Developer notes
Data model (InnoDB, prefix ?:kv_pur_)
Section titled “Data model (InnoDB, prefix ?:kv_pur_)”| Table | Contents |
|---|---|
suppliers |
Supplier with purchasing terms; company_id = vendor (MV) or storefront (Ultimate); core_supplier_id links a row to the core Suppliers add-on (0 = own supplier). |
product_suppliers |
Product ↔ supplier: supplier SKU, unit cost (supplier currency, 4 decimals), pack quantity, preferred flag. |
products |
Per product: reorder point, target stock (NULL = setting defaults), last and weighted average cost (primary currency). |
orders |
Purchase order: number (series_key + seq_no unique), status D/S/P/R/X, currency + exchange rate snapshot, supplier snapshot (JSON), dates, totals, link token. |
order_items |
Lines: product id + name/code snapshot, supplier SKU, ordered and received quantity, unit cost, line total. |
receipts, receipt_items |
Receipt log; receipt_key is unique (form token); per line the stock state (P pending, Y applied, N not tracked) and the stock before/after. |
history |
Events per purchase order (created, edited, e-mailed, marked sent, received, cancelled). |
counters |
Last number per series. |
Guarantees
Section titled “Guarantees”- Numbering: the counter row of the series is locked first (
SELECT … FOR UPDATE, created only when missing), the purchase order is inserted with the next number and the counter moved in the same transaction. Deadlocks are retried. Numbers are unique and consecutive per series. - Receiving: the purchase order row is locked; open quantities are checked; receipt, lines, received quantities and status are written in one transaction. After the commit each receipt line is claimed with a conditional update (
stock_stateP → Y) and only the claiming request changes the stock, with one statement:amount = amount + qty(read back withLAST_INSERT_ID()). A double submit with the same receipt key is a no-op; lines left pending by an interrupted request are applied when the purchase order is opened, never twice. - After a stock change the core hook
update_product_amount_postruns (variations, master products, stock alert add-ons) and core back-in-stock notifications are sent when the stock goes from 0 or less to more than 0. - Warehouses: for products whose stock is split by the core Warehouses add-on, the quantity goes to the warehouse chosen on the purchase order (or the first warehouse) through the warehouses manager, which also updates the product quantity.
Hooks used
Section titled “Hooks used”get_product_data_post (storefront note), update_product_post (product editor fields), delete_product_post, delete_company, template_document_get_name. Template hooks: admin products:list_quantity, products:update_product_amount; storefront products:product_amount. The products.view main block cache gets the add-on tables as update handlers and a day/setting/licence key.
Document variables (Design → Documents → Purchase order)
Section titled “Document variables (Design → Documents → Purchase order)”All values are HTML-escaped by the add-on.
po:title,number,date,expected,status,currency,payment_terms,notes[],terms[],ship_to[],lines[](name,code,sku,qty,received,unit_cost,total),totals(subtotal,shipping,has_shipping,other,has_other,total).b(your company):name,address_lines[],email,phone,logo_url.sup(supplier):name,contact,email,phone,address_lines[].
E-mail template kv_purchase_orders_suppliers_po: po_number, supplier_name, contact_name, buyer_name, expected_date, total_text, lines_count, message_lines, has_attachment, document_html, view_url.
Public PHP API
Section titled “Public PHP API”use Tygh\Addons\KvPurchaseOrdersSuppliers\Orders;use Tygh\Addons\KvPurchaseOrdersSuppliers\Receiving;use Tygh\Addons\KvPurchaseOrdersSuppliers\Products;
$result = Orders::create(['supplier_id' => 3, 'lines' => [['product_id' => 12, 'qty' => 10, 'unit_cost' => '4.20']]]);Orders::markSent($result['po_id']);Receiving::receive($result['po_id'], [$item_id => 10], ['receipt_key' => 'unique-key', 'update_cost' => true]);$on_order = Products::onOrder([12, 13]); // [product_id => qty]File map
Section titled “File map”app/addons/kv_purchase_orders_suppliers/ addon.xml, init.php, func.php controllers/backend/kv_purchase_orders_suppliers.php purchasing pages (admin + vendor) controllers/backend/products.post.php product list / editor data controllers/frontend/kv_purchase_orders_suppliers.php supplier link (printable purchase order) resources/document_templates.xml, email_templates.xml schemas/ block_manager, documents, menu, permissions Tygh/Addons/KvPurchaseOrdersSuppliers/ Config, Access, Money, Tx, Numbering, Suppliers, Products, Orders, Receiving, Suggestions, View, Output, Mailer, Exporter, ServiceProvider, Document/{Type,Context}, License/*, Upgrade/Synchronizerdesign/backend/templates/addons/kv_purchase_orders_suppliers/ views, components, hooks, licensedesign/backend/css/addons/kv_purchase_orders_suppliers/styles.lessjs/addons/kv_purchase_orders_suppliers/func.jsvar/themes_repository/responsive/templates/addons/kv_purchase_orders_suppliers/hooks/products/product_amount.post.tplvar/themes_repository/responsive/css/addons/kv_purchase_orders_suppliers/styles.lessvar/langs/en/addons/kv_purchase_orders_suppliers.po