Skip to main content

Bulk Edit Products

Overview​

The Bulk Edit module changes many products in one operation: prices, stock, dimensions, visibility, taxonomies and tax settings. It records every run in a history table with the previous values, so a run can be reverted within a retention window, and it can save a set of changes as a reusable preset.

It is for stores making catalogue-wide changes — a seasonal price move, a stock reset, a shipping-class correction — that would otherwise be done product by product.

Availability​

ItemValue
Module keybulk_edit
TierPremium
Entitlement keybulk_edit
Admin tabbulk-edit, under Operations
Enabled optionaiowc_module_enabled_bulk_edit (off until turned on)
REST namespaceaiowc/v1

Enabling the module creates the two tables below and seeds the settings row.

Settings​

Stored in a single option row, aiowc_be_settings, written once at enable time if it does not already exist. This module writes the row directly rather than through the shared settings helper, so there are no legacy per-key options to migrate.

KeyDefaultMeaning
max_products_per_edit500A run with more product ids than this is refused with too_many_products.
enable_undotrueWhether previous values are captured before a run, and whether undo is permitted.
undo_retention_days30Age beyond which an applied run can no longer be reverted.
editable_fieldsthe 20 fields belowThe fields the settings route reports as editable.

Editable fields​

regular_price, sale_price, stock_quantity, stock_status, manage_stock, weight, length, width, height, status, catalog_visibility, featured, categories, tags, sku, backorders, sold_individually, tax_status, tax_class, shipping_class.

Numeric fields accept an operation rather than only a literal value. Prices support set, increase_fixed, decrease_fixed, increase_percent and decrease_percent; stock quantity supports set, increase and decrease.

Admin screen​

The Bulk Edit tab is a placeholder. It renders a heading, an "Apply Bulk Changes" button and a one-row example table. No control on it is wired to a request and the page calls no endpoint, so the routes below are reachable only by calling the API directly.

How a run behaves​

POST /bulk-edit/apply runs synchronously inside the request. In order it: refuses an empty product list or an empty change set; validates the changes; refuses a list longer than max_products_per_edit; captures the current value of each changed field for every product when undo is on; writes a pending history row holding the fields, the product ids and the captured values; then applies the changes product by product, collecting per-product errors rather than aborting.

Undo reads the history row, refuses when undo is disabled, when the row is not applied, or when the row is older than undo_retention_days, and otherwise writes the captured values back.

REST API endpoints​

All routes are on aiowc/v1 and require manage_woocommerce, plus a REST nonce on cookie-authenticated requests. Unlike most modules here, these routes return their payload directly rather than wrapped in the shared response envelope.

MethodPathPurposeRequired args
POST/bulk-edit/applyApply a change set. Body carries productIds, changes and an optional presetId.–
POST/bulk-edit/productsList products matching a filter set. Body carries filters, limit (default 50) and offset.–
GET/bulk-edit/filter-optionsThe values available to build a filter with.–
GET/bulk-edit/editable-fieldsThe fields a run may change.–
GET/bulk-edit/historyPast runs; accepts limit, offset, status.–
POST/bulk-edit/undo/{id}Revert one applied run.id
GET/bulk-edit/presetsList saved presets; accepts search.–
POST/bulk-edit/presetsCreate a preset.–
GET/bulk-edit/presets/{id}Read a preset.id
PATCH/bulk-edit/presets/{id}Update a preset.id
DELETE/bulk-edit/presets/{id}Delete a preset.id
GET/bulk-edit/settingsRead the settings above.–
POST/bulk-edit/settingsUpdate the settings above.–

WooCommerce integration​

The module registers no storefront hooks, no shortcodes and no blocks. Every product write goes through the WC_Product API — wc_get_product() and the product setters — so changes respect WooCommerce's own data layer.

Database schema​

TableHolds
{prefix}aiowc_bulk_edit_presetsSaved change sets.
{prefix}aiowc_bulk_edit_historyOne row per run: preset, user, product count, the fields changed, the product ids, the captured previous values and the run status.

Background jobs​

BulkApplyJob exists and listens on aiowc_be_bulk_apply (batch size 50), but nothing schedules it: BulkApplyJob::schedule() has no caller, and the apply route does its work inline. In this release every bulk edit runs in the request that started it, which is what max_products_per_edit is guarding.

Entitlement limits​

bulk_edit is an on/off grant with no licence-side quota. The run size is bounded by max_products_per_edit, a store setting.

Health check​

The module reports a warning when its tables are missing, and otherwise reports that it is functioning normally.