PhoenixKit Warehouse

Warehouse module for PhoenixKit.

A drop-in PhoenixKit module — add it to a host app's deps and it is auto-discovered, adding a Warehouse section to the admin panel. Like every PhoenixKit module it has no endpoint, router, or Ecto repo of its own; it borrows the host's via phoenix_kit.

Status: implemented. Stock keeping, the document set and their posting rules below are in use; see CHANGELOG.md for the release history.

Scope

Stock per item and location

Documents

Documents are created as drafts and take effect when posted (a transfer ships and then is received). Each has a number drawn from its own sequence, and a draft can be soft-deleted. Most also have a storage folder for attachments and a comment thread.

Document Effect on stock
Goods receipt Adds each line's received_quantity (and sets unit_value when the line carries one). Can be created from a supplier order.
Goods issue Subtracts each line's issued_quantity, never below zero; if any line is short the whole posting rolls back and the document stays a draft. Carries a reason: production (the default), sale, damage or other. Can be created from internal orders.
Inventory document (stocktake) Sets the stock of each listed item to its counted_quantity (absolute, not a delta); other stock rows are untouched. Can be re-posted.
Transfer Shipping subtracts from the source warehouse, receiving adds to the destination; cancelling an in-transit transfer credits the source back.
Internal order, supplier order None. They record demand and procurement and feed the documents above.

Posting semantics worth knowing:

Programmatic posting

For callers that are not a person at a form (a shop, a POS, an integration), GoodsIssues.create_and_post/2, GoodsReceipts.create_and_post/2 and Inventories.create_and_post/2 create and post in one transaction: a call refused by validation or the stock check leaves no draft and consumes no document number. A failure after the insert (a database error while posting) rolls the draft back too, but the number sequence has advanced.

Linking documents to host records

Documents link to host-owned records (orders, sub-orders, ...) through source_refs and the generic PhoenixKitWarehouse.SourceKinds registry, so the package has no dependency on any specific "order" concept. Kinds come from the host's config :phoenix_kit_warehouse, :source_kinds list and from any registered PhoenixKit module that exports warehouse_source_kinds/0; the two are merged by kind, and the host's definition wins on a conflict.

Other modules

Requires phoenix_kit_catalogue (the items), phoenix_kit_locations (the warehouses), phoenix_kit_billing (currency formatting) and phoenix_kit_comments (document comment threads). A plan source for core's mix phoenix_kit.media.reorganize is included.

Installation

Add to your host app's mix.exs:

{:phoenix_kit_warehouse, "~> 0.3"}

Then fetch deps, apply the module's tables, and enable it in Admin → Modules:

mix deps.get
mix phoenix_kit.update

Removing this module

There is deliberately no automated uninstall. PhoenixKitWarehouse.Migrations.down/1 never drops any of the 8 phoenix_kit_warehouse_* tables or a row in them, for any target version — a host that merely removes this dependency from mix.exs has not consented to deleting live stock balances and document history, and a migration whose result depended on which packages happen to be compiled in would be nondeterministic (it would break core's manifest, chain hash, and squash verification). Removing the data is therefore a deliberate, manual operator step, in FK-safe order (children before parents):

-- Only after removing :phoenix_kit_warehouse from mix.exs, and only if you
-- actually want every stock balance and document gone for good.
DROP TABLE phoenix_kit_warehouse_goods_issues;
DROP TABLE phoenix_kit_warehouse_goods_receipts;
DROP TABLE phoenix_kit_warehouse_supplier_orders;
DROP TABLE phoenix_kit_warehouse_internal_orders;
DROP TABLE phoenix_kit_warehouse_inventory_documents;
DROP TABLE phoenix_kit_warehouse_stock;
DROP TABLE phoenix_kit_warehouse_transfers;
DROP TABLE phoenix_kit_warehouse_min_stock;
-- The document-number sequences are not OWNED BY their columns, so
-- dropping the tables leaves them behind.
DROP SEQUENCE phoenix_kit_warehouse_goods_issues_number_seq;
DROP SEQUENCE phoenix_kit_warehouse_goods_receipts_number_seq;
DROP SEQUENCE phoenix_kit_warehouse_supplier_orders_number_seq;
DROP SEQUENCE phoenix_kit_warehouse_internal_orders_number_seq;
DROP SEQUENCE phoenix_kit_warehouse_inventory_documents_number_seq;
DROP SEQUENCE phoenix_kit_warehouse_transfers_number_seq;

If you want to keep the tables (e.g. you plan to reinstall the module later) but stop this chain from tracking them, clear the version marker instead — it lives only on the anchor table:

COMMENT ON TABLE phoenix_kit_warehouse_stock IS NULL;

Development

See AGENTS.md for architecture, conventions, testing, and the release checklist.

License

MIT — see LICENSE.