=== StockControls for WooCommerce ===
Contributors: stockcontrols
Tags: woocommerce, inventory, stock management, stock control, audit log
Requires at least: 6.5
Tested up to: 7.1
Requires PHP: 7.4
Requires Plugins: woocommerce
Stable tag: 1.0.0
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

WooCommerce stock editing, reviewed CSV imports, movement history, suppliers and basic purchase orders in one workspace.

== Description ==

StockControls helps you review stock changes, understand recorded movements and replenish from suppliers inside WordPress.

Free features:

* Product and variation search by name, SKU or ID; stock/category filters and quantity/name/SKU sorting.
* Clickable stock summaries and up to 10 personal saved inventory views per account and store.
* Shared setup guidance, storage/history health checks and responsive stock controls.
* Shared-parent inventory labels so listings are not confused with separate stock pools.
* Multi-product exact quantities or signed adjustments, required reasons and preview before saving.
* Stale-stock checks before preview and commit; durable per-row results and retry protection.
* CSV import with ID/SKU matching, column mapping, validation and reviewed changes; a separate resumable path supports up to 10,000 rows / 10 MB.
* Movement history with current product names/SKUs, product search, quantities, actor, source, UTC time and order links when supplied by supported WooCommerce hooks.
* Product-level WooCommerce low-stock thresholds and complete, verified inventory/history CSV exports.
* Saved single-operator available-to-sell stocktakes, variance review, recovery and CSV reports.
* Exact-SKU keyboard scanner input for product lookup and draft counts; manual entry also works.
* Central suppliers, contacts, addresses, supplier product references and lead times.
* Editable purchase-order drafts, unit costs, shipping/tax amounts, expected dates, local PDF/print and CSV documents.
* Product search for supplier assignments and PO drafts, plus order-status and delivery-date filters.
* Review and confirm actual quantities for each product or a full delivery, with saved receipt recovery and stock-history links.
* Reasoned amendments and cancellation of outstanding purchase orders, preserving received quantities and history.

Pro adds priority/supplier planning views, delivery-timing guidance, reviewed bulk planning setup, optional recurring sales refreshes, minimum-order/pack suggestions, alternative supplier terms, buying baskets, team counts and multi-line shipment review with remaining delivery dates. Manual receiving, amendments and cancellation are included in Free.

No telemetry, external account, licensing server or remote data collection is included. Camera scanning, barcode-label generation, warehouse quantity allocation, cross-store synchronization and supplier email automation are not included.

== Installation ==

1. Back up your store and use a staging copy first.
2. Install and activate WooCommerce 9.1 or newer on WordPress 6.5+ and PHP 7.4+.
3. Upload the stockcontrols ZIP through Plugins > Add New, or copy its folder into wp-content/plugins.
4. Activate StockControls for WooCommerce on the individual site.
5. Open StockControls > Setup & health, then Inventory. Enable stock management for products you want to adjust. Setup & health explains storage checks, history warnings and background work.
6. For purchasing, create a supplier, assign stock-owning products and create a purchase-order draft.

Requirements: standard WooCommerce product storage, MySQL/MariaDB GET_LOCK support and InnoDB product, post-meta, lookup, audit and purchasing tables. Unsupported storage cannot accept StockControls stock changes. Network-wide activation and custom product data stores are unsupported.

Free and Pro both use version 1.0.0. When replacing development builds, back up first and update Free before Pro. Purchasing records are retained.

== Frequently Asked Questions ==

= Can I save my inventory filters? =

Yes. Save / manage views stores the current search, stock/category filters and sorting. Up to 10 named views are available per WordPress account and store, with no Pro requirement. A view stores no stock quantities and does not change products.

= How does bulk editing work? =

Select products on the inventory page, enter exact quantities or signed changes and supply a reason. The selection count and proposed quantities help you review preparation; entering a quantity selects its row. Preview first, then explicitly apply. A changed quantity or stock owner invalidates a stale selection rather than overwriting a newer sale. Shared-stock listings cannot appear twice in the same batch.

= What CSV format can I import? =

Use UTF-8, comma-separated values. The column-mapping importer supports up to 200 product rows / 1 MB. The separate Large CSV imports screen supports up to 10,000 rows / 10 MB using the exact template headers: product_id, sku, quantity, delta, reason and optional expected_quantity. Supply at least one identifier and exactly one quantity operation per row. Both identifiers must agree when present. Use a dot for decimals; zero is allowed for quantity. A row reason or default form reason is required. Large imports reject other headers; the smaller importer lets you explicitly map or ignore columns. The downloadable template is separate from inventory export.

Any invalid row blocks the preview from being applied. Without expected_quantity, stock changes are detected from preview onward; earlier sales cannot be inferred from an old spreadsheet. With it, the expected stock must match before preview. See README.md for an example.

= How do larger imports resume? =

Upload and validation change no stock. Review the saved rows and explicitly confirm background applying; each slice changes at most 25 rows. Background work uses WordPress scheduling, which depends on site traffic or a host cron runner. Continue manually from the same job if it is delayed. Jobs belong to their original WordPress account and store; the reviewer must retain permission to change stock. Saved rows are not repeated after interruptions. Cancellation stops uncommitted rows and does not undo completed changes. A file with invalid rows cannot be approved; fix the file and upload a new job. Up to 10 unfinished jobs are available per account and store.

= Can part of a batch succeed? =

Yes. Rows commit independently, up to 25 per click. Results identify saved, pending, retryable and rejected rows. Reopen the same batch after an interruption: saved rows are not repeated. Correct stale or rejected rows in a new preview. Discarding remaining changes does not undo saved changes. Unstarted previews expire after 24 hours; unstarted or finished temporary results are cleaned after 30 days without an update while the plugin is active. Started unfinished changes retain their recovery records.

= Can I find history by product name or SKU? =

Yes. Search the current product name, SKU or ID, then narrow by movement source and dates. Names/SKUs describe the current catalog; recorded stock-owner and requested-product IDs stay unchanged. Search includes all matching product identities. Older/Newer pages keep the initial record-ID boundary; refresh latest records to include newer movements. Changes to current names/SKUs can change matches while browsing. If a complete search exceeds the host’s query budget, narrow the filters and retry. For a removed product, clear the name/SKU search and use the separate exact Product ID field. CSV export uses the same filters and captures a new complete database snapshot.

= How do CSV exports stay complete? =

Inventory and history exports are prepared and verified before download. They support up to 1 million rows, 256 MiB and 45 seconds, or the host’s shorter request limit. These are safety ceilings, not a guarantee that every store can export that much in one request. A read error, lost permission or exceeded limit returns an error without a partial CSV; narrow the selected filters and retry. A connection interruption during delivery may still interrupt the download.

Inventory keeps the selected sort order and captures product values together. Default thresholds and included category scope use the WordPress settings available when export starts. Inventory export is a report, not the import template. Spreadsheet formula prefixes are neutralized.

= Can I save stocktakes or use a scanner in Free? =

Yes. Create a saved count for 1–200 selected products, enter available-to-sell quantities and review the variances before applying. Exclude goods already allocated to unfulfilled orders, even if they are still on the shelf. Counting does not pause checkout; changed stock must be reviewed again. A keyboard scanner can type an exact SKU to find a product or add one draft unit to a matching count line. Scanning and saving a draft do not change live stock. Camera scanning and barcode-label generation are not included. Pro adds team assignment, blind counts, recount thresholds and independent approval.

= Does movement history capture every stock change? =

No. StockControls records its own service writes and observes supported WooCommerce stock hooks, including ordinary product updates, order reductions/restorations and refund restocking. Order links and source labels are added when available. Direct database writes, unsupported extension behavior and historical changes before activation are not reconstructed. External observation is best effort: logging failure does not stop checkout, and an admin notice reports incomplete history.

= Does it support variations and decimals? =

Yes. Inherited variations change the parent's stock pool, and history identifies both products when available. Purchasing uses the actual stock-owning product. Dashboard counts are listings. Fractions require WooCommerce precision support; unsupported fractions are rejected. Stock adjustments support up to six decimals within +/-999999999.

= Which purchasing features are free? =

Supplier records, product assignments, editable/cancellable drafts, one supplier and up to 50 product lines per PO, unit costs, shipping/tax amounts, expected dates, PDF/print, CSV, reviewed actual-quantity and full-order receiving, and reasoned amendments/cancellation of outstanding orders. Filter orders by status, overdue/near-term delivery or missing dates. Search product names/SKUs when assigning suppliers or building drafts. Quantity per PO line is greater than zero and at most 1,000,000. Currency/precision are captured from the store. Tax is manually entered; the purchase order is not a tax invoice. Supplier sending, returns and accounting integration are not included.

= Why does an older purchase order show a financial-details notice? =

Development-build POs did not record these financial details. Missing currency/precision and buyer details are initialized from the store during upgrade and labelled. Zero historical cost fields do not establish that the goods were free. Review before sending the document.

= When does receiving change stock? =

Enter the quantity that physically arrived for a product and choose Review delivery, or use Review full receipt only when all outstanding goods have arrived. Check the quantities, then confirm. Reviewing alone changes no stock. For example, receive six of ten ordered units now and leave four outstanding until they arrive. Both manual paths are included in Free.

= What if receiving is interrupted? =

Reopen the same purchase order and resume its saved receipt. A full-order receipt may have completed some lines before interruption; retrying uses stable tokens and does not add those quantities twice. Finish pending receipts before changing the order. Do not create a replacement receipt or clear database records manually.

= Can I edit or cancel an ordered purchase order? =

Yes. Free can amend an ordered or partly received PO with a reason and a current revision. An amended quantity cannot be less than the amount already received. Cancellation stops outstanding quantities counting as incoming without removing received stock or history. Finish saved pending receipts before editing or cancelling. Supplier returns are not included.

= Will PDF documents preserve international names? =

The local PDF font supports Windows-1252. Unsupported text is rejected rather than silently replaced. Use Print / Save as PDF with browser fonts when a name or address needs other characters. No external document service is used.

= Is it compatible with HPOS? =

HPOS compatibility is declared, and order references use WooCommerce APIs. Test your store’s checkout, refunds and stock workflows on staging with its actual extensions before installation or updates.

External stock history is best-effort under simultaneous updates. If a WooCommerce callback quantity cannot be verified against persisted stock, the plugin flags an incomplete-history notice and skips that entry. Simultaneous external changes can also coalesce or look like a no-op without a notice. StockControls writes retain their transactional movement record.

= What happens to data on uninstall? =

Data stays by default. An administrator can opt into removing the movement log in StockControls > Settings. Temporary batches are removed with the log. If a purchase receipt is pending or a started import, stocktake or bulk change has unfinished rows, deletion is skipped so it can recover safely. Unreadable batch records also preserve the audit history for review. Rebuildable catalog, sales and planning indexes are removed with the log. Supplier, purchasing, saved stocktake and large-import records remain even with that option enabled, as do WooCommerce stock quantities and thresholds. Large-import records include private uploaded source chunks and row outcomes; completion or cancellation does not delete them. Temporary batch results have their own cleanup while the plugin is active. Audit history has no automatic purge or UI editing, but database administrators can change it.

= What does acknowledging a history warning do? =

Setup & health lets each administrator acknowledge a recorded warning for their account. It changes the reminder display, not stock, history records or missing movements. New warnings still need review.

= Does StockControls send alerts or create supplier orders automatically? =

No. WooCommerce handles its normal low-stock emails. Export a purchase order and send it through your existing supplier process, then mark it ordered. Pro can show local reminders and separately enabled staff email summaries. It does not place supplier orders automatically.

== Privacy ==

StockControls stores movement quantities, sources, WordPress actor IDs, reasons, supplier contacts, purchasing documents, receipt links, saved counts, private import source/results, saved views and local setup/warning preferences in the local store database. Imports and local PDF generation do not contact an external service. Authorized users can export records. Avoid unnecessary personal information in reasons and retain downloaded records appropriately.

== Screenshots ==

== Changelog ==

= 1.0.0 =
* Initial public release: reviewed bulk stock editing and CSV import, shared-parent inventory, source/order-linked movement history, low-stock thresholds and CSV exports.
* Separate resumable large CSV jobs with streaming validation, explicit approval, saved per-row outcomes, cancellation of uncommitted rows and interrupted-work recovery.
* Supplier directory and purchase orders with draft editing, costs, expected delivery dates, PDF/print documents, reviewed actual-quantity/full receiving, and reasoned amendments/cancellation preserving received goods.
* Personal saved views, compact responsive inventory, setup/health guidance, searchable purchasing products, delivery filters and receipt review before confirmation.
* Complete current-name/SKU history search, stable record-boundary navigation and verified inventory/history CSV downloads; recorded owner/request identities are preserved.
* Saved available-to-sell stocktakes, variance review and exact-SKU keyboard scanning into draft counts.
* Permission checks, stale-stock protection, durable retry results and explicit movement-log retention controls.

== Upgrade Notice ==

= 1.0.0 =
First public release. Back up and validate on staging. Update Free before the matched Pro 1.0.0 package when replacing development builds; purchasing records are retained.
