Contents

Hooks reference - Plugixa Inventory

Every hook is prefixed plugixa_inventory_. Add listeners from a small plugin or your theme’s functions.php.

Lifecycle

Action Fires
plugixa_inventory_loaded The plugin has booted and the container is built
plugixa_inventory_activated On activation, after the tables exist
plugixa_inventory_deactivated On deactivation
plugixa_inventory_uninstall On uninstall, before anything is removed
plugixa_inventory_register_rest_routes With the namespace and the container, so your own routes can join it
plugixa_inventory_enqueue_assets When the app’s assets are enqueued

Records

do_action( 'plugixa_inventory_entity_created', $entity, $id, $data );
do_action( 'plugixa_inventory_entity_updated', $entity, $id, $data, $old );
do_action( 'plugixa_inventory_entity_deleted', $entity, $id );
do_action( 'plugixa_inventory_entity_restored', $entity, $id );
do_action( 'plugixa_inventory_entity_purged',  $entity, $id );

$entity is the slug: item, category, warehouse, recipient, stock_movement, transaction, and with Pro transfer, adjustment and unit.

Also plugixa_inventory_entity_assigned when a record’s assigned user changes, and plugixa_inventory_entity_field_changed for a single field.

The matching filters run before the write, so a listener can change what is saved or stop it:

Filter Purpose
plugixa_inventory_before_insert Change the data about to be inserted
plugixa_inventory_before_update Change the data about to be updated
plugixa_inventory_can_delete Refuse a trash
plugixa_inventory_can_purge Refuse a permanent delete
plugixa_inventory_load_record Change a record as it is loaded
plugixa_inventory_filter_output Change what an endpoint returns

Delete blockers

The mechanism behind “this warehouse still holds stock”:

add_filter( 'plugixa_inventory_warehouse_delete_blockers', function ( $blockers, $id ) {
    if ( my_warehouse_is_locked( $id ) ) {
        $blockers[] = __( 'This warehouse is locked for the stocktake.' );
    }
    return $blockers;
}, 10, 2 );

An empty array means “go ahead”. Anything in it is shown to the user and the trash is refused. There are three: ..._warehouse_delete_blockers, ..._item_delete_blockers and ..._recipient_delete_blockers.

Stock

Hook Kind Fires
plugixa_inventory_document_finalized action A document was finalised: $entity, $id, $document, $applied
plugixa_inventory_stock_applied action A batch of stock changes was written: $batch, $result
plugixa_inventory_stock_level_changed action An item’s total changed: $item_id, $total
plugixa_inventory_stock_error action A stock operation failed
plugixa_inventory_stock_audited action The reconcile ran: $report
plugixa_inventory_layers_seeded action Cost layers were opened: $report

plugixa_inventory_document_finalized is the one most integrations want. It is the moment stock actually moved, and it fires for every document type.

Notifications

Hook Kind Purpose
plugixa_inventory_alert_types filter Declare a new kind of alert
plugixa_inventory_alert_audience filter Decide who an alert reaches
plugixa_inventory_should_notify filter Suppress one notification
plugixa_inventory_alert_sent action After sending: $type, $payload, $counts
plugixa_inventory_before_send_mail action Before an email leaves
plugixa_inventory_email_throttle filter Change the sending rate limit

Permissions

Hook Kind Purpose
plugixa_inventory_user_can filter The single permission decision, handed the record
plugixa_inventory_capabilities filter The capability map
plugixa_inventory_entity_types filter Register an entity, with its fields
plugixa_inventory_filterable_fields filter What a list may be narrowed by

plugixa_inventory_user_can is where the Pro Roles module lives - the entire module is essentially one listener on it. Every one of the plugin’s permission callbacks routes through the method that fires it, which is why granular permissions needed no controller changes.

Import and export

Hook Kind Purpose
plugixa_inventory_import_targets filter Add a mappable column
plugixa_inventory_import_write_extras filter Write extra data per imported row
plugixa_inventory_import_document_lines filter Change the opening-stock document
plugixa_inventory_record_writers filter Register a generic writer, which is what makes an entity importable
plugixa_inventory_record_names filter Human names for records in messages

The App Manager and settings

Hook Kind Purpose
plugixa_inventory_modules filter The registered modules
plugixa_inventory_apps filter The App Manager’s cards
plugixa_inventory_app_toggled action An app was switched: $id, $enabled
plugixa_inventory_sanitize_settings filter Validate your own setting
plugixa_inventory_settings_saved action After a save: $settings
plugixa_inventory_admin_config filter What the admin bundle is given
plugixa_inventory_bootstrap_payload filter What /bootstrap returns

The four that hold the seam together

These exist so that a free build is a working plugin rather than a crippled one. Each replaced a place where free code called something that became premium:

Filter So that
plugixa_inventory_alert_types A module describes the event it raises, beside the code that raises it
plugixa_inventory_warehouse_metrics A warehouse tile is contributed, so a dashboard does not need two document modules in order to boot
plugixa_inventory_occurred_at_sources A document module names its own table, so a migration cannot join one that is absent
plugixa_inventory_costing_strategy Costing answers with the object, not a name - a name filter could only choose between implementations the free build already knew

That last distinction is the useful one to copy: a filter returning a name can only select from what the caller already knows about. A filter returning an object lets something the caller has never heard of answer.

Costing

Hook Kind Purpose
plugixa_inventory_costing_strategy filter Supply your own costing implementation
plugixa_inventory_costing_methods filter The methods offered in settings
plugixa_inventory_costing_method filter The method in force
plugixa_inventory_max_layer_walk filter How far a layer walk may go before it gives up

Front end

Hook Kind Purpose
plugixa_inventory_is_app_page filter Whether this page holds the app
plugixa_inventory_app_page_keep_styles filter Stylesheets to keep through the style strip
plugixa_inventory_public_request_captcha filter Add a challenge to a public request
plugixa_inventory_client_ip filter How the visitor’s address is determined behind a proxy

Example

Post a message when a document is finalised:

add_action(
    'plugixa_inventory_document_finalized',
    function ( string $entity, int $id, array $document, array $applied ): void {
        if ( 'transfer' !== $entity ) {
            return;
        }
        my_notify_depot( $document, $applied );
    },
    10,
    4
);

Troubleshooting

Symptom Usual cause
A listener never fires Register it on plugins_loaded or later, and check the argument count.
A filter has no effect Another listener runs later. Raise the priority number to run after it.
A Pro hook does nothing Its module is absent. The hook fires; nothing listens.
plugixa_inventory_user_can is called constantly It is. Every permission decision goes through it. Keep the listener cheap.
A delete blocker is ignored Return the array. A listener that returns nothing removes every blocker.
An entity has no CRUD routes It needs to be registered through plugixa_inventory_entity_types.

What to do next

Quick Links