# Filters and hooks - Supplyline 1.x documentation

> React to purchase orders and deliveries, change reorder points, add suppliers, rows, columns and fields from code.

Supplyline's hooks are WordPress actions and filters. Supplyline Pro is built on them, and you can use them in a small custom plugin or your child theme's `functions.php`.

## Reacting to purchase orders

### supplyline_po_status

Fires when a purchase order's status changes, with the purchase order and the new status (`ordered`, `partial`, `received` or `cancelled`).

```php
// Tell the warehouse when an order is placed.
add_action( 'supplyline_po_status', function ( $po, $status ) {
	if ( 'ordered' === $status ) {
		wp_mail( 'warehouse@example.com', 'Incoming: ' . $po->number(), 'Expected ' . $po->expected() );
	}
}, 10, 2 );
```

### supplyline_stock_received

Fires for each line received, after its units were added to stock. Gets the product (or `false` for a line that isn't a product), the units, the purchase order and the line (`product`, `pool`, `name`, `sku`, `qty`, `cost`, `received` before these units).

```php
add_action( 'supplyline_stock_received', function ( $product, $units, $po, $line ) {
	if ( $product ) {
		error_log( sprintf( '%d × %s arrived on %s', $units, $product->get_name(), $po->number() ) );
	}
}, 10, 4 );
```

## Reordering

### supplyline_reorder_plan

A product's reorder point and quantity, before **To reorder** checks them. Gets `$plan` (`point`: int, or null for none; `qty`: the quantity to suggest, 0 for "just enough"; `auto`: whether the point was worked out rather than set), the product, and `$context` (`stock`, `on_order`, `available`, `sold`, `days`, `rate`, `supplier`). Rows with `auto` show "suggested" under the point.

```php
// Keep two weeks of sales on top of every reorder point.
add_filter( 'supplyline_reorder_plan', function ( $plan, $product, $context ) {
	if ( null !== $plan['point'] && $context['rate'] > 0 ) {
		$plan['point'] += (int) ceil( $context['rate'] * 14 );
		$plan['auto']   = true;
	}
	return $plan;
}, 10, 3 );
```

### supplyline_reorder_products

The product and variation IDs **To reorder** checks: those with a reorder point. Add IDs to have products without one checked too (they need a point from `supplyline_reorder_plan`). Also gets the units sold per product in the sales period and the period's days.

### supplyline_reorder_rows

Rows that aren't products, shaped like a product's row (`key`, `name`, `stock`, `on_order`, `point`, `qty`, `suppliers` and the rest; see `Reorder::suggestions()`), with a key of their own such as `pool-12`. Gets the rows and the units on order per line key.

## Suppliers and products

### supplyline_product_offers

More suppliers for a product or variation, after its main one. Each offer is `supplier` (ID), `sku`, `price` (in the supplier's currency), `min` and `pack`. A product with more than one supplier gets a supplier choice on **To reorder**, and the chosen supplier's terms go on the purchase order.

```php
add_filter( 'supplyline_product_offers', function ( $offers, $product ) {
	if ( 'MUG-1' === $product->get_sku() ) {
		$offers[] = array( 'supplier' => 123, 'sku' => 'ALT-MUG', 'price' => '6.50', 'min' => 24, 'pack' => 12 );
	}
	return $offers;
}, 10, 2 );
```

### supplyline_supplier_currency

The currency a supplier's prices and new purchase orders are in. Gets the store's currency and the supplier ID.

### supplyline_supplier_fields

Prints extra `<tr>` rows in the supplier's **Details** box. Save them on `save_post_supplyline_supplier` after checking the `supplyline_supplier_nonce` field (action `supplyline_supplier`).

## The purchase order screen

| Hook | Use |
|---|---|
| `supplyline_po_columns` (filter) | More columns in the Products table, after Total: key => label, or key => `array( 'label' => …, 'tip' => … )`. Print each cell on `supplyline_po_column` (action: key, line, purchase order). |
| `supplyline_po_totals` (action) | Rows between the subtotal and the total. Gets the purchase order and the number of columns after Total, for the last cell's colspan. |
| `supplyline_po_total` (filter) | The purchase order's total (the lines' subtotal). Add your rows' amounts here. |
| `supplyline_po_add_lines` (action) | More ways to add lines on a draft, under the product search. Add a line from JavaScript with `jQuery( document.body ).trigger( 'supplyline_add_line', [ { product, pool, name, qty } ] )`. |
| `supplyline_po_details` (action) | More details in the side box, after the expected date. |
| `supplyline_po_options` (action) | Options above the side box's buttons on a draft or an open purchase order. |
| `supplyline_po_links` (action) | Links next to Print. Start each with " \| ". |
| `supplyline_po_save` (action) | The form is being saved (nonce and capability checked), before its action runs: read your fields from `$_POST`. Throw an `InvalidArgumentException` to stop with its message. Gets the purchase order and the action (`save`, `order`, `receive`, `cancel`). |
| `supplyline_po_message` (filter) | The notice after saving: a key of `supplyline_messages`. Gets the key, the purchase order and the action. |
| `supplyline_messages` (filter) | The notices: key => `array( type, text )`. |
| `supplyline_po_order_error` (filter) | Why a draft can't be ordered yet: return a message to stop **Mark as ordered**. |
| `supplyline_po_supplier_set` (action) | A purchase order got its supplier, when created or when a draft's supplier changes. |

## Stockpool pool lines

A purchase order line can be a Stockpool pool (`pool` => ID instead of `product`). Supplyline keeps such lines but leaves the pool's details to an add-on (Supplyline Pro):

| Hook | Use |
|---|---|
| `supplyline_pool_name` (filter) | The pool's name for a new line. Without one, a new pool line is left out; an existing one keeps its name. |
| `supplyline_pool_offer` (filter) | The pool's supplier, SKU, price, minimum and pack size. |
| `supplyline_pool_receivable` (filter) | Whether a pool line can be received. False unless an add-on says so. |
| `supplyline_receive_pool` (action) | Units of a pool line arrived: add them to the pool. Gets the pool ID, the units and the purchase order. |

## supplyline_loaded

Fires once Supplyline has loaded (on `plugins_loaded`, only when WooCommerce is active). Hook an add-on's setup to it, so it only runs when Supplyline is there. `SUPPLYLINE_VERSION` is defined from then on.

## PHP API

`Extendiment\Supplyline\PurchaseOrder` (`create()`, `get()`, `all()`, `page()`, `lines()`, `set_lines()`, `mark_ordered()`, `receive()`, `cancel()`, `on_order()`, and `locked()` to run code in a purchase order's lock), `Suppliers` (`all()`, `get()`, `name()`, `currency()`), `ProductFields` (the meta key constants, `supplier()`, `cost()`, `point()`), `Offers` and `Reorder::suggestions()` are public. Errors are `InvalidArgumentException`s with translated messages.

Source: https://extendiment.com/plugins/supplyline/docs/1.x/filters-and-hooks
