=== StockControls Inventory Operations 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.1.7
License: GPL-2.0-only
License URI: https://www.gnu.org/licenses/old-licenses/gpl-2.0.html

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

== Description ==

Launch editions (1.1.7): Free includes immediate manual stock corrections, reasons/history, SKU lookup, reviewed CSV imports/exports, suppliers, ordinary purchase orders/PDF/print, full and partial receiving, receipt recovery, amendments and cancellation. Pro adds saved/resumable stocktakes, saved progress, variance review and reconciliation, alongside team/blind counts, recount/approval, replenishment and advanced supplier/shipment reviews. Deactivating Pro retains saved counts and batch results and pauses reconciliation; reactivate a compatible Pro to resume. No grandfathering or data reset.

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.
* Basic SKU product lookup and immediate manual quantity corrections with reasons and history.
* 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 saved/resumable individual stocktakes, saved progress, variance review and reconciliation, plus 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 ==

Updating 1.1.5: replace Free with 1.1.7, then replace Pro if installed. Keep both plugins installed; do not uninstall them. Both plugin folders are unchanged from 1.1.5.

Upgrading from the old `stockcontrols` directory: deactivate Pro, then deactivate the old Free plugin. Keep the old Free plugin installed but inactive; do not delete or uninstall it. Install and activate this newly named Free plugin, then replace Pro with the matching 1.1.7 package and activate Pro. The directory changes; existing StockControls data keys stay the same. Back up your store and test on staging first. Deactivation pauses optional Pro reminders and availability observations; review and re-enable them afterwards if wanted, and refresh planning data.


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 stockcontrols-inventory-operations-1.1.7.zip through Plugins > Add New, or copy its stockcontrols-inventory-operations folder into wp-content/plugins.
4. Activate StockControls Inventory Operations 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.1.7. For existing copies in the current folders, back up first and replace Free before Pro without uninstalling. For the old stockcontrols folder, follow the rename instructions above. 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 I remove old finished large imports? =

Yes. An administrator can open their own completed, finished-with-rejections or safely cancelled job, download any results they need, and choose Review removal. The review verifies the source and row outcomes and shows the records to be removed. A separate confirmation permanently removes only that job’s source chunks, row results and job record. Stock quantities, movement history, products, purchase orders and other imports stay unchanged. Pending, uncertain, changed or unverifiable work is kept. Reviews expire after 15 minutes and are tied to the signed-in session. A minimal hashed removal reference remains to prevent reuse of an old import; no CSV content or row results are stored in it. Downloaded copies and backups require separate removal. There is no automatic cleanup.

= 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. Daily cleanup can remove never-started previews after 30 days without an update, unless a saved stocktake still references them. For a retained stocktake review that has not started applying, return to counting and prepare a fresh review. All started batches, including completed ones, retain their recovery records while the plugin is active.

= 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? =

PDF downloads are generated locally with an embedded DejaVu Sans font and support covered Latin, Greek, Cyrillic, Hebrew and Arabic characters, including right-to-left text shaping. Characters outside that font (including many CJK/Indic characters and emoji) return an explicit error instead of being replaced. Use Print / Save as PDF for those documents. Downloads require PHP mbstring, GD and a writable temporary directory; the rest of the plugin and browser print remain available without them. No external document service or font download 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, a started import, stocktake or bulk change has unfinished rows, or a saved stocktake still references a batch result, deletion is skipped so retained work stays readable and recoverable. Unreadable batch records or a failed stocktake-reference check 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. Use the separately reviewed finished-import removal action while the plugin is active; its minimal replay-prevention reference remains on uninstall. 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.

== Bundled PDF software ==

The local PDF renderer includes privately namespaced mPDF and its dependencies, plus an embedded DejaVu Sans font. This combined Free distribution uses GPL version 2 because mPDF is GPL-2.0-only; original StockControls code remains available under GPL-2.0-or-later. Third-party components retain their supplied license notices. The exact rebuild script, Composer manifest and lock, dependency versions and instructions are included in development/pdf-dependencies/. Start with development/pdf-dependencies/README.txt. These are optional developer tools; WordPress does not load or run them.

== Screenshots ==

== Changelog ==

= 1.1.7 =
* Move saved stocktakes into the separate Pro package. Keep partial receiving, immediate corrections and stored recovery evidence in Free.


= 1.1.6 =
* Use WordPress database APIs for transaction diagnostics and bind SQL query values throughout inventory, history and purchasing.
* Validate submitted inventory and purchasing arrays explicitly and use full prefixes for temporary workflow notices.
* Preserve permission refresh, transaction recovery and saved-stocktake retention safeguards.


= 1.1.5 =
* Refresh role definitions and user permissions before CSV workers continue stock changes.
* Preserve batch results referenced by saved stocktakes during daily and optional uninstall cleanup.
* Correct retention wording: all started batches, including completed results, remain available for recovery while active.

= 1.1.4 =
* Remove unused upstream PDF build/test files from the installer.
* Include the complete developer-only PDF rebuild recipe and pinned dependency lock.
* Clarify original-code and combined-package licensing.
* Keep the overview free of missing-table errors before the first large CSV import, while reporting incomplete import storage.

= 1.1.3 =
* Local PDF export supports more international names with an embedded Unicode font.
* Reviewed removal of safely finished large-import source data and results.
* Pro guides the next purchasing step using saved store information.

= 1.1.2 =
* Compact navigation alongside WordPress, with the branded sidebar available in optional Focus mode.
* More direct overview guidance and practical, clearly labelled Pro workflow examples.
* Correct current package versions and installation guidance in both editions.

= 1.1.1 =
* Distinctive directory name and text domain; existing stock data keys remain compatible.
* Enqueued purchase-order print styling, optional focus mode and reduced upgrade promotion.

= 1.1.0 =
* New Studio workspace with grouped navigation, local appearance settings and responsive layouts.
* Clearer stock priorities and local examples of Pro planning and team workflows.
* Existing stock reviews, permissions and update behavior are preserved.

= 1.0.1 =
* Harden request sanitization and prepared SQL in Free and Pro.
* Preserve stock transaction freshness, nonce checks and contextual output escaping.
* Keep bundled translations available with WordPress just-in-time loading.

= 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.1.6 =
Replace Free first, then matching Pro without uninstalling. This revision corrects review findings in database query construction, form validation and temporary workflow prefixes while retaining existing stock and purchasing records.

= 1.1.5 =
Replace Free first, then matching Pro without uninstalling. This update fixes CSV permission refresh and preserves saved-stocktake review recovery. Stock, purchasing and saved counts are retained.

= 1.1.4 =
Replace Free first, then matching Pro without uninstalling. This packaging update preserves existing stock, purchasing and settings.

= 1.1.3 =
Replace Free first, then matching Pro without uninstalling. Import cleanup is optional and requires explicit review and confirmation. Existing stock and purchasing records are retained.

= 1.1.2 =
Updating 1.1.1: replace Free, then Pro if installed, without uninstalling. Both plugin folders are unchanged. For an old stockcontrols folder, follow the separate rename instructions in Installation. Back up and test on staging first.

= 1.0.1 =
Update Free first, then the matched Pro 1.0.1 package. Back up and test on staging; existing stock, purchasing and settings are retained.

= 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.
