// Changelog
What’s new in SaleCraft
Every release, newest first. The latest version is 1.1.21.
1.1.21 (2026-11-08)
- Installation guide matches the WPBay build without a code (WPBay review of 1.1.19, item 2, issue #94): the
Installation page, and so the offline guide (
documentation/index.html) and the Docs tab, still described the licence-screen gate in front of WooCommerce › SaleCraft that 1.1.19 removed. It now says SaleCraft opens on the Campaigns tab with the free features working straight away and a notice linking to Enter purchase code, and that the code is registered under Settings › Licence.docs/licensing.mddescribes the same flow for developers.
1.1.20 (2026-11-08)
- Undo of a cancelled quick change restores a product left half-applied (issue #93): a quick change saves what it will change, writes the product, then marks it changed. When the background work died between the write and that last step and the quick change was cancelled before the watchdog resumed it, undo only looked at products marked changed: a quick change holding only that product went straight to "Undone" and one with other products restored those but not it, so it kept the new price. Undo now also goes through these products and compares the saved record with the product's current values, as it does for the others: values that still hold what the quick change set go back, anything edited by hand since stays, and a product that was never written is left alone and marked skipped. Undo progress, the Undo button and the watchdog's restart of a stalled undo count them too. Cancel now stops a running batch after the product it has in hand instead of at the end of its slice, and an undo waits while a batch of the cancelled quick change is still queued or running, so it cannot finish before that batch's last write.
1.1.19 (2026-11-08)
- Free features work without a WPBay purchase code (issue #91): with no code registered, the WPBay SDK
replaced WooCommerce › SaleCraft with its "Register your product" form, so nothing else could be opened even
though the listing and readme say only the Pro features need a code. The SDK is now loaded with
no_activation_required, so it leaves the page alone. The code is entered on SaleCraft's own Licence screen (Settings › Licence card › Activate licence), which sends the SDK's own register request. While no code is registered, SaleCraft shows a notice that the Pro features are locked with an Enter purchase code link, and the Plugins row has an Activate licence link. The SDK's own "Your license is not active ... Please activate your license to use this product" warning is hidden for SaleCraft, since it said the opposite. Pro features and updates still need a registered code.
1.1.18 (2026-11-08)
- WPBay listing: daily licence check and video link (review of 1.1.15, item 3): the description and
docs/wpbay-listing.mdsaid that when WPBay cannot be reached the purchase code is checked again "within the hour"; the WPBay SDK checks once a day, so they now say the daily check tries again the next day (readme.txt's FAQ says the same, and the 1.1.7 changelog lines in readme.txt and CHANGELOG.md no longer say "in an hour"). The "Video tour" link in the WPBay descriptions now points to the demo video on YouTube instead of theVIDEO_URLplaceholder. The WPBay release kit also writeslisting-text/wpbay-description-rich.html, a standalone page with the feature images loaded from demo.braincraft.rs, to open in a browser and copy into WPBay's description editor as rich text.
1.1.17 (2026-11-08)
- Takeover attempts no longer use up restore retries (review of 1.1.15, finding 2): every failed attempt by a higher-priority campaign to take over a product counted as a failed restore of the yielding campaign. The watchdog repeats the takeover every few minutes, so after about 20 minutes the 4 automatic retries were spent before that campaign even ended, and a failed restore at its end only got the Retry restore button. The count now starts again from 0 each time a takeover attempt keeps the item applied, so the restore at the campaign's end gets its full set of automatic retries.
1.1.16 (2026-11-08)
- Ended campaign's failed restore blocks takeovers (review of 1.1.15, finding 1): if restoring a product
failed while a higher-ranked campaign was waiting for it and the yielding campaign then ended, its item was
failedon a completed campaign and no longer counted as a rival. The watchdog released the waiting campaign before retrying the restore, so it applied on top of the old sale price and recorded that as "before"; the retry then saw a changed value and gave up, and the product stayed on sale after both campaigns ended. A new campaign starting on the product after the failed restore did the same. Now an ended campaign's item that is still applied, applying, or failed to restore holds the product: any campaign wanting it waits ("Waiting for restore: ...") whatever its rank, until the restore succeeds or the merchant resolves it, and then applies to the original price.
1.1.15 (2026-11-08)
- WPBay listing matches the package (WPBay review, round 3, item 3): the description opens with a "Good to
know before you buy" box (purchase code required, connects to wpbay.com, Slack optional), has a table of what
the purchase code unlocks and what works without it, spells out what happens without a valid code (including
scheduled campaigns with slow-seller or Dokan rules being marked Failed), and lists every connection to WPBay
and Slack with when it happens and what is sent.
docs/wpbay-listing.mdadds a checklist for clearing any "no external services" wording from the WPBay product page, and the WPBay release kit says the same.
1.1.14 (2026-11-08)
- Overlap takeover keeps recovery data after a failed restore (WPBay review, item 2): when a higher-ranked campaign took over a product and restoring the yielding campaign's change threw (a save error), the item was still put on hold, which deleted its before/after journal, and the takeover applied on top. Now the yielding item stays applied with its journal and the winner's item waits ("Waiting for restore: ..."). The watchdog releases those waiting items on every run (every few minutes) so the takeover is tried again; if the yielding campaign ends first, its own restore retries from the kept journal and the product then goes to the winner. Products whose restore worked are taken over as before, and hand edits are still kept.
- When a campaign ends and restoring a product fails, that product is not handed to a campaign waiting for it until the restore succeeds, so the waiting campaign never applies on top of the ended one's price.
- A campaign's product list shows each product's regular price next to a sale price change ("Sale price: — → 278.99 (regular price 349.00)"), so the price the sale is off is visible.
1.1.13 (2026-11-08)
- Failed restores are retried (WPBay review 2, item 1): when a product could not be saved while a campaign
ended or a quick change was undone (a lock, a time-out), it stayed on its sale values for good: the item was
marked Failed and no later restore, undo or watchdog run looked at it again. Such an item now keeps its
before/after record and a count of failed tries. The watchdog retries it a few minutes later, up to three more
times, and logs each retry in the Activity tab. After that, a Retry restore button on the campaign and on
the quick change (and
POST /campaigns/{id}/retry-restore,POST /jobs/{id}/retry-restore, vendor routes too) tries again by hand. A retry restores only properties that still hold the value the campaign set, so a hand edit made in the meantime is kept. - Database version 7:
bcrs_cc_campaign_items.undo_tries. - Troubleshooting page: "A product could not be restored".
1.1.12 (2026-11-07)
- Full docs in Lite: Lite's Docs tab has every page and question, Pro ones included, with a "Pro" badge on each Pro page, section, table row and question. A Pro page says so under its title and links to the product page (braincraft.rs/products/salecraft), which is also where Lite's upgrade links go.
- The listing, readme and Licence page now say that registering or deactivating a WPBay purchase code also sends the site's admin email address to WPBay.
1.1.11 (2026-11-07)
- Repeating campaigns keep running without a licence: a series the merchant set up now runs through a licence lapse, run after run, until they unschedule or delete its next run. 1.1.8 skipped those runs (marked Failed) until the licence was valid again. Setting up or changing a repeat still needs the licence, and the editor says how to stop the series.
- Docs, readme and the WPBay listing text describe this.
1.1.10 (2026-11-07)
- Move a WPBay purchase code yourself (WPBay review, finding 4): once a code was registered the WPBay SDK hid its licence screen, so buyers had to ask support to move SaleCraft Pro to another site. A new Licence screen (WooCommerce › SaleCraft › Settings › Licence, and Licence on the Plugins screen) shows the registered code, masked, and a Deactivate on this site button. It sends the WPBay SDK's own revoke request; the code is removed from the site only when WPBay confirms, and if WPBay cannot be reached nothing changes.
- The Settings tab has a Licence card in Pro, linking to where the licence is managed (the new screen).
- Docs, the WPBay listing text and the WPBay installation steps describe moving the licence without a ticket; support is only needed when the old site no longer exists.
1.1.9 (2026-11-07)
- Documentation for WPBay only (WPBay review): the Licence, updates and connections page, the readme and this changelog describe only the WPBay purchase code, and the licence table lists only states a WPBay purchase can be in.
- The plugin header's Author URI is now https://braincraft.rs.
- The build fails if a file outside
wpbay-sdk/describes another store's licence.
1.1.8 (2026-11-07)
- Repeating campaigns survive a licence lapse (WPBay review): the next run of a repeating campaign is now always scheduled, whatever the licence state. A later run that comes due without a valid licence changes nothing and is marked Failed with the reason, and the series carries on by itself once the licence is valid again. Before, the series stopped for good.
- Editing a repeating campaign without the licence keeps its repeat rule (it used to be dropped silently). The rule can still be turned off; setting up a new or different one needs the licence. The editor says the repeat is kept.
- Slow-seller and Dokan store rules are known but locked without the licence: a stored campaign that uses them stays editable, and a run, preview or new campaign says the rule needs a valid licence instead of "Unknown field".
1.1.7 (2026-11-07)
- WPBay server errors no longer remove the purchase code (pre-submission review, #65): the daily licence check removed the stored purchase code, and locked Pro, whenever WPBay's reply wasn't a success, including 500, 502, 503 and 429 replies with a JSON error body. Now only a definite answer removes it: WPBay served the reply (2xx, or a 4xx other than 408, 425 or 429) and said the code is not valid, refunded, cancelled or for another product. Anything else keeps the code and checks again at the next daily check. The manual Check button no longer caches "invalid" for a day after a server error either.
1.1.6 (2026-11-07)
- Buyer documentation for each store: the Docs tab, the readme and the new illustrated guide now describe the package the buyer actually has: WPBay download, purchase-code registration and support steps.
- Illustrated guide inside the Pro zips:
documentation/index.html(every Docs page with screenshots and the FAQ),changelog.htmlandlicensing.htmlship in the plugin folder, so the guide the readme promises is there whichever store the zip came from. The build fails if a file the readme names, or a screenshot, is missing. - Getting help: a new section in Troubleshooting with what to send and where, for each store.
- The Pro zips' admin bundle is built from that store's docs.
1.1.5 (in progress)
- Licence and connections disclosed (WPBay review): a new Docs page, Licence, updates and connections, explains purchase-code activation, which features the licence unlocks, what happens when it is missing, invalid, expired or cannot be checked, and lists every connection to another server (WPBay licence, updates and optional deactivation feedback; optional Slack webhook). The readme, FAQ, Notifications docs and store listings no longer claim "no external requests".
docs/wpbay-listing.md: the licence and connections sections for the WPBay product page.- Tests pin that a running campaign still ends and restores, and Revert now still works, after the licence lapses.
1.1.4 (in progress)
- Import keeps repeating campaigns: export already saved each campaign's repeat rule, but import dropped it, so a weekly, fortnightly or monthly campaign came back as a one-off draft. Import now checks the rule the way the campaign editor does and keeps it; the check and the import list how each campaign repeats. A rule that fails the check, or that uses settings this version does not know, skips the campaign and says why. A later run of a series with a set number of runs keeps the runs it had left, and its last run comes in as a one-off, with a note. A site where repeating campaigns are not available imports a one-off and says so.
1.1.3 (in progress)
- Recovery reaches older campaigns: the watchdog that restarts stalled background work used to look at
only the newest 100 active campaigns and the newest 100 ended ones, so an older campaign left with applied
items and no restore queued was never picked up. It now reads only campaigns that still have work left,
oldest first, at most 100 of each kind per run, and remembers where it stopped (option
bcrs_cc_watchdog_cursor), so every campaign is reached within a few runs however many there are.
1.1.2 (2026-11-07)
- Partly saved changes stay restorable: when a product is saved but a later part of the same write fails (for example a brand change with WooCommerce Brands turned off), the saved changes stay on record and the item counts as applied, so Quick changes undo and campaign restoration put them back. Only properties that still hold the value SaleCraft set are restored, so manual edits made since are kept. Brand changes are now checked before the product is saved, so a missing Brands taxonomy fails with nothing written.
- Licences and updates: SaleCraft Pro activates with a WPBay purchase code and updates itself from WPBay, through the WPBay SDK. Until the store product IDs are filled in, the plugin works as 1.1 did, with no licence asked.
- Pro features: slow sellers, recurring campaigns, Reports and the dashboard widget, notifications, storefront badge, countdown and block, Dokan, and export/import need an active licence or trial.
- SaleCraft Lite for wordpress.org: a free edition built from the same code (
npm run build:lite) with the calendar, one-off campaigns, templates (Black Friday, Cyber Monday, weekend flash sale, clearance), overlaps and priorities, Quick changes, Activity, the lowest price label, the scheduled tasks card and Docs. The Pro files are left out of its zip entirely, its bundle is built from its own source, and it has its own wordpress.org readme and docs.npm run build:editionsalso makes the Pro zips for each store. - Lite and Pro side by side: activating Pro switches Lite off and keeps every campaign and setting; Lite does nothing while Pro is active.
- Deleting with "Delete all data" now removes every
bcrs_cc_option, so Pro settings left behind by a switch to Lite go too.
1.1.1 (2026-11-06)
- Product rules on one line: in the New campaign wizard and in Quick changes each rule now sits on one aligned line. The "Units sold" and "Last sold" values no longer wrap their unit text onto a second line, the remove button stays beside its rule, value boxes are as tall as the field chip, and the "Match all/any rules" choice sits level with its words.
- Translation template: the release package now builds the scripts before it writes
languages/bcrs-salecraft.pot, so the template holds every admin screen string, not only the PHP ones.
1.1.0 (2026-11-05)
- New name and layout: now SaleCraft – Sale Scheduler & Campaign Manager for WooCommerce. Tabs: Campaigns (opens
on the calendar), Reports, Quick changes (the bulk editor), Activity, Settings, Docs.
Plugin folder, main file, text domain and translation template are
bcrs-salecraft(wasbc-salecraft); the author is BrainCraft.rs. The Docs tab is self-contained: no links to an external docs site. - Settings tab: the lowest price label, Dokan vendor features and data on delete in one place, saved
together; the WooCommerce settings sections they used to be in now link to it. Other features add sections
through
bcrs_cc_settings_sections. - Export and import campaigns (Settings tab): save every campaign as a JSON file and import it on another site, for example from staging to live. Categories, tags, attributes and shipping classes are matched by slug, products by SKU, Dokan stores by login. The import is checked first and lists each campaign it must skip and why; imported campaigns are saved as drafts.
- Quick changes, restyled: products are chosen with chip-style rules, a one-line summary says what the change will do, and the preview shows each product's category, shop-style before and after prices and why any were skipped. The campaign editor's preview and change cards use the same look.
- Dashboard widget: the sales running now with revenue so far, the next ones to start, and links into SaleCraft, on the WordPress dashboard for store managers.
- Reports tab: every campaign that has run side by side, with revenue, orders and the change against the period before it, totals across them, sorting, and each campaign's full report.
- Slow sellers: two product rules. "Units sold" (at most / at least N units in the last N days) and
"Last sold" (more than N days ago or never, in the last N days, never) find products that stopped selling,
so a clearance campaign or bulk update can be built from them. They count paid orders net of refunds, like
the sale performance report, with or without High-Performance Order Storage, and count a Dokan checkout
split per vendor once. Figures are cached for an hour (filter
bcrs_cc_sales_rules_cache_seconds). - Notifications: email (to listed addresses or the admin email) and Slack (incoming webhook) when a
campaign starts, ends, is reverted, or did not run on time, each switched on separately under SaleCraft ›
Settings › Notifications, with a "Send test notification" button. Off by default. Messages give
the campaign, the event, the time in store time, the products affected and a link to the campaign. "Did not
run on time" is sent once per overdue start or end, with when it was due and when it was noticed. Slack
posts never wait for an answer, so a visitor's page load is not slowed. Filters
bcrs_cc_notification_messageandbcrs_cc_notification_channels; actionbcrs_cc_campaign_event. - Scheduled tasks card: the Campaigns tab shows whether the site's scheduled tasks are running: when they last ran, whether WP-Cron is on, the Action Scheduler version and the next campaign start or end. It turns into a warning, with a link to the cron setup docs, when they have not run for over an hour or a start or end is more than 15 minutes overdue. "Did not run" now says plainly why and that nothing needs undoing.
- Repeating campaigns: every week, every 2 weeks or every month, with an optional number of runs or last date, and one-click "Every weekend" and "Every Friday". Each run is its own campaign (own products, restore and sale performance); the next run is scheduled when one starts. Later runs show in the list and, outlined, on the calendar.
- Duplicate: copy a campaign into a new one, with past dates moved to the same weekday after today.
- Campaign templates: slow sellers, Black Friday, Cyber Monday, a weekend flash sale and clearance, each filling in the name, dates, discount and products in one click, all editable before saving. Slow sellers is a monthly one-week sale on products in stock that have not sold in 60 days (new arrivals left out), so slow stock is discounted and put back without anyone remembering to. A first-run screen on the Campaigns tab explains how a campaign works and offers the templates while there are no campaigns yet.
- Storefront: a product on sale in a running campaign shows the campaign's name in its sale badge and a
countdown to the end of the sale under the price (product pages by default, optionally product lists; only
in the sale's last days, 7 by default). A Campaign products block and
[salecraft_campaign_products]shortcode list a campaign's products, or those of every running campaign, in WooCommerce's own product grid. Classic and block themes, styled by the theme; settings in the Settings tab.
1.0.0 (2026-11-04)
First release.
- Bulk updates: choose products with rules (category, tag, attribute, price, stock, stock status, product status, on sale, dates, custom fields, IDs; nested all/any groups; published products only unless you include other statuses), change prices, stock, categories, tags and custom fields, preview every product before and after, run in the background, cancel, and undo.
- More product data: bulk updates and campaigns can also change status (published, draft, pending, private), catalog visibility, featured, reviews and menu order; backorders, low stock threshold and sold individually; shipping class, weight and dimensions; tax status and class; global attribute terms (add, remove, replace; attributes used for variations are left alone); WooCommerce brands; name, short description, description and purchase note (find and replace, add before or after, replace all) and SKU (find and replace, add before or after); upsells and cross-sells. All with the same preview, history and undo. Weight, dimensions, tax class, description and SKU go on variations when the rules match variations.
- Campaigns: the same changes with a start and an end in store time. Products are chosen at the start and restored at the end or on "Revert now". Hand edits made in between are never overwritten.
- Overlapping campaigns: a priority decides which campaign changes a product; the next one takes over when it ends. Overlaps are shown before scheduling.
- Variable products: rules can match whole products or individual variations.
- Dokan marketplaces: a Vendor rule to include or leave out stores, an optional opt-out vendors set in their store settings, a notice on the vendor's product page while a campaign has changed it, and optional vendor campaigns and bulk updates in the vendor dashboard, each switched on separately, for the vendor's own products only (prices, stock, categories, tags; store campaigns always come first). Sale performance counts a checkout Dokan splits per vendor once.
- Prices: set, change by percent or amount, remove the sale, rounding to a step or a .99-style ending, sale dates. A discount never raises a deeper sale already in place.
- Sale performance: every campaign that has run shows revenue, orders and units for the products it changed against the same length of time just before it, its best-selling products and a CSV export; the campaign list shows each campaign's revenue and change. Paid orders only, refunds taken off, with or without HPOS.
- EU lowest price (Omnibus): a history of every price change (hand edits, imports, REST, scheduled sales,
campaigns) and "Lowest price in the last 30 days" under the price of products on sale, on product pages or
everywhere, automatic for EU stores, with editable wording. Public function and hooks for other plugins
(
docs/integration.md). - Calendar: the Campaigns tab can show every campaign on a week or month calendar, as blocks spanning their dates in store time, coloured by status and stacked by priority; click one to open it.
- Activity log: who did what and when, with results and failures; retention from 30 days to always.
- Docs tab: the full documentation and FAQ inside the plugin, searchable, with a Docs link on the Plugins screen. Bundled, so it works offline.
- Reliability: batches restart on their own if a PHP time-out or fatal error stops them; a campaign whose window passes without scheduled tasks running is marked "Did not run" and changes nothing.
- Translation-ready (
bcrs-salecraft.pot). HPOS compatible. Deleting the plugin keeps its data unless you choose to delete it (WooCommerce › Settings › Advanced › SaleCraft). - Tested with WordPress 6.4–7.1, WooCommerce 8.0–11.2 and PHP 7.4–8.4.