Version History - Margin Master

Version History

A complete record of every Margin Master release

2026.910.33745
September 10, 2026

Added test coverage for menu navigation depth; Automatic restoration of known stamped identities; Enhanced error handling for automatic strategy backups.

User Interface

  • Improvement Added test coverage for menu navigation depth

    A new automated test verifies that all menu targets referenced in training lessons are within reach of the menu lookup system. The test analyzes the XAML structure to measure nesting depth and ensures no lesson tries to navigate to a menu that's too deeply nested to be opened programmatically.

  • Bug Fix Training tours now open nested menu fly-outs

    Training lessons that demonstrate nested menu options will now properly open those menus during lesson playback.

  • Bug Fix Training tours now open nested menu fly-outs

    Training lessons that walk through nested menu commands now properly open those menus so you can see what they're demonstrating.

  • Infrastructure Added test to prevent unreachable menu targets in lessons

    Added automated test that parses the main window XAML and validates that all menu items referenced in training lessons are within reach of the menu lookup logic. This prevents future lessons from targeting menus nested too deeply to be opened during playback.

Reporting & Exports

  • Improvement Splash screen handling during large export prompts

    The loading screen now properly hides when you're asked to confirm a large export, making the dialog easier to see and interact with.

  • Bug Fix Large Westlake Excel export confirmation dialog fixed

    When exporting more than 50,000 price changes to Westlake Excel format, you'll now see the confirmation dialog asking if you want to continue. Previously this would fail silently without completing the export.

  • Bug Fix Large Westlake Excel export confirmation dialog fixed

    When exporting large datasets (over 50,000 records) to Westlake Excel format, you'll now see the confirmation prompt asking if you want to continue, and the export will complete successfully after you confirm.

  • Bug Fix Error messages during Westlake export now display correctly

    If an error occurs during a Westlake Excel export, you'll now see an error message explaining what went wrong instead of the export appearing to do nothing.

Performance & Reliability

  • Improvement Enhanced error handling for automatic strategy backups

    Added defensive error handling to the auto-backup service's trigger method. When the system cannot read the backup setting due to database connectivity issues, it now logs a warning and skips the backup attempt rather than propagating the exception to calling code. This prevents unobserved task exceptions at startup and false error reports in save workflows.

  • Bug Fix Detect store identity contradictions at startup

    If you see a message saying your store settings don't match your database, the system will guide you to confirm the correct store information before continuing. This prevents pricing data from the wrong vendor being loaded into your database.

  • Bug Fix Auto-backup no longer causes false save failure messages

    You will no longer see "Failed to save strategy" error messages when your pricing strategies have actually saved successfully. This could happen when the database was slow to respond.

  • Bug Fix Automatic strategy backup no longer crashes when settings unavailable

    Fixed rare crashes during startup or misleading "Failed to save strategy" errors when automatic backups couldn't check their settings due to temporary database issues.

  • Bug Fix Auto-repair the specific license server failover identity

    If your store was affected by the August license server issue, the system will automatically restore your correct store identity on startup.

  • Bug Fix Organization ID now follows confirmed store identity

    When your store identity is validated, the system now ensures your organization settings match your actual store, not a previously incorrect one.

  • Bug Fix Protect About table from credential sync overwrites

    Database credential synchronization now preserves the About table's store identity when it contradicts incoming ApplicationSettings, rather than overwriting the database's own record. This ensures the independent evidence needed for startup validation remains intact until the user confirms the store through Store Configuration.

  • User Interface Improved Store Configuration warning display

    Warning messages in the store setup window now wrap to multiple lines so you can read the full explanation.

  • Infrastructure Store Configuration writes confirmed identity to About table

    When the user validates and saves store credentials through Store Configuration, those values are now recorded in the About table as well as ApplicationSettings. This ensures startup validation won't re-prompt for the same identity on every launch after a legitimate store change.

Infrastructure & Internal

  • Improvement Automatic restoration of known stamped identities

    Implemented automatic recovery for the specific license fallback case (Ace 33859) that affected 24 installations between February and August 2026. When this known stamped identity is detected on a database whose About table names a different vendor's store, the database's own store number is offered as a suggestion in the Store Configuration window, streamlining the correction process.

  • Improvement Database setup preserves contradicting About records

    Modified the database setup wizard to skip synchronizing store identity to the About table when a vendor contradiction is detected. This preserves the database's independent record of its own identity so the startup validation can detect the mismatch and prompt the user to resolve it.

  • Improvement Store Configuration now updates About table on save

    The Store Configuration window now records the user-confirmed store number and vendor in the About table after validation succeeds. This keeps the database's own identity record in sync with ApplicationSettings, preventing repeated prompts on subsequent launches after a legitimate store change.

  • Bug Fix Store identity contradiction detection at startup

    If your store settings were accidentally changed to another company's store number, the app will now catch this at startup and ask you to confirm your correct store information before proceeding.

  • Bug Fix Database restore now reports SQL Server errors immediately

    If a database restore fails, you'll now see the actual error message from SQL Server right away instead of waiting 30 seconds for a vague timeout message.

  • Bug Fix Demo database upload now blocks unsafe databases

    The "Update Cloud Demo Database" workflow now refuses to proceed if any provenance check fails, listing each specific failure reason before any backup is created. Previously, only the database name prefix was checked, which allowed customer data to be published.

  • Bug Fix Database restore file naming fixed for non-standard backups

    Database restores now work correctly even when the backup file name doesn't match the database name inside it, preventing conflicts with your live database files.

  • Bug Fix Strategy execution tracking disabled for demo databases

    Strategy runs on demo databases are no longer posted to the cloud analytics system. Previously, executions on demo databases (which contained real customer data until this fix) were being reported as store 99999's activity, leaking customer pricing strategies and dollar impacts.

  • Bug Fix Organization ID now updates when store identity is corrected

    When your store information is corrected, cloud sync settings will now automatically update to use your correct organization instead of keeping another store's settings.

  • User Interface Improved Store Configuration window message display

    Fixed the context message banner in the Store Configuration window to properly wrap long messages by replacing horizontal StackPanel with DockPanel layout. Messages explaining identity conflicts now display completely instead of being truncated.

  • Infrastructure Demo database provenance verification system

    Implemented DemoDataProvenancePolicy and DemoDataProvenanceReader to verify that demo databases are genuinely synthetic before publication. A database must pass all checks: correct naming prefix, presence of a synthetic-data marker (written only by the scrub script), no POS/server credentials, no connection strings, and no strategies imported from real stores. This was created in response to an incident where both demo databases were discovered to be real customer databases (Ace store 11325 and DIB store 3174) with only store identity changed, including plain-text SFTP passwords.

  • Infrastructure Demo database provenance verification system

    Created DemoDataProvenancePolicy and DemoDataProvenanceReader to verify that a database is provably synthetic before allowing it to be published as a demo database. The system checks four requirements: correct naming (MarginMaster_Demo_*), presence of a synthetic-data marker written only by the scrub script, no populated credential or store-identity settings, and no strategy names indicating imports from real stores (like "11325v0045-PS_imported"). All checks must pass before a database can be uploaded.

  • Infrastructure Upload gate in Demo Mode workflow

    Modified DemoModeWorkflowService to run provenance verification before backing up and uploading a demo database. If verification fails, the upload is blocked and a detailed message explains which checks failed. This prevents repeat of the September 2026 incident where real customer databases (Ace store 11325 and DIB store 3174) containing plain-text SFTP passwords were published to all Demo Mode users.

  • Infrastructure Strategy execution tracking guard for demo databases

    Added check to prevent strategy execution analytics from demo databases being posted to the cloud fleet tracking system. Previously, strategy runs on demo databases (which contained real customer data until this fix) were reported as store 99999's executions, mixing curated demo data with fleet statistics.

  • Infrastructure Demo database scrubbing script

    Added Invoke-DemoDatabaseScrub.ps1 PowerShell script that transforms a customer database into a safe demo database by regenerating all store-specific pricing and sales values from deterministic hashed seeds, removing POS imports and credentials, clearing real-store strategy artifacts, and writing the synthetic-data marker as the final step. The script is kept outside the shipped application's embedded scripts directory.

  • Infrastructure Demo database scrubbing script

    Added PowerShell script Invoke-DemoDatabaseScrub.ps1 that transforms a customer database into a safe demo database by regenerating all store-specific pricing and sales values from deterministic hashes, removing POS imports and credentials, blanking server addresses, and writing the synthetic-data marker as the final step. The script refuses to process any database not named "MarginMaster_Demo_*" and can verify that no values match the original source table.

  • Infrastructure Comprehensive test coverage for provenance verification

    Added 10 unit tests that pin the exact behavior of the provenance policy, including verification that the leaked Ace demo database as-it-was would be refused on every count except the name. Tests ensure all credentials found on leaked databases remain in the checked lists.

  • Infrastructure Comprehensive provenance policy tests

    Added test suite pinning the exact checks that failed on the leaked demo databases, ensuring every credential found on those databases (AFTPIP, AFTPUSER, AFTPPASS, MySql credentials, RSD server addresses, store contact information) remains in the checked lists. Tests verify that databases matching the leaked demos' exact state are refused on every count except the name prefix.

2026.909.40658
September 10, 2026

Menu command to reopen Strategy Execution Summary; Strategy execution summary can be reopened from menu; Rename Database window works on any database.

Strategy & Pricing

  • New Feature Menu command to reopen Strategy Execution Summary

    After running a strategy, you can now use Strategy > Show Strategy Execution Summary to bring back the results screen if you closed it. This lets you review the numbers, see which steps ran, and use the "Show Skus Not Priced" or "Show Skus That Changed" buttons without waiting for the strategy to run again.

  • New Feature Strategy execution summary can be reopened from menu

    After running a pricing strategy, you can now go to the Strategy menu and choose "Show Strategy Execution Summary" to bring back the results screen, even if you closed it. This lets you review the numbers, see which steps ran, and drill into the changes without running the strategy again. The menu option is only available after you've run a strategy since opening Margin Master.

  • Improvement "Show Skus NOT included in Strategy" now works as a composable filter

    After choosing "Show Skus NOT included in Strategy," you can now add departments, vendors, or any other selection and press Refresh to narrow down the unpriced items. The filter stays active until you clear it.

  • Improvement "Show Skus NOT included in Strategy" now persists as an active filter

    When you choose "Show Skus NOT included in Strategy," you can now add other filters like department or vendor and press Refresh to see unpriced items within that selection. The filter stays on until you clear it.

  • Improvement User-requested summary always shows regardless of settings

    If you've turned off automatic strategy summaries in settings, the new menu command will still show the summary when you ask for it—the setting only controls whether it pops up automatically after each run.

  • Improvement All pricing commands now respect the No Pricing Rule filter

    Set Future Price, Remove Decreases, and all exports now work correctly with the No Pricing Rule filter—they'll only affect the unpriced items you're viewing.

  • Improvement Strategy Execution Summary "Show Execution Log" renamed to "Show Execution Logs"

    The "Show Execution Logs" button opens the folder with detailed logs from all your strategy runs.

  • Bug Fix Delete Displayed Skus now works on the unpriced items list

    You can now delete the unpriced items if needed—the Delete Displayed Skus command is no longer blocked.

  • User Interface Summary command bypasses "show after run" setting

    If you've turned off the setting that automatically shows the summary after each strategy run, the new menu command still works—it knows you're asking for it specifically.

  • User Interface No Pricing Rule filter now shows its state clearly

    The "No Pricing Rule" filter now shows up either as a ticked BLANK in your PS Rule box (if you have one), or as a pill you can click to turn off. Press F12 to clear it along with everything else.

  • User Interface Filter appears in PS Rule selection box or as a pill indicator

    If you have a PS Rule box, the filter shows as a checked "BLANK" entry you can untick. Otherwise, a "No Pricing Rule" pill appears next to your selection tabs—click it to turn off the filter.

  • User Interface Command disabled until first run in session

    The command is grayed out when you first open Margin Master, with a tooltip explaining it will become available after you run a strategy. It stays available for the rest of your session, even if you close and reopen the summary multiple times.

  • User Interface Tooltip explains when menu item is disabled

    If the menu option is greyed out, hovering over it explains that you need to run a strategy first before the summary can be shown.

  • User Interface "Show Execution Log" renamed to "Show Execution Logs"

    The "Show Execution Log" button is now "Show Execution Logs" to clarify that it opens a folder with multiple log files.

  • Architecture Introduced NoPricingRuleFilterPolicy to centralize filter logic

    Added NoPricingRuleFilterPolicy class to define which column answers "did any step touch this SKU" (PSRuleHistory), which selection box should carry the filter, and the BLANK sentinel value. This ensures the on-screen filter, execution summary count, and Excel export always agree on what "no rule" means, preventing drift between different code paths.

Imports & POS

  • Improvement Store Identification in Import Progress Messages

    Import progress messages now always show a clear store identifier instead of displaying blank spaces for certain store types.

  • Improvement Merge duration now logged for diagnostics

    The support log now records how long each store's POS data merge takes to complete. This allows support staff to distinguish between slow merges (normal for large stores) and truly stuck operations, since the 10-minute command timeout meant both could appear identical in logs.

  • Improvement Merge Duration Now Logged for Support Diagnostics

    Added timing and duration logging for the POS-to-store-table merge operation. With a 600-second command timeout, support logs previously couldn't distinguish between a slow merge and a stuck one. Merge completion is now logged with elapsed time, enabling faster diagnosis of import performance issues.

  • Bug Fix Import Progress Now Updates During Long-Running Merge Operations

    If you're importing a large POS file, you'll now see the import progress through "merging POS data," "rebuilding SKU index," and "finalizing store data" steps instead of the screen appearing frozen on one line.

  • Bug Fix Progress updates now show during POS merge operations

    When importing large Compass stores, the progress screen now shows "merging POS data," "rebuilding SKU index," and "finalizing store data" as separate visible steps instead of appearing frozen during the merge.

  • Bug Fix Corrected store display name in Compass import progress

    Fixed a display issue where Epicor character-based stores showed "Processing Store Data" with a blank space instead of the store identifier. The progress message now uses the same effective store key shown in the main import loop, ensuring consistent labeling throughout the import process.

User Interface

  • Improvement Added tooltip explanation for disabled "Show Affected Items" button

    Hovering over the "Show Affected Items" button now explains that you need to select a step from the list above first, even when the button is greyed out.

  • Bug Fix Strategy summary drill-in buttons now display correct results

    Clicking "Show Skus Not In Strategy" or "Show Affected Items" from the strategy summary now correctly displays only the filtered items you requested, instead of showing all price changes.

  • Bug Fix Strategy Summary buttons no longer clipped at narrow widths

    All buttons in the Strategy Execution Summary are now visible and clickable, even when the dialog is resized smaller.

  • Bug Fix Strategy Summary dialog width corrected

    The Strategy Execution Summary window now opens wider so the Close button and other action buttons all fit on one line without wrapping.

  • Bug Fix Strategy Execution Summary dialog width increased

    When viewing the Strategy Execution Summary, all buttons now appear on one line and are fully visible without any wrapping or clipping.

  • Bug Fix Strategy summary action buttons no longer clipped

    All buttons in the strategy summary dialog are now fully visible and properly arranged, with no text overlap or clipping.

  • Bug Fix Strategy Summary drill-in results now stay on screen

    When you click "Show Skus Not In Strategy" or "Show Affected Items" in the Strategy Execution Summary, the grid now displays the items you requested instead of showing all price changes.

  • User Interface Dialog sizing refinement

    The width calculation now accounts for the measured space requirements: approximately 925 pixels for the six buttons and 300 pixels for the checkbox column. This ensures proper layout without clipping or overlapping elements.

  • User Interface Dialog size optimization

    The dialog dimensions were measured and calculated based on actual button requirements rather than estimated, ensuring the layout remains stable and readable at the new size.

  • User Interface Show Affected Items button tooltip now visible when disabled

    Hovering over the greyed-out "Show Affected Items" button now explains that you need to select a step first.

Infrastructure & Internal

  • New Feature Rename Database window works on any database

    If your database has a generic name like "OlderMM" or still says "MarginMaster3", you can now rename it to something that identifies your store (like "DIB_10368_Woodstock_Hardware_Epicor"). Margin Master suggests the name from your store information and you can edit it. The rename keeps a backup, so nothing is lost.

  • New Feature Rename any Margin Master database

    The Rename Database tool now works on any of your databases, not just the default "MarginMaster3" name. It suggests a name that identifies your store and you can edit it. Your connection switches automatically when you rename the database you're using.

  • New Feature Closed store detection with title bar indicator

    A red warning badge will appear in the title bar if your store number has been retired. Click it to see details and migrate to your current store number.

  • New Feature Comprehensive store number migration service

    The migration tool now moves all your pricing rules, margins, and exceptions to the new store number automatically, not just basic settings.

  • Improvement Database housekeeping moved to SQL Server Tools

    The database housekeeping tools (Optimize/Shrink, Reset Database, Run Maintenance Scripts) are now easier to find: open SQL Server Tools from File > Utilities and look in its Tools menu, right alongside Rename, Migrate and Delete Database.

  • Improvement Database utilities consolidated under SQL Server Tools

    All database tools are now together in File > Utilities > SQL Server Tools. Look in its Tools menu for Rename, Migrate, Delete, Optimize/Shrink, Reset Database, and Run Maintenance Scripts.

  • Improvement Database naming logic centralized and tested

    The convention for building a database name from store information (`{Vendor}_{StoreNumber}_{StoreName}_{POS}`) now lives in one tested place (`DatabaseNameBuilder` in `MarginMaster.Common`) instead of three hand-maintained copies that had drifted. The builder sanitizes each part, validates names against SQL Server's reserved words and character rules, recognizes generic/timestamped names (like "MarginMaster3" or "OlderMM_20260909_160718") that identify no store, and generates unique names when the base name is already taken. This is shared by the Create New Database window, the Rename Database window, and backup file naming, so they always agree on what counts as a valid name.

  • Improvement Force-refresh organization store list for status checks

    GetOrganizationStoresAsync gains a forceRefresh parameter that drops the 30-day cache entry before fetching. Required for closed-store detection since a store retired last week would otherwise report as open for a month. The store identity health check uses this flag to ensure StoreStatus reflects current cloud state rather than stale cached data.

  • Bug Fix Fixed store scope tokens silently skipped during renumbering

    The previous implementation only matched store scope tokens followed by a pipe character (StoreNumber~3605|), causing it to miss tokens in the last position of a rule — precisely the most common shape for per-store pricing rules. Rules scoped to a single store were the most likely to be missed, leaving stores operating under retired numbers. The new StoreScopeTokenRewriter correctly handles tokens at any position including end-of-string.

  • Bug Fix Prevented accidental SKU and price corruption during store renumbering

    Store renumbering previously used a simple string replacement (Replace("3605","10368")), which would silently corrupt any SKU, product group, cost, or margin value that happened to equal the old store number. The new token-based rewriter anchors every change to the "StoreNumber~" prefix, ensuring only actual store scope tokens are modified while leaving all pricing data untouched. Includes 17 new tests specifically guarding against distinct corruption scenarios.

  • Bug Fix Fixed idempotence flag that caused store conversion to re-run on every import

    The EpicorStoreMapStrategiesConverted flag was being written back as "false" instead of "true", causing the entire store number conversion to re-run on every Epicor extract. This was harmless only as long as no store number was ever reused. The flag now correctly latches after successful conversion, and the conversion process properly tracks and logs the number of rules changed.

  • Bug Fix Store identity repair for organizations with multiple or zero open stores

    If your organization has multiple stores, the tool will ask you to confirm which one is correct rather than guessing.

  • Bug Fix Renaming the active database now switches the connection before dropping the old name

    When renaming the database Margin Master is currently connected to (which is allowed), the connection is switched to the new name *before* the old database is dropped. This is required because the drop runs `SET SINGLE_USER WITH ROLLBACK IMMEDIATE`, which would otherwise kill the app's own session. The Rename Database window warns when the selected database is the active one and offers to switch the live connection after the rename succeeds.

  • User Interface Rename Database Window replaces in-line rename flow

    Renaming a database now opens a window where you pick the database, see the suggested name, watch the progress, and get a clear result—no more jumping between message boxes.

  • User Interface Dry-run preview before migration

    Before changing your store number, you'll see a preview of exactly what data will be moved, so you can confirm the migration is safe.

  • User Interface Rename Database menu item no longer conditionally hidden

    The "Rename Current Database" menu item is now always available when you have a database open, regardless of its current name.

  • Database Store identity read from database for rename suggestions

    `IInstanceMigrationService.GetStoreIdentityAsync` reads vendor, store number, store name, and POS system directly from a database's `dbo.ApplicationSettings` table—independent of the running application's settings—so a name can be suggested for any Margin Master database on any instance, even one the app isn't connected to. This prevents the old problem where a rename suggestion depended on the *current* store's settings rather than the database's own identity.

  • Architecture Shared database copy service powers both rename and migration

    Database renaming and instance migration now share a common `CopyDatabaseAsync` service that handles backup + RESTORE-to-new-location + optional drop-source. This generalizes `InstanceMigrationService` so a migration is a copy with the name unchanged, while a rename is a copy to the same server under a new name. The service derives new physical file names from `RESTORE FILELISTONLY` rather than string-replacing the old database name inside the old file name, fixing cases where the .mdf was never named after the database in the first place (the MM-1458 backup was exactly that: database "OlderMM", logical names "MarginMaster2", physical files "DIB_3605_Woodstock_Hardware_Epicor"). This deletes the old `DatabaseRenameService`, whose string-replacement assumption was a no-op whenever the file and database names didn't match.

  • Architecture Shared database name builder prevents drift

    A new `DatabaseNameBuilder` class centralizes the database naming convention ({Vendor}_{StoreNumber}_{StoreName}_{POS}), validation rules, uniqueness logic, and generic-name detection. This logic was previously maintained in three separate hand-written copies (Create New Database, the old rename tool, and backup file naming) that had diverged over time—MM-1458 was the cost of that drift, where a Do-it Best store ran on a database called "OlderMM" and submitted backups that couldn't be identified. The Create New Database window, Rename Database window, and backup services now all use this shared implementation.

  • Architecture Centralized store number normalization to prevent inconsistent renumbering

    Store number comparison logic (leading zero handling) has been consolidated into StoreScopeTokenRewriter.NormalizeStoreNumber in MarginMaster.Common, shared by both WPF migration and DataImport. StoreIdentityRepairPolicy now delegates to this single implementation, eliminating the risk of half-applied renumbering caused by inconsistent "is this the same store" checks across different code paths.

  • Infrastructure Instance migration service extended for same-server renames

    `InstanceMigrationService.CopyDatabaseAsync` is the new general form behind both migrations and renames: it copies a database from one server+name to another server+name via backup and restore, optionally dropping the source afterward. A rename is this operation with the server unchanged and drop-source enabled. The restore step now relocates the physical .mdf/.ldf files to match the destination database name (via RESTORE FILELISTONLY and per-file MOVE clauses), so a renamed database gets files named after its new identity rather than keeping the old MarginMaster3.mdf forever.

  • Infrastructure Training lesson audio and documentation updated

    The sample training lessons for "menu-bar" and "reset-stale-data" have been re-rendered to reflect the menu structure changes (the rename tool now being available for all databases, and the housekeeping tools moving to SQL Server Tools). The SQL Server Setup Window documentation has been updated to describe the new Tools menu and the Rename Database window.

2026.909.20833
September 9, 2026

Antivirus and endpoint security exclusions documentation; Background download progress reporting; Background update download with progress callback.

User Interface

  • Improvement Background update download with progress callback

    Enhanced the AutoUpdateService.DownloadUpdatesInBackgroundAsync method to accept a progress callback parameter, allowing callers to receive percentage updates during the download. Progress events are marshaled from background threads to the UI dispatcher, with duplicate percentage values filtered to avoid unnecessary UI updates.

  • User Interface Update download progress indicator

    You'll now see a blue "Installing update…" badge with a percentage in the title bar while updates download in the background. You can keep working normally—nothing restarts until the green "Update Ready" button appears.

  • User Interface Clarified update badge meanings

    The blue "Update Available" badge now means a download failed and clicking it will retry—it's not shown during active downloads anymore.

  • Infrastructure Update progress tracking across startup and manual check flows

    Added update download progress tracking to three code paths: the automatic update timer task (ExecuteAutoUpdateTaskSafeAsync), the snoozed update pill surfacing (SurfaceSnoozedUpdatePillAsync), and manual update checks (CheckForUpdatesAsync). Each path now shows the downloading pill with percentage updates and properly clears it in a finally block to prevent stuck UI state if downloads fail.

Performance & Reliability

  • New Feature Antivirus and endpoint security exclusions documentation

    A new help document is available for your IT staff that explains which folders and files to exclude from antivirus scanning to prevent update and startup problems.

  • Bug Fix Startup update operations now bounded with timeout protection

    If the update server doesn't respond during startup, Margin Master will now give up after a reasonable time and open normally instead of staying stuck on the splash screen. The automatic hourly check will retry the update in the background.

  • Architecture Progress-based stall detection for update downloads

    Introduced DownloadStallWatch, a state machine that monitors download progress signals to distinguish between slow-but-working transfers and genuinely stalled connections. It tracks consecutive seconds without progress rather than total elapsed time, ensuring slow stores can still complete updates while preventing indefinitely stalled transfers from blocking startup. The 90-second threshold was chosen because Velopack's progress callback fires frequently, so prolonged silence indicates bytes have stopped arriving. Comprehensive unit tests validate both thresholds—never abandoning working downloads and always abandoning dead ones.

  • Infrastructure StartupUpdateGuard service wraps bounded update operations

    Created StartupUpdateGuard to encapsulate all timeout logic for startup-path update operations, using TaskTimeoutHelper to race operations against their timeouts and DownloadStallWatch for progress monitoring. The service separates timeout handling from update logic and makes the decision-making testable in isolation. When operations are abandoned, they're allowed to finish or die in the background since Velopack writes to temporary files that the next attempt purges.

Infrastructure & Internal

  • Improvement Background download progress reporting

    Modified DownloadUpdatesInBackgroundAsync to accept an optional progress callback and pass it through to the underlying DownloadUpdatesAsync method. All three silent download call sites (periodic timer check, startup snoozed-update path, and background download after check) now light the pill with percent-complete updates. Each caller clears the pill in a finally block so failed downloads cannot strand the indicator, and SetUpdateDownloadingPill swallows dispatcher errors to prevent masking real exceptions.

  • Bug Fix Corrected misleading XAML comment

    The blue "Update Available" pill now correctly means a download failed and needs to be retried, while the new "Installing update…" pill shows when a download is actively running.

  • User Interface Update download progress indicator

    When Margin Master downloads an update in the background, you'll now see a blue "Installing update…" pill in the title bar showing progress percentage. This lets you know the app is working on fetching a new version, not just running slowly.

  • Infrastructure Update documentation for download visibility

    Updated banners-and-badges.md and update-modes.md to document the new "Installing update…" pill, clarifying the distinction between actively downloading (blue pulsing pill with percent), download complete and ready to apply (green "Update Ready" pill), and download failed (blue "Update Available" pill). Added search keywords for users looking to understand why Margin Master is downloading or showing update progress.

2026.908.35163
September 8, 2026

"Show Skus Not In Strategy" button on execution summary; Export not-priced items to Excel with reason column; "Show Skus Not In Strategy" button on execution summary.

Strategy & Pricing

  • New Feature "Show Skus Not In Strategy" button on execution summary

    Click "Show Skus Not In Strategy" on the summary screen to see the items your strategy didn't select—no need to hunt through the menus.

  • New Feature Export not-priced items to Excel with reason column

    Export the full not-priced list to Excel with a Reason column that tells you what to fix for each item. The file isn't limited by your display records setting, so you get the complete list.

  • New Feature "Show Skus Not In Strategy" button on execution summary

    The execution summary now has a "Show Skus Not In Strategy" button that opens the list of items your strategy didn't select, so you can go straight from the number to the actual items.

  • New Feature Export not-priced items to Excel with reasons

    You can now export the complete list of not-priced items to Excel from the execution summary or the Strategy menu. The export includes a Reason column explaining why each item was left alone, and it's not limited by your maximum display records setting.

  • Improvement Strategy Execution Summary reworded "Items not priced" line

    The summary now says clearly that unpriced items are not an error—your strategy just didn't select them. It shows how many had no cost versus how many weren't selected by any step.

  • Improvement Zone override editor with clear button and validation

    The zone override field now has a clear button to remove overrides, and won't let you save a zone number that doesn't exist in the pricing data.

  • Improvement "Show Skus NOT included in Strategy" is gated until a strategy has run

    The "Show Skus NOT included in Strategy" menu item is now disabled until you've run a strategy at least once. If the list is empty after a run, you'll see a message explaining that every item was priced.

  • Improvement Automatic repair of invalid zone overrides during sync

    After each sync, the system automatically fixes any stores with invalid zone overrides and reports which stores were corrected in the import log.

  • Improvement Added logging for zone pricing failures

    Zone pricing operations now log when a store's zone override points to a zone with no data, making it much easier to diagnose pricing issues. Previously these failures were completely silent.

  • Improvement Strategy Execution Summary rewords and explains "Items not priced"

    The execution summary now explains that "Items not priced" is normal, not an error—it just means your strategy's steps didn't select those items. The line shows how many were skipped because no step selected them versus how many have no cost.

  • Improvement Zone Pricing Failure Now Logged and Reported

    If a store somehow ends up with a zone that has no pricing data, you'll now see a clear warning in the import results instead of the problem being silent.

  • Improvement "Show Skus NOT included in Strategy" only available after a strategy run

    The "Show Skus NOT included in Strategy" menu is greyed out until you've run a strategy—before that, nothing has been priced yet so the list would be meaningless.

  • Improvement Empty "Show Skus NOT included in Strategy" grid now explains itself

    If the not-in-strategy screen is empty, you'll see a message confirming that every item was covered—not just a blank grid.

  • Improvement Execution log reworded unpriced section

    The detailed strategy log file now says "ITEMS LEFT WITHOUT A NEW PRICE: N" instead of "SKUS WITH NO PRICING RULE," and explains "Not an error—the strategy's steps did not select these items." It logs the NoRuleCount separately ("N were touched by no step at all (PSRuleHistory is empty). This is what Strategy > Show Skus NOT included in Strategy loads.") so a support reader can reconcile the grid's row count against the file.

  • Bug Fix Zone Override Validation on Store Manager Screen

    When entering a zone override for a store, Margin Master now checks that the zone number you typed is valid before saving it. If the zone doesn't exist, you'll see an error message and the value won't be saved.

  • Bug Fix Zone override validation prevents invalid pricing zones

    Stores with invalid zone overrides will now show an error when you try to enter them, and the system will automatically fix any existing invalid overrides during import.

  • Bug Fix Zone Override field now rejects invalid zone numbers

    If you try to enter a zone number that doesn't exist in your vendor catalog, the system will now warn you and prevent the save. You can also click the X button to clear a zone override completely.

  • Bug Fix "Show Skus NOT included in Strategy" now identifies the correct items

    The "Show Skus NOT included in Strategy" screen now shows the correct list of items your strategy didn't select. Previously, if your strategy had a catch-all step, some items were missing from the list.

  • Bug Fix Automatic repair of stores with invalid zone overrides

    Stores that previously had broken zone overrides (showing zero or invalid zone numbers) will automatically have those bad values cleared, restoring correct zone pricing.

  • Bug Fix Automatic Repair of Invalid Zone Overrides

    If a store has a zone override set to a zone number that doesn't have any pricing data, the system will automatically remove that override during sync and let the store use its assigned zone. You'll see a note in the import results if this happens.

  • Bug Fix Zone Resolution Fallback Logic

    Stores with invalid zone numbers stored from before this fix will now correctly use their Ace-assigned zones instead of pricing at "zone 0."

  • Bug Fix Zone pricing now reports configuration issues for invalid zones

    If a store's zone has no pricing data, you'll now see a clear warning in the import report instead of pricing silently being skipped.

  • Bug Fix "Show Skus NOT included in Strategy" now counts correctly

    The "Show Skus NOT included in Strategy" list now shows all items no step touched, even when your strategy has a catch-all step—it was undercounting before.

  • Bug Fix Model-level fallback for non-positive zone values

    Updated StoreManagerInfo.EffectiveZone to treat zero or negative zone values as "not set" and fall through to the assigned zone, then to national zone 99999. Previously a stored zero was honored as a valid override, resolving to pricing zone "0" which matched no records.

  • Bug Fix "Unlimited" maximum display records now works correctly

    When you set maximum display records to "Unlimited," grids will now actually load all records instead of stopping after just one row.

  • Bug Fix "Unlimited" maximum display records now works

    Setting Maximum Display Records to "Unlimited" now actually loads all records instead of stopping at one.

  • User Interface Clear Button for Zone Override

    You can now click the X button in the Zone Override box to remove an override and let the store use its regular Ace-assigned zone. Before, there was no way to clear an override once entered.

  • User Interface Strategy Execution Log enhanced with not-priced breakdown

    The execution log's unpriced section now reports the NoRule subset separately from the total, labels both populations by what they mean, and names the menu path that reaches them, so a support reader can reconcile the grid's row count against the file.

  • User Interface Strategy Execution Summary layout additions

    Added "Show Skus Not In Strategy" and "Export Not Priced" buttons to StrategyExecutionSummaryView.xaml, shown only when HasUnpriced is true. The view model raises their CanExecuteChanged when HasUnpriced changes via POCO convention. Both buttons set request flags (ShowNotInStrategyRequested, ExportNotPricedRequested) and close the dialog so the grid or export runs without a modal in the way, matching the "Show Affected Items" pattern.

  • Database Unpriced report now tracks three counts per table

    UnpricedSkuTableCount gained a NoRule field—the subset of unpriced rows with an empty PSRuleHistory trail. This is what "Show Skus NOT included in Strategy" loads, reported separately from the total unpriced count (which also includes rows a step claimed but could not price) so the summary can quote the number the grid will actually match.

  • Architecture Unpriced predicates unified into shared helpers

    The execution summary report, the grid loader, and the export were three hand-written WHERE clauses selecting the "not priced" population, and they had already drifted. They are now RoundingSql.NoRuleTouchedPredicate(), UnpricedPredicate(), and UnpricedReasonSql(), interpolated by every reader, so the number the summary quotes and the rows the grid and export load cannot disagree. UnpricedSkuReport gains NoRuleCount so the summary can quote the subset the menu item actually loads, separately from the unpriced total.

  • Infrastructure Shared predicates for unpriced/not-touched queries

    Added RoundingSql.NoRuleTouchedPredicate(), UnpricedPredicate(safeCostSql), and UnpricedReasonSql(safeCostSql) helpers. The unpriced report, the grid loader, the export, and the execution log all call the same expressions, so the counts can never drift. Comprehensive tests in NoRuleTouchedPredicateTests, UnpricedPredicateTests, and UnpricedReasonSqlTests lock the predicates' shape and their relationship (no-rule is a strict subset of unpriced; the predicates are complements across the main table).

  • Documentation Updated "Reviewing a Strategy" guide

    Documented the reworded "Items not priced" line, the new summary buttons, why the menu item is greyed out before a run, the export format and Reason column values, and the distinction between the full unpriced total and the no-rule subset. Added three common questions covering the rewording, the count difference, and how to get the list into Excel.

Imports & POS

  • Improvement Clear messaging for missing import layouts

    If you see an empty import file list, you'll now see a message explaining why and how to fix your POS system settings.

  • Improvement Enabled chunked writes for MySQL Compass inventory imports

    Large MySQL Compass inventory imports (10,000+ items) are now processed in smaller batches to prevent timeouts.

  • Improvement Chunked write operations reduce database blocking

    Inventory writes are now split into batches of 5,000 items with 100ms pauses between batches, matching the proven approach used for Epicor imports. This prevents large imports from being blocked by other database activity and exceeding timeout limits. Previously, all items were written in a single uninterrupted stream which could be blocked past the timeout threshold on busy servers.

  • Improvement Added transient retry logic for MySQL Compass bulk merge operations

    Wrapped the BulkMergeAsync call with SqlTransientRetry to handle command timeouts (-2), which are typically caused by momentary database blocking. Since the merge operation uses the primary key, re-running is safe. This prevents one-off timeout failures from aborting the entire import.

  • Improvement Corrected logging severity for missing import layouts

    Changed the severity of missing import layout messages from Error to Warning, since this is a configuration condition rather than a defect. These warnings are now reported through the store configuration issue collector to notify the appropriate person, while keeping the error dashboard clear of configuration-related messages.

  • Bug Fix Added retry limit for failed MySQL Compass inventory blocks

    If a MySQL Compass inventory import fails repeatedly on the same batch of items, you'll now see an error message after 3 attempts instead of the application appearing frozen.

  • Bug Fix Import no longer retries failed blocks indefinitely

    If a Compass inventory import encounters repeated database errors, you'll now see a clear error message instead of the import hanging indefinitely.

  • Bug Fix Import dialog now explains why file list is empty for unsupported POS types

    If your POS system type isn't supported, the Import Manager now shows a message explaining why no files appear instead of just showing an empty list.

  • Bug Fix Prevented redundant error logging for missing import layouts

    Fixed a memoization bug where failed POS type lookups were never cached, causing the same error to be logged repeatedly. Store 1918 generated 23 identical error reports in 15 minutes by reopening the import dialog. The lookup result is now cached per service instance regardless of success or failure.

  • Bug Fix Reduced duplicate error logging for missing layouts

    Fixed an issue where the system logged the same "no import layout" error up to 23 times when checking import files for a POS type without a layout. The system now checks once per session and reports configuration issues through the proper channel instead of flooding error logs. This particularly affected stores on POS systems like Spruce that don't yet have import layouts.

  • Bug Fix Corrected connection pooling for bulk inventory writes

    Switched to non-MARS (Multiple Active Result Sets) connection strings for MySQL Compass bulk writes to prevent connection interleaving issues. This resolves timeout failures that occurred when bulk copy operations competed with other active queries on the same connection, which was the root cause of failures at specific high-volume stores.

  • Bug Fix Import layout folder no longer created unnecessarily

    Fixed an issue where listing import files for a POS type would create empty directories in the application folder even when no layout existed for that POS system. These orphaned folders accumulated during updates. The system now only reads existing layout directories without creating new ones.

  • Bug Fix Switched to non-MARS connection for MySQL Compass inventory imports

    Changed from ActiveConnectionString to ActiveConnectionStringNoMARS to match the convention used by sibling dw_item imports. MARS (Multiple Active Result Sets) was causing the bulk copy to interleave with other database reads on the same connection, contributing to batch timeout failures at store 17201.

  • Bug Fix Stopped probing for "Unknown" POS type import layout

    The system no longer attempts to load an import layout when the POS type is "Unknown", which is the sentinel value for "not configured yet". This eliminates unnecessary lookups and prevents logging errors during application startup before store settings finish loading.

  • Bug Fix Prevented folder creation when listing import mapping files

    Fixed MappingFilesForPOS to return an empty list when the layout folder doesn't exist instead of creating it. Previously, this created empty Unknown\ and Spruce\ directories in the Velopack "current" folder for any store whose POS had no layout, which were then orphaned after updates.

  • User Interface Added clear error notifications for repeated MySQL Compass import failures

    If a MySQL Compass import fails repeatedly, you'll now see a clear error message explaining what happened instead of a progress bar that never completes.

2026.907.33451
September 7, 2026

Enhanced update check logging; Update check activity now logged for diagnostics; Periodic update checker now arms on every launch.

Performance & Reliability

  • Improvement Enhanced update check logging

    Added log entry "Periodic update check armed — next check in {Interval}" when the update timer starts, making it possible to verify from customer logs whether the checker is alive. Previously it was impossible to distinguish between "checked and found nothing" and "never armed at all."

  • Bug Fix Periodic update checker now arms on every launch

    Margin Master will now correctly check for and download updates every hour while running, ensuring you get bug fixes and improvements as soon as they're available instead of waiting until you restart the app.

  • Bug Fix Update timer cleanup improvements

    StopAutoUpdateTimer now properly disposes the cancellation token source and clears all task references. The run loop re-reads the timer field each iteration to handle mid-loop disposal or replacement, preventing potential race conditions when updates are applied or timers are restarted.

Infrastructure & Internal

  • Improvement Update check activity now logged for diagnostics

    Added logging when the periodic update checker is armed, including the configured check interval. This makes it possible to verify from customer logs whether the background checker is running, distinguishing between "checked and found nothing" versus "never started checking" scenarios.

  • Bug Fix Periodic update check now starts correctly on every launch

    Fixed a defect (MM-1454) where the automatic update checker would not activate when the application was launched normally. The issue was caused by pre-creating a timer object in the constructor without a consumer task, which made the startup guard incorrectly believe a checker was already running. The guard now properly tests whether the background check task is active, ensuring updates are discovered automatically every hour rather than requiring a manual restart to pick them up.

  • Bug Fix Auto-update timer lifecycle management improved

    Enhanced cleanup of update checker resources to properly dispose of cancellation tokens and clear background task references. This ensures the checker's running state is accurately reflected and prevents resource leaks during timer restarts.

2026.906.25226
September 6, 2026

Azure SQL detection prevents unnecessary shrink operations; Daily automatic optimization disabled on Azure SQL; Optimize/Shrink Database dialog updated for Azure SQL.

Performance & Reliability

  • Improvement Azure SQL detection prevents unnecessary shrink operations

    If you use Azure SQL to host your Margin Master database, optimization now runs faster and generates less transaction log activity. You won't be charged for larger backups caused by unnecessary shrink operations.

  • Improvement Daily automatic optimization disabled on Azure SQL

    On Azure SQL, Margin Master no longer runs automatic database optimization at startup, preventing unnecessary delays when opening the application.

  • User Interface Optimize/Shrink Database dialog updated for Azure SQL

    When you run Optimize/Shrink Database on Azure SQL, the dialog clearly explains that the shrink step will be skipped and asks if you want to rebuild indexes and update statistics instead.

  • User Interface Optimize Database Indexes reports Azure SQL shrink skip

    The "Optimize Database Indexes" command now reports "shrink skipped: Azure SQL" in its completion summary when running against an Azure SQL database, making it clear that the shrink step was intentionally omitted rather than failed.

  • User Interface Shrink Log Files script removed from Azure SQL maintenance menu

    If you use Azure SQL, the Shrink Log Files option will not appear in the Run Maintenance Scripts menu since it doesn't apply to cloud-hosted databases.

  • Infrastructure Database optimization policy unit tests added

    New DatabaseOptimizationPolicyTests pin the Azure SQL detection and shrink-skip behavior with comprehensive unit tests covering Azure SQL Database, Azure SQL Managed Instance, on-premises SQL Server editions, and failed version detection scenarios. The tests ensure that a failed version lookup always preserves on-premises behavior.

  • Infrastructure Documentation updated with Azure SQL section and daily optimization details

    The SQL Optimization documentation now includes a dedicated "Azure SQL" section explaining the shrink skip behavior, documents the automatic daily optimization pass (previously undocumented), and corrects the step order to reflect that shrinking happens before index rebuild (a code change from 2026-08-20).

2026.904.35423
September 5, 2026

One-click settings folder repair; Settings folder repair dialog features; Settings folder permissions documentation.

Cloud Sync & Vendor Data

  • New Feature Added POS import divergence detection and warning

    If your "Last Import" date doesn't match the import history in the grid below it, you'll now see a warning explaining the discrepancy and suggesting you import again.

  • New Feature Point-of-sale data divergence warning added

    The Data Aging screen now warns you when the POS import date and import history don't match, just like it does for vendor syncs.

  • Improvement Rewrote divergence warning messages to report gaps, not verdicts

    Warning messages on the Data Aging screen now say when Margin Master couldn't confirm a sync result, rather than claiming your data didn't update when it may have.

  • Improvement Divergence warning messages revised to report facts, not verdicts

    Warning messages on the Data Aging screen now explain that your catalog may already be up-to-date even when dates disagree, rather than claiming the sync failed.

  • Bug Fix Fixed "Last Synced" date advancing for failed or empty syncs

    The "Last Synced" date on the Data Aging screen will no longer move forward unless your vendor catalog data actually updated or was confirmed current.

  • Bug Fix Last Synced date no longer advances when no tables ran

    The "Last Synced" date on the Data Aging screen will no longer move forward after a sync that didn't actually run any tables.

  • Bug Fix Made sync statistics failures visible without being fatal

    If a sync merges your data but can't record the result, you'll now see a notification explaining that your catalog is up to date but the history won't show it until the next successful sync.

  • Bug Fix Last Synced date requires all tables to succeed when no rows moved

    If a vendor sync finds no changes but some tables failed, the date will no longer incorrectly advance, preventing stale data from appearing up-to-date.

  • Bug Fix Sync bookkeeping failures reported separately and no longer block date stamp

    If vendor data syncs successfully but cannot be recorded in the history, you'll see a notification explaining that your data is current even though the sync history looks out of date.

  • Infrastructure Added comprehensive tests for sync outcome rules

    Created VendorSyncOutcomePlannerTests with 7 test cases pinning the rule for when a sync should update the "Last Synced" date, and DivergenceMessageWordingTests that reads the view model source to verify the warning messages never claim the sync failed to update data when only the bookkeeping failed. The tests document the actual store incidents (5645 and 554) that led to this fix.

  • Infrastructure Sync outcome decision logic extracted and unit tested

    Created VendorSyncOutcomePlanner as a pure, tested function to decide whether a sync result should stamp the "Last Synced" date. Includes 169 lines of unit tests covering the empty result, partial success, and "already current" scenarios that previously produced incorrect stamps.

User Interface

  • Improvement Added export and import path properties

    Added ExportPath and ImportPath properties to CostBreakViewModel that provide initial directory paths for file dialogs, resolved through the application settings service. These properties ensure file dialogs open to the user's preferred locations.

  • Bug Fix Fixed Price toggle now works in Cost Break levels

    You can now use the Fixed Price checkbox in cost break levels—it will correctly display existing settings and save your changes. The Fixed Price and Margin % fields now appear and disappear as expected based on the toggle.

  • Bug Fix Fixed broken data bindings in Cost Break grid

    The Cost Break screen will now load cleanly without internal errors.

  • Bug Fix Restored level numbers in cost break grid right-click menus

    When you right-click on a cost break row, the menu options now correctly show the level number (e.g., "Delete Cost Break Level #3" instead of "Delete Cost Break Level #").

  • Bug Fix Removed non-functional Import and Set Default buttons

    The Export menu in the Cost Break screen no longer shows a non-functional Import option.

  • Bug Fix Rebuild button now applies Break Type and Break Points changes

    The Rebuild button beside Break Type and Break Points now works—click it to apply your changes when auto-rebuild is turned off.

  • Bug Fix Wired up the Rebuild button

    The Rebuild button in the Cost Break screen now works correctly to recalculate your cost break levels after changing Break Type or Break Points.

  • Bug Fix File dialogs now open to correct default locations

    When importing or exporting cost break models, the file browser now opens to your configured default import/export folder instead of a random location.

  • User Interface Removed two non-functional controls

    Removed a hidden "Set Default" button and an "Import Cost Break Models" menu item that were bound to commands that never existed. Both were carried over from other screens and could never work. Left comments documenting what would be needed to restore them if the features are implemented in the future.

Performance & Reliability

  • Improvement Simplified pricing unit reset mechanism

    The mechanism that snaps the plus/minus units selector back to "0" after rejecting a "Rounding Points" choice now uses a simpler, more reliable approach. Instead of managing timer lifecycle, the reset is scheduled as a deferred UI operation that runs once the combo box selection update has completed.

  • Improvement Future Price panel threading safety enhanced

    The Future Price panel's plus/minus units reset now properly executes on the UI thread using the WPF Dispatcher. This eliminates potential cross-thread exceptions that could occur when the old timer-based approach modified UI-bound properties from background threads.

  • Bug Fix Random crashes when editing Cost Break levels

    The Cost Break screen will no longer crash when you edit price levels rapidly or while calculations are running in the background.

  • Bug Fix Fixed crash when editing Cost Break pricing levels

    The Cost Break dialog will no longer crash when you quickly edit margin targets or cost boundaries.

  • Bug Fix Eliminated timer leak in plus/minus units selector

    The Future Price panel's plus/minus units selector was creating a new background timer on every selection change without properly disposing of previous timers. Each abandoned timer continued firing every 100ms for the entire application session, writing to UI-bound properties from background threads. This has been replaced with a single deferred dispatcher call that properly executes once on the UI thread with no lingering state.

  • Bug Fix Future Price panel timer memory leak eliminated

    Fixed a critical memory leak where the Future Price panel created a new System.Timers.Timer every time the user attempted to select "Rounding Points" in the plus/minus units dropdown. Each abandoned timer would continue firing every 100 milliseconds for the life of the application, gradually degrading performance. The reset mechanism has been replaced with a single deferred dispatcher call that safely resets the selection without leaking resources.

  • Bug Fix Cost Break boundaries incorrectly shifting by one cent

    When working with Cost Breaks, the price boundaries between levels will now stay exactly where you set them instead of drifting by one cent during automatic recalculations.

  • Bug Fix Fixed pricing boundary drift in Cost Break levels

    Cost Break pricing boundaries will now stay exactly where you set them instead of drifting slightly when the grid updates.

  • Bug Fix Memory leak from Cost Break background timers

    Closing a Cost Break window now fully releases system resources, improving overall application performance especially after opening and closing the dialog multiple times.

  • Bug Fix Fixed memory leak after closing Cost Break window

    Closing the Cost Break dialog will no longer leave background processes running, improving overall application performance.

  • Architecture Migrated Cost Break timers to UI thread

    Replaced System.Timers.Timer with DispatcherTimer throughout the Cost Break dialog to ensure all timer callbacks execute on the UI thread, eliminating threading hazards and making the dialog more stable during user interaction.

Infrastructure & Internal

  • New Feature One-click settings folder repair

    Click "Fix This Now" when you see the settings folder warning—Windows will ask permission, then Margin Master fixes it automatically and tells you to restart.

  • New Feature Settings folder repair dialog features

    The settings warning now shows exactly which files are blocked and gives you a "Copy Details" button to send the fix command to your IT department if you need help.

  • New Feature Settings folder permissions documentation

    Added comprehensive help page at marginmaster.com/documents/support/settings-folder-permissions covering what the alert means, how to use the Fix This Now button, the manual icacls command for administrators, why the problem happens, and common questions. The repair dialog links directly to this page.

  • Improvement Graded settings folder problems

    Old files left behind by previous Margin Master versions won't trigger the "Cannot Save Settings" warning anymore—only files the app actually needs will cause an alert.

  • Improvement Settings folder repair dialog with automatic fix

    When the settings folder alert appears, click "Fix This Now" and choose "Yes" at the Windows prompt — Margin Master will grant the permission and tell you to restart. If you'd rather have your IT department handle it, "Copy Details" gives them everything they need.

  • Improvement Self-healing release feed

    The publish workflow now automatically downloads and re-indexes any packages within the retention window that are missing from the remote feed, allowing the feed to repair itself if entries are lost. This ensures the delta chain remains complete even if previous publishes had issues.

  • Improvement Critical versus non-critical settings files

    You'll only see the settings folder alert when a file Margin Master actually uses is blocked — old files left behind from previous versions won't trigger it anymore.

  • Improvement Version comparison fixed for retention

    Package versions are now compared as semantic versions rather than strings, so version 2026.1001.x correctly ranks above 2026.903.x. Previously, string comparison could cause incorrect packages to be retained or pruned from the feed.

  • Improvement Updated startup stuck training lesson

    Revised the "startup-stuck" training lesson audio and script to describe the new Fix This Now button and clarify that only files Margin Master uses raise the alert, not legacy leftovers.

  • Bug Fix Delta update chain restored

    The release feed merge step was silently failing because the remote feed backup was stored in a directory that the packaging tool clears on each run. This caused 34 of 37 stores updating from one version to the next to download the full 175 MB package instead of a much smaller delta. The backup is now saved outside the cleared directory, and the build will fail loudly if the merge cannot complete, preventing silent degradation.

  • Bug Fix Blob cleanup now functional

    The Azure blob cleanup step was silently failing due to an invalid command-line flag. Cleanup is now feed-driven: only packages not referenced by the uploaded feed are deleted, and failures are reported rather than swallowed.

  • User Interface Settings blocked title-bar pill

    If you close the settings warning without fixing it, a red "Settings Cannot Be Saved" notice stays in the title bar—click it to bring the fix button back.

  • User Interface Title-bar indicator for blocked settings folder

    If the settings folder is blocked, a red "Settings Cannot Be Saved" marker stays in the title bar at the top of the window until you fix it — click it to bring up the repair dialog again.

  • Infrastructure Velopack CLI version pinned

    The Velopack packaging CLI is now pinned to match the exact version of the Velopack library shipped in the application, preventing version mismatches that can break delta patching. Bumping the library version in the central package configuration now automatically updates the CLI version.

  • Infrastructure New support documentation

    Added docs/marginmaster/support/settings-folder-permissions.md (Part VIII, Chapter 20) explaining what the settings folder is, why Windows blocks it, how Fix This Now works, what to do if it fails, and the manual icacls commands for IT departments. The Data Aging page gained clarification about dash values in Last Update columns (normal for POS systems without per-row timestamps) and why both banners appear after extended downtime. The startup lesson's audio for step 4 re-rendered to describe the new button workflow instead of "ask your administrator."

CloudSync
2026.904.23918
September 4, 2026

Rounding scheme lookups now deterministic; Added comprehensive test coverage for header consolidation; Settings reload coordination enhanced.

Strategy & Pricing

  • Improvement Rounding scheme lookups now deterministic

    Modified GetRoundingScheme and GetRoundingSchemeAsync to order results by ID, ensuring consistent behavior when multiple header rows exist during the brief window before consolidation runs. This prevents non-deterministic failures where the "wrong" duplicate might be selected.

  • Improvement Added comprehensive test coverage for header consolidation

    Created 232 lines of automated tests covering multiple duplicate header scenarios: trailing space twins, case-insensitive duplicates, empty survivors receiving another header's rows, leading space twins, and schemes with different pricing tables. Tests validate that consolidation preserves all pricing bands, uses the lowest ID as the survivor, and properly trims scheme names.

  • Improvement Ordered header queries by ID for consistency

    Modified RoundingScheme lookups to explicitly order by ID when multiple headers might exist. This ensures consistent behavior during the transition period when duplicates are being discovered and consolidated.

  • Bug Fix Duplicate rounding scheme headers now consolidated automatically

    If your store had a rounding scheme that stopped working after an update, it will now be automatically repaired when Margin Master starts.

  • Bug Fix Consolidated duplicate RoundingScheme headers before validation

    If you had rounding schemes that appeared empty after updates, this fix ensures all pricing bands are preserved when duplicate scheme names are consolidated.

  • Bug Fix Corrected attribution for August 31st Fremont error

    Updated technical documentation to correctly attribute the Fremont store's "1075 duplicate group(s), 2 header row(s), 1075 generated levels" error to duplicate RoundingScheme headers rather than the point table generator stall fixed in PR #1409. Added diagnostic guidance: when duplicates equal generated levels and header row count exceeds one, the cause is duplicate headers, not the generator.

  • Bug Fix Forced regeneration after header consolidation

    Schemes whose headers were just consolidated now skip checksum validation and force a full regeneration. The stored checksum describes the pre-consolidation split table, so merged details must be regenerated under the surviving ID before the system can trust them.

  • Bug Fix Minor code quality improvements

    Fixed a nullable reference warning in TrainingPlayerViewModel by reading the current step once instead of repeatedly dereferencing it. Corrected a column name reference in the download stats SQL query from "StoreName" to "Name" to match the Stores table schema.

  • Infrastructure Added comprehensive duplicate header consolidation tests

    Created six test cases covering trailing space twins, empty survivors receiving merged rows, case-insensitive collisions, no-collision scenarios, leading space handling, and triplet consolidation. Tests use throwaway databases and skip gracefully when the test server is unreachable.

Performance & Reliability

  • Improvement Settings reload coordination enhanced

    Multiple simultaneous reconnection events (from file watchers and explicit callers) are now properly coordinated. When a reload is already in progress, new requests join the existing operation and queue one final pass to load the latest state. The returned task completes only after all queued reloads finish, ensuring consumers never read partial or cleared settings during the reload process.

  • Bug Fix Settings corruption during database restore prevented

    Database restore operations will no longer lose your saved column views, license registration, or other custom settings.

2026.903.31398
September 3, 2026

The deployment process now records the exact build version when marking support issues as "Ready for Testing," enabling the backend to automatically track when each store has received the fix through auto-update check-ins.

2026.903.29159
September 3, 2026

Read the narration toggle in lesson detail pane; Narration script preview in lesson library; Quoted phrase search syntax.

User Interface

  • New Feature Read the narration toggle in lesson detail pane

    When browsing training lessons, you can now click "Read the narration" to see exactly what the lesson will say at each step before you start it. This works with the new narration search—find a lesson by what it says, then read what it says.

  • New Feature Narration script preview in lesson library

    Click "Read the narration" in the lesson details to see the full script that plays during each step, making it easier to preview lessons before starting them.

  • New Feature Quoted phrase search syntax

    Put quotes around multiple words to search for them as an exact phrase. For example, "price change" will only find lessons containing those two words together in that order.

  • Improvement Enhanced lesson search with full-content indexing

    When searching for training lessons, you can now type any words that appear in the lesson's narration or instructions, not just the title. For example, searching for "price endings" will find lessons that mention price endings in their steps, even if the title doesn't include those words. Use quotes around multiple words like "zone pricing" to find that exact phrase.

  • Improvement Enhanced lesson search with full-text narration

    You can now search for lessons using any word or phrase from the tutorial narration, not just the lesson title. For example, searching for "price endings" will find the Rounding Editor lesson even though that phrase only appears in the spoken narration.

  • Improvement Background run badge now identifies which data was refreshed

    When you open Margin Master after a background update, the title bar badge now tells you exactly what was updated—for example, "Vendor Data updated 3 hours ago" or "Vendor + Epicor Data updated 2 hours ago"—instead of the vague "Data updated" message.

  • Improvement Background badge identifies specific data updated

    When the background service updates your data, the badge now tells you exactly what was refreshed—Vendor catalogs, your POS inventory, or both—so you know which data is current.

  • Improvement Badge distinguishes between updates and "already current" checks

    If the background service checked for updates but everything was already current, the badge now says "Data checked... already current" instead of misleadingly saying data was "updated."

  • Improvement Badge distinguishes "nothing to do" from actual updates

    If the background service checks and finds your data is already up to date, the badge now says "already current" instead of claiming it updated something.

  • Improvement Refined lesson detail pane layout

    Restructured the "What you will do" section header to accommodate the script toggle button on the right side while maintaining the section title on the left. The toggle includes a tooltip explaining its purpose.

  • Improvement App self-updates no longer trigger data update badges

    The "data updated" badge now only appears when pricing or catalog data was actually refreshed, not when the app itself was updated.

  • User Interface Updated search box placeholder text

    The search box now shows helpful instructions explaining you can search lesson content and use quotes for exact phrases.

  • User Interface Step display enhanced to support narration script

    The step list in the lesson detail pane now shows both the numbered step title and optional narration text. When the script view is enabled, narration appears indented and italicized beneath each step. Series headings continue to show only part titles without narration.

  • User Interface Enhanced step display with collapsible narration

    Each lesson step now shows its spoken narration text beneath the step title when narration view is turned on.

  • User Interface Updated search box placeholder text

    The search box placeholder now reads "Search titles and narration — use 'quotes' for phrases" to inform users about the enhanced search capabilities and quoted phrase syntax.

  • Database Added SidesRefreshed field to background job status

    Added a new SidesRefreshed column to the BackgroundJobStatus table that records whether each run refreshed vendor data, POS data, both, or neither. The field is nullable to support backward compatibility with older status records, which fall back to interpreting the job type.

  • Database Added SidesRefreshed column to background job status

    The BackgroundJobStatus table gains a nullable SidesRefreshed column to record which data sources each run touched. The schema migration is idempotent and handles rows written before this feature shipped by falling back to the job type.

  • Architecture New LessonSearch engine with unit tests

    Added a pure static search engine (LessonSearch class) with methods for parsing search terms, matching text against terms, and building searchable text from lesson content. Includes comprehensive unit tests covering term parsing, AND semantics, phrase matching, and cross-field search behavior. The engine ensures phrases never match across field boundaries (fields are newline-separated).

  • Architecture New BackgroundRunSides vocabulary class

    Introduced BackgroundRunSides as a central vocabulary for recording and interpreting which data sources a background run refreshed, with unit test coverage ensuring the composition and display logic remain consistent.

  • Infrastructure Comprehensive search test coverage

    Added unit tests covering term parsing (bare words vs. quoted phrases), match logic (AND semantics, case-insensitivity, phrase ordering), and searchable text construction (including narration content). Tests verify that phrases cannot match across field boundaries and that empty queries disable filtering.

2026.902.30550
September 2, 2026

In-app training lessons for POS system imports; Seven new training guides and lessons; Troubleshooting lesson for startup problems.

Strategy & Pricing

  • Improvement Store Manager repair logic moved to shared service

    Refactored the StoreManagerInfo ordinal repair logic from StoreManagerViewModel into StoreManagerInfoWriter as a reusable method, following the MM-1368 headless pattern. The Store Manager window now delegates to this shared implementation, eliminating code duplication and enabling the repair to run in multiple contexts.

  • Improvement Comprehensive test coverage for data repair

    Added unit tests that verify the repair logic is safe to run repeatedly (idempotent), never resurrects invalid sentinel values as literal store numbers, always clears corruption markers, and correctly skips Epicor databases where the affected field serves a legitimate purpose.

  • Bug Fix Zone pricing now repairs corrupted store data automatically

    If your store has multiple yards and items were pricing incorrectly at $19.99 when they should be $26.99 (or similar zone-based price differences), this is now fixed automatically.

  • Bug Fix Automatic repair of legacy store number corruption

    If your store was pricing items at the wrong zone, zone pricing will now automatically use your correct assigned zone after the next sync or import.

  • Architecture Centralized repair logic

    Moved the char-ordinal repair SQL statement from StoreManagerViewModel to StoreManagerInfoWriter so both the Store Manager window and the headless zone pricing pipeline can share the same validated repair logic, reducing code duplication and maintenance burden.

  • Infrastructure Added comprehensive tests for store data repair

    Added StoreManagerOrdinalRepairTests with five test cases that verify the repair logic: restores correct POS store numbers, never creates invalid "99999" store numbers, always clears corruption markers, only touches corrupted rows (idempotent), stamps update timestamps, and safely no-ops for Epicor systems where the data structure is legitimate.

User Interface

  • New Feature Seven new training guides and lessons

    Seven new guides are now available in Training Mode (lessons 1020-1022, 2023-2025, and 3005) that walk you through multi-computer setup, adding catalog items, importing spreadsheets, cost break pricing, manual price entry, price sensitivity codes, and Ace MAP pricing.

  • Improvement Excel import documentation rewritten for accuracy

    The Excel import help now correctly explains that importing custom spreadsheets is an advanced feature best done with support assistance the first time.

  • Improvement MAP/IMAP pricing documentation corrections

    The MAP and IMAP pricing documentation now accurately describes which columns appear automatically and how they're labeled in the Future Price panel.

  • Improvement Price sensitivity code documentation updates

    Updated price sensitivity code documentation to clarify that Do-It-Best's OneClick Statistics shows awareness codes A through E plus a "Not Assigned (X)" row, and corrected the Add from Catalog menu caption to match the actual implementation.

  • Infrastructure 39 narration clips rendered for new training content

    Rendered 39 audio narration clips for the seven new training lessons and guides using text-to-speech synthesis, enabling the interactive walkthrough experience with voice guidance.

Infrastructure & Internal

  • New Feature In-app training lessons for POS system imports

    Turn on Training Mode from the Help menu and type the lesson number (4006 for BisTrack, 4007 for Paladin, 4009 for RockSolid, or 4008 for Transact) to learn how to import your store data step by step.

  • New Feature Troubleshooting lesson for startup problems

    If Margin Master gets stuck while starting up, the new lesson explains what each startup message means and how to fix it.

  • New Feature Lesson explaining column view behavior after updates

    If your columns look different after an update, the new lesson shows how to restore them and how to prevent changes in the future.

  • New Feature Lesson on beta and general release update modes

    The new lesson explains how you get on beta testing, how to tell if you're on it, and how you automatically return to regular updates.

  • New Feature Lesson on recurring price changes

    If the same price changes keep coming back week after week, the new lesson explains why it happens and how to stop it.

  • New Feature Lesson on narrowing price change scope

    The new lesson shows how to work on just one department at a time or apply changes to only specific items.

  • Improvement Extended lesson coverage for existing content

    More common questions now have step-by-step lessons available in Training Mode.

  • Improvement Documentation cross-references to new lessons

    Added "Walk through it in the app" callout boxes to 8 handbook pages (edit-columns.md, printing-and-exporting.md, selection-boxes.md, update-modes.md, and four POS import pages) directing readers to the corresponding interactive lessons with their lesson numbers.

  • Infrastructure Training backlog progress tracking

    Automated backlog tracking now shows 93 completed lessons (up from 64), 91 open tasks (down from 122), covering 29 newly-addressed support topics including stuck logins, column resets, beta mode, duplicate price changes, and POS-specific imports.

2026.902.22878
September 2, 2026

Training guide for software updates; Interactive guide for software updates; Moving to a new computer series (guides 1011-1013).

Imports & POS

  • Improvement Drive path handling distinguishes between system and mapped drives

    Added logic to differentiate between the system drive root (typically C:\, which standard users cannot write to) and other drive roots like mapped network drives. Bare drive letters are stored with trailing backslashes to ensure Windows interprets them as drive roots rather than current directories on those drives.

  • Improvement Increase SQL timeout for large import data moves

    Large store imports on slower servers are now much less likely to timeout during the final data processing steps.

  • Improvement Clear per-store error tracking in multi-store imports

    Multi-store imports now clear error state between each store so that one store's processing failure does not incorrectly trigger data-loss protection for subsequent stores in the batch.

  • Improvement Better error reporting for database operation failures

    The SQL service now records exceptions from failed ExecuteNonQueryAsync calls so that downstream code can distinguish between "zero rows affected" and "operation failed with timeout/error," enabling more accurate diagnostics in import processing.

  • Bug Fix Mapped drive root paths now persist correctly in export settings

    If you export files to a mapped drive like M:\, that path will now stay saved in your settings instead of changing back to C:\MarginMaster every time.

  • Bug Fix Export path configuration now supports mapped drive roots

    If you configure a mapped network drive (like M:\) as your export folder, Margin Master will now remember and use that location instead of switching it back to C:\MarginMaster.

  • Bug Fix Prevent silent data loss when import times out

    If a Paladin multi-store import is interrupted by a database timeout, you'll now see a clear error message and your store's existing data will remain unchanged, instead of silently losing all inventory data for that store.

  • Bug Fix Prevent silent data wipe on SQL timeout during multi-store import

    If your database runs slowly during a multi-store import, the import will now wait long enough to complete successfully instead of accidentally deleting your store's data.

  • Bug Fix Drive root paths now stored with trailing backslash

    Non-system drive roots are now canonicalized with a trailing separator (M:\ instead of M:) because Windows interprets "M:" as "current directory on M:" rather than the root. This ensures the configured path always points to the intended root directory.

  • Bug Fix Record SQL failures for proper error attribution

    Import error messages now correctly identify which store failed in multi-store imports, making it easier to diagnose and re-run specific stores.

User Interface

  • New Feature Training guide for software updates

    The new guide walks you through how Margin Master checks for updates automatically, what to do when the Update Available badge appears, and how to check for updates yourself from the Help menu whenever you want.

  • New Feature Interactive guide for software updates

    When you open Training Mode, you'll find a new guide under Getting Started that explains how updates work, what to do when you see the blue Update Available badge, and how to check for updates yourself using the Help menu.

  • New Feature Moving to a new computer series (guides 1011-1013)

    When setting up Margin Master on a new computer, three new training guides show exactly what to do: first back up your old database, then install on the new PC, then restore the backup.

  • New Feature New PC migration guide series

    Training Mode now walks you through moving Margin Master to a new computer step-by-step, including backing up your data, installing the software, and getting your database back.

  • New Feature Ten new training guides added to the in-app tutorial catalog

    The Help menu now includes ten new step-by-step guides covering common tasks like recovering from a failed update, understanding why price change counts differ between screens, creating pricing rules, troubleshooting unexpected strategy results, and connecting to your Epicor system.

  • New Feature Ten training guides added to What's New catalog

    The What's New dialog now offers ten new step-by-step training guides covering common tasks like setting up Epicor connections, troubleshooting pricing strategies, understanding price change counts, and recovering from failed updates—each with audio narration and on-screen guidance.

  • New Feature 11 new training lessons and guides

    The Help menu's Lessons & Guides now includes 11 new walkthroughs covering common tasks like setting up a new computer, building pricing strategies, fixing frozen programs, and moving your work to another machine. Each guide narrates the steps and highlights what to click.

  • New Feature Training / Guide Mode available to all users

    You can now turn on Training / Guide Mode from the Help menu to access step-by-step guides that walk you through tasks right inside Margin Master.

  • New Feature Price change day series (guides 2002-2004)

    Three new guides teach the complete price change process: running the strategy, sending the file and printing tags, then finalizing in your point-of-sale system.

  • New Feature Price change day workflow guides

    New guides show the complete price change process from executing your strategy through printing tags and finalizing in your POS.

  • New Feature Audience-gated training guides for specific vendors and POS systems

    Training guides now appear based on your store's configuration—for example, Ace Hardware stores see zone pricing guides, while Epicor users see Eagle-specific connection instructions.

  • New Feature Lesson 1017 — Your regular data routine

    Learn your regular routine: update vendor data from the cloud, then import your point-of-sale inventory, and understand why the same record count each time is normal.

  • New Feature Clearing stale or orphaned data guide (5001)

    A new guide explains how to clear out old SKUs or vendor data that won't go away, starting with the gentlest fix and working up to deeper resets.

  • New Feature Data reset and cleanup guide

    A new guide explains how to clear stale SKUs or fix pricing data that won't update, from gentle fixes to deeper resets.

  • New Feature Lesson 2016 — Setting up your pricing (roadmap)

    Get a roadmap of Margin Master's pricing setup: which features do what, and which lessons explain each part.

  • New Feature Lesson 2017 — When tags print wrong

    Troubleshoot tag printing: learn why unchanged items got tags, how to pick the right printer, and how to reprint missed labels without wasting sheets.

  • New Feature Lesson 2018 — Importing competitor prices

    Load competitor prices from a spreadsheet into your grid's Comp columns to compare your pricing against other stores.

  • New Feature Lesson 3004 — Updating your Do-it Best data

    Do-it Best stores: learn how to update your vendor catalog and pricing from the cloud, and what to do if something doesn't sync.

  • New Feature Lesson 4003 — Getting price changes into Paladin

    Paladin users: send your price changes to Paladin by exporting the text file it imports, then finish the price change in Paladin.

  • New Feature Lesson 4004 — Getting price changes into RockSolid

    RockSolid users: Margin Master writes price changes directly into RockSolid's import table — learn the paths that matter and how to finish the change.

  • New Feature Lesson 4005 — Importing your Propello data

    Propello users: import your inventory directly from Propello's cloud, or set up the connection if you haven't already.

  • New Feature Lesson 6002 — When SQL Server stops after a Windows update

    If Margin Master can't reach its database after a Windows update, learn how to restart the SQL Server service and get back to work.

  • New Feature Lesson 6003 — When the store list looks wrong

    Fix a missing or extra store in your store list by re-importing POS data or adjusting the Exclude setting in Store Manager.

  • New Feature Lesson 6004 — Letting support see your screen

    Learn how live support sessions work: what you're allowing, what needs administrator approval, and how you stay in control.

  • Improvement Training lesson wording refinement

    The training guide now better explains how What's New works after updates and reminds you it's always available on the Help menu.

  • Improvement Removed confusing optional clean-up step from training

    The training guide no longer includes an optional clean-up step that many found confusing, making the lesson easier to follow from start to finish.

  • Improvement Training backlog tracking

    Updated training backlog tracking to mark the `run-software-update` task as completed (moved from 376 open sessions to the done list). The task covered update procedures, the update badge, and Help > Check for Updates functionality, now fully addressed by the new guide.

  • Improvement Training backlog updated

    The "Update Margin Master to the latest version" task (run-software-update) has been marked as complete in the training backlog, moving from 376 open support sessions to the done list now that the interactive guide is available. This was the most frequently requested training topic across all classified support chats.

  • Improvement Enhanced update failure recovery instructions

    The training guide now gives clearer instructions on what to do if an update doesn't complete successfully.

  • Improvement Extended existing lessons with additional coverage

    Several existing training guides now cover additional related topics and one correction was made to accurately describe the Rounding Schemes editor layout.

  • Improvement Expanded training catalog organization with new topics and sections

    Reorganized the training catalog to include five top-level topics (previously three): Getting Started, Pricing & Analysis, Vendor-Specific, POS Systems, and Database. Added new sections within Pricing & Analysis (Strategies, Troubleshooting) to accommodate the growing guide library. The catalog structure now supports 134 total entries with clear subtopic organization.

  • Improvement Training content covers most-requested support topics

    The ten new guides directly address the most frequently asked support questions identified from 7,893 chat sessions: reinstalling after a failed update (96 sessions), creating pricing rules (88 sessions), troubleshooting strategy results (84 sessions), investigating count discrepancies (81 sessions), fixing pricing mismatches (55 sessions), setting up Epicor connections (44 sessions), managing SKU exceptions (42 sessions), troubleshooting SKU prices (41 sessions), excluding items from price changes (38 sessions), and configuring zone pricing (31 sessions). This reduces the need for live support on these common workflows.

  • Improvement Training catalog reorganization

    Training topics are now better organized, with database tasks in their own section and price change day broken into clear steps.

  • Improvement SKU exception guide clarifies permanent behavior

    SKU exceptions now have a dedicated training guide explaining that they stay in effect permanently until you remove them—they don't expire on their own.

  • Improvement Comprehensive exclusion methods guide

    A new guide explains all four ways to exclude items from price changes, from temporary exclusions in a single rule to permanent protections for specific SKUs.

  • Improvement Lesson content updates and corrections

    Improved existing lessons with better coverage mapping and fixed several documentation errors about printing, filtering, and menu locations.

  • User Interface Training lesson clarification for What's New behavior

    The training guide now correctly explains that What's New appears after updates based on your settings, and reminds you it's always available on the Help menu.

  • User Interface Updated summary step to hand off to part 2

    The final step of the training now clearly guides you to the next part where you'll send price changes and print tags.

  • User Interface Training catalog reorganized with new topics

    Training topics are now organized into five clear categories including vendor-specific and POS system guides, making it easier to find relevant help for your store's setup.

  • User Interface Help menu integration

    The guide shows you exactly where to find Check for Updates in the Help menu and what happens when you click it.

  • User Interface In-app guide callouts added to handbook pages

    Handbook pages now show which in-app guides walk you through each task, making it easier to launch the right narrated walkthrough.

  • User Interface Training catalog reorganization

    Training guides are now better organized with new sections for database tasks and price change day workflows.

  • Infrastructure Updated training audio files and rendering metadata

    Regenerated audio file for step 6, removed the audio for the deleted step 7, and updated the render.json manifest to reflect the new step structure and voice settings.

  • Infrastructure New Support topic category in lesson catalog

    Expanded the lesson catalog structure to include a sixth topic category "Support" with initial subtopic "Troubleshooting", housing lesson 6001 (frozen program). Updated lesson catalog tests to reflect 33 total lessons across 6 topics (Getting Started, Pricing & Analysis, Vendor-Specific, POS Systems, Database, Support).

  • Infrastructure Training backlog progress

    These seven guides cover 11 keys from the support chat backlog (migrate-mm-to-new-pc, backup-database-and-strategy-files, restore-database-from-backup, execute-price-changes, print-price-tags-labels, export-price-changes-to-pos, finalize-price-changes, reset-database-to-fix-data-issues, clear-orphaned-skus-after-import), reducing the open backlog from 186 to 177 items. Every fact in the guides was verified against window titles, menu paths, and current documentation.

  • Infrastructure Training audio assets

    Added 49 narrated audio files (.mp3) and rendering manifests for the seven new lessons, using the en-US-AvaMultilingualNeural voice for consistent narration across all training steps.

  • Infrastructure 69 narration audio clips rendered

    Rendered 69 MP3 narration clips for the new lessons using en-US-AvaMultilingualNeural voice, with hash-based render manifests to track text changes. Re-rendered 3 existing clips where narration text was updated (rounding-schemes-4, sku-price-tools-3, when-an-update-fails-4).

  • Infrastructure Training audio narration rendering

    Rendered 72 new narration audio clips using Azure text-to-speech (en-US-AvaMultilingualNeural voice) for the 11 new lessons. All render hashes tracked in .render.json files for reproducibility. Training tests updated (33/33 passing) to include new lesson in catalog validation.

Infrastructure & Internal

  • New Feature Ten new training lessons for common support scenarios

    Added 10 new interactive lessons covering frequently-requested support topics: managing and moving strategies (#2011, #2014), building rounding schemes from scratch (#2013), using custom groups (#2012), handling strategies after updates (#2015), reconnecting feeds on new computers (#1015), changing database server connections (#5002), fresh store setup roadmap (#1016), frozen program troubleshooting (#6001), Epicor store exclusion (#4002), and Ace Hardware data updates (#3003). Each lesson includes multi-step audio narration, on-screen UI targeting, and auto-advance for guided workflows.

  • Improvement Simplified price execution tutorial

    The guided tutorial for executing pricing strategies now has one fewer step, making it quicker to complete while still covering all essential tasks.

  • Improvement New Support topic section in training catalog

    Added "Support" as a sixth topic category in the training catalog alongside Getting Started, Pricing & Analysis, Vendor-Specific, POS Systems, and Database, providing better organization for troubleshooting and maintenance lessons.

  • Improvement Enhanced documentation with training lesson references

    Updated 8 documentation pages to reference relevant training lessons, including auto-updates, cloud vendor sync, database setup, installation, POS connections, store manager, custom groups, pricing strategies, rounding schemes, and strategy backup/restore. Each page now points users to the specific lesson number they can launch from the Help menu.

  • Improvement Expanded lesson coverage tracking

    Extended lesson metadata to cover 20+ additional support chat tasks including strategy troubleshooting, connection issues, server moves, fresh installations, frozen programs, store exclusions, antivirus conflicts, and more. Lessons now explicitly track which support scenarios they address.

  • User Interface Updated tutorial audio

    Re-recorded step 6 audio to remove references to the cleanup operations and now directs users to click Finish to proceed to sending changes and printing tags. Removed step 7 audio file entirely.

  • User Interface Audio narration for all new lessons

    Generated and embedded MP3 audio files (80+ audio segments) for all new lessons using Azure text-to-speech (en-US-AvaMultilingualNeural voice), providing consistent narration across the expanded training library.

2026.901.31604
September 1, 2026

Rounding scheme editor now shows saved changes immediately; Future price panel rounding dropdown refreshed properly.

User Interface

  • Bug Fix Rounding scheme editor now shows saved changes immediately

    When you edit a rounding scheme and save it, those changes now appear immediately if you reopen the editor. Previously, you would see the old values until you closed and restarted Margin Master, even though your changes were actually saved.

  • User Interface Future price panel rounding dropdown refreshed properly

    The rounding scheme dropdown in the future price panel now always shows up-to-date scheme settings after you make changes.

2026.901.28986
September 1, 2026

Topic-organized lesson catalog; Topic-organized lesson catalog; Lesson library with tree view and detailed descriptions.

Strategy & Pricing

  • Improvement Enhanced validation and automatic repair of rounding schemes

    Rounding schemes with data corruption are now automatically repaired when Margin Master starts up, ensuring consistent pricing calculations.

  • Improvement Enhanced duplicate detection and cleanup after regeneration

    Improved the duplicate detection logic that runs after regenerating rounding schemes to distinguish between duplicates caused by the generator (now impossible) versus duplicates from multiple scheme header rows sharing the same name. The system now logs detailed diagnostics showing the number of duplicate groups, header rows, and generated levels, then automatically cleans up any duplicates found, using the same cleanup process as when saving schemes.

  • Bug Fix Generator stall when prices round below themselves

    Certain rounding scheme configurations would previously stop working partway through the price range, leaving higher-priced items unrounded. These schemes now generate complete pricing tables that cover the full product catalog.

  • Bug Fix Generator stall in rounding schemes with round-down rules

    If you had a rounding scheme that seemed to stop working above a certain price (leaving prices unrounded), this has been fixed. All prices will now round correctly according to your scheme rules.

  • Infrastructure Force regeneration of all rounding schemes on upgrade

    Incremented the rounding scheme generation version from 2 to 3, which triggers a one-time regeneration of all rounding schemes on upgrade. This ensures any existing schemes with stalled pricing tables are automatically repaired. All 850 user schemes tested regenerate identically (byte-for-byte) except for previously stalled tables, which now complete correctly.

  • Infrastructure Comprehensive test coverage for generator stall scenarios

    Added 150+ new test cases covering all known triggers for the generator stall bug, including right-side rounding fallbacks below the maximum point, rollback rules without supporting right-side rounding, rollbacks landing inside range overrides, and property-based testing with 500 random rule combinations. These tests ensure the generator never creates backwards-stepping bands and always reaches the upper price limit.

  • Infrastructure Comprehensive test coverage for generator edge cases

    Added 150+ lines of test coverage including specific reproduction cases for each stall trigger pattern, a seeded property test that generates 500 random rounding configurations, and validation helpers that detect stalled walks and verify band integrity. The property test reproduced the issue 192 times out of 4,000 random schemes on the old engine; all now pass on the fixed engine.

  • Infrastructure Rounding scheme generation version bumped to v3

    Incremented the rounding scheme generation version to force regeneration of all existing schemes on upgrade, ensuring any schemes affected by the stall bug are automatically rebuilt with the fix applied.

User Interface

  • New Feature Topic-organized lesson catalog

    The lesson library is now organized by category making it easier to browse and find relevant training for your needs.

  • New Feature Topic-organized lesson catalog

    The lesson browser now organizes lessons by topic and subtopic, making it easier to find lessons on a specific subject. Topics you don't have access to won't appear in your catalog.

  • New Feature Lesson library with tree view and detailed descriptions

    You can now browse all available lessons in a tree organized by topic and series, click any lesson to see what it covers and where you left off, then press Start when ready.

  • New Feature Lesson library with tree and description panel

    Browse lessons in a new library view with a tree on the left and full details on the right, including all steps and where you left off. Search for lessons by name, click one to read about it, then press Start when ready.

  • New Feature Lessons vs. Guides distinction

    When browsing training content, you'll now see items marked as either lessons or guides. Lessons show you around without changing anything; guides walk you through real tasks step-by-step.

  • New Feature Lessons vs. Guides distinction

    Lessons teach concepts by showing you around the screen. Guides walk you through real tasks like creating a database or importing data – you do each step yourself, and the guide waits for you to complete it before moving on.

  • New Feature Lessons & Guides library with narrated walk-throughs

    Click the new training button to access guided lessons and step-by-step guides that teach you how to use Margin Master. Lessons explain features with narration and spotlights, while guides walk you through real tasks like setting up a new database or importing your sales data.

  • New Feature In-app lesson editor for developers

    Internal development tool only—not visible to customers.

  • New Feature Multi-part lesson series with navigation

    Related lessons can now be linked together in multi-part series that automatically guide you from one part to the next.

  • New Feature Multi-part lesson series

    Some lessons are now organized into multi-part series that you can navigate through step-by-step, with automatic skip over any parts you don't have access to.

  • New Feature Speech-bubble callout mode during lesson playback

    During lessons, the training card becomes a small speech bubble that automatically moves to point at each step's target, staying out of your way while guiding you through the task.

  • New Feature Speech-bubble callout mode during lessons

    During a lesson, the window becomes a speech bubble that sits next to whatever you need to click, with an arrow pointing at it. It follows each step automatically, or you can drag it aside if it's in your way.

  • New Feature Creating a New Database guide

    Use the new "Creating a new database" guide to set up a fresh database for your store step-by-step, with voice narration explaining each choice.

  • New Feature Main window overview lesson series

    The new "Main window overview" training series walks you through every part of the main screen, from menus to buttons to the pricing grid, explaining what each area does and how to use it.

  • New Feature Main window overview lesson series

    A new six-part lesson series explains every part of the main screen: menus, selection boxes, buttons, the grid, the summary and the pricing panel.

  • New Feature "Creating a new database" guide

    You can now use Training / Guide Mode to walk through creating a brand new database for your store. The guide highlights each field and button as you fill out the form.

  • New Feature Database creation and POS import guides

    New step-by-step guides walk you through creating a database for your store and loading your point-of-sale data, so you can get started with Margin Master quickly and confidently.

  • Improvement Smarter bubble positioning for menus

    The training bubble now stays out of the way of menus and dialogs, making it easier to follow along with each step.

  • Improvement Lesson numbering reorganized into topic blocks

    Lesson numbers have been reorganized so the number itself indicates what topic it covers (1000s = Getting Started, 2000s = Pricing & Analysis, etc.).

  • Improvement Lesson numbering convention

    Lesson numbers now indicate their topic area—for example, lessons starting with 2xxx are about pricing and analysis, while 1xxx covers getting started.

  • Improvement Centred initial placement with monitor awareness

    The training card now opens in the centre of your screen and stays visible even if you unplug a monitor, and it remembers where you last put it.

  • Improvement Narration bar for lessons while library is open

    You can keep the lesson library open while a lesson plays using the narration bar at the bottom, or switch to the speech bubble by clicking "Back to lesson" in the header.

  • Improvement Narration bar while library is open during lessons

    You can now keep the lesson library open while a lesson plays—controls at the bottom let you step through the lesson while seeing the full lesson list.

  • Improvement Smart bubble placement avoids menus and dialogs

    The training bubble now automatically moves out of the way of menus and windows, so you can always see what you're clicking.

  • Improvement Guided database creation and data import

    New training guides now walk you step-by-step through setting up a fresh database and importing your store's sales data.

  • Improvement Lesson browser pane auto-hides on narrow screens

    On smaller screens, the lesson list temporarily hides itself when a dialog opens, then reappears when you close the dialog.

  • Improvement Automatic dialog avoidance

    On smaller screens, the training card automatically moves aside when a dialog opens so you can see both, then returns when you close the dialog.

  • Improvement Enhanced lesson progress indicators in tree

    Lessons now show icons indicating whether you've started them, finished them, or are currently playing them, and you can see at a glance how many lessons in each topic you've completed.

  • Improvement Smart training window behavior

    Training bubbles now stay out of your way when you switch to another program, and during guided walkthroughs you can click the actual buttons and menus being explained.

  • Improvement Lesson series support and simplified progress tracking

    Lesson series now always start from the beginning, making it easier to review any part.

  • Improvement Series navigation and progress display

    When working through a multi-part lesson series, you'll see which part you're on and can easily jump to the previous or next part using the new buttons.

  • Improvement Intro lesson updated for new interface

    The intro lesson now explains how to use the lesson library and speech bubble instead of the old training interface.

  • Improvement Simplified progress tracking

    Each lesson and guide now starts from the beginning every time, making it easy to refresh your knowledge whenever needed.

  • Improvement Training overlay respects application focus

    Training bubbles now step aside politely when you switch to another program, then come back when you return to Margin Master.

  • Improvement Training mode introduction lesson rewritten

    The first-time training introduction now shows you how to move the lesson window and find lessons in the new browser layout.

  • Improvement Persistent layout and browse state

    The training window remembers whether you had the lesson list open or closed and reopens that way next time.

  • Improvement Intro lesson updated for new interface

    The introductory "Training Mode" lesson now explains the new library and speech-bubble interface.

  • User Interface Lesson browser and player combined into one window

    The lesson list now stays open next to the lesson player so you can see what other lessons are available while learning. Click "Lessons ▸" in the header to show or hide the list.

  • User Interface Single training window with collapsible lesson browser

    The lesson list now appears beside the lesson card instead of in a separate window, so you can browse other lessons while one is playing.

  • User Interface Pricing Equation Analysis button removed from toolbar

    The toolbar button for Pricing Equation Analysis has been removed to simplify the interface. If you need this feature, it's still available in the Strategy menu.

  • User Interface Training window position and size remembered

    Drag the training window to any spot on your screen — it will reappear there the next time you open lessons, even after restarting the application.

  • User Interface Improved lesson browser organization

    Lessons are now organized by topic with your progress shown on each one, and multi-part lessons have a "Start Series" button that takes you through them in order.

  • User Interface Training window sized for smaller displays

    The training window now fits completely on laptop screens — you'll always see every button and control without needing to resize your application.

  • User Interface Enhanced catalog metadata

    The lesson catalog now supports additional metadata fields including topic, subtopic, order (for sorting within topics), summary (one-sentence description), series information (series ID, part number, series title), and maintains the existing audience filtering. Catalog entries are sorted by order, then number, then series part within each topic section.

  • User Interface Window sizing and placement improvements

    The library mode defaults to 820×560 (up from 700×420) to accommodate the tree and description panes. The callout mode uses a fixed 400×300 size. Both modes remember their last user-dragged position separately and clamp to the monitor's work area on startup, ensuring the window remains accessible on smaller screens like laptops.

  • User Interface Renamed Training Mode to Training / Guide Mode

    The Training Mode feature has been renamed to "Training / Guide Mode" to better reflect that it includes both lessons and hands-on guides.

  • User Interface Updated Training Mode labels and terminology

    Look for "Training / Guide Mode" in the Help menu and the "Lessons & Guides" button in the title bar when training mode is on.

  • User Interface Series navigation and context

    Multi-part lessons now show which part you're on and have Previous and Continue buttons to move through the series.

  • User Interface "Lessons ▸" button toggles between library and callout modes

    The "Lessons" button in the header now switches between the full library and the compact speech bubble while a lesson plays.

  • User Interface Updated narration voice and lesson structure

    Lessons now start by telling you exactly what they cover, and the welcome tour only plays once a day.

  • User Interface Updated welcome lesson

    The first-time training tour now shows you how to move the card and find lessons by topic.

  • User Interface Tree row styling and state indicators

    Tree rows now show chevrons (▸/▾) for expandable groups, and state glyphs for lessons: empty circle for not started, half-filled circle (◐) in accent color for in-progress, checkmark (✓) in green for completed, and filled circle (●) in accent color for currently playing. The selected lesson is highlighted with a semi-transparent accent background. Part numbers (e.g., "1.") appear before lesson titles in multi-part series.

  • User Interface Enhanced element targeting for spotlights

    Adds named targeting for button bar items, data flyouts, toolbar containers, and menu items, allowing lessons to accurately spotlight specific UI elements. Resolves visual tree containers to find actual spotlight targets, improving the precision of visual guidance during training.

  • User Interface Speech bubble tail positioning

    The bubble's tail is a WPF `Path` element positioned outside the 14px margin grid to avoid WPF's layout clipping, and dynamically placed on the right, left, bottom, or top edge depending on which side of the target fits best within the monitor's work area. The tail points directly at the center of the spotlighted control.

  • Database Training content delivery infrastructure

    Training lessons and audio are stored as embedded resources with a content mirror system that downloads JSON and MP3 files to a local cache folder. The render sidecar tracks SHA256 hashes of narration text to detect which audio files need re-rendering when wording changes. Content is served from the `marginmasterdownloads/training` blob container.

  • Architecture Lesson browser refactored to library view model

    Replaced `LessonBrowserViewModel` (172 lines) with `LessonLibraryViewModel` (291 lines), which maintains a flattened tree of `LibraryNode` and `LibraryRow` objects for efficient rendering without a WPF TreeView control. The view model now loads lesson content on demand to populate the description pane, tracks expansion state for topics and series, supports filtering, and handles selection separately from playback state.

  • Architecture Lesson browser refactored to library viewmodel

    Replaced LessonBrowserViewModel (172 lines, flat topic/series/lesson lists with expand/collapse) with LessonLibraryViewModel (291 lines, tree-based with LibraryNode/LibraryRow hierarchy, selection state, search filtering, and LessonDetail for the description panel). The new architecture flattens the expanded tree into rows for rendering without a TreeView control, enabling custom styling and single-click selection with double-click activation.

  • Infrastructure Documentation updated for button row

    The button row documentation has been updated to reflect the removal of the Pricing Equation Analysis button from the toolbar's technical reference.

  • Infrastructure Backward-compatible catalog format

    All new catalog fields (topic, subtopic, order, summary, series, part, seriesTitle) are optional, ensuring existing lesson catalogs and the content sync system continue working without modification. The flat lesson list remains functional, and the LessonCatalog.Topics() method derives the browsable tree from the new fields when present. Cloud catalog will need to be re-uploaded after deployment to take advantage of the new organization features.

  • Infrastructure Developer training hooks

    Added MM_TRAINING_LESSON environment variable for developers to start a specific lesson at launch, bypassing the intro. Named UI elements in the Create New Database dialog (cboPrimaryVendor, txtStoreNumber, cboPosSystem, txtDatabaseName, btnValidateLicense, btnCreateDatabase) so they can be targeted by training steps.

  • Infrastructure Guide authoring rules and validation

    Added test-enforced authoring rules: guides cannot use command targets (they never perform steps for the user), must include a summary explaining what they do, and if they change data must mention "End" in the narration. Lessons (tours) cannot use waitFor signals since they advance on Next only. Added x:Name attributes to Create New Database window controls (cboPrimaryVendor, txtStoreNumber, cboPosSystem, txtDatabaseName, btnValidateLicense, btnCreateDatabase) to support guide targeting.

  • Infrastructure Developer lesson editor with Azure TTS integration

    On development machines where the lesson source folder is detected, adds an in-app editor (✎ button on the bubble) for changing step titles and narration. The workflow is: edit text → Read it back (renders with Azure text-to-speech en-US-AvaMultilingualNeural voice and plays preview) → Approve and publish (updates source JSON, saves MP3, updates render sidecar, mirrors to content folder, and uploads to Azure blob storage via `az` CLI). The media player is released before file replacement to avoid locks. Uses AZURE_SPEECH_KEY or falls back to Azure CLI authentication.

  • Infrastructure Training window spotlight targets added

    Added targetable elements for spotlight highlighting within the training window itself: TrainingWindowHeader (drag handle), btnBrowseLessons (toggle button), LessonBrowser (scrolling list), AllLessonsHeading, and LessonIdBox. The overlay sits under the card so spotlights on the card itself are narration-only without visual highlighting.

  • Infrastructure TrainingWindowMoved signal for interactive lessons

    Added TrainingWindowMoved signal raised when the user drags the training card to a new position, enabling lessons to wait for and teach window repositioning as an interactive step (used in the revised training-mode introduction lesson).

Performance & Reliability

  • Improvement Export error messages now include operating system reason

    Export error messages now explain why the operation failed (for example, "access denied" or "file is locked"), not just which file was affected.

  • Improvement Backup directory now derives from import path setting

    The automatic backup folder (used for database and strategy backups) is now recalculated each time from the current import path setting rather than cached at startup, ensuring Options changes take effect immediately. Falls back to ProgramData when the derived path cannot be created.

  • Bug Fix Export path resolution unified across all operations

    When no custom export or import folder is configured, Margin Master now consistently uses C:\MarginMaster for all operations instead of sometimes trying to write to the C:\ drive root (which Windows blocks for standard users).

  • Bug Fix Settings folder permission check prevents silent save failures

    If Margin Master can't save settings because of Windows permissions, you'll now see an error message at startup that lists exactly what's wrong and tells you to ask your administrator to grant Modify access to the settings folder.

  • User Interface Clear permission error dialog with actionable guidance

    The error message shows exactly which files can't be written and tells you who to contact to fix the permissions.

  • Infrastructure Comprehensive permission validation

    The new ProgramDataAccessCheck helper performs two validation steps: creates a test file to verify the directory is writable, then attempts to open every existing *.json file in the folder root for write access. This two-tier approach catches the specific scenario where folder ACLs allow new file creation but existing files have restrictive permissions from being created under a different user account. File locking by other processes is explicitly treated as non-fatal (contention is not a permissions problem).

  • Infrastructure Path resolution logic consolidated and tested

    Replaced the IGlobalFileConfigService.DefaultExportPath / DefaultImportPath properties and their internal GetValidPath / TryCreateDirectory helpers with new extension methods on IApplicationSettingsService (ApplicationSettingsPathExtensions) and IImportSettingsProvider (ImportSettingsProviderPathExtensions). Added MarginMasterPaths.ResolveImportExportFolder and NormalizeImportExportFolder as the single pure resolver all 67 call sites now share, with 16 test cases pinning normalization, fallback, and creation behavior.

Infrastructure & Internal

  • New Feature SQL Server Authentication Setup Guide for IT Administrators

    Stores with their own IT departments can now share official setup instructions for configuring SQL Server when running Margin Master on multiple computers.

  • Improvement Export error messages now include the full file path and reason

    Export failures now surface the operating system's error message (access denied, file in use, path not found) alongside the full file path, making it easier to diagnose export problems without guessing which folder was attempted.

  • Improvement Updated Firewall Requirements Documentation

    Modified the firewall and network requirements guide to link to the new customer-facing SQL Server setup guide instead of the support-only script documentation. The script reference has been moved to a support-only section so it remains available to internal staff but doesn't create broken links for customers.

  • Improvement Bare drive roots (C:\) rejected as import/export folders

    The path normalizer now treats a bare drive letter (C:\ or C:) the same as a blank setting and substitutes the default folder. This prevents the original MM-1446 condition where a malformed or incomplete setting resulted in write attempts to the drive root.

  • Improvement Cross-Referenced SQL Remote Access Script

    Added a related link from the internal support script documentation to the new customer-facing guide, making it easy for support staff to direct customers to the appropriate resource.

  • Bug Fix Export path now resolves consistently across all operations

    Exports that previously failed with "Access denied" will now succeed. The export path shown in Options will match the path actually used by all export operations.

  • Architecture Centralized import/export path resolution logic

    Created MarginMasterPaths.ResolveImportExportFolder() and extension methods on IApplicationSettingsService (GetDefaultImportPath/GetDefaultExportPath/SetDefaultImportPath/SetDefaultExportPath) so all 34 readers of these settings see the same normalized value. Removed duplicate path-resolution code from GlobalFileConfigService and individual ViewModels.

2026.828.41108
August 29, 2026

The auto-update system now measures and reports download performance for every update, tracking bytes transferred, download duration, and whether delta patches or full packages were used. This telemetry is sent to Manager on the next check-in to help determine if stores are benefiting from small…

2026.828.37248
August 29, 2026

Interactive training system with spoken narration; Azure Neural TTS narration for training lessons; Training Mode toggle with visual indicator.

User Interface

  • New Feature Interactive training system with spoken narration

    When you start a training lesson, a small window appears with spoken instructions. The screen dims except for the button or menu you need to click, which pulses with a highlight. After you complete each step, the lesson moves forward automatically or when you click Next.

  • New Feature Azure Neural TTS narration for training lessons

    Training lessons now play with a professional voice instead of robotic text-to-speech, making them easier to follow.

  • New Feature Training Mode toggle with visual indicator

    Turn on Training Mode from the Help menu to see lessons. The window gets a glowing blue border and the title bar shows a "Show Lessons" button.

  • New Feature Lesson reference numbers for documentation and support

    When working with support, you can now use lesson numbers like "1001" to quickly start the right training.

  • New Feature Welcome to Training Mode lesson (Lesson 1000)

    When you first turn on Training Mode, a welcome lesson plays automatically to walk you through how to find lessons, understand lesson numbers, and navigate the training system.

  • New Feature Help buttons offer "Walk me through it" option

    Click the blue "?" button on any screen to choose between reading the help page or launching an interactive training lesson that walks you through the task.

  • New Feature Screen-aware lesson list

    When you click "Show Lessons," you'll see lessons for the screen you're on first, then all other available lessons.

  • New Feature Sample lesson: Opening Options and finding Miscellaneous tab

    The sample training lesson walks you through opening the Tools menu, clicking Options, and finding the Miscellaneous settings page.

  • New Feature Dialog detection for lesson steps

    The training system now automatically detects when new dialogs open by monitoring the application's window collection and raising "Dialog:{title}" signals. This allows lessons to wait for specific windows to appear before advancing, enabling multi-step workflows that cross dialog boundaries.

  • New Feature Visual tree element search for lesson targets

    Lesson steps can now target any named element in the application, including those inside UserControls, by walking the WPF visual tree. Previously only elements directly accessible through Window.FindName were reachable.

  • New Feature Rounding Schemes training lesson

    A new lesson shows how to open the Rounding Schemes editor where you set price endings like 99 cents.

  • Improvement Training player remains enabled during modal dialogs

    The training assistant now stays interactive when guiding you through screens like Options, so you can continue following instructions without the tutorial freezing.

  • Improvement Auto-advance support for navigation steps

    Training lessons now advance automatically after certain actions, making tutorials flow more smoothly without extra clicks.

  • Improvement Enhanced coordinate conversion for spotlight targets

    Added ToLocal method that properly converts spotlight target rectangles from the main window's DPI context into the overlay's local coordinate system, accounting for different DPI scaling on each display. This ensures the dimmed areas and highlight outlines draw precisely around the intended UI elements.

  • Improvement "Lessons..." menu added to all help buttons

    Click any help button (?) and select "Lessons..." to see all available training, even if there's no specific lesson for the current screen.

  • Improvement Intro lesson waits for catalog refresh

    The welcome lesson waits to make sure all content is loaded before starting, so it won't fail if you enable Training Mode right after opening the app.

  • Improvement Automatic dialog avoidance

    When you open a dialog during training, the player automatically moves aside so both windows stay visible, then returns to its original spot when you close the dialog.

  • Improvement Intro lesson plays once per session

    The welcome lesson only plays the first time you turn on Training Mode each day—toggling it off and on again won't replay the introduction.

  • Improvement Enhanced z-order management for training player

    The training player now reliably stays on top and clickable even when other windows are open, so you can follow along with lessons without interruption.

  • Improvement Shared spotlight overlay between training components

    The spotlight overlay (which dims the screen and highlights the target) is now shared between Training Mode's glowing frame and active lesson steps, rather than creating a new overlay for each lesson. This prevents visual conflicts and ensures smooth transitions.

  • Improvement Lesson list window stays accessible during training

    Applied ModalSurvivor to the lesson list window so it remains usable when other dialogs are open, consistent with the training player window behavior.

  • Bug Fix Spotlight overlay positioning when maximized

    When using interactive training while Margin Master is maximized, the spotlight overlay now properly fits the window without extending past the screen edges.

  • Bug Fix Spotlight overlay positioning on mixed-DPI displays

    When using multiple monitors with different display scaling settings, training spotlights previously appeared offset from the highlighted area. This is now fixed and spotlights align correctly.

  • Bug Fix Removed window glow effect in training mode

    The blue glow that appeared around the window edges during training lessons has been removed because it was spilling onto other monitors in multi-screen setups.

  • Bug Fix Training overlay positioning on maximized windows

    When using training mode with Margin Master maximized, the spotlight overlay now appears in the correct position on your screen.

  • Bug Fix Rounding schemes lesson dialog detection

    The interactive training for rounding schemes now correctly waits for the Edit Rounding Scheme dialog to appear before continuing.

  • Bug Fix Training windows survive modal dialogs

    Training lessons now work properly when walking you through dialog windows—the training instructions stay visible and usable.

  • Bug Fix Spotlight overlay repositions after DPI changes

    The training spotlight effect now stays properly positioned when you move Margin Master between monitors with different scaling settings.

  • User Interface Modern card-style training player design

    The training player now looks more modern with a sleek, rounded design and shows your progress through each lesson with a visual progress bar at the bottom.

  • User Interface Step counter added to training progress indicator

    When following a training lesson, you'll now see "Step 3 of 7" (for example) displayed next to the progress bar, making it easy to know exactly where you are in the lesson.

  • User Interface Draggable training player with persistent positioning

    You can now drag the training player to any position on screen by clicking and dragging the top bar, and it will stay where you put it.

  • User Interface Resizable training player window

    You can now resize the training window by dragging the corner to make it larger or smaller.

  • User Interface Help menu adds "Training (preview)" option (Debug builds only)

    In preview builds, you'll see a "Training (preview)" option in the Help menu that starts the sample lesson.

  • User Interface Refined lesson instructions

    Updated the sample Options lesson with clearer wording, instructing users they can close the Options window at their convenience rather than requiring it before clicking Finish.

  • User Interface Lesson list elements now targetable

    Added x:Name identifiers to lesson list UI elements (AllLessonsHeading, LessonIdBox) and the main window's "Show Lessons" button (btnShowLessonsPill), allowing the introductory lesson to highlight and reference these interface elements directly as part of its interactive tutorial.

  • User Interface Redesigned training player controls and layout

    Reorganized button layout with new pill-style buttons, moved the Exit button to the header for quicker access, added a resize grip in the bottom-right corner, and implemented a StepDots visual progress indicator that shows completed steps in accent color, the current step wider and white, and upcoming steps dimmed.

  • User Interface Training mode activates window glow effect

    When training mode is active, the main window shows a subtle cyan glow around its border.

  • Architecture Lesson asset extraction system

    Enhanced Lesson.LoadEmbedded method to extract embedded audio files (MP3) to the local file system on first use, with file existence and size validation to avoid re-extraction. Audio paths in lesson steps are resolved to absolute local paths when an asset folder is provided, enabling the narrator to play pre-rendered audio instead of synthesizing speech at runtime.

  • Architecture Training library independent of DevExpress and UI framework

    MarginMaster.Training is a standalone library with no dependencies on DevExpress or MarginMaster.UI.WPF. The host application implements ITrainingHost (perform actions, locate UI elements) and ITrainingLauncher (start lessons), while the library handles lesson playback, narration, spotlight overlay, and progress tracking. WpfTrainingHost reuses ScreenshotRunner's menu/reflection helpers to drive the UI consistently.

  • Architecture Updated lesson catalog structure

    LessonCatalog.FindById() now accepts both slug-style IDs ("rounding-schemes") and short numeric references ("1002" or "#1001"), improving flexibility for support scenarios and documentation references.

  • Infrastructure Lesson audio rendering script

    Added Render-LessonAudio.ps1 PowerShell script for authoring-time rendering of lesson narration. The script reads a lesson.json file, sends each step's text to Azure Speech REST endpoint, and writes MP3 files to the lesson's audio folder. Supports configurable voice selection (default: en-US-AvaMultilingualNeural), region, and speaking style.

  • Infrastructure Added overlay lifecycle tracing

    Added diagnostic trace logging to the spotlight overlay to track when the frame is shown or hidden, when the overlay window appears, and when fallback positioning logic is used. This will help diagnose any future issues with the training overlay not appearing correctly or following the main window properly.

  • Infrastructure Developer testing hook for training mode

    Added a debug-only environment variable (MM_TRAINING_MODE=1) that automatically enables training mode at startup, making it easier for developers to test overlay behavior without manual interaction.

  • Infrastructure Training diagnostic logging

    Added trace logging throughout the training system that reports step transitions, signal satisfaction, and lesson progress to the application log. This helps diagnose lesson authoring issues and player behavior during development and support scenarios.

  • Infrastructure Training progress stored per-machine

    Implements LessonProgressStore that saves lesson progress (current step index, completion status) to a JSON file in CommonApplicationData. Lessons automatically resume where the user left off, and completed lessons are marked as done.

  • Infrastructure JSON-based lesson format with embedded catalog

    Defines a lesson format supporting step narration (text-to-speech or pre-recorded audio), targets (menu items, commands, Options tabs, named elements), wait conditions, and auto-advance. Lessons are cataloged by documentation slug so help buttons can find the matching lesson. The sample catalog and lesson are embedded as resources.

  • Infrastructure Spotlight overlay window with click-through transparency

    Implements SpotlightOverlay as a transparent, topmost, click-through window that dims the entire screen except for the target rectangle, which pulses with an animated outline. Uses Win32 extended window styles (WS_EX_TRANSPARENT, WS_EX_LAYERED) to allow interaction with the main window while the overlay is visible.

  • Infrastructure Windows Speech API integration for narration

    Adds System.Speech package reference (10.0.11) and implements WindowsNarrator using SpeechSynthesizer for text-to-speech and MediaPlayer for optional pre-recorded audio files. Prefers natural-sounding English voices when available, supports cancellation, and runs on the UI thread as required by MediaPlayer.

Infrastructure & Internal

  • New Feature Cloud-hosted training content with local caching

    Training lessons automatically update from the cloud when you turn on training mode, so you'll always have the latest content without needing to update the application. If you're offline, the app uses built-in lessons so training always works.

  • New Feature Lesson audience targeting system

    Training lessons may now be customized for your specific vendor, POS system, or even your individual store.

  • New Feature Launch lessons directly by ID

    You can now type a lesson ID from the documentation into the lesson list and click Start to jump straight to that lesson.

  • Improvement Background training content synchronization

    When you open Margin Master, it now quietly downloads the newest training lessons in the background so they're ready whenever you need them, even if you go offline later.

  • Improvement Training Mode access control

    Training Mode menu visibility changed from a debug-only compile-time flag to runtime check based on IsSupportMachine property. The menu item now appears only on machines registered in RS_Data.SupportMachines and verified via the /api/support/machines/check endpoint, ensuring training features are restricted to authorized support personnel.

  • Improvement Graceful failure handling for content refresh

    The background refresh task logs any failures but allows the application to continue using cached or embedded lessons without interruption. Screenshot mode automatically skips the refresh to avoid external network calls during automated testing.

  • Improvement Automatic catalog refresh after content sync

    When training mode is activated, the app syncs content from the cloud and then reloads the lesson catalog, ensuring newly published lessons appear immediately. The TrainingLauncher now exposes a ReloadCatalog method to refresh the catalog from the updated content folder without restarting the application.

  • Cloud Sync Selective training content download

    The cloud sync process now downloads the lesson catalog first, filters it by the current store's context (vendor, POS system, store number, and organization), then downloads only the applicable lesson files and their audio narration. This reduces bandwidth usage and local storage while enabling vendor-specific or store-specific training content.

  • User Interface Help menu simplification

    Removed IsTrainingPreviewVisible property from MainMMViewModel and simplified XAML binding to directly use IsSupportMachine. This eliminates technical debt from the training mode spike and aligns the feature with the application's existing support machine authorization system.

  • User Interface Removed DevExpress glow effect from training mode

    The blue glow effect around the window in training mode has been removed for a cleaner look.

  • User Interface Filtered lesson catalog display

    The training lesson list now shows only lessons relevant to your store's vendor and point of sale system.

  • Infrastructure Training context integration

    The training host now provides the store's configuration context (vendor type, POS system type, store number, and organization ID) to the training launcher. This context is used to filter the lesson catalog when loading from either embedded or cloud-synced content.

  • Infrastructure TrainingContentSyncService for cloud synchronization

    A new service pulls training content from Azure blob storage, comparing blob modification times against local files and downloading only what has changed. Files are written to a temporary .download file and moved atomically to prevent corruption. Failures are logged but never disrupt the user experience since embedded content remains available.

2026.828.26403
August 28, 2026

Introduction and Core Concepts Page; Installation Prerequisites and SQL Server Setup Pages; Saved selections documentation expanded.

User Interface

  • Improvement Updated Propello documentation

    Updated the Propello import guide documentation to reflect the new confirmation message wording, ensuring consistency between the application and help documentation.

  • Improvement Enhanced Propello failure reasons

    Failure reasons in the push report now include more detailed validation messages from the Propello library itself, providing better context when items cannot be uploaded during bulk operations or retry attempts.

  • Bug Fix Propello push report formatting corrected

    When a price update fails to push to Propello, the error report now clearly shows which SKU and store were affected instead of running the numbers together.

  • User Interface Clearer Propello pre-send confirmation dialog

    When you send prices to Propello Price Review and some items are already waiting there, the confirmation message now more clearly explains that sending again is safe: any SKU you're re-sending will have its price updated, but other items already waiting won't be removed.

  • User Interface Clarified Propello pre-check prompt wording

    Before sending prices to Propello, if some items are already waiting, you'll see a clearer explanation that re-sending a SKU replaces its pending price without removing anything else from the queue.

Reporting & Exports

  • Bug Fix Propello push report formatting improved

    When pricing updates fail to upload to Propello, you'll now see each failed item clearly labeled with "SKU [number] @ store [number]: [reason]" instead of confusing columns that ran together.

Infrastructure & Internal

  • New Feature Introduction and Core Concepts Page

    New *How Margin Master Thinks* page introduces the three foundational ideas behind the application: vendor pricing as a baseline (not the final answer), hierarchical strategy execution, and rounding as a margin improvement tool. Serves as the handbook's conceptual introduction before installation chapters.

  • New Feature Installation Prerequisites and SQL Server Setup Pages

    Added *Prerequisites* page covering system requirements, SQL Server versions (2022/2025 supported), network needs, and pre-installation checklist. New *Install or Upgrade SQL Server Express* and *Install or Upgrade SQL Server Management Studio* pages document the SQL Server Tools window's guided installation process, including instance naming (`MARGINMASTER`), backup behavior during upgrades, and reboot handling. The older in-app installer documentation is now support-only.

  • New Feature Saved selections documentation expanded

    Expanded "Load Saved Selection" documentation to "Save and Load Saved Selections," now covering the camera button workflow for saving the current selection boxes and Future Price panel settings as a named snapshot, and explaining how saved selections serve as both reusable filters and strategy steps.

  • New Feature Main Window Component Pages

    Split the main window orientation into focused pages: *The Menus* (every menu item with keyboard shortcuts), *The Button Row* (all 10 toolbar buttons numbered with explanations of vendor SKU vs. non-vendor SKU filtering), *The Main Data Grid* (column meanings, color coding, symbol columns, right-click actions), *The Summary Section* (Displayed/All/None modes, monthly impact columns, export options), and *Banners and Badges* (every title-bar pill and banner with meanings and actions). *Main Window Orientation* is now the chapter's landing page linking to each detailed page.

  • New Feature Store Manager Reframed as Data Processing Hub

    The Store Manager guide now clearly explains why matching your stores to vendor store numbers is essential for correct pricing, and how to fix stores that show "needs setup" or import zero items.

  • New Feature Supported POS Systems master list

    You can now look up your point-of-sale system in the handbook's POS Systems chapter and find either a complete import guide or a page confirming the system is supported with next steps.

  • New Feature Strategy hierarchy guide

    Added documentation explaining how pricing strategies execute top-to-bottom with last-step-wins behavior, using a worked example of a hardware store pricing paint at 42% margin while holding sensitive items to Level 1 price. Emphasizes general-to-specific ordering and how PSRule shows which step finally priced each SKU.

  • New Feature Stub Pages for Cross-References

    Added first-draft *Printing and Exporting* and *Rebuild Data* pages so new pages' links resolve; these will be expanded in later phases. All pages carry proper frontmatter matching `handbook-map.json` structure (part, chapter, order).

  • New Feature Supported POS Systems Complete List

    You can now see a complete list of every point-of-sale system Margin Master works with, even if detailed setup instructions are still being written.

  • New Feature Creating strategy steps guide

    Added step-by-step documentation for creating a strategy step from the main window: set selection boxes, configure the Future Price panel action, then press the camera to save the snapshot as the newest step in the active strategy. Explains all "Set Future Price to" options including vendor price levels, target margin, cost breaks, fixed retail, and margin snapshot.

  • New Feature Vendor Settings and POS Connections tab documentation

    The handbook now explains how to set up Do it Best mailbox connections, test them, and configure Ace Direct SKU handling through the Options window.

  • New Feature Updating and deleting steps guide

    Added documentation for managing existing strategy steps in the Strategy Manager, including re-ordering with Up/Down buttons (Ctrl for 5 places, Alt for top/bottom), activating/deactivating steps, renaming, editing conditions and rounding, and the Load workflow for changing a step's core selection or action.

  • New Feature Troubleshooting Vendor Sync Guide

    New guide helps you diagnose and fix issues when vendor data sync fails or doesn't update prices as expected.

  • New Feature Advanced topics: Store Grouping and Troubleshooting Vendor Sync

    The handbook now covers how to group stores for shared pricing and how to diagnose why vendor data sync might fail or appear incomplete.

  • New Feature Reviewing and executing strategies guide

    Added documentation covering pre-run strategy review (checking step order, SKU counts, active status), executing with Ctrl+X, interpreting the Strategy Execution Summary (sitting margin, profit impact, "Not priced" warnings), and using "Show Skus NOT included in Strategy" to find items no step priced.

  • New Feature Store Grouping Advanced Topic

    Advanced multi-store users can now learn how to group stores together for unified pricing across locations in the same market.

  • Improvement Store Manager repositioned as data-processing hub

    The Store Manager guide now explains clearly why matching your stores to vendor numbers is required for accurate pricing and how to fix stores that won't import.

  • Improvement Troubleshooting sections added to 17 POS import guides

    Each POS import guide now includes a troubleshooting table showing what to check when imports fail or data doesn't appear.

  • Improvement POS Import Troubleshooting Sections

    Every POS import guide now includes a troubleshooting table to help diagnose common issues like "no files found" or imports that complete but don't update the grid.

  • Improvement Reworked SQL optimization documentation with symptom-first approach

    The database troubleshooting guide now starts with common symptoms like slow refreshes and tells you which tool to run first, making it easier to fix performance problems without needing database expertise.

  • Improvement Cloud Vendor Data Sync Updates

    The vendor sync documentation now clearly shows which vendors are fully supported and which are in development.

  • Improvement Vendor sync guide updated for True Value and Emery Jensen

    The vendor sync guide now mentions True Value members and Emery Jensen stores and explains that your chosen vendor determines which catalog data is synced.

  • User Interface Options Window and Settings Documentation

    The handbook now includes step-by-step guides for every setting in Tools > Options, making it easier to configure import paths, export formats, vendor connections, and data preferences.

  • User Interface Options Window documentation suite

    The handbook now explains every setting in Tools > Options, where to find import/export paths, how to test POS connections, and what each vendor-specific option does.

  • User Interface Selection boxes documentation

    Added complete guide explaining how selection boxes work on the main window, including left-click include vs right-click exclude behavior, Shift-range selection, type-to-scroll navigation, how boxes combine (OR within, AND across), and special comparison boxes for price, cost, margin, quantity, and date fields. Also documents the PSRule box, Store Number display options, and the F12 clear-all shortcut.

  • User Interface New handbook chapter: How Margin Master Updates

    You can now read about how Margin Master updates itself and choose the update method that works best for your computer in the new handbook chapter.

  • User Interface Margin Master branding consistency sweep

    User-facing text now says "Margin Master support", "Margin Master cloud" and "Margin Master licensing server" instead of RetailerSoft. RetailerSoft remains where it names the company (installer signature, file paths under %ProgramData%\RetailerSoft). The engineering notes file at the docs root gained internal-only frontmatter so it no longer publishes publicly; the firewall guide is now in the search index.

  • User Interface POS / Connections Tab Documentation

    Clear guidance now available on where to configure your point-of-sale connection based on which system your store uses.

  • User Interface New handbook chapter: Importing from Excel

    The Excel import feature now has its own detailed guide showing how to map spreadsheet columns to Margin Master fields and save those maps for reuse.

  • User Interface New handbook chapter: Cost Break Strategies

    You can now read step-by-step instructions on how to use cost break models in your pricing strategies to apply sliding margins based on item cost ranges.

  • User Interface New handbook chapters: Catalog Lookup, What's New, and Help Buttons

    New handbook pages explain how to look up vendor catalog information for any SKU, view what changed in each version update, and use the help buttons found on most Margin Master windows.

  • User Interface Button Row Screenshot

    Added numbered `button-row.png` screenshot with 10 labeled buttons; main window screenshots updated with support-only icons redacted from toolbar (Implementation Plan and Pricing Equation Analysis buttons blanked in manifest).

  • Infrastructure Handbook reading order established

    Every doc under docs/marginmaster/ now carries part / chapter / order frontmatter mirroring the new docs/handbook-map.json, which defines Introduction + Parts I–VIII across 21 chapters. HandbookMapTests in MarginMaster.Tests fails the build when a doc is missing from the map, frontmatter disagrees with the map, two docs share an order in a chapter, or a user-only doc is parked in the appendix. Reference material (installation scripts, catalog-file layouts, engineering notes) stays in an Appendix on purpose.

  • Infrastructure User handbook expansion - selection boxes and strategy building

    The online help now includes detailed guides on using selection boxes, saving your work with the camera button, and building pricing strategies step-by-step with real examples.

  • Infrastructure Handbook map tests enforce documentation structure

    Added HandbookMapTests.cs with four enforcing tests: every doc is placed in a chapter or listed in the appendix on purpose, frontmatter matches the map, orders are unique within each chapter, and user-only docs are not parked in the appendix. Drift between the map and the files now fails the build instead of silently scrambling the handbook's reading order.

  • Infrastructure Handbook Map Synchronization Script

    New `docs/sync-handbook-map.py` Python script regenerates `handbook-map.json` and `index.json` from document frontmatter, ensuring the table of contents, navigation links, and search index stay in sync with the docs. Handbook now has Introduction (Part 0) plus Parts I–VIII with 21 chapters.

  • Infrastructure Completed handbook first pass

    This phase completes the handbook's first full pass with Introduction plus Parts I–VIII, every chapter now populated. Includes 826 lines added across 12 documentation files, updating the handbook map, search index, and changelog. Co-authored with Claude.

  • Infrastructure Handbook structure and navigation

    Updated handbook-map.json and index.json to organize the new pages into Chapter 13 (Selection Boxes) and Chapter 15 (Building Pricing Strategies) within Part VI (Learning Margin Master), with proper ordering, search keywords, and cross-references.

  • Infrastructure Handbook structure and index regeneration

    Updated handbook-map.json with 213 new lines placing all new pages into the correct Parts/Chapters (Part III Initial Configuration gains Chapter 6 Tools > Options with 6 docs, Chapter 7 POS Systems gains 46 docs, Chapter 8 Store Manager gains store-grouping cross-reference; Part VII Advanced Topics gains Chapter 18). Regenerated index.json with 2,254 new lines covering all new pages, updated timestamps, corrected titles, and refreshed body excerpts. All 17 modified POS guides and 8 new/modified Getting Started pages carry last_updated "2026-08-28".

  • Infrastructure Options Window Screenshot Manifest

    Added options.manifest.json defining screenshot capture specifications for the Options window (window-relative crops at 1600×1000, showing navigation, tabs, and buttons) with shots for overview, Miscellaneous tab, Export Options tab, and Ace Hardware tab.

  • Infrastructure Handbook Map and Search Index Updates

    Updated handbook-map.json with 213 new entries organizing the Options, POS Systems, and Store Manager chapters; regenerated index.json with 2,254 additions reflecting all new pages, updated titles (Store Manager → "Store Manager: The Hub of Data Processing"), reordered items (Supported POS Systems now order 2 in Chapter 7), and search keywords for every new guide.

2026.827.40550
August 28, 2026

Damaged .NET runtime detection at startup; Automatic damaged-runtime detection at startup; Propello Options tab: Save & Test connection.

Strategy & Pricing

  • Bug Fix Cost break target margin input now stores values correctly

    When setting up cost break pricing levels, typing a target margin percentage like "70" now correctly saves as 70% instead of 7,000%, and the calculated prices will be correct.

  • Bug Fix Cost break Target Margin calculation error

    If you previously entered a Target Margin like "70" and saw strange negative prices, those cost breaks will now calculate correctly. Any affected cost break strategies will automatically heal when you view them.

  • Bug Fix Self-healing logic for existing misconfigured cost breaks

    Cost breaks that were previously saved with incorrect margin values (showing thousands of percent) will automatically fix themselves and start working correctly.

  • Bug Fix Culture-invariant cost break SQL generation

    Changed BuildCostBreakSQL to emit From/To/TargetMargin values using InvariantCulture formatting to prevent localization issues where decimal separators could corrupt the generated SQL on systems with different regional settings.

  • User Interface Target Margin input mask added

    When editing Target Margin in cost break levels, the cell now guides you to enter values as percentages and prevents incorrect entries.

  • Infrastructure Cost break validation tests

    Added comprehensive unit tests (CostBreakTargetMarginTests) to verify that whole-percent values (1 or greater) are correctly converted to fractions, while existing fractional values and edge cases remain unchanged.

  • Infrastructure Test coverage for target margin normalization

    Added comprehensive unit tests (CostBreakTargetMarginTests) to verify that whole percent values (70, 42.5, 100) are converted to fractions (0.70, 0.425, 1.00) while existing fractional values remain unchanged, preventing regression of this critical pricing bug.

Imports & POS

  • New Feature Propello Options tab: Save & Test connection

    Go to Tools > Options > Propello, enter your Propello URL (for example "anchorace" or "https://anchorace.epicorretailcloud.com/"), username and password, then click Save & Test. Margin Master will verify the connection and save it. If the test reports a permissions problem, ask your Propello administrator to grant the listed rights to the user, then test again.

  • New Feature Direct Propello cloud connection

    Set up the connection once in Tools > Options > Propello with your store's Propello web address and login. After that, Get POS Data downloads your inventory automatically.

  • New Feature Direct POS download from Propello

    After connecting Propello in Tools > Options, click Data > Get POS Data. Margin Master will download the product export from Propello and show how much time is left. If it fails, you can still import an Excel file you exported from Propello yourself.

  • New Feature Price Review upload from Print dialog

    Use Print/Export and choose "Propello Price Review" to send your price changes straight into Propello — they land in Price Review for you to approve in the portal.

  • New Feature Propello Price Review upload from Print/Export

    Select the rows you want to change in Propello, click Print/Export, choose "Propello Price Review" and enter the date you want the new prices to take effect. Margin Master will send the changes to Propello Price Review (they will not be finalized automatically) and show you what was uploaded.

  • Improvement Guided setup prompt for unconfigured Propello connections

    If you haven't set up Propello yet, clicking "Get POS Data" will now show a helpful message asking if you want to set up the connection now, making first-time setup easier.

  • Improvement Cloud connection availability check for Propello

    When you open Propello settings, Margin Master now checks what connections are saved in the cloud and updates the Restore from Cloud button accordingly.

  • Improvement RscGate enforces one RSC rule across all import paths

    A new centralized RscGate decision point now applies the same RSC validation rule at every Do it Best per-store build site: the drain rebuild, BisTrack Direct SQL and CSV imports, legacy BCP ingest, Propello, and Compass catalog merges. This ensures no import path can bypass the RSC requirement or accidentally build against the wrong catalog.

  • Improvement RSC lookup logic simplified and documented

    The GetSpecificRSCResponse model now includes IsResolved and RequiresRsc properties that clearly indicate whether a store can be built. The fallback ladder (ResolveEffectiveRsc) that borrowed RSCs from other sources has been removed. A new RscGate service provides a single, testable decision point used by all import paths (drain, BisTrack preload, legacy BCP ingest, Propello/Compass merges) to enforce the "no RSC means not built" rule consistently.

  • Improvement Restore button disabled when no connections available

    The Restore from Cloud button is now disabled until you've successfully saved at least one Propello connection, with a clear explanation of why it's unavailable.

  • Improvement Propello progress message formatting refinement

    Progress messages during Propello imports now display time information more cleanly without duplication.

  • Improvement Propello API export compatibility

    Propello's Inventory Viewer export (requested through the API with the "Margin Master (Auto)" saved view) uses different column headers than the hand-exported Products grid ("Store Number" vs "Store #", "curr_month_less_0_sales_units" vs "Feb-26"). Import column definitions now recognize both spellings through aliases, so cloud downloads and manual exports import through the same code path without requiring schema changes.

  • Improvement Connection test and restore from cloud

    The new Propello tab in Options includes a "Save & Test" button that validates credentials by logging in and creating/repairing the saved view Margin Master needs. Propello connections are backed up to the RetailerSoft cloud after a successful test and can be restored from the cloud if the local settings are lost, matching the workflow for other POS connections.

  • Improvement Duplicate removal now runs after every store build

    RemoveDuplicatesFromMainTable now runs after every per-store build (previously skipped by some import paths), is guarded to safely handle missing tables, and orders by [ID] to keep the first-inserted row rather than picking arbitrarily. This ensures exactly one row per (StoreNumber, SKU) in every main table.

  • Improvement User-friendly Propello failure messages

    When a Propello operation fails, Margin Master explains the problem in store-owner terms: "bad credentials" if the username/password is wrong, "permissions issue" if the Propello user lacks required rights (with a list of the rights needed), and "portal or network" for timeouts or connectivity problems. A manual fallback lets stores import a hand-exported file if the cloud download fails.

  • Bug Fix Fixed BisTrack CSV imports creating duplicate SKUs

    If you use BisTrack CSV imports and noticed the same item appearing multiple times in your pricing grid after import, this fix ensures each SKU loads only once. Verified with a 22-store customer file: 23,712 SKUs now correctly produce 23,702 distinct entries instead of 93,459 duplicated rows.

  • Bug Fix Fixed BisTrack CSV import creating duplicate SKUs

    Previously, after importing BisTrack CSV files, you would see the same SKU repeated multiple times in the pricing grid. This has been fixed—each SKU now appears only once after import.

  • Bug Fix RSC is now store-specific and never borrowed

    Do it Best stores must now have their own RSC assigned in Store Manager to import correctly. If a store is missing its RSC, it will appear in the "NOT IMPORTED" list at the end of the import with instructions to set the RSC and re-import.

  • Bug Fix Do it Best RSC enforcement prevents incorrect pricing

    If your Do it Best store doesn't import, check the import results screen for "no RSC set in Store Manager" — open Store Manager, set the correct RSC for that store, and re-import.

  • Bug Fix Excel header range expanded to support full Propello API exports

    When importing Propello API exports, all 240 columns of data are now successfully imported. Previously, the last five columns were silently lost.

  • Bug Fix BisTrack stores no longer exempt from RSC filter

    BisTrack Direct SQL stores were previously exempt from RSC filtering (skipRscFilter flag), which caused every SKU to appear multiple times when multiple RSCs existed in the catalog. This exemption is removed—all Do it Best stores now filter by their assigned RSC.

  • Bug Fix Main table duplicate removal now keeps deterministic rows

    The RemoveDuplicatesFromMainTable SQL query now keeps the first-inserted row (lowest ID) when deduplicating on StoreNumber and SKU, rather than letting SQL Server pick arbitrarily. The query is now guarded to safely run on tables that may not exist. All Do it Best import paths (BisTrack 1040, BisTrack 6828, legacy BCP, drain refresh) now run this deduplication step.

  • Bug Fix RSC predicate now correctly applied in legacy BCP imports

    The legacy BCP ingest's RSC filter targeted outdated SQL syntax that the query builder no longer emitted, causing the filter to silently fail. The replace logic now targets the correct JOIN syntax and validates that it matches what the builder actually generates.

  • Bug Fix BisTrack Direct SQL RSC filter now applies correctly

    The RSC filter for BisTrack Direct SQL stores was silently failing because the string replacement targeted outdated SQL syntax that the query builder no longer emits. The replacement now targets the current "LEFT JOIN [MMVendorData] ON [MMVendorData].[SKU] = " syntax and includes validation to detect future mismatches. BisTrack Direct SQL is no longer exempt from RSC filtering — stores at multi-RSC organizations now receive correct, filtered pricing.

  • Bug Fix Connection save now awaited to update cloud count immediately

    Changed the cloud backup during Save & Test from fire-and-forget to awaited, ensuring that CloudConnectionCount is immediately updated to reflect the newly saved connection. This guarantees the Restore button becomes enabled right after a successful save operation.

  • Data Import Propello header alias support for API exports

    When importing Propello files, the system now automatically recognizes different header names from API downloads and manual exports, so you no longer need to worry about which export method was used.

  • Data Import Comprehensive alias mapping for Ace Hardware and Do-It-Best columns

    All Propello column variations for Ace Hardware and Do-It-Best imports are now recognized automatically.

  • Data Import Import Manager now reads wider Excel files

    Both the general Excel file reader and the Propello-specific import service have been updated to handle wider spreadsheets, ensuring compatibility with current and future Propello API export formats.

  • User Interface Import workflow improved for first-time Propello users

    New users will see a clear explanation of how to connect to Propello, with the option to go directly to the settings screen.

  • User Interface Dynamic tooltips for Restore from Cloud button

    Hovering over the Restore from Cloud button now shows helpful information about whether saved connections are available and how many exist for your store.

  • User Interface Store configuration errors reported consistently

    Stores that cannot be built due to missing or invalid RSC mappings are logged at Warning level and added to the store configuration issue collector with severity "NotImported". The import results screen displays these stores in a "NOT IMPORTED" section with actionable messages like "no RSC set in Store Manager — set it and re-import" or "RSC '04' is set but the synced vendor data has no rows for it — sync vendor data for RSC 04 and re-import".

  • User Interface Store configuration issues now report missing RSCs

    After importing, any Do it Best stores missing an RSC will be listed in the "NOT IMPORTED" section with instructions on how to fix the issue in Store Manager.

  • Database Propello credentials in settings

    Three new application settings store the Propello connection: PropelloUrl (normalized https tenant URL), PropelloUsername, and PropelloPassword (DPAPI-encrypted per machine). The password is excluded from the settings-transfer delete-on-default list so it always persists, and all three are backed up to the cloud after a successful test.

  • Architecture Added BuiltMainTables flag to POS import handlers

    Introduced a new property on the POS import handler interface that allows handlers to signal whether they built the per-store main tables during the ingest phase. This flag is now passed from the handler through the Import Manager to the main import process, ensuring the rebuild step has accurate information about what work has already been completed. Added comprehensive unit tests to prevent future regressions by ensuring this flag travels the correct path through the application.

  • Architecture GetSpecificRSCResponse simplified to resolved/not-resolved

    GetSpecificRSCResponse now carries RequiresRsc, MappedRsc, and IsResolved properties instead of fallback tracking (UsedFallback, FallbackSource). The ResolveEffectiveRsc ladder method and its tests are deleted—there is no longer any RSC borrowing logic.

  • Infrastructure Added test coverage to prevent flag-reading regression

    Introduced comprehensive unit tests (PosIngestBuiltMainTablesFlagTests) that enforce the correct path for the "main tables built during import" flag. These tests verify that MainMMViewModel never reads the flag from its own service instance, that ImportFilesViewModel correctly retrieves it from the handler, and that all BisTrack handlers properly report whether they built the tables. This prevents future regressions of the quadruplication bug.

  • Infrastructure MarginMaster.Propello library integration

    The MarginMaster.Propello library (sibling repo, cloned by publish.yml next to FileHelpers.Core) is referenced as a ProjectReference and wrapped behind one interface (Services/Propello/IPropelloConnectionService implemented by PropelloConnectionService). No other Margin Master file sees the library namespace — all consumers (ViewModels, tests) talk in library-free DTOs (PropelloConnectionSettings, PropelloProgressInfo, PropelloTestResult, PropelloDownloadResult, PropelloPushOutcome, PropelloUserError). The pure helpers (PropelloUrlNormalizer, PropelloUserMessages, PropelloSplashProgress, PropelloPriceChangeBuilder) are unit-tested in MarginMaster.Tests/Propello/PropelloIntegrationTests.cs (34 tests) without needing a live Propello tenant. Credentials are backed up to api/pos/credentials (new PosCredentialDescriptor.ForPropello, AuthMode=Web) and reported after each import like the other POS types. Documentation added: propello.md, import-propello.md, index.json, version-map.json, CLAUDE.md updates.

  • Infrastructure Test coverage for header alias resolution

    Added PropelloHeaderAliasTests validating that the 240-column API export header row resolves correctly, that hand-exported headers remain unchanged, and that alias matching is case-insensitive. Added integration test ensuring the progress message formatting handles library-appended elapsed time correctly.

  • Infrastructure Propello library integration

    A new sibling library (MarginMaster.Propello) handles all direct interaction with the Epicor Retail Cloud portal: login, saved-view creation, report export download, Price Review status checks, and price-change upload. The library is referenced only by PropelloConnectionService; the rest of the application (ViewModels, tests) works with library-free DTOs, keeping the portal-specific logic isolated and unit-testable.

Cloud Sync & Vendor Data

  • Improvement Auto-load Propello credentials from cloud

    If you install Margin Master on a new computer, your Propello connection settings will be automatically filled in from your cloud-saved configuration. You'll see a message showing when the connection was last validated, and you just need to click "Save & Test" to confirm it still works.

User Interface

  • Improvement Propello setup shortcut

    When setting up Propello for the first time, clicking "Yes" on the connection prompt will now take you directly to the Propello settings tab instead of making you find it yourself.

  • Improvement Clearer URL placeholder text

    The Propello URL field now shows a clearer example of what to type.

  • Improvement Repositioned permissions reminder

    The message about contacting your Propello administrator for permissions issues was moved from the static help text to an italicized note at the bottom of the contextual help panel, making it visible regardless of which field is focused.

  • User Interface Dynamic help panel in Propello settings

    When setting up your Propello connection, click into any field to see specific instructions about what to enter there. The help panel on the right updates automatically to guide you through each step.

  • User Interface Legal document menu added

    Click Help > Legal to open any of the three legal documents in your web browser.

  • User Interface Legal submenu added to Help menu

    The Help menu now includes a Legal submenu where you can view the End User License Agreement, Privacy Policy, and Terms of Use by clicking on any of these options.

  • Infrastructure License file updated to proprietary terms

    Replaced the placeholder MIT license template in LICENSE.txt with the actual proprietary licensing terms. The file now clearly states that Margin Master is licensed software (not sold), references the online EULA, and notes that vendor data is confidential proprietary information that may not be disclosed or duplicated except as permitted by the EULA.

  • Infrastructure License file updated to reflect proprietary licensing

    The LICENSE.txt file has been replaced with a proprietary license notice indicating that Margin Master is licensed software owned by RetailerSoft, Inc. The file now references the EULA and related policies available at marginmaster.com, establishing the website as the authoritative source for license terms.

Performance & Reliability

  • New Feature Damaged .NET runtime detection at startup

    When you open Margin Master, if Windows runtime files are missing (often due to antivirus quarantine or a failed Windows update), you'll see a dialog listing exactly what's missing with a button to repair it automatically.

  • New Feature Automatic damaged-runtime detection at startup

    On launch, Margin Master now checks that all the Windows system files it needs are intact. If something is missing, you'll see a clear message explaining what's wrong instead of cryptic errors later.

  • New Feature Red ".NET Runtime Damaged" title-bar pill

    A red warning badge stays in the title bar until the runtime is actually fixed — you can't accidentally dismiss it and forget about it.

  • New Feature One-click runtime repair from dialog and title-bar pill

    When Margin Master finds a problem with the Windows runtime, a red warning appears in the title bar. Click it to run an automatic repair — Windows will ask for permission, then the script downloads and fixes the issue. The warning disappears once the repair finishes.

  • Improvement Enhanced version gate safety handling

    Improved the version gate logic to treat declining as an expected, safe user choice rather than an error condition. The application now properly cleans up and hides the loading splash screen when users choose not to proceed with opening a newer database.

  • Improvement Cloud sync failure now offers runtime repair when applicable

    If cloud sync keeps failing with every table erroring out, Margin Master now checks whether a Windows runtime file is missing and walks you through the repair instead of just saying "check the log."

  • Improvement Enhanced Install-DotNetRuntime.ps1 script with integrity check and repair mode

    The "Install .NET Runtime" support script is now smarter — it checks what files are missing, repairs the existing installation if it's up-to-date, or installs a newer version if available, then verifies the fix worked.

  • Improvement Global exception handlers offer runtime repair

    If Margin Master crashes with a missing-file error while you're working, it now recognizes when the problem is a damaged Windows runtime and offers the repair tool rather than a cryptic error message.

  • Improvement Install-DotNetRuntime.ps1 now repairs the current runtime

    The repair script now checks your installed runtime first and tells you exactly which files are missing, then either installs a newer version or repairs the current one, and re-checks afterward to confirm the fix worked.

  • Bug Fix Version gate decline no longer crashes application

    If you see a warning that a database was created by a newer version of Margin Master and click "No," the app will now stay open normally instead of crashing.

  • Bug Fix Application crash when declining version gate prompt

    If you're asked whether to open a database file from a newer version of Margin Master and click "No," the app will now continue running normally instead of crashing.

  • Cloud Sync Detect damaged runtime during sync and offer immediate repair

    If a cloud sync fails because Windows system files are missing, Margin Master now tells you exactly that and offers the repair button on the spot — no need to restart the app or contact support to figure out what's wrong.

  • User Interface Global exception handlers detect runtime damage and surface repair dialog

    Even if an unexpected error happens elsewhere in the app due to missing Windows files, Margin Master now recognizes the signature and shows the repair dialog instead of a confusing crash message.

  • Database Enhanced documentation and search keywords for runtime repair

    The support script's documentation (`docs/marginmaster/support/scripts/install-dotnet-runtime.md` and the script's own `.md`) now explains the repair workflow, the startup check, and the title-bar pill. New search keywords: "repair dotnet", "runtime damaged", "missing assembly", "System.Threading.Tasks.Parallel", "vcruntime140_cor3", "corrupt runtime". The troubleshooting section covers what to do when antivirus keeps re-quarantining the file.

  • Architecture FrameworkIntegrity detection shared across app layers

    The missing-assembly detector moved from RowVersionTableSync (CloudSync layer) to a new FrameworkIntegrity class in Common, now shared by the WPF app's startup check, sync error handler, and global exception handlers. It walks the exception chain for FileNotFoundException, BadImageFormatException, and DllNotFoundException, filters to System.* / Microsoft.* assemblies and known shared-framework native libs (vcruntime140_cor3.dll, etc.), and provides a CheckCurrentRuntime() method that reads the process's own NETCore.App + WindowsDesktop.App deps.json manifests and stats every declared runtime/native file. RuntimeRepairService in the WPF layer orchestrates the UI (one dialog, one script runner, one main-window pill) for all detection sites.

  • Infrastructure Centralized runtime-integrity logic in FrameworkIntegrity helper

    A new `FrameworkIntegrity` class provides pure, testable functions for reading `.deps.json` manifests, checking files on disk, and detecting framework-load exceptions. The bulk-upsert engine's existing `FindMissingFrameworkAssembly` logic was moved here and extended to handle `DllNotFoundException` for native libraries (`vcruntime140_cor3.dll`). Detection now covers managed assemblies, native DLLs, and both the `Microsoft.NETCore.App` and `Microsoft.WindowsDesktop.App` shared frameworks.

Infrastructure & Internal

  • New Feature Automated documentation screenshot generation

    No direct user impact—this is an internal documentation tool.

  • New Feature Automated screenshot generation for documentation

    A new `--screenshot --manifest=<file>` launch mode starts Margin Master like a headless run (no mutex, no startup dialogs), shows the main window at a manifest-specified size on a pinned theme, opens each listed dialog or menu through view-model commands, captures it as a PNG, and exits. Manifests live in `docs/<category>/screenshots/` beside each doc and specify which screens to open (main window, Options tabs, Print dialog, effective-date picker, or drop-down menus), optional view-model method invocations, property overrides to hide real store identifiers, and crop rectangles. A PowerShell runbook (`Update-DocScreenshots.ps1`) builds Debug and runs the capture against a test database. Screenshots are deterministic across machines (visual captures render at a pinned DPI), version-controlled, and served by Manager for web/PDF/Word rendering.

  • New Feature Automated screenshots for Getting Started documentation

    Documentation pages now include actual screenshots from Margin Master showing exactly where to find features and buttons, with numbered callouts matching the text.

  • Improvement Propello integration guide restructured with screenshots

    The Propello guide is now easier to follow with screenshots showing each step of setting up the connection, importing your data, and sending prices back to Propello.

  • Improvement Screenshot harness supports command invocation and highlights

    Extended the screenshot manifest to support `command` targets (invoking any public MainMMViewModel method), highlight annotations with optional numbered badge labels (red rounded outlines that draw attention to specific fields), automatic prompt dismissal during dialog closure, and settle delays for windows that load asynchronously. Commands can run to completion for setup steps (e.g., refreshing the grid so later dialogs have data) or capture the dialog they open.

  • Improvement Propello guide restructured with screenshots

    The Propello setup guide now has pictures showing exactly where to enter your Propello URL, username, and password, and where to click to import your data and send price changes back.

  • Bug Fix DIB member-retail error message corrected

    The error message when a DIB price file is missing now correctly refers to DIB files instead of Propello.

  • Bug Fix Corrected error message for missing DIB member retail file

    The "No DIB Price File Files Found" message now correctly reads "No DIB Price File (mbrxxxx.csv) Found" and instructs users to place "the DIB Member Retail Price File" in the import directory (was "Propello Export File").

  • User Interface Database and support documentation screenshots

    Added automated screenshots to seven documentation guides: SQL Optimization (Help menu, Database Utilities menu, Missing Index Recommendations window, Maintenance Scripts dialog), Resetting Data (Utilities menu), System Diagnostics window, Issue Submission (Help menu, Support Issues window, Contact step), and SQL Server Tools window. Menu paths corrected throughout documentation to reflect actual application structure (e.g., maintenance scripts live under File > Database > Utilities, not Help > Database Utilities).

  • User Interface Screenshot mode suppresses startup prompts and auto-update

    When `ScreenshotMode.IsActive` is true (set during screenshot startup), the What's New dialog, data-aging view, database rename prompt, and auto-update check are all suppressed so nothing modal lands on top of a capture. Startup checks still run to ensure a valid database and schema, but every dialog is headless-suppressed.

  • User Interface Ace Hardware pricing feature screenshots

    Replaced six placeholder SVG images in the MAP/IMAP pricing guide with real screenshots showing MAP Price and IMAP Price columns in the data grid (overview and close-up), Future Price panel with Ace MAP Price Amount selected, and the Data menu with "Update Ace Hardware Data" highlighted. Added screenshots to the Critical Retail Pricing guide showing the Strategy menu and configuration dialog with price mode toggle and comparison operators highlighted.

  • User Interface Documentation images with numbered callouts and flexible layouts

    Help documentation now shows zoomed-in screenshots of specific buttons and fields right next to the text explaining them, with numbered circles matching numbered instructions.

  • Infrastructure Pricing documentation screenshots

    Added 19 generated screenshots to 14 Pricing docs covering strategy manager, premade-strategy catalog, rounding editor and scheme check, custom groups, SKU exceptions, min/max strategies, cost breaks, Profit Analyzer, One Click Statistics, all three Future Price tabs, backup/restore pickers, wildcard selection, and lock column. Each screenshot is automatically captured from the running application using manifest files that script the UI, ensuring documentation stays current with the software.

  • Infrastructure Screenshot harness enhancements

    Extended the automated screenshot system to support nested dialogs (a shot that invokes a method opening a further dialog now captures that nested window with `opensDialog: true`), dotted property paths for setting view model state (`"FuturePricePanel.SelectedTabIndexFuturePriceRounding": "1"` navigates child view models), screen-level `set` executed before opening dialogs, and per-shot `settleMs` delays for asynchronous content. Automatic strategy backup is now suppressed during screenshot runs to avoid uploading demo-store data to the cloud.

  • Infrastructure Documentation maintenance

    Updated 14 pricing documentation files with embedded screenshots, numbered highlight badges linking images to text legends, and metadata refresh. The `docs/index.json` search index and `CHANGELOG.md` now reflect the new screenshots. This builds on the Getting Started screenshot work from the previous release.

  • Infrastructure Screenshot harness supports nested menu navigation

    Enhanced the screenshot automation system to accept nested menu paths using slash notation (e.g., "mnuFile/mnuDatabaseManagement/mnuDatabaseUtiltities"). The harness now opens each menu level sequentially and properly closes them in reverse order, enabling automated capture of deeply nested menu structures.

  • Infrastructure Screenshot manifest and conventions

    Documentation screenshots are defined in JSON manifests committed alongside docs (e.g., docs/marginmaster/pos-systems/screenshots/propello.manifest.json). Each manifest specifies window size, render scale, screens to open (main, options tabs, dialogs, menus), view-model methods to invoke, placeholder property values (to avoid showing real store identifiers), and crop rectangles. Output must be a .png inside a screenshots/ folder—the runner refuses to write anywhere else. Conventions and technical details added to docs/CLAUDE.md.

  • Infrastructure Screenshot manifest format and safety rules

    Screenshot manifests are JSON files specifying window size, render scale, and a list of screens (each naming a target: `main`, `options` + tab name, `print`, `effective-date`, or `menu` + BarSubItem name). Shots can invoke public view-model methods (e.g. `ShowFieldHelp`), set properties (to show placeholders instead of real store identifiers), and crop. The runner refuses to write any file that is not a `.png` inside a folder named `screenshots`, preventing accidental overwrites elsewhere. Tests enforce this rule and validate manifests against incomplete or unsafe configurations.

  • Infrastructure Screenshot manifest validation and annotation rendering

    Manifest validation ensures command targets name a method, highlights have positive dimensions and valid hex colors, and setup-only commands (those that run to completion without opening a dialog) are allowed to have zero shots. Visual and screen-mode captures both render highlights with anti-aliased outlines, badge circles, and centered bold labels over the captured pixels before applying crop.

  • Infrastructure Documentation index and version tracking updated

    Updated docs/index.json with new Propello guide structure (headings, body excerpt, keywords including "import propello data", "restore from cloud", "options"), docs/version-map.json source file tracking, and docs/CHANGELOG.md entry. Documentation last-updated dates refreshed to 2026-08-27.

CloudSync
2026.827.15501
August 27, 2026

Automatic first-run vendor data download; Automatic first-run vendor data download; Added timeout protection for database connection loading.

Imports & POS

  • Bug Fix Store identifier corruption during legacy upgrade

    Your store number will now be recognized correctly after upgrading from an older version.

  • Bug Fix Legacy Compass data migration failure on new databases

    If you had multiple stores using Compass with older Margin Master versions, your historical per-store inventory data will now properly migrate to the new unified format even on first-time database upgrades.

  • Bug Fix Legacy MySQL/Compass stores now preserve POS data during upgrade

    If you're upgrading from an older version with MySQL/Compass, your pricing data will now appear in the grid immediately after the upgrade instead of showing an empty table.

  • Bug Fix Empty main table after MySQL/Compass upgrade

    After upgrading, all your existing item data will now appear in the pricing grid immediately instead of showing an empty table.

  • Bug Fix Corrected migration sequence to prevent storematchup corruption

    Fixed the order of migration steps so that legacy store-number normalization runs before the storematchup table is read. Previously, a legacy 3.9.x store number stored as the raw POS character (e.g., "1") would be misinterpreted as ordinal 1 instead of the correct ASCII value 49, creating incorrect storematchup entries that would never match Compass data. This sequencing fix prevents the corruption from occurring during the upgrade.

Cloud Sync & Vendor Data

  • Improvement Automatic first-run vendor data download

    On first launch or after a database upgrade, vendor catalog data now downloads automatically in the background. You'll see a status message on the splash screen but won't need to click Yes to continue.

  • Improvement Automatic first-run vendor data download

    When you first install Margin Master or reset your database, the vendor catalog will download automatically during startup instead of asking you to confirm. The splash screen will show "No [Vendor] data found — updating your vendor data now…" while the download completes.

  • Bug Fix Main table now rebuilds after automatic vendor download

    After the first-time vendor data download, your pricing grid will now show up-to-date costs and retail prices immediately instead of stale data.

  • User Interface Updated splash screen messaging

    The startup screen now shows a clearer message explaining that your vendor catalog is being downloaded automatically.

User Interface

  • User Interface Incremental search for Store Information dropdowns

    When selecting your Primary Vendor, RSC, or POS System in Settings, you can now type the first letter (like "O" for Orgill) to jump directly to that option instead of clicking through the entire list.

Performance & Reliability

  • Improvement Added timeout protection for database connection loading

    Synchronous database connection loads on the UI thread now have a 10-second timeout limit. If the load lock cannot be acquired within this window, the system logs a warning and proceeds with loading to avoid UI stalls. This provides a safety mechanism against potential threading issues while maintaining normal fast-path performance.

  • Improvement Background feature check handles database transitions gracefully

    The application will no longer crash with "Invalid object name" errors when switching between databases or during restore operations.

  • Improvement Background feature flag reads gracefully handle database transitions

    Added error handling to the background feature flag check that runs on a timer from the UI thread. During database restore or switching operations, settings reads can temporarily fail while the database is in transition. The flag now safely degrades to "disabled" rather than surfacing as an unhandled exception, preventing potential UI crashes during restore operations.

  • Improvement Skip redundant maintenance after first-run vendor sync

    When the application performs a first-run vendor sync (automatically downloading vendor catalogs for an empty database), it now skips the subsequent shrink and index rebuild maintenance since those tables were just freshly created. This optimization reduces startup time on the slowest launch scenario a customer experiences—the very first time opening a new database.

  • Improvement Optimized first-run startup performance

    When the first-run vendor sync rebuilds all main tables during startup, deferred database maintenance (shrink and index rebuild) is now skipped since those tables were just rebuilt seconds ago. This eliminates wasted time on the slowest launch customers experience. The once-a-day maintenance gate will run it on the next startup.

  • Improvement Strategy loading completes before maintenance status updates

    The pricing strategy loader now completes before database maintenance begins, preventing the "Shrinking database..." status message from being immediately overwritten by "Strategy loading completed." This provides clearer feedback about what operations are taking longer during startup.

  • Improvement Database maintenance no longer overwrites strategy loader status

    The strategy loader now completes before deferred maintenance begins, preventing multi-minute "Shrinking database..." status messages from being immediately overwritten by "Strategy loading completed" messages.

  • Bug Fix Eliminated deadlock during restore-from-backup operations

    The application will no longer freeze on the "Calculating Rounding Points" screen when restoring a database backup. The restore process now completes smoothly without requiring the application to be force-closed.

  • Bug Fix Eliminated deadlock during restore-from-backup operations

    Restore-from-backup operations will no longer cause the application to freeze or hang when reconnecting to the database.

  • Bug Fix Database connection pool cleared after restore

    After restoring a backup, the application will now properly reconnect to the database instead of showing login errors or configuration screens.

  • Bug Fix Connection pool cleared after database restore

    Database restore operations now complete cleanly without triggering unexpected errors or configuration screens.

  • Bug Fix Database readiness checks now block main screen display

    When opening Margin Master or switching databases, you'll now see a "Bringing this database up to date" message while necessary updates complete, instead of seeing an empty pricing grid that fills in later.

  • Bug Fix Database ready checks now run before selection panel loads

    When opening Margin Master or switching databases, the pricing grid will now wait to appear until all necessary data is ready, eliminating the brief "No Items Found" message that previously appeared while vendor catalogs were being loaded.

  • Bug Fix Database readiness check now verifies restored database

    The "Waiting for database to be ready" step after a restore now accurately reflects when the database is actually accepting connections.

  • Bug Fix Database readiness check now validates restored database

    The restore process now waits for the database to be fully ready before continuing, preventing connection errors.

  • Bug Fix Database switch now properly migrates legacy databases

    The StoreManagerInfo migration (converting legacy per-store POS mapping to the unified table) only ran during cold startup, meaning switching to a legacy database via the watcher or menu never converted it. This migration now runs through RunDatabaseReadyChecksAsync, which both startup and ReinitializeForDatabaseChangeAsync reach, so a switch to a legacy database converts exactly like a cold start.

  • Bug Fix Database maintenance no longer interferes with database switching

    Fixed an issue where database maintenance operations (index rebuilds and shrinking) started on one database could continue running against a different database after switching. The application now waits for any in-flight maintenance to complete before switching databases, preventing maintenance commands from landing on the wrong database. Wait time is bounded by the shrink operation's 600-second timeout.

  • Bug Fix Prevented database maintenance from affecting wrong database during switch

    Database maintenance (shrink and index rebuild) could start on one database and finish its index pass on the next database after a switch, because the task ran asynchronously without tracking. The maintenance task is now stored in _deferredMaintenanceTask, and ReinitializeForDatabaseChangeAsync waits for it to complete with a "Waiting for database maintenance to finish..." message before switching databases.

  • Architecture Improved async/await patterns in database connection service

    Added ConfigureAwait(false) to all async operations in the database connection service to prevent unnecessary context switching and reduce the risk of dispatcher-related deadlocks. This follows best practices for library-style code that doesn't require UI thread affinity.

  • Infrastructure Added defensive timeout for database connection loading

    Implemented a 10-second maximum wait time for synchronous database connection loads. If the lock cannot be acquired within this timeframe, the system logs a warning and falls back to a direct load operation. This ensures that any future regression degrades gracefully to a logged warning rather than a frozen application.

Infrastructure & Internal

  • Bug Fix Replaced blocking re-import dialog with callback to prevent service hangs

    If you leave an Epicor import paused overnight and the system runs an automated import, the system will now download fresh data instead of potentially freezing.

  • Architecture Epicor FTP extractor moved to DataImport library

    The EpicorFTPFileExtractorService has been relocated to the MarginMaster.DataImport library as part of ongoing modularization. The service now uses interfaces (IImportDatabaseService, IApplicationSettingsService) instead of concrete dependencies, enabling better separation and reuse across different host applications including the WPF desktop app, background services, and diagnostic tools.

  • Infrastructure DatabaseService now directly implements import interface

    DatabaseService now implements IImportDatabaseService directly through explicit interface members (DatabaseService.ImportSeam.cs), allowing DataImport-side services to accept the interface while WPF callers continue passing DatabaseService unchanged. The existing adapter remains for dependency injection scenarios. This eliminates an unnecessary wrapper layer while maintaining compatibility.

  • Infrastructure Supporting utilities moved to Common library

    MessageRotator and SqlTransientRetry (now public) have been moved to MarginMaster.Common along with their tests, making them available to the DataImport library and other components. StoreManagerInfoWriter and EpicorConnectionFailureMessage were moved to DataImport as they're required by the Epicor extractor service.

MI9FalconPaladinTransactWestLakeDoitBestCloudSync
2026.826.17225
August 26, 2026

Resumable upload protocol for support issue attachments; Resumable block-based attachment uploads; Strategy restore now reports what was actually restored.

Strategy & Pricing

  • Improvement Strategy restore now reports what was actually restored

    After restoring a strategy backup, the completion message now tells you exactly what came back—such as "Restored 11 rule steps, 3 custom groups, and 53 SKU exceptions for: 05598-PS_imported." If no rules were restored, you'll see a warning explaining why and what to check.

  • Improvement Strategy execution summary explains when no prices changed

    If you run a strategy and no prices change, the summary now explains why—such as "The active strategy 'DEFAULT' has 1 rule(s), but none of them matched any item. Another strategy in this database does have rules: '05598-PS_imported'. If that is the one you meant to run, select it in the strategy list first."

  • Improvement Strategy execution summary displays empty run warnings

    The strategy execution summary now highlights when no prices were changed and suggests which strategy you should use instead.

  • Bug Fix Strategy restore now reports actual results instead of file contents

    When you restore a strategy backup, Margin Master now tells you exactly how many rules, custom groups, and exceptions were actually restored, and warns you clearly if nothing was brought back.

  • Bug Fix Empty strategy runs now provide actionable guidance

    If you run a pricing strategy that changes nothing, Margin Master now explains why and tells you which other strategy contains your actual rules, turning a support call into a two-click fix.

  • Bug Fix Prevented duplicate GlobalFileConfig rows on repeated restores

    Restoring the same backup file multiple times no longer creates duplicate copies of your pricing rules and settings.

  • Bug Fix Restoring the same backup file multiple times no longer duplicates strategy rules

    Restoring the same strategy backup multiple times now works correctly—it won't create duplicate copies of your strategy rules.

  • User Interface Strategy execution summary screen shows "No prices changed" notice

    The summary screen after running a strategy now includes a warning section at the top if no prices were changed, explaining why and what to do next.

  • Infrastructure Consolidated strategy restore completion messages

    Unified three copy-pasted completion message blocks (local file restore, cloud restore, legacy file restore) into a single ShowStrategyRestoreCompleteMessage method that cannot drift apart. All three entry points now use the same logic to report what was actually restored.

  • Infrastructure Strategy restore result tracking

    Introduced BackupRestoreResult model to capture what a restore operation actually wrote (strategies, steps, groups, exceptions) rather than inferring success from the backup file's contents. All restore code paths (local file, cloud, legacy formats) now return this detailed result, enabling accurate user-facing reporting regardless of which options were selected or which per-strategy skip logic applied.

  • Infrastructure Empty strategy run notice helper

    Added EmptyStrategyRunNotice helper class to generate consistent user-facing explanations for strategy runs that changed no prices. The helper queries for other strategies with rules and produces messages like "The active strategy 'DEFAULT' contains no pricing rules. Another strategy in this database does have rules: '05598-PS_imported'. If that is the one you meant to run, select it in the strategy list first."

Performance & Reliability

  • Improvement TypeMismatch differences now track nullability

    The TypeMismatch schema difference now records ModelIsNullable and DatabaseIsNullable fields, matching the pattern already used by NullabilityMismatch. When model nullability is unknown, the generator falls back to the database's current nullability to make the ALTER statement nullability-neutral, and only when both are unknown does it choose the non-destructive NULL direction. This ensures that "unknown" never means "tighten."

  • Improvement NULL scrub uses current column type, not model type

    When tightening a nullable column to NOT NULL, the generated UPDATE statement that clears existing NULLs now uses a default literal appropriate for the column's current type rather than the model's target type. The scrub runs before the ALTER COLUMN executes, so writing an empty string into an int column would have been silently converted to 0 rather than the intended empty value. A new SchemaColumnSql helper class centralizes this logic for both TypeMismatch and NullabilityMismatch scenarios.

  • Improvement Database migration version now advances correctly

    The application will start faster since database schema commands only run once instead of repeating on every launch.

  • Improvement Enhanced schema command validation

    Extended the schema update validation logic to recognize both ALTER TABLE and UPDATE commands when determining if they target a view. Previously, only ALTER TABLE commands were checked, allowing NULL-scrub UPDATE statements to fail repeatedly. The validation now correctly identifies all commands that target table-like objects and verifies their applicability.

  • Improvement Self-healing for previously tightened columns

    Columns that were incorrectly tightened to NOT NULL by previous versions will automatically heal on the next startup. With ModelIsNullable now properly populated, the comparer detects model-nullable-vs-database-NOT-NULL as a NullabilityMismatch and generates the corrective ALTER COLUMN NULL statement.

  • Bug Fix Schema comparer forced NOT NULL on all type changes

    Fixed a database schema issue that could cause startup errors or prevent certain fields from accepting empty values.

  • Bug Fix Schema migration nullability handling corrected

    Database updates will no longer fail when column types need to change, preventing startup errors that previously blocked the application from running.

  • Bug Fix Schema migration now skips UPDATE commands targeting views

    Database updates no longer fail repeatedly at startup when vendor data views are present in the database.

  • Bug Fix Schema updates now successfully add NOT NULL columns to populated tables

    Database schema updates that previously failed repeatedly during startup will now complete successfully.

  • Bug Fix NULL value scrubbing during column tightening

    When the database schema needs to change a column from optional to required, existing empty values are automatically filled in so the update can complete successfully.

  • Bug Fix Fixed error adding non-nullable columns to populated tables

    New database columns are now added successfully even when your database contains existing transaction data.

  • Bug Fix Schema commands no longer attempt to modify database views

    Startup diagnostic logs will no longer show repeated schema update failures for vendor data tables.

  • Bug Fix Type change literal uses current column type

    NULL scrub statements now use the column's existing database type to generate the replacement literal, rather than the model's target type. This prevents silent type conversions where writing an empty string into an integer column would be converted to 0 instead of the intended empty value.

  • Architecture Centralized column SQL generation

    Extracted nullability clause and NULL scrubbing logic into a new SchemaColumnSql helper class with comprehensive unit tests (130 lines of test coverage). Both the TypeMismatch and NullabilityMismatch code paths now use the same tested logic, ensuring consistent handling. Unknown nullability now falls back to the database's current state rather than incorrectly defaulting to NOT NULL.

  • Infrastructure Added comprehensive schema SQL generation tests

    Added 27 new unit tests in SchemaColumnSqlTests covering nullability clause generation, NULL scrubbing logic, default literal selection for all SQL types, and edge cases like unknown nullability states. Full test suite now has 1,871 passing tests.

Infrastructure & Internal

  • New Feature Resumable upload protocol for support issue attachments

    Implemented a complete resumable upload system that breaks large files into 8 MB blocks and tracks which blocks have already been uploaded to Azure. When a connection drops mid-upload, the next attempt scans Azure to identify which blocks are already staged and only sends the missing ones. Azure retains uncommitted blocks for seven days, allowing uploads to resume even after connection failures. The system uses deterministic block IDs based on file offset and upload tag to ensure blocks from different attempts of the same file can be correctly matched and assembled.

  • New Feature Resumable block-based attachment uploads

    When attaching large files to support tickets (especially database backups that can take hours), if the upload is interrupted you can simply retry and it will pick up where it left off instead of starting from zero.

  • Improvement Smart credential renewal during long uploads

    Long-running uploads now proactively renew their Azure credentials before they expire, using the server's clock to measure and compensate for clock skew on the store PC. The refresh buffer is now proportional to upload duration rather than a fixed five minutes, preventing uploads from failing halfway through with expired credentials. When Azure refuses a credential, the cached token is immediately invalidated so retries fetch a fresh one instead of reusing a poisoned entry.

  • Improvement Intelligent retry logic for transient Azure failures

    Upload failures are now classified into credential issues (403, authentication errors), transient conditions (timeouts, 429, 5xx errors), and fatal errors (invalid requests, missing containers). Transient failures retry automatically with exponential backoff and jitter to prevent concurrent blocks from retrying simultaneously. Credential issues trigger automatic SAS token renewal. Fatal errors stop immediately with clear error messages rather than wasting time on futile retries.

  • Improvement Enhanced upload progress reporting with resume indicators

    The upload status now shows transfer rate, time remaining, and—most importantly—how many bytes were resumed from a previous attempt. Database backup uploads display human-readable progress ("4.5 MB/s - 38 min left - 500 MB already uploaded") instead of just a percentage, giving users meaningful feedback during multi-hour transfers.

  • Improvement Enhanced upload progress reporting with resume metrics

    Upload status now shows transfer speed, time remaining, and how much data was already uploaded when resuming an interrupted upload.

  • Improvement Intelligent retry policy with exponential backoff

    Failed blocks are now retried up to eight times with exponential backoff and jitter (starting at 2 seconds, capped at 60 seconds). The system distinguishes between transient failures (network timeouts, server errors) that warrant retry, credential problems that need a fresh token, and fatal errors (missing container, invalid request) that should stop immediately. This prevents wasting time on hopeless retries while recovering from temporary connection issues.

  • Improvement Server clock skew compensation for SAS token expiration

    The client now learns the server's clock time with each SAS token response and calculates local clock skew. This prevents store PCs with incorrect clocks from treating valid tokens as expired (if running fast) or continuing to use expired tokens (if running slow). SAS tokens are also refreshed proactively based on expected upload duration rather than waiting for a 403 response mid-upload.

  • Improvement Upload slot persistence across retry attempts

    Each resumable upload opens a server-managed slot that assigns a unique blob name and block ID format. The slot is cached by issue ID, file path, file size, and last-modified timestamp. Retrying the same file reuses its slot (enabling resume), while a recreated database backup at the same path correctly gets a fresh slot to prevent assembling mismatched blocks.

  • Improvement Extended blob client network timeouts

    Azure SDK blob client network timeout increased from the default 100 seconds to 10 minutes, with exponential retry configured. This prevents legitimate slow transfers on store uplinks from timing out prematurely, especially for 8 MB blocks on connections with intermittent packet loss.

  • Improvement Upload slot fallback logic for older servers

    The uploader now explicitly checks whether the server supports resumable uploads (via 404/405 responses) before falling back to the legacy direct-upload path. When a server understands the slot request but declines it (e.g., file over size limit, expired token), the real error message is preserved instead of being replaced by a different error from the fallback path. This fixes cases where a 466 MB backup was reported as "over the 128 MB limit" when the actual problem was an expired credential.

  • Improvement Graceful fallback for legacy API servers

    New upload slot endpoint requests are classified by UploadPathDecider: 404/405 responses fall back to the legacy upload-target path (non-resumable but functional), while understood refusals (expired token, file too large, missing issue) report their actual error rather than silently switching paths. This prevents MM-492-style misdiagnosis where an authorization failure on the resumable path fell through to a different path whose unrelated size limit complaint became the user-facing message.

  • Bug Fix Corrupted backup uploads from short reads

    Fixed a critical bug in AzureBlobService where short file reads would stage blocks padded with trailing zeros, producing database backups that were the correct length but silently corrupt—invisible until someone tried to restore them. The uploader now stages only the exact bytes returned by each read operation.

  • Bug Fix Incorrect progress bar calculations

    Fixed progress calculations that truncated instead of rounding up block counts, causing progress bars and ETAs to run against a denominator that was one too small. Also fixed SupportIssuesViewModel showing percentages calculated from file counts instead of bytes, driving the progress bar to 2500% when uploading two files.

  • Bug Fix SAS token cache invalidation on credential refusal

    Added InvalidateToken method to IBlobAccessService. When Azure refuses a credential, the cached token is immediately evicted so the next request mints a fresh one. Previously a poisoned cache entry would remain until it expired naturally, causing every retry to fail identically until the expiration window passed.

  • User Interface Support Tools screen attachment upload status

    The Submit Issue dialog now displays detailed upload progress including phase name, transfer rate, estimated time remaining, and resumed byte count during attachment uploads. The status text adapts to each phase (Preparing, Scanning, Staging, Committing, Verifying, Registering) rather than showing a percentage alone during non-transfer phases.

  • Architecture New blob upload service abstractions

    Introduced IResumableBlobUploader interface and ResumableBlobUploader implementation in MarginMaster.Common with supporting types: BlobUploadProgress, BlobUploadOutcome, BlobUploadPhase, BlobUploadFailureKind, ResumableUploadRequest, BlobSasLease, ResumableBlockPlan, BlobRetryPolicy, and UploadPathDecider. These enable testable, pure functions for planning, retry decisions, and outcome classification separate from I/O concerns.

  • Infrastructure Comprehensive test coverage for upload protocol

    Added five test suites (2,614 lines total) covering retry classification, block ID agreement with the server, resume reconciliation, progress adaptation, and upload path decisions. The block ID tests use golden vectors copied verbatim from the server's own tests, ensuring the client and server implementations stay synchronized—critical because a disagreement silently commits blobs assembled from mismatched blocks.

  • Infrastructure Comprehensive retry policy and block plan test coverage

    Added extensive unit tests pinning retry classification logic, exponential backoff calculations with jitter, block ID format agreement with server (golden vectors), block plan arithmetic, resume reconciliation, upload slot identity rules, and progress adapter behavior. These tests prevent silent correctness regressions that would corrupt uploaded blobs by assembling mismatched blocks.

  • Infrastructure Configurable Azure SDK timeouts and retry behavior

    Configured BlobClientOptions throughout the application for the first time—previously every blob operation ran on the SDK's default 100-second network timeout. Network timeout is now 10 minutes with exponential retry (3 attempts, 2-30 second backoff), appropriate for large blocks on slow or intermittent store uplinks.

2026.825.23794
August 25, 2026

Blob name returned for partial upload failures; Reduced error logging noise from label printing; Enhanced diagnostic accuracy for import troubleshooting.

Imports & POS

  • Improvement Enhanced diagnostic accuracy for import troubleshooting

    The Import Manager now better distinguishes between different types of database errors during vendor data updates. Previously, both permanent structural errors (like missing columns or tables) and exhausted retry attempts were reported identically, making troubleshooting difficult. Error messages now acknowledge that the detailed cause has already been logged and direct support teams to the correct log entry rather than suggesting an incorrect root cause.

  • Bug Fix Corrected misleading error messages during vendor data import failures

    When a vendor data update failed during import, the error message incorrectly claimed "Retrying did not resolve the timeout" even when the actual problem was a structural SQL error (such as a missing table) that was never retried. The system now accurately reports the failure and directs users to check the log for the specific cause. This corrects misdiagnosis issues encountered at stores 3174 and 3875, where investigators were looking for non-existent timeout problems when the real issue was SQL errors like missing database tables.

Performance & Reliability

  • Improvement Reduced error logging noise from label printing

    The previous implementation caused a single bug to generate 78 of 84 distinct error groups in seven days because each SKU produced its own error signature. By using a parameterized query with constant SQL text, all errors now collapse into a single fingerprint, dramatically reducing log noise and making real issues easier to identify.

  • Improvement Orphan detection runs on every startup

    Even if your store was renumbered in the past, the system will detect and fix any mismatched table names the next time Margin Master starts.

  • Improvement Automatic orphan detection runs on every sync

    The orphaned table check now runs on every single-store sync pass rather than only when a renumber occurs. This ensures databases where metadata was already repaired days or weeks earlier will still have their orphaned tables corrected, matching the real-world scenario where the issue was reported after the repoint had already completed.

  • Bug Fix Label printing UPC fallback no longer throws database errors

    When a SKU has no vendor GTIN barcode data, label printing falls back to reading the UPC from the Store table. The previous query selected the entire Store row into a data structure that expected OrderMultiple to be an integer, but on 168 of 170 live databases that column contains text values like "1.00". This caused Dapper to throw a mapping error for every row. The query now reads only the UPC column as a string, eliminating the type mismatch. Additionally, the SKU is now passed as a parameter rather than interpolated into the SQL, which prevents each SKU from creating its own unique error fingerprint in logs.

  • Bug Fix Label printing no longer crashes when falling back to store inventory for UPC codes

    Label printing will now work reliably even when UPC codes need to be looked up from your store's inventory data, fixing crashes that could occur when printing multiple labels at once.

  • Bug Fix Orphaned main table after store renumber

    If your store was renumbered, the main pricing table will now automatically update to use the new store number instead of keeping the old one, and the store selection dropdown will show only the correct current number.

  • Bug Fix Rename orphaned main table after store renumbering

    If your store number changes, the pricing table automatically updates to the new number so you won't see your old store number appearing in dropdown lists.

  • Bug Fix Added safety guard for UPC string slicing

    Added a LEN >= 2 check in the WHERE clause to ensure the UPC value is long enough before slicing it with [2..], preventing potential index out-of-range errors. Previously this was implicitly handled by a catch block that has now been removed.

  • Data Import Re-stamp store number column after table rename

    After renaming a per-store main table, the StoreNumber column in every row is updated to the new number and SelectionLists is cleared to force regeneration. Without this, the store selector would continue reading the old number from the column data even after the table was renamed.

  • Database Clean up stale indexes after table rename

    When a per-store main table is renamed, any managed indexes are dropped and removed from the ManagedIndexes registry, then recreated under the new table name. This prevents carrying stale "RSIX_9645_*" indexes on a table now named for store 19532, which would impact query performance.

  • Infrastructure Safe rename with multiple validations

    The rename operation includes several safety checks: refuses to act unless there is exactly one orphaned table candidate, verifies the target table name is available (won't overwrite an existing table), uses a rename lock to prevent concurrent operations, and reuses the existing rename sequence for leading-zero fixes. Also drops and rebuilds RSIX indexes to prevent stale index cost.

  • Infrastructure Safety checks prevent destructive renames

    The rename logic includes multiple safeguards: it only renames when exactly one candidate table exists, refuses to rename if a table already exists under the target name, and ignores StoreGroup compound tables or other POS systems' tables. These checks ensure automatic renames never destroy data when the database has multiple per-store tables or other ambiguous conditions.

Infrastructure & Internal

  • New Feature Blob name returned for partial upload failures

    When a file successfully uploads to Azure blob storage but fails to register against the support ticket, the response now includes the blob name. This allows future retry logic to re-register the existing blob rather than re-uploading a multi-gigabyte file.

  • Improvement Server-controlled upload size limits

    The application now reads upload size limits from the server instead of using hardcoded values. This allows the server to advertise its actual multipart body limit (which increased from 128 MB to 256 MB in recent versions) and ensures older clients don't incorrectly reject uploads that newer servers can handle.

  • Improvement Server-controlled upload size limits

    The maximum file size for the legacy multipart upload method is now retrieved from the server rather than using a hard-coded client constant. The 128 MB constant remains only as a fallback for older servers that don't advertise their limit. Non-positive values are treated as "not advertised" rather than "nothing allowed."

  • Improvement Resume support for interrupted uploads

    Removed the DeleteIfExistsAsync call before blob uploads, which was discarding staged uncommitted blocks and destroying Azure's ability to resume interrupted transfers. The UploadAsync method already overwrites existing blobs by default, so the delete was unnecessary and harmful for large multi-gigabyte files.

  • Improvement Better upload resume capability for large files

    Removed pre-upload blob deletion that was destroying Azure's uncommitted block tracking. Large multi-gigabyte uploads can now properly resume from partial progress if retried, rather than restarting from zero every time.

  • Bug Fix More accurate vendor update error messages

    Changed the error message shown when vendor catalog updates fail to avoid incorrectly naming "timeout" or "retries" as the cause. The underlying database operation returns the same error code for both structural database errors (like a missing table) and genuine timeouts, so the application cannot distinguish between them. Now the message directs users to check the detailed log for the actual cause rather than making an incorrect assumption. This change was prompted by two support investigations (stores 3875 and 3174) where the message incorrectly blamed timeouts when the real issue was a dropped database table.

  • Bug Fix Accurate error reporting for failed attachment uploads

    When attaching large files to support tickets fails, you'll now see the real reason (like "connection timed out" or "credentials expired") instead of always being told the file is too large.

  • Bug Fix Accurate error reporting for failed attachment uploads

    When a large file upload to support fails, the error message will now tell you the real reason (like "upload location expired" or "server unavailable") instead of incorrectly saying the file is too big.

  • Bug Fix Restore large file uploads for stores without dedicated containers

    Stores that don't have dedicated cloud storage can now successfully upload large files to support tickets (this was broken and always failed with a size error).

  • Bug Fix Shared container uploads now work correctly

    Support file uploads now work correctly for all stores, including those without dedicated cloud storage containers.

2026.824.42540
August 25, 2026

Store identity conflict detection and logging; Store identity conflict detection; Reusable numeric editor with format presets.

Strategy & Pricing

  • Improvement Enhanced error logging for barcode lookup failures

    Added detailed warning logging when VendorGTIN or Store table UPC lookups fail during label printing. The system now logs the specific SKU and exception details, making it easier to diagnose why individual labels might print without barcodes.

  • Bug Fix Label barcode printing failure caused by data type mismatch

    Fixed an issue where labels would print without any barcode when certain products were missing vendor information. Now barcodes print correctly by looking up the UPC from your store's product data.

  • Bug Fix Rollback of UPC lookup improvements

    Reverted PR #1334 which attempted to fix a data exception when printing labels by reading only the UPC column from the Store table. The fix inadvertently caused issues, so the system has been returned to the previous UPC fallback implementation that queries the full Store record when VendorGTIN lookup fails.

  • User Interface Label printing UPC behavior restored

    Label printing now uses the original UPC lookup method. When generating barcodes for labels, the system first checks VendorGTIN, then falls back to the Store table UPC field, using the previous query approach.

Imports & POS

  • Improvement Enhanced SQL error logging for structural issues

    The database service now logs the complete SQL error message (including table and column names) when encountering structural errors like missing tables or columns, rather than truncating to a generic preview. This ensures diagnostic telemetry captures the full context needed to identify which specific object is missing.

  • Bug Fix Improved diagnostic accuracy for vendor update failures

    When vendor data updates fail, the error message now tells you to check the log for specific details instead of always blaming a timeout.

Cloud Sync & Vendor Data

  • Improvement Enhanced error logging for sync failures

    Sync error logs now include the full exception details with stack traces instead of just error messages. This ensures connectivity issues like SQL Server timeouts are properly recorded in telemetry for support diagnosis, preventing scenarios where errors appeared as "Unknown" type with no diagnostic information.

  • Bug Fix SQL Server timeouts now treated as connectivity failures

    If your database server stops responding during sync, you'll now see one clear message saying "a server could not be reached" instead of multiple confusing error messages for each table being synced.

  • Cloud Sync Reused proven connectivity detection logic

    Cloud sync now uses the same SQL error classification logic already tested and proven in the POS import system, ensuring consistent handling of connectivity issues across the application. Added test coverage to prevent genuine sync defects (missing tables, columns, deadlocks) from being misclassified as connectivity problems and suppressed from error telemetry.

  • User Interface Clearer connectivity failure messages

    Error messages during sync are now more accurate about which server couldn't be reached, helping you troubleshoot the right system.

User Interface

  • Improvement Reusable numeric editor with format presets

    Margin and price fields now display consistently throughout the application.

  • Improvement Display scale conversion handles all DevExpress mask types

    Added logic to correctly interpret DevExpress numeric mask scaling rules: predefined "p" (lowercase) divides by 100 while "P" (uppercase) does not; bare "%" in custom masks divides by 100 while "%%" or "\%" do not. Currency ("c2") and plain number ("n2") masks are correctly identified as non-scaling. This ensures the spinner increment adjustment applies only to true percent masks and not to fields like Future Price → Margin % which use an escaped literal percent sign.

  • Improvement Added display scale detection for numeric masks

    Implemented logic to detect when a numeric mask scales the displayed value differently from the stored value. The system now correctly identifies that lowercase "p" masks and bare "%" symbols in custom masks scale by 100x, while uppercase "P", escaped "\%" literals, and "%%" sequences do not. This ensures spinner increments are calculated in the correct value space.

  • Improvement Enhanced caret position tracking across value changes

    Split increment resolution logic into ResolveExponent and Pow10 functions, with CaretIndexForExponent as the inverse operation. This allows the system to restore caret position by place value (ones, tenths, hundredths) rather than character position, maintaining correct behavior when formatted text grows or shrinks.

  • Improvement Converted caret-aware spinning to reusable attached properties

    Replaced the MMNumericEdit custom control with NumericEdit.CaretAware and NumericEdit.FormatMode attached properties that work on standard SpinEdit instances. This architecture allows any spin editor in the app to opt into caret-aware behavior via XAML attributes without breaking DevExpress theme rendering.

  • Bug Fix Caret-aware numeric stepping for margin and price editors

    When you're editing a margin percentage or dollar amount and press the up or down arrow (or use the mouse wheel), the number now changes at the digit where your cursor is blinking, not always by whole numbers.

  • Bug Fix Numeric editors rendered blank after MM-1403 merge

    Margin %, Fixed Retail, and Manual amount fields now display correctly instead of appearing blank.

  • Bug Fix Numeric spin editors no longer render as blank controls

    Margin percent and fixed retail price editors now display correctly instead of appearing as blank boxes.

  • Bug Fix Percent field spinner applies correct increment

    When using the up/down arrows on Current Margin and similar percent fields, the value now changes by the expected amount (like 0.10%) instead of jumping by 10 full percentage points.

  • Bug Fix Percent field spinners stepped 100 times too large

    When you click the up or down arrow buttons on percent fields like Current Margin, the value now changes by the correct small amount (like 0.1%) instead of jumping by a full 10%.

  • Bug Fix Caret drifted between digits when spinning repeatedly

    Holding the Up or Down arrow key now consistently steps the same digit instead of jumping around.

  • Bug Fix Caret position now stays locked to the same digit during repeated spins

    Holding down the Up or Down arrow key now repeatedly steps the same digit instead of jumping to different digits each time.

  • User Interface Caret-aware stepping for numeric spinners

    When you click into a margin or price field and use the up/down arrow keys or spinner buttons, only the digit where your cursor is positioned will change—making it much easier to fine-tune prices to the nearest cent or tenth of a percent without retyping the entire value.

  • User Interface Applied caret-aware spinners to Future Price Panel

    Updated the Margin % and Fixed Retail spinners in the Future Price Panel to use MMNumericEdit with FormatMode="Percent" and FormatMode="Currency" respectively. Removed the attached behavior markup in favor of the control's built-in functionality.

  • User Interface Format presets for common numeric types

    MMNumericEdit introduces a FormatMode property with presets for Currency, Percent, and Number formats, automatically stamping the appropriate mask and format settings. FormatMode defaults to Inherit so existing call sites that assign Mask from code-behind (like UC_MMCostSelectionBox) continue to work unchanged. The Percent preset uses a literal "%" suffix rather than a P-mask to avoid the 100x scaling issue—margin is stored in percentage points throughout the application.

  • User Interface Applied caret-aware spinners to selection box controls

    Updated UC_MMSelectionBox and UC_MMCostSelectionBox to use MMNumericEdit with FormatMode="Inherit". These controls assign their masks from bindings or code-behind at runtime, so the Inherit mode preserves that behavior while adding caret-aware stepping.

  • User Interface Updated Future Price and selection box editors

    All numeric input fields in Future Price calculations and item selection now work consistently.

  • User Interface Updated all affected editors to use new attached property syntax

    Migrated editors in UC_MMCostSelectionBox (range From/To fields), UC_MMSelectionBox (specific value field), and FuturePricePanel (margin percent and fixed retail editors) from the now-removed MMNumericEdit tag to SpinEdit with NumericEdit.CaretAware and NumericEdit.FormatMode attached properties. Functionality remains identical but rendering now works correctly.

  • Architecture Custom control replaces attached behavior

    Converted the CaretAwareSpinBehavior attached behavior into MMNumericEdit, a SpinEdit subclass. This simplifies XAML (no longer requires explicit Interaction.Behaviors tags), improves testability (the control exposes its increment resolution logic as a static method), and provides a cleaner extension point for format presets. The control inherits SpinEdit's default theme style so it renders identically to standard editors while adding the caret-aware increment calculation in the Spin event handler.

  • Infrastructure Test coverage for mask scaling behavior

    Added comprehensive test cases covering all DevExpress mask types including "p2", "P2", "#,##0.00%", escaped literal "\%", currency, and number formats to verify the display scale calculation returns 100 for rescaling masks and 1 for non-rescaling masks. Includes hands-on verification test that a "p2" editor configured like Current Margin now steps by fractions (≤0.01) instead of whole percentage points.

  • Infrastructure Expanded test coverage for numeric increment resolution

    Added MMNumericEditTests and MMNumericEditIncrementTests with 16 test cases, expanding on the 7 cases the old behavior tests covered. New tests pin DevExpress assumptions the control depends on (that Increment assigned during the Spin event is applied, that fractional increments survive), verify that negative signs and decimal separators are handled correctly, confirm that FormatMode presets stamp the expected masks, and ensure the Percent mask is a literal suffix rather than a scaling mask.

  • Infrastructure Comprehensive test coverage for increment resolution

    Added 15 test cases covering caret position resolution, including edge cases like negative numbers, caret on decimal separator, deep fractions, currency symbols, group separators, and text with no digits. Verified that DevExpress SpinEdit respects Increment assigned during the Spin event and that fractional increments survive the spin operation.

  • Infrastructure Expanded test coverage for caret restoration logic

    Added comprehensive unit tests for the new caret position restoration algorithm, including round-trip verification that a caret index for a given place value resolves back to the same exponent, and that the caret correctly follows digits when text length changes (e.g., 9.99 becoming 10.00).

Performance & Reliability

  • Improvement Store identity conflict detection and logging

    The store identity repair process now detects and logs a warning when the vendor configured in application settings contradicts the vendor recorded in the database's About table. This mismatch can occur when a failed-over license answer writes another company's identity into settings. The repair correctly refuses to proceed (preventing data corruption), but now explicitly logs the conflict with both vendor names and instructions to correct it manually in Store Configuration. Previously, this protective refusal was silent, making the issue impossible to diagnose from logs.

  • Improvement Error logging added to label printing diagnostics

    Added warning-level logging to both the vendor GTIN lookup and Store UPC fallback paths. Previously, exceptions were silently swallowed, making it impossible to diagnose why certain labels printed without barcodes. The new logging will surface these issues in diagnostic reports, helping identify data quality problems before they affect label printing.

  • Improvement Better error messages when servers are unreachable

    The fail-fast message when sync cannot reach a server no longer incorrectly states "Manager API unreachable" in cases where the local SQL Server is the actual problem. It now says "a server could not be reached" to avoid sending users to investigate the wrong system.

  • Improvement Added detailed progress reporting during SKU exception loading

    When opening a store's SKU-level exceptions, you'll now see exactly how many have loaded, the percentage complete, and how much time is left—so you know the system is working and not frozen.

  • Improvement Exception details now included in cloud sync error logs

    Three sync logging points that previously omitted exception details now include full stack traces: per-table failures, SQL timeout errors, and the summary when multiple tables fail. This ensures diagnostic information reaches error telemetry instead of appearing as "Unknown" exception types.

  • Bug Fix Fixed multi-minute freeze when opening SKU-level exceptions screen

    The SKU-level exceptions window now opens in seconds instead of minutes, even for stores with thousands of exceptions.

  • Bug Fix Barcodes now print correctly when vendor GTIN is unavailable

    If a product didn't have vendor catalog information, its label would print without a barcode. This is now fixed—labels will show the correct barcode from your store's product data when vendor information is missing.

  • Bug Fix SQL Server connectivity failures now treated as environmental issues

    If your SQL Server becomes temporarily unavailable during cloud sync, you'll now see one clear warning message instead of multiple confusing errors.

  • Bug Fix Fixed 30-second UI freeze when closing SKU-level exceptions screen

    Closing the SKU-level exceptions window is now instant, even after working with thousands of exceptions.

  • Bug Fix Save button now enables after rounding scheme changes

    The Save button now lights up correctly when you change a rounding scheme on the SKU-Level Exceptions screen.

  • Bug Fix Short UPC codes no longer cause errors during label printing

    Labels with unusually short UPC codes will now print reliably instead of potentially failing.

  • Bug Fix Removed non-functional Apply and Save buttons from Future Price panel tabs

    Confusing Apply and "Save" buttons that did nothing have been removed from the Future Price panel's Rounding and Advanced tabs in the SKU-Level Exceptions window.

  • Bug Fix Fixed progress bar staying empty during SKU exception load

    The progress bar now fills smoothly as SKU-level exceptions load, giving clear visual feedback.

  • Bug Fix Fixed column auto-sizing freeze on large exception lists

    The SKU-level exceptions grid now sizes its columns instantly, even with tens of thousands of exceptions loaded.

  • Bug Fix Fixed Save button not re-enabling after bulk rounding scheme changes

    After changing the rounding scheme for multiple SKU exceptions at once, the Save button now becomes available immediately so you can save your changes.

  • User Interface Added accurate progress reporting during exception load

    When loading SKU-level exceptions, you'll now see exactly how many have loaded, the percentage complete, and how much time is left, instead of a frozen progress screen.

  • User Interface Hid non-functional Save/Snapshot buttons in SKU exception Future Price panels

    The Future Price panel in SKU-level exceptions no longer shows misleading "Save" buttons that don't work—use the Save button at the top of the window instead.

  • Performance Dramatically improved screen open time for large exception counts

    Opening a store's SKU-level exceptions now takes seconds instead of minutes, even when there are tens of thousands of exceptions to display.

  • Infrastructure Store identity repair policy validation

    Added validation logic to distinguish between benign "nothing to do" scenarios and actual vendor contradictions during store identity repair. The system now treats Ace Hardware and Emery Jensen as the same vendor family (since EJ stores are carried as Ace in vendor tables), and recognizes Unknown vendor values as non-contradictions to avoid false alarms for pre-About databases. No behavior changed—repairs that previously succeeded still succeed, and repairs that were refused are still refused, but contradictions are now visible.

  • Infrastructure Cloud sync reuses existing connectivity detection logic

    The cloud sync engine now delegates SQL connectivity failure detection to the same curated error-number list already used by POS imports (including error 258 for network unavailability), ensuring consistent behavior across the application and preventing divergent maintenance of duplicate logic.

  • Performance Optimized grid column sizing for large datasets

    The SKU-Level Exceptions grid no longer freezes for several seconds after loading when there are many exceptions.

  • Infrastructure Added performance logging for SKU exception load times

    The system now logs the total time and row count for each SKU-level exception load operation, providing diagnostic data for performance monitoring and future optimization efforts.

Infrastructure & Internal

  • Improvement Store identity conflict detection

    Added detection and logging for cases where the vendor configured in Store Configuration (e.g., Ace Hardware) contradicts the vendor recorded in the database (e.g., Do-It-Best). This condition was previously detected and correctly refused for safety reasons, but the refusal was silent, making customer issues impossible to diagnose from logs. The system now logs a clear warning message when this contradiction is found, directing the user to correct the vendor in Store Configuration. The safety behavior is unchanged — the system still refuses to automatically overwrite store identity when vendors conflict.

  • Bug Fix Support diagnostics for failed license failover

    Resolved a specific diagnostic gap (MM-1393) where a failed-over license could write an incorrect vendor into application settings, leaving the application configured for one vendor while the database belonged to another. This state was correctly refused by the automatic store-renumber repair, but produced no log output, preventing support from identifying the root cause. The new logging makes these cases immediately visible in customer logs.

CloudSync
2026.824.24215
August 24, 2026

Remote SQL Access Configuration Script; Remote SQL Access Setup Script; Automatic post-publication catch-up.

Imports & POS

  • Improvement Main table ownership clarified with run-scoped flag

    Replaced a file-existence probe (which was true for every BisTrack store) with a run-scoped flag (`BuiltMainTablesDuringIngest`) set only by the two BisTrack CSV preload builds. Those handlers use a custom SQL script that is not column-equivalent to the generic rebuild—it writes different columns (Lock, PSRule, Discontinued) and computes StoreCost and CMargin differently—so the rebuild must leave their tables untouched to avoid silently changing customer data.

  • Improvement SelectionLists no longer cleared during import

    Selection boxes (vendor, category, etc.) will no longer go blank if a background import runs while you're using Margin Master.

  • Improvement SelectionLists table no longer cleared during BisTrack Direct SQL ingest

    The SelectionLists table (which populates dropdown selection boxes) is no longer truncated mid-ingest, preventing the UI from showing empty dropdowns when a background import runs while the app is open. The rebuild process now owns this cleanup step, performing it at the appropriate time.

  • Bug Fix POS import no longer drops main tables during background runs

    If a background import runs while you're using Margin Master, your pricing grid and selection boxes will no longer be cleared. All table rebuilds now happen during the post-processing step that waits until you close the app or click OK.

  • Bug Fix BisTrack Direct SQL main tables now rebuilt during post-processing

    BisTrack Direct SQL was the last POS system whose ingest destroyed and rebuilt its own main tables before the post-processing rebuild could run. The table build is now handled by the standard rebuild process, using the same SQL builder against the same Store rows the ingest loads. This prevents the app from dropping pricing tables while open with a background import in progress—a scenario that previously left stores with no main tables at all.

  • Bug Fix Failed store configuration no longer stops entire import run

    If one store has a configuration problem during import, the other stores will still complete their imports successfully.

  • Bug Fix RSC lookup failures no longer halt entire import runs

    When a single store's RSC lookup failed during main table rebuild, the entire import run would stop with a modal error, silently skipping all remaining stores. This was particularly problematic for unattended background runs. The rebuild now logs the error, reports the affected store in the post-import summary, and continues processing remaining stores.

  • Bug Fix Epicor MySQL-Compass import no longer drops all main tables

    When importing selected Epicor stores (Shift-click), stores you didn't select will keep their pricing data instead of being cleared and left empty.

  • Bug Fix Selection lists no longer cleared mid-ingest

    Dropdown menus in the pricing grid will no longer go blank during a background import.

  • Architecture BisTrack Direct SQL main table ownership transferred to rebuild

    BisTrack Direct SQL imports previously built per-store main tables during the ingest phase, which could leave stores without main tables if a background import ran while the app was open and the subsequent rebuild was deferred indefinitely. The import now loads only the [Store] staging tables and lets the unified rebuild process create main tables using the same generic SQL builder as other POS systems. This fixes edge cases like store 16254 ending up with no main tables at all.

  • Architecture New PosMainTableOwnershipPolicy defines which import phase owns tables

    Introduced PosMainTableOwnershipPolicy to explicitly define whether the ingest or rebuild phase builds each POS system's main tables. Almost all POS systems (Epicor, Mi9, Falcon, RockSolid, TransAct, Propello) now use rebuild-owned tables. Only BisTrack and WestLake remain ingest-owned because their drain logic does not yet rebuild their tables. The policy includes fail-safe tests to prevent new POS systems from accidentally inheriting ingest-owned behavior.

  • Architecture BisTrack CSV preload builds now explicitly flag their main table ownership

    The two BisTrack CSV preload paths (standard and DIB 6828 format) use a specialized SQL script that computes columns differently than the generic rebuild process. These handlers now set an explicit flag indicating they built the main tables, replacing a file existence check that incorrectly applied to all BisTrack stores including Direct SQL. This ensures the rebuild correctly skips or processes main tables based on what actually happened during ingest, not POS type assumptions.

  • Infrastructure Comprehensive tests prevent future main table ownership regressions

    Added PosIngestOwnsNoMainTablesTests to mechanically enforce that ingest-layer code does not touch main tables or SelectionLists. The test scans all files in the ingest services directory and fails if any unauthorized file contains main table DDL or SelectionLists truncates. An explicit allowlist documents the four remaining files that still build tables (BisTrack, WestLake, and their supporting code) with reasons why each exception exists and what needs to happen to remove it.

Cloud Sync & Vendor Data

  • New Feature Automatic post-publication catch-up

    Stores scheduled before the vendor publishes will now automatically catch up mid-morning with a quick vendor-only sync (seconds), instead of waiting until the next overnight run.

  • New Feature Post-publication vendor catch-up

    If your nightly sync runs before vendors publish (most stores do), you'll now automatically get the current catalog mid-morning without waiting until the next night, and it won't re-import your POS data.

  • New Feature Unattended updates are now reported on next launch

    When you open Margin Master after the background service updated your data overnight, you'll see a green badge and a notification confirming the update happened and when.

  • Improvement Once-per-day vendor sync guard

    Margin Master now tracks exactly what vendor data you have, not just when you last synced. If you reset your data or restore a backup, the sync will run normally without a prompt.

  • Improvement Background updates apply in place from a badge

    When new data downloads in the background, an amber "Click to update data" badge appears at the top of the screen. Click it when you're ready—you'll be asked once whether to run your pricing strategy too, then the data updates and your grid refreshes. The app no longer closes and restarts, so your session stays open.

  • Improvement In-place rebuild from activity badge

    When new pricing or catalog data downloads in the background, you'll see an amber badge at the top of the screen. Click it when you're ready to load the new data—the app stays open and shows progress just like a manual import.

  • Improvement Run outcomes distinguish parked work from completed work

    Run history now clearly shows when new data has been downloaded but is waiting for you to apply it, instead of reporting "completed" when the tables haven't been rebuilt yet.

  • Improvement Configurable publication cutoff per store

    Added VendorPublicationCutoffTime setting (format "HH:mm", default 09:00) so support can adjust the cutoff for stores in unusual timezones or when vendor publication timing drifts. Unparseable values fall back to the default rather than throwing—a typo in a setting must not stop a store from syncing. Erring late is the safe direction; a cutoff set too early would close the guard on a sync that ran before the catalog was finished.

  • Improvement Configurable publication cutoff time

    Support can now adjust when the system expects vendor catalogs to be published, if your region's timing differs from the 09:00 default.

  • Improvement Vendor-only data update mode

    Introduced --vendor-only command-line switch for headless data updates, which drops the POS import leg and fetches only vendor catalogs. Used by the post-publication catch-up to avoid redundant full POS imports. Recognized in all spellings (--vendor-only, --vendoronly, /vendor-only, case-insensitive).

  • Improvement Strategy leg of rebuild is bracketed as destructive

    The pricing strategy rewrites FuturePrice across the main tables and ran unflagged, so an app starting up mid-strategy could open onto half-written prices. The background runner now brackets the strategy phase with SetStrategyPhaseDestructiveAsync so concurrent startups wait rather than binding to incomplete data. The drain already brackets itself; this closes the gap for the strategy leg that runs after the drain has cleared its own flag.

  • Improvement Accurate status reporting for parked rebuilds

    The Background Jobs history now clearly shows when data was downloaded but not yet applied, making it easier to understand your store's current state.

  • Bug Fix Publication cutoff replaces date-based sync guard

    If your store syncs early in the morning (before ~9 AM), you were getting yesterday's catalog and staying a day behind. This is now fixed—the system knows when catalogs are published and waits for them.

  • Bug Fix Badge click now reloads the grid with new data

    Clicking the badge after a background update now reloads the grid with the new data, not just the filter dropdowns.

  • Bug Fix Background updates resume after machine restarts

    If your computer restarts or Margin Master closes unexpectedly while a background update is waiting, the next scheduled update will now complete automatically—your data stays current without manual intervention.

  • Bug Fix Scheduler no longer wedges when work is parked with no session present

    Background updates now resume correctly after a reboot or unexpected shutdown, even if a previous update was waiting to be applied.

  • Cloud Sync Publication cutoff-based freshness rule

    If your store syncs early in the morning before vendors publish their catalogs, the system now correctly recognizes when you need to fetch the day's catalog instead of treating yesterday's data as current.

  • Cloud Sync Background service skips redundant vendor syncs

    The scheduled background update will no longer interrupt you to rebuild vendor data that hasn't changed since the last sync.

  • Cloud Sync Vendor data fingerprint for drift detection

    A new VendorSyncFingerprint captures the row count and highest RowVersion of each synced vendor table and is written alongside the sync timestamp. Comparing the recorded fingerprint to the current state detects when data changed underneath a stored timestamp — such as after Reset All Data, a database restore, or external edits — and reopens the guard automatically. The fingerprint is measured in 41-242ms on real customer databases and is cheap enough to run on every sync and every service tick.

  • Cloud Sync Fingerprint check unchanged; reopens guard after reset/restore

    The existing fingerprint-based evidence check (comparing recorded vs. current table row counts and checksums) is untouched and still required alongside the timestamp. This is what reopens the guard after Reset All Data or a restore-from-backup, where the timestamp alone would lie and suppress the most-needed sync.

  • User Interface Confirmation prompt before repeating same-day sync

    If you click Update Vendor Data and you already synced earlier today, Margin Master will ask "Are you sure?" before downloading the catalog and rebuilding your tables again.

  • User Interface Color-coded activity badge states

    The activity badge color tells you what clicking it will do: blue means a background job is running, green means the data is already loaded (quick refresh), and amber means new data is ready to apply (takes a few minutes).

  • User Interface Repeat-sync prompt now shows actual sync time and publication status

    When you manually sync vendor data that's already current, the confirmation message now clearly shows when you last synced and confirms you already have the latest catalog.

  • User Interface Improved sync confirmation message

    When manually syncing vendor data that's already current, the confirmation now shows exactly when you last synced (date and time) and explains that you already have the latest published catalog.

  • Database New SyncVendorDataFingerprint application setting

    A new ApplicationSettingKey.SyncVendorDataFingerprint stores the vendor data fingerprint alongside the existing SyncVendorData timestamp. The two are written together atomically in RecordVendorSyncSucceededAsync after every successful vendor sync, whether interactive or headless, and are read together to evaluate the guard.

  • Database Vendor catch-up tracking

    Added VendorCatchUpLastRunDate application setting to store the local date the catch-up last ran, ensuring it fires at most once per day even across service restarts. An in-memory flag would allow a restart to re-trigger the catch-up on the same day.

  • Architecture Removed restart-based rebuild infrastructure

    Removed the `--rebuild-and-restore` command-line switch and `RebuildAndRestoreRunner` class that orchestrated the child process spawn, twenty-minute pipeline lock wait, and session restoration. The rebuild now uses the same `DrainPostProcessingAsync` flow triggered by manual POS imports, eliminating special-case logic and simplifying background coordination.

  • Infrastructure Vendor table lists and publication cadence

    A new VendorSyncTables class in MarginMaster.Common maps each vendor to the tables its sync populates, intentionally duplicating VendorSyncRequest.GetTablesForVendor so the background service can evaluate the guard without referencing MarginMaster.CloudSync. Drift tests pin the two lists together and enforce that every table added to a vendor sync also appears in the fingerprint. The class also records that Do-it Best publishes Monday-Friday, so a Friday sync remains current through the weekend.

  • Infrastructure Comprehensive test coverage for cutoff logic and vendor-only flag

    VendorSyncGuardTests rewritten with 19 test cases covering both sides of the 02:00 case (stale after cutoff, current before it), the Friday-before-cutoff weekend case, reset/restore scenarios, and fingerprint evidence. New VendorOnlySwitchTests pins the --vendor-only flag recognition—failure here would be silent, causing the catch-up to run a full POS import every morning instead of a seconds-long vendor sync. Full suite green: 1,727 passed.

  • Infrastructure Removed restart-based rebuild flow

    Deleted OfferParkedRebuildAsync, CaptureSessionAndRestartAsync, LaunchRebuildAndRestoreChild, RestoreCapturedSessionAsync, RebuildAndRestoreRunner, the RebuildAndRestore command, --rebuild-and-restore and --restore-session command-line switches, and the MaxDeferrals/DeferFor deferral machinery. AppLaunchSource.Restore is deliberately kept: the server validates LAUNCHSOURCE against a fixed list and discards unknown values, so dropping the member would put the client out of step with the server contract, and it still appears in historical rows.

  • Infrastructure Freshness evaluation in background service

    Background service now evaluates vendor sync decision conservatively (treats all vendors as daily-publishing) when resolving whether to launch the app, with the actual headless run re-evaluating using the real vendor type and stopping if nothing is due. Prevents the service from being overly cautious and missing legitimate runs.

User Interface

  • Bug Fix Caret-aware spinning for margin and retail price editors

    When editing margin percentages or fixed retail prices, you can now position your cursor at any digit and use the up/down arrows to adjust just that digit. For example, in "41.30%", placing your cursor after the "3" and clicking the up arrow changes it to "41.40%", not "42.30%".

  • User Interface Improved precision control in pricing fields

    This improvement works across all pricing screens where you set future margins or retail prices, making it easier to make small adjustments like changing cents or tenths of a percent.

  • Infrastructure Comprehensive test coverage for spin increment calculation

    Added 18 test cases covering place-value resolution logic, including handling of currency symbols, group separators, mask literals, edge cases like empty text and out-of-bounds cursor positions, and verification that DevExpress SpinEdit correctly applies fractional increments assigned during the Spin event.

Performance & Reliability

  • New Feature "Update Waiting on Background Service" dialog with one-click fix

    When the background service blocks an update, you'll see a new dialog that lets you stop it with one click and install the update right away.

  • New Feature Stop Service for Update dialog

    When an update needs the background service stopped, you'll see a clear explanation and can authorize it with one click, or choose to turn the service off so it never blocks updates again.

  • New Feature Headless file import bypasses Import Files dialog

    Scheduled POS file imports will now work reliably for stores using file-based imports.

  • Improvement Service relocated to prevent update failures

    The background service has been moved to a permanent location so updates can install even when it's running, preventing the "could not stop the background service" errors that previously blocked updates.

  • Improvement Background service relocated outside program folder

    The background service now runs from a permanent location, so updates can install even while it's running scheduled imports.

  • Improvement Multi-step unlock process before updates

    If an update can't install because something is holding the program folder, Margin Master now tries several ways to fix it automatically before asking for your help.

  • Improvement Epicor Compass connection errors now handled in headless mode

    Stores running Epicor Compass will now properly log connection errors during scheduled imports instead of hanging.

  • Improvement Stale vendor data check skipped during scheduled imports

    Scheduled imports will now proceed even when vendor data is slightly out of date, rather than skipping the import entirely.

  • Improvement Escalating stop methods for background service

    The unlock process now tries three progressively stronger methods before giving up: (1) polite stop via the Authenticated-Users grant (no UAC), (2) force-kill the service process by PID from 'sc queryex' (still no UAC), (3) hand back ServiceStopFailed so the UI can offer elevated stop or disable. Steps 1-2 run unattended in silent/headless update paths. The force-kill step clears exactly the case where the grant self-heal hasn't run yet—it needs no service rights, only rights over the process, so it succeeds when the user installed the service. Implemented in new InstallDirectoryUnlocker class with full test coverage (14 new/rewritten tests, 1,684 passing total).

  • Improvement Failed unlock outcomes carry specific explanations

    Error messages about blocked updates now correctly identify what's actually preventing the update, making it easier to resolve the issue.

  • Improvement Orphaned store table cleanup moved to rebuild

    Moved the cleanup of main tables belonging to excluded or removed stores from the ingest to the rebuild phase for Epicor MySQL-Compass. This work now happens silently (matching prior behavior where a wildcard drop removed them unconditionally) but only after all active store tables are safely rebuilt, and includes the same store-list validation fail-safes used in the prompted cleanup path.

  • Bug Fix Update abort errors now identify the correct subsystem

    Previously, when an auto-update had to abort because the install directory was locked, it always reported "Could not stop the background service" regardless of the actual cause. In reality, there were two distinct reasons for failure: either another Margin Master instance (typically a headless import launched by the service) was still running, or the background service itself wouldn't stop. This led to misleading error reports—one store (Niemann Ace 13329) that had been updating successfully every day for a week reported a service stop failure when the actual issue was a data-update import in progress. The error messages now correctly reflect which subsystem caused the abort, making troubleshooting and support tickets more accurate.

  • Bug Fix Update failure when background service blocks install directory

    Updates that couldn't install because the background service was running will now ask you to stop the service instead of just failing silently. The update will complete once the service stops.

  • Bug Fix Background imports no longer drop active pricing tables

    Background price updates will no longer clear your pricing data if Margin Master is open when they run. Previously, scheduled imports could leave you with empty price tables until you manually approved a rebuild.

  • Bug Fix Prevent background service hangs from hidden dialogs

    Scheduled updates no longer freeze when encountering problems that would normally show a popup dialog. Issues requiring attention now appear in logs and error reports instead of silently hanging.

  • Bug Fix Headless runs no longer hang on dialogs in session 0

    Scheduled imports and data updates will no longer get stuck when encountering errors that would normally show a dialog, preventing overnight updates from failing silently.

  • Bug Fix SelectionLists no longer cleared during ingest

    Dropdown menus throughout the application will no longer go blank during background imports.

  • Bug Fix Enable scheduled imports for file-based stores

    Scheduled automatic imports now work correctly for stores importing from files, even when vendor data hasn't been synced recently.

  • Bug Fix Partial imports now preserve unselected store data

    When rebuilding specific stores using Shift+click, other stores' pricing data will remain intact instead of being accidentally deleted.

  • Bug Fix Deferrals no longer counted as update failures

    Choosing "Not Now" on an update, or having an import running when an update tries to install, no longer counts as a failure that could block future automatic updates.

  • Bug Fix Update deferrals no longer counted as failures

    Margin Master now correctly distinguishes between an update that's waiting its turn (like when an import is running) and one that actually failed, so temporary delays won't block future automatic updates.

  • Bug Fix Startup checks now fail fast instead of hanging headless

    Added headless guards to StartupCheckService for license status changes, database connection validation, and schema upgrades. These operations require user confirmation or desktop windows, so headless runs now log clear error messages and throw InvalidOperationException instead of blocking forever on dialogs nobody can see. This prevents the service scheduler from pausing with no diagnostic information.

  • Bug Fix Service restart sentinel now set before stop, not after

    Fixed a race where AutoUpdateRestartBackgroundService was set after WaitForStatus, so a stop that timed out but completed left the sentinel unwritten and the service stayed down until reboot. Now sets wasRunning = true before calling Stop(), so the restart obligation is recorded the moment the stop is issued.

  • User Interface Update health tracking now exempts deferrals

    UpdateHealthState.RecordFailure is no longer called for IsDeferral outcomes (sibling process or user-declined stop). The startup post-update check skips recording when LastUnlockResult.IsDeferral is true. Silent update runs (UpdateInstaller) mark the version in UpdateBlockedByServiceLock when the service is specifically what stopped the apply, so the next interactive launch offers the fix immediately. ClearUpdateBlockedByServiceLock runs on every successful update, regardless of route, so the prompt can't outlive the problem.

  • Database New ApplicationSettingKey entries for service relocation

    Added UpdateBlockedByServiceLock (marks when a specific version is blocked by the service so the next launch offers the fix immediately), BackgroundServiceRelocated (remembers the one-time migration prompt was accepted), and clarified that AutoUpdateRestartBackgroundService is set only when a running service was stopped by the update process.

  • Architecture Import phase separation enforcement

    Introduced PosMainTableOwnershipPolicy to formally define which phase of an import owns the per-store main tables, with mechanical tests (PosIngestOwnsNoMainTablesTests, PosMainTableOwnershipPolicyTests) that fail if new code attempts to modify main tables or SelectionLists during the ingest phase. Almost all POS systems now correctly defer main table work to the rebuild; BisTrack and WestLake remain ingest-owned because their rebuild logic currently declines to build them.

  • Architecture Install directory unlock logic extracted to dedicated class

    Moved unlock orchestration from AutoUpdateService into new InstallDirectoryUnlocker class, injected as a singleton. AutoUpdateService now exposes LastUnlockResult (InstallDirectoryUnlockResult) so callers can distinguish deferrals from faults before recording failures. TryUnlockInstallDirectory returns typed outcomes instead of collapsing to bool, and logs deferrals at Warning (below ErrorReportingSink threshold) while genuine service failures log at Error. Added InstallDirectoryUnlockResult.IsUserActionable to identify the one outcome the stop-service dialog can fix. Surface-area contract pinned in MainMMViewModel.surface.approved.txt (EnsureBackgroundServiceRelocated added).

  • Infrastructure Test coverage added for both update abort scenarios

    Added comprehensive test coverage to ensure both abort paths—sibling process running and service stop failure—report their own distinct error messages and cannot regress to the generic message. The tests verify that the abort decision logic remains unchanged (maintaining safety of the fleet-wide update mechanism) while the diagnostic accuracy improves.

  • Infrastructure Add LaunchContext.IsHeadless flag and safety tests

    Introduced a process-wide LaunchContext.IsHeadless flag set by every headless command (--data-update, --import-vendor, --import-pos, etc.) to identify unattended runs. Defaults to false (the safe direction: showing a dialog to an interactive user costs a click; hiding one loses information). Added HeadlessDialogHangGuardTests with code scanning to prevent raw MessageBox.Show calls in POS import code paths and verify all headless commands properly set the flag, ensuring these hangs cannot silently return.

  • Infrastructure Background service binaries now signed and staged separately

    The service executable is now signed individually (in addition to living inside the signed app folder) since it's copied to %ProgramData% and registered as an auto-start service—exactly the shape SmartScreen scrutinizes. The publish pipeline stages it into a service\ subfolder (not flat in PUBLISH_DIR) with its own secrets-injected appsettings.json. Localization satellite assemblies are stripped from both the app folder and the service subfolder. BackgroundWindowsServiceController now exposes StagedServiceFolder, InstalledServiceFolder, and StagedServiceExePath to distinguish the staging location from the run location.

  • Infrastructure Service binaries staged separately in publish

    The background service is now published to a service\ subfolder of the install rather than flat into the program directory, and is signed independently. The publish workflow copies secrets to both the app's appsettings.json and service\appsettings.json, and strips localization folders from both trees.

  • Infrastructure Added comprehensive test coverage for headless dialog guards

    Created HeadlessDialogHangGuardTests with regex-based scanning of import partials to detect raw MessageBox.Show calls, verification that all headless command-line arguments set LaunchContext.IsHeadless, and confirmation that the safe default is interactive. The tests guard the rule that an unattended run never raises a dialog and document the specific hang signature: "Launching headless run" with no matching "exited with code" in service logs.

  • Infrastructure Uninstall hook removes service folder

    The uninstall hook now removes the service's binaries from %ProgramData% after stopping and deleting the service registration. Best-effort to avoid leaving orphaned files after uninstall, since Velopack only removes what it installed.

Infrastructure & Internal

  • New Feature Remote SQL Access Configuration Script

    Multi-PC stores can now use File > Utilities > Installation Scripts > Enable Remote (LAN) Access to automatically set up the host computer so other workstations can share the same database.

  • New Feature Remote SQL Access Setup Script

    Support can now run a single automated script on the main store computer to set up database sharing for additional PCs. The script checks everything needed for remote access and reports what's wrong, then fixes it when you run it again with -Apply.

  • Improvement Enhanced diagnostic logging for update failures

    The auto-update service now captures and logs the specific reason each update attempt is aborted, making it easier to diagnose why updates are deferred at particular stores. This addresses a real-world triage issue where Niemann Ace 13329 was reported as having service-stop failures despite successfully auto-updating every day for a week.

  • Improvement Encrypted Password Storage

    Database passwords are now stored encrypted for better security.

  • Improvement Expanded SQL Server install/upgrade documentation

    Clarified critical safety rules in the SQL Server installation documentation, including the ownership guard that prevents touching any SQL instance the application cannot prove belongs to Margin Master, instance naming behavior differences between the in-app installer and support scripts, and authentication mode (Windows-only by default). Added 30 lines of new content covering when and why a technician would need to enable remote SQL access.

  • Improvement Documentation for multi-PC database setup

    Added comprehensive documentation page "Enable Remote (LAN) SQL Access" explaining how Margin Master shares databases across multiple store PCs, when the setup script is needed, what it checks, how to set up the workstation side, and troubleshooting for common connection failures (SQL error 18456, error 53, SQL Browser issues). Updated Database Setup guide to reference the script and explain that SQL Server Express defaults to Windows-authentication only. Updated Firewall and Network Requirements to document the inbound TCP/1433 and UDP/1434 rules required for multi-PC stores, scoped to Domain and Private profiles only.

  • Bug Fix Auto-update abort messages now identify the correct cause

    When an automatic update is postponed, you'll now see a more accurate explanation of why — whether it's because a background task is running or because an import is in progress.

  • Bug Fix Installation Scripts console path resolution

    Fixed the Enable-SQLRemoteAccess.ps1 script to provide the correct command for applying SQL fixes. When launched from the Installation Scripts dialog, the PowerShell console starts in C:\WINDOWS\system32, not in the script folder, so the previously documented relative path (.\Enable-SQLRemoteAccess.ps1 -Apply) would fail. The script now prints the full path from $PSCommandPath at the end of each audit run, which correctly resolves regardless of working directory. Documentation updated to explain why the full path is required and to show the correct cached location.

  • Bug Fix Remote access script now prints correct -Apply command

    The Enable-SQLRemoteAccess.ps1 script, launched from the Installation Scripts dialog in Support Tools, opens a PowerShell console that starts in C:\WINDOWS\system32 rather than the script's folder. Previously, instructions told users to run ".\Enable-SQLRemoteAccess.ps1 -Apply" which would fail with "is not recognized" because the relative path couldn't resolve. The script now prints the exact command with full path at the end of the audit: "& 'C:\ProgramData\RetailerSoft\MarginMaster\Scripts\Enable-SQLRemoteAccess.ps1' -Apply". Users can simply copy and paste this line to apply the fixes.

  • Bug Fix Database Setup window SSMS upgrade button now resolves required script dependencies

    The "Upgrade SSMS" button in Database Setup now works reliably on all machines.

  • Bug Fix Database Setup window SSMS upgrade now resolves required scripts

    The Database Setup window's "Upgrade SSMS" button was downloading only the Upgrade-SSMS.ps1 shim but not the Install-SSMS.ps1 script it depends on, causing failures with "Install-SSMS.ps1 not found". Both scripts are now downloaded together, matching the behavior of the guided SQL Server Setup window which already handled this correctly.

  • Bug Fix SQL Authentication Credentials Lost After Restart

    Workstations connecting to a shared database with SQL authentication now stay connected across restarts instead of reverting to Windows authentication and requiring credentials to be re-entered.

  • Bug Fix SQL authentication credentials now persist across restarts

    When connecting to a shared database on another PC, your SQL login username and password now stay saved. Previously you had to re-enter them every time you opened Margin Master.

  • Bug Fix PowerShell Script Encoding Compatibility

    Fixed Install-OleDb12.ps1 containing two em-dash characters (U+2014) that caused "Missing closing '}'" parse errors under Windows PowerShell 5.1. Files are UTF-8 without BOM, which 5.1 mis-decodes. All ten support scripts now verified ASCII-only and parse clean under both Windows PowerShell 5.1 and PowerShell 7+.

  • User Interface Updated documentation with full path requirement explanation

    Documentation for the Enable-SQLRemoteAccess script now explains why the full path is required and includes a note at the top of the usage section. The docs clarify that Margin Master always caches the script at the documented location regardless of whether it came from the cloud, local cache, or embedded in the application, and that the console is already elevated so no additional setup is needed.

  • User Interface Remote access script added to Installation Scripts dialog

    The Installation Scripts window now includes a tool for setting up database sharing when you have multiple PCs in the store.

  • User Interface Installation Scripts Dialog Entry

    Added "Enable Remote (LAN) Access" to the Installation Scripts dialog with full description explaining it checks and configures host requirements for multi-PC setups, reports only by default, and requires -Apply to make changes.

  • Infrastructure PowerShell script analysis suppression

    Added a justified PSAvoidUsingPlainTextForPassword suppression to the -Password parameter. The password is a fixed credential compiled into the shipped client and must reach SqlConnectionStringBuilder as a plain string; using SecureString would add unnecessary complexity and break the unattended -NonInteractive execution path. The value is already masked in all output.

  • Infrastructure Added comprehensive documentation for Upgrade-SSMS script

    Created complete documentation (Upgrade-SSMS.md) clarifying that this script is a thin shim delegating to Install-SSMS.ps1, explaining when it's used (guided setup, Database Setup window, Diagnostic Tool), its parameters, exit codes, and troubleshooting. Also added the script to the documentation index with appropriate search keywords and metadata. Intentionally not added to the Installation Scripts catalog since Install-SSMS already covers that entry point.

  • Infrastructure Added documentation for Upgrade-SSMS support script

    Created comprehensive documentation explaining that Upgrade-SSMS is a thin shim that delegates to Install-SSMS, where it's used in the application, and how to troubleshoot missing sibling script errors. Documentation added to both the public docs site and the scripts folder.

  • Infrastructure Encrypted password storage for SQL logins

    Added EncryptedPasswordConverter JSON converter that encrypts SQL Server passwords at rest in DatabaseConnections.json using AES with machine-specific keys. Handles migration transparently—passwords written before this converter existed are read as plaintext and re-encrypted on the next save. Failed decryption (from a regenerated machine key or moved file) yields an empty password rather than garbage, so the app prompts for credentials instead of mysteriously failing authentication. Applied to SqlServerDatabase.Password property.

  • Infrastructure Documentation metadata updates

    Updated last_updated timestamps on database-setup.md and firewall-network-requirements.md to reflect recent edits made during this work.

  • Infrastructure Corrected SQL Server installation documentation inaccuracies

    Fixed three outdated claims in sql-server-install-upgrade.md dating from February 2026: (1) SQL Server 2025 Express is no longer preview and is now the default with 2022 as fallback, not a user choice, (2) documented the ownership guard rule that prevents the installer from touching any SQL instance it cannot prove belongs to Margin Master, and (3) clarified that new instances use Windows Authentication only with no sa account, pointing to the remote access documentation for multi-PC scenarios. Also documented the instance naming behavior (defaults to SQLEXPRESS, uses dedicated name only when occupied) and how it differs from the Install-SQLExpress.ps1 script (which always defaults to MARGINMASTER).

  • Infrastructure Updated documentation search index

    Added the new Upgrade-SSMS documentation to the searchable index with appropriate keywords including "Install-SSMS not found", "shim", "ssms 18", "ssms 19", "ssms 20", and "ssms 22" to help support staff find troubleshooting guidance.

  • Infrastructure Documentation for Multi-PC Database Setup

    Added comprehensive documentation including support script guide (enable-sql-remote-access.md), updates to database-setup.md and firewall-network-requirements.md covering the shared MarginMaster login and host configuration requirements, troubleshooting guide for common connection failures (error 18456, 53), and search metadata for "second PC", "workstation", "login failed", etc.

  • Infrastructure Comprehensive test coverage for authentication persistence

    Added DatabaseConnectionAuthenticationTests with eight test cases covering SQL authentication detail extraction from connection strings, Windows authentication clearing stored credentials, handling empty/unparseable connection strings, connection string rebuilding from stored records, and encrypted password JSON serialization round-trips. Pins the regression where authentication mode was hard-coded to Windows-only.

  • Infrastructure Test Coverage for Connection Authentication

    Added DatabaseConnectionAuthenticationTests with 188 lines covering SQL authentication persistence, Windows authentication credential clearing, empty/unparseable connection string tolerance, connection string rebuilding, and encrypted password round-tripping. Pins the regression where authentication details were discarded on save.

CloudSync
2026.823.35418
August 24, 2026

Epicor SFTP session leak causing self-worsening connection failures; Misleading Epicor connection error guidance; Data Aging View showing contradictory day counts.

Infrastructure & Internal

  • Bug Fix Epicor SFTP session leak causing self-worsening connection failures

    Epicor Eagle imports now properly close their connections, preventing the "server disconnected" error from appearing after multiple retries.

  • Bug Fix Misleading Epicor connection error guidance

    When an Epicor import fails, the error message now tells you what actually went wrong (network issue, server problem, or bad credentials) instead of always saying to check the server address.

  • Bug Fix Data Aging View showing contradictory day counts

    The Data Aging View now clearly shows vendor data ages in "business days" while POS data ages in "days"—both are correct, just counting different ways.

  • Bug Fix Data Aging View header overstating vendor data freshness

    If vendor sync runs but doesn't actually update catalog tables, the Data Aging View now shows a red warning telling you the real merge date and to run Get Vendor Data again.

2026.823.33154
August 23, 2026

Added numeric formatting to cost and quantity selection boxes; Applied proper numeric formatting to all value entry fields; Migration safety guarantees.

User Interface

  • Improvement Added numeric formatting to cost and quantity selection boxes

    Dollar amounts and quantities in strategy filters now display with proper formatting—dollar signs for costs, commas for large numbers, and percentages for margins.

  • Improvement Applied proper numeric formatting to all value entry fields

    All number entry fields now display with proper formatting: dollar signs for prices, percent symbols for margins, and decimal formatting for quantities. This makes it clearer what type of value you're entering.

  • Improvement Selection boxes now seed default values for empty editors

    When entering price ranges or manual amounts, empty fields now start at "$0.00" instead of blank, and clicking in a field selects the number so you can type right over it.

  • Improvement Preserved user-entered values across checkbox state changes

    If you uncheck the Manual option and then check it again, your previously entered amount will still be there instead of being erased.

  • Bug Fix Manual amount entry now hides properly when unchecked

    Unchecking "Manual" in price comparisons now correctly hides the amount entry box. Your typed amount is saved if you check Manual again.

  • Bug Fix Manual amount entry visibility now follows checkbox state

    The Manual amount entry box now appears only when the Manual option is checked and disappears when you uncheck it. Your previously entered amount is remembered if you check Manual again.

  • Bug Fix Margin fields now format consistently with grid columns

    Margin filters now show percentages matching the grid columns (e.g., "35.00%"). Note: Old margin rules may display incorrectly (3,000% instead of 30%) if they were saved with wrong values—these rules weren't working correctly before, but the issue is now visible.

  • Bug Fix Fixed Current Margin comparison to use percentage format

    When setting up rules that compare Current Margin or other percentage fields, the value entry box now shows percentages (like "10.00 %") instead of plain numbers, matching what you see in the grid.

  • Bug Fix Comparison operators now seed with default value instead of blank

    When you select a comparison operator like "Greater Than," the value box now starts with 0 instead of being blank, and the number is pre-selected so you can just start typing your amount.

  • Bug Fix Fixed percentage value storage to use fractions, not scaled display values

    Percentage-based pricing rules now save and filter correctly. Previously, a rule like "Current Margin < 10%" wouldn't match any products because it was actually comparing against 10.0 instead of 0.10.

  • User Interface Manual amount editor repositioned for clarity

    The Manual amount entry box now appears directly under the "Manual" option instead of at the bottom of the panel, making it clearer which field you're filling in.

  • User Interface Manual amount editor moved to its own line

    The Manual amount entry box now appears on its own line below the Manual checkbox, making it easier to see and use without text getting cut off.

  • User Interface Future Price panel fields restyled for consistency

    The Future Price panel's Margin % and Fixed Retail fields now have consistent styling with a cream background and gold border.

  • Architecture Added SelectionValueEntryPolicy with comprehensive test coverage

    Introduced SelectionValueEntryPolicy as a pure, testable decision function that determines which value editor to show based on row state. Added 15 unit tests pinning the behavior, including the specific "Manual unchecked shows nothing" case that was the original bug. Separated presentation logic from decision logic to enable reliable testing of the UI state machine.

Performance & Reliability

  • Bug Fix Background service infinite loop on data updates

    Fixed a critical defect where the DataUpdate job could not record its last-run timestamp due to an incorrect mapping, causing the background service to re-download vendor catalogs every five minutes indefinitely until manually stopped. The job-to-setting mapping is now exhaustive and logs an error if a job type has no marker rather than silently using another job's key.

  • Bug Fix Fixed infinite data-update loop

    The background service was repeatedly relaunching the DataUpdate job every five minutes because it was writing the last-run timestamp to a retired setting key. The job could not record that it had run, so the schedule stayed permanently due. Added exhaustive mapping to ensure every job type writes to its own last-run marker, with loud failures if a new job is added without one.

  • Bug Fix Rebuild workflow now waits for pipeline lock instead of abandoning

    When you agree to a data rebuild, the system now waits for any background work to finish before applying it, instead of asking you again.

  • Bug Fix Prevented duplicate rebuilds when prior rebuild is pending

    The background service now checks whether a rebuild from the previous run is still awaiting user consent before ingesting data again. Previously, if the user hadn't responded to the first prompt, the service would re-download the data, stack a second prompt, and race any rebuild the user eventually agreed to.

  • Bug Fix Prevented duplicate rebuild prompts during active sync

    You will no longer see multiple rebuild prompts stacking up while waiting to respond to the first one.

  • Bug Fix Rebuild now waits for pipeline lock instead of abandoning

    After agreeing to a data update, the rebuild will now wait for any background jobs to finish rather than asking you to restart again.

  • Bug Fix User session now correctly restored after successful rebuild

    Your saved filters and selections are now properly restored after a data rebuild completes successfully.

  • Bug Fix Restored user screen selections after rebuild

    Your table filters, selections, and grid view are now properly restored after agreeing to a data update and restart.

  • Bug Fix Grid data now loads when restoring captured session

    When your session is restored after a data update, the pricing grid now automatically reloads with your filters applied instead of appearing empty.

  • Infrastructure Added comprehensive last-run marker mapping tests

    Added contract tests that walk the BackgroundJobType enum and verify each job has its own unique last-run setting key. Prevents future jobs from being added without proper scheduling markers, which would cause infinite launch loops.

  • Infrastructure Improved test reliability for multi-instance scenarios

    Interactive session presence tests now adapt to whether Margin Master is already running on the test machine instead of asserting "no instance present" unconditionally, which previously caused test failures on machines where someone had the app open during testing.

Infrastructure & Internal

  • Improvement Migration safety guarantees

    The migration explicitly sets the Execute Strategy step to false, ensuring that unattended repricing is never enabled during migration since the retired schedule model did not imply consent to automatic price updates. Migration failures now retry on next startup rather than marking themselves complete, preventing stores from being left permanently unmigrated.

  • Bug Fix Schedule migration now runs from the background service

    Fixed a critical path where stores updated silently by the background service never migrated their schedules. The service relaunches through --post-update-start-service which exits before the database opens, preventing app-side migration from running. The service now migrates schedules on its own startup, ensuring stores that never open the app can still convert to the new schedule format and continue importing overnight.

  • Bug Fix Schedule migration now runs from Windows service

    The migration that converts legacy Vendor and POS schedules to the new Data Update job format now executes from the Windows service itself, not just the app. This fixes a critical gap where stores updated silently by the service (without the app ever launching) would never migrate, causing them to silently stop importing overnight data. The service-side migration runs before the first schedule evaluation, ensuring stores remain operational.

  • Bug Fix App update check schedule is now migrated

    The automatic app update check was reshaped from mode/interval to days-and-time but was not being migrated. This would have caused stores to never auto-update again after taking this release, as the service would find no days selected and treat the job as unrunnable. All three background schedules (vendor sync, POS import, and app updates) are now properly converted, with all seven days selected to preserve the previous daily behavior.

  • Bug Fix App update check schedule migration

    The migration now also converts the app update check schedule from the retired interval-based format to the new days-and-time format. Without this conversion, stores would stop checking for updates entirely, preventing them from receiving future fixes. The migration defaults to checking all seven days to preserve the existing daily check behavior.

  • Architecture Single shared migration implementation

    Created a unified BackgroundScheduleMigrator class used by both the desktop app and Windows service, ensuring they can never disagree about a store's schedule configuration. The migrator accepts get/set delegates so it can work against either the app's settings service or the service's SQL reader without creating dependencies between them.

  • Architecture Unified schedule migration implementation

    The app and background service now share a single BackgroundScheduleMigrator implementation rather than maintaining separate copies. This prevents the two components from disagreeing about a store's schedule configuration, which would be worse than either being wrong independently. The shared migrator is tested with 191 test cases covering all migration scenarios.

  • Infrastructure Comprehensive migration test coverage

    Added 191 lines of tests covering all migration scenarios including idempotency, edge cases with missing settings, the critical safety property that migration never enables unattended repricing, and verification that both the app and service call the shared migrator. Also added reachability tests to ensure the migration runs on every possible update path.

2026.823.26161
August 23, 2026

Add WPF services (1 new); Update MarginMaster.BackgroundService (4 updated); Update view models (4 updated).

Strategy & Pricing

  • New Feature Add WPF services (1 new)
  • Improvement Update MarginMaster.BackgroundService (4 updated)
  • Improvement Update view models (4 updated)
  • Improvement Update WPF views (1 updated)
2026.823.25094
August 23, 2026

Shared strategy catalog and download; Shared strategy catalog and download; Strategy Comparison Report dialog.

Strategy & Pricing

  • New Feature Shared strategy catalog and download

    Open Strategy > Get Premade Strategies to see ready-made pricing strategies for your vendor. Click "Download / Update" to install one, then open it in the Strategy Manager. To customize it, use the "Copy Current Strategy" button to create an editable copy.

  • New Feature Shared strategy catalog and download

    Instead of building pricing strategies from scratch, you can now download starter strategies built by RetailerSoft for your vendor. Open Strategy > Get Premade Strategies, select a strategy, and click Download. The downloaded strategy is read-only — open it in the Strategy Manager and use "Copy Current Strategy" to make an editable copy you can customize.

  • New Feature Strategy Comparison Report dialog

    Open Strategy > Compare Strategies to capture snapshots of your pricing results and compare them side-by-side. The report shows how much profit each strategy gains and which one wins.

  • New Feature Shared strategy catalog and installer

    The Strategy menu now has "Get Premade Strategies" — a library of ready-to-use pricing rules you can install with one click. Installed strategies are read-only templates; use "Copy Current Strategy" to make an editable version.

  • New Feature Strategy Comparison Report dialog

    Open the Strategy menu and select "Compare Strategies" to capture your current pricing results with a custom label (e.g., "2023 Current Rules"), then run a new pricing strategy and capture it again (e.g., "2024 Test Strategy"). Select both snapshots, choose whether to view results Overall, By Store, or By Department, and click "Build Comparison" to see which strategy makes more money and by how much per year.

  • New Feature Strategy Utilities hub

    Look for "Strategy Utilities…" in the Strategy menu to access all strategy tools in one place.

  • New Feature Strategy Utilities hub

    A new "Strategy Utilities" option in the Strategy menu provides one-click access to all pricing strategy tools in a single dialog.

  • New Feature Unified sensitivity scoring engine

    Price sensitivity analysis is now available for both Ace Hardware and Do it Best stores, showing which departments are most "blind" (eligible for price increases) versus most "sensitive" (requiring careful pricing).

  • New Feature Copy custom groups from another strategy

    On the Manage Custom Groups screen, click the hamburger menu and choose "Copy Group from Another Strategy..." Pick a strategy from the left list, then pick the group to copy from the right list. The system will suggest a name for the copied group. Click "Copy Group" and the group will be added to your current strategy with all its SKUs and settings intact.

  • New Feature Copy custom groups from another strategy

    On the Manage Custom Groups screen, click the hamburger menu and choose "Copy Group from Another Strategy..." to copy a group from a different pricing strategy into the current one. The original group is not changed.

  • New Feature Bulk "Resolve Unassigned" actions for SKU exceptions

    When SKU exceptions are missing a price level, the hamburger menu now shows "Resolve Unassigned" with options to delete them all, inactivate them all, or assign a price level to all of them at once. This fixes the common problem where imported strategies contain hundreds of exceptions that can't price anything.

  • New Feature Bulk "Resolve Unassigned" menu in SKU Level Exceptions

    If you have active SKU exceptions with no price level (which the strategy pre-flight warns about), you can now fix them all at once using the "Resolve Unassigned" menu instead of editing each one individually.

  • New Feature Import Competitor Prices dialog

    Open File > Utilities > Import Competitor Prices, click Download Template to get a correctly formatted spreadsheet, fill in your SKU and competitor price columns, then browse to your file and click Import. The prices appear in Competitor 1 through Competitor 5 columns.

  • New Feature Import Competitor Prices from spreadsheet

    Open File > Utilities > Import Competitor Prices, select your spreadsheet, review what was found, and click Import. Your competitor prices will load into the Competitor 1–5 fields where you can use them for pricing analysis and strategies.

  • New Feature Replace or Add mode for each competitor price column

    When importing competitor prices, you can now choose "Add" or "Replace" for each column. Use Replace when your POS already fills the field and you want only your own prices there, or when reloading a shop report and old prices should not remain. The window shows how many items already have values so you can make an informed choice.

  • New Feature Added option to hide Strategy Execution Summary after runs

    Check or uncheck "Show this summary after each strategy run" to control whether this report appears. You can also find this setting in Options > Miscellaneous. The strategy still runs the same way and logs everything normally — only the summary report is hidden.

  • New Feature Below-cost pricing warning on SKU exceptions

    When saving SKU exceptions that price below cost, you'll see a warning listing which items and why (e.g., "1005412 — its -25% margin prices below cost"). You can review and choose "Save anyway" if it's intentional.

  • New Feature Below-cost warning when saving SKU exceptions

    When saving a SKU exception that prices below cost, you'll see a warning listing which items and why (e.g., "1005412 — its -25% margin prices below cost"). You can review and choose to save anyway if it's intentional.

  • New Feature Read-only strategy state for downloaded strategies

    Strategies you download from the premade catalog are read-only and show a banner explaining this. Click "Copy Current Strategy" to make an editable version you can customize.

  • New Feature Shared strategy installation and versioning

    Downloaded strategies show a banner "Shared strategy vN — read-only" in the Strategy Manager. You can execute, activate, export, and back them up, but to make changes you must use "Copy Current Strategy" first. When a newer version is available, re-download it from the catalog — since the original cannot be edited, no local changes can be lost.

  • New Feature Shared strategy publisher (support machines only)

    Support staff can publish local pricing strategies to the shared catalog for all stores to use.

  • New Feature Local snapshot storage for strategy results

    Your captured pricing snapshots are saved locally on your computer and remain available even after syncing with the cloud, so you can compare strategies weeks or months apart.

  • New Feature Automatic strategy result snapshots

    Every time you run a strategy, the system automatically saves a snapshot of what changed. You can later compare these snapshots to see how different strategy runs affected your pricing. Only the most recent automatic snapshot for each strategy is kept.

  • New Feature Auto-capture strategy comparison snapshots

    Every time you run a strategy, Margin Master now saves a snapshot of the price changes in the background. You can turn this off in the Compare Strategies dialog if you prefer to capture snapshots manually.

  • New Feature Find and resolve duplicate SKUs across groups

    On the Manage Custom Groups screen, click the hamburger menu and choose "Find Duplicate SKUs..." to see any SKUs that appear in more than one group. Click the X next to a group name to remove that SKU from that group immediately. This helps prevent pricing conflicts where the same item is assigned to multiple groups.

  • New Feature Find duplicate SKUs across custom groups

    Click the hamburger menu and choose "Find Duplicate SKUs..." to see which items appear in more than one custom group. Click the X next to a group name to remove that item from that group.

  • New Feature Bulk "Resolve Unassigned" actions for custom groups

    When custom groups are missing a price level, the hamburger menu now shows "Resolve Unassigned" with options to delete them all, inactivate them all, or assign a price level to all of them at once.

  • New Feature Bulk "Resolve Unassigned" menu in Manage Custom Groups

    If you have active custom groups with no price level, you can now delete them, inactivate them, or assign a price level to all of them at once using the new "Resolve Unassigned" menu.

  • New Feature Replace or Add choice per competitor column

    When importing competitor prices, you can now choose "Replace all existing values" to clear out prices that came from your POS system, so filters like "Competitor 1 greater than 0" return only the items in your spreadsheet.

  • New Feature Automatic column enablement for strategy requirements

    When you open or run a pricing strategy, Margin Master will now automatically show any columns that strategy needs, so you can see and edit all the price levels the strategy uses.

  • New Feature Automatic column view reconciliation for pricing strategies
  • New Feature Auto-repair offer for margin groups with recognizable names

    If you have a custom group named something like "25%Margin" that stopped pricing, the app will now offer to restore the 25% margin setting when you open or close the custom groups screen.

  • New Feature Below-cost pricing warning on custom groups

    When saving custom groups that price below cost, you'll see a warning listing affected groups and the reason (e.g., "Clearance Items — it prices from cost and then subtracts").

  • New Feature Below-cost warning when saving custom groups

    When saving a custom group that prices below cost, you'll see a warning listing which groups and why (e.g., "Clearance Items — it prices from cost and then subtracts"). You can review and save anyway if it's intentional.

  • New Feature Shared strategy publishing (support machines only)

    Support users can share a pricing strategy with all stores by opening it in the Strategy Manager and selecting "Update or Create Shared Strategy" from the menu.

  • New Feature Shared strategy publishing (support machines only)

    (Support machines only) You can publish a local strategy to the shared catalog using the "Update or Create Shared Strategy" menu item in the Strategy Manager. Margin Master will validate the strategy and warn you about anything that might not work on all stores before publishing.

  • New Feature Multi-grain comparison rollups (Overall, By Store, By Department)

    View your comparison across the entire organization, broken down by individual store, or broken down by department — the dollars always add up to the same overall total.

  • New Feature Strategy result freshness detection

    The Compare Strategies screen now shows whether each saved strategy result is "Current" or "Not Current" based on whether your data or the strategy itself has changed since it was last run.

  • New Feature Combine stores toggle for cross-store pricing analysis

    When analyzing strategies, you can now check "Combine stores" to see departments and classes rolled up across all your stores—useful when you price all stores the same and don't need to see each store separately.

  • New Feature Combine-stores view for strategy comparison

    You can now check "Combine stores" to group pricing by department and class across all your stores at once, since most stores price everything the same way anyway.

  • New Feature Price level picker for bulk assignment

    When assigning a price level to multiple exceptions or groups at once, you'll see a picker showing only price levels that work without additional settings.

  • New Feature Automatic column display after import

    After importing, Margin Master asks if you want to display the competitor columns you just loaded so you can see the prices right away.

  • New Feature Pre-flight validation for rules that cannot price

    Before running a strategy, you'll now see a warning if any custom groups or SKU exceptions are incomplete and won't price anything, giving you a chance to fix them before the run.

  • New Feature Excel export of comparison results

    Click "Export to Excel" to save the comparison table for sharing with management or further analysis in Excel.

  • New Feature Automatic rerun of stale strategies

    If you select strategies with outdated results, the system offers to automatically rerun them before showing the comparison, ensuring you're always comparing current numbers.

  • New Feature Smart value parsing and validation

    The import understands prices like "$1,234.567" (rounds to $1,234.57) and skips blank cells instead of zeroing them out, so your existing prices stay safe.

  • New Feature Comprehensive import logging

    Every import creates a log file showing exactly what happened—which prices were loaded, which cells were skipped, and which SKUs weren't found in your database. Click "Open Log" to review it.

  • New Feature Strategy Comparison Report dialog

    Open the Strategy menu and select "Compare Strategies" to capture your current pricing results with a custom label (e.g., "2023 Current Rules"), then run a new pricing strategy and capture it again (e.g., "2024 Test Strategy"). Select both snapshots, choose whether to view results Overall, By Store, or By Department, and click "Build Comparison" to see which strategy makes more money and by how much per year.

  • New Feature Local snapshot storage for strategy results

    Your captured pricing snapshots are saved locally on your computer and remain available even after syncing with the cloud, so you can compare strategies weeks or months apart.

  • New Feature Multi-grain comparison rollups with Excel export

    View your comparison across the entire organization, broken down by individual store, or broken down by department — the dollars always add up to the same overall total. Click "Export to Excel" to save the comparison table for sharing with management.

  • New Feature Docs: add ECI hosting-migration advisory to the VPN requirement doc
  • New Feature Docs: add ECI NAT-over-tunnel requirement and an IT question checklist
  • New Feature Add Import Competitor Prices ΓÇö load a spreadsheet into Comp1-Comp5
  • New Feature Add an end-to-end cloud sync fidelity harness
  • Improvement Relative sensitivity scoring for easier comparison

    Sensitivity scores now range from 0 (least sensitive) to 100 (most sensitive) within each group, making it much easier to spot which areas are most affected by price changes.

  • Improvement Relative sensitivity scoring within peer groups

    Each row's sensitivity score now shows how it ranks against its peers—100 means most price-sensitive in its group, 0 means least sensitive—making it easier to spot which departments or classes need the most careful pricing.

  • Improvement Honest sensitivity score display with confidence-based coloring

    Sensitivity scores now show the real number instead of exaggerating small differences between stores. The color helps you spot which items are more price-sensitive (red) versus less sensitive (green), but only when there's enough data to be confident.

  • Improvement MAP and IMAP always available at Ace stores

    At Ace stores, "MAP Price" and "IMAP Price" are always available when setting future prices, so you can correct critical pricing violations with one click.

  • Improvement "Just Run" now applies pricing corrections automatically

    When you click "Just Run" in Ace Critical Pricing, Margin Master now automatically fixes the pricing violations and shows you what was changed, instead of just listing the problems. You'll see a breakdown of how many items were corrected in each category (below-cost, below-MAP, below-IMAP).

  • Improvement "Just Run" applies corrections automatically

    When you click "Just Run" in the Ace Critical Pricing tool, Margin Master now immediately fixes pricing violations and sets future prices for you. You'll see a summary of how many items were corrected in each category (below-cost, below-MAP, below-IMAP), and the grid will display the items with their new future prices ready to export to your POS.

  • Improvement Margin suggestion prompts also show step numbers

    When the system suggests margin percentages for your pricing groups, it now shows the step number so you can easily find which group it's referring to.

  • Improvement Specific error messages for each RockSolid export failure condition

    When a RockSolid price export fails, you'll now see exactly what's wrong (like "RockSolid.RS is marked read-only" or "another program has the file locked") instead of a list of possibilities to check.

  • Improvement Preserved pricing strategy configuration over view changes

    Your saved pricing strategies will continue working with all their original settings even after you customize which fields are visible in your workspace.

  • Improvement Add service method to create individual price level items

    Added a new CreateFuturePriceSetToLevel method to PriceLevelListService that builds a single set-to level item outside the normal offered-list filter, enabling the restoration of price levels that exist in saved rules but aren't currently surfaced by the active view.

  • Improvement Redesigned strategy comparison with staleness detection

    When comparing strategies, you now select them by name, and the system tells you if their results are out of date. Out-of-date strategies are automatically rerun before the comparison shows, so you always see accurate results.

  • Improvement Three-way strategy comparison

    You can now compare up to three pricing strategies side-by-side instead of just two, making it easier to evaluate multiple options at once.

  • Improvement Per-row checkbox state management

    Each strategy picker row now tracks its own IsEnabled state independently, allowing the UI to dynamically enable or disable individual checkboxes based on the current selection count. This provides clear visual feedback about which strategies can be selected at any given moment.

  • Improvement Visual feedback for selection cap

    Added an IsEnabled property to strategy picker rows that dynamically updates as selections change. Unselected strategies become visually disabled (greyed out) when the three-selection cap is reached, while previously selected strategies remain enabled and can be deselected.

  • Improvement Strategy names now appear in column headers

    Column headers now show your actual strategy names instead of "Baseline" and "Candidate."

  • Improvement User-controlled restoration after strategy comparison

    After comparing strategies, you'll be asked whether you want to recalculate your original strategy's prices (which can take a while), clear the prices, or leave them alone—no more waiting for automatic recalculations you might not want.

  • Improvement User-controlled restore after comparison runs

    After comparing strategies, you now choose whether to reapply your original strategy (which reruns it completely), clear the Future Prices, or keep them as-is—no more waiting for automatic reruns you might not need.

  • Improvement Simplified column labels

    Column headers are now simpler and easier to read, showing just the metric type since the strategy name appears in the group header above.

  • Improvement Enhanced diagnostic logging for Future Price panel failures

    Improved the error log message when Future Price panel initialization fails at startup to clearly indicate that the panel will be unavailable for the session and that no strategy steps can execute. This helps support staff quickly identify the root cause when users report strategy execution failures.

  • Improvement Better error messaging for incomplete pricing rules

    When reviewing pricing rules, you'll now see a clear message telling you "it is a Set-to-SKU rule with no SKU entered" instead of a generic error, making it easier to fix the problem.

  • Improvement Warnings when min/max strategy models are missing

    You'll now see a warning message if a pricing strategy tries to use a min/max model that doesn't exist in your database.

  • Improvement Skip remaining batches when anchor lookup fails

    Since the anchor SKU lookup is group-level and deterministic (every batch in the group uses the same missing anchor), the system now short-circuits execution after detecting the first failure instead of attempting to process each remaining batch with identical failures. This reduces unnecessary processing and log noise.

  • Improvement Strategy execution behavior unchanged when summary is hidden

    Hiding the summary doesn't change how the strategy runs or what information is saved — it only hides the report window.

  • Improvement Better error logging when exception loading fails

    When SKU exception loading fails, the error log now includes the strategy name, SKU (if filtering to a specific SKU), and how many exceptions had successfully loaded before the failure. This helps distinguish between "no exceptions exist" and "the load failed partway through," since both previously resulted in an empty grid with no visible error.

  • Improvement Better error logging for SKU exception load failures

    Enhanced error logging to report which pricing strategy was being loaded, which SKU (if filtering to one), and how many exceptions had successfully loaded before the failure. This helps distinguish between "no exceptions exist" and "the load crashed partway through."

  • Improvement Dynamic "Set Future Price to" level list

    The "Set Future Price to" list now updates automatically when you change column views or selection boxes — extended price levels appear only when their fields are visible.

  • Improvement Strategy comparison setting persists immediately

    The auto-capture checkbox in the Compare Strategies dialog now saves its state immediately when toggled, rather than waiting for the dialog to close. Since the dialog has no OK/Cancel buttons, this prevents the setting from being lost when the user closes the window.

  • Improvement Three-way comparison support

    You can now compare up to three pricing strategies side by side instead of just two.

  • Improvement Enhanced sensitivity tooltips

    Hovering over a sensitivity score shows both the relative ranking and the detailed breakdown of price sensitivity metrics.

  • Improvement Pricing panel prevents saving incomplete set-to-SKU rules

    The Future Price panel now matches the behavior of margin and fixed retail rules by not emitting action tokens when the SKU field is left blank, preventing the creation of malformed pricing rules at the point of entry.

  • Improvement Missing min/max strategies no longer silently fail

    If a pricing step references a min/max strategy that isn't set up in your database, you'll now see a clear warning instead of having the setting silently removed.

  • Improvement Grid reloads in place after Apply

    After applying price changes to Ace Critical Pricing items, the list stays on screen with the new future prices shown, and the Summary panel updates to reflect your changes.

  • Improvement Documentation updated to reflect new behavior

    The Critical Retail Pricing documentation now describes "Just Run" as "Instant Correction" rather than "Instant Analysis," clarifying that it applies price changes immediately instead of just displaying a list for manual review.

  • Improvement Completion message now leads with SKUs applied

    The import completion message now clearly tells you how many SKUs from your file were successfully applied to your pricing data.

  • Improvement Import log now records Replace/Add choices and cleared values

    The log file now includes which columns were Replaced vs. Added, how many values were erased before the file was applied (per table and per column), and clarifies that SKUs "not in any main table" (rather than "not in Store") were skipped. The completion message and log both remind users that competitor prices are cleared by the next main-table rebuild (POS import, cloud sync, or manual rebuild) and must be re-imported afterwards.

  • Improvement Added safeguards to prevent empty store routing filters

    Introduced MainTableSelectionPolicy.RoutingListIsEmpty and RemoveEmptyRoutingKeys methods to consistently detect and remove empty store routing filters before they can cause discovery failures. GetFiltersDictionary now omits empty StoreGroup values rather than publishing them, matching the existing behavior for StoreNumber. The system logs a warning when empty routing keys are removed, helping identify misconfigured store grouping settings.

  • Improvement Enhanced validation and range checking for price level lookups

    Added safety checks when looking up price levels by index position. The system now validates that indexes are within valid ranges before using them, and falls back to the recorded price level enum when available. Competitor price levels (Comp1-5) are now resolved by identity rather than list position, preventing the same type of mismatch that caused the main defect.

  • Improvement Conservative detection to avoid warning fatigue

    The below-cost warning only appears when the system is certain the price will be below cost, so you won't see unnecessary alerts on normal pricing rules.

  • Improvement Sitting margin query available as standalone service

    Introduces ISittingMarginQueryService, which runs the shared sitting-margin bucket query against every resolved main table and returns the raw per-grain rows (Store/VendorOwned/Velocity/Dept/Class with additive CP/FP/COGS dollars). This is the sitting-margin calculation as a first-class product — no Profit Analyzer ViewModel spin-up required — so the Strategy Comparison dialog can capture results independently of the Profit Analyzer screen.

  • Improvement Clarified snapshot capture message

    The message when capturing a new snapshot now correctly states it captures all store pricing data, not just selected items.

  • Improvement Automatic strategy reruns with awaited snapshot capture

    When you compare strategies that need updating, the app runs them one by one automatically, shows progress for each, then displays the comparison when all are finished.

  • Improvement Sensitivity heat tinting only for reliable scores

    Sensitivity scores based on limited data now appear without color highlighting, so you know they're less reliable.

  • Improvement Unassigned entry detection and menu visibility

    The "Resolve Unassigned" menu appears automatically when SKU exceptions or custom groups are missing price levels, and shows the exact count of affected items.

  • Improvement Strategy pre-flight now suggests bulk resolution

    The strategy pre-flight warning now tells you about the "Resolve Unassigned" menu when it finds pricing rules that won't work.

  • Improvement Count message displays after splash screen closes

    The "Found X critical pricing items" message box now opens only after the loading splash screen is fully closed, following the application's splash-before-modal rule. Previously the message could appear while the splash was still visible.

  • Improvement Column reconciliation runs before strategy editor and execution
  • Improvement Strategy Comparison math is dollar-weighted and reconciles exactly

    The A/B comparison aggregates detail rows to the selected grain using the same SittingMarginMath roll-up, ensuring the grand total is dollar-weighted (not an average of per-grain percentages) and reconciles exactly with the per-store and per-department rows. Candidate-vs-baseline dollars is the incremental profit the new strategy makes over the old one (candidate annual $ − baseline annual $), and when a grain is absent from the baseline snapshot (e.g., a new department), the baseline dollars fall back to zero and the sitting anchor comes from the candidate's current price.

  • Improvement Documentation updated with Replace/Add guidance and POS caveats

    Help documentation now includes a "Replace or Add" section explaining when to use each mode, notes that Epicor and Paladin POS systems pre-fill Comp1–Comp5, clarifies that prices are cleared by main-table rebuilds (not just POS imports), corrects the technical detail that main tables are what matters (not [Store]), and adds staged multi-file import instructions (first file Replace, subsequent files Add).

  • Improvement Stable template key derivation for strategy identity

    Shared strategies are identified by a stable template key derived from the strategy name (lowercase, spaces/punctuation to hyphens, deduplicated hyphens, trimmed). This key is used for upsert operations during publishing and for matching installed strategies to catalog updates, allowing strategies to be renamed in the catalog without breaking the link to already-installed copies.

  • Improvement Full documentation with troubleshooting

    Adds comprehensive user documentation at docs/marginmaster/pricing/import-competitor-prices.md covering file format, recognized column names, value parsing rules, the import workflow, how to use competitor prices in strategies and variance columns, log location and contents, and common questions including the POS import durability caveat and SKU matching behavior. Indexed with 18 search keywords including "shop report", "market price", and "load competitor prices".

  • Improvement Strategy comparison auto-capture with freshness stamping

    The fire-and-forget snapshot capture after each strategy run now stamps the snapshot with the current freshness marker via the new optional dataVersion parameter. The capture method is also exposed as an awaited Task<int> for the compare orchestrator to call synchronously between back-to-back runs, preventing the race where fire-and-forget capture overlapped with the next run's FuturePrice reset.

  • Improvement One Data Update job, scheduled by day and time
  • Improvement Update DevExpress components to 26.1.4
  • Bug Fix Custom group margin percentages preserved on save

    If you previously set up a custom group with a margin percentage and found it wasn't pricing anything, you'll need to open it, re-enter the margin %, and save it again. The app will now keep your settings.

  • Bug Fix SKU exceptions with blank store scope now display correctly

    If you saw a padlock icon showing an exception exists but couldn't see it in the SKU Detail tab, those exceptions will now appear correctly.

  • Bug Fix SKU exceptions with blank store scope no longer crash the exceptions tab

    If a SKU had a pricing exception but the Sku Level Exceptions tab showed nothing, it will now display correctly.

  • Bug Fix Fixed negative margin rules incorrectly flagged as unrunnable

    Pricing rules with negative margins (like -25% to price below cost) now save and run correctly instead of showing a "will be skipped" error.

  • Bug Fix Negative margins now run correctly for SKU exceptions

    If you set a negative margin percentage to price below cost, the exception will now apply correctly when your pricing strategy runs.

  • Bug Fix Old version detection prompt crash resolved

    The application will no longer crash when checking for old Margin Master versions during startup.

  • Bug Fix Custom group warnings now include step number to prevent misidentification

    When you save custom groups, any warnings about missing price levels or below-cost pricing now show both the step number and group name (like "step 6 - PLUMBING L2"), making it easier to find the right row when you have groups with the same name in different strategies.

  • Bug Fix Group identification in pricing validation warnings

    When you save pricing groups and see a warning, it will now show "step 2 - PLUMBING L2" instead of just "PLUMBING L2", making it easy to find the exact row that needs fixing.

  • Bug Fix Export now validates file access before clearing MMImport table

    If a price export to RockSolid fails, your existing queued prices in the POS will no longer be lost.

  • Bug Fix Restored missing reference in Profit Analyzer

    Added back the System.Text reference required by ProfitAnalyzerViewModel, which was causing a compilation failure after the strategy comparison code was recovered.

  • Bug Fix Strategy steps no longer silently fail when targeting hidden price levels

    If you saved a strategy step to update zone pricing or a custom field, then later hid that field from your view, the step will now still work correctly instead of silently skipping all items.

  • Bug Fix Restore hidden price levels when loading saved pricing rules

    When you load a pricing rule that uses a price level not currently shown in your view (like a zone price when zone columns are hidden), the rule will now work correctly instead of silently failing. Your pricing strategies will apply as configured even when you switch between different column views.

  • Bug Fix Restored price levels now inserted in correct dropdown position

    When opening a saved pricing rule, zone pricing levels and other special levels now appear in the right spot in the dropdown menu instead of at the bottom of the list.

  • Bug Fix Restored pricing levels now insert at enum-ordered position

    When you open a saved future price rule, any pricing levels that were previously selected but aren't normally shown will now appear in their correct position in the dropdown list instead of at the very bottom.

  • Bug Fix Strategy picker checkboxes now update immediately

    When you check or uncheck a pricing strategy in the comparison picker, the selection now registers right away. Previously, you had to click somewhere else before the selection would take effect and enable the Compare button.

  • Bug Fix Strategy picker checkboxes now respond immediately

    When selecting strategies to compare, the checkboxes now respond instantly when clicked. The Compare button and the limit of 3 selections will update right away instead of after clicking elsewhere.

  • Bug Fix Strategy Comparison column headers now render correctly

    Fixed a rendering issue where the Strategy Comparison screen's column headers displayed internal system text ("System.Windows.Controls.StackPanel") instead of the intended two-row format with strategy name and metric label. The fix restructures how headers are defined using HeaderTemplate instead of direct Header content, allowing the TreeListControl to properly display strategy names bound from the view model. All nine comparison columns (Baseline and Candidate strategy metrics for projected percentage, delta points, and annual dollars) now show the correct formatted headers.

  • Bug Fix Strategy Comparison header rendering corrected
  • Bug Fix Strategy Comparison tree performance improvement

    The comparison tree no longer feels sluggish when scrolling through pricing strategies with many low-coverage items.

  • Bug Fix Strategy Comparison screen performance improvement

    The Strategy Comparison screen will feel more responsive and smoother, especially when scrolling through large lists of items.

  • Bug Fix Pricing strategy execution now handles initialization failures gracefully

    If a pricing strategy fails to run and shows a message about the Future Price panel not being initialized, restart Margin Master. If the problem continues, contact support—there may be an issue loading your store's rounding schemes or cost break data.

  • Bug Fix Guard against null Future Price panel during strategy execution

    If you see an error about the Future Price panel not being initialized when running a pricing strategy, restart Margin Master. If the error continues, contact support as there may be an issue loading your store's pricing configuration data.

  • Bug Fix Pre-flight check now matches execution logic for custom groups

    You'll no longer see warnings about custom group rules that wouldn't actually run anyway.

  • Bug Fix Pre-flight dialog now excludes inactive custom groups with ACTIVE~FALSE token

    The warning dialog before running a strategy will no longer show custom groups that won't actually run.

  • Bug Fix Empty SKU field no longer terminates pricing strategy execution

    If you accidentally left the SKU field blank in a "Set to SKU" pricing rule, that step will now be skipped instead of stopping your entire pricing strategy. You'll see a warning in the pre-flight check so you can fill in the missing SKU before running the strategy.

  • Bug Fix Blank Set-to-SKU rules no longer terminate pricing strategies

    If you previously created a pricing rule with "Set to SKU" selected but forgot to enter a SKU number, the entire pricing strategy would stop working. Now that rule will simply be skipped, and your strategy will continue processing remaining rules normally.

  • Bug Fix Restored one-click Active checkbox toggling

    The Active checkbox now responds immediately when clicked, allowing you to quickly enable or disable SKU exceptions and custom groups without extra steps.

  • Bug Fix Restore checkbox editing in SKU Exceptions grid

    In SKU Exceptions, you can now click once on the Active checkbox to enable or disable an exception instead of having to navigate to the cell first.

  • Bug Fix Min/max strategies now apply to all store group tables

    When you run a pricing strategy with min/max limits across multiple store groups, those limits now correctly apply to all groups instead of only the first one.

  • Bug Fix Min/max strategies now apply to all main tables in multi-table groups

    When running pricing strategies on store groups with multiple tables, min/max rules (like MAP enforcement) now correctly apply to all tables instead of only the first one.

  • Bug Fix Display warning when Set-to-Sku anchor is missing

    If you run a custom pricing group that's set to match another item's price, but that item has been deleted from your POS system, Margin Master will now show a clear "SKIPPED" warning explaining what happened instead of appearing to succeed with no changes.

  • Bug Fix MAP and IMAP always available in Future Price panel at Ace stores

    When reviewing Ace Critical Pricing items, you can now always choose "MAP Price" or "IMAP Price" from the Future Price panel's dropdown to quickly correct pricing violations.

  • Bug Fix Execute Strategy confirmation now distinguishes deliberate clicks from automatic reruns

    When you deliberately run Execute Strategy again within 2 minutes of finishing the previous run, the system will no longer ask you to confirm — it knows you meant to do it. The confirmation only appears for unexpected automatic runs.

  • Bug Fix Individual SKU exception saves now work reliably

    When editing a single SKU exception, your changes will now save properly. If a save fails, you'll see which SKUs had problems and can try again — changes won't be silently lost.

  • Bug Fix SKU exception Type column now updates immediately after price assignment

    When you set a price level for a SKU exception that previously showed "U" (unpriced), the Type column will now immediately show the correct letter (R/M/D/C/S) representing the assigned price level, without needing to close and reopen the dialog.

  • Bug Fix Import now reports accurate SKU match counts on all POS systems

    If you use Epicor or Compass POS, competitor price imports will now show the correct "SKUs applied" count instead of falsely reporting that your items weren't found.

  • Bug Fix Pricing strategies now process inventory when Store Grouping enabled without groups

    If you accidentally turned on Store Grouping without setting up any groups, automatic pricing will now work correctly instead of silently skipping all items.

  • Bug Fix Strategy rules now save the correct price level

    Fixed MM-1397 where a rule set to "55% Margin" could be saved as "Store Cost" and reprice items incorrectly. Store 5088 had a rule that should have set 55% margin but instead repriced 395 items to cost on every strategy run. The root cause was that the system saved which position a price level was in a list, not which level was actually selected. When zone price levels were restored into one list but not another, the positions fell out of sync and the wrong level was serialized. The system now records the actual price level selected, making the save process immune to list position changes.

  • Bug Fix Fixed critical strategy serialization error when required columns were hidden
  • Bug Fix Margin cost basis now retained when loading custom groups

    Custom groups set to calculate margin from Average Cost or Replacement Cost will now stay on that cost basis when you reopen and save them.

  • Bug Fix Active status filter now correctly filters exceptions

    The Active filter now correctly shows only active exceptions instead of showing everything.

  • Bug Fix Active/Inactive filter now works correctly in SKU exceptions

    Filtering SKU exceptions by Active or Inactive status now shows the correct records without changing their active state.

  • Bug Fix Unreachable modal dialog behind splash screen

    The old version uninstall prompt can now be clicked and responded to instead of being stuck behind the startup screen.

  • Bug Fix Strategy comparison snapshot selections now persist after refresh

    When you refresh the list of saved pricing snapshots, your currently selected baseline and candidate snapshots will stay selected instead of resetting.

  • Bug Fix Pre-flight check now matches execution logic for SKU exceptions

    Pre-flight warnings for SKU exceptions now accurately reflect which rules will actually run.

  • Bug Fix Pre-flight dialog now only shows SKU exceptions that will execute

    The warning dialog before running a strategy will no longer show SKU exceptions that won't actually run.

  • Bug Fix Restore checkbox editing in Custom Groups grid

    In Custom Groups, you can now click once on the Active checkbox to activate or deactivate a group item instead of having to navigate to the cell first.

  • Bug Fix Null price level columns no longer break min/max calculations

    Min/max strategies now work correctly even when comparison or zone price columns are empty for some items.

  • Bug Fix Apply button now targets only the critical pricing list

    Clicking "Apply" in the Future Price panel now updates only the critical pricing items shown in the grid, not every item in your store. The list stays on screen after Apply so you can see the corrected prices immediately.

  • Bug Fix Apply now targets the critical pricing list, not the whole store

    When viewing Ace Critical Pricing results, clicking Apply in the Future Price panel now changes only the items shown in the list, not every item in your database.

  • Bug Fix Critical pricing steps skip safely when selection rules cannot load

    If any pricing rule can't be applied safely (for example, if MAP data is missing), that correction is skipped and reported in the results message, preventing accidental store-wide price changes.

  • Bug Fix Custom group store condition deletions now persist

    When you remove stores from a custom group's conditions, those changes now save correctly instead of being lost.

  • Bug Fix Resolved Unassigned filter now updates correctly after fixing SKUs

    In the Resolve Unassigned workflow, SKUs you've just fixed will now disappear from the list immediately after you save, making it easier to track your progress through unassigned items.

  • Bug Fix Import no longer reports false "SKUs not found" failures

    The import now correctly tells you how many prices were applied. Previously it could report "SKUs not found" even when the prices had successfully loaded into your pricing grid.

  • Bug Fix Main table discovery now handles missing store routing information correctly

    The pricing grid and reports now find your inventory correctly when store filters aren't set, rather than showing empty results.

  • Bug Fix Product codes with apostrophes no longer cause export failures

    Products with apostrophes or quotes in their codes (like 1/2" X 6') now export correctly to RockSolid.

  • Bug Fix Corrected service dependency lifetime registration

    Changed SittingMarginQueryService and StrategyComparisonService from singleton to transient registration to match the lifetime of ISelectionService, preventing potential dependency injection errors.

  • Bug Fix OneClick Pricing Sensitivity Mix corrected for vendor and labels

    OneClick statistics now show the correct price sensitivity labels and categories for your vendor (Ace Hardware or Do it Best), with all sensitivity codes properly displayed.

  • Bug Fix Custom group edits no longer lost when switching groups

    When editing custom groups, switching between groups no longer asks if you want to save, and your changes are kept until you click Save or close the window.

  • Bug Fix Switching custom groups no longer discards unsaved changes

    You can now edit multiple custom groups without saving after each one—your changes stay in place until you click Save or close the window.

  • Bug Fix Preserve min/max configuration when model is temporarily missing

    Loading and re-saving a strategy in a database that's missing the referenced min/max model no longer permanently deletes the step's min/max configuration. The InstructionSet and StrategyFormulaService now keep the ACTIONMINMAX reference even when the model lookup fails, preventing accidental data loss.

  • Bug Fix Summary panel now populates for critical pricing lists

    The Summary panel at the bottom now shows how many critical pricing items have been corrected (have a future price set).

  • Bug Fix Price level selection properly detects unsaved changes

    If you select a pricing method but leave the value blank, the Save button will now activate so you can be prompted to complete or discard your change.

  • Bug Fix Strategy serialization now uses recorded level instead of list position
  • Bug Fix Null-safe handling of missing rule text in legacy exceptions

    Added null safety when processing the RuleText field during legacy exception migration. Exceptions with missing rule text no longer crash the migration process.

  • Bug Fix Prices now export correctly on non-US regional settings

    Computers configured with European number formats (comma as decimal separator) now export prices correctly to RockSolid.

  • Bug Fix Removed vendor- and POS-specific always-show overrides

    All stores now see the same consistent behavior: price levels appear in the dropdown only when the matching field is visible in your current layout.

  • Bug Fix Handle null pricing levels in min/max calculations

    The min/max case expression now NULL-guards the level column (Comp5, zones, etc.) so that NULL values are read as 0 (no clamp) instead of propagating NULL into FuturePrice. Previously, a NULL Comp or zone level would cause the entire CASE statement to evaluate as UNKNOWN and write NULL into the FuturePrice column.

  • Bug Fix Active flag now persists correctly on save

    The Active column in the database is now updated alongside rule text during saves. Previously only the rule text was written, causing the Active flag to diverge and break pre-flight filtering queries.

  • Bug Fix Disabled ACE connection pooling to prevent inherited read-only sessions

    Import and export built byte-identical connection strings, so ADO.NET handed the export the import's pooled ACE session. Because an ACE session's open mode is fixed when first opened, a read-only import session made the export fail with no filesystem evidence. The connection string now includes `OLE DB Services=-4` to disable pooling, ensuring each operation gets its own session with the correct access mode.

  • Bug Fix SKU-level exceptions rounding scheme now preserved

    SKU exceptions with specific rounding schemes will now keep those schemes when you reopen them.

  • Bug Fix Strategy run timestamp only updated after actual execution

    If you cancel a strategy run before it starts, the app will no longer think you just ran it and ask if you want to run it again immediately.

  • Bug Fix FuturePricePanel level-list refresh on view change

    The FuturePricePanel now exposes RefreshPriceLevelList(), called by MainMMViewModel when the active column view or selection box view name changes (OnActiveColumnViewName_Changed / OnActiveSelectionBoxViewName_Changed event handlers). The refresh captures the selected enum, rebuilds the ItemsSource from the service, re-applies the specific-value captions (Cost Break, Margin, Fixed Retail, SKU), and restores the selection to avoid a transient TwoWay binding swap. MainMMViewModel's own PriceLevelList (indexed against the panel's selection in CanTakeSnapshot) rebuilds in lockstep. The Edit Columns and Edit Selection Boxes dialog closes also trigger the refresh (MainMMViewModel.Dialogs3.cs) so membership changes take effect immediately.

  • Bug Fix Price level preserved when not in current column view

    If you configured a custom group or SKU exception using a price level that isn't currently visible on this computer, it will now keep that price level setting instead of losing it when you save.

  • Bug Fix A strategy turns on the columns its rules price from
  • Bug Fix A licence confirms a store's identity, it never redefines it
  • Bug Fix An empty store-routing list means no filter, not zero stores
  • Bug Fix Give the grid and strategy path the same fallback
  • Bug Fix A fallback must fall back to something real
  • Bug Fix Never drop a database table we do not recognize
  • Bug Fix Competitor price import reported a false failure, and add Replace/Add per column
  • Bug Fix Fix the seed index that could never be created, and the duplicate rebuild pass
  • Bug Fix Reconciler DELETE was ambiguous on every run
  • Bug Fix Heal a store whose vendor renumbered it
  • Bug Fix Refresh the SKU exception Type column after a future price is set
  • Bug Fix Fix self-perpetuating startup index rebuild (shrink was running last)
  • Bug Fix Fix silent save failures on individual SKU exceptions and custom groups
  • Bug Fix Fix MM-1387 + MM-1392: custom-group rounding display, Mi9 User4 recency window
  • Bug Fix Stop DMV index bloat on main tables, auto-disable failing indexes
  • Bug Fix Fix app lockup after Ace Critical Pricing "Save as Strategies"
  • Cloud Sync Shared strategy API endpoints

    Added three new API endpoints under api/v2/SharedStrategy: GET (catalog list filtered by vendor type), GET /{templateKey} (full definition including steps and bundled rounding schemes), and POST (publish with machine-hash authorization). Catalog items include metadata only; full definitions are fetched separately to minimize bandwidth. The server stores definitions as opaque JSON, allowing step RuleText content to evolve without server changes.

  • Data Import Smart value parsing and validation

    If a cell is blank or contains text like "N/A", that price is skipped and the existing value is kept — nothing is ever accidentally zeroed. Every import writes a log showing what was recognized, what was ignored, and any rows that couldn't be imported.

  • Data Import Export service now supports tree views

    `ExportService` now binds to `DataViewBase` instead of `TableView`, enabling Excel export from both grid and tree list controls. This allows users to export the new hierarchical comparison results while preserving the existing flat-grid export functionality elsewhere in the application.

  • Data Import Durable storage in POS data

    Competitor prices are stored with your POS data and will be replaced the next time you import POS data — keep your spreadsheet and re-import after each POS import.

  • Data Import Template download for correct file format

    Click "Download Template" to get a pre-formatted Excel file you can fill in with your competitor prices—the headers and format are already correct.

  • User Interface Removed duplicate title from Strategy Execution Summary

    The Strategy Execution Summary now has a cleaner look with just one title instead of two.

  • User Interface Dynamic "Set Future Price to" filtering based on active views

    Extended price levels like Level3, Comp prices, or zone pricing now appear in the "Set Future Price to" dropdown only when you've added those fields to your column layout or selection boxes. Basic options like Current Price, Future Price, and Store Cost are always available.

  • User Interface Dynamic "Set Future Price to" dropdown filtering
  • User Interface Relocated strategy commands to Strategy Manager toolbar

    The buttons to browse premade strategies and compare strategy results are now at the top of the Strategy Manager screen instead of in the Strategy menu.

  • User Interface Consolidated strategy tools into Strategy Manager

    To access premade strategies or compare results, open Strategy Manager (Ctrl+S)—the buttons are now in the toolbar at the top of that window.

  • User Interface Maximum selection limit enforced in strategy comparison

    When selecting pricing strategies to compare, you can now pick up to three. After checking three strategies, any unchecked boxes will grey out. Simply uncheck one of your selections to enable the others again.

  • User Interface Selection limit enforced in Strategy Comparison picker

    When you select three pricing strategies to compare, the checkboxes for other strategies will grey out so you know you've reached the limit.

  • User Interface Renamed baseline columns to "Current" throughout comparison grid

    The comparison grid now uses "Current" instead of "Sitting" to describe your store's existing prices, and shows how much money each strategy would gain or lose "vs Current" prices.

  • User Interface Renamed baseline columns to clarify comparison context

    When comparing pricing strategies, columns now clearly show they're comparing against your current prices, making it easier to understand potential margin impact.

  • User Interface Replaced flat comparison grid with hierarchical tree view

    Comparison results now appear as a tree you can expand and collapse. Start with stores, then click to see departments within each store, then classes within each department.

  • User Interface Hierarchical tree view replaces flat comparison grid

    Results now show as a tree you can expand: stores at the top level, departments inside stores, and classes inside departments. Collapsed stores show the store total; expand to see the breakdown.

  • User Interface Clearer confirmation message before strategy comparison reruns

    Before rerunning strategies for comparison, the confirmation message now tells you if your active strategy will need to be restored afterward, so you won't be surprised by an extra step.

  • User Interface Clearer explanation of active strategy restore during comparison

    Before running a comparison, you'll now see a clear explanation if your active strategy needs to be rerun afterward to put your prices back the way they were.

  • User Interface Two-row comparison headers with color-coded strategy columns

    Strategy comparison results now show clearer column headers with strategy names in bold and color-coded columns (blue, green, amber) to make it easier to compare multiple pricing strategies.

  • User Interface Color-coded comparison columns with two-row headers

    Each strategy in the comparison now has its own color (blue, green, or amber) with the strategy name shown above each column group, making it much easier to compare results at a glance.

  • User Interface Grouped strategy column headers

    Each pricing strategy's columns are now grouped together with a clear header showing the strategy name, making it easier to compare results across different strategies at a glance.

  • User Interface Enhanced column organization with header bands

    Each pricing strategy now has a clear header label spanning its columns, making it easier to compare "Proj %", "Δ pts", and "vs Current $/yr" values across different strategies without confusion.

  • User Interface Honest sensitivity score display

    Sensitivity scores now show the real number (like 56) instead of exaggerating tiny differences. The color still shows how it compares to similar stores, but only when we have enough data to be confident.

  • User Interface Strategy menu reorganization

    When you click the Strategy menu, you'll now find Strategy Utilities at the very top instead of at the bottom, making it faster to access common utility functions.

  • User Interface Automatic refresh after view changes
  • User Interface Removed strategy-versus-strategy comparison columns

    Removed confusing columns that compared one pricing strategy to another — now every strategy just shows its impact compared to what you're charging today.

  • User Interface Simplified Strategy Comparison grid layout

    Removed redundant dollar amount columns that showed both absolute values and comparisons to baseline. The comparison now displays only the "vs Current $/yr" columns for each strategy, reducing visual clutter and focusing users on the meaningful comparison metric.

  • User Interface Improved progress message during strategy restore

    The progress message when restoring your active strategy after a comparison now makes it clear this is a restore step, not another comparison run.

  • User Interface Enhanced progress message during strategy restore

    When the app restores your active strategy's prices after a comparison, the progress message now clearly explains what's happening.

  • User Interface Sensitivity and Blind % columns added to strategy comparison tree

    Strategy comparison reports now show price sensitivity scores and blind percentages for each store, department, and class, helping identify where small price increases are safest.

  • User Interface Strategy Comparison screen header improvements

    Column headers in the Strategy Comparison grid now properly bind to strategy names (BaselineName, CandidateName, CandidateCName) and render them with consistent formatting: bold strategy name on the first line with text trimming for long names, and a semi-transparent metric label on the second line.

  • User Interface Improved header text display
  • User Interface Streamlined header templates

    Removed redundant strategy name labels from individual column headers since the band headers now provide this context. Column headers now display only their metric type (e.g., "Proj %", "Δ pts"), making the grid more compact and easier to scan.

  • User Interface SKU counts added to row names

    Each store, department, and class row now shows how many SKUs it contains in parentheses.

  • User Interface SKU counts displayed in row names

    Each department and class now shows how many products it contains directly in its name.

  • User Interface Clearer sitting margin column labels

    The comparison screen now clearly labels margins as "Sitting %" so you know exactly what type of margin you're looking at.

  • User Interface Clearer "sitting margin" column labels

    Column headers now say "Sitting %" to make it clearer these are sitting margin percentages, not other types of margins.

  • User Interface Pre-flight validation now identifies missing SKU in set-to-SKU rules

    Before running a pricing strategy, you'll now see a clear warning if any step has "Set to SKU" selected but the SKU field is empty, so you can fix it right away.

  • User Interface Progress splash screen during "Just Run"

    While applying corrections, a splash screen displays progress through each category (e.g., "Setting future prices: CP<MAP [1 of 3]"). After completion, the results message shows a detailed breakdown of items priced per category, or notes if any step was skipped due to missing data.

  • User Interface Import Competitor Prices dialog

    The Import Competitor Prices window shows you exactly what it found in your file before importing, and warns you to re-import after each POS data import since competitor prices are stored with POS data.

  • User Interface Dropdown refreshes automatically after view edits

    When you add or remove columns or selection box fields and save your changes, the "Set Future Price to" dropdown updates instantly to reflect the new available options.

  • User Interface Auto-capture toggle added to Compare Strategies dialog

    You can turn automatic snapshots on or off using a checkbox in the Compare Strategies screen.

  • User Interface Updated grand total label in Strategy Comparison

    The grand total section now displays "Current:" instead of "Sitting:" to maintain consistent terminology throughout the screen.

  • User Interface Improved restoration dialog messaging

    Dialog messages now better explain what happens to your pricing data after a comparison and what each option does.

  • User Interface Updated comparison run confirmation message

    The confirmation dialog before running stale strategies now accurately describes the new restore behavior, explaining that the user will choose whether to reapply their active strategy rather than stating it will automatically rerun.

  • User Interface Enhanced sensitivity tooltips

    Hovering over a sensitivity score now shows both the easy-to-read relative score and the detailed absolute score with full breakdown.

  • User Interface Enhanced Manage Custom Groups hamburger menu

    Two new options are available in the Manage Custom Groups hamburger menu: copying groups from other strategies and finding duplicate SKUs.

  • User Interface "Unassigned" status filter added to SKU Level Exceptions

    You can now filter the SKU exceptions list to show only "Unassigned" rows—active exceptions that have no price level and never price anything.

  • User Interface Enhanced run summary message for missing anchor SKU

    The run summary will now tell you exactly which item is missing and remind you to edit your pricing group to choose a different price level.

  • User Interface Completion message shows per-category pricing results

    The results message now shows exactly how many items were corrected in each category, making it easy to see what changed.

  • User Interface Read-only state enforcement in Strategy Manager

    The ManagePricingStrategyV2View displays a read-only banner ("Shared strategy vN — read-only. Use 'Copy Current Strategy' to make an editable copy.") above the step list when the loaded strategy has a shared-strategy provenance marker. The step detail panel and bottom grid controls are disabled (IsEnabled bound to IsCurrentStrategyShared via BooleanNegationConverter). All mutating commands (add/edit/delete step, rename strategy, save changes) check BlockIfShared and show an informational message directing the user to copy the strategy first. The publish menu item is visible only when IsSupportMachine is true (gated on the ApplicationSettingsService flag set by CheckIsSupportMachine during startup). Strategy export, execution, activation, and backup remain fully enabled for shared strategies.

  • User Interface Removed grain selector dropdown from results toolbar

    The "View by" dropdown is gone—just expand or collapse tree rows to see the level of detail you want.

  • User Interface Added help text when no min/max strategies exist

    The pricing panel now shows helpful guidance when you need to create a min/max strategy.

  • User Interface Just Run now shows Summary panel

    The Just Run flow now calls BuildSummaryAsync with the critical pricing predicate after loading the grid, so the Summary panel displays the count of items with Future Price <> 0 within the critical pricing set. This provides immediate feedback on how many violations have been addressed.

  • User Interface Updated documentation reflects new "Just Run" behavior

    The Critical Retail Pricing documentation now describes "Just Run" as "Instant Correction" rather than "Instant Analysis," clarifying that the button applies pricing changes immediately and explaining that both "Just Run" and "Save as Strategies" produce identical corrections—the difference is timing (immediate one-time fix vs. automated workflow integration).

  • User Interface Automatic column display offer

    After importing, Margin Master asks if you want to add the imported competitor columns to your current view so you can see the prices right away — click Yes and they appear in the grid and selection boxes.

  • User Interface Import window shows Replace/Add controls and existing value counts

    The import window now tells you how many items already have prices in each competitor field, so you can decide whether to add your prices or replace what's there.

  • User Interface Import dialog shows existing value counts before import

    When a file is loaded, the dialog queries the main tables to count how many items already carry values for each Comp level, displaying for example "101,391 of 106,565 items currently have a Competitor 1 price." This count appears next to the Replace/Add choice and is what makes the choice informed rather than blind. A note explains when existing values come from the POS (common on Epicor and Paladin). The query is non-blocking and the import can proceed even if the count fails.

  • User Interface Visual indicators for groups that cannot price

    Incomplete custom groups will now show a red error icon in the list, so you can see which ones need attention without opening each one.

  • User Interface Manage Pricing Strategy dialog enhancements

    The Manage Pricing Strategy dialog now displays a banner above the step list when the loaded strategy is a shared install ("Shared strategy v{N} — read-only. Use 'Copy Current Strategy' to make an editable copy."). All mutating operations (Add Step, Delete Step, Reorder, Edit Step, Delete Strategy) are blocked with a friendly message directing users to copy the strategy first or manage it from the catalog. Support machines see a new "Publish Shared Strategy" menu item; the dialog surfaces build-time warnings (view-dependent operands, missing groups/exceptions) and prompts for confirmation before uploading.

  • User Interface Improved Future Price panel min/max selection

    The pricing panel now shows a helpful message when no min/max strategies exist, with instructions on how to create one.

  • User Interface Unassigned status filter in Sku Level Exceptions

    You can now filter the SKU exception list to show only entries with no price level set, making it easier to review what will be affected by bulk actions.

  • User Interface Replace mode requires confirmation before clearing values

    When at least one column is set to "Replace all existing values," the Import button shows a confirmation dialog stating how many existing prices will be erased and from which fields. This prevents accidental data loss. The dialog clarifies that values from the POS will return on the next POS import, but user-entered prices are not recoverable.

  • User Interface User notification when strategy columns are auto-enabled

    When the system automatically adds columns for a strategy, users now see a message identifying which strategy needed the columns and which ones were added. This prevents confusion from layouts silently rearranging and provides transparency about why the view changed.

  • User Interface User notification when strategy columns are added
  • User Interface Excel export for comparison results

    The Strategy Comparison dialog includes an "Export to Excel" button that exports the comparison grid (all rows plus the grand total) to a spreadsheet, allowing users to share the A/B analysis with stakeholders or archive it for review.

  • User Interface Strategy comparison picker and results states

    The Compare Strategies window now starts with a list of all your strategies showing their status, making it easier to pick which ones to compare.

  • User Interface Improved snapshot labeling

    Comparison snapshots now prefer the strategy name (when available) over the custom label when displaying in the comparison picker and results grid, making it clearer which strategy each result represents.

  • User Interface Strategy Manager read-only banner and menu integration

    The Strategy Manager displays a banner above the step list for shared strategies ("Shared strategy vN — read-only. Use 'Copy Current Strategy' to make an editable copy") and disables the step detail panel, bottom bar controls, and all mutating menu items. Support machines see a new "Update or Create Shared Strategy" menu item; all users see the "Get Premade Strategies" menu item in the main Strategy menu.

  • User Interface Demo mode restriction

    The Import Competitor Prices command is disabled in demo mode to prevent modification of sample data, consistent with other import and data-modification features.

  • User Interface Snapshot management controls

    After capturing a new snapshot, it automatically becomes the "Candidate (B)" compared against your previous snapshot as "Baseline (A)", making it easy to test a new strategy against what you were doing before.

  • Database StrategyResultSnapshot and StrategyResultSnapshotDetail tables

    Introduces two new local-only tables (StrategyResultSnapshot header and StrategyResultSnapshotDetail rows) that store labeled snapshots of the sitting-margin query. Each snapshot captures the current-price sales, future-price sales, and COGS at the Store/Dept/Class/Velocity/VendorOwned grain, preserving the exact dollar totals so they roll up to any grain (department → store → org) without rounding error. Snapshots survive the rebuild between two strategy runs and are never sent to the cloud. The tables are created automatically on first use via idempotent CREATE IF NOT EXISTS scripts.

  • Database Shared strategy provenance tracking

    Installed shared strategies write a provenance marker to GlobalFileConfig (Section=SHAREDSTRATEGY, Name=strategy name, Key=Origin) containing the template key, version, SharedStrategyId, and install timestamp as JSON. The presence of this marker is what makes a strategy read-only; the installer queries it to determine install state (not installed / current / update available) and the Strategy Manager queries it to enable/disable edit controls. Install and update operations trigger automatic strategy backups with reason "shared-strategy-install" or "shared-strategy-update".

  • Database Strategy snapshot freshness stamp storage

    Adds a DataVersion column to the StrategyResultSnapshot table to store the freshness stamp at capture time. Includes an idempotent ALTER migration for existing customer databases that were created before this feature. Pre-feature snapshots have null DataVersion and are treated as never current.

  • Database StrategyResultSnapshot.DataVersion column

    Adds a nullable DataVersion column to the StrategyResultSnapshot table to store the freshness stamp at capture time. An additive migration ensures existing customer databases pick up the new column. Snapshots captured before this feature (DataVersion = null) are always treated as Not Current.

  • Database Shared strategy models and API endpoints

    Adds SharedStrategyModels.cs (SharedStrategyCatalogItem, SharedStrategyDefinition, SharedStrategyStep, SharedStrategyOrigin, PublishSharedStrategyRequest/Response) and three new API client methods: GetSharedStrategyCatalogAsync (filters by vendor type, returns metadata only), GetSharedStrategyDefinitionAsync (fetches the full body by template key), and PublishSharedStrategyAsync (upserts with machine-hash validation). The server stores definitions as opaque JSON blobs — only Margin Master parses RuleText, so step content can evolve without server changes. Rounding schemes travel only when not auto-seeded (KnownSchemeType schemes are skipped); the installer creates missing schemes but never overwrites same-name local schemes. Custom groups, SKU exceptions, and min-max strategies deliberately do not travel — they are store-specific.

  • Database Dual-table update strategy

    Imported prices appear in your grid immediately and are saved with your POS data, but remember to re-import after each POS data import since that replaces the [Store] table.

  • Architecture Pure policy class with comprehensive test coverage

    The filtering logic is isolated in a new FuturePriceSetToLevelPolicy class with 107 lines of unit tests covering pseudo-levels, core levels, extended fields, view membership rules, Bloom Retail suppressions, and the removal of vendor/POS escape hatches. The policy receives a unified set of fields from both the column view and selection box view and makes purely functional decisions about each level's availability.

  • Architecture Tree building logic added to comparison math service

    New `BuildTree` method in `StrategyComparisonMath` constructs the three-level hierarchy by grouping baseline, candidate, and optional third-candidate rows by store, department, and class keys. Each node applies the same sitting-margin and profit-delta calculations as the flat rows, ensuring exact reconciliation. Unit tests verify that store totals sum to the grand total and department/class children sum to their parent nodes.

  • Architecture Added run attribution tracking to identify deliberate vs. automatic strategy executions

    Implemented a new ExecuteStrategyFromMenu command that wraps the core ExecuteStrategy method and explicitly marks runs as "Menu"-triggered. The system now defaults to marking runs as "Unattributed" instead of assuming they came from the menu, making it easier to identify and diagnose unexpected duplicate executions. This tracking also feeds into telemetry for better diagnosis of the rare duplicate-execution issue.

  • Architecture Thread-safe modal dialog helper added

    Added ShowModalSafeAsync method that ensures message boxes can be safely shown from any thread by first closing the splash screen verifiably (via EnsureSplashClosedAsync) and then marshaling the dialog call to the UI thread. This replaces unsafe HideSplashScreen calls that could not be verified and left modals unreachable.

  • Architecture Policy-based level offering logic
  • Architecture Sitting margin calculation extracted to SittingMarginMath and SittingMarginQueryBuilder

    Extracts the sitting-margin roll-up (gross profit / sales at current price and future price) from SittingMarginTelemetryService into a standalone static class, SittingMarginMath, and the Profit Analyzer's bucket SQL (the SELECT…GROUP BY that sums last-12-months sales/COGS into price bands) into SittingMarginQueryBuilder. This makes the sitting-margin calculation a single source of truth shared by the on-screen Profit Analyzer, the deferred telemetry post, and the new Strategy Comparison product, eliminating duplicated logic and ensuring all three measure identically. The shared valid-item filter excludes obvious pricing errors symmetrically for both current and future prices.

  • Architecture Tree node math reconciles at every level

    Every tree node—store, department, and class—computes its measures (projected margin, delta points, annual dollars) using the same dollar-weighted sitting margin math over its own subset of items. Each parent's totals exactly equal the sum of its children's totals, ensuring perfect reconciliation from class level up to store level. A new test verifies this reconciliation property.

  • Architecture Below-cost detection logic added

    Added BelowCostPriceDetector helper class that analyzes pricing rule text to identify below-cost scenarios: negative margins, cost-based pricing with subtractions (e.g., Store Cost minus 10%), and flat retail prices below item cost. The detector reads the stored rule text directly rather than UI state, following the same discipline as MissingPriceLevelDetector to ensure what's checked cannot drift from what's stored. Only certain shapes are reported to avoid false positives that would train users to click through warnings. Includes 106 unit tests covering all detection scenarios.

  • Architecture Shared strategy provenance tracking and machine-hash validation

    Each installed shared strategy writes a provenance marker (SharedStrategyOrigin: template key, version, server ID, install timestamp) into GlobalFileConfig (Section=SHAREDSTRATEGY, Key=Origin); the presence of this JSON is what makes a local strategy "shared" (static/read-only). Strategies without the marker — every pre-existing strategy — behave exactly as before. The publisher and the CheckMachine support-machine probe share the same machine-hash algorithm (SHA256 of "RS-SupportMachine-2024-Verify!" + uppercased machine name, lowercase hex); the server validates every publish request against the SupportMachine registry and returns 403 for non-support machines. Template keys are derived from strategy names (lowercase, trimmed, hyphen-separated) and serve as the upsert identity — publishing to the same key updates the existing shared strategy for all stores.

  • Architecture Refactored dialog services for Strategy Manager

    The dialog services for the Shared Strategy Catalog and Strategy Comparison views have been moved from MainMMViewModel to ManagePricingStrategyV2ViewModel, aligning with the UI reorganization. The frozen-surface contract test has been updated to reflect the removal of the two public methods from the main window's viewmodel.

  • Architecture Removed obsolete strategy menu commands

    Removed ShowSharedStrategyCatalog and CompareStrategies commands from MainMMViewModel and their associated dialog service registrations in MainMMWindow.xaml. These commands and dialogs have been relocated to ManagePricingStrategyV2ViewModel, streamlining the main window's responsibilities.

  • Architecture Table-driven sensitivity mapping with SQL generation

    Implemented table-driven code-to-score mappings with generated SQL CASE statements, pinned by unit tests. Moving a code between rungs (e.g., adjusting DIB "E" from 50 to 25) requires only a one-number change in the map, automatically reflected in all SQL queries. Unit tests lock the contract: shared rung values, units-weighted math, null (never zero) scores when no assigned volume exists, additive roll-ups, and the blind/sensitive share and coverage companion metrics.

  • Architecture New StrategyColumnRequirementPolicy service

    Introduced StrategyColumnRequirementPolicy to determine which columns a strategy requires based on its rules. The policy is deliberately minimal—it only requests columns when adding them would actually make a level usable, avoiding unnecessary layout changes. For example, it won't request Retail/Level1/Level2 columns at Bloom Retail stores where those levels are suppressed regardless of view settings. Includes 23 new unit tests covering boundary conditions and ensuring the policy adds exactly what's needed and nothing extra.

  • Architecture Standalone sitting-margin query service

    Extracted the sitting-margin bucket query (the SELECT…GROUP BY that aggregates last-12-months sales/COGS into price bands at current and future price) from ProfitAnalyzerViewModel into a standalone, reusable SittingMarginQueryService. The query logic now lives in SittingMarginQueryBuilder as a single source of truth, and the roll-up math (gross profit / sales) lives in SittingMarginMath, ensuring the on-screen Profit Analyzer, the sitting-margin telemetry post, and the new Strategy Comparison product all measure margins identically. Added comprehensive unit tests (StrategyComparisonMathTests) locking the A/B diff math: dollars are additive so overall = Σ store = Σ dept, the grand total is dollar-weighted (not an average of per-grain percentages), and candidate-vs-baseline dollars is the incremental profit the new strategy makes over the old one.

  • Architecture Price level assignment policy for bulk actions

    A new BulkAssignableLevelPolicy class defines which price levels the "Assign Price Level" action may offer. Only self-contained levels (Retail, Level 1, Level 2, CurrentPrice, StoreCost, vendor-specific levels like Ace_MSURetail, and zone levels) are offered; levels that require a per-rule value (Margin %, Fixed Retail, Cost Break, Set-to-SKU) are excluded because assigning them in bulk would recreate the exact "cannot price" state the action exists to fix. Unit tests pin this exclusion list.

  • Architecture Removed legacy synchronous ExportRockSolid method

    Dropped the dead sync ExportRockSolid method, which carried a second copy of the concatenated DELETE/INSERT pattern with the same apostrophe and culture bugs. All export operations now route through ExportRockSolidAsync with the corrected, parameterized approach.

  • Architecture Strategy freshness service

    Introduces StrategyFreshnessService and StrategyFreshnessStamp to compute and validate freshness stamps. The stamp is composed from vendor catalog RowVersion (for Ace/DIB/EJ), POS ImportProcessing max date, and a SHA-256 content hash of the strategy's GlobalFileConfig rows (which have no modification timestamps). Unit tests lock the contract: snapshots with missing stamps are never current, and any component change invalidates the stamp.

  • Architecture Standalone sitting-margin query service and math

    Extracted the sitting-margin bucket query (the SELECT…GROUP BY that aggregates last-12-months sales/COGS into price bands at current and future price) from ProfitAnalyzerViewModel into a standalone, reusable SittingMarginQueryService. The query logic now lives in SittingMarginQueryBuilder as a single source of truth, and the roll-up math (gross profit / sales) lives in SittingMarginMath, ensuring the on-screen Profit Analyzer, the sitting-margin telemetry post, and the new Strategy Comparison product all measure margins identically. Added comprehensive unit tests (StrategyComparisonMathTests) locking the A/B diff math: dollars are additive so overall = Σ store = Σ dept, the grand total is dollar-weighted (not an average of per-grain percentages), and candidate-vs-baseline dollars is the incremental profit the new strategy makes over the old one.

  • Refactor Finish the store-settings move out of GlobalFileConfig
  • General Merge pull request #1310 from retailersoft/fix/schedule-migration-at-startup
  • General Migrate the background schedule on startup, not on opening Options
  • Infrastructure Custom groups service enhancements

    Extended CustomGroupsService with new methods to support the copy and duplicate-finder features: GetGroupCountsByStrategyAsync returns the count of custom groups per strategy for the picker list; GetGroupsWithSkuCountsAsync loads all groups in a strategy with their SKU counts for the picker grid; CopyGroupToStrategyAsync performs the transactional copy of one group's settings and SKU list to a new GroupID in another strategy; GetGroupSkuRowsAsync retrieves all SKU memberships for duplicate detection; and RemoveSkuFromGroupAsync deletes a single (GroupID, SKU) row. Two new helper classes handle naming (GroupCopyNameHelper picks the next free "- Copy" variant) and duplicate detection (DuplicateSkuFinder groups SKUs by membership count and filters to those in 2+ groups).

  • Infrastructure Added regression tests for derived column notifications

    Implemented source contract tests that verify all editing paths that reshape SKU exception rules properly notify the grid's derived columns (Type and FuturePriceAction). These tests prevent future code changes from reintroducing the same notification oversight by scanning the view model source for instruction mutations that mark the row dirty and ensuring they include the required property change notifications.

  • General Merge pull request #1309 from retailersoft/fix/update-stops-service
  • Infrastructure Added null-safety throughout exception loading

    Added null checks and null-coalescing throughout the exception loading and migration code path to prevent any single malformed exception record from crashing the entire load. Null or empty RuleText fields are now handled gracefully, and null rows are filtered out before processing.

  • Infrastructure Export service widened to support tree exports

    ExportService.View property type changed from TableView to DataViewBase (the common base class for both TableView and TreeListView) so Excel export now works for both flat grids and hierarchical tree lists.

  • Infrastructure Added comprehensive test coverage for store routing normalization

    Added 251 lines of tests in StoreRoutingKeyNormalizationTests to pin the meaning of empty store routing lists and prevent regression. Tests cover the exact incident scenario (store 12180), single-store and multi-store configurations with no groups defined, and all database shapes found across customer sites. Full test suite remains green at 1,502 tests.

  • General Do not swap the install folder while a headless import holds it
  • Infrastructure Shared strategy models and API endpoints

    New model classes (SharedStrategyCatalogItem, SharedStrategyDefinition, SharedStrategyStep, SharedStrategyOrigin, PublishSharedStrategyRequest/Response) define the wire format and local provenance structure. ApiClientService adds three endpoints: GET api/v2/SharedStrategy (catalog list filtered by vendor type), GET api/v2/SharedStrategy/{key} (full definition), and POST api/v2/SharedStrategy (publish with machine hash). SupportMachineHasher centralizes the SHA256(salt + MACHINENAME) computation used by both CheckIsSupportMachine and publish authorization. SharedStrategyInstallService and SharedStrategyPublishService encapsulate all materialization, validation, and round-trip logic. PricingStrategyService adds RegisterInstalledStrategyAsync to notify the cached strategy list of a directly written strategy without activating it. Comprehensive unit tests (SharedStrategyTests) pin the machine hash algorithm, template key derivation, provenance JSON round-trip, and catalog row state logic.

  • Infrastructure Updated approved test baseline

    Added the CompareStrategies command to the MainMMViewModel frozen-surface contract test, keeping test expectations in sync with the new feature.

  • Documentation Clarified Just Run does not respect prior selections

    Updated the Ace Critical Pricing documentation to clarify that "Just Run" always analyzes every store and item, clearing any active selection-box filters first to ensure nothing is silently excluded from the compliance check. The previous docs incorrectly suggested prior selections would be respected.

  • Infrastructure Tests pin MAP/IMAP always-offered policy at Ace stores

    FuturePriceSetToLevelPolicy tests now verify that MAP and IMAP are offered at Ace Hardware stores even with empty column views (the deliberate vendor exception for the Critical Pricing workflow), while other extended fields remain view-gated and non-Ace stores retain view-gating for MAP/IMAP.

  • Infrastructure Header-driven mapping with comprehensive tests

    The new CompetitorPriceFileReader class is deliberately free of WPF and database dependencies and is covered by 32 unit tests that pin the header-mapping logic, rounding rules, ignore-not-zero behavior, duplicate-SKU handling, and delimited-file parsing. Tests verify that headers are matched case/space/underscore insensitively, that column order doesn't matter, that unrecognized columns are safely ignored and reported, and that duplicate or missing required headers abort before any write occurs.

  • General Merge pull request #1308 from retailersoft/feature/rebuild-consent
  • Infrastructure Added comprehensive SQL generation tests

    Added 183 lines of unit tests (`CompetitorPriceImportSqlTests.cs`) that pin the SQL generated for Replace (multi-table SKU matching, per-level clearing, COALESCE updates) and verify that only Replace-mode levels supplied by the file are cleared, that the clear is unfiltered so absent SKUs end up empty, and that SKU matching requires presence in at least one main table rather than just [Store].

  • General Ask before a rebuild destroys what is on screen
  • Infrastructure Comprehensive test coverage for export preflight checks

    Added RockSolidExportPreflightTests to verify each blocker condition is detected separately and produces distinct remedy text. Tests confirm shared file access is not reported as a lock (the false diagnosis this change removes), folder probes never touch the POS's .ldb lock file, and permission problems name elevation rather than closing the POS.

  • Infrastructure Comparison orchestration refactored to MainMMViewModel

    The Compare Strategies flow (showing picker, running strategies, showing results) is now orchestrated from MainMMViewModel.StrategyUtilities.cs using a post-close dispatch pattern (the hub dialog records the chosen action and closes; MainMMViewModel dispatches afterward), preventing nested modals. The comparison dialog service is now registered on MainMMWindow instead of ManagePricingStrategyV2View.

  • General Merge pull request #1307 from retailersoft/feature/data-update-job
  • Infrastructure Shared strategy install service

    SharedStrategyInstallService materializes downloaded definitions into local GlobalFileConfig strategy rows, validates step parseability before writing anything, installs bundled rounding schemes only when no same-name scheme exists locally, and refuses to overwrite existing strategies or update/remove the active strategy. Warnings are collected for view-dependent operands (Comp1-5, Ace_MSURetail) that only resolve when the field is in the active column view, informing users of potential portability limitations.

  • Infrastructure Comprehensive unit test coverage

    Adds 379 lines of tests (CompetitorPriceFileReaderTests) pinning the import rules: header mapping by name not position, case/space/underscore normalization, decimal rounding, duplicate header detection, missing column validation, price parsing with currency symbols, and the "invalid values are ignored, never zeroed" contract.

  • Infrastructure Unit tests for shared strategy pipeline

    Added SharedStrategyTests pinning the machine hash algorithm (must match server's SupportMachineService), template key derivation, provenance JSON round-trip, catalog row status logic, and definition JSON serialization preserving step order. These tests ensure the publish/download pipeline stays in lock-step with the server and that provenance markers remain readable across versions.

  • General Merge pull request #1306 from retailersoft/feature/service-safety-gates
  • Documentation Import Competitor Prices user guide

    Adds a complete help article (docs/marginmaster/pricing/import-competitor-prices.md) documenting the file format, recognized column names, value parsing rules, import steps, how to use the imported prices in strategies and comparisons, the log format, and common questions. The article is indexed and searchable under "Pricing & Analysis".

  • General Stop the service and the app colliding over a rebuild
  • General Merge pull request #1305 from retailersoft/feature/service-heartbeat
  • General Service checks in with the Manager and executes queued commands
  • General Merge pull request #1304 from retailersoft/feature/launch-attribution
  • General Report how the app was launched, and let short headless runs check in
  • General Merge pull request #1303 from retailersoft/fix/MM-1397-strategy-column-requirements
  • General Merge pull request #1302 from retailersoft/fix/MM-1393-store-identity-source-of-truth
  • General Merge pull request #1301 from retailersoft/fix/MM-1399-empty-routing-keys
  • General Merge pull request #1300 from retailersoft/docs/eci-hosting-migration-advisory
  • General Docs: re-stamp verified_sha for eci-vpn-requirement
  • General Merge pull request #1299 from retailersoft/fix/MM-1399-main-table-selection
  • General Merge pull request #1298 from retailersoft/fix/MM-1399-table-cleanup-policy
  • General Merge pull request #1297 from retailersoft/perf/reconcile-count-gate
  • General Gate key-set reconciliation on a row count, and watch every vendor table
  • General Merge pull request #1296 from retailersoft/docs/lock-column-and-tooltips
  • General Explain the lock icons: tooltips in the grid + a doc for the "*" column
  • General Merge pull request #1295 from retailersoft/docs/eci-vpn-nat-requirement
  • General Docs: stamp verified_sha for eci-vpn-requirement
  • General Merge pull request #1294 from retailersoft/docs/testing-lesson
  • General Record the targeted-testing correction in lessons
  • General Merge pull request #1292 from retailersoft/feature/nsoftware-bump-and-drift-detection
  • General Merge pull request #1293 from retailersoft/fix/MM-1396-competitor-price-import
  • General Bring unlicensed packages up to latest stable
  • General Bump nsoftware to current builds and make drift fail the build
  • General Merge pull request #1291 from retailersoft/fix/vendorgtin-reconciler-and-sync-tail
  • General Actually populate TombstonesKept and MaxRowVersionSyncedHex
  • General Cut two pieces of collateral work out of the post-sync tail
  • General Surface a failed sync table instead of hiding it behind the ones that worked
  • General Merge pull request #1290 from retailersoft/chore/approve-import-competitor-prices-surface
  • General Approve ImportCompetitorPrices on the MainMMViewModel surface
  • General Correct stale docs publishing instructions
  • General Merge pull request #1289 from retailersoft/feature/import-competitor-prices
  • General Merge pull request #1288 from retailersoft/fix/MM-1395-store-renumber
  • General Merge pull request #1287 from retailersoft/fix/MM-1394-sku-exception-type-refresh
  • General Merge pull request #1283 from retailersoft/perf/cloud-sync-proxy-compression
  • General Merge pull request #1286 from retailersoft/fix/refresh-without-drop
  • General Merge pull request #1285 from retailersoft/fix/key-set-reconciliation
  • General Merge pull request #1284 from retailersoft/fix/sync-engine-correctness
  • General Merge pull request #1282 from retailersoft/test/cloud-sync-fidelity-harness
  • General Skip the drift check when the proxy cannot answer it
  • General Refresh in place, index the local table, validate counts over the proxy
  • General Remove local rows the vendor hard-deleted
  • General Stop the sync skipping rows it can never come back for
  • General Negotiate compression on cloud sync proxy requests
  • General Merge pull request #1280 from retailersoft/fix/dib-level5-edlp-zero
  • General Stop the MMVendorData view inventing a DIB EDLP price
  • General Merge pull request #1281 from retailersoft/fix/green-main-di-baseline-and-surface-snapshot
  • General Get main green: refresh the surface snapshot and baseline PriceLevelSelectViewModel
  • General Merge pull request #1279 from retailersoft/fix/startup-db-maintenance-shrink-order
  • General Merge pull request #1278 from retailersoft/docs/poco-house-style-guard
  • General Pin runtime POCO as the ViewModel house style
  • General Merge pull request #1277 from retailersoft/chore/devexpress-26.1.4
  • General Merge pull request #1276 from retailersoft/fix/MM-sku-exception-individual-save
  • General Merge pull request #1275 from retailersoft/fix/strategy-rerun-prompt-deliberate-click
  • General Stop asking a deliberate Execute Strategy click to confirm itself
  • General Merge pull request #1274 from retailersoft/fix/MM-1387-MM-1392-mi9-rounding-display-user4
  • General Merge pull request #1273 from retailersoft/fix/MM-1391-index-bloat
  • General Merge pull request #1272 from retailersoft/fix/startup-cost-reduction
  • General Cut startup DB cost: batch index seeding, cached blank flags, gated scans
  • General Merge pull request #1271 from retailersoft/fix/sitting-margin-single-scan
  • General Remove background sitting-margin scans (fleet slowness reports)
  • General Merge pull request #1270 from retailersoft/feature/acp-just-run-applies-steps
  • General Ace Critical Pricing "Just Run" now applies the corrections
  • General Merge pull request #1269 from retailersoft/fix/ace-critical-pricing-just-run
  • General Make Ace Critical Pricing "Just Run" a workable pricing flow
  • General Merge pull request #1268 from retailersoft/fix/data-aging-pill-clock-icon
  • General Use clock icon on the Data Aging title-bar pill
  • General Merge pull request #1267 from retailersoft/fix/ace-critical-pricing-splash-lockup

Imports & POS

  • Improvement Enhanced RockSolid export error messaging

    If the RockSolid export fails, you'll now see clear instructions telling you to close RockSolid on all computers, check if the file is read-only, and verify you have permission to update files in that folder.

  • Improvement Enforce required Alternate SKU column for RockSolid

    The Alternate SKU column now appears automatically in all your saved column views and cannot be hidden, since RockSolid requires this field for syncing data with your POS system.

  • Improvement Compass incremental sync now works correctly from first import

    Compass imports after the first one now complete faster by only loading changed items instead of reloading everything.

  • Improvement Export error messages now show the full file path

    Error messages now show exactly which file couldn't be updated, making it easier to locate and fix permission issues.

  • Improvement Text export performance improved for large exports

    The UPC lookup now runs one bulk query per export instead of two database queries per row, significantly improving export speed for files with hundreds or thousands of items.

  • Improvement Store Manager Epicor store sorting by character ordinal

    Enhanced Store Manager query to order Epicor stores by their character ordinal value while non-Epicor stores continue to sort numerically when possible, ensuring consistent and logical store ordering in the grid.

  • Improvement Common questions expanded for migration timing

    Added three new FAQ entries covering whether stores should still build tunnels given the temporary nature, what ECI Connect is and whether it works with Margin Master, and how to request an earlier migration slot from ECI. Includes practical guidance that stores needing pricing data now should still build since the firewall purchase isn't wasted and only tunnel reconfiguration is required.

  • Improvement Setup process guidance strengthened

    Added a tip to send WAN IP and subnet information in writing on the case thread and keep a copy, after a case where ECI stated they never received network details while the store believed they had sent them, causing a month-long delay. Updated technical details to note that server addresses are site- and era-specific and will change post-migration.

  • Bug Fix First-time Compass import error eliminated

    The first Compass import at a new store now completes cleanly without generating error reports.

  • Bug Fix Compass first-import crash resolved

    If you're setting up Margin Master for the first time with Compass, the initial import will now complete successfully instead of failing with an error.

  • Bug Fix Comprehensive error message for RockSolid export failures

    If a price export to RockSolid fails, you'll now see a checklist of all three things to verify, not just one, making it faster to find and fix the actual problem.

  • Bug Fix UPC column in text exports now writes actual codes instead of X's

    When you export pricing to a text file, the UPC column will now show the correct UPC codes for your products instead of all X's. If a product doesn't have a UPC in the system, it will still show X's as a placeholder, and the export will note how many products are missing UPCs.

  • Bug Fix Manual catalog SKU additions now persist correctly

    When you used "Add From Catalog" to manually add a vendor SKU to your pricing grid, the item appeared to be added successfully but would disappear the next time you rebuilt your catalog. This is now fixed—manually added items will stay in your grid as expected.

  • Bug Fix Fixed RSC hijacking when vendor store numbers match Epicor character ordinals

    Stores at Do-It-Best Epicor Compass sites now receive pricing from their correct RSC code instead of accidentally using another store's RSC when store numbers overlap with internal character codes.

  • Bug Fix RockSolid export failures no longer appear on app-error dashboard

    File access issues during RockSolid export are now logged as warnings rather than errors, preventing them from appearing on the application error dashboard. This change recognizes that write-refused conditions are environmental issues on the store's machine, not application faults, consistent with how connectivity failures are already handled in cloud sync.

  • Bug Fix Fixed Store Manager hiding case-distinct Epicor store pairs

    Store Manager now correctly displays all Epicor stores, including those whose store identifiers differ only by uppercase/lowercase letters (which represent different physical stores in Epicor).

  • Bug Fix Mi9 required columns now correctly enforced

    Fixed an inverted logic condition that prevented the SKU and Store Group columns from being automatically added for Mi9 users when missing from a view. The force-add logic now correctly triggers when these columns are absent rather than when they are present.

  • Bug Fix Backstop ensures required columns in saved views

    Added validation when saving or copying column views to automatically append any missing required columns (such as Alternate SKU for RockSolid) to the end of the view. This prevents edge cases where saved view configurations could be persisted without mandatory columns.

  • User Interface Alternate SKU column enforced for RockSolid

    The Alternate SKU column will automatically appear in your Main Table grid right next to the SKU column and will always stay visible.

  • User Interface ECI hosting migration warning added to VPN documentation

    The VPN setup guide now warns that ECI is moving to new servers — if you set up a tunnel now, you'll need to reconfigure it in a few months when the migration finishes.

  • User Interface Column removal blocked in Edit Columns dialog

    If you try to hide the Alternate SKU column in Edit Columns, you'll see a message explaining it's required for RockSolid and the column will remain checked.

  • User Interface Prevent removal of Alternate SKU column in Edit Columns dialog

    When customizing columns, you'll see a message if you try to hide the Alternate SKU column, explaining that RockSolid requires it to stay visible.

  • User Interface ECI Connect service documented with compatibility questions

    ECI has a new service called ECI Connect that might replace VPN tunnels, but we don't yet know if it will work with Margin Master — please let us know what ECI tells you about it.

  • Database Automatic repair of missing database defaults

    Added a startup healing routine that detects and repairs existing databases missing the CreateDate default constraint on ManualCatalogItems table. The fix runs idempotently on every startup, ensuring all installations are automatically corrected without manual intervention.

  • Infrastructure Correct logging level for file permission failures

    RockSolid export failures caused by file permissions, read-only attributes, or locked files are now logged as warnings instead of errors. This prevents store-specific machine configuration issues from appearing on the application error dashboard as though Margin Master itself were broken. Genuine application failures continue to log as errors.

  • Infrastructure Schema generator now emits DEFAULT constraints

    Enhanced MigrationBasedSchemaCreator to emit DEFAULT constraints for all model-defined defaults (both SQL expressions and CLR default values), preventing the same class of failures on future fresh database installations. CLR defaults are formatted as culture-invariant T-SQL literals to ensure cross-locale compatibility.

Cloud Sync & Vendor Data

  • New Feature Manual Ace zone refresh command

    If your Ace zone assignments change at the corporate level, you can now use Options > Refresh Ace Zones in Store Manager to immediately update all your stores' zones without waiting for the next sync. The system will tell you how many stores had their zones updated.

  • New Feature Manual Ace zone refresh command

    Click Options > Refresh Ace Zones to re-check the assigned zone for all your stores against the latest Ace data. You'll see a summary of how many zones changed.

  • New Feature Data rebuild consent flow

    When new vendor or POS data arrives while you're working, Margin Master will now ask before restarting to apply it, instead of wiping your screen without warning. You can postpone up to 3 times if you're in the middle of something.

  • New Feature Session capture and restore

    After a data update restart, Margin Master will automatically restore your grid selection and return you to exactly where you were before the update.

  • New Feature Session capture and restore

    When you accept a data update, Margin Master saves what you have on screen, applies the update, and automatically reopens with your selection and pricing strategy restored.

  • New Feature Deferral limits on parked updates

    You can postpone a data update up to 3 times. After that, it will be applied automatically to ensure your pricing stays current.

  • Improvement Periodic refresh now updates in-place instead of dropping tables

    During the monthly catalog refresh, you'll no longer see a period where catalog data temporarily disappears from the system.

  • Improvement In-place table refresh replaces drop-and-recreate

    Scheduled monthly vendor catalog refreshes now happen seamlessly in the background. Pricing data remains accessible throughout the refresh instead of briefly disappearing.

  • Improvement Consent prompt before destructive rebuild

    If a data update runs while you're working, Margin Master now asks permission before applying it instead of disrupting your screen. You can apply it immediately, postpone it for 2 hours, or let it apply automatically after being postponed 3 times.

  • Improvement Better timeout diagnostics in sync logs

    When sync issues occur, support staff will receive clearer information about what went wrong and how to fix it.

  • Improvement Made reconciliation failures non-fatal to sync operations

    If the cleanup step encounters an issue, your pricing data will still sync successfully rather than failing the entire operation.

  • Improvement Enhanced zone lookup with cache control

    Extended the GetAceZonesToSync API method with a forceRefresh parameter that drops the 7-day cache, allowing manual refresh operations to fetch fresh data from the server while preserving normal cache behavior for automatic lookups.

  • Improvement Unified zone lookup logic across Store Manager

    Refactored zone resolution into a single LookupAceZoneAsync method shared by both the auto-fill-on-entry path and the new manual refresh command. This ensures consistent behavior: local AceStoreDepartmentZoneRecords rows are checked first (minimum zone across departments), and if the store isn't found there, the cloud API is queried. The forceRefresh parameter controls whether the 7-day cache is bypassed.

  • Improvement Data Aging screen flags stale sync dates from recent failures

    In the Data Aging screen, tables that failed their most recent sync attempt are now highlighted in red with an explanation, so you can tell the difference between "no new data" and "sync is broken".

  • Improvement Reconciliation failures no longer block entire table sync

    Sync now completes successfully even if the cleanup step encounters an error. The data you need is synced correctly, and cleanup will be retried next time.

  • Improvement Separate ingest from rebuild

    Data downloads now complete in the background even while you're working. Only the final table rebuild step waits for your approval.

  • Improvement Epicor import data preserved during store renumbering

    If your Epicor store gets renumbered, your pricing data will rebuild automatically from existing import files without waiting for a new data import.

  • Improvement Enhanced Epicor store data migration during renumbering

    When an Epicor store is renumbered, the system now preserves historical POS data by moving staging table records, purchase order data, and the main table itself to the new vendor store number. This prevents data loss and ensures continuous pricing history across the renumbering event.

  • Improvement Sync statistics now record watermark and tombstone metrics

    SyncStatistics now captures MaxRowVersionHex (the highest RowVersion synced) and TombstonesKept (count of soft-deleted rows retained locally) for each table sync. These metrics enable fast diagnosis of tables that appear to re-transfer the same rows on every sync—previously this required cross-database reconstruction to distinguish a regressing watermark from the producer re-stamping rows.

  • Improvement MMVendorData view health checks now 400x faster

    Post-sync verification now queries the view's input tables (DIBCatalogRecords and DIBPriceLevelRoundingDetails) directly instead of materializing the entire MMVendorData multi-join view. The old COUNT(*) FROM MMVendorData took 6.7 seconds and contributed the majority of total sync time on some stores. The new indexed checks run in ~16ms and detect the same failure condition (missing SchemeID=2 rounding rows).

  • Improvement Duplicate index rebuild eliminated after catalog add

    Rebuilding the main table via catalog add (UPDATE-style rebuild) now skips the managed index rebuild when CreateTopPanel is also queued, since CreateTopPanel runs the identical rebuild pass moments later. This eliminates redundant index recreation and ~3 seconds of selection box cache rebuilding on every sync for DIB stores using per-store POS tables.

  • Bug Fix Increased timeout for table structure operations

    Sync operations will no longer fail with timeout errors when working with large vendor catalogs on slower computers.

  • Bug Fix Do-It-Best EDLP column now displays accurate data

    The Do-It-Best EDLP price column in the pricing grid now correctly shows zero when EDLP pricing is not available, instead of displaying an incorrect calculated price.

  • Bug Fix DIB EDLP column showing fabricated prices

    When viewing Do-It-Best items, the "DIB EDLP" column was showing prices that looked real but were actually calculated from a pricing formula. Since Do-It-Best doesn't provide EDLP pricing, this column now correctly shows zero.

  • Bug Fix Out-of-order transaction commits no longer cause permanent data loss

    Catalog and zone pricing updates now always arrive, even when the vendor's database processes multiple updates simultaneously.

  • Bug Fix Prevent false drift detection during version mismatches

    Fixed an issue where a store running newer Margin Master software would incorrectly detect data drift when syncing with an older cloud server. The newer client requests an active-only row count (excluding deleted records), but older servers silently ignore this flag and return a count including tombstones. The client would compare this inflated count against its own live count, conclude it was missing data, and force a full resync of the entire partition on every sync. This was particularly problematic for AceZoneRecords tables where 90% of cloud rows are tombstones. The client now returns -1 for "cannot answer" and skips validation rather than triggering unnecessary resyncs.

  • Bug Fix Sync engine no longer skips rows during concurrent updates

    When vendor catalogs were being loaded while sync was running, some price or product updates could be skipped and never appear in Margin Master. This is now fixed—all updates will be captured, even during busy catalog import periods.

  • Bug Fix Store renumbering now fully reconciles all internal references

    If your vendor gives you a new store number, the system will now automatically update all internal references after you enter it in Store Configuration. You'll no longer experience incorrect pricing due to mismatched store numbers.

  • Bug Fix Automatic repair when vendor renumbers a store

    If your vendor changes your store number, the system will now automatically update all internal records to match after you validate the new number. You no longer need to manually correct store mappings or worry about pricing at the wrong zone.

  • Bug Fix Fixed SQL ambiguity error in VendorGTIN reconciliation

    When vendors like Ace Hardware or Do-It-Best permanently remove products from their catalogs, those deletions will now correctly sync to your local database instead of leaving old records behind.

  • Bug Fix Failed sync tables now reported when other tables succeed

    When syncing vendor data, you'll now see a notification listing any tables that failed to sync, even when other tables succeeded. Previously, these failures were invisible unless all tables failed.

  • Bug Fix VendorGTIN reconciliation failure resolved

    VendorGTIN and catalog data now properly clean up deleted items during sync. Previously, items removed by the vendor would remain in your database indefinitely.

  • Bug Fix Newly entered store numbers now auto-populate zones correctly

    When you enter an Ace store number for a new store location, the Ace Zone field will now always populate automatically, even if that store hasn't been through a vendor sync yet.

  • Bug Fix Auto zone fill now works for newly added stores

    When you type in a vendor store number for a new store, its Ace Zone now fills in automatically right away, even if that store hasn't gone through a vendor sync yet.

  • Bug Fix Removed incorrect READPAST hint that skipped locked rows

    The sync no longer skips catalog rows that are being updated at the same time, ensuring all changes are captured.

  • Bug Fix Eliminated duplicate label printing from retired GTINs

    Products with reassigned barcodes will no longer print extra labels showing old, retired barcodes.

  • Bug Fix Retry logic now correctly detects when sync is complete

    Sync will now correctly continue until all pending changes are downloaded, even when the server is under heavy load and individual queries need to be retried with smaller batches.

  • Bug Fix Duplicate barcode labels from retired GTINs eliminated

    SKUs with updated barcodes will now print only one label with the correct, current barcode instead of printing extra labels with old retired barcodes.

  • Bug Fix Manual vendor store number corrections now persist correctly

    When you change a store's Vendor Store # in Store Manager, the change will now stick instead of reverting when you restart the application.

  • Bug Fix Store Manager vendor store number changes now update all related records

    Changes to vendor store numbers in Store Manager now save correctly and persist across restarts.

  • Bug Fix Database connection error message corrected for SQL query defects

    Error messages during sync now accurately describe what went wrong instead of incorrectly blaming database connection issues.

  • Bug Fix Query timeout retry now correctly resumes sync loop

    After a temporary timeout, sync now correctly downloads all remaining changes instead of stopping partway through.

  • Bug Fix Count validation now works for firewalled stores using proxy mode

    The system can now automatically detect and repair incomplete syncs for stores behind firewalls, improving data accuracy.

  • Bug Fix Epicor per-store table reconciliation now runs consistently

    Stores using Epicor will no longer see duplicate store entries or incorrect zone pricing from leftover data tables.

  • Bug Fix Fixed orphaned Epicor main tables when using Store Manager without store mapping

    Epicor stores will no longer show duplicate entries in reports or price incorrectly due to leftover old pricing tables.

  • Bug Fix Count validation handles server version differences gracefully

    When an older Manager version doesn't support the activeOnly flag on count queries, the proxy now returns -1 to signal "cannot answer" rather than an incorrect tombstone-inclusive count. This prevents false-positive drift detection that would trigger unnecessary full resyncs on every sync cycle.

  • Bug Fix Scheduled refresh no longer forces reconciliation unconditionally

    Scheduled syncs now run more efficiently and avoid SQL errors that previously affected some Ace Hardware catalog tables.

  • Bug Fix Removed obsolete 'NoChanges' sync status

    Dropped references to the 'NoChanges' status value in sync history queries, as SyncStatisticsManager only ever writes 'Success' or 'Failed'. The Data Aging query previously filtered for both 'Success' and 'NoChanges', but the latter was never produced.

  • Bug Fix Critical composite index now created correctly

    Fixed the Store table's composite index on [StoreNumber, SKU] (RSIX_Store_StoreNumberSKU), which was registered but never actually created due to a SQL guard that could not match multi-column definitions. The index now builds correctly on non-WestLake stores. Existing stores will have their stale seed definitions refreshed automatically. This index supports faster lookups when filtering the pricing grid by store and SKU together.

  • Bug Fix Prevent rebuild loops on persistent failures

    If a rebuild fails during the background apply phase, the parked work record is still cleared and the application is still relaunched. This prevents the user from being restarted in a loop on a rebuild that would fail the same way every time. The failure is logged to history where the user can see it, but they are not left without an application.

  • Bug Fix Per-store POS tables no longer truncate global mainTable

    DIB stores using RockSolid, Transact, or non-MySQL Epicor build per-store main tables and never write to the global [mainTable]. The rebuild process now skips truncating [mainTable] and clearing SelectionLists for these stores, eliminating an unnecessary 3+ second selection box rebuild on every sync.

  • Cloud Sync Key set reconciliation for hard-deleted vendor records

    When vendors completely remove products from their catalogs, those products are now automatically removed from your local database during sync.

  • Cloud Sync Key set reconciliation for hard-deleted vendor records

    When vendors completely remove products from their systems (not just mark them deleted), those items are now properly removed from your local database instead of staying forever.

  • Cloud Sync Intelligent cleanup gate prevents unnecessary work during sync

    Syncs complete faster when no vendor catalog records have been removed, especially for large tables.

  • Cloud Sync Server response now indicates whether active-only filter was applied

    The cloud sync proxy now checks whether the server actually applied the activeOnly filter when counting rows. If the server response doesn't confirm the filter was applied (indicating an older Manager), the count is treated as unreliable and drift validation is skipped for that partition.

  • Cloud Sync Failed table syncs now reported even when other tables succeed

    You'll now see a notification if any vendor data table fails to sync, even when other tables sync successfully. This helps catch partial sync failures that were previously invisible.

  • Cloud Sync Hard-deleted vendor records now cleaned up automatically for all tables

    Removed vendor items and outdated catalog data are now automatically cleaned up across all vendor tables, preventing issues like printing labels with retired barcodes.

  • Cloud Sync Opt-in reconciliation per table with safety guards

    Reconciliation is deliberately opt-in via the ReconcileKeys flag because it reads every in-scope key from the cloud. For a narrow table like VendorGTIN (three columns, ~88k rows) this is negligible; for large tables like AceZoneRecords it would be expensive. The reconciler also refuses to act on an empty cloud key set, preventing catastrophic data loss if a network failure or truncated read returns zero records—it will not interpret that as "the vendor retired everything."

  • Cloud Sync Opt-in reconciliation with safety guardrails

    Reconciliation is opt-in per table via the ReconcileKeys flag because it reads every in-scope key from the cloud, which is inexpensive for narrow tables like VendorGTIN (~88k rows, 3 columns) but would be costly for large tables like AceZoneRecords. Added a safety guard that refuses to act on an empty cloud key set, preventing catastrophic data loss if a cloud read fails or returns no results.

  • Cloud Sync Count validation now works in proxy mode

    The system now automatically detects and corrects incomplete vendor data downloads, even for stores behind firewalls.

  • Cloud Sync Reconciliation runs even when no changes detected

    Reconciliation executes on the "nothing changed" sync path as well as normal updates. This is critical: a hard delete bumps no RowVersion, so the sync where reconciliation needs to fire is precisely the one where the watermark reports zero rows to fetch. Both direct SQL and HTTPS proxy modes are supported; proxy mode pages through the existing rows endpoint requesting only key columns plus RowVersion.

  • Data Import Verified Do-It-Best catalog feed structure

    Confirmed that the Do-It-Best FTP catalog feed contains only CTLD, PCD, PRDCD, EstimatedNetCost, and order/promo files—no EDLP or everyday-low-price data is provided. This validation ensures the system accurately reflects the vendor's actual data structure.

  • User Interface Updated Store Manager documentation

    Updated store-manager.md documentation to describe the new Refresh Ace Zones feature and clarified that zone auto-population works for newly entered stores via cloud fallback when local sync data is unavailable.

  • User Interface Refresh Ace Zones button in Store Manager toolbar

    Look for the new "Refresh Ace Zones" button in the Store Manager toolbar when working with Ace Hardware stores.

  • User Interface Sync failure notification uses non-blocking toast instead of modal dialog

    Failed table notifications now appear as non-blocking notifications rather than modal dialogs, because the sync splash screen is still visible and post-processing tasks are queued. A modal dialog would strand the background work behind the splash, preventing completion. The notification lists which tables failed and directs users to the application log for details.

  • User Interface Sync history grid now highlights stale success dates

    The data aging screen now clearly marks when a table's sync date is stale because a later attempt failed. Look for red dates with "(last sync failed)" to identify ongoing sync issues.

  • User Interface Main screen rebuild coordination

    The main view model now checks for parked rebuilds during background job polling, offers them when the pipeline is idle, and handles the capture/restore workflow. Consent prompts never interrupt active strategy runs or imports.

  • User Interface Deferral limits prevent silent staleness

    You can postpone a data update up to 3 times. After that, it will apply automatically to ensure your pricing stays current.

  • Database PendingPipelineWork table

    Added a new `PendingPipelineWork` table to store rebuild details (steps, strategy, selection, state) across the app restart that applies it. Steps are stored by name rather than enum values to survive build changes. Single-row table by design—newer parked work replaces older.

  • Database Cleanup policy registration

    PendingPipelineWork table added to DatabaseTableCleanupPolicy's protected table list to ensure it is not inadvertently dropped during maintenance operations.

  • Architecture Added test coverage for DIB EDLP column behavior

    Created comprehensive tests to prevent regression of this issue. Tests verify that Level5 is set to zero for Do-It-Best items, that it does not source from the rounding ladder, and that Level3/Level4 continue to use the ladder as intended. This prevents a repeat of the MM-1354 issue where a ladder-calculated value was incorrectly placed in a vendor-specific pricing column.

  • Architecture Unified active row counting logic

    Created ActiveRowCounter helper to centralize the "how many live rows exist for this scope" query used by both the count-validation pass and the reconciliation gate. This ensures both features measure the same thing, preventing silent failures where divergent SQL could cause reconciliation to skip when it should run.

  • Architecture Rebuild-and-restore runner

    A new headless command (`rebuild-and-restore`) applies accepted rebuilds and relaunches the app. Launched by the closing app itself rather than the Windows service, ensuring it runs in the user's session and can restore windows to their desktop even on locked or remote-desktop machines.

  • Infrastructure Comprehensive test coverage for DIB EDLP column

    Added DibEdlpLevel5Tests to verify that the MMVendorData view assigns zero to Level5 and does not source it from the rounding ladder (np.Next3). The tests also verify that Level3 and Level4 continue to legitimately use the ladder, preventing regression of the MM-1354 fix for DIB Aux Retail.

  • Performance & Reliability Added indexes to speed up sync operations on large catalogs

    Syncing large vendor catalogs (especially Orgill and Ace Hardware) will complete noticeably faster.

  • Performance & Reliability Database indexes added for sync operations

    Cloud sync now runs significantly faster, especially for stores with large vendor catalogs.

  • Infrastructure Added test coverage for out-of-order transaction commits

    Added comprehensive sync fidelity tests that reproduce the out-of-order commit race condition using overlapping transactions with different rowversions. Tests verify that rows are deferred rather than skipped when transactions are still in flight, and that all data is eventually synchronized once transactions commit.

  • Infrastructure Added test coverage for filtered reconciliation

    Extended sync fidelity tests to cover reconciliation scenarios where the filter column is also a key column, which is the production configuration for VendorGTIN and DIBCatalogRecords. Tests verify both that reconciliation works under these conditions and that rows outside the filter scope are left untouched.

  • Infrastructure Added comprehensive sync fidelity test coverage

    Added test case RowCommittedOutOfOrder_IsNotSkippedPastAndLost that reproduces the out-of-order commit race condition, verifying that rows committed out of order are deferred and delivered rather than permanently lost. Test fixture now enables READ_COMMITTED_SNAPSHOT to match production RS_CLOUD database settings.

  • Infrastructure Enhanced cloud sync proxy API

    Extended the ICloudSyncProxy interface and ApiCloudSyncProxy implementation to support counting active (non-tombstone) rows in a vendor catalog partition. This enables post-sync validation to verify that the local catalog matches the vendor's published data by comparing active row counts.

  • Infrastructure Comprehensive sync fidelity test coverage

    Added three new test cases covering hard delete scenarios: verification that hard deletes are invisible to standard watermark sync, validation that reconciliation correctly removes orphaned rows, and confirmation that reconciliation refuses to delete all local data when the cloud returns an empty key set.

  • Infrastructure Parked rebuild storage

    Introduces PendingPipelineWork table and service to store rebuild jobs that are waiting for user consent. The table persists the queued post-processing steps by name (not enum ordinal) to survive application version changes across the restart boundary. Includes automatic table creation on first use, matching the pattern used for BackgroundJobStatus and BackgroundJobLock. Steps that no longer parse in the restored version are logged and skipped rather than causing a failure.

  • Infrastructure Session-aware background runner

    Added RebuildAndRestore headless command that applies a parked rebuild and relaunches the interactive application. This runner is spawned by the closing app itself (not by the Windows service) to inherit the user's session context, avoiding impersonation issues on locked workstations, multi-session machines, and remote desktop connections. The runner waits for the interactive presence marker to clear (up to 2 minutes) before touching any tables, ensuring the grid has fully released its handles.

User Interface

  • New Feature Copy Summary button on Strategy Execution Summary

    When viewing the Strategy Execution Summary after a pricing run, you can now click "Copy Summary" to copy the entire report to your clipboard, making it easy to paste the information into an email, support ticket, or notes.

  • New Feature Title bar data aging warning pill

    You'll now see a warning badge in the title bar when your data needs updating. It starts amber when vendor data gets old and turns red with a pulsing effect when your POS data is too old. Hover over it to see details, or click to update your data.

  • New Feature Title-bar data aging warning pill

    Look for a new "Data Aging" badge in the title bar. It appears amber when your data is getting old, and turns red and blinks when your POS data really needs updating. Click it to see details and update your data.

  • New Feature Related issue linking for follow-up submissions

    If you have an open issue but need to report a new but related problem, select "Submit a new issue related to this one" to keep them connected.

  • New Feature Lock column documentation

    Created comprehensive documentation (pricing/lock-column.md) explaining all seven padlock icons, when the column appears, how to interpret blank cells, and common questions. Includes each icon rendered inline, technical details about the data source, and the relationship between icons and pricing rules. Also cross-references SKU-level exceptions and custom groups documentation.

  • Improvement Settings path changes apply instantly

    Changes to default file paths in Settings now take effect immediately. You no longer need to restart Margin Master after updating Import Path, Export Path, or Network Import Root.

  • Improvement Instant application of default path changes

    After changing your default import or export folder in Settings, all file dialogs will immediately use the new location—no restart required.

  • Improvement Simplified deletion confirmation

    When deleting a database, you now type "delete" instead of the full database name to confirm the action.

  • Improvement Delete button now updates while typing confirmation

    The delete button's enabled/disabled state now re-evaluates with each keystroke in the confirmation box, providing immediate visual feedback rather than waiting for focus change.

  • Improvement Confirmation text box enabled for active database selection

    When trying to delete the currently open database, you can now type in the confirmation box to see the full warning message. The Delete button will still be disabled to prevent accidental deletion of the active database.

  • Improvement Runs with errors always show execution summary

    If a strategy run has any problems, you'll always see the Execution Summary screen with the error details, even if you've turned off the after-run summary in settings.

  • Improvement Summary always appears for runs with errors

    Even if you've turned off the Strategy Execution Summary in settings, it will still appear automatically whenever a pricing run encounters errors, so you'll always know when something needs attention.

  • Improvement Weekday-only aging calculation for Do it Best

    If you're a Do it Best store, the system now understands that vendor updates only happen on weekdays, so you won't see false warnings on Mondays after syncing on Friday.

  • Improvement Updated default POS data aging threshold

    The warning for outdated POS data now appears after 5 days instead of 1 day by default, which better matches typical store update schedules.

  • Improvement Console log visibility based on outcome

    The console log now adapts its visibility based on setup outcome: it remains front and center while running and on failure (for troubleshooting), but on success it's hidden by default behind a "View Log" button to emphasize the success confirmation panel.

  • Improvement Console log visibility refined by outcome

    The setup console log now adapts based on outcome: it remains front-and-center during installation and on failure (when troubleshooting is needed), but is demoted to an opt-in "View Log" button on success. This prevents successful installations from feeling uncertain or incomplete due to log text dominating the final screen.

  • Improvement Friendlier SQL Server version display

    When selecting a database server, you'll see clear version names like "SQL Server 2025 Express" instead of confusing numbers.

  • Improvement Suppressed misleading "0 records / 01/01/01" rows in POS import history

    The POS import history grid no longer shows confusing empty rows with "0 records" and placeholder dates from 2001.

  • Improvement Default POS aging threshold increased to 5 days

    The default threshold for POS data age warnings has been increased from 1 day to 5 days to better match typical import schedules.

  • Improvement Vendor sync now updates freshness timestamp even when no changes found

    When vendor sync finds no changes, the system now correctly recognizes your data as up-to-date instead of showing aging warnings.

  • Improvement Step 1 routing logic refined for different entry points

    Plain "Submit New Issue" with open issues now routes to Step 1 for duplicate checking. Direct updates via the issue pill or menu actions ("Update Issue") skip to Step 2 as before. The follow-up flow and startup mode continue to bypass Step 1 since they have explicit intent.

  • Improvement Support Scripts menu relocated to setup dialogs

    Support Scripts is now accessed from within the setup windows instead of the main Tools menu, making it available even when the database isn't yet configured.

  • Improvement Empty POS tables no longer create misleading fallback rows

    The POS table fallback logic now skips tables with zero records, preventing empty tables from masking the "no POS data" condition. Previously, a table with zero rows could suppress both the fallback and the "never imported" warning, making the dialog appear as though data existed when it didn't.

  • Improvement Do It Best weekday-only vendor aging calculation

    For Do It Best stores, the system now understands that vendor data doesn't age over weekends, so you won't see false warnings on Mondays.

  • Improvement Delete button now updates while typing confirmation

    The delete button now responds instantly as you type, making it clearer when you've correctly entered the confirmation text.

  • Improvement Enhanced SKU exceptions and custom groups documentation

    Updated sku-level-exceptions.md and custom-groups.md with details on creating exceptions (via Sku Detail tab, not "Add Selected Sku to Custom Group"), added Ctrl+E shortcut, corrected window sizes and Export to Excel paths, documented save-time warnings, explained duplicate-wins rule and execution order, and added sections on the lock icon. Fixed incorrect references to tables/fields that don't exist. Added documentation for Copy Group from Another Strategy and Find Duplicate SKUs features in custom groups.

  • Bug Fix Sensitivity score columns now populate in catalog comparisons

    When comparing vendor catalogs, the sensitivity score columns will now display values instead of appearing blank.

  • Bug Fix SKU exception Type column now refreshes after editing future price

    When you assign a price level to an SKU exception, the Type column now immediately changes from 'U' (unassigned) to the correct type (R/M/D/etc.) instead of staying stuck on 'U' until you close the dialog.

  • Bug Fix One Click Statistics self-heals when no tables are selected

    One Click Statistics will now always display data, even if your current selection doesn't include any pricing tables.

  • Bug Fix File dialogs now consistently honor configured default paths

    Open and Save dialogs now always start in your configured default paths. Previously, they would remember the last folder you browsed to during your session, which could be confusing if you had configured specific default locations.

  • Bug Fix Backup directory now updates with import path changes

    When you change your default import path, the automatic backup location now updates correctly to match.

  • Bug Fix Fixed SKU exceptions staying in Unassigned list after being resolved

    When you fix an unassigned SKU exception and save, it now disappears from the "Unassigned" list right away instead of staying visible until you close the dialog.

  • Bug Fix Print button now functional in One Click dialog

    The Print button in One Click Statistics now works correctly.

  • Bug Fix Improved state synchronization in Delete Database dialog

    Fixed various property change notifications to ensure all UI elements (confirmation box, delete button, status messages) stay properly synchronized when database selection changes or deletion state updates.

  • Bug Fix Timestamp now updated on successful no-change syncs

    Successful syncs now correctly update your "last synced" timestamp even when there are no catalog changes, so you won't see false warnings about stale data when you're syncing regularly.

  • Bug Fix Caller prefill preserved when selecting "New Issue" sentinel

    Selecting the "New Issue" option in Step 1 now restores any pre-filled Title/Description (from error reports or diagnostics) instead of blanking the form, ensuring automatic diagnostic data isn't lost.

  • Bug Fix Improved state synchronization in Delete Database dialog

    Fixed various property change notifications to ensure all UI elements (confirmation box, delete button, status messages) stay properly synchronized when database selection changes or deletion state updates.

  • User Interface Copy Summary button added to Strategy Execution Summary

    When a strategy finishes, you can now click "Copy Summary" on the Execution Summary screen to copy all the details including any errors, making it easy to paste into an email or support ticket.

  • User Interface Issue Wizard Step 1 restored with duplicate prevention

    Before submitting a new issue, you'll see a list of your open issues first, helping you avoid filing duplicates.

  • User Interface Enhanced SQL setup success confirmation

    When SQL Server setup finishes successfully, you'll see a clear green confirmation screen with the server name you can copy, instead of just a small banner that was easy to miss.

  • User Interface Success confirmation panel for SQL setup

    After SQL Server installs successfully, you'll now see a clear green checkmark and your database connection details, instead of scrolling through technical logs to confirm it worked.

  • User Interface SQL Instances window layout improved

    When viewing SQL Server instances during setup, all buttons and information now fit on screen without needing to scroll sideways.

  • User Interface Friendly step-by-step progress during SQL Server setup

    During SQL Server installation, you'll now see clear progress messages like "Downloading SQL Server 2025 Express" instead of technical console text. The technical log is still available under "Technical details" if needed.

  • User Interface Friendly step-by-step progress display during SQL installation

    When setting up SQL Server or running database scripts, you'll see clear step descriptions like "Installing SQL Server LocalDB" and "Configuring firewall rules" instead of scrolling console text.

  • User Interface Database connection window now appears in taskbar

    If you need to reconnect to your database at startup, the connection window will now appear in your taskbar so you can easily find it.

  • User Interface Cleaned up duplicate menu entry

    The Support Scripts tool can now only be accessed from the SQL Server Setup > Tools menu, removing a duplicate menu entry that previously appeared in the database connection window.

  • User Interface SQL Server instance dropdowns show product and version

    When selecting a SQL Server instance in database utilities, you'll now see which version of SQL Server is running (like "SQL Server 2025 Express") to help you choose the correct server.

  • User Interface Utilities menu reorganized into functional groups

    The Utilities menu is now organized into clear sections: diagnostics and logs at the top, data tools in the middle, and reset options at the bottom, making it easier to find what you need.

  • User Interface Utilities menu reorganization

    The Utilities menu is now better organized with related tools grouped together, making it easier to find the right tool and harder to accidentally click dangerous reset options.

  • User Interface Color-coded warning banners in Data Aging dialog

    When you open the Data Aging screen, you'll now see color-coded warnings: red banners alert you when POS data is old or missing entirely, and amber banners warn when vendor data needs a sync. These match the colored pill in the title bar.

  • User Interface Prominent warning banners for stale data

    When you open the Data Aging screen, you'll now see orange or red warning banners if your vendor or POS data is out of date, making it obvious when you need to sync or import fresh data.

  • User Interface Clock icon for Data Aging indicator

    The Data Aging warning in the title bar now shows a clock icon instead of a warning triangle, making it clearer that the alert is about outdated pricing data.

  • User Interface Updated Data Aging icon

    The Data Aging indicator now displays a clock symbol, making it clearer that it relates to how current your pricing data is.

  • User Interface Lock column tooltips in main grid

    Hover any padlock in the "*" column to see what it means. The column header also has a tooltip explaining the column's purpose.

  • User Interface Lock column tooltips added

    Hover over any padlock in the "*" column to see exactly how that item was priced. The column header tooltip now explains what the column is for.

  • User Interface Support Scripts relocated to setup window Tools menus

    Support Scripts is now found in the Tools menu of the SQL Server Setup and Database Setup windows instead of the main window's File menu.

  • User Interface Technical log collapsed by default, auto-expands on failure

    The technical console log is now hidden by default to keep the screen simple, but automatically appears if something goes wrong so support can troubleshoot.

  • User Interface Updated confirmation prompt text

    The prompt text in the Delete Database window was updated from "Type the database name to confirm deletion" to "Type the word delete to confirm" to reflect the new confirmation method.

  • User Interface Confirmation box disabled for active database

    The confirmation text box in the Delete Database dialog is now disabled when the selected database is the currently active one, making it visually clear that deletion is not possible. Previously, users could type the confirmation text even though the delete button would remain disabled.

  • User Interface Communications Tester moved to diagnostics section

    The Communications Tester utility has been moved from the middle of the menu to the diagnostics section alongside log file tools, since it serves a diagnostic purpose rather than a data management function.

  • User Interface "No POS data" banner for stores that have never imported

    If you've never imported any POS data, the screen now shows a clear message explaining that you need to import your point-of-sale data to see sales and margin information.

  • User Interface Updated Z column header tooltip

    Restored the header tooltip for the "Z" (zone pricing) column, which was being lost when the header was replaced with the bare "Z" symbol. Now reads: "Zone — vendor zone pricing applies to this item."

  • User Interface Column header tooltips clarified

    Hover over the "*" or "Z" column headers to see what those symbols mean.

  • User Interface Improved path configuration reliability

    Enhanced path configuration across multiple screens including Main Window, Cost Break, Custom Groups, Pricing Strategy, Rounding Editor, Rounding Scheme Check, and SKU-Level Exceptions to ensure consistent behavior when working with import/export operations.

  • User Interface Updated file dialogs across multiple screens

    Applied the instant path update behavior to file dialogs in Cost Break, Custom Groups, Pricing Strategy, Rounding Editor, Rounding Scheme Check, and SKU-Level Exceptions screens. All now respect updated default paths immediately without storing previously-selected directories between sessions.

  • User Interface Toggle command for showing/hiding log details

    Added a ToggleLogCommand and ShowLogDetails property to allow users to reveal the full console log on the success screen when needed, supporting power users who want to review what happened without cluttering the default experience.

  • User Interface SQL Server Setup always accessible from Database Setup window

    If you need to install or configure SQL Server during first-time setup, you can now access SQL Server Setup directly from the Database Setup window's Tools menu.

  • User Interface SQL Server Setup renamed to SQL Server Tools

    The "SQL Server Setup" menu option and window are now called "SQL Server Tools" to better reflect all the database management tasks you can do there.

  • User Interface Updated tooltips and documentation

    Updated tooltips on the Miscellaneous options screen and the summary screen's checkbox to clarify that runs with errors always show the summary. Documentation now includes a complete section on the Strategy Execution Summary screen with button descriptions and behavior details.

  • User Interface SQL Server Setup menu always accessible from Database Setup

    The Database Setup window now includes a "SQL Server Setup..." option in its Tools menu, ensuring that users on brand-new machines (with no SQL instance and no database) can always reach the guided SQL installation wizard from the initial setup screen.

  • User Interface DateTime.MinValue displayed as "—" in import history grid

    When enriching POS import history from main tables that lack a LastUpdate column, the CreateDate now displays as "—" instead of "01/01/01 12:00 AM", which was confusing and appeared to be corrupt data.

  • User Interface Enhanced Options data aging section labels

    Updated the Data Aging group box label in Tools > Options > Miscellaneous to clarify that the thresholds control when the title-bar warning appears, making the connection between the setting and the new visual indicator clearer to users configuring their preferences.

  • User Interface Result screen shows related issue link

    After submitting a related issue, you'll see confirmation showing which issue it's connected to.

  • User Interface Confirmation box disabled for active database

    If you select the database you're currently using, the confirmation box is now grayed out to show you can't delete it.

  • User Interface "SQL Server Setup" renamed to "SQL Server Tools"

    The "SQL Server Setup" feature has been renamed to "SQL Server Tools" to better describe what it does.

  • User Interface Lock icon description converter with tests

    Implemented LockIconDescriptionConverter as the single source of truth for tooltip wording, with comprehensive unit tests (LockIconDescriptionConverterTests) that fail if a new icon is added without corresponding tooltip text. The converter returns null for values with no icon (NULL, 'N', 'U'), ensuring blank cells show no tooltip.

  • Architecture DataAgingIndicatorPlanner extended with VendorIsStale and PosIsStale flags

    The DataAgingIndicatorPlanner.Result record now includes VendorIsStale and PosIsStale boolean flags, making it easier for the Data Aging dialog to determine when to show banners without re-evaluating thresholds. Unit tests added to verify the flags match the existing ShowWarning and IsAlarm logic.

  • Architecture Pure data aging decision logic with comprehensive tests

    Extracted a new DataAgingIndicatorPlanner class containing pure, side-effect-free computation of the warning pill's visibility, alarm state, and tooltip text. The planner is fed from application settings and returns a decision record, with 166 lines of unit tests pinning the behavior including threshold comparisons (age >= threshold warns), weekday-only calculations, never-synced cases, and tooltip wording.

  • Architecture Script output parsing service

    A new ScriptOutputParser service uses regular expressions to detect phase headers (>> Step N: ...) and heartbeat lines (still working: label (m:ss elapsed)) from PowerShell script output, enabling the UI to translate technical console streams into structured progress information. The parser scans each appended chunk of output and extracts the last phase and heartbeat label found, which view models then bind to UI elements.

  • Architecture Extracted data aging decision logic into testable planner

    Created DataAgingIndicatorPlanner as a pure, side-effect-free calculation engine for all data aging indicator decisions. The planner is fully covered by 15+ unit tests that pin the exact behavior for threshold comparisons (inclusive), weekday-only vs. calendar aging, never-synced scenarios, tooltip construction, and click-hint display. This separation ensures the title-bar indicator and the Data Aging dialog can share identical logic.

  • Architecture Data aging stale flags exposed in planner result

    The DataAgingIndicatorPlanner.Result record now includes VendorIsStale and PosIsStale boolean flags, allowing the Data Aging dialog to share the exact same staleness logic as the title-bar aging indicator. This ensures both UI elements always agree on whether data is current or needs attention.

  • Infrastructure Unit tests for summary text generation

    Added comprehensive unit tests for BuildSummaryText and HasStepProblems methods, covering successful runs, terminated runs, and various error conditions (load failures, exceptions, no matching data). Tests verify that all error details are included in the copyable summary text.

  • Infrastructure Test coverage for error summary features

    Added comprehensive unit tests that verify the Copy Summary button includes all error details (missing selection values, rounding schemes, step exceptions) and that the HasStepProblems logic correctly identifies when a run must show the summary despite user preferences.

  • Infrastructure Added notification contract tests for SKU exception derived columns

    Added source-level contract tests that verify any code path that reshapes an SKU exception's pricing rule and marks it dirty also notifies the derived "Type" and "Set Future Price to" columns. This prevents future edits from introducing the same display bug.

  • Documentation New Lock Column reference page

    Added comprehensive documentation (docs/marginmaster/pricing/lock-column.md) explaining the lock icon system: what each of the seven padlock symbols means, when they appear, how to interpret blank cells, and how locks relate to SKU-level exceptions and custom groups. Includes a visual key with all seven icons, common questions, and technical details for support.

  • Infrastructure New ScriptOutputParser for structured progress extraction

    Added ScriptOutputParser service that scans PowerShell setup script output for structured markers: ">> Step N: ..." phase headers (from Write-Step) and "still working: label (m:ss elapsed)" heartbeat lines (from Invoke-ChildProcess), converting them into friendly CurrentPhase and PhaseDetail properties for display.

  • Documentation Enhanced SKU-level exceptions and custom groups guides

    Updated sku-level-exceptions.md and custom-groups.md to explain how exceptions and groups interact with the lock icon system, including new sections on "How exceptions run," "The lock icon on the main grid," and expanded troubleshooting for duplicate exceptions and below-cost pricing warnings.

  • Documentation Updated search index and main window orientation

    Added lock icon keywords to the search index (lock icon, padlock, star column, asterisk column, etc.) and updated main-window-orientation.md to include a section explaining the two narrow symbol columns ("*" and "Z") with a reference to the new Lock Column page.

  • Infrastructure Removal of unused VerifyDataAging method

    Removed the legacy VerifyDataAging() method from MainMMViewModel, which had zero callers and implemented an older daily-check pattern. The new title-bar indicator replaces this functionality with continuous passive monitoring.

  • Infrastructure Removed legacy startup data aging dialog

    Retired the VerifyDataAging method that previously showed blocking modal dialogs at startup when data was stale. The new always-visible title-bar indicator provides continuous awareness without interrupting the startup flow, and users can click the pill to access the full Data Aging dialog when needed.

Reporting & Exports

  • Improvement Smarter detection of genuine update failures

    When an update download completes but doesn't take effect on restart (a "swap no-op"), the system now checks whether this is the first attempt for that version or a repeated failure. A first no-op is logged as a warning locally, since the swap usually completes on the next launch. Only when the same target version fails again does the system escalate to an error report on the support dashboard. This change was driven by observing store machines that reported update "failures" on every release cycle yet consistently arrived at each new version within days — their install directories weren't locked, the swaps were simply deferred.

  • Improvement Added logging for missing UPC codes during export

    The export process now logs a warning when SKUs have no UPC code available in either the VendorGTIN or Store tables, showing how many rows were affected. These rows still export with the "XXXXXXXXXXXXXX" placeholder, but the log now provides visibility into data quality issues.

  • Bug Fix UPC column now exports actual values in text exports

    When you export pricing data to NEWRETAILS.txt or other text formats that include UPC codes, the file will now contain the actual UPC numbers instead of showing "XXXXXXXXXXXXXX" for every item.

  • Bug Fix Excel export blank rows with future price substitution

    When printing or exporting to Excel with the "Use Current Price when Future Price = $0.00" option selected, all product information (SKU, description, cost, etc.) now appears correctly instead of showing blank rows.

  • Bug Fix Excel export blank rows with price substitution

    When exporting to Excel with the "Use Current Price when Future Price = $0.00" option checked, items will now show all their data correctly instead of appearing as blank rows.

  • Bug Fix Sentinel cleanup for synchronous apply failures

    When an update apply fails immediately (before the restart), the system now clears the pending-update sentinel and records the failure at the correct location. Previously, a sentinel written before a failed apply would persist and cause the next launch to misclassify the failure as a locked install directory for a swap that was never attempted. This fix applies to all apply paths: the startup version gate, the database setup window's "Download and Install Now" button, and manual update checks from the Help menu.

  • Bug Fix Reconcile obsolete failures before classifying new outcomes

    The system now clears provably outdated failure states before deciding how to classify the current launch's update outcome. When a machine reaches the version it previously failed to install (via repair install, manual installer, or the background service), the old failure counter is reset before the current launch evaluates whether to report a problem. This prevents a machine that has already healed from incorrectly coloring the current launch's verdict.

  • Performance UPC lookup optimized for large exports

    Changed the UPC resolution logic from running two database queries per exported row to a single bulk lookup that processes all SKUs at once in batches of 1,000. This eliminates hundreds or thousands of individual queries during export operations and dramatically improves export speed for files containing UPC columns.

  • Infrastructure Code cleanup in export logic

    Removed obsolete commented-out code from a previous implementation and enabled nullable reference type checking in the PrintViewModel to improve code quality and catch potential null reference issues.

Performance & Reliability

  • Improvement Automatic connection registry cleanup

    When you start Margin Master, it now cleans up your database history by removing entries for databases that have been deleted from the server, but only when it can verify the server is still available.

  • Improvement Added protective duplicate handling to configuration loading

    Enhanced the STORERSC loading logic in the Store Manager to match the same duplicate-handling pattern already used for other configuration entries (existingByOrdinal). This ensures consistent and reliable configuration loading even with imperfect source data.

  • Improvement Enhanced UPC lookup query filtering

    Modified the BuildUpcLookup fallback query to exclude Store rows with NULL or empty UPC values in the WHERE clause. This prevents Entity Framework from attempting to materialize NULL database values into non-nullable string properties, which was the root cause of the exception.

  • Improvement Local server alias consolidation

    If you have multiple connection history entries for the same local database server (due to different naming like "localhost" vs your computer name), these are now automatically combined into a single entry.

  • Improvement Azure SQL compatibility level detection improved

    Compatibility level checks and automatic adjustments now recognize that Azure SQL supports level 160 regardless of its reported 12.0 product version, ensuring optimal query performance for Azure-hosted databases.

  • Improvement Enhanced splash screen cleanup safety

    Both splash screen teardown paths now call SplashScreenManager.CloseAll(force) to guarantee cleanup of any orphaned splash windows, matching the ground-truth force-close approach already used in the async ensure-closed method. The close verification logic was enhanced to check both the service state and the static ActiveSplashScreens registry, ensuring that an orphaned manager (one the service has detached from but is still showing a window) keeps the watchdog timer armed for retry attempts.

  • Improvement Added orphan-aware splash screen cleanup

    Loading screens are now more reliably dismissed when operations complete, even in edge cases.

  • Improvement Strategy summary now shows sitting margin instantly

    The strategy summary dialog now shows your sitting margin and profit impact numbers right away instead of displaying "Calculating..." while you wait.

  • Improvement Automatic cleanup of legacy and problematic indexes

    Existing databases with accumulated performance-draining indexes will be automatically cleaned up when the application starts.

  • Improvement Mi9 recent price change flag now includes 60-day lookback

    Items with recent Mi9 price changes now stay flagged for 60 days after the change takes effect, making it easier to identify recently-changed items in strategies and filters.

  • Improvement Index rebuilds now skip small indexes where fragmentation is noise

    Daily database optimization now focuses on indexes where defragmentation actually improves performance, completing faster.

  • Improvement Added minimum size threshold for index rebuild candidates

    Database maintenance now skips very small indexes that don't benefit from rebuilding, reducing startup time and avoiding unnecessary database locks.

  • Improvement Automatic repair of incorrect seed index definitions

    The index seeding system now detects when a registered index definition has drifted from the current correct version and automatically updates it. This ensures the fleet repairs itself on first startup after update without requiring manual intervention or database scripts. Only affects seed indexes; DMV and SelectionBox-registered indexes are never modified.

  • Improvement Unrecognized tables are now reported separately from obsolete tables

    When optimizing the database, you'll now see two separate messages: one listing obsolete Margin Master tables you can safely remove, and another listing any tables this version doesn't recognize (which won't be touched at all).

  • Improvement Database cleanup now explains what it will remove

    When running database cleanup, you'll now see clear explanations of which tables can be safely removed and which ones the software doesn't recognize, with guidance on what to do.

  • Improvement New main table selection policy with comprehensive tests

    Introduced MainTableSelectionPolicy with 267 lines of tests pinning the exact behavior that prevented store 12180's incident, including how Mi9 single-table mode short-circuits, how grouping fallback resolves, and how leftover Mi9_mainTable tables are ignored in multi-table mode. The policy centralizes logic previously duplicated across DatabaseService1 and StoreDataService with subtle differences.

  • Improvement Service restart only occurs when service was actually running

    Auto-updates will no longer turn on the background service if you had it turned off.

  • Improvement Removed duplicate migration code from Options screen

    Consolidated the schedule migration logic into a single implementation that runs at startup rather than maintaining separate copies in the Options tab. This prevents the two implementations from drifting apart and producing different migration results for the same store.

  • Improvement Strategy comparison snapshots now captured synchronously

    The automatic strategy-comparison snapshot capture (used for before/after analysis) is now awaited during the "Preparing summary..." phase instead of running in the background. This prevents the snapshot from racing with any user actions after the strategy completes, ensuring it captures a consistent view of the pricing results.

  • Improvement Configurable splash behavior for bulk strategy saves

    Added a showSplashOnReload parameter to SaveOrUpdateStrategyToActiveStrategyAsync so callers performing multiple consecutive saves (like Ace Critical Pricing three-step conversion) can suppress intermediate splash displays. Defaults to true (show splash) to preserve existing behavior for single saves.

  • Improvement Strategy comparison captures now feed execution summary

    When viewing the Strategy Execution Summary after a run, sitting margin and profit impact numbers now appear immediately instead of calculating in the background.

  • Improvement Auto-disable repeatedly failing indexes

    Sync and import operations will no longer get stuck repeatedly attempting to build indexes that cannot complete on your system.

  • Improvement Mi9 effective date now available as a grid column and rule criteria

    You can now see the exact date when a Mi9 price change took effect or will take effect by adding the "Mi9 $ Effective Date" column to your pricing grid.

  • Improvement Maintenance now runs under pipeline gate to prevent deadlocks with sync

    Wrapped the OptimizeDatabaseIfNeededAsync call in the heavyPipelineGate semaphore to serialize it with startup sync and strategy runs. The ALTER INDEX REBUILD operations target the same main tables that sync's SyncMainTableCostFields updates, and when the two overlapped SQL Server would pick one as a deadlock victim. Observed cost on 2026-08-20 was 37 seconds lost on a single index rebuild plus retry backoff. The gate already serializes strategy runs against post-processing for this reason; maintenance belongs behind it too.

  • Improvement New policy class for main table selection

    Introduced MainTableSelectionPolicy as a pure-static testable class that centralizes the logic for choosing which main tables to read. All six decision branches are now covered by unit tests pinning the exact customer scenario (Ace store 12180's database state), preventing this class of regression. The policy replaces duplicate code in DatabaseService1 and StoreDataService that had already diverged (StoreDataService was missing the Mi9 single-mainTable guard).

  • Improvement Show Changed Items grid loads with immediate busy indicator

    When viewing changed items after a strategy run, you'll see a "Loading changed items…" message right away instead of a frozen-looking window.

  • Improvement Optimized strategy comparison snapshot capture

    Modified the snapshot capture process to accept pre-computed sitting-margin rows, so callers that need the data for multiple purposes (snapshot storage and summary display) only pay for the expensive scan once. The StrategyComparisonService now provides an overload that accepts already-fetched rows.

  • Improvement Optimization progress now shows on a fixed 0-100 scale

    The startup progress bar now moves smoothly during database optimization instead of jumping around.

  • Improvement Corruption filter now runs before emptiness check

    Table names containing '*' (database corruption) are now filtered out before checking if the list is empty, so a database whose only match is corrupt gets the last-resort fallback instead of an empty list. This ordering is verified by a unit test.

  • Bug Fix Application crash on startup with duplicate RSC assignments

    Margin Master will no longer crash at startup if your store configuration accidentally contains duplicate RSC assignment records. The application will use the first assignment it finds and continue loading normally.

  • Bug Fix Fixed crash on startup with duplicate STORERSC configuration

    The application will no longer crash at startup if your configuration files have duplicate RSC assignment entries for the same store.

  • Bug Fix SQL Express installer crash on advanced format disk detection

    The SQL Express setup wizard will no longer crash on newer computers with NVMe solid-state drives, and will properly detect when special compatibility settings are needed.

  • Bug Fix SQL Express installer crash with strict PowerShell mode

    Fixed a PowerShell array handling issue in the disk sector size detection code that would cause the SQL Express installer and upgrader to crash on systems with strict PowerShell mode enabled. The scripts now properly handle the return value when checking for disks with physical sector sizes larger than 4KB, which is important for SQL Express compatibility.

  • Bug Fix Fixed label printing crash with NULL UPC values

    Fixed a crash that could occur when printing labels for items that don't have UPC codes in your store's database.

  • Bug Fix Resolved cross-thread crash during price level view changes

    Fixed an issue where the price level dropdown could fail to update properly when switching between pricing views, especially during background operations. The list will now refresh correctly in all scenarios.

  • Bug Fix Cross-thread crash in future pricing panel

    Switching between views while working with future pricing will no longer cause the application to crash unexpectedly.

  • Bug Fix Fixed missing embedded setup scripts causing SQL Server installation failures

    If you previously experienced errors when trying to install or upgrade SQL Server Management Studio from the Setup window, this issue is now resolved. The installation scripts are now properly included with the application.

  • Bug Fix Prevented re-entrant close crash in SQL Server Setup window

    Fixed a rare issue where quickly double-clicking the Close button in the SQL Server Setup window could show an error message, even though the window closed properly.

  • Bug Fix SQL Server Setup window close crash eliminated

    The SQL Server Setup window will no longer crash if you accidentally click the close button or X multiple times quickly.

  • Bug Fix Azure SQL customers no longer nagged about outdated versions

    If your store uses Azure SQL Database, you will no longer see daily warnings that your SQL Server is outdated.

  • Bug Fix Strategy runs now block all user input until completion

    When running a pricing strategy, the app will now stay unavailable until the entire process completes and you see the summary, preventing accidental clicks that could interfere with the calculations.

  • Bug Fix Strategy run now blocks all user interaction until complete

    You won't see brief flickers where the app becomes clickable during a strategy run anymore — it will stay locked with the progress screen until all pricing is fully calculated and ready.

  • Bug Fix Application lockup during Ace Critical Pricing save-as-strategies

    After saving Ace Critical Pricing items as pricing strategies, the app will no longer freeze with an unresponsive main window requiring a force-quit.

  • Bug Fix Eliminated orphaned splash screen during Ace Critical Pricing save

    If you saved Ace Critical Pricing settings as pricing strategies, a loading screen could get stuck on your screen and block all mouse and keyboard input, forcing you to close Margin Master from Task Manager. This no longer happens.

  • Bug Fix Prevent automatic index creation on main pricing tables

    Pricing updates and strategy runs will complete much faster, particularly for multi-store groups—one affected store saw zone pricing speed improve from 5 minutes 48 seconds down to 915 milliseconds.

  • Bug Fix Execution summary now displays rounding and change counts for custom groups

    When you run custom groups, the execution summary will now correctly show whether rounding was applied and how many items were changed, making it easier to verify that your pricing updates ran as expected.

  • Bug Fix Custom group rounding display in execution summary

    After running a custom group or SKU exception that applies rounding, the execution summary now correctly shows which rounding scheme was used instead of showing blank.

  • Bug Fix Execute Strategy confirmation dialog now fires only for phantom runs

    When you click Execute Strategy or press Ctrl+X, the pricing run now starts immediately instead of asking you to confirm. The confirmation dialog will only appear if the system detects a suspicious automatic re-run.

  • Bug Fix Database optimization now shrinks before rebuilding indexes

    Startup database maintenance will now complete faster and won't repeat the same work every day.

  • Bug Fix Corrected database maintenance operation order to prevent self-perpetuating rebuilds

    The application will start faster when database maintenance is needed, especially on larger databases. The maintenance process now completes in one pass instead of having to repeat the same work every day.

  • Bug Fix Store table composite index now correctly created

    The RSIX_Store_StoreNumberSKU index, which enables fast lookups by store number and SKU, was never actually created on any database due to a SQL generation bug. The CREATE statement included a guard clause that checked for a column literally named "[StoreNumber],[SKU]" instead of checking for both columns separately, causing the statement to succeed as a no-op while logging "1 created" on every startup. The index is now written longhand and will be automatically created on first startup after update. This index improves performance for store-specific SKU lookups on non-WestLake databases.

  • Bug Fix Database cleanup can no longer destroy unrecognized tables

    If the database cleanup finds tables it doesn't recognize, it will now show you the list and explain that they won't be touched, rather than offering to delete them.

  • Bug Fix Database cleanup no longer destroys unrecognized tables

    If you use "Optimize Database," the cleanup will now only remove tables from old features that are no longer used. Any tables it doesn't recognize will be shown to you in a message but will never be deleted automatically.

  • Bug Fix Selection boxes empty when store grouping misconfigured

    If you turn on "Use Store Grouping" in Options before creating any groups, your selection boxes will still work—the system will use your store's real data and show a warning in the logs.

  • Bug Fix Empty grid when store grouping enabled without defined groups

    If you had store grouping turned on in Settings but never created any groups, the pricing grid would show no items and pricing strategies wouldn't update anything. Now the grid and strategies will work normally using your store's data, and a warning will remind you to either set up groups or turn off grouping.

  • Bug Fix Selection boxes empty when store grouping enabled without groups

    If you accidentally turned on "Use Store Grouping" without setting up groups, your selection boxes will now work correctly instead of appearing empty.

  • Bug Fix Auto-update now detects and avoids locked install folder scenarios

    If an auto-update tries to install while a background import is running, it will now wait and retry on the next launch instead of silently failing to update.

  • Bug Fix Background schedule migration now runs on every startup

    Previously, the migration that converts old separate vendor and POS schedules into the unified Data Update schedule only ran if someone opened the Background Service tab in Options. Since the new Data Update keys default to OFF, stores that upgraded without visiting that screen would silently stop running overnight data updates. The headless service couldn't recover on its own because it only launches when a schedule is active. Now the migration runs on every application launch, both interactive and headless, ensuring all stores migrate successfully.

  • Bug Fix Schedule migration moved to startup to prevent silent update failures

    Your overnight data updates now migrate automatically when Margin Master starts, so vendor catalogs and POS imports continue running on schedule even if you never open the settings screen.

  • Bug Fix Progress indicators now accurately reflect strategy execution status

    The progress bar during strategy runs now correctly shows how much of the entire process is complete, rather than jumping to 100% while steps are still running.

  • Bug Fix Progress bar stays accurate throughout entire run

    The progress bar during strategy runs now shows accurate overall progress instead of jumping to 100% while steps are still processing.

  • Bug Fix Mi9 recent price change flag now remains active for 60 days after effective date

    Items with price changes from Mi9 will now stay flagged as "recently changed" for 60 days after the change takes effect, so your REMOVECHANGE rules will properly protect those prices for the full two-month window.

  • Bug Fix Resolve socket exhaustion during long sync operations

    Long sync operations are now more reliable and won't cause network connection issues on the store computer.

  • Bug Fix Fixed unnecessary global mainTable clearing on per-store POS rebuilds

    After sync completes, dropdown lists (like SKU selection) now populate instantly instead of taking several seconds to reload.

  • Bug Fix Store number dropdown empty for some stores

    The Store dropdown will now populate correctly for all configurations.

  • Bug Fix Strategy comparison snapshot no longer races with user actions

    The automatic strategy-comparison snapshot (when Auto Capture Strategy Results is enabled) now completes fully under the "Preparing summary…" splash instead of running in the background. This prevents the snapshot from reading FuturePrice values that could change if the user started another action immediately after the summary closed.

  • Bug Fix Database optimization no longer deadlocks with startup cloud sync

    Startup will no longer occasionally pause for 30+ seconds when database maintenance and cloud sync run at the same time.

  • Bug Fix Fixed scheduled sync failures on Ace tables with filtered key columns

    Resolved an issue (MM-1398) where scheduled full refreshes were running orphan cleanup on all Ace Hardware tables simultaneously, causing SQL ambiguity errors (SQL 209) on tables where the filter column is also a key column. The sync service no longer force-enables reconciliation during scheduled refreshes since it's now enabled by default with appropriate safeguards.

  • Bug Fix Selection box cache now validates source tables contain data

    Selection boxes that appeared empty due to a temporary configuration issue will now automatically populate correctly after the issue is resolved, without needing manual database cleanup.

  • Bug Fix Splash screen immediately reappears after strategy summary

    After closing the strategy summary, you'll see a "Loading changed items..." message right away instead of a brief moment where the screen appears frozen without explanation.

  • Bug Fix Empty selection boxes not re-scanned after restart

    If selection boxes are empty due to missing data, restarting the application or rebuilding will now correctly re-scan them once data is present.

  • Bug Fix Store group list no longer includes per-store tables in fallback

    Fixed GetGroupList to filter out per-store main tables when store grouping falls back due to missing group tables. Previously would attempt to parse store numbers as group names, creating invalid group entries.

  • Bug Fix Migration retries on failure instead of skipping permanently

    If the migration encounters a transient error (such as database connectivity issues), it deliberately does not mark itself as complete. This allows the migration to retry on the next application launch rather than leaving a store permanently unmigrated and unable to perform background updates.

  • Bug Fix Store group list showing store numbers instead of group names

    GetGroupList now filters to only StoreGroup_{group}_mainTable tables using IsStoreGroupMainTable. Without this filter, the grouping fallback list (which can now include per-store tables like Epicor_12180_mainTable) would have split the table name and invented a store group named "12180".

  • Bug Fix Leftover Mi9_mainTable could be double-counted

    A multi-table Mi9 store caught mid-restructure with a leftover Mi9_mainTable would have double-counted it alongside the real per-store tables (it matches LIKE '%mainTable'). The policy now explicitly excludes the Mi9 single-table name unless the store is actually in single-table mode.

  • Cloud Sync Extended orphan cleanup to all vendor tables by default

    All vendor catalog tables now automatically remove records that vendors have deleted from their systems, preventing issues like printing labels with outdated barcodes.

  • Cloud Sync Improved connection lifecycle management

    Configured the HTTP connection pool with a 10-minute lifetime to balance connection reuse with server-side resource management. Extended the overall request timeout to 5 minutes to accommodate large catalog downloads.

  • User Interface New Mi9 $ Effective Date column

    A new "Mi9 $ Effective Date" column shows exactly when a price change took effect or will take effect, separate from the yes/no flag.

  • User Interface Updated execution summary default text

    Changed the Strategy Execution Summary dialog's sitting margin and profit impact lines from "Calculating..." to "Not calculated" as the default state, accurately reflecting that these metrics are only available when strategy comparison auto-capture is enabled.

  • User Interface Improved maintenance progress reporting with fixed 0-100 scale

    The progress bar during database maintenance now moves smoothly from start to finish instead of jumping around.

  • User Interface Removed artificial delay in selection box tab creation

    Eliminated the 500ms artificial delay that was previously added between each selection box tab during startup, providing a faster and more responsive initial load experience.

  • Database System diagnostics display corrected for Azure SQL

    The System Diagnostics screen now correctly displays Azure SQL edition information when showing database version details.

  • Database Identified 10 obsolete tables safe for removal

    Curated a list of tables from retired features that have been proven to have no remaining readers: legacy Sync Framework artifacts (scope_info, scope_config, schema_info), retired sync-tracking tables (MMVendorData_tracking, VendorGTIN_tracking, Ace_ZonePrice_tracking, Ace_ZonePrice, Ace_Current_tracking), replaced tables (Ace_Levels), and removed features (DIB_Costs). Each entry has been verified to have no creator that still runs and no reader anywhere in the codebase.

  • Architecture Moved sitting-margin telemetry responsibility

    Removed the daily startup sitting-margin telemetry submission (which full-scanned every main table 12 seconds after the splash screen closed) and the post-execution cloud posting. Cloud sitting-margin posting will be moved to the Windows service to run on a schedule without impacting the desktop application's responsiveness.

  • Architecture Implement connection pooling with DNS refresh

    Switched from per-request HTTP clients to a single shared client backed by a SocketsHttpHandler with a 10-minute pooled connection lifetime. This allows DNS changes to be picked up periodically while maintaining connection reuse benefits. Bearer tokens are now set per-request rather than as default headers to safely handle token refreshes during long-running sync operations.

  • Architecture Simplified MMVendorDataBuilder interface

    The BuildMMVendorDataViewAsync method no longer returns a row count that neither caller was reading. The expensive query that produced this unused number has been eliminated, and the method signature changed from Task<int> to Task.

  • Architecture POS import table protection now derives from the POS system enum

    Instead of hand-typing POS prefixes into a static list, the cleanup policy now derives them directly from PointOfSaleSystemTypeEnum, so a newly supported POS system automatically protects its tables—{POS}, {POS}_{store}_mainTable, {POS}_bcp, etc.—the same day it's added. Comprehensive unit tests walk every table name created by SqlTableCreationScripts and every POS in the enum, ensuring no live table can silently fall out of protection if the schema changes.

  • Architecture Added database table classification policy

    Introduced DatabaseTableCleanupPolicy with comprehensive unit test coverage that prevents the allowlist from drifting out of sync with the schema. The policy automatically derives POS table names from PointOfSaleSystemTypeEnum and cross-checks created table names against SqlTableCreationScripts. Two "drift guard" tests ensure newly added tables or POS systems are automatically protected without manual list maintenance.

  • Architecture Synchronized duplicate table resolution logic

    Applied the same fix to both DatabaseService3 and StoreDataService to prevent the two implementations from drifting, ensuring consistent behavior across all consumers of main table resolution.

  • Architecture Added IndexMaintenancePolicyTests to pin size and fragmentation thresholds

    Created a new test suite pinning the 1,000-page minimum and 30% fragmentation threshold. The tests document the regression origin (Aubuchon Mi9, 2026-08-20: 110s rebuilding 54 indexes, 13 of which were too small to benefit) and verify boundary conditions at exactly 999/1000 pages and 30.0/30.1% fragmentation. IndexMaintenancePolicy is a pure static class matching the pattern established by ImportFolderCleanupPolicy.

  • Performance Removed background sitting-margin scans causing slowness

    Margin Master will no longer slow down after running pricing strategies or when first starting up in the morning. Background calculations that were making the app unresponsive have been removed.

  • Performance Removed deferred sitting-margin background scans

    Strategy runs no longer trigger slow background calculations. The Strategy Execution Summary dialog still shows current and future sitting margin plus profit impact, but now displays "Not calculated" when auto-capture of strategy results is disabled in settings.

  • Performance Batched index seeding during startup

    Index seeding now uses a single database connection and pre-reads existing index names before inserting only missing entries, replacing the previous approach that opened a new connection for each index (~276 connection roundtrips on a 23-table store). This eliminates a significant startup bottleneck when all indexes already exist.

  • Performance Batched index registration during startup

    Changed the critical index seeding process to register all indexes in a single database connection instead of opening a new connection for each index. Previously, stores with 23 main tables would make ~276 separate database connections during startup just to check index registration status. The system now builds the full index list first, reads registered indexes once, and inserts any missing registrations in a single batch.

  • Performance Enable compression negotiation for cloud sync

    Cloud sync operations now use less internet bandwidth and may complete faster, especially when syncing large vendor catalogs.

  • Performance Enable compression for cloud sync requests

    Cloud sync operations now transfer less data over the network, making syncs faster and more efficient, especially for large vendor catalogs.

  • Performance Replaced slow MMVendorData health check with fast targeted queries

    Syncs finish several seconds faster—the health check at the end of each vendor sync now completes almost instantly.

  • Performance Optimized orphan record detection in Cloud Sync

    Scheduled vendor catalog syncs now finish much faster. Stores with large Ace Hardware catalogs will notice the most improvement, with sync times reduced by 30+ seconds in many cases.

  • Infrastructure PowerShell array handling consistency

    Applied the comma operator prefix to array returns in disk detection functions, matching the pattern already used in Invoke-SqlQuery. This ensures arrays remain intact across PowerShell versions and strict-mode settings in both Install and Upgrade scripts.

  • Infrastructure PowerShell array syntax correction

    Updated the Get-LargerThan4KSectorDisks function in both install and upgrade scripts to use the comma operator for proper array wrapping, preventing unwinding of single-element arrays that triggered errors in strict mode. This ensures the database installation process completes successfully across all PowerShell configurations.

  • Infrastructure Added automated tests to prevent setup script deployment failures

    Created comprehensive tests that verify all setup scripts referenced by the Guided SQL Server Setup window and Installation Scripts dialog are correctly embedded as resources. These tests check for Install-SQLExpress.ps1, Upgrade-SQLExpress.ps1, Install-SSMS.ps1, Upgrade-SSMS.ps1, Uninstall-SSMS.ps1, Uninstall-SQLServer.ps1, Set-ExecutionPolicy.ps1, Install-DotNetRuntime.ps1, and Install-OleDb12.ps1. The build will now fail immediately if any script is missing, preventing this class of silent deployment failure from recurring.

  • Performance Removed daily sitting-margin telemetry from startup

    The application no longer runs a lengthy background calculation shortly after startup, improving responsiveness when you begin working.

  • Performance Cached selection box blank-row detection

    The "BLANK" option check for each selection box field is now persisted in the SelectionLists cache table during initial build, eliminating the need to scan every main table on warm starts. The cache is automatically cleared when data changes, ensuring accuracy while dramatically reducing repeated database scans during startup.

  • Performance Cached blank value flags in selection boxes

    Selection box lists (Department, Vendor, Category, etc.) now persist their "BLANK" option status in the cache database, eliminating the need to probe every main table for blank values on warm startups. The blank value check (a UNION scan across all main tables) now only runs when the list is freshly rebuilt from actual data, not when loading from cache.

  • Infrastructure Improved diagnostic tracking for duplicate strategy runs

    Added "Unattributed" as an explicit trigger source for strategy runs that reach the execution engine without identifying how they were invoked. This provides the provenance tracking needed to diagnose the intermittent duplicate-execution defect where sessions sometimes produce two pricing runs approximately 52 seconds apart. The CanExecuteStrategy guard already disables the menu item and keyboard shortcut during a run, so any unattributed run is definitively not a UI click and can now be traced accurately.

  • Performance Reuse HTTP connections during cloud sync

    Cloud sync is now more reliable on store machines, especially during long sync sessions, by preventing network connection issues that could interrupt the sync process.

  • Performance Eliminated redundant database query in table resolution

    Hoisted the group table lookup query above the grouping decision branch so the common path reuses the result instead of querying sys.tables twice. This saves a database roundtrip when store grouping is properly configured.

  • Infrastructure Migration logic consolidated to single implementation

    The schedule migration code was moved from BackgroundServiceTabViewModel into MainMMViewModel.BackgroundCoordination.cs and is now called from both interactive startup (MainMMViewModel.InitializeAsync) and headless service runs (HeadlessRunner). This eliminates duplicate code and ensures consistent migration behavior across all launch paths.

  • Infrastructure Safety backup before cleanup

    Before modifying the connection registry, a safety backup is written to DatabaseConnections.json.cleanup.bak, providing a recovery path if manual restoration is needed. The cleanup runs fire-and-forget on a background thread after successful startup validation and swallows all exceptions to ensure it never affects application startup or stability.

  • Infrastructure Reorganized setup script storage location

    Removed duplicate Upgrade-SSMS.ps1 script from the root Scripts folder and consolidated all setup scripts under the `scripts` folder (lowercase) to maintain consistency with the repository structure. This cleanup ensures there's a single source of truth for all PowerShell installation scripts.

  • Infrastructure SQL Server version detection enhanced with engine edition

    Added EngineEdition property to SQL Server version detection queries and telemetry. This allows the application to distinguish Azure SQL from on-premises installations and apply the correct version-support policies to each deployment type.

  • Performance Optimized main table row count checks

    Main table reconciliation now uses a single metadata query against sys.dm_db_partition_stats instead of running individual COUNT(*) queries for each store table (60-120 COUNT(*) operations on multi-million-row tables for large Epicor sites). Falls back to COUNT(*) only when metadata is unavailable.

  • Performance Optimized main table rebuild checks

    Replaced individual COUNT(*) queries for each store's main table with a single metadata query using SQL Server partition statistics. For large multi-store databases (especially Epicor sites), this eliminates 60–120 COUNT(*) operations on multi-million-row tables during startup, reducing the time spent checking which tables need rebuilding.

  • Performance Eliminated duplicate index rebuild pass during startup

    Previously, the managed index rebuild process ran twice in quick succession when both RebuildMainTables and CreateTopPanel steps were queued—once during table rebuild and again a few hundred milliseconds later during selection box build. The first pass is now skipped when CreateTopPanel is also scheduled, since BuildSelectionBoxesAsync performs the same rebuild as part of its comprehensive seed-clean-rebuild sequence. This reduces startup time by eliminating redundant index existence checks and CREATE statements.

  • Infrastructure Comprehensive test coverage for update service interaction

    Added complete test suite verifying the update-service interaction contract, including guards for: both apply paths stopping the service first, failed stops aborting the update, headless imports blocking swaps, restart sentinel being set only when needed, sentinel consumption, and service binary bundling in publish workflow. These source-level tests protect against silent runtime failures that would otherwise be undetectable until machines stop receiving updates.

  • Infrastructure Added tests to verify migration runs on startup

    Created ScheduleMigrationReachabilityTests with four test cases that verify the migration runs in both interactive and headless startup paths, does not remain in the Options tab, and never enables unattended repricing. These tests prevent silent regressions where stores could lose their overnight update schedules.

  • Infrastructure Added migration reachability tests

    New unit tests verify that the migration runs on both interactive and headless startup paths, confirms the Options tab no longer maintains its own copy, and validates that the migration never enables unattended repricing (ExecuteStrategy remains false). These tests prevent regression of the critical migration behavior that keeps stores updating overnight.

  • Infrastructure Removed unsafe legacy cleanup methods

    Removed dead code (SqlServerService.RemoveDeletedDatabasesAsync and SyncDiscoveredInstancesAsync) whose unsafe semantics would have deleted remote server entries and lacked the careful reachability checks implemented in the new cleanup system.

  • Performance Daily-gated DMV index recommendations during startup

    The automatic high-impact index creation from DMV scans is now limited to once per day instead of running during every startup splash screen. Post-strategy-run index recommendations continue to execute normally, ensuring optimal indexes are still created when needed.

  • Performance Gated connection registry cleanup to weekly execution

    The connection registry cleanup process now runs once per week instead of on every application launch. The cleanup probes every SQL Server listed in the connection registry with a 3-second timeout, which caused noticeable delays on machines with stale VPN entries or unreachable servers. Since the registry only changes when connections are modified, weekly cleanup is sufficient.

  • Performance Optimized Ace Hardware zone pricing query

    Modified the Ace zone pricing update script to use an explicit column list instead of SELECT *, allowing SQL Server to use the covering index RSIX_AceZoneRecords_ZoneSku without expensive key lookups. This optimization contributed to the overall 5.7x speedup in zone pricing updates observed in testing.

  • Infrastructure Corrected Mi9 field mapping documentation

    Updated CLAUDE.md and mi9-data-pipeline.md to clarify the positional (not alias-based) mapping of Mi9 user fields, document the UserDatetime1 effective date field, and correct the LastPriceChange field description (populated by Ace enrichment, not available for raw POS data).

  • Infrastructure Added shared row counting utility for sync operations

    Introduced ActiveRowCounter helper class to ensure both the orphan detection gate and existing count-validation logic use identical SQL queries. This prevents drift between the two count methods, which would silently break the optimization's correctness guarantee.

  • Infrastructure Drop order now follows foreign key dependencies

    The cleanup now drops obsolete tables in a curated FK-safe order (children before parents) rather than sorting alphabetically, which previously caused SQL error 3726 by attempting to drop StrategyResultSnapshot before its child StrategyResultSnapshotDetail.

  • Performance Weekly-gated connection registry cleanup

    Connection registry cleanup (which probes every server in the connection list with a 3-second timeout per server) now runs weekly instead of on every launch, using a file-based timestamp gate. Reduces startup overhead for stores with multiple or stale server entries.

  • Performance Gated high-impact index auto-creation to daily execution

    The DMV scan that identifies missing high-impact indexes now runs once per day instead of on every selection panel build (every startup and rebuild). This expensive database scan and potential index creation work is deferred from the splash screen startup window to reduce launch time. Post-strategy index recommendations continue to run immediately after strategy execution.

  • Infrastructure Added IndexMaintenancePolicy class with unit test coverage

    Extracted index rebuild decision logic into a dedicated IndexMaintenancePolicy static class with comprehensive unit tests (IndexMaintenancePolicyTests.cs). Tests pin the 1,000-page minimum and 30% fragmentation threshold, verify boundary conditions, validate the candidate selection and ordering logic, and document the regression origin with real measurements from Aubuchon Mi9. Follows the static-core pattern established by ImportFolderCleanupPolicy.

  • Infrastructure Double-check guard before every DROP TABLE

    DatabaseCleanupService now re-checks the cleanup policy immediately before each DROP TABLE operation, so even if a future refactor passes in the wrong list, no table is destroyed.

  • Performance Deferred post-startup housekeeping tasks

    Heavy background operations like SKU exception description validation and automatic strategy backups now run sequentially in a delayed chain (starting 30 seconds after startup) instead of firing simultaneously during the splash screen. This moves resource-intensive work out of the critical startup path and prevents multiple operations from competing for database resources.

  • Performance Sequenced post-startup housekeeping tasks

    SKU exception description validation and automatic strategy backup now run sequentially 30 seconds after the main window appears, rather than firing simultaneously during startup. This prevents multiple heavy database and cloud storage operations from competing during the busiest part of application launch.

Infrastructure & Internal

  • New Feature Guided SQL Server Setup Window

    A new "Guided SQL Server Setup" button on the Database Setup screen walks you through installing or upgrading SQL Server—you no longer need to run PowerShell scripts manually.

  • New Feature Guided SQL Server Setup wizard

    Use Tools > SQL Server Setup to install or upgrade SQL Server through a step-by-step wizard that automatically detects what's on your computer and recommends the right action. You'll see live progress as the installation runs and be notified if a restart is needed.

  • New Feature Database Migration Between SQL Server Instances

    After installing a new SQL Server instance, you can now use "Migrate Database" (from the Tools menu or the success screen button) to move your Margin Master data onto it. The tool automatically backs up your database, moves it to the new instance, and optionally cleans up the old copy.

  • New Feature Migrate Database between SQL Server instances

    After installing a new SQL Server instance, you can use the "Migrate Database" option to move your Margin Master data from an old instance to the new one. The tool shows only your Margin Master databases, handles the technical details automatically, and keeps a backup file for safety.

  • New Feature Delete Database utility in SQL Server Setup

    You can now safely remove old Margin Master databases from Tools > Delete Database in the SQL Server Setup screen. The tool automatically backs up the database before deleting it and requires you to type the database name to confirm—the active database cannot be deleted from here.

  • New Feature Delete Database utility in SQL Server Setup

    IT staff can now safely remove old Margin Master databases through the SQL Server Setup window. The tool prevents accidental deletion by requiring you to type the database name exactly, won't let you delete the active database, and creates a backup first (enabled by default).

  • New Feature Service health monitoring and heartbeat

    The background service now reports its health to the cloud automatically, making it easier for support to diagnose scheduling issues without needing your log files.

  • New Feature Service heartbeat to cloud

    The background service now checks in with the Manager every hour (adjustable by the server), reporting its version, enabled state, job schedules, and last run results. This solves the "silent failure" problem where a stopped, crashed, or misconfigured service is indistinguishable from one that simply has no work scheduled. On startup, the service checks in immediately so new installs and restarts are visible right away. The heartbeat continues even during long-running imports so the service never appears dead.

  • New Feature Unified Data Update job replaces separate Vendor and POS schedules

    Overnight data updates are now faster because POS and vendor data are imported together in one process instead of two separate runs.

  • New Feature Remove Empty SQL Server Instances

    Once you've moved all databases off an old SQL Server instance, you can remove that empty instance directly from the "SQL Server Instances" list using the "Remove..." button. The system prevents removing any instance that still has databases or wasn't originally installed by Margin Master.

  • New Feature Remove empty SQL Server instances

    After moving all your databases off an old SQL Server instance, you can now remove that empty instance directly from the SQL Server Setup window to free up disk space and simplify your setup.

  • New Feature Remote log upload command

    If support needs to troubleshoot an issue, they can now request your diagnostic logs remotely instead of asking you to find and email files from your computer.

  • New Feature Remote command channel

    Support can now send time-limited commands to a specific store's background service through the Manager. The service polls for commands during each heartbeat, executes them, and reports results back on the next check-in. Commands are an allow-list of known operations the service already implements—anything unrecognized is rejected as unsupported rather than attempted. This channel is designed to never disrupt scheduled operations; all failures are logged and swallowed.

  • New Feature Optional scheduled pricing strategy execution

    You can now schedule your pricing strategy to run automatically after the overnight data update, so future prices are ready each morning without manual intervention.

  • New Feature Tools menu: SQL Server Instances viewer

    You can now view all SQL Server instances on your computer from the Tools menu, including which one Margin Master uses.

  • New Feature Remote log collection

    When you contact support about background service issues, they can now retrieve diagnostic logs remotely without needing to ask you to find and send files.

  • New Feature Optional automatic strategy execution after data updates

    The overnight data update can now automatically run your pricing strategy after importing data, so new prices are ready when you open the store.

  • New Feature Automated script resolution with version skew protection

    Setup scripts are resolved through a three-tier fallback (Azure blob → local cache → embedded resource) with parameter compatibility checking. If a cached or downloaded script is older than the app build and missing required parameters like -LogFile or -NonInteractive, the system automatically falls back to the embedded version to prevent silent parameter-binding failures.

  • New Feature Tools menu: Re-check, diagnostics, and log folder

    The Tools menu now has shortcuts to re-scan your computer, copy diagnostic info for support, and open the setup log folder.

  • New Feature Tools menu with SQL Server instance inspector

    You can now view all SQL Server instances on the computer via Tools > SQL Server Instances to see which ones belong to Margin Master and which belong to other applications.

  • Improvement Faster SQL Server instance detection

    The "Checking this computer" step is now much faster, especially on machines with multiple SQL Server instances or many databases.

  • Improvement Start stopped SQL Server instances

    If a SQL Server instance is stopped, you can now start it directly from the instance list without manually using Windows Services.

  • Improvement Start stopped SQL Server instances

    If you see a stopped SQL Server instance, you can now click "Start Instance" to start it and verify whether it's being used by Margin Master.

  • Improvement Streamlined removal confirmation flow

    When a SQL Server instance is successfully removed, the progress window now closes automatically and displays a clear confirmation message before returning to the instances list. This provides clearer feedback that the operation completed. Failed removals continue to keep the log window open for troubleshooting.

  • Improvement Instant reconnection after database migration

    When migrating a database to another SQL Server, you no longer need to restart Margin Master. The app reconnects to the moved database instantly and continues working.

  • Improvement Connect after migration now defaults ON

    When moving a database, Margin Master will now automatically connect to it when the move completes.

  • Improvement Same-day installation script logs attached to issues

    If you run database installation or SSMS setup scripts and then report a problem the same day, those installation logs are now automatically included with your support ticket to help diagnose setup issues faster.

  • Improvement Automatic script log attachment to support issues

    If you install or upgrade SQL Server or SQL Server Management Studio and then report a problem the same day, the installation logs will automatically be included with your support ticket to help our team diagnose the issue faster.

  • Improvement Unified data update with single rebuild

    Overnight data updates now complete faster because the system rebuilds your pricing data once instead of twice.

  • Improvement Startup self-heal upgrades legacy service permissions

    If you installed the background service before this update, Margin Master will automatically upgrade its permissions the next time the app starts (one-time elevation prompt) so future uninstalls work correctly.

  • Improvement Startup self-heal upgraded to detect missing delete permission

    The startup self-heal that ensures the background service has proper permissions now checks for all three required rights: start (RP), stop (WP), and delete (SD). Services installed before this change had only start/stop and will be upgraded automatically. Added ApplicationSettingKey.BackgroundServiceFullGrantOk to track the upgraded grant; the old BackgroundServiceStartStopGrantOk key is superseded but retained for backward compatibility.

  • Improvement New Default Instance Name: MARGINMASTER

    New SQL Server installations will use the instance name "MARGINMASTER" to avoid conflicts with other applications that may use "SQLEXPRESS."

  • Improvement Intelligent instance ownership detection

    The detection service queries each installed SQL Server instance to determine ownership by checking for Margin Master database signatures. Instances with at least one Margin Master database and no foreign databases are classified as "MarginMaster-owned" and eligible for in-place upgrade. All others are treated as foreign and never modified. Offline instances are safely classified as unknown/foreign to prevent accidental modification.

  • Improvement Hidden child installer windows in non-interactive mode

    The SQL Server installer no longer shows extra console windows popping up during installation.

  • Improvement Clearer migration completion messages

    After migration completes, the message now clearly tells you whether Margin Master will connect to the migrated database when you restart.

  • Improvement System Diagnostics now shows Azure SQL edition

    The System Diagnostics screen now displays "Azure SQL" or "Azure SQL MI" for the database version label when connected to Azure-hosted databases, instead of showing an incorrect SQL Server year version.

  • Improvement Launch attribution now distinguishes desktop usage from background automation

    License check-ins now include LAUNCHSOURCE (Desktop, Service, Manual, or Restore) and LAUNCHJOB (Vendor, Pos, Updates) fields. This allows the server to separate actual store usage from scheduled overnight imports and updates, providing accurate usage metrics in the fleet dashboard. The context is set at startup in App.OnStartup before any API calls can occur.

  • Improvement Day-of-week scheduling replaces interval-based schedules

    You now pick which days of the week scheduled jobs run (Monday, Tuesday, etc.) and what time they run at, making it easier to plan around your store's schedule.

  • Improvement Added comprehensive test coverage for update-service interaction

    Added source-level contract tests that verify the update process correctly stops the background service before swapping files, aborts if the stop fails, only restarts the service if it was actually running, checks for blocking processes, and ensures the service binary is included in published builds. These guards prevent silent update failures that would otherwise be invisible at runtime.

  • Improvement Intelligent SQL Instance Ownership Detection

    The setup wizard now accurately identifies which SQL Server instances belong to Margin Master, ensuring other applications' databases are never touched.

  • Improvement Smart upgrade vs. fresh install decision logic

    The planner automatically decides between in-place upgrade (when a single, older, Margin Master–owned Express instance exists alone on the machine) and side-by-side fresh install (when foreign instances exist, multiple instances exist, or the MM instance is non-Express). This prevents the scripts from attempting upgrades in unsupported scenarios and ensures clean installations when needed.

  • Improvement SQL Restore Progress and Database Readiness

    Enhanced SqlRestoreService to surface SQL Server's "percent processed" InfoMessage events as live progress updates during restore operations, and to explicitly set restored databases to MULTI_USER mode with a readiness wait loop (up to 30 seconds) to ensure the database is immediately usable after restore completes. Fixed a bug in SqlExpressMigrationService where restored databases were incorrectly named after the timestamped backup filename instead of the intended database name due to a missing RenameTo option.

  • Improvement SQL restore now surfaces live progress and ensures database readiness

    Database restore operations now show real-time progress percentages and won't finish until the database is fully ready for use.

  • Improvement Store identity from legacy GlobalFileConfig is preserved during migration

    Enhanced GetStoreSettingsAsync to read ApplicationSettings first as the source of truth, then gap-fill from GlobalFileConfig only when ApplicationSettings values are blank. Previously, the method only read GlobalFileConfig (which it deletes on every startup), causing 109 of 134 surveyed databases to resolve a blank vendor and drop all Ace/Do it Best entities from the data model. Disagreements between the two sources are now logged as warnings, with ApplicationSettings winning and the legacy row removed.

  • Improvement Day-and-time scheduling replaces interval-based model

    Scheduled jobs are now configured by picking days of the week and a time, making it easier to set up overnight automation that matches your store's routine.

  • Improvement Enhanced PowerShell Scripts with Non-Interactive Mode

    Install-SQLExpress.ps1 and Upgrade-SQLExpress.ps1 gain new parameters: -LogFile (starts a transcript for live tailing), -NonInteractive (auto-answers confirmation prompts per safe defaults), -ApplySectorWorkaround (consents to the 4K sector alignment fix), and -ReuseExistingBackups (upgrade only, skips re-backup if backups already exist). Scripts now report results via [MM-RESULT] markers that the app parses to auto-select the newly installed instance. Exit code contract: 0 = success, 3010 = reboot required, 20 = sector workaround consent needed.

  • Improvement Non-Interactive SQL Uninstall Script

    Updated Uninstall-SQLServer.ps1 to support fully automated operation for the guided setup window, adding parameters for -InstanceNames (bypassing the interactive menu), -AllowEmptyRemoval (permitting removal of instances with zero databases), -LogFile (transcript for real-time tailing), and -NonInteractive (suppressing all console prompts). In non-interactive mode, safe prompts auto-answer Yes while risky prompts (continue without backup, continue after failed backup) answer No and exit with code 1. Child processes (setup.exe) now run with hidden windows and emit transcript heartbeat messages every 20 seconds during long silent phases. Exit codes standardized to 0 (success), 3010 (reboot required), or 1 (failure or ownership guard rejection).

  • Improvement Uninstall script supports non-interactive automation and heartbeat logging

    The Uninstall-SQLServer.ps1 PowerShell script now accepts -NonInteractive, -InstanceNames, -AllowEmptyRemoval, and -LogFile parameters for automated removal workflows. In non-interactive mode safe prompts auto-answer Yes while risky prompts (continue without backup, continue after failed backup) answer No and exit with code 1. Long-running child processes (setup.exe uninstaller) now emit heartbeat messages every 20 seconds so transcript readers can distinguish active progress from hangs.

  • Improvement Post-deletion refresh in SQL Server Setup

    After a database deletion completes, the SQL Server Setup window automatically re-scans all instances to update their ownership classifications, such as marking an instance as "Empty" if the last Margin Master database was removed.

  • Improvement Destination server auto-selected after migration

    After moving a database, the server that received it is automatically selected so you can connect right away.

  • Improvement Adaptive polling interval for responsive command execution

    The service normally checks in once per hour, but the server can request faster polling (down to 30 seconds) while commands are outstanding. This makes remote support requests feel immediate without maintaining persistent connections or requiring inbound firewall rules. The minimum interval is enforced client-side to prevent server bugs from creating request loops.

  • Improvement Background job status now tracks destructive rebuild phases

    Added an IsDestructivePhase flag to the BackgroundJobStatus table to distinguish between safe ingest operations (writing vendor/POS tables) and destructive rebuilds (dropping and recreating main tables and selection lists). This allows startup, the background service, and monitoring tools to make safe decisions about when to wait versus when to proceed. The flag is set during main table and selection list rebuilds and cleared during ingest and upon job completion.

  • Improvement Server Scanner Now Finds Registry-Installed Instances

    The server list now automatically finds your SQL Server instance even if it has a custom name like MARGINMASTER.

  • Improvement Live script output tailing with file watcher

    The elevated script runner tails the PowerShell transcript in real time using a FileSystemWatcher, marshaling log updates through the WPF dispatcher so users see progress immediately. Previously, script output was only visible after completion.

  • Improvement Mutually exclusive detection and execution layouts

    Detection, plan review, execution, and result phases are now strictly mutually exclusive via the ShowExecution binding. The execution layout (step list + dark console panel) stays hidden during detection to prevent visual artifacts.

  • Improvement Leading zeros in store numbers now normalized consistently

    Store number comparisons throughout identity validation and renumbering detection now use a single normalization method (StoreIdentityRepairPolicy.Normalize) that preserves leading zeros only when the entire value would otherwise collapse to empty string. This prevents false mismatches when the licensing server returns store numbers with different zero-padding than what's stored locally.

  • Improvement Contact phone number now migrates from legacy storage

    Added migration support for contact phone numbers, which were previously never read from GlobalFileConfig and therefore remained stranded there permanently while email and contact name had migrated to ApplicationSettings. Phone numbers are now reconciled along with other store information on startup.

  • Improvement New database creation writes identity to ApplicationSettings

    InitializeNewMarginMasterDatabaseAsync now writes store number, vendor type, and POS system to ApplicationSettings instead of GlobalFileConfig during database creation. This ensures newly created databases have their identity in the correct location from the start, matching where the running application reads it.

  • Improvement Settings access for service identity

    Extended BackgroundSettingsStore to read application settings by their raw property names (StoreNumber, RetailerSoftVendor, PCGUID) so the service can gather the identity information needed for check-ins, since those values are persisted by the WPF app under non-enum keys.

  • Improvement Enhanced run attribution and history tracking

    The run history now clearly shows when the scheduled data update changed your prices, making it easier to track overnight pricing changes.

  • Improvement In-window sector workaround consent flow

    When a SQL setup script exits with code 20 (sector workaround needed for older installers), the wizard displays an inline decision prompt explaining the issue and allows the user to consent or decline, then re-runs the script with -ApplySectorWorkaround if approved. This replaces the previous Read-Host prompts that couldn't be used in hidden/elevated scripts.

  • Improvement Database credential merge now updates ApplicationSettings

    The credential merge operation in DatabaseSetupViewModel now writes reconciled store identity to ApplicationSettings instead of GlobalFileConfig. Previously it updated About and GlobalFileConfig but never ApplicationSettings, which allowed the two copies to drift apart over time.

  • Improvement Post-setup instance auto-selection

    After a successful SQL installation or upgrade, the Database Setup window automatically refreshes the server list and selects the newly installed/upgraded instance, allowing users to proceed directly to database creation or restore without manual server selection.

  • Improvement Enhanced Install-SQLExpress.ps1 with new parameters

    The install script now supports -LogFile for transcript routing, -NonInteractive to suppress Read-Host prompts (required for hidden execution), -InstanceName override (defaults to MARGINMASTER), and improved sector workaround handling with exit code 20 for consent requests.

  • Improvement Enhanced Upgrade-SQLExpress.ps1 with backup reuse option

    The upgrade script now accepts -ReuseExistingBackups to skip fresh backup creation when acceptable pre-upgrade backups already exist, -LogFile, and -NonInteractive for wizard integration. Result marker lines ([MM-RESULT] Instance=... Server=...) allow the wizard to extract the upgraded instance details programmatically.

  • Bug Fix Uninstall now removes background Windows service

    When you uninstall Margin Master from Windows Apps & features, the background Windows service is now properly removed instead of being left behind on your computer.

  • Bug Fix Uninstall now removes background service

    When you uninstall Margin Master from Windows settings, the background service is now removed automatically. Previously, the service would remain on your computer after uninstall.

  • Bug Fix SQL installer crash on database-heavy systems

    Fixed a PowerShell array-wrapping bug in the SQL Express installer's ownership-check logic that caused crashes on systems with many databases. On instances with 170+ databases, the bug generated "identifier too long" SQL errors by concatenating all database names together. On instances with no databases, it threw PropertyNotFoundStrict exceptions that failed the "Remove Empty Instance" step during discovery. The fix corrects six call sites across Install, Upgrade, and Uninstall scripts. Since failures occurred during the discovery phase, no data was ever modified.

  • Bug Fix Manual catalog SKU additions now succeed in new databases

    Manually adding SKUs to vendor catalogs will now work correctly without silent failures.

  • Bug Fix Setup scripts now properly embedded in installer

    SSMS and .NET Runtime installation will now work reliably even when your computer is offline or the cloud backup is temporarily unavailable.

  • Bug Fix Azure SQL Database incorrectly flagged as outdated

    If your store uses Azure SQL Database or Azure SQL Managed Instance for hosting, you will no longer see warnings about running an unsupported or outdated version of SQL Server.

  • Bug Fix Store identity now protected from cross-tenant license responses

    If your store information ever appeared to change to a different company's store number after a network interruption, this issue is now fixed. Your store identity will remain stable even during connectivity problems.

  • Bug Fix Store identity now reads from single authoritative source

    Fixed a critical issue where store identity (store number, vendor, RSC code, POS system) was stored in both GlobalFileConfig and ApplicationSettings but only partially synchronized between them. A survey of 134 customer databases found all still carrying duplicate POSTYPE entries, 62 carrying duplicate STORENAME, and four stores with actively conflicting identities (including one Ace store incorrectly configured as Do it Best, causing it to use the wrong database tables). ApplicationSettings is now the single authoritative source, with automatic reconciliation on startup that preserves data and logs warnings when conflicts are detected.

  • Bug Fix License validation now rejects responses for different stores

    If the licensing service accidentally returns information for a different store, Margin Master will now reject it and keep your existing license instead of changing your store identity.

  • Bug Fix Headless background jobs now wait for license check-in before exiting

    Previously, scheduled imports that completed in under 30 seconds would exit before their license check-in POST reached the server, causing them to not appear in the fleet dashboard. The headless runner now waits up to 10 seconds for the check-in to complete, ensuring all background runs are properly recorded regardless of how fast they complete. Found when Great Lakes Ace and Breed & Company showed "1 launch today" despite having five scheduled service runs and zero interactive launches.

  • Bug Fix Silent updates now wait when app is open

    Updates will no longer fail silently when you have Margin Master open. The background service now waits until you close the app, and your open session will install updates automatically.

  • Bug Fix Background service now detects open app sessions before starting updates

    The background service's silent self-update would previously attempt to swap application files while a user had Margin Master open. Because Velopack cannot replace folders used by a running process, updates would silently fail and the machine would remain on the old version indefinitely. The service now uses a machine-wide presence marker to detect interactive sessions and defers updates until the app is closed, allowing the app's own hourly update check to handle installations while in use.

  • Bug Fix Auto-update now waits for headless imports to complete

    When the background service launches a headless import (MarginMaster.exe --data-update), that import process holds the installation directory open for its entire duration. Previously, if an update was ready to apply during an import, it would stop the service but proceed with the file swap anyway. Because the headless import child process continued running even after the service stopped, the swap would fail silently—reporting success but actually making no changes—leaving the machine stuck on the old version indefinitely. The update system now detects when another Margin Master process is running from the install folder and defers the update until the next launch after the import completes.

  • Bug Fix Cleanup of orphaned SQL Server Agent services

    SQL Server's uninstaller sometimes leaves the SQL Server Agent service registration behind after removing an instance (observed on SQL 2025 Standard). The removal script now automatically deletes these orphaned Agent service registrations after verifying the engine service has been successfully removed.

  • Bug Fix Clean up orphaned SQL Server Agent service after instance removal

    The uninstall script now detects and removes orphaned SQL Server Agent service registrations that SQL setup sometimes leaves behind after uninstalling an instance (observed with SQL 2025 Standard). The cleanup only runs when the engine service is confirmed removed, ensuring safe deletion.

  • Bug Fix Database list refreshes after migration or deletion

    The list of available databases now updates automatically after moving or deleting a database.

  • Bug Fix Fixed case-sensitivity issue in scripts folder

    Normalized file paths for setup scripts that were tracked under a capital-S `Scripts/` folder while other scripts used lowercase `scripts/`. On Windows these appeared identical but caused the cloud upload process to miss certain files. All scripts are now consolidated under the lowercase `scripts/` directory.

  • Bug Fix Store renumbering now prevents cross-vendor overwrites

    If your store was accidentally configured with the wrong vendor's store number, the automatic repair system will no longer incorrectly overwrite your actual store information across multiple database tables.

  • Bug Fix Restore missing store identity from legacy configuration

    Added fallback logic to recover store identity from GlobalFileConfig when ApplicationSettings is blank, rather than leaving the store permanently unconfigured. Previously, if ApplicationSettings lacked a store number, the application could never recover it and would only display the Store Configuration window. The reconciliation now seeds ApplicationSettings from the legacy row when needed, then removes the duplicate to prevent future conflicts.

  • Bug Fix Short headless runs now register in fleet dashboard

    Fixed an issue where fast scheduled imports (under ~30 seconds) would exit before their license check-in completed, causing these runs to not appear in the fleet dashboard at all. The app now waits up to 10 seconds for the check-in to complete before shutting down. Longer imports were already counted because they naturally took long enough for the background post to finish.

  • Bug Fix Startup no longer crashes when opening during background rebuild

    If you launch Margin Master while a background import is rebuilding data, the app will now wait and show you the rebuild progress instead of opening with blank or incomplete pricing tables.

  • Bug Fix App startup now waits for destructive rebuild phases to complete

    If you open Margin Master while a background update is rebuilding data, you'll see a progress message on the startup screen instead of an empty or partially-loaded grid.

  • Bug Fix Failed uninstall no longer leaves instance stopped

    If removing a SQL Server instance fails, the instance will be automatically restarted so it remains usable and visible in the list.

  • Bug Fix Service restored after failed instance removal

    If removing a SQL Server instance fails, the service will automatically restart so your system is left as it was before the attempt.

  • Bug Fix Active database deletion now shows immediate feedback

    If you try to delete the database Margin Master is currently using, you'll now see a clear message explaining that you need to switch to another database first.

  • Bug Fix Live database switching disabled during first-run setup

    Database migration during initial setup now completes smoothly without freezing.

  • Bug Fix PC registration now uses persistent computer ID

    Fixed GetPCGUID to read the persisted ComputerSettings.PCGUID value instead of generating a fresh random GUID on every license request when the MM_PCGUID machine environment variable was absent (which it always was). This was causing every license validation to register as a new PC against the store's licensed computer count rather than recognizing returning installations.

  • Bug Fix Service no longer launches pointless update checks every cycle

    Stores running automatic background updates will no longer waste resources checking for updates that don't exist. The service now correctly tracks which version is installed.

  • Bug Fix Installed version now updates from headless runs

    The recorded installed version was only written during interactive app startups. On machines where the background service handled all updates and no user opened the app, the recorded version remained frozen at the last manually-opened build. This caused the service's update pre-check to detect a "newer" version every cycle and launch the full app only to be told it was already current. Headless runs now update the installed version marker, eliminating unnecessary update checks.

  • Bug Fix Service restart sentinel now correctly gated

    Refined the logic that records whether the background service should be restarted after an update. The sentinel is now set only when a service that was actively running is stopped for the update, preventing updates from quietly enabling a service the user intentionally left disabled.

  • Bug Fix SDDL parser now correctly identifies delete permission

    The SDDL rights parser now splits the rights string into two-character codes before checking for "SD" (delete), preventing false positives when the substring "SD" spans code boundaries (e.g., "RSDT" is RS + DT, not R + SD + T). Updated unit tests confirm the parser correctly rejects legacy start/stop-only grants and malformed rights strings.

  • Bug Fix Script log documentation updated

    Issue submission documentation now describes the three-bucket auto-attachment system: application logs, strategy execution logs, and same-day installation script logs. Search keywords updated to include "strategy execution logs", "installation script logs", and "script transcript".

  • Bug Fix Manual catalog insert now explicitly provides CreateDate

    Updated the INSERT statement for manual catalog items to explicitly provide GETDATE() for CreateDate as a defensive measure, ensuring the operation succeeds even if the DEFAULT constraint is somehow missing.

  • Bug Fix Vendor resolution now reads from ApplicationSettings instead of deleted rows

    If certain features or data weren't working correctly for Ace Hardware or Do it Best stores, this fix restores proper vendor-specific functionality by ensuring your vendor type is correctly identified.

  • Bug Fix Store renumbering now requires vendor agreement

    The automatic store renumbering feature (MM-1395) now verifies the licensed vendor matches the database's vendor before re-pointing a store to a new number. A renumbering only happens within the same vendor family. This prevents a license response for a different company's store from stamping their identity across StoreManagerInfo, GlobalFileConfig, and About tables, which would destroy all copies of the real store's identity. Ace Hardware and Emery Jensen are treated as one vendor family since EJ stores are carried as Ace in the vendor tables.

  • Bug Fix SQL Express migration now renames restored databases correctly

    Fixed SqlExpressMigrationService to pass RenameTo: dbName in RestoreOptions. Previously the restored database inherited the timestamped backup file's name (e.g., "MyDb_PreMigration_20260816_143022") causing subsequent verification and compatibility-level steps that connected using the original dbName to fail.

  • Bug Fix Prevented premature job firing on first enable

    The IsDue calculation now walks back 0..6 days instead of 0..7, preventing a never-run job from treating "last week's occurrence" as overdue and firing immediately when enabled. A dedicated test pins this behavior, ensuring that enabling a 02:00 schedule at midday does not trigger an import in the middle of a working day.

  • Bug Fix SQL Server detection now recognizes all named instances

    Fixed DatabaseService3.IsSqlServerInstalledAsync and SqlServerScannerService to detect any MSSQL$ service prefix (covering MARGINMASTER, SQLEXPRESS, and custom names) instead of only checking for MSSQLSERVER and MSSQL$SQLEXPRESS. This prevented machines with only a MARGINMASTER instance from being recognized as having SQL Server installed.

  • Bug Fix RSC code reads and writes corrected across the application

    Fixed DatabaseUpdateService.RSCCode property and CleanMMVendorData method to read from ApplicationSettings.RSC instead of the legacy GlobalFileConfig row that GetStoreSettingsAsync deletes on every startup. Previously, reading the deleted row meant setting the RSC here had no effect, and the MMVendorData cleanup was being skipped on migrated databases.

  • Cloud Sync Azure SQL engine edition reported to fleet telemetry

    License validation now reports the SQL Server engine edition (SQL_ENGINEEDITION) to fleet telemetry, allowing Manager to distinguish between Azure SQL Database, Azure SQL Managed Instance, and on-premises editions for support and monitoring purposes.

  • User Interface Faster instance detection with live progress

    The setup window now shows what it's checking in real-time and runs much faster on computers with many databases.

  • User Interface Heartbeat timer during SQL Server setup

    During SQL Server installation or upgrade, the setup window now shows how long each step has been running and reassures you that long silent phases are normal and still progressing.

  • User Interface Heartbeat status updates during SQL Server installation

    When installing or upgrading SQL Server, the setup window now shows how long each step has been running and displays "still working" messages during long quiet periods so you know it hasn't frozen.

  • User Interface Success confirmation after removing SQL Server instance

    After successfully removing a SQL Server instance, you'll now see a confirmation message and return to the instances list automatically, making it clearer that the removal completed.

  • User Interface Optional automatic connection to migrated database

    A new checkbox lets you tell Margin Master to use the migrated database automatically when you restart the application, even if you're currently working with a different database.

  • User Interface Clearer "cannot upgrade in place" explanation

    The setup wizard now clearly explains why a new SQL Server instance is being installed instead of upgrading your existing one.

  • User Interface Fixed busy indicator display during detection

    The setup window shows a proper busy indicator while checking your computer and no longer appears frozen during detection.

  • User Interface Hidden child installer windows in non-interactive mode

    Installer windows no longer flash on screen during SQL Server setup, making the installation process cleaner and less distracting.

  • User Interface Visible Refresh buttons added

    You can now refresh the SQL Server instance list using the Refresh button at the bottom of the window instead of closing and reopening it.

  • User Interface Refresh buttons added to SQL setup screens

    You can now click "Refresh" to update the list of SQL Server instances after making changes to your system.

  • User Interface Updated migration checkbox label for clarity

    The Migrate Database window now clearly indicates that the connection switch happens immediately when the move completes.

  • User Interface Progress updates during script log collection

    Both the full Submit Issue wizard and Quick Issue Submit dialog now display "Collecting installation script logs..." and "Uploading installation script logs..." status messages during the attachment process, providing visibility into this new automatic step.

  • User Interface Database documentation indexed for search

    Added the SQL Express vs. Full License guide to the documentation index with comprehensive search keywords covering common symptom searches like "slow performance," "50 GB limit," "database size cap," and "when to upgrade SQL Server," making it discoverable through the in-app help system.

  • User Interface Clearer detection summary with labeled sections

    The "What we found" section is easier to read, with SQL Server and Management Studio status shown on separate labeled lines.

  • User Interface Enhanced removal workflow feedback

    After a successful instance removal, users now see a confirmation dialog stating "Instance 'X' was successfully removed" and are returned to the refreshed instances list, making the outcome of the operation immediately clear.

  • User Interface Multi-stage confirmation workflow

    The Delete Database dialog implements progressive disclosure with instance selection, database dropdown (showing only verified Margin Master databases), backup checkbox (default on), and a text field requiring exact database name entry. Visual warnings appear if the selected database is currently active. A red header and warning text emphasize the destructive nature of the operation.

  • User Interface Delete Database dialog with confirmation workflow

    The delete tool walks you through choosing a server and database, asks if you want a backup first, and requires typing the database name exactly before the Delete button activates.

  • User Interface Issue submission progress messages for script logs

    Both the full Submit Issue wizard and Quick Issue Submit dialogs now display "Collecting installation script logs..." and "Uploading installation script logs..." status messages when script transcripts are found and attached. This upload occurs after the standard application log attachment and before database backup/additional file uploads.

  • User Interface Automatic window closure after successful migration

    After moving a database, the migration windows close automatically and Margin Master loads your data from the new location right away.

  • User Interface Redesigned Background Service settings panel

    The Background Service settings screen is simpler and shows exactly what your overnight update will do and when it will run next.

  • User Interface Improved status text clarity

    Status messages throughout the setup process are clearer and easier to understand.

  • User Interface Migrate Database Button on Setup Success Screen

    After installing a new SQL Server instance, the success screen now shows a "Migrate a Database..." button to help you immediately move your data onto the new instance.

  • User Interface Post-installation guidance links migration tool

    After the setup finishes installing a new SQL Server instance, a "Migrate a Database" button appears to guide you through moving your data onto the new instance.

  • User Interface Inline Sector-Workaround Consent Dialog

    If your hard drive needs a special compatibility fix during SQL installation, the setup window will ask for your permission before applying it—no hidden prompts.

  • User Interface Redesigned Background Service settings screen

    The overnight automation settings are now simpler to configure, with clear day-of-week checkboxes and plain-English descriptions of when jobs will run.

  • User Interface Database Setup Window Quick-Launch Buttons

    You can launch the guided SQL Server setup from multiple places: the Database Setup screen, the File menu under Utilities, or the Support Scripts window.

  • User Interface SQL Server Setup menu item and buttons

    Added "SQL Server Setup" to the Tools > Support menu in the main window and as a button in the Database Setup window's SQL Server and SSMS sections, providing multiple entry points to the guided setup flow.

  • Database Schema creator now honors default value constraints

    The MigrationBasedSchemaCreator now emits DEFAULT constraints (both SQL expressions and literal values) when creating tables, ensuring NOT NULL columns like CreateDate have working defaults. Includes culture-invariant formatting for bool, string, DateTime, and enum defaults.

  • Database Startup migration heals missing CreateDate default

    Added a startup migration that detects and repairs ManualCatalogItems tables created without the CreateDate DEFAULT constraint, preventing insert failures in databases created prior to this fix.

  • Database Store identity writes now update correct storage location

    Fixed four code paths that were writing store identity to GlobalFileConfig instead of ApplicationSettings: database setup, database creation, RSC code updates, and POS system changes. These writes were being silently discarded on the next startup when the per-startup cleanup removed the GlobalFileConfig entries, causing settings to appear saved but then vanish. All identity writes now go to ApplicationSettings where the running application reads them.

  • Database Compatibility level correctly set for Azure SQL

    Database compatibility level logic now recognizes Azure SQL can use level 160 (SQL 2022 feature set) regardless of its reported product version, ensuring optimal query performance and feature availability.

  • Database Automatic cleanup of legacy store identity configuration

    Added a versioned migration that removes residual store identity entries from GlobalFileConfig once ApplicationSettings contains valid data. The cleanup backs up removed data to GlobalFileConfigBackup first and includes safety checks: it refuses to run when ApplicationSettings has no store number (preventing deletion of the last surviving copy of a store's identity), and only marks itself complete on success so failed deletions retry on next startup rather than leaving orphaned data.

  • Database Added destructive-phase tracking to background job status

    Added `IsDestructivePhase` flag to the `BackgroundJobStatus` table to distinguish between safe ingest phases (which write vendor/POS tables the grid never binds to) and destructive rebuild phases (which drop and recreate main tables and selection lists). The distinction matters because ingest can safely run underneath an open app and can take ten minutes—making users wait through that would be its own bug. The flag is set by actual phase transitions rather than matching phase text, so renaming a step cannot break the data-corruption guard. Includes idempotent ALTER for stores that already have the table.

  • Database New settings keys for unified schedule and migration flag

    Added ApplicationSettingKey entries for the Data Update job configuration (enabled, days, time, last run, include POS, include vendor, execute strategy) and for the day-based schedules for the updates job. Added BackgroundScheduleMigrated flag to track when old per-job schedules have been converted to the new unified model. Vendor and POS keep their enum values so historical run-history rows still render, but nothing schedules them anymore.

  • Architecture ApplicationSettings is now the single source of truth for store identity

    Consolidated store identity management so ApplicationSettings is the authoritative source for store number, vendor type, RSC code, POS system, and store name. License responses no longer overwrite these values—they only confirm them or fail validation. Previously, these values were written to three locations (ApplicationSettings, GlobalFileConfig, and About table) with no reconciliation, causing stores to disagree with themselves. A survey of 134 databases found all carried both copies, with four actively disagreeing (including one with mismatched vendors causing incorrect entity resolution).

  • Architecture Introduced LaunchContext ambient for process-wide launch metadata

    Created LaunchContext static class to hold AppLaunchSource and background job name, set once during startup and readable by license validation. Uses the same ambient pattern as MarginMasterVersionSettings to provide launch attribution without requiring dependency injection in low-level services.

  • Architecture Single rebuild for combined data sources

    The post-processing queue now supports deferred draining, allowing both POS and vendor imports to queue their rebuild steps before draining once. This is the core architectural change that enables the unified Data Update job: both ingests contribute to the same queue, which deduplicates and drains in a fixed order, producing exactly the union of both rebuilds in a single pass. The headless runner suppresses post-processing drains during import steps and explicitly drains once after both sources have contributed.

  • Architecture Decision-Tree Planner with Unit Test Coverage

    Introduces SqlSetupPlanner, a pure-logic component (17 unit tests in SqlSetupPlannerTests) that maps detected SQL environments to ordered script steps. The planner enforces product rules: upgrade only single MM-owned Express instances in place; never touch foreign instances; always install side-by-side when multi-instance or non-Express; SQL steps before SSMS steps. Behavior is pinned by tests to prevent regression.

  • Infrastructure SQL Server Express edition limits documentation

    Created new documentation explaining SQL Server 2025 Express limitations (50 GB database cap, 4 cores, 1.4 GB buffer pool, no SQL Agent) versus full licensed editions. Includes a comparison table, guidance on when stores have outgrown Express based on symptoms like slow performance during peak hours or multi-store deployments, and clarifies that the 2025 edition's increased size cap (up from 10 GB) doesn't change compute restrictions. Indexed for support staff and end users researching database performance issues or upgrade decisions.

  • Infrastructure DevExpress component update

    Updated DevExpress.Wpf and DevExpress.Document.Processor from version 26.1.3 to 26.1.4. This maintenance update includes the latest bug fixes and stability improvements from DevExpress for the UI grid controls, dialogs, and document processing components used throughout Margin Master.

  • Infrastructure nsoftware component version update

    Updated nsoftware.IPWorks to build 9722 and nsoftware.IPWorksSSH to build 9716, with corresponding updates to runtime license stamps in licenses.licx. These components handle FTP and SFTP vendor file downloads.

  • Infrastructure Launch attribution for scheduled background jobs

    Behind-the-scenes improvement that helps RetailerSoft better understand how stores are using Margin Master versus how often automated background jobs are running.

  • Infrastructure PowerShell strict-mode compatibility

    Removed double array-wrapping around Invoke-SqlQuery results that caused incorrect iteration behavior under Windows PowerShell 5.1 strict mode. Plain assignment now correctly binds the inner row array across all zero, single, and multi-row result scenarios.

  • Infrastructure Database fingerprint safety verification

    The delete operation performs dual fingerprint verification—once when populating the database list and again immediately before dropping—to ensure only genuine Margin Master databases can be deleted. The service counts core Margin Master tables (Store, Item, PricingRule, etc.) and requires a minimum match threshold before allowing deletion.

  • Infrastructure Database fingerprint verification for deletion safety

    Implemented database verification logic that checks for the presence of core Margin Master tables (Item, Store, Vendor, etc.) before allowing deletion. Only databases that match the Margin Master signature with a minimum number of core tables can be selected for deletion, preventing accidental deletion of unrelated databases.

  • Infrastructure Script log collection service added

    New ScriptLogCollector service consolidates script transcript discovery across three different app locations (%TEMP%\MarginMaster\InstallationScripts\Logs, %TEMP%\MarginMaster\ScriptLog_*.txt, and C:\ProgramData\RetailerSoft\MarginMaster\DiagnosticTool\Logs\Scripts). Only logs written on the requested date are collected, ensuring relevance to same-day issues. Handles locked files gracefully by reading with FileShare.ReadWrite and deduplicating entry names when multiple sources contain identically-named files.

  • Infrastructure Automated license drift detection

    Added IPWorksLicenseBuildTests to fail the build if nsoftware package versions are bumped beyond what the runtime licenses cover. Previously, this mismatch would only surface as connection failures at runtime; now it's caught during development. The drift check now runs in all configurations, not just DEBUG builds, and reports failures during startup validation before any vendor sync attempts.

  • Infrastructure Uninstall hook logging

    The Velopack OnBeforeUninstallFastCallback hook now logs sc.exe stop and delete exit codes to UninstallHook.log in the ProgramData log folder, which survives uninstall. This provides a forensic trail for diagnosing service-removal failures and replaces silent failures that previously hid orphaned services.

  • Infrastructure Uninstall hook now logs service removal outcomes

    The Velopack uninstall hook now writes detailed outcomes (sc.exe exit codes, access denied errors, success/failure) to UninstallHook.log in the ProgramData log folder. This file survives uninstall and provides a forensic trail for troubleshooting orphaned services, since Serilog is not yet configured inside uninstall hooks.

  • Infrastructure Invoke-ChildProcess helper for setup scripts

    Added a new PowerShell helper function that starts child processes with proper window hiding in non-interactive mode and polls for completion while writing periodic heartbeat messages to the transcript. This ensures long-running silent phases (media extraction, VC++ install, SQL setup) remain visible to both the UI (via transcript) and the user (via status bar timer).

  • Infrastructure Heartbeat logging in PowerShell scripts

    The Install-SQLExpress.ps1 and Upgrade-SQLExpress.ps1 scripts now include an Invoke-ChildProcess function that writes heartbeat lines to the transcript every 20 seconds during long child processes, ensuring the UI transcript reader can distinguish between silent execution and hung processes.

  • Infrastructure Documentation update for attachment workflow

    Support documentation updated to describe the three script log sources, same-day collection logic, shared-access file reading for locked transcripts, and best-effort upload behavior.

  • Infrastructure Added automated tests to prevent silent script embed failures

    Created SetupScriptEmbeddedResourceTests that verify all setup scripts referenced by the installer (Upgrade-SSMS.ps1, Install-SQLExpress.ps1, Install-DotNetRuntime.ps1, etc.) are properly embedded with the exact resource names the resolver expects. This prevents the embed glob from silently breaking in future builds due to path changes or git case-folding issues.

  • Infrastructure Dependency updates

    Updated Entity Framework Core from 10.0.10 to 10.0.11, Microsoft.Extensions.* packages from 10.0.10 to 10.0.11, MySqlConnector from 2.6.1 to 2.6.2, and various other supporting libraries (NuGet.*, Sep CSV parser, ClosedXML, xunit test runner). These updates include security patches and bug fixes from upstream packages.

  • Infrastructure Added comprehensive tests for launch attribution mapping

    LaunchAttributionTests pins the command-line-to-attribution mapping and validates that enum member names match what the server accepts. This prevents silent reclassification if either side changes - job names travel as text so new background jobs require no database migration, but renaming would split history into two separate entries on the dashboard.

  • Infrastructure Comprehensive test coverage for launch attribution

    Added 115 lines of tests to verify that each launch scenario (desktop, scheduled service, manual "Run Now", and silent updates) is correctly identified and reported. This ensures usage metrics remain accurate as new background job types are added and prevents scenarios where automated activity is miscounted as user engagement.

  • Infrastructure Command execution framework with security boundaries

    Implemented a command dispatcher with a fixed allow-list of supported operations. Commands name operations the service already implements and never carry executable payloads. Authentication uses store and vendor numbers rather than sensitive credentials, so the system is designed with limited blast radius. Unrecognized commands are reported as unsupported (not failed) so services running older builds are distinguished from broken ones. Commands expire automatically and all execution happens asynchronously without blocking scheduled jobs.

  • Infrastructure Automatic pre-delete backup with abort on failure

    When backup is enabled (the default), the service creates a timestamped backup file (e.g., MyStore_PreDelete_20260816_143022.bak) before deletion. If the backup fails for any reason, the deletion is aborted and the database remains untouched. The backup file is retained even after successful deletion to allow recovery if needed.

  • Infrastructure Removed obsolete standalone SSMS upgrade script

    Deleted stale root-level Scripts/Upgrade-SSMS.ps1 file. All resolver calls now use the correct version located in the SqlScripts/Powershell subdirectory.

  • Infrastructure DiagnosticTool cleanup

    Removed unused nsoftware package references from MarginMaster.DiagnosticTool. The tool wasn't using these components and was unnecessarily shipping licensed assemblies.

  • Infrastructure Command dispatcher and token authentication

    Created a command routing system that matches incoming command types to their handlers and enforces expiration times. The service authenticates to the Manager using store number and vendor ID to obtain short-lived bearer tokens (cached and auto-refreshed). Uses the same fallback URL list as the main app to handle Azure deployments and network issues gracefully.

  • Infrastructure Added cross-session presence detection

    Introduced a new `InteractiveSessionPresence` marker using a Global mutex that the background service (running in session 0) can see when an interactive user (in session 1) has the app open. The existing single-instance mutex was session-local and invisible across session boundaries. Includes full test coverage (62 new tests) and fail-safe behavior—if the marker cannot be created or checked due to permissions, it reports "nobody is there" and degrades to previous behavior rather than blocking unattended operations.

  • Infrastructure Settings migration preserves existing schedules

    Existing per-job vendor and POS schedules are automatically migrated into the unified data update configuration once on first launch: all seven days are selected (preserving daily behavior), the earlier of the two configured times is used, and the ExecuteStrategy option is set to false unconditionally. The migration ensures no store begins scheduled repricing without explicit consent, even when upgrading from configurations that previously ran separate vendor and POS jobs.

  • Infrastructure MySql.Data version pin documentation

    Added explicit documentation that MySql.Data remains pinned at 6.10.9 as the legacy fallback driver behind the UseMySqlConnector toggle. This clarifies that it is not on the routine update path and will only be removed once migration to MySqlConnector is complete.

  • Infrastructure Token-based authentication for service API

    The service acquires and caches bearer tokens for API authentication using store number and vendor ID, refreshing them before expiration. Includes automatic fallback between primary and backup API endpoints, with preference for whichever worked last time to minimize calls on healthy systems.

  • Infrastructure Added cross-session presence marker using Global mutex

    Introduced InteractiveSessionPresence utility that uses a Global\ mutex to signal when an interactive Margin Master session is open. Unlike the existing single-instance mutex (which is session-local), this marker is visible to the background service running in session 0. The implementation gracefully degrades to local-only scope if SeCreateGlobalPrivilege is unavailable and fails to false (reports "not present") if the marker cannot be read, ensuring permission issues never block legitimate operations.

  • Infrastructure Shared Script Resolution and Elevated Execution Services

    Extracts script resolution (blob download → local cache → embedded fallback) into SetupScriptResolver and elevated PowerShell execution with live log tailing into ElevatedScriptRunner, replacing duplicated logic in DatabaseSetupViewModel and ScriptProgressViewModel. Includes parameter-capability probing: if a cached/blob script predates required parameters like -LogFile, it is replaced by the embedded copy to prevent silent failures.

  • Infrastructure Legacy GlobalFileConfig store identity rows are cleaned up

    Added CleanUpStoreIdentityGlobalFileConfigAsync migration that removes SETTINGS/STOREINFORMATION rows from GlobalFileConfig once ApplicationSettings holds the store's identity. This cleanup runs after GetStoreSettingsAsync reconciles the values, ensuring no data loss. The cleanup version flag is excluded from settings transfer to prevent a transferred "already done" flag from suppressing cleanup on a database that still needs it.

  • Infrastructure Comprehensive test coverage for schedule logic and planner

    Added BackgroundScheduleTests to verify day-of-week schedule evaluation, including edge cases like DST boundaries, never-run jobs, and daily schedules. Added DataUpdatePlannerTests to prove what a scheduled data update does given its configuration, including the critical safety case that a strategy-only configuration (no data sources) is refused to prevent unattended repricing.

  • Infrastructure Command-line interface supports unified data update

    The headless runner now accepts --data-update to run the full configured update in one process. The legacy --import-vendor and --import-pos flags are retained as support escape hatches for diagnostics, but the scheduler only invokes the unified command. Post-processing drain suppression allows both imports to queue steps into a single rebuild operation.

  • Infrastructure Support Documentation

    Adds new guided-setup support doc (marginmaster/support/sql-server-setup-window.md) with screenshots and troubleshooting steps, plus updates to install-sql-express.md and upgrade-sql-express.md documenting the new script parameters and exit codes. Index entries link the new content.

  • Infrastructure Comprehensive unit test coverage for setup planner

    Added SqlSetupPlannerTests with 19 test scenarios covering all decision branches: clean machine, single old instance upgrade, multi-instance side-by-side install, foreign instance handling, offline instance classification, instance name collision fallback (MARGINMASTER → MARGINMASTER2 → MARGINMASTER3), SSMS ordering, and answer handling (ReuseExistingBackups switch).

Other Changes

  • New Feature Sensitivity Score engine

    The system now analyzes which departments are most sensitive to price changes based on your actual sales volume, helping identify where to be careful with price increases versus where you have more flexibility.

  • New Feature Do it Best Awareness Code E support

    Added support for Do it Best Awareness Code "E" (Commodity), mapped to the 25-point bottom rung alongside "D" (Low Awareness). OneClick query now captures "E" separately and the sensitivity engine scores it as low-awareness volume eligible for margin improvement. This aligns with Do it Best's five-tier awareness system.

  • Improvement One Click auto-recovers from empty table selection

    If no pricing tables are selected, One Click will now automatically analyze all available tables instead of showing blank results.

  • Bug Fix Old version uninstall dialogs now open correctly

    When Margin Master detects an old version at startup, the uninstall prompt will now appear properly on your screen instead of being hidden or causing an error.

  • Bug Fix Fixed sensitivity score calculation SQL error

    Corrected a SQL alias mismatch in the sensitivity scoring engine that referenced "x.Code" instead of "codes.Code" for both Ace Hardware and Do-it-Best vendors. This bug could have caused sensitivity scores to be calculated incorrectly or fail to execute during margin analysis.

  • Bug Fix Statistics display on One Click dialog open

    When you open the One Click dialog, you'll now see the correct item counts right away instead of all zeros.

  • Bug Fix One Click Statistics populate on initial load

    When you open One Click Statistics, the numbers now show up right away instead of showing all zeros until you click a checkbox.

  • Bug Fix OneClick Pricing Sensitivity Mix labels corrected

    The Pricing Sensitivity Mix panel on OneClick now shows the correct labels for each sensitivity category—previously "Sensitive" and "Blind" were backwards for Ace stores.

  • Bug Fix Fixed Print button binding in One Click screen

    Corrected a typo in the Print button command binding ("PrintClickComand" to "PrintClickCommand"). This was a latent bug as the button is currently disabled.

  • User Interface Strategy Comparison sensitivity columns

    Strategy Comparison now shows which departments and classes are most price-sensitive, with higher scores meaning customers are more aware of price changes in those categories.

  • User Interface Improved One Click dialog initialization

    The dialog now calls PopulateCurrentStoreAsync during initialization to ensure statistics are visible immediately, since the checkbox toggle handlers only refresh data on change events, not on initial state.

  • Architecture Sensitivity scoring test coverage

    Added comprehensive unit tests locking the sensitivity-score contract: shared 25-100 rung mappings for Ace and Do it Best, units-weighted scoring math, null-when-no-assigned-volume behavior (never zero), additive roll-ups enabling class-to-department aggregation, and Blind/Sensitive share calculations. Tests ensure code changes (like moving DIB "E" to the 25 rung) are intentional and verified.

  • Infrastructure New thread-safe modal dialog handler

    Introduced ShowModalSafeAsync method to safely display modal dialogs from background startup tasks. This ensures the splash screen is verifiably closed and all dialogs are opened on the UI thread, preventing both threading violations and unreachable dialogs blocked by the splash screen.

RockSolidCloudSyncAceHardware
2026.821.38968
August 22, 2026

Release notes aren't available for this version.

2026.821.27571
August 21, 2026

Release notes aren't available for this version.

2026.821.785
August 21, 2026

Release notes aren't available for this version.

2026.820.24918
August 20, 2026

Release notes aren't available for this version.

2026.820.18712
August 20, 2026

Release notes aren't available for this version.

2026.819.39755
August 20, 2026

Release notes aren't available for this version.

2026.818.39569
August 19, 2026

Release notes aren't available for this version.

2026.817.38458
August 18, 2026

Release notes aren't available for this version.

2026.816.31181
August 16, 2026

Release notes aren't available for this version.

2026.815.39391
August 16, 2026

Release notes aren't available for this version.

2026.814.38443
August 15, 2026

Release notes aren't available for this version.

2026.813.38101
August 14, 2026

Release notes aren't available for this version.

2026.812.36690
August 13, 2026

Release notes aren't available for this version.

2026.811.41670
August 12, 2026

Release notes aren't available for this version.

2026.810.37001
August 11, 2026

Release notes aren't available for this version.

2026.810.22480
August 10, 2026

Release notes aren't available for this version.

2026.731.41011
August 10, 2026

Pre-flight check warns about incomplete pricing rules before strategy execution; Better error detail sharing; Non-blocking validation allows saving work-in-progress exceptions.

Strategy & Pricing

  • New Feature Pre-flight check warns about incomplete pricing rules before strategy execution

    Before running a strategy, you'll now be warned if any custom groups or SKU exceptions are set up incorrectly and won't price anything, with details about what needs to be fixed.

  • Improvement Better error detail sharing

    Long lists of excluded location codes can now be copied with one click instead of being typed manually from the screen.

  • Improvement Non-blocking validation allows saving work-in-progress exceptions

    When warned about incomplete exceptions, you can choose to save them anyway to finish the work later—the system will check again before actually running your pricing strategy.

  • Improvement Enhanced save-time validation message for pricing groups
  • Improvement Automatic repair offer on screen open

    If you open the screen and have groups with margin percentages in their names but no margin settings, the system will offer to fill in the missing margins automatically, making it easier to fix broken groups right away.

  • Improvement Enhanced reliability for SKU-Level Exceptions screen

    Saving and closing the SKU-Level Exceptions screen will work reliably, even if the system encounters internal messaging issues.

  • Improvement Close-time validation runs after save prompt

    Both manager screens now run their validation checks after the save/discard prompt rather than before, ensuring the checks work on what's actually stored in the database. This prevents the confusing scenario where you discard unsaved changes but still get warnings about problems that no longer exist, or miss warnings about problems you just saved.

  • Improvement Save button now explains when there's nothing to save

    If you click Save and nothing happens, you'll now see a message explaining why—either there are no changes, or you need to click out of the box you just typed in.

  • Bug Fix Restored missing price level comparison options

    When creating pricing strategy steps, the standard price levels (Retail, Level1, Level2) now always appear in the "compare to" dropdown, even if you're using a custom column view. Previously, these options could disappear if your view showed certain price columns, which caused pricing steps to stop working.

  • Bug Fix Custom Group margin percentages now save correctly

    When you type a margin percentage into a custom group, it will now save properly instead of disappearing.

  • Bug Fix SKU exception validation now warns on incomplete pricing rules

    If you save a SKU exception without filling in all the pricing details (like choosing "Margin %" but not entering a percentage), you'll now see a warning telling you which SKUs won't be priced. You can still save the incomplete rule to finish later, but you'll know it won't work until completed.

  • Bug Fix Automatic margin recovery from group names at save time
  • Bug Fix Custom Groups manager detects and repairs incomplete rules on close

    If you close the Custom Groups screen with groups that have names like "25%Margin" but no actual margin set, Margin Master will now offer to set the margin for you based on the name. This prevents pricing rules from silently failing to apply.

  • Bug Fix Manage Custom Groups screen crash on open

    The Manage Custom Groups screen will no longer crash when opening. If you have groups that need pricing repairs, you'll see the repair prompt after the window appears.

  • Bug Fix Cancelled pricing runs no longer count as completed runs

    If you cancel a pricing run before it starts, the app will no longer ask if you want to run it "again" on your next attempt.

  • Bug Fix Resolved pricing strategies that compared against missing levels

    Existing pricing strategies that compare current price to standard levels like "Level1" now work correctly, even when those levels aren't visible in your current column view.

  • Bug Fix Price levels no longer dropped when re-saving custom groups or SKU exceptions

    Custom groups and SKU exceptions will keep their configured price levels even if you can't see that price level in your current view settings.

  • Bug Fix SKU Exceptions manager reports incomplete rules on close

    If you try to close the SKU Exceptions screen with exceptions that won't actually price (missing margin, markup, or price level), Margin Master now shows you which SKUs have problems and lets you stay on the screen to fix them instead of silently failing later.

  • Bug Fix Custom groups now preserve their cost basis setting when saved

    Custom pricing groups will now keep their cost basis setting (like Average Cost) when you make changes and save the group.

  • Bug Fix Rounding scheme selection no longer causes save failures

    The Save button will work correctly even if a custom group uses a rounding scheme that's not available on your computer.

  • Bug Fix Error icon updates after changes

    Error icons now correctly appear and disappear as you fix or break pricing groups, keeping the display accurate.

  • Bug Fix Repair prompt timing improved

    The prompt offering to fix custom groups with no price level now appears at a better time—after the window is visible but before user interaction begins. The prompt is displayed at application idle priority so the window paints fully first, and is protected against WPF's re-parenting behavior that could cause it to appear multiple times. A failure in the repair offer itself can no longer prevent the screen from opening.

  • Bug Fix Saved rounding schemes no longer overwritten by global default

    Custom groups and SKU exceptions will remember the rounding scheme you chose for them instead of switching to the default rounding scheme.

  • User Interface Copy button for strategy load errors

    When a pricing strategy error appears showing excluded location codes, click the new Copy button to copy all the details to your clipboard instead of manually typing them out.

  • User Interface Copy button added to Strategy Step Load Error dialog

    When you see a Strategy Step Load Error, you can now click the Copy button to copy the entire error message, then paste it into an email or support ticket instead of manually typing it out.

  • User Interface Repositioned Copy button in load error dialog

    When an error occurs during strategy execution, the Copy button now appears at the bottom right, just below the error message box, making it easier to understand that clicking it will copy the error details shown above.

  • User Interface Copy button repositioned in error dialog

    When you see an error dialog during strategy execution, the Copy button now appears at the bottom right, next to the action choices and directly under the error message box, making it easier to understand what text will be copied.

  • User Interface Immediate error display for broken pricing groups

    Broken pricing groups now show a red error icon immediately when you open the screen, with a message explaining what's wrong. You don't need to open each group or wait until closing to find problems.

  • Database Added validation logic for pricing rule completeness

    Created new MissingPriceLevelDetector helper class with 35 unit tests to analyze saved rule text and determine if a rule can produce a price. This logic is pure and reusable, working directly from the stored rule format rather than UI state, making it reliable for both save-time validation and pre-flight checking.

  • Architecture New MarginNameParser utility with comprehensive test coverage

Other Changes

  • Improvement Enhanced update failure state reconciliation timing

    Moved obsolete update failure cleanup to run before classifying the current launch's update state, ensuring that machines which have already successfully updated don't carry stale failure markers that would incorrectly influence the current launch's error reporting level.

  • Bug Fix Eliminated false-positive update failure alerts for self-healing stores

    Stores that successfully update but take an extra app restart to complete the process will no longer show up as "update failed" on support dashboards.

  • Bug Fix Fixed misreported update failures from version gate and database setup

    The version gate check during startup and the update-from-database-setup-window path were leaving behind "pending update" markers when the update failed to apply, causing the next launch to incorrectly report a locked install directory for an update that was never attempted. Both paths now clear the pending marker and record the failure at the actual point of failure.

  • Infrastructure Added comprehensive update health policy test coverage

    Added six new tests in UpdateHealthPolicyTests that replay real store occurrence sequences, including Store 12233's self-healing deferred updates and Store 12082's genuinely locked installation scenarios.

2026.808.40347
August 9, 2026

Release notes aren't available for this version.

2026.808.26435
August 9, 2026

POS data completeness validation; Import completeness verification with user confirmation; Update warning dialogs now show specific version information.

Strategy & Pricing

  • Improvement Zone assignment logging added to pricing updates

    Support staff can now see exactly which pricing zone was used for your store in the application logs, making it easier to troubleshoot pricing questions.

  • Improvement Unrounded pricing steps now flagged in execution log

    The strategy run summary now warns if pricing steps might produce unrounded prices like $12.63, which happens when a step calculates a price but has no rounding rule applied.

  • Improvement Self-comparison fallback now logs a warning

    When a comparison field cannot be resolved, SelectionService.StepQuerySQL still falls back to comparing the column to itself (a safe no-op), but now logs a warning identifying the filter and operator involved. This ensures MM-1367-type failures leave a diagnostic trace instead of silently pricing nothing.

  • Improvement Enhanced error logging for comparison field failures

    Added warning logs in SelectionService when a pricing filter has a comparison operator but no valid comparison value, helping diagnose cases where rules fail to load properly due to missing price levels in the current view.

  • Improvement Added comprehensive test coverage for column view scenarios

    Added six new automated tests covering edge cases including single-column views, mixed price column views, and the exact Ace Hardware customer configuration that triggered the original failure (a view containing only Ace_MapPriceAmt). All tests verify that saved strategy operands correctly resolve regardless of column view configuration.

  • Bug Fix Custom groups without price levels now warn before saving

    When saving a custom group, you'll now get a warning if it's active but has no price level selected. Previously these groups looked complete but never priced anything when the strategy ran.

  • Bug Fix Custom groups with no price level now reported in strategy run summary

    If a custom group can't run, the strategy summary now shows why it was skipped instead of leaving it out.

  • Bug Fix Strategy rules no longer drop comparison fields silently

    If a pricing rule compares to a column that isn't available in your current view (like Level1 or Retail), you'll now see an error message instead of the rule silently pricing nothing.

  • Bug Fix Strategy rules now preserve comparison fields when loading

    If you save a pricing strategy that compares against a specific price level (like Ace Level1 or Zone Retail), then switch to a different view that doesn't show that price level, the strategy will now alert you to the problem instead of silently pricing nothing.

  • Bug Fix Ace zone pricing now applies automatically during import

    If your store uses Ace or Emery Jensen zone pricing, your catalog will now show the correct prices for your assigned zone immediately after import, without needing to open the Store Manager screen first.

  • Bug Fix Built-in price levels now always available for strategy comparisons

    If you have pricing strategies that compare current price to Retail, Level 1, or Level 2, those comparisons will now work correctly even if you've customized your column view to hide those price columns from the grid.

  • Bug Fix Strategy run summary now reports steps that price without rounding

    The strategy run summary now shows which pricing steps calculated prices without rounding them. This helps catch mistakes where unrounded prices overwrite rounded ones.

  • Bug Fix Warning when saving custom groups without a future price level

    When saving a custom group that's missing its price level, you'll now get a warning that it won't price anything when the strategy runs.

  • Bug Fix Built-in vendor price levels now load correctly from saved rules

    Saved pricing rules that compare to vendor levels (like Ace Level1 or Zone Retail) will now load and re-save correctly without losing the comparison field.

  • Bug Fix Vendor price level entries now correctly match saved rules

    Fixed the built-in vendor price level entries (Retail, Level1, Level2, Zone Retail, Zone Level1, Zone Level2) to carry their canonical field names. Previously these entries displayed as "Ace Level1" but had no field name stored, so when a rule saved the canonical "Level1" token, it couldn't match on reload. This mismatch caused the comparison operand to be dropped entirely.

  • Bug Fix Prevented duplicate price level entries in comparison lists

    Enhanced field name matching to prevent the same price column from appearing twice in comparison pickers when both the column view and built-in list offer it. The user's custom display label (from Field Name Mapping) now takes precedence, with the built-in entry filling the gap only if the column view doesn't already supply that field.

  • Bug Fix Bulk-apply rounding now correctly updates steps that had no rounding

    Using "Set Rounding for Active Steps" now actually adds rounding to steps that didn't have it before, instead of silently doing nothing.

  • Bug Fix Consistent zone selection when multiple store records exist

    When multiple Store Manager records resolve to the same POS store number (such as a vendor-matched store plus a locally-discovered store under the same number), the system now uses a deterministic order to select which record's zone to apply: preferring records with an assigned zone, then those with a vendor store number, then the oldest record. Previously, the selection was arbitrary and could result in inconsistent zone assignments.

  • Bug Fix Apply rounding to all active steps now correctly enables rounding flag

    Applying rounding to all steps now works correctly even on steps that previously had no rounding scheme.

  • Data Import Improved store number matching for zone assignments

    Zone assignment now handles store numbers with and without leading zeros correctly (e.g., "017644" and "17644" are recognized as the same store). The system uses numeric matching on both sides and gracefully skips non-numeric store numbers rather than failing the entire assignment process.

  • User Interface Enhanced strategy execution summary with configuration issue reporting

    The Main Table strategy execution summary now includes two new diagnostic sections: one listing custom groups that were skipped due to configuration issues (with reasons), and another identifying pricing steps that wrote unrounded calculated prices. These sections appear only when relevant issues are detected, providing visibility into previously silent failures.

  • Architecture Added UnroundedPriceStepDetector helper class

    Introduced logic to determine whether a strategy step computes a price arithmetically and writes it without rounding, used for flagging potentially problematic configurations while filtering out legitimately rounding-free rules to maintain signal quality.

  • Infrastructure Added comprehensive tests for comparison field resolution

    Added 9 new tests in SelectionBoxDetailTests covering the exact MM-1367 failure condition (level absent from view must report failure), vendor-prefixed label resolution, numeric "Manual" comparisons, and round-trip correctness. Six of these tests fail against the previous code, confirming the bug and the fix.

  • Infrastructure Automated tests added for zone assignment logic

    Added comprehensive test coverage to ensure the zone backfill process only writes vendor-assigned zones (never user overrides), handles deleted records correctly, matches store numbers properly, and performs no-op updates when zones are already correct. These tests prevent regression of the MM-1368 fix.

Imports & POS

  • New Feature POS data completeness validation

    The app now checks that the data it received from your point of sale is complete before updating your prices, preventing situations where a dropped connection would accidentally erase most of your items.

  • New Feature Import completeness verification with user confirmation

    If an import is interrupted or only partially succeeds, Margin Master now asks you to confirm before replacing your data, explaining exactly which stores failed and what will happen if you continue.

  • Improvement Connection string password redaction in logs

    All POS connection strings are now redacted before being written to logs, stripping passwords while preserving server, database, and user ID for support diagnostics. Prevents accidental disclosure of SQL credentials when logs are attached to support issues or emailed.

  • Improvement Prevent modal dialogs from blocking headless service

    Import error notifications now check whether the application is running as a Windows service (headless mode) and skip modal dialogs that would block indefinitely. Headless runs automatically decline incomplete imports rather than waiting for user input.

  • Bug Fix Fast failure and clear messaging when POS system is unreachable

    If you try to import while disconnected from the store network, you now get an answer in about 3 seconds with a clear explanation, instead of waiting 30+ seconds for a confusing error message.

  • Bug Fix Fast failure when POS server is unreachable

    If your computer isn't connected to the store network, imports now tell you within seconds instead of making you wait, and your existing data stays safe.

  • Bug Fix Epicor store designation validation in Store Manager
  • Bug Fix Validation for Epicor store designations in Store Manager

    If you try to enter a multi-digit number like "10" or "87" for an Epicor store, Margin Master will now show an orange warning box explaining that Epicor requires a single-character designation, not a store number. This prevents accidentally creating a store mapping that would import zero rows.

  • Bug Fix Restored POS import functionality for multiple systems

    Imports from Spruce, RockSolid MAX, and BisTrack systems that crashed immediately after starting will now work correctly again.

  • Bug Fix Restored functionality for Spruce, RockSolid MAX, and BisTrack imports

    Imports from Spruce, RockSolid MAX, and BisTrack systems now work correctly again after being broken in the previous release.

  • Bug Fix RockSolid rejected-row errors no longer treated as application crashes

    When your RockSolid export file contains rows that can't be imported, you'll still see the error message and error file as before, but these won't be incorrectly reported as application crashes.

  • Bug Fix Prevent stale data from being re-imported as current

    Your pricing data now stays accurate even if the network drops during an import — old prices will never accidentally appear as if they're current.

  • Bug Fix Preserved legacy storage format compatibility
  • Bug Fix MySQL Compass bulk import failures now halt processing instead of continuing silently

    If a Compass import fails partway through, the system will now stop and alert you instead of quietly continuing with incomplete data and showing incorrect prices.

  • Bug Fix Do-It-Best vendor data merge timeout extended from 2 to 10 minutes

    Do-It-Best pricing imports will no longer time out on busy systems, ensuring you always get current vendor prices instead of outdated ones.

  • Bug Fix Accurate import status and row count reporting

    The import history now correctly shows whether each import actually worked and how many items were imported, instead of sometimes saying "success" when nothing was actually imported.

  • Bug Fix Connectivity errors now classified separately from data errors

    Network and reachability failures (error numbers 2, 17, 40, 53, 64, 121, 258, 10053, 10054, 10060, 10061, plus SocketException and Win32 host-unreachable errors) are now recognized as "the source is unavailable" rather than genuine data faults. This allows the app to show helpful "are you connected to the store network?" guidance instead of raw provider error messages.

  • Bug Fix SQL passwords removed from support logs

    Connection strings are now redacted before being written to log files, removing the SQL password that was previously logged in clear text. Since logs are routinely attached to support emails, this prevents accidental disclosure of store credentials while preserving all diagnostic information support needs.

  • Bug Fix Import run history now records actual fetch results

    Import processing records now capture per-store row counts and success/failure status from the actual fetch, replacing the previous boolean success flag that couldn't distinguish "read everything" from "read nothing but didn't throw." Prevents situations where stale staging table rows would be re-imported and stamped with today's date.

  • Bug Fix Network interruption mid-import now exits cleanly

    When connectivity is lost partway through a multi-store import, the process now breaks out immediately instead of waiting for a full timeout on every remaining store. Working export files are no longer deleted before confirming the connection is open, preserving the fallback option to reprocess an existing export.

  • Bug Fix SystemInfoDto POS identity now sent correctly to cloud

    Fixed issue where support submissions from clients with unmapped PointOfSaleSystemType values (SpruceWareNet, Versys, TAMS, Unknown) violated the cloud database foreign key constraint and lost the customer's report. The DTO now consistently populates both the legacy PointOfSaleSystemId and the new PointOfSaleSystemType/TypeName fields via SetPointOfSaleSystem().

  • User Interface Validation message banner in Store Manager

    When there's a problem with your store matchup entries, you'll now see a highlighted orange message box above the grid that tells you exactly which store has the problem and how to fix it.

  • User Interface Stale data notification banner

    When an import can't reach your point of sale, a banner now tells you exactly when your on-screen data was last updated, so you know you're looking at older prices.

  • User Interface Validation feedback in Store Manager
  • User Interface Visual banner when viewing data from previous import

    A yellow warning banner now appears at the top of the screen when you're looking at older data because the latest import couldn't reach your point of sale, showing exactly when that data is from.

  • Architecture SQL Server endpoint parsing for TCP probes

    Introduced SqlServerEndpointParser to extract host and port from connection strings for network reachability checks. Handles tcp: prefixes, named instances, explicit ports, local aliases, and named pipes. Named instances on dynamic ports return an inconclusive result (since a closed 1433 proves nothing about a SQL Browser-managed instance), allowing the full connection attempt to proceed.

  • Infrastructure Removed unused service registration code

    Deleted the CommonServiceCollectionExtensions.cs file that contained service registrations which were never actually called by the application. This dead code created a maintenance trap where developers could add registrations that appeared correct but had no effect, which was the root cause of this issue.

  • Infrastructure Added dependency injection validation tests

    Implemented automated validation tests that verify all registered services can actually be constructed by the dependency injection container. This prevents issues like MM-1364 from reaching production by catching missing service registrations during development and continuous integration testing, rather than at runtime in front of customers.

  • Infrastructure Added dependency injection validation testing

    Created automated tests that validate the entire dependency injection container at build time, ensuring every registered service can actually be constructed. The test runs without requiring a live database and maintains a baseline of intentionally runtime-constructed ViewModels. This will catch similar registration errors before they reach production.

  • Infrastructure Removed unused service registration code

    Cleaned up an obsolete extension method (AddMarginMasterCommonServices) that was never being called by the application. This dead code previously registered several services including INetworkReachabilityService, but since it was never invoked, those registrations never took effect.

  • Infrastructure Enhanced issue submission with accurate POS system identification

    Issue reports now correctly map POS system types to cloud database foreign keys, fixing a constraint violation that caused some customer reports to be lost entirely. All four submission paths now use a consistent helper that maintains backward compatibility with older servers.

User Interface

  • Improvement Update warning dialogs now show specific version information

    When an update warning appears, it will now clearly show which version is available instead of displaying "(unknown)".

  • Bug Fix Update deferral tracking now resets after successful updates

    Margin Master will no longer incorrectly warn that updates are failing when you're already running the latest version.

  • Architecture Enhanced update deferral tracking system

    Added a new setting (AutoUpdateDeferredVersion) to track which specific version the deferral clock is running against. The deferral date is set once when an update is first seen, while the version is refreshed whenever a newer release supersedes an older one, ensuring accurate reporting throughout the 7-day maximum deferral window.

Reporting & Exports

  • Improvement Enhanced error reporting fingerprinting

    Improved how errors are grouped in the support dashboard by distinguishing wrapper exceptions (AggregateException, TargetInvocationException) from the actual faults they contain. Previously, unrelated errors such as blocked Windows notifications, network timeouts, and resource disposal issues were grouped together under a single fingerprint, making them impossible to diagnose or fix individually. Error grouping now includes the innermost exception type and the first application stack frame for wrapper exceptions, allowing each distinct issue to be tracked separately while maintaining fingerprint stability for all other error types.

  • Bug Fix Fixed crash after canceling strategy execution

    You can now safely import POS data or perform other operations immediately after canceling a pricing strategy—previously this would cause an error.

  • Bug Fix Improved license validation during service outages

    The application will no longer ask you to reconfigure your license when the licensing server is temporarily down—your existing license will remain valid throughout brief service interruptions.

  • Bug Fix Corrected "Back to Database Selection" logging

    Fixed an issue where choosing "Back to Database Selection" during license validation was incorrectly logged as a license validation failure with a null error message. This navigation action is now logged appropriately as an informational event rather than an error.

Other Changes

  • Improvement License service outages no longer interrupt workflow

    You'll no longer see license configuration prompts during temporary outages of our licensing service as long as your existing license is still current.

  • Improvement Suppressed spurious license revalidation error logs

    Eliminated a spurious error log entry ("License revalidation failed: null") that appeared whenever a user chose to return to database selection from the license configuration window instead of completing revalidation. This normal navigation action is now logged as informational rather than an error.

  • Bug Fix BLANK option now appears in single-value selection boxes

    If you have a field like User Code 3 that has one value on some items and is blank on most others, you can now select BLANK to see all the items without that code. Previously, you could only see the items with the code.

  • Bug Fix BLANK option now appears for single-value columns with blanks

    Previously, if a field like User Code 3 had only "M" on some items and was blank on everything else, the filter dropdown would only show "M" with no way to select the blank items. Now the dropdown correctly shows both "M" and "BLANK" so you can filter either group.

  • Bug Fix Error grouping now distinguishes between different underlying failures

    Background error tracking is now more accurate, which helps us identify and fix issues faster.

  • Bug Fix Strategy execution cancellation no longer breaks subsequent imports

    Cancelling a pricing strategy will no longer cause the next data import to fail with an error.

  • Architecture Removed unused duplicate method

    Deleted CreateUniqueFieldListFromMainTableFieldListAsync, a 108-line near-duplicate of the main unique-list builder that had no callers anywhere in the solution but carried the identical one-value bug. Removing it prevents future developers from accidentally reintroducing the defect.

  • Infrastructure Added automated tests for BLANK option logic

    Created a comprehensive test suite (BlankSelectionOptionTests) that pins the exact rule for when BLANK should be offered: blanks must exist in the data AND the field must have at least one real value. Tests cover single-value fields with blanks (the MM-1359 case), multi-value fields, fully populated fields, and entirely-blank fields.

  • Infrastructure Added test coverage for BLANK option logic

    Added comprehensive unit tests that verify when the BLANK option should and shouldn't appear: it appears when the column has blanks in the data and at least one real value, but not when the column is entirely blank (which would create a useless BLANK-only dropdown) or when no blanks exist in the data.

2026.807.36661
August 8, 2026

Release notes aren't available for this version.

2026.807.20583
August 7, 2026

Release notes aren't available for this version.

2026.806.38452
August 7, 2026

Release notes aren't available for this version.

2026.805.35287
August 6, 2026

Update alerts now show target version number; Plus-or-Minus spinner now steps by whole dollars in Dollars mode; Plus-or-Minus spinner increment corrected.

Strategy & Pricing

  • Improvement Update alerts now show target version number

    If you see an update warning, it will now tell you which version it's trying to install instead of showing "(unknown)".

  • Bug Fix False update warning after successful installation

    If you successfully update Margin Master, you will no longer see a warning that the update failed.

  • Bug Fix Update tracking for machines upgrading from pre-August 2026 versions

    Resolved a specific issue affecting machines updating from versions older than 2026.804. These older versions stored update status in store-wide settings, while newer versions use machine-specific settings. When the migration logic correctly discarded the old store-wide data (since it couldn't identify which workstation wrote it), the system had no record of a successful update and never cleared the deferral clock. The authoritative "up to date" response from the update server now serves as the definitive signal to clear tracking, regardless of migration path.

Other Changes

  • Bug Fix Plus-or-Minus spinner now steps by whole dollars in Dollars mode

    When using the Plus-or-Minus feature set to Dollars, clicking the up or down arrows now changes the amount by a full dollar ($1.00) instead of just one cent. You can still type fractional dollar amounts if needed, but the spinner buttons work correctly.

  • Bug Fix Plus-or-Minus spinner increment corrected

    When adjusting prices using the plus-or-minus feature in Dollars mode, clicking the up/down arrows now changes the value by $1 instead of 1¢, making it easier to apply dollar-based price adjustments.

  • Bug Fix Vendor catalog no longer deleted when RSC setting is corrected

    If your store's RSC code is corrected in Settings, the next sync will automatically reload the complete vendor catalog for the new RSC instead of leaving you with incomplete data.

  • Bug Fix Schema migration no longer fails repeatedly on tables converted to views

    DatabaseMigrationService now skips ALTER TABLE commands whose target is a view. MMVendorData became a view, so 21 of 47 schema commands failed on every startup — 63 log entries in a single day at store 3936, burying real failures. These commands are now skipped silently since they are unapplicable by definition.

  • Cloud Sync Multi-RSC stores no longer lose their primary RSC catalog

    Stores with multiple RSC codes configured will keep catalog data for all locations, including the main store RSC.

  • Cloud Sync Dramatic table shrinkage during sync now logged as a warning

    Any sync that reduces a table by more than 20% now logs a warning with before/after counts. Store 3936's catalog shrank from 79,661 to 1,167 rows with nothing in the log but "Successfully synced" — the loss left no trace. The warning helps distinguish deliberate scope changes from data corruption.

  • Cloud Sync Count validation self-heal no longer deletes data before refetching

    When count validation detects a local/cloud mismatch and triggers a re-sync, the local partition is no longer deleted first. Re-syncing from RowVersion 0 reaches the same end state via upsert and tombstone cleanup, without a window where a refetch failure would leave the partition empty while the sync still reports success.

  • User Interface Improved spinner behavior consistency across unit types

    The Plus-or-Minus spinner arrows now work the same way for all measurement types—each click increases or decreases by one whole unit of whatever type you've selected.

  • User Interface Strategy execution summary now shows why steps skipped SKUs

    When a pricing strategy step skips products, the summary dialog now explains exactly what's missing — like a product group that no longer exists — so you know what to fix.

CloudSync
2026.804.39936
August 5, 2026

Release notes aren't available for this version.

2026.804.30834
August 4, 2026

Release notes aren't available for this version.

2026.803.41581
August 4, 2026

SQL Server version support policy enforcement; SQL Server version detection and warning system; SQL Server version detection and warning system.

Imports & POS

  • New Feature SQL Server version support policy enforcement

    If your computer is running an old version of SQL Server, Margin Master will now notify you and recommend upgrading to SQL Server 2025 (SQL Server 2022 is the minimum supported version).

  • New Feature SQL Server version detection and warning system

    If your computer is running an old version of SQL Server, Margin Master will now warn you and recommend upgrading to SQL Server 2025 or at least SQL Server 2022.

  • New Feature SQL Server version detection and warning system

    If your computer is running an old version of SQL Server, Margin Master will now warn you at startup and recommend upgrading to SQL Server 2025 (or at least SQL Server 2022). SQL Server Express is free from Microsoft.

  • Improvement Import file scan results now logged for diagnostics

    The Import Manager now writes a detailed log entry after each scan showing how many files were found, how many matched the POS system, how many are backups, and how many are displayed under the current filter. This was added after a store reported an empty import list that required extensive troubleshooting to diagnose. The log entry distinguishes between "no files matched" and "files matched but were filtered out" (for example, when the Backup Files filter is active but all matched files are regular POS exports). This improvement enables faster remote diagnosis of import file visibility issues without requiring database restores or file exchanges.

  • Improvement Smarter filtering of non-import files

    The Import Manager is now better at automatically skipping files that aren't POS exports, even if they have slightly different names or are in folders with unusual names.

  • Improvement Enhanced file filtering for Margin Master export copies

    Copied or renamed versions of export files (like "NEWRETAILS - Copy.TXT") are now automatically ignored during import scanning, just like the originals.

  • Improvement Import Manager dialog cleanup

    Removed unused custom import functionality from the Import Manager, including a non-existent property binding that was generating errors in the log every time the dialog opened, dead code branches, and commented-out blocks.

  • Bug Fix Import Manager dialog no longer fails silently after finding files

    If the Import Manager has trouble reading your import folder, it will now show you an error message explaining what went wrong instead of appearing to freeze with an empty file list.

  • Bug Fix Import Dialog no longer fails silently when loading files

    If the import screen has trouble reading files from your import folder, you'll now see an error message explaining the problem instead of a blank screen.

  • Bug Fix Import scan no longer hangs on mismatched files

    If you have unrelated text or CSV files in your import folder, the Import Manager will now skip them quickly instead of freezing. Your actual POS export files will be detected and displayed normally.

  • Bug Fix Import scan no longer hangs on incompatible files

    If you have extra copies of files or unrelated spreadsheets in your import folder, the Import Manager will now skip them quickly instead of freezing. Your actual import files will appear in the list as expected.

  • Bug Fix Import no longer hangs on unparseable TransAct records

    If your TransAct import file has a record with corrupted or invalid data (like a price that isn't a number), the import will now skip that bad record and continue importing the rest of your data, instead of freezing forever.

  • Bug Fix Import Dialog no longer fails silently when loading files

    If the import screen has trouble reading files from your import folder, you'll now see an error message explaining the problem instead of a blank screen with a stuck loading indicator.

  • Bug Fix Null dispatcher guard in Import Dialog progress management

    Fixed a null reference exception in the Import Dialog's ProgressEnd method that could occur when the DispatcherService was not yet initialized. The method now uses the same DispatchSafe pattern as the rest of the file loading process, preventing crashes during edge-case timing scenarios.

  • User Interface Improved error handling throughout Import Dialog

    All Import Dialog file loading operations are now wrapped in proper exception handling. Previously, unhandled errors in the async WindowLoaded method would be silently swallowed, leaving the UI in an inconsistent state. The busy progress overlay is now guaranteed to clear even when errors occur.

  • User Interface Clearer status messages during import scan

    When the Import Manager skips a file, you'll now see a clearer explanation of why it was ignored.

  • Infrastructure Comprehensive test coverage for bad record handling

    Added automated tests that verify the import engine correctly handles files containing unparseable records in various positions: mid-file, as the last line, and files consisting entirely of bad records. These tests run with a strict 30-second timeout to ensure that any regression causing infinite loops will immediately fail the test suite rather than hanging the build system. Tests were verified against the actual customer database, where all three scenarios hung for the full 30-second cap before the fix and completed in under 500ms after.

  • Infrastructure Added comprehensive test coverage for import file validation

    Added 7 new unit tests covering the field-count sniff logic, including tests for the exact file that caused the customer's scan to hang (2-field file vs. 37-field layout), real BisTrack exports, files with quoted commas in descriptions, truncated rows, header-only files, and the timeout bounds.

  • Infrastructure Error reporting suppression for unsupported environments

    Added the ability to suppress cloud error reporting when running in known-unsupported environments. When SQL Server 2017 or older is detected, all telemetry reporting stops for that session to avoid polluting error data with expected failures from unsupported configurations.

  • Infrastructure Error reporting suppressed for unsupported SQL Server versions

    When SQL Server 2017 or older is detected, cloud error telemetry reporting is automatically suppressed for the entire session. The database schema errors that result from these unsupported versions are expected consequences of running below the minimum functional version, not actionable bugs—reporting them would pollute the error data stream. Users still see warnings in the UI, but errors are only logged locally.

Cloud Sync & Vendor Data

  • Bug Fix Fixed version reporting to show consistent format

    Store version numbers are now consistently reported in the semantic version format shown in the Margin Master title bar (e.g., 2026.803.41581) rather than mixing two different formats side-by-side. The system now combines data from multiple sources and filters out outdated readings from legacy installs on secondary machines that were masking actual current versions. This resolves cases where stores 2928 and 4161 appeared outdated due to old installations on sibling machines, and where Ruidoso #9039 incorrectly appeared as unpatched when it had already updated.

  • Bug Fix Corrected "last seen" time calculation for store activity

    Fixed a timezone defect where "last seen" times were overstated by four hours. The system was mixing UTC timestamps from auto-update check-ins with Eastern timestamps from application activity without conversion, causing the MAX() calculation to always favor the UTC value. All timestamps are now normalized to Eastern time before comparison, providing accurate "days quiet" measurements for store activity monitoring.

Performance & Reliability

  • Improvement Enhanced startup error handling

    Improved the application's resilience to configuration errors by adding a fallback mechanism for unrecognized setting keys. Instead of causing a startup failure, missing configuration keys now log a warning and use a conventional format, ensuring the application can always start even if future updates introduce configuration issues.

  • Bug Fix Application startup hang resolved

    Margin Master will now open normally instead of freezing on the loading screen.

  • Bug Fix Application startup hang resolved

    The application will no longer freeze on the loading screen when it checks for update information at startup.

  • Infrastructure Safety net for future configuration keys

    Added a fallback mechanism that automatically generates configuration keys using a conventional naming pattern when an explicit mapping is missing. This prevents any future missing key mappings from causing application startup failures, logging a warning instead so developers can add proper mappings where needed.

Other Changes

  • Improvement Update success now clears failure state on version advancement
  • Bug Fix SQL Server minimum-version check now uses engine version

    If you have an older version of SQL Server installed (2017 or 2019), Margin Master will now correctly recognize it as incompatible and guide you through upgrading or installing the required SQL Server 2022 version. Previously, it would incorrectly attempt to use these older versions.

  • Bug Fix SQL Server minimum version validation corrected

    When connecting to an existing SQL Server instance, the app now correctly identifies whether that server version is compatible with Margin Master. Previously, older incompatible SQL Server versions could be incorrectly accepted.

  • Bug Fix Update health state now tracked per machine
  • Bug Fix Obsolete failure counters now cleared automatically
  • Infrastructure One-time migration from store-wide to machine-specific update tracking
2026.802.35491
August 4, 2026

Cost basis selector for Margin % pricing; Show Affected Items for Strategy Steps; Show Affected Items for strategy rules.

Strategy & Pricing

  • New Feature Cost basis selector for Margin % pricing

    Below the Margin % field, you'll see a new "Margin on cost" dropdown. Pick "Store Cost (Default)" to calculate margin the usual way, or choose Replacement Cost, Average Cost, Cost2, or MFG Cost if you want the margin based on a different cost value. Items missing that cost will be skipped.

  • New Feature Show Affected Items for Strategy Steps

    When a pricing rule changes margins or other values it selected on, the normal "Load" button shows nothing because the rule can't find items that now have different values. "Show Affected Items" shows what the rule actually changed on its last run by looking at the history record instead. Double-click any step in the execution summary to see its affected items.

  • New Feature Show Affected Items for strategy rules

    To see which items a strategy rule affected: open the Strategy Execution Summary after running a strategy, select a rule from the list, and click "Show Affected Items" (or double-click the row). The main pricing grid will load showing every item that rule changed, regardless of whether later rules modified them further.

  • Improvement Enhanced Unpriced SKU Report accuracy

    The Unpriced SKU Report after a strategy run now shows a complete count of items without prices, including those that couldn't be priced due to missing cost data.

  • Improvement Unpriced SKU report now counts all unpriced items

    The unpriced items report after running a pricing strategy now accurately counts all items that didn't receive a new price, including those that couldn't be priced due to missing cost information.

  • Improvement Clearer warning message for unmatched stores

    Import warnings now more clearly explain when a store needs to be set up in Store Manager.

  • Improvement Clearer diagnostic message for unmatched stores

    If an item table can't be matched to your store setup, the error message now clearly explains that the table isn't linked to a store record, making it easier to diagnose configuration issues.

  • Improvement Enhanced protection for POS program directories

    RockSolid sites that point DEFAULTIMPORTPATH at the POS installation folder (required because the importer reads RockSolid.RS in place) are now protected by two independent guards: the folder is both outside C:\MarginMaster and under Program Files (x86). Test cases now explicitly verify that C:\Program Files (x86)\Rock and the critical files Rock.exe and RockSolid.RS can never be deleted by future code changes.

  • Improvement Strategy execution duplicate-run prevention

    You can no longer accidentally run the same pricing strategy twice in quick succession—the system now prevents double-clicks and asks for confirmation if you try to re-run within two minutes.

  • Improvement Store Manager auto-fills RSC from organization majority

    When opening Store Manager, any store without an RSC after loading cloud settings is now defaulted to the organization's most common (majority) RSC. This value is marked dirty and pushed to the cloud on save, ensuring Manager learns the derived RSC. The auto-fill is non-destructive—it only fills blank values and never overwrites an explicitly-set RSC.

  • Improvement Consistent History Recording Across Pricing Methods

    Consolidated PSRuleHistory append logic into a single shared function used by both rounding-based pricing and explicit SQL pricing paths. Previously each site built its own de-duplication test, risking divergent behavior where a row's audit trail depended on whether the step happened to use a rounding scheme. Both paths now produce byte-identical history strings.

  • Improvement Duplicate strategy run prevention with user confirmation

    If you accidentally click Execute Strategy twice in a row, the app now asks you to confirm before discarding the current results and running again. The menu item is also grayed out during the entire strategy run to prevent accidental clicks.

  • Improvement Distinct SKU count logging for strategy runs

    Strategy runs now log how many distinct SKUs were actually priced (COUNT(DISTINCT SKU) WHERE FuturePrice <> 0) alongside the per-step total. The TotalSkusAffected metric reported to the cloud is a sum of work across all steps where a SKU touched by five steps counts five times, making it unsuitable for run-to-run comparison; the new distinct count provides the comparable figure.

  • Bug Fix DIB retail prices now correctly filter by store's assigned RSC

    If your Do it Best store has multiple Regional Service Centers, you were seeing prices from the wrong RSC on some items. This is now fixed, and the correct prices for your RSC will display automatically.

  • Bug Fix Restored RSC filtering for Do-It-Best retail price calculation

    Your store will now see the correct retail prices for your region instead of prices from other Do-It-Best regions.

  • Bug Fix Unified annual impact calculation across all POS systems

    Annual impact now correctly shows how much revenue your pricing changes will generate, measured the same way for all stores regardless of which point-of-sale system you use.

  • Bug Fix Unified annual impact calculation across all POS systems

    The annual revenue impact numbers shown after running a strategy are now accurate and consistent regardless of which POS system your store uses. Previously, some systems reported misleading negative impacts even when strategies raised prices.

  • Bug Fix Catch-all rules now attribute unpriced SKUs

    When running a pricing strategy, you'll now see which rule examined each SKU, even if that SKU couldn't be priced due to missing cost information.

  • Bug Fix Catch-all rules now claim all selected SKUs

    When a pricing rule can't calculate a price for an item (usually because cost information is missing), the rule's name will now appear in the pricing analysis so you can see which rule tried to price it.

  • Bug Fix Catch-all pricing rules now stamp all covered items

    When viewing pricing analysis, items with no cost will now correctly show which pricing rule applied to them, even if no actual price could be calculated.

  • Bug Fix PSRule attribution now works on all items for catch-all rules with rounding

    When a pricing rule applies to all items, you'll now see the rule name in the PSRule column for every item, even items that couldn't be priced because they're missing cost information.

  • Bug Fix Zone pricing now resolves correctly for non-Epicor stores

    If you noticed your store's pricing didn't match your assigned zone after a recent update, this fix restores the correct zone-based pricing. Stores were being priced at the national zone even when a specific zone was configured.

  • Bug Fix Ace Hardware zone pricing now resolves correctly on non-Epicor systems

    If your store uses Ace Hardware or Emery Jensen pricing zones with RockSolid, Transact, BisTrack, Catalyst, Falcon, Paladin, or MySQL Compass, your items will now price at your correct assigned zone instead of incorrectly using the national zone.

  • Bug Fix Import cleanup restricted to application's own folder

    If you use a custom import folder outside C:\MarginMaster (like D:\Imports or the POS program folder), old .BAK backup files will accumulate instead of being automatically removed after 7 days. This is intentional—it's safer to let backups build up than risk deleting important POS files.

  • Bug Fix Store Manager RSC assignments now apply to pricing builds

    If you assigned an RSC to a store in Store Manager but pricing still used a different RSC, that will now work correctly. The RSC you see in Store Manager is the RSC that will be used for pricing.

  • Bug Fix Store Manager RSC mappings now reach the pricing build

    If you've assigned RSCs to stores in Store Manager, those stores will now price correctly using their assigned RSC instead of the default application setting.

  • Bug Fix Restore DIB auxiliary retail pricing

    If you price bulk items (like wire, chain, or rope sold by the foot but priced by the roll) using the auxiliary retail, those prices will now appear and your pricing rules will work correctly.

  • Bug Fix Restored Do-It-Best auxiliary retail pricing in vendor data view

    The MMVendorData view now correctly populates the Ace_MSURetail column with Do-It-Best auxiliary retail values from the catalog's SuggAuxRetail field. Previously this column was hardcoded to zero when the view was created, breaking the downstream pricing calculations that depended on it. The view also now includes the PrivateLabel field from the DIB catalog, which is a letter code present on approximately 10% of SKUs.

  • Bug Fix Mi9 stores now report all twelve months of sales history

    Mi9 stores' annual impact figures now include the most recent month, which was previously missing.

  • Bug Fix Corrected Mi9 monthly sales history to include all twelve months

    Annual impact calculations for Mi9/RockSolid stores now include all twelve months of sales history instead of only eleven, making the projections more accurate.

  • Bug Fix RSC fallback logic now runs on correct code path

    Stores that don't have an RSC assigned will now borrow one from other stores in your organization instead of using the wrong default, and new store numbers will price using a reasonable RSC rather than showing no data at all.

  • Bug Fix RSC fallback ladder now executes for all stores

    The RSC fallback logic introduced in MM-1341 (which borrows a workable RSC from other org stores when a store has no explicit mapping) was accidentally implemented in StoreDataService, which is never injected or called. Every pricing operation called DatabaseService instead, so the ladder never ran and stores with missing mappings always fell back to the application-level RSC. The ladder now lives in DatabaseService4.GetSpecificRSCAsync on the actual execution path.

  • Bug Fix Strategy Step Names with Special Characters

    Pricing rule names containing %, _, or [ characters now work correctly and won't lose their history records.

  • Bug Fix Wildcard characters in rule names now handled correctly

    Strategy rules with special characters like "%" or "_" in their names now work correctly and won't accidentally match other rules or skip recording their changes.

  • Bug Fix Correct Level3 column for DIB stores

    The "DIB Aux Retail" column in your pricing grid now shows the correct auxiliary retail prices from the Do it Best catalog instead of internal rounding values.

  • Bug Fix Corrected Level3 (DIB Aux Retail) column population across all POS import paths

    The "DIB Aux Retail" column in the pricing grid now shows the correct auxiliary retail prices instead of being blank or showing rounding values.

  • Bug Fix Margin calculations respect cost availability

    If you select Replacement Cost for margin calculation but a product has no replacement cost entered, that product will be skipped instead of accidentally using a different cost.

  • Bug Fix Missing STORERSC entries now fall back to application-level RSC

    If your store's RSC mapping is not configured, the system will use your main RSC setting and alert support, rather than showing random prices.

  • Bug Fix Eliminated SKUs with no future price from impact calculations

    The Compass/Epicor variant was substituting CurrentPrice when FuturePrice was zero, which incorrectly included every SKU the strategy never touched in the impact totals, inflating them with unrelated price drift. These SKUs are now properly excluded from all calculations.

  • Bug Fix Cloud sync now preserves locally-derived RSC assignments

    RSC assignments that Store Manager fills in automatically (like when it picks the most common RSC in your organization) will now sync to the cloud properly and won't be lost.

  • Bug Fix Fix auxiliary retail for MySQL Compass stores

    If you use MySQL Compass and have pricing rules that check for auxiliary retail prices (like "MSU Retail greater than 0"), those rules will now find and price the correct items.

  • Bug Fix Fixed MSU Retail updates for MySQL Compass users

    Pricing rules that filter on MSU Retail (such as "Ace_MSURetail~GREATER~0.00") now work correctly for Compass POS users.

  • Data Import Cost basis preserved in saved strategies and SKU exceptions

    Your cost basis choice is saved with the strategy and works everywhere—regular pricing rules, custom groups, and individual SKU overrides.

  • Data Import One-time automatic repair of incorrect DIB retail prices on upgrade

    When you first open Margin Master after this update, it will automatically correct any retail prices that were pulled from the wrong Regional Service Center. This happens once in the background and requires no action from you.

  • Data Import One-time automatic repair for affected Do-It-Best stores

    The first time you open Margin Master after this update, it will automatically recalculate all prices to fix any incorrect regional pricing.

  • Data Import Restore DIB PrivateLabel attribute

    The PrivateLabel field from the Do it Best catalog (a letter code present on approximately 10% of SKUs) was being discarded during import. This catalog attribute now imports correctly and populates on applicable items.

  • User Interface Double-click to show affected items

    You can now double-click any rule in the Strategy Execution Summary to quickly see which items it affected.

  • User Interface Dynamic cost basis options based on column visibility

    The cost basis dropdown is populated based on which cost columns are visible in the user's current column view, matching the existing behavior for the "Set To" price level list. Store Cost (Default) is always offered first, followed by any alternate cost columns the store has configured and made visible.

  • User Interface Store Manager projections preserve manual edits

    Store Manager now uses fill-only mode when loading (writes only to stores with no GlobalFileConfig row) and overwrite mode when saving (user-asserted values win). This prevents Store Manager from clobbering RSC or store matchup entries created in the older Store Number Match Up screens while still healing gaps automatically. Test coverage added to pin the projection rules.

  • Database Improved PSRuleHistory audit trail consistency

    Consolidated all PSRuleHistory writing logic to use a single shared method (AppendPsRuleHistorySql) that properly escapes rule names and prevents duplicate entries. This ensures consistent audit trails regardless of whether a rule uses rounding schemes or other pricing logic, and fixes issues where rules containing underscore characters were incorrectly de-duplicated.

  • Database Added comprehensive test coverage for DIB auxiliary retail pricing

    Added 199 lines of automated tests that verify all four SQL scripts correctly source the Level3 column from SuggAuxRetail, prevent regressions that would redirect Level3Zone away from the rounding ladder, and ensure the Compass update path maintains both pricing arms. These tests enforce the invariant that every DIB main table build path must read auxiliary retail pricing, preventing silent data loss.

  • Database Added comprehensive unit tests for change summary SQL

    Created ChangeSummarySqlTests.cs with 11 test cases locking in the contract that all three SQL variants must measure against CurrentPrice, exclude SKUs with FuturePrice = 0, emit exactly H1..H12 (no H0, no H13), and count exactly twelve months. Tests verify that Compass skips its partial current period (in_sales_units_per_1) and starts at per_2, and that Mi9 no longer references RetailLevel1 or emits the dropped H0 column.

  • Architecture Pricing attribution logic tightened for catch-all rules

    The companion stamp statement that attributes unpriced rows now runs as the exact complement of the main pricing statement: the pricing UPDATE's WHERE clause carries the zero-price guard, the stamp's WHERE clause carries the negation of that guard, and together they cover every row in the table. Verified against customer database: catch-all rules now claim all 1,221 unpriced rows (up from 130), with no impact to priced rows (CHECKSUM_AGG unchanged). Renamed StampUnclaimedPsRuleSql to StampUnpricedPsRuleSql to better describe the selection criteria.

  • Architecture Moved unpriced-item stamping to apply to all catch-all rules

    Relocated the PSRule stamping logic for unpriced items from inside the rounding-only path to after both the rounding and no-rounding paths. This ensures that any catch-all rule (one with no WHERE clause) stamps its name on every item it covers, regardless of whether the rule uses rounding or not. The fix ensures consistent attribution behavior across all pricing rule configurations.

  • Architecture Added test coverage to prevent RSC filtering regression

    Introduced DibRscPredicateTests that enforce the RSC predicate must exist in the resolved SQL body (not just comments), be bound to the {RSC} variable, and never revert to the comment-based activation pattern. These tests would have caught the original regression during the MM-1046 refactoring that inadvertently removed the RSC filter marker in commit 592206a.

  • Architecture Centralized zero-price guard logic

    Extracted the zero-price guard expression (which prevents pricing items with no cost basis) into a single shared method to ensure consistency across all three rounding generators and the new attribution statement. This prevents the logic from drifting apart as previously happened between the rounding and no-rounding code paths.

  • Architecture New StampUnclaimedPsRuleSql method for attribution

    Introduced RoundingSql.StampUnclaimedPsRuleSql() to handle attribution of items that pass a step's selection criteria but fail the zero-price guard. This method writes only PSRule and PSRuleHistory columns, never overwrites existing attributions, and uses the same zero-price guard logic (inverted) that the main rounding statements use. The change preserves the invariant that PSRule always names the rule that produced the live FuturePrice.

  • Architecture Separated store identity from table-naming logic

    Introduced StoreManagerSql.MainTableKeyExpr to distinguish between a store's identity (vendor store number preferred) and the key used to name its per-store tables (POS store number preferred for non-Epicor systems). The two expressions now have distinct names, documentation, and test coverage to prevent future confusion. Epicor continues to use vendor store numbers for both purposes.

  • Architecture Separated store identity key from main table suffix key

    Introduced a new MainTableKeyExpr method that generates the correct expression for matching per-store table names, which is distinct from the store's identity key (KeyExpr). For Epicor, both expressions are identical since Epicor names tables by vendor store number. For all other POS systems, the main table key prefers POS store number first (matching how tables are actually named from SELECT DISTINCT StoreNumber), while the identity key prefers vendor store number first (a configured store's true identity). This architectural separation prevents future confusion between these two related but distinct concepts.

  • Infrastructure Renamed and clarified PSRule stamping method

    Renamed RoundingSql.StampUnclaimedPsRuleSql to StampUnpricedPsRuleSql and removed the WHERE clause that prevented stamping items already claimed by earlier rules. This reflects the method's actual purpose: it's the complement to the pricing statement, covering exactly the rows that the pricing statement excluded (items with zero-priced basis). Together, they ensure every row in a catch-all selection is attributed.

  • Infrastructure Added automated tests to prevent RSC predicate regression

    Created DibRscPredicateTests suite with assertions that verify the RSC variable is consumed in the SQL body (not just declared in comments), the resolved script filters MMVendorData by the supplied RSC, no unsubstituted placeholders remain after resolution, and the RSC predicate is never reintroduced as a comment marker that C# uncomments. These tests would have caught the original regression from commit 592206a.

  • Infrastructure Removed stray temp_build directory from repository

    Deleted 200+ files of committed build output (DevExpress DLLs, import layouts, SQL scripts) that were mistakenly tracked in the temp_build folder. This directory contained a pre-regression copy of the vendor data SQL script that made the broken RSC mechanism appear functional when searching the codebase. Updated .gitignore to prevent future build output commits.

  • Infrastructure Enhanced strategy execution telemetry

    Strategy execution reports now show more accurate counts of how many products were actually repriced.

  • Infrastructure Added unit tests for mapping-write logic

    Added ShouldWriteMappingTests.cs with six test cases pinning the rule that decides whether Store Manager should write a mapping to GlobalFileConfig, covering scenarios like no existing row (always writes), blank new value (never writes), load vs. save behavior (fill-only vs. overwrite), and unchanged values (skipped to avoid churning rows). This rule is critical to MM-1351's fix because it must never clobber a mapping the user set elsewhere and must never invent one from a blank.

  • Infrastructure Removed committed build output and updated .gitignore

    Deleted the temp_build/ directory containing stale build artifacts (300 files, 28K deletions). The stale copy of UpdatemainTableFromMMVendorData.sql still contained the commented RSC marker, making repository searches incorrectly suggest the mechanism was still wired up. Added temp_build/ to .gitignore to prevent future commits of build output.

  • Infrastructure Add regression tests for DIB auxiliary retail

    Added comprehensive test coverage (DibAuxRetailLevel3Tests) to prevent future regressions in DIB auxiliary retail handling. The tests enforce that all main table build paths correctly source Level3 from the auxiliary retail field rather than reverting to rounding ladder values.

  • Infrastructure Strategy execution telemetry enhancements

    Added SummaryFormatVersion field (defaulting to 2) to StrategyExecutionTrackingRequest to prevent the cloud from mixing incompatible calculation methods across schema versions. Added TriggerSource ("Menu", "AiReviewPrompt", or "Headless") and SecondsSinceLastRun fields to identify the source of duplicate same-session executions. Enhanced logging to capture full stack traces when a strategy re-runs within 300 seconds of the previous one.

Imports & POS

  • Improvement Import unconfigured stores automatically

    When your POS system exports data for a store you haven't set up yet in Margin Master, that store's products now show up automatically. You'll see a notice at the end of the import telling you which stores to finish configuring in Store Manager.

  • Improvement Reduced telemetry noise for configuration states

    Unmapped stores no longer generate error-level telemetry events or leave behind orphaned temp tables during each import run, reducing log clutter and making genuine import errors easier to identify.

  • Improvement Automatic RSC fallback for stores without mappings

    Stores without a price code (RSC) assigned will automatically use the same price code as your other stores, so you'll see pricing data immediately instead of zero items.

  • Improvement Automatic zone fallback for stores without zone assignments

    Stores without a pricing zone will now use the national zone automatically, giving you correct vendor pricing until you assign a specific zone in Store Manager.

  • Improvement Re-enable previously auto-excluded stores

    Stores that were hidden because they had no vendor number will automatically reappear in your next import.

  • Improvement Added policy and tests for StoreNumber normalization eligibility

    Created StoreRoutingFilterPolicy.ShouldNormalizeStoreNumber and Mi9TableConstants.IsStoreGroupMainTable to centralize and test the decision logic. The policy now explicitly rejects store-group tables, all-stores tables (mainTable, Mi9_mainTable), and tables with unusable derived tokens (empty strings or "mainTable" itself). Added 20 new unit tests covering group table recognition, normalization policy for all table types, and regression guards for the reported bug.

  • Improvement Smarter RSC fallback when store mapping is missing

    Stores without their own pricing RSC now use the same RSC as your other stores, giving more consistent pricing until you assign the correct RSC in Store Manager.

  • Bug Fix Graceful handling of unmapped BisTrack stores during import

    If your BisTrack export includes a new store that hasn't been assigned a vendor yet, the import will skip that store cleanly with a warning instead of showing errors. Once you map the store to a vendor in Store Manager, future imports will process it normally.

  • Bug Fix Graceful handling of unmapped stores during import

    If a new store location appears in your POS data before it's been set up in Margin Master, the import will skip it with a clear message instead of showing an error, and you'll still be able to find and configure it in Store Manager afterward.

  • Bug Fix Unconfigured stores now import instead of being silently excluded

    New stores from your POS system will now show up in Margin Master right away, even before you've assigned them a vendor store number in Store Manager.

  • Bug Fix Prevented StoreNumber normalization from running on store-group tables

    Fixed incorrect data updates that caused the application to hang during startup when using store groups.

  • Bug Fix Import folder cleanup deleting RockSolid installation files

    The app will no longer accidentally delete RockSolid program files during its daily maintenance routine. If you experienced "RockSolid database file not found" errors after July 2nd, this fix resolves the root cause.

  • Bug Fix Import folder cleanup now protected against deleting POS installation files

    If your import folder is set to your RockSolid installation directory, the daily cleanup will no longer touch any of your POS files—only the old import backups Margin Master created.

  • Bug Fix Fixed StoreNumber normalization tracking to be per-table instead of session-wide

    Fixed an issue where some store-specific pricing tables wouldn't update correctly after the first data operation in a session.

  • Bug Fix Simplified store/group name extraction logic

    Collapsed redundant if/else branches in GetStoreOrGroupNameFromTableName — both StoreGroup_{group}_mainTable and {POS}_{store}_mainTable carry the identity in the second underscore-delimited token, so the conditional was returning the same value regardless of branch.

  • Bug Fix Epicor store char validation allows POS-keyed imports

    Epicor record validation now distinguishes between "store char never seen before" (dropped so discovery can register it) and "known store with no vendor number" (passed through keyed by POS store number). Previously, both cases were rejected at parse time, making unmapped stores permanently invisible even after they were discovered.

  • Cloud Sync Zone sync includes defaulted zones and reconciles by effective key

    Zone sync for grouped Epicor stores now gathers zone overrides using the effective-key eligibility predicate, ensuring stores with POS-only keys are included. The excluded-store reconciliation prompt (PromptAndDropExcludedStoreMainTablesAsync) matches tables by EffectiveStoreKey instead of VendorStoreNumber so POS-derived table names resolve to their store rows for friendly labeling.

  • Data Import Store discovery unchanged for unmapped stores

    The skip logic deliberately runs after the Store table insert, ensuring that new POS stores are still discovered by the system after import. This allows them to appear in Store Manager for vendor mapping, which would be impossible if they were skipped earlier in the process.

  • Data Import Epicor stores import under POS-derived keys when unmapped

    Epicor store discovery and INDecoded import no longer auto-exclude stores missing a Vendor Store Number. EpicorINRecord.IsValid now passes rows from known store chars even when unmapped (the conversion list keys off EffectiveStoreKey), EpicorFTPFileExtractorService registers new stores without excluding them, and the RSC resolution borrows a working RSC instead of skipping the main-table build. Unmapped stores are reported to the configuration notice, not shown in per-loop MessageBoxes.

  • Data Import MySQL/Compass import includes stores with POS numbers only

    MySQL and Compass import paths now include stores that have a POS store number but no vendor number in their eligible store lists, using EffectiveStoreKey for table naming and eligibility. Previously these stores were filtered out by the "LEN(ISNULL(VendorStoreNumber,'')) > 0" predicate, causing their data to be ignored despite being present in the POS export.

  • Data Import BisTrack/DIB imports build against borrowed RSCs

    The three BisTrack/DIB import paths (1040, 6828, and generic InsertIntoMainTable) no longer skip the main-table build when GetSpecificRSCAsync returns no store-specific RSC. The RSC ladder resolves a fallback, the table builds against that RSC, and the store is reported to the configuration notice. Closes an MM-1341-shaped hole where a blank RSC left the MMVendorData join unfiltered, silently pricing the store off an arbitrary RSC.

  • User Interface End-of-import notice for incomplete store configuration

    After importing, if any stores need setup, you'll see one notice listing them all and offering to open Store Manager for you.

  • User Interface Single configuration notice replaces multiple import warnings

    After import, you'll see one summary showing all stores that need attention, with an option to open Store Manager immediately to fix them.

  • Database One-time repair re-enables previously auto-excluded stores

    Stores that were previously hidden because they had no vendor number assigned will automatically reappear after this update.

  • Database Store effective key calculation in SQL and C#

    Added StoreManagerSql helper class and StoreManagerInfo.EffectiveStoreKey property, both implementing the same logic: VendorStoreNumber when assigned, otherwise the POS-derived fallback (PosStoreNumber for most systems, PosStoreCharOrdinal for Epicor extended chars). All eligibility filters, table-name generation, and store lookups now use this consistent expression instead of testing VendorStoreNumber presence.

  • Architecture Effective store key resolves vendor number or POS fallback

    Introduced StoreManagerInfo.EffectiveStoreKey and its SQL twin StoreManagerSql, which resolve to VendorStoreNumber when assigned or fall back to PosStoreNumber (or PosStoreCharOrdinal for Epicor non-alphanumeric chars). All eligibility filters, table-naming logic, and reconciliation queries now use the effective key, ensuring configured stores behave identically while unconfigured stores gain a working fallback. Added 28 new unit tests covering the key resolution, RSC ladder, and issue collector.

  • Infrastructure Import folder cleanup policy with unit tests

    Created ImportFolderCleanupPolicy as a standalone, testable component with two independent safety rules: IsProtectedFolder blocks cleanup in system/program directories, and IsRemovableBackup only allows deletion of Margin Master's own backup files. Comprehensive unit tests replay the exact 72 filenames from the customer incident to ensure none can ever be deleted again. If the import path is misconfigured to point at a protected directory, the app now logs a warning instead of silently skipping cleanup.

  • Infrastructure Import cleanup policy with comprehensive test coverage

    Added ImportFolderCleanupPolicy class with IsProtectedFolder and IsRemovableBackup methods to enforce the two safety rules, plus ImportFolderCleanupPolicyTests with 31 test cases covering the exact files that were deleted in the customer incident. The rules are now directly unit-testable and cannot drift apart from the actual cleanup logic.

  • Infrastructure Store configuration issue collector service

    Added IStoreConfigurationIssueCollector singleton to gather "this store isn't configured correctly" observations across an import run. Import subsystems report issues as they discover them; MainMMViewModel drains and displays them once at the end. Deduplicates store/issue pairs automatically so per-store loops don't create duplicate notices.

  • Documentation Updated Store Manager and Epicor troubleshooting docs

    Corrected docs/marginmaster/getting-started/store-manager.md and docs/marginmaster/pos-systems/troubleshooting-epicor-zero-skus.md to reflect that a blank Vendor Store Number is no longer a cause of missing SKUs or store exclusion. Stores now import under their POS-derived key until a vendor number is assigned.

Cloud Sync & Vendor Data

  • Improvement Statistics tracking failures now degrade gracefully

    Sync statistics are diagnostic data and no longer have the authority to fail a data synchronization. If the statistics table cannot be accessed or updated (before, during, or after sync), the system will log a warning and continue syncing data without statistics for that table. Previously, a statistics recording failure at the end of a successful sync could turn the completed sync into a reported failure.

  • Bug Fix Local database contention no longer aborts cloud sync

    Previously, when the local SyncStatistics table experienced lock waits (due to multiple sync operations or database activity), the 30-second timeout would abort the entire table sync and report it as a "Cloud sync timeout" error with misleading suggestions to reduce batch size or optimize server indexes. The statistics tracking commands now use a 120-second timeout to wait out contention, and statistics failures are gracefully degraded rather than aborting the sync. Resolves issue affecting store 18788 where four Ace Hardware tables reported false timeout errors within five minutes.

  • Bug Fix Data Aging view now displays after vendor reset

    If you reset vendor data and choose to sync immediately, you'll now see the Data Aging screen as expected, and the sync will complete normally instead of appearing to freeze.

  • Bug Fix Data Aging view now displays after vendor reset

    After you reset vendor data and choose to sync immediately, you'll now see the Data Aging screen when the rebuild finishes, just like when you sync from the toolbar button.

  • Bug Fix Do-It-Best mailbox downloads now process successfully

    If you use Do-It-Best and noticed order confirmations or catalog updates weren't appearing in Margin Master, this fix restores that functionality. Purchased items will now appear in your pricing grid as expected.

  • Bug Fix Do-It-Best mailbox files now processed after download

    Order confirmations, POS reload files, and inventory updates from Do-It-Best that were downloaded from your mailbox will now be imported and visible in Margin Master instead of being silently skipped.

  • Bug Fix Fixed DIB mailbox downloads being marked as incomplete transfers

    Do-It-Best order confirmations now arrive correctly in your pricing grid. Previously, all mailbox files appeared as incomplete downloads and were never processed.

  • Bug Fix Fixed mailbox file download path handling

    Downloaded mailbox files are now correctly recognized and processed instead of being marked as incomplete transfers.

  • Bug Fix FTP download helper now returns actual filename written to disk

    Modified FTPHelperSync2.DownloadFile to return the actual path written (instead of just success/failure) so the caller and helper stay synchronized about the filename. When a remote timestamp is supplied, it's appended to prevent two same-named remote files from overwriting each other in the download folder. Also stopped flattening underscores to hyphens, which was breaking DIB's TYPE_MEMBER_yyyyMMdd-HHmmss naming convention.

  • Bug Fix Mailbox files now filed correctly into permanent storage

    Processed Do-It-Best mailbox files now appear correctly in the Local Files section, organized by member number and file type.

  • Bug Fix Fixed mailbox files not filing into member-specific folders

    Downloaded Do-It-Best files now organize properly into store-specific folders instead of failing to save.

  • Bug Fix Fixed mailbox file storage folder creation

    Mailbox files now move into the correct storage folders (MailBoxFiles\[member]\[ORDCNFM|POSLOAD|RTL_INV]) instead of failing silently.

  • Bug Fix Mailbox file archiving now uses correct folder structure

    Previously downloaded Do-It-Best files now appear properly in the "Local Files" view, organized by member and file type.

  • Bug Fix Filename timestamps now preserve DIB naming convention

    Corrected the timestamp format applied to downloaded files to maintain DIB's underscore-based naming convention (TYPE_MEMBER_yyyyMMdd-HHmmss) instead of converting all underscores to hyphens, which was breaking the expected file structure.

  • Bug Fix Preserved underscore separators in DIB filenames

    Fixed a character replacement that was converting underscores to hyphens in downloaded filenames, breaking the DIB naming convention (TYPE_MEMBER_yyyyMMdd-HHmmss) that other parts of the system parse. Filenames now maintain their original format.

  • Bug Fix Removed misleading "FTPS firewall" error for mailbox failures

    The recent change that surfaced "TransferIncomplete" dialogs blamed FTPS firewall issues when mailbox downloads failed, but this was incorrect—the failure occurred 1.1 seconds into the transfer (a blocked passive channel would have burned the full 45-second timeout), and directory listings using the same channel succeeded. The real cause was the filename mismatch, now resolved.

  • Infrastructure Added mailbox file-path contract tests

    Introduced comprehensive unit tests to verify download path construction and filing path logic, preventing future silent regressions. Tests cover timestamped downloads, member folder preservation, file-type subfolder organization, and rooted-path edge cases.

  • Infrastructure Added comprehensive test coverage for DIB mailbox file paths

    Created 10 new automated tests that verify the two path computations used in DIB mailbox processing, preventing future silent regressions. Tests confirm that timestamped downloads produce distinct filenames, member folders are preserved, and file type subfolders are created correctly.

User Interface

  • Improvement Simplified Create Support Issue button behavior

    The green "Create Support Issue" button now creates a new issue right away instead of showing a menu first, making it faster to start logging issues.

  • Improvement Simplified Create Support Issue button

    Click the Create Support Issue button to go straight to the new issue form — no more dropdown menu to navigate.

  • Improvement Update tracking protected against database timeouts

    Added a 5-second timeout cap to the update sentinel write operation to prevent blocking when the database connection string is valid but the server is unreachable. The operation runs asynchronously off the UI thread and continues with the update even if the sentinel write fails or times out, ensuring diagnostic tracking never prevents a user-requested update from proceeding.

  • Improvement Update sentinel write is fault-tolerant on database setup screen

    The update sentinel write from the database setup screen is designed to gracefully handle scenarios where no database connection exists yet (such as initial setup). The write runs off the UI thread with a 5-second timeout and swallows any failures, ensuring that database connection issues never prevent a user-requested update from proceeding. Timeouts and failures are logged for diagnostic purposes but do not interrupt the update process.

  • Bug Fix Update sentinel now tracked from database setup screen

    If you apply an update from the database setup screen and it fails multiple times, the app will now correctly offer to run a repair install to fix the problem.

  • Bug Fix Update failure tracking now works from database setup screen

    When applying updates from the database setup screen, the app now attempts to write the update sentinel to the database before restarting. This write is done on a best-effort basis with a 5-second timeout, since this screen can run before a database connection exists. The sentinel write enables tracking of consecutive update failures, which can trigger a repair install option if updates repeatedly fail. Previously, updates applied from this screen were never tracked, so existing customers updating from the "Manage Database Connections" screen would not benefit from the automatic repair install safety net.

  • User Interface Added menu bar to Support Issues window

    You can now access Quick Submit from the Actions menu at the top of the Support Issues window.

  • User Interface Added Actions menu bar to Support Issues screen

    Look for the new Actions menu at the top of the Support Issues screen to access Quick Submit for faster issue reporting.

  • User Interface Per-section empty-state text in Support Issues list

    When you have closed all your open issues, you'll now see a "No open issues" message under the Open section header instead of just blank space.

  • User Interface Added empty state messages to Support Issues sections

    You'll now see a clear message telling you when there are no issues in a section, instead of just seeing blank space.

Reporting & Exports

  • Improvement Network latency warning threshold adjusted

    Network connection tests no longer show warnings for connections that are working normally but happen to be a bit slower due to distance from the server.

  • Improvement Standardized version reporting in diagnostics

    Connection diagnostic reports for MySQL and FTP connections now use the standardized semantic version format (e.g., "3.2.1") instead of the assembly version, providing clearer and more consistent version information when troubleshooting with support.

  • Bug Fix Update health tracking now scoped per workstation

    If you work at a store with multiple workstations, you should no longer see incorrect "Margin Master could not install an update" messages caused by another computer's update activity.

  • Bug Fix Failure counter now clears after successful updates from any source

    If the "Margin Master Update Problem" dialog previously suggested a repair install, that repair will now properly clear the error state and stop the daily notifications.

  • Bug Fix Stale update sentinel no longer leaves failure counter stuck

    Update status tracking is now properly reset when Margin Master updates through alternate installation methods.

  • User Interface Connection report text wrapping enabled

    Connection test results now display in an easier-to-read format that doesn't require scrolling left and right.

Performance & Reliability

  • Improvement Improved connection timeout handling consistency

    Changed exception handling for connection timeouts from TaskCanceledException to the more general OperationCanceledException, and reduced timeout logging from Error to Warning level since timeouts are expected behavior when servers are unreachable rather than exceptional conditions.

  • Improvement Faster follow-up update checks preserved

    Fixed the 10-minute quick-check timer being overridden on startup. After applying an update, the app deliberately checks for follow-up fixes more frequently (every 10 minutes instead of hourly) to quickly pick up any hotfixes. This accelerated check now persists correctly instead of being reset to the standard one-hour interval.

  • Bug Fix Support Issues screen crash resolved

    The Support Issues screen will now open correctly without crashing when accessed from Support Tools.

  • Bug Fix Support Issues Actions menu crash resolved

    The Actions menu in Support Tools now opens correctly without causing the application to crash.

  • Bug Fix Eliminated unobserved exception crash during database connection testing

    When the app tests a connection to a database server that is offline or unreachable, you will no longer see delayed error messages or crashes appearing 15-20 seconds after the connection attempt.

  • Bug Fix Database connection timeout handling improved

    When the application tests a database connection that times out (such as when the server is unreachable), it now handles the timeout cleanly without causing the application to crash several seconds later.

  • Bug Fix Auto-update retry loop prevention

    If Margin Master can't install an update after trying twice, it will stop restarting on its own. You can still update anytime using the Help menu.

  • Bug Fix Auto-update retry prevention for failed versions

    If an update fails to install on your computer, Margin Master will stop trying to install that specific version automatically. You can still install it manually using the "Update Ready" button or Help menu, and when a newer version is released, it will try that one automatically.

  • Bug Fix Update problem dialog now properly notifies users

    If there's an update problem, you'll now see a dialog offering to repair the installation instead of the app restarting before you can respond.

  • Bug Fix Update problem dialog timing correction

    The update problem dialog will now reappear on the next launch if it was closed automatically due to a restart, ensuring you always have a chance to see it and choose a repair option.

  • Bug Fix Auto-update check timer preservation

    Corrected timer initialization logic to preserve the accelerated 10-minute check interval that is set after a successful update. Previously, the startup routine unconditionally set a 1-hour interval, overriding the shorter interval meant to help machines quickly pick up follow-up fixes after an update.

  • Bug Fix Blocked automatic updates for specific failed versions

    The automatic update system now consults the failure counter (AutoUpdateConsecutiveFailures) before attempting installation. Previously this counter was recorded but never checked, causing the hourly timer and 7-day forced-update override to repeatedly attempt the same version that had already failed. The block is version-specific—new releases always get attempted since locks are often transient.

  • Infrastructure Exception handling refinement

    Changed connection timeout exception handling from catching TaskCanceledException to the more appropriate OperationCanceledException, and downgraded timeout logging from Error to Warning level since timeouts are expected failure scenarios rather than exceptional errors.

Other Changes

  • Improvement Changed behavior for recurring support issues

    If an issue you previously marked as resolved happens again, the system will now help you file a new follow-up ticket that references the original one, making it easier for support to see the full history.

  • Improvement Changed 'Not Resolved' action to create follow-up issue

    If you previously marked a support issue as resolved but the problem comes back, clicking "Alert support that this issue is NOT resolved" will now create a new follow-up issue instead of reopening the old one.

  • Improvement Streamlined follow-up issue creation

    When you create a follow-up from a closed issue, you'll now skip the contact selection screen and go straight to describing the problem, saving time since it automatically uses the same contact as before.

  • Improvement Follow-up issues automatically reuse original contact

    When you create a follow-up issue, the same contact person from your original issue is automatically selected.

  • Improvement Automatic RSC defaulting for unmatched stores

    When Store Manager can't determine a store's RSC from your POS system or existing settings, it will now automatically use the RSC that most of your other stores use, saving you from having to fill in missing RSCs manually.

  • Improvement Auto-populate blank RSC codes with organization majority

    If a store is missing its RSC code, Store Manager will automatically fill it with the RSC used by most of your other stores, saving you from entering it manually.

  • Improvement Live Support link includes store context

    Your store information now transfers automatically when you open Live Support chat, so support staff can see your store details right away.

  • Improvement Streamlined backup metadata reading

    The Restore Database screen now loads backup file information faster, especially when working with large database backups.

  • Bug Fix Eliminated IPWorks Zip license validation failures

    Fixes an issue where the application would sometimes fail to read or create ZIP files due to license validation errors, especially on terminal server environments.

  • Bug Fix StoreNumber normalization no longer corrupts store-group tables

    Fixed a bug that caused Margin Master to freeze for several minutes during startup when using store groups. Store selection and historical pricing data now work correctly for grouped stores.

  • Bug Fix Corrected button availability for follow-up creation

    Fixed the condition for enabling the "Create a new issue from this one" button to check IsResolved instead of IsClosedFinal, allowing follow-up creation from any resolved issue, not just those fully closed by support.

  • Bug Fix Live Support errors now logged

    Failures when opening the Live Support URL are now logged instead of silently swallowed, making it easier to diagnose issues when the browser fails to launch or the URL is malformed.

  • Bug Fix Fixed license loading timing issue in Restore Database window

    The Restore Database window now works correctly when opened during initial application startup.

  • Bug Fix ZIP read failures now surface in Restore Database file list

    If a ZIP backup file is corrupt or unreadable, the Restore Database screen now shows what went wrong instead of hiding the file from the list.

  • Data Import Do it Best mailbox uploads use built-in ZIP compression

    DIB mailbox batch file uploads now compress inventory files using System.IO.Compression. The archive layout (files stored under bare file names with no directory component) matches what IPWorks Zip produced, so Do it Best receives the same format.

  • Data Import Do it Best mailbox archive format preserved

    ZIP archives created for Do it Best mailbox uploads continue to store files under their bare file names (no directory structure), matching the exact layout that Do it Best expects. This maintains compatibility with the vendor's systems despite the underlying compression library change.

  • User Interface Simplified resolve/reopen logic on Support Issues screen

    The resolve button on support issues now only marks issues as resolved—it won't reopen them. To report a recurring problem, use the "NOT resolved" or "Create a new issue from this one" option instead.

  • User Interface Simplified issue resolution workflow

    Removed the reopen functionality from the MarkResolved command. The action now only supports marking issues as resolved (one-way), simplifying the workflow and preventing confusion between reopening and filing follow-ups.

  • User Interface Submit Issue wizard now supports direct navigation to submission step

    Added StartOnSubmitStep flag to the Submit Issue wizard, allowing certain workflows (like follow-ups) to bypass earlier wizard steps when all required information is already known. The wizard validates that a contact is selected before allowing direct navigation to step 3.

  • User Interface Follow-up wizard opens directly on submission step

    The follow-up form now skips contact selection and opens ready for you to describe the problem and submit.

  • User Interface Store Manager RSC display improvements

    The Store Manager screen now applies the majority RSC default during initialization, right after loading cloud store settings. The defaulted RSC is persisted to the database using the existing `UpdateDatabaseFromCloud` path, ensuring the value is saved and remains consistent. The process is logged with details about how many stores were defaulted and which RSC was used.

  • User Interface Submit Issue wizard supports pre-selected contacts

    Added PreSelectContactId and StartOnSubmitStep properties to SubmitIssueViewModel to support the follow-up flow. The pre-selected contact is resolved against the freshly loaded store and support contacts list, ensuring the prior contact is still valid and available before auto-selecting it.

  • User Interface Restore Database dialog now uses built-in ZIP extraction

    Database restore from ZIP files works the same way, but is now more reliable when opening archives created by earlier versions of the software.

  • User Interface Updated startup license report

    Removed IPWorks Zip from the component license validation report shown during application startup. The report now shows only IPWorks FTP and IPWorks SFTP, which remain as licensed components. The NSoftwareLicenses:IPWorksZip configuration key is now ignored.

  • Database Per-table tracking of StoreNumber normalization

    Changed the normalization tracking from a single session flag to a per-table HashSet. Previously, the first table lookup would mark the work as complete for the entire session, causing any tables that appeared later to silently skip normalization for the remainder of the session. Each table is now tracked individually and normalized exactly once per session, even if it's discovered after other tables have already been processed.

  • Database Scoped to Store Manager display only

    This change affects only the Store Manager's RSC display and persistence (`StoreManagerInfo.RSCCode` table). The legacy pricing-join RSC source (`GlobalFileConfig.STORERSC` setting) remains unchanged, ensuring backward compatibility with existing pricing workflows.

  • Architecture Store context URL builder consolidated

    Created a shared StoreContextUrlBuilder service that both the What's New page and Live Support link use to build URLs with store context parameters. This eliminates duplicate URL-building logic and ensures consistent store identification across all external web pages the application opens.

  • Architecture New table classification helpers for main table types

    Added IsStoreGroupMainTable() and ShouldNormalizeStoreNumber() helper methods to distinguish between per-store tables (Epicor_1316_mainTable), store-group tables (StoreGroup_Core_mainTable), and all-stores tables (mainTable). These helpers enforce that StoreNumber normalization only applies to per-store tables where it's semantically correct, preventing data corruption in tables with different grain structures.

  • Infrastructure Removed nsoftware IPWorks Zip dependency

    Eliminated the nsoftware IPWorks Zip component after recurring machine-specific node-check failures ("Could not find a valid license on this system") that persisted across multiple key rotations and affected backup restore operations on customer machines. All ZIP operations now use System.IO.Compression, which is part of the .NET framework and requires no licensing.

  • Infrastructure RSC majority calculation with unit tests

    Added StoreManagerRscHelper.ComputeMajorityRsc, a pure function that identifies the most frequent non-blank RSC value. Includes comprehensive unit tests covering edge cases (all blanks, ties, whitespace handling, case-insensitivity) to ensure the majority is computed correctly and reproducibly.

  • Infrastructure Consolidated ZIP operations into single helper class

    ZIP file operations for database backups are now faster and more reliable.

  • Infrastructure New ZipFileHelper utility class

    Created ZipFileHelper to wrap System.IO.Compression with async support, progress reporting, and compatibility with archives previously created by IPWorks Zip. Includes comprehensive test coverage, including verification that backup metadata stored in ZIP comments by the old component can still be read.

  • Infrastructure Unit test coverage for RSC majority calculation

    Added comprehensive unit tests that verify the majority RSC calculation against real-world data distributions (e.g., Great Lakes Ace: H=71, I=8, N=1, blank=18 → H). Tests cover edge cases including empty inputs, all-blank values, clear majorities, deterministic tie-breaking, and whitespace/case handling.

  • Infrastructure Removed IPWorks Zip runtime license configuration

    Removed IPWorksZip license key from appsettings.json, Azure Key Vault retrieval in the publish workflow, startup validation, and the IPWorksLicenseService. The three ApplicationSettingKey enum entries (IPWorksLicenseFTP, IPWorksLicenseSSH, IPWorksLicenseZip) are now marked as legacy/unread to preserve existing database rows and enum ordinals.

EpicorFalconPaladinRockSolidTransactWestLakeCloudSyncDoitBest
2026.729.31240
July 29, 2026

Release notes aren't available for this version.

2026.728.31346
July 28, 2026

Release notes aren't available for this version.

2026.727.37411
July 28, 2026

Release notes aren't available for this version.

2026.726.32673
July 27, 2026

BisTrack network import root with automatic branch file ingest; BisTrack network import root with automatic per-branch file collection; Purchase order number tagging for BisTrack items.

Strategy & Pricing

  • New Feature AI-powered rounding scheme analysis

    The AI assistant examines your rounding scheme's annual profit impact, shows which price-ending transitions (like .79→.99) generate the most revenue, identifies high-impact SKUs, and calculates charm pricing percentages. Results appear in an easy-to-read dialog that helps you understand whether a scheme is worth activating.

  • New Feature AI-powered rounding scheme analysis

    In the Rounding Scheme editor, click the new "Analyze with AI" button to get a detailed analysis of how the selected scheme will affect your pricing. The AI examines your actual sales data to show total profit impact, which price endings change most, and which individual products drive the biggest gains or losses. This helps you understand the real-world effect before applying a scheme.

  • New Feature Deterministic strategy review scoring engine

    Strategy reviews now show consistent, reproducible scores every time you review the same strategy—the math is stable and auditable.

  • New Feature AI pricing strategy review and scoring

    When you ask the AI to review a pricing strategy, it will score how well the strategy is working across multiple factors like how many items it prices, how consistently it uses rounding rules, and how many exceptions are needed—all on a simple 0-100 scale.

  • New Feature AI strategy review and scoring system

    When you ask the AI assistant to review your pricing strategy, it now provides a detailed 0-100 score showing exactly where your strategy is strong or weak, with specific recommendations for improvement prioritized by volume impact.

  • New Feature Strategy execution summary screen

    After running a pricing strategy, you'll see a summary showing how long it took, how many steps ran, and how many items were affected. Each step shows its status so you can quickly see if anything failed or was skipped.

  • New Feature AI Review button in Pricing Strategy Manager

    When you click "AI Review" in the strategy manager, the system will check if your strategy has been run recently. If not, it will offer to run it first so the AI can review your actual pricing results and give you accurate feedback.

  • New Feature Strategy execution summary dialog

    After running a pricing strategy, you'll now see a summary showing how long it took, how many products were affected, and what happened in each step. If AI is enabled, you can click "AI Review" to get feedback on your strategy.

  • New Feature Profit impact display on Strategy Execution Summary

    When you finish running a pricing strategy, the summary window now shows exactly how many profit dollars you'll gain or lose and what your margin will change from and to (for example, "30.0% -> 35.0%" and "+$2,500 gained").

  • New Feature Cloud upload checkbox in Strategy Backup dialog

    When backing up your strategy, check "Upload to Cloud" to save a copy to the Margin Master cloud in addition to the local file.

  • New Feature Strategy execution performance tracking

    Reviews now identify which pricing steps waste time updating products that later steps re-price, helping you eliminate slow, unnecessary work from your strategy.

  • New Feature Strategy review snapshot persistence

    Strategy reviews now show up-to-date scores immediately after running a strategy, without waiting for the AI to recalculate.

  • New Feature AI-powered strategy review from summary

    If AI is turned on, you'll see an "AI Review" button on the summary screen. Click it to get an AI-powered analysis of your pricing strategy's effectiveness, including a scorecard and recommendations based on the items that were just repriced.

  • New Feature AI Review button in Manage Pricing Strategies

    The strategy manager now has an "AI Review" button that analyzes your active pricing strategy and provides recommendations. The system will ask you to run the strategy first if it hasn't been executed recently.

  • New Feature Unified local/cloud restore source picker

    When restoring, you now pick your backup source (Local or Cloud) in one dialog, then choose what to restore from that backup.

  • New Feature Tabbed Local/Cloud restore picker

    Restoring a strategy now shows a single dialog with Local and Cloud tabs, so you can pick from either source without opening multiple windows.

  • New Feature AI strategy analysis tools

    You can now ask the AI questions like "Which products aren't being priced by my strategy?" or "Show me which strategy steps are being overridden by later steps" and get detailed answers.

  • New Feature AI strategy analysis tools

    You can now ask the AI assistant questions like "What's my strategy score?", "Which items aren't being priced?", or "Show me my strategy steps" and get detailed answers.

  • New Feature Manager-initiated strategy review with run requirement

    Before running an AI review of a strategy that hasn't been executed recently, you'll be asked if you want to run it first so the AI can analyze real data instead of just the rules.

  • Improvement Strategy backup cloud upload now uses Azure blob storage

    Strategy backups now upload to the cloud more reliably and can handle larger files without timing out.

  • Improvement Strategy cloud backup uses blob storage

    Strategy backups to the cloud are now more reliable and have no file size limits.

  • Improvement Rounding dimension now compares to vendor-default scheme

    The AI now scores your rounding schemes by comparing them to your vendor's standard scheme. Tighter schemes (fewer price points) score higher because they capture more margin.

  • Improvement SKU-level exceptions performance optimization

    The "SKU Level Exceptions" step in strategy execution now runs about 4 times faster.

  • Improvement SKU exceptions deduplication and conflict resolution

    If you have multiple exceptions for the same SKU, the newest one now automatically wins, and the summary will tell you how many conflicts were resolved.

  • Improvement Exact organization-level margin calculations

    Margin calculations for multi-store strategies are now more accurate, especially when stores have different sales volumes.

  • Improvement Strategy steps wait for in-progress rebuilds instead of failing

    Strategy steps now wait up to 10 minutes for panel rebuilds to finish, ensuring they read the correct field configuration instead of randomly failing with false "field missing" errors.

  • Improvement Startup splash screen ownership tracking

    Implemented an ownership tracking mechanism for the freshness check splash screen, matching the pattern already used by other startup operations like LoadColumnUsingViewManagerAsync. The `ownsSplash` flag ensures that only the code path that displayed the splash is responsible for hiding it, preventing scenarios where one operation accidentally closes a splash screen that another operation is still using.

  • Improvement Improved delete confirmation message

    When deleting a custom group, the confirmation message now tells you exactly how many items will be removed.

  • Improvement Enhanced delete confirmation message

    When deleting a Custom Group, the confirmation message now tells you how many SKUs will be removed.

  • Improvement Enhanced backup selection with DevExpress tree control and cloud upload checkbox

    When backing up, you'll see an improved checklist tree showing what's available to back up, and you can choose to upload to the cloud at the same time.

  • Improvement Strategy cloud backup remembers upload preference

    When backing up your strategy, the "Upload to Cloud" option will remember your last choice.

  • Improvement Non-vendor SKU pricing coverage (dimension 3)

    The AI now checks that items without vendor pricing (like custom or special-order items) have proper cost-based pricing rules set up.

  • Improvement Conflicting exception detection and logging

    The strategy summary now shows how many duplicate SKU exceptions were skipped, with the most recent exception being applied when conflicts occur.

  • Improvement Accurate error messages distinguish rebuild timing from missing fields

    If a strategy step fails to load, the error message will now tell you whether the selection panel was being rebuilt (a timing issue you can fix by re-running) versus a field actually being missing from your view layout.

  • Improvement Smart de-duplication prevents redundant cloud uploads

    If your strategy hasn't changed since the last cloud upload, the system won't waste time uploading an identical copy.

  • Improvement Strategy cloud restore reads from blob storage

    When restoring a strategy from the cloud, you'll see backup file names and sizes more clearly in the restore dialog.

  • Improvement Strategy-scoped exception and step counting

    Exception counts in strategy reviews now show only the exceptions that actually belong to that strategy, not unrelated exceptions from other strategies in the database.

  • Improvement PricingStrategy-code reliance penalty

    The AI now warns when your strategy relies on vendor pricing codes (A/B/C/D) because items next to each other on the shelf can have different codes, making rules unpredictable.

  • Improvement Strategy execution workflow enhancement

    Strategy execution now captures comprehensive summary data including per-step results, processing duration, and termination status. This data is immediately available to the new summary dialog and persisted for AI review operations, ensuring the review process has access to the most recent execution metrics.

  • Improvement Hardened validity gate for profit analysis

    Incorrectly entered future prices (like accidentally typing $0 or an unrealistic amount) will no longer throw off your profit and margin calculations.

  • Improvement Enhanced backup tree view with DevExpress TreeViewControl

    The backup selection tree is easier to read and automatically focuses on your pricing strategies when opened.

  • Improvement Refined rubric definitions for accuracy

    The AI now gives more accurate guidance about rounding improvements, correctly identifies when non-vendor items need special pricing rules, and warns about risky pricing patterns that could make shelf neighbors inconsistently priced.

  • Improvement Catch-all and cross-hierarchy hygiene refinements

    The AI now only flags "ALL" catch-all rules when they're not at the end of your strategy, where they belong.

  • Improvement Exclude built-in views from backup and restore selection

    The backup and restore dialogs now only show views you created, not the built-in default views.

  • Improvement Strategy cloud backup retention policy

    The cloud will keep your 3 most recent strategy backups automatically.

  • Improvement Enhanced hygiene detection

    The AI can now tell you exactly which strategy steps are using unstable name fields instead of reliable codes, and warn you when a catch-all rule is positioned incorrectly.

  • Improvement Exclude built-in views from backup selection

    The backup tree now shows only your custom views, not the built-in system defaults.

  • Improvement Strategy completion workflow optimization

    The strategy execution summary now appears immediately after completion instead of waiting for the price changes grid to load.

  • Bug Fix Backup and restore now preserve inactive SKU exceptions

    All pricing exceptions on a strategy are now safely preserved when backing up and restoring, even if they're temporarily turned off.

  • Bug Fix Store-specific SKU exceptions now preserved during backup and restore

    When you back up and restore a pricing strategy, SKU exceptions that were set for specific stores will now stay assigned to those stores instead of incorrectly applying to all stores.

  • Bug Fix Strategy steps no longer skip during selection panel rebuilds

    If a pricing strategy previously gave you different SKU counts across runs (like swinging between 588 and 600+ items), or showed confusing "field not in the current view" errors for fields that were definitely present, those issues are now fixed. All strategy steps will apply consistently every time.

  • Bug Fix Splash screen cleanup after freshness check

    When Margin Master starts up and checks your pricing data, the "Verifying pricing data..." message will now disappear as soon as the check finishes, rather than staying visible until a later step closes it.

  • Bug Fix Splash screen leak during freshness verification

    The loading screen will no longer appear to freeze on the "Verifying pricing data..." message during application startup.

  • Bug Fix Store Number column sorting corrected

    When you sort by Store Number in the pricing grid, stores now appear in the correct order (1, 2, 3... 10, 11) instead of the confusing alphabetical order (1, 10, 11... 2, 20).

  • Bug Fix Eliminated false FAILED warning for Sitting Margin History sync

    You will no longer see incorrect "FAILED" warnings when saving Sitting Margin History — the system now properly recognizes when the save completed successfully.

  • Bug Fix Store-specific pricing exceptions now restore correctly

    Store-specific pricing exceptions now remember which store they apply to when restoring from a backup.

  • Bug Fix Inactive SKU exceptions no longer lost during backup

    Inactive (turned off) SKU pricing exceptions are now included in backups so they can be recovered if needed.

  • Bug Fix Follow-up to MM-1321

    This change addresses a remaining issue from ticket MM-1321 where store 4229 reported being stuck on the "Verifying pricing data..." message. The freshness check now tracks whether it owns the splash screen and only hides it if it was the one that displayed it, preventing conflicts with other startup operations.

  • Bug Fix Prevented strategy manager from opening during execution

    You can no longer accidentally open the strategy manager while a strategy is running.

  • Bug Fix Custom group SKU descriptions preserved when copying strategies

    When copying a pricing strategy, custom group SKU descriptions now copy over instead of appearing blank.

  • Bug Fix Custom group SKU descriptions preserved when copying strategies

    When copying a pricing strategy, custom group SKU descriptions now carry over correctly instead of appearing blank.

  • Bug Fix Improved group deletion behavior

    After deleting a group, the list now automatically selects the next available group.

  • Bug Fix Strategy execution timing accuracy

    Fixed a timing bug where custom groups containing zero SKUs would leave their processing end time null, causing the next phase (SKU exceptions) to incorrectly absorb that step's elapsed time in reports. All steps now properly record their completion time regardless of the number of items processed.

  • Bug Fix Custom group SKUs attach to correct groups when copying strategies with duplicate group names

    If a strategy has multiple custom groups with the same name, copying the strategy now keeps each group's SKUs separate instead of merging them incorrectly.

  • Bug Fix SKU Level Exceptions dialog no longer shows stuck loading indicator

    The "Please Wait..." loading message in the SKU Level Exceptions screen no longer gets stuck after the data has finished loading.

  • Bug Fix Early returns from BuildSelectionBoxesAsync no longer wipe the panel

    When BuildSelectionBoxesAsync returned early (no current view, or a view with no tabs), it left MainTabs cleared but never refilled it, permanently wiping the selection panel until the next successful rebuild. The panel is now only modified on successful completion.

  • Bug Fix Fixed cloud upload failure due to timestamp changing mid-backup

    The backup filename includes a timestamp (now HHmmss format), but BackupFileName was re-evaluating DateTime.Now on every read. During a single backup operation, the write/zip/cloud-read steps targeted different files, causing "could not find file" errors during cloud upload. The filename is now stamped once at the start of each backup (BeginNewBackupFile) and reused throughout. Same-day backups no longer overwrite each other thanks to the time component.

  • Bug Fix Duplicate cloud strategy backups avoided

    If your strategy hasn't changed since the last cloud backup, the system won't upload a duplicate copy to the cloud.

  • Bug Fix Fixed duration calculation for empty custom groups

    Corrected the processing time calculation for custom groups that matched zero SKUs. Previously these groups would show inflated durations in the summary because the timer wasn't properly stopped, absorbing time from subsequent processing phases.

  • Bug Fix SKU Level Exceptions screen now shows wait indicator during load

    The SKU Level Exceptions screen now shows a "Please Wait" indicator while loading large exception lists instead of appearing frozen.

  • Bug Fix Strategy backup filename stability for cloud uploads

    Cloud uploads now work reliably, and multiple backups on the same day no longer overwrite each other.

  • Bug Fix Internal tombstone records no longer copied to new strategies

    The CopySkuExceptionsAsync method lacked the DUPLICATE filter present in all other queries against the SKU exceptions table, carrying retired tombstone records into each new strategy. These internal markers are now excluded from copy operations.

  • Cloud Sync Automatic strategy review snapshots

    Your strategy scores update automatically each time you run a pricing strategy, so the AI always shows you the latest analysis without any delay.

  • Cloud Sync Enhanced telemetry for organization-level profit reporting

    The system now persists the underlying sales and gross profit dollar totals (both current and future price scenarios) when posting sitting margin data to the cloud. This enables Margin Master Manager to compute exact organization-level profit metrics by simple summation across stores and groups, replacing the previous inventory-weighted approximation. The profit gained or lost is calculated as the difference between future and current gross profit totals (ΣGrossProfitFP − ΣGrossProfitCP).

  • Cloud Sync AI instruction fetching and message proxying through Manager

    Extends ApiClientService with GetAiInstructionsAsync (fetches the editable system prompt markdown from api/v2/ai/instructions) and SendAiMessagesAsync (proxies Claude requests through api/v2/ai/messages with Bearer token, X-AI-Feature/Session-Id/Sequence metering headers, and a 120-second timeout for tool-heavy turns). The server relays requests to Anthropic using RetailerSoft's key, so no API key configuration is required on the client.

  • Cloud Sync Enhanced strategy execution telemetry

    Sitting margin telemetry posted to the cloud now includes dollar totals (sales and gross profit at both current and future prices) in addition to margin percentages, allowing the cloud to aggregate profit metrics exactly across any organization structure. Store and group-level summaries persist these values for accurate regional and enterprise-level reporting.

  • Data Import Improved data quality filtering for profit analysis

    Strategy profit projections are now more reliable and won't be thrown off by pricing errors in your data.

  • User Interface Per-row delete button added to custom groups grid

    Each custom group row now shows a small delete icon on the right side. Click it to remove that group after confirming.

  • User Interface Per-row delete buttons in Manage Custom Groups

    Each Custom Group now has a delete button (trash icon) next to it for quick removal.

  • User Interface Simplified strategy backup/restore menu structure

    The Utilities menu now has just two strategy options: "Backup" and "Restore" instead of four separate buttons.

  • User Interface Simplified Strategy menu with two unified commands

    The Strategy menu now shows just "Backup" and "Restore" instead of four separate options.

  • User Interface "Upload to Cloud" checkbox now remembers your preference

    The "Upload to Cloud" option on the strategy backup screen will now remember whether you had it checked or unchecked the last time you used it.

  • User Interface "Analyze with AI" action on Rounding Scheme screen

    Right-click any rounding scheme and choose "Analyze with AI" to get instant insights on profit impact, price changes, and recommendations. A progress indicator shows you what the assistant is doing while it works.

  • User Interface AI analysis result dialog in Rounding Scheme editor

    The "Analyze with AI" option appears in the Rounding Scheme editor's action menu when AI features are enabled. After a brief analysis period (with status updates), a window displays the results in plain text, explaining the scheme's profit impact and strategic considerations.

  • User Interface Execute-first workflow for AI strategy reviews

    The AI will only review strategies that have been recently run, so you always get feedback based on your latest pricing calculations, not outdated numbers.

  • User Interface Improved consistency between grid and dropdown

    The main pricing grid's Store Number sorting now uses the same NumericStringComparer that the store number selection box uses, ensuring consistent behavior throughout the application.

  • User Interface Strategy Execution Summary displays profit metrics

    After executing a strategy, you can now see at a glance how much your margin will change and the estimated profit impact in dollars.

  • User Interface Improved strategy execution progress and completion flow

    After running a strategy, the summary screen now appears immediately without delays, and the window no longer flickers between busy and ready states.

  • User Interface Strategy restore dialog now lists cloud backups from blob storage

    When restoring a strategy from the cloud, you'll now see a cleaner list showing file names, dates, versions, and file sizes for all available backups.

  • User Interface New dialog services for strategy analysis

    Registered two new dialog services in the main window: StrategyAiResultView for displaying AI analysis scorecards, and StrategyExecutionSummaryView for the post-run summary. Both use the standard 750×750 resizable dialog style and are center-aligned over the parent window. Added StrategyExecutionSummaryViewModel to the dependency injection container.

  • User Interface New dialog services for AI results and execution summary

    Registered two new dialog services in the main application window: StrategyExecutionSummaryView (750×750 resizable) for displaying execution results, and StrategyAiResultView (750×750 resizable) for showing AI-generated strategy analysis reports.

  • User Interface Strategy execution window control improvements

    The screen now stays properly locked during the entire strategy execution process, preventing accidental clicks that could interfere with the operation.

  • User Interface Visible upload progress during cloud backup

    You'll now see progress messages while your strategy backup uploads to the cloud instead of the app appearing frozen.

  • User Interface AI Review workflow improvement

    Clicking "AI Review" in the strategy summary now closes the summary first, then shows the AI analysis separately instead of stacking windows.

  • User Interface Enhanced execution summary dialog

    The summary screen now has clearer buttons with icons, and clicking "AI Review" smoothly transitions to the analysis without overlapping windows.

  • Database DUPLICATE tombstone records protected from accidental deletion

    Added safeguards across backup, restore, and copy operations to prevent deletion of internal DUPLICATE tombstone records. These records are now consistently excluded from operations that could make them unrecoverable, ensuring database integrity.

  • Database Read-only rounding analysis toolset

    AiRoundingToolset provides six read-only SQL tools reusing the analyze-rounding-scheme JOIN logic (RoundingSchemeDetail + Last12 volume weighting): list main tables, list schemes, get active scheme, score a scheme (items changed, up/down split, annual impact, charm %), show top ending transitions by profit, and list top SKUs by absolute impact. Table names are validated against sys.tables; scheme IDs are int parameters. Results are returned as JSON arrays (up to 50 rows for table queries, top 12/20 for aggregates).

  • Architecture Client-side agentic loop service

    Implements AiAssistantService, which orchestrates the full tool loop: fetch instructions, send a user prompt, parse tool_use blocks in the assistant's response, execute each tool via AiRoundingToolset, return tool results as a new user message, and repeat up to 12 iterations until the model returns a stop_reason other than "tool_use". All tool execution is logged and exception-safe; errors are returned to the model as tool_result blocks with is_error=true.

  • Architecture Unit tests for scoring rubric

    Added StrategyReviewScorerTests with hand-computed baseline verification, determinism checks (byte-identical JSON on repeated scoring), hygiene penalty coverage, and volume-blind fallback scenarios, ensuring the rubric math remains stable across code changes.

  • Architecture AI toolset integration and dependency injection

    Integrated the new AiStrategyToolset and StrategyReviewService into the application's dependency injection container and merged the strategy tools with existing rounding tools in AiAssistantService. The strategy toolset is co-authored with Claude Opus 4.8 (1M context) and follows the same architectural pattern as the existing AiRoundingToolset, ensuring consistent tool definition, error handling, and JSON response formatting.

  • Architecture Sitting margin computation refactoring

    The sitting margin calculation has been refactored to return a comprehensive result object (SittingMarginResult) containing both the margin ratios and the underlying dollar totals (sales and gross profit for both current and future prices). This enables exact aggregation at any level and provides the profit delta calculation in one place. New unit tests lock down the aggregation math, margin calculations, profit delta logic, and formatted output for both gains and losses.

  • Architecture Five-test validation suite

    Added comprehensive test coverage: rubric math verification against hand-computed values, determinism (byte-identical scores for the same strategy), hygiene flag generation, non-vendor edge cases (zero non-vendor items = full marks), and volume-blind detection (zero sales history).

  • Architecture Sitting margin calculation testing

    Added comprehensive unit tests covering sitting margin aggregation logic, including dollar totals summation, margin computation, profit delta calculation, edge cases (zero sales, negative profit), and UI formatting. Tests lock the deterministic calculation behavior that feeds cloud telemetry, local execution summaries, and organization profit charts.

  • Infrastructure Client-side AI assistant service with tool loop

    Implements IAiAssistantService (AiAssistantService class) to orchestrate the full tool-calling loop: fetches system instructions via GET /api/v2/ai/instructions, builds tool definitions from AiRoundingToolset, sends each turn to POST /api/v2/ai/messages with metering headers (X-AI-Feature="AnalyzeRoundingScheme", X-AI-Session-Id, X-AI-Sequence), processes tool_use blocks by executing local tools, and loops until the model returns stop_reason != "tool_use" (max 12 iterations). Uses Claude Opus 4-8 model with 4000 max tokens and a 120-second HTTP timeout for tool-heavy turns.

  • Infrastructure Read-only rounding analysis toolset

    Adds AiRoundingToolset with six SQL-based tools validated against sys.tables (table names) and parameterized scheme IDs to prevent injection. Tools mirror the existing RoundingSchemeDetail/Last12 JOIN logic used by the analyze-rounding-scheme skill: list_main_tables, list_rounding_schemes, get_active_rounding_scheme, score_rounding_scheme (items, changed count, impact dollars, up/down split, charm %, pushed-over-whole-dollar count, above-lowest-comp count), ending_transitions (top 12 FromEnding→ToEnding by impact with item/unit counts), and top_skus_by_impact (top 20 SKUs by absolute impact with description, current/rounded price, units). Results are JSON arrays (max 50 rows) or error objects.

  • Infrastructure AI API client methods for instruction fetch and message relay

    Extends ApiClientService with GetAiInstructionsAsync (fetches markdown system prompt from GET /api/v2/ai/instructions, returns AiInstructionsDto.Instructions) and SendAiMessagesAsync (proxies raw Claude JSON request to POST /api/v2/ai/messages with X-AI-Feature/Session-Id/Sequence headers, returns HTTP status and response body for caller-driven tool loop). Both methods use bearer token authentication and the RetailerSoft server base URL. SendAiMessagesAsync uses a 120-second timeout to accommodate multi-tool turns.

  • Infrastructure Headless execution support

    Added detection for headless/service mode execution to skip showing the modal summary dialog when running without a UI, ensuring future Windows service-based strategy execution won't block waiting for user interaction.

Imports & POS

  • New Feature BisTrack network import root with automatic branch file ingest

    If your store exports BisTrack data to a network share with separate folders per branch, you can now enter that share path in Settings → Miscellaneous → Network Import Root. Margin Master will automatically find and copy the right files before each import—you no longer need to manually copy files from the network to your local import folder.

  • New Feature BisTrack network import root with automatic per-branch file collection

    In Settings > Miscellaneous, BisTrack users will see a new "Network Import Root" field. Enter a network share path (like \\server\MM\Export) that contains per-branch subfolders (Branch01, Branch15, etc.). Each time you run an import, Margin Master will automatically copy the latest files from these branch folders into your local import folder—eliminating the manual copy step.

  • New Feature Purchase order number tagging for BisTrack items

    Items from purchase orders now show their PO number in a custom field (which you can display as "PO Number" in your field settings), making it easy to filter and price items by purchase order.

  • New Feature Purchase order file processing for BisTrack

    Items from your purchase orders will now show their PO number in the "PO Number" field, making it easy to filter and analyze pricing for specific purchase orders.

  • New Feature POS export date shown in Data Aging view

    The "Last Update" date in Data Aging now shows when your POS system created the export file, giving you a more accurate view of how fresh your data really is.

  • New Feature Automatic import of new items from purchase orders

    New items that appear on purchase orders but not yet in your catalog are automatically added so you can price them right away instead of waiting for the next catalog update.

  • New Feature Automatic addition of new purchase order items

    New items on your purchase orders that haven't appeared in your POS export yet will be automatically added to Margin Master so you can price them right away.

  • Improvement Network import deduplication now based on local folder contents
  • Improvement Network import speed optimization for multi-branch stores

    Network imports for stores with multiple branches now start processing much faster instead of appearing to hang on "Begin POS Data Import."

  • Improvement Faster network branch import scanning

    Importing from network folders is now much faster, especially when bringing in data from multiple stores at once.

  • Improvement Simplified reprocessing workflow for network imports

    To import a branch file again, just delete its .BAK backup file or rename it back to .csv—no need to hunt for hidden tracking files.

  • Improvement Data Aging screen now shows actual POS export date

    The "Last Update" column in Data Aging now shows when your POS created the export, giving you a more accurate picture of how fresh your data is.

  • Improvement Enhanced splash screen cleanup reliability

    All splash screen teardown operations now include a ground-truth forced closure that closes every active splash window unconditionally. This runs before modal dialogs open and during all cleanup operations, ensuring orphaned splash screens cannot hide behind dialogs and re-surface later. The operation is safe to call repeatedly and has no effect when no splash windows are active.

  • Improvement Import history tracking enhanced

    Import processing history now records the source file's export timestamp and file name per store, providing better audit trail and data aging visibility. Previous import records for each store are automatically replaced with the latest import information.

  • Improvement Optimized drift detection SQL query

    The drift count calculation was refactored to use a derived table with a SUM aggregate instead of a simple EXISTS check, allowing accurate counting of drifted rows for threshold comparison while maintaining query performance.

  • Bug Fix Eliminate duplicate POS store numbers in Store Manager

    When viewing the Store Manager, you'll now see only one entry per store number instead of duplicate rows, making it easier to manage store assignments.

  • Bug Fix BisTrack description update failure after import

    After importing BisTrack data, product descriptions and custom group names now update properly instead of showing outdated information.

  • Bug Fix BisTrack import processing table resolution failure

    When importing BisTrack catalog files, the system will no longer fail with a database error. SKU exceptions and custom groups will update correctly after each import completes.

  • Bug Fix Eliminated stranded splash screen deadlock after vendor imports

    After importing vendor catalogs, the "Finalizing…" message will now properly disappear instead of getting stuck on screen and preventing you from using the application.

  • Bug Fix Prevent false-positive drift detection from single divergent cost rows

    Stores with a few discontinued or special-priced items will no longer trigger an unnecessary pricing rebuild on every launch.

  • Bug Fix Prevent importing partially-written BisTrack export files

    Margin Master will no longer import BisTrack files that are still being written to the network. If an export is in progress when you start an import, the app will skip incomplete files and import them on the next run once they're fully written.

  • Bug Fix File stability check prevents importing incomplete exports

    Margin Master now waits for files to finish being written before importing them, preventing the issue where partial data was silently imported from files that were still being created on the network.

  • Bug Fix Store normalization for multi-branch comparison

    Store numbers are now normalized before comparison during the orphan detection process, ensuring that "01" and "1" are treated as the same store. This prevents accidental removal of stores whose numbers differ only in leading zeros between the import files and Store Manager records.

  • Bug Fix Stop repeated self-heal attempts when drift cannot be resolved

    Startup time improved from 37 seconds to 19 seconds for affected BisTrack stores by eliminating repeated rebuilds and selection list rescans.

  • Bug Fix Changed exports are now reliably reprocessed
  • Bug Fix Network import no longer overwrites active files in import folder

    The ingest now skips copying a network file if an active local file with that name already exists in the import folder, preventing the system from clobbering files that are awaiting processing or have been manually renamed back from backup for reprocessing.

  • Bug Fix Prevented branch catalog loss from PO file processing

    Fixed a serious issue where importing a purchase order file could accidentally delete most of your branch catalog, leaving only the items from that one PO.

  • Bug Fix Purchase order files excluded from branch catalog rebuild

    Processing purchase order files will no longer accidentally wipe out your branch catalog—only the items on the PO will be tagged, and your full inventory stays safe.

  • Data Import Network ingest now uses local folder state for deduplication instead of manifest

    The import process now checks your local import folder to see what's already been imported, rather than maintaining a separate hidden tracking file.

  • Data Import Automatic purge of orphaned BisTrack store data

    If your store stops exporting data for a particular branch location, that branch will automatically disappear from your store selection lists after the next import, instead of remaining as an unusable "phantom" option.

  • Data Import Orphaned store purge for BisTrack multi-branch imports

    When a store location is removed from your BisTrack system and stops being exported, its data will now be automatically cleaned up after the next import instead of remaining visible in store selection dropdowns.

  • Data Import Store number normalization for orphan detection

    Store number matching now uses the same normalization logic as the import process itself: leading zeros are stripped and whitespace is trimmed, so store "01" and "1" are treated as identical. This ensures accurate detection of which stores are still active versus orphaned, preventing false positives that could incorrectly preserve dead data or incorrectly delete active stores.

  • Data Import Network branch ingest now copies purchase order files

    Purchase order files from your network folders will now be automatically copied and processed without affecting your regular catalog imports.

  • Data Import Automatic network branch folder filtering by store number

    Margin Master will only copy files from network branch folders that match your store numbers—any extra folders on the share (like backups or other stores' data) are automatically ignored.

  • Data Import Network ingest runs automatically before each BisTrack import

    Each time you run an import, Margin Master will first check the network share for new branch files and copy them automatically. If the network isn't available, the import continues with files already on your local computer.

  • Data Import Purchase order file parsing and validation

    Added RSImportFileHelperService.ReadPurchaseOrderFile to parse PO number from the filename (stripping "PO" prefix and extension), extract the branch from the file's Store column, and collect distinct SKUs. The method validates that the file uses the expected DIB1040 layout and contains usable data before processing. Pure filename parsing logic is separately unit-tested.

  • User Interface Improved Store Manager data integrity

    The Store Manager load query now uses a ranking system to prioritize rows with complete data over blank entries. This ensures that store mappings display the most complete and recent information available when the database contains multiple records for the same POS store number.

  • User Interface Import and export path fields now use folder picker controls

    The Import Path, Export Path, and Network Import Root fields in Settings now have a "..." browse button to pick folders, and you can still type or paste network paths directly.

  • User Interface Network Import Root folder picker added to Miscellaneous settings

    When configuring the network import root, you can click the folder icon to browse for the network share instead of typing the path manually. A warning appears if the folder can't be reached right now, but you can still save the setting.

  • User Interface Purchase order processing integrated into import workflow

    ProcessBisTrackPurchaseOrdersAsync now runs after branch builds and orphan purging but before the post-processing queue in the main import flow (MainMMViewModel.ImportData1.cs). The splash screen displays progress for each PO being processed, and detailed logging tracks PO counts, items tagged, and new items added. Errors are reported via the standard import error notification without blocking the main import.

  • Infrastructure Network share remains strictly read-only

Cloud Sync & Vendor Data

  • Improvement Diagnosed and resolved sync failures at Hills Flat Lumber Co (store 5645)
  • Improvement Prioritized error messaging in sync dialog

    The sync failure dialog now checks for damaged runtime conditions first before falling back to connectivity or generic error messages, ensuring the most specific and actionable error information is always shown to the user.

  • Bug Fix Orphaned splash screen cleanup

    The "Finalizing..." screen that appears during sync will no longer get stuck on your screen, blocking you from using Margin Master.

  • Bug Fix Cloud sync failure dialog now surfaces .NET runtime repair instructions
  • Bug Fix .NET runtime damage detection in sync failures

    If sync fails because your .NET installation needs repair, you'll now see a clear message telling you to repair or reinstall .NET Desktop Runtime, instead of being told to check a log file.

  • Cloud Sync Improved splash screen lifecycle management

    Added fallback logic in the Main Table view model to unconditionally close all active splash screens during teardown operations. This ensures that even if the splash service's state tracking becomes inconsistent, no visual elements will remain orphaned on screen.

User Interface

  • New Feature AI Services settings tab

    A new AI settings section has been added to the Options screen where AI features can be turned on or off for this computer.

  • New Feature AI Options tab with master enable switch

    You'll see a new "AI (Artificial Intelligence)" tab in Settings. It starts as OFF and requires the support password to enable. Once enabled, future AI-powered pricing tools will become available.

  • Improvement Dramatically faster exception list loading

    The Sku Level Exceptions window now loads much faster, and the progress bar updates smoothly instead of appearing frozen.

  • Improvement Dramatically faster loading for SKU Level Exceptions

    Large lists of SKU exceptions now load much faster, and you'll see smooth progress updates instead of the window appearing frozen.

  • Improvement Enhanced duplicate row selection logic

    When multiple database records exist for the same POS store number, the system now intelligently selects the best record by prioritizing rows with populated vendor store numbers and RSC codes, then falling back to the most recently updated record. This ensures users always see the most complete and current store information.

  • Improvement Numeric-aware store number sorting

    Store numbers in dropdown lists now sort in natural numeric order (1, 2, 10 instead of 1, 10, 2).

  • Improvement Numeric store number sorting across exception and custom group dialogs

    Store numbers now appear in numeric order (1, 2, 10) instead of alphabetical order (1, 10, 2) throughout the exception and custom group screens.

  • Bug Fix Removed duplicate store entries in Store Manager

    If you previously saw the same store listed multiple times in Store Manager, you'll now see just one row per store with the most complete information displayed.

  • Bug Fix Restore dialog now uses actual database names by default

    When you select a backup to restore, the suggested restore name will now be the original database name (like "MM_1372_ImportTest") instead of a newly generated name that might have dashes or underscores from your store name. This prevents database name errors and makes it easier to identify which backup you're restoring.

  • Bug Fix Store Number column now sorts numerically in Main Table

    When you click the Store Number column header to sort your pricing data, stores now appear in the correct numerical order. For example, Store 2 will now appear before Store 10 instead of after it.

  • User Interface Resizable Exceptions window with improved grid layout

    You can now resize the Sku Level Exceptions window to see more data at once. The delete button stays visible even with long store lists, and you can scroll horizontally to see all columns.

  • User Interface Resizable SKU Level Exceptions window

    You can now resize the SKU Level Exceptions window to see more rows and columns at once.

  • User Interface Password-protected feature activation

    Enabling AI services requires entering the support password ("Sunshine", case-insensitive) in a modal dialog, mirroring the security model used by the Background Service tab. Disabling the feature does not require a password. This ensures AI capabilities are only activated on machines where pre-release testing is intended.

  • User Interface Grid sorting and filtering enabled

    Click any column header to sort the list, or use the filter dropdown to find specific exceptions quickly.

  • User Interface Password-protected AI enablement

    Turning on AI services requires entering a support password; turning it off does not require a password.

  • User Interface Token usage placeholder panel

    The AI tab includes a "Token Usage & Allowance" section that currently displays placeholder text. This panel is prepared to show token consumption and monthly allowance information once the server-side metering and billing APIs are implemented in future phases.

  • User Interface Enhanced grid column behavior

    Added minimum and maximum widths to key columns, enabled sorting and filtering on all data columns, and improved text wrapping and tooltip display for store lists that exceed the column width.

  • Database New application setting for AI feature flag

    Added AIServicesEnabled to the ApplicationSettingKey enumeration. This boolean setting (default false) controls whether AI services are enabled machine-wide and will gate the visibility of all AI-related actions and panels throughout the application.

  • Infrastructure Machine-level AI visibility gate

    Introduced ApplicationSettingKey.AIServicesEnabled, a new machine-local setting that defaults to FALSE. This serves as the single master switch for all AI functionality across the application. When disabled, no AI actions, panels, or features are visible anywhere in the app — Margin Master behaves exactly as it did before. This allows the AI feature to ship in a completely dark state and be revealed only on machines where it is deliberately enabled during the pre-release phase.

Reporting & Exports

  • New Feature Export AI results to browser for printing and PDF

    You can now click "Open in Browser (Print / PDF)" to open the AI analysis in your web browser, where you can print it or save it as a PDF file.

  • New Feature Browser export for print and PDF

    Click "Open in Browser (Print / PDF)" to open the review in your web browser, where you can print it or save it as a PDF using your browser's File menu.

  • Improvement Friendlier progress messages during AI analysis

    The progress window during AI analysis now shows clearer status messages like "Scoring the strategy" instead of technical tool names.

  • Improvement Friendlier AI progress messages

    The progress splash during AI analysis now shows clearer messages like "Finding coverage gaps" instead of technical tool names.

  • Improvement Standardized version numbers in diagnostic reports

    Diagnostic reports now display the canonical application version format (e.g., 2026.726.32673) instead of the raw assembly version (e.g., 20.26.726.32673), matching the version shown in the title bar. This applies to both FTP and MySQL/Compass connection diagnostics.

  • Bug Fix Fixed false "slow/unstable connection" warnings

    Connection tests no longer show false warnings about slow speeds on normal internet connections.

  • User Interface AI results display as formatted HTML

    When you view AI analysis results, tables and headings now display properly formatted instead of as raw text with pipe symbols.

  • User Interface HTML rendering for AI review output

    AI reviews now show formatted tables, headings, and styled text instead of plain text with markdown symbols.

  • User Interface Connection report window now wraps text

    Connection test reports are now easier to read without needing to scroll sideways.

  • User Interface AI result dialog now fills available space

    The AI result dialog no longer uses a fixed-size text box. The browser control and its border now expand to fill the dialog, and the dialog itself has minimum dimensions (640×480) but can be resized for better readability of large reports.

  • User Interface Resizable AI result dialog

    You can now resize the AI review window to see more content at once.

Performance & Reliability

  • Bug Fix Application crash during column drag operations

    Dragging column headers to rearrange columns or set up grouping now works reliably without causing the application to crash.

  • User Interface Updated grid header styling across all screens

    Modified nine grid header styles across multiple screens including the Main Table, Excel Import dialogs, Cost Break analysis, SKU-Level Exceptions, and Store Manager views. The styling changes are internal only—all headers maintain their current visual appearance (left/right/center alignment, bold formatting) while now properly supporting column drag operations.

Other Changes

  • New Feature Time-limited secure download links for cloud backups

    Download links for cloud backups now expire after 7 days for security.

  • New Feature Create follow-up issue from closed support tickets

    When viewing a closed issue, click "Create a new issue from this one" to report a related problem. The form will automatically include a reference to the original issue.

  • Improvement Database restore naming behavior updated

    When you restore a database backup, the suggested database name will now match the original backup's name instead of creating a new name, making it clearer which database you're restoring.

  • Improvement New workflow for following up on fully-closed support issues

    If a problem comes back after support has fully closed your issue, you'll now click "Create a new issue from this one" instead of "Reopen". This automatically fills in a new issue form that references your original issue, so support can see the history while keeping proper records.

  • Improvement Support issue state now distinguishes user-resolved from staff-closed

    If you mark an issue resolved, you can still reopen it if the problem persists. If support closes an issue, you'll create a new follow-up issue instead of reopening the old one.

  • Improvement Support ticket pre-filling now more accurate

    You won't accidentally report update problems to support when everything is actually working fine.

  • Improvement Cancel option for unusually long startup operations

    If startup is taking longer than expected, you'll now see an explanation and a Cancel button that lets you choose whether to wait or return to the app.

  • Improvement Enhanced elapsed time display during long operations

    The progress window now shows elapsed time in a clearer format and explains that work will continue in the background if you choose to cancel.

  • Improvement Folder browse dialogs open at current path

    When browsing for import/export folders in Settings, the dialog now starts at your current folder instead of the desktop, making it easier to adjust existing paths.

  • Improvement Improved SQL connection timeout messaging

    When SQL connection diagnostics time out after 5 seconds, users now see a clearer message: "Cannot connect to port {port} within the timeout. The server may be unreachable or the port blocked." This provides better guidance when troubleshooting unreachable SQL servers in the Settings screen.

  • Improvement Folder picker starts at current backup location

    The backup folder browse dialog in the Restore Database window now opens at the current backup path (matching the Options window behavior) instead of the system default location.

  • Improvement Backup filenames include timestamps for uniqueness

    Multiple backups created on the same day now create separate files instead of overwriting each other.

  • Improvement Backup completion now generates secure links

    After completing a backup, the "Copy Link" button now gives you a secure link that expires after 7 days.

  • Bug Fix Update-health warning incorrectly triggered after successful update

    If Margin Master successfully updated itself when you launched it, you will no longer see a confusing warning message about update problems on that same launch.

  • Bug Fix Update deferral warning no longer shows after successful update

    Fixed MM-1336 where the "you've been behind on updates for N days" prompt could appear immediately after the application successfully updated itself. When an update completes successfully, the deferral tracking is now properly reset, preventing the stale anchor from incorrectly triggering the overdue update dialog on the same launch that just updated.

  • Bug Fix Splash screen no longer disappears during legitimate long-running operations

    On slower computers or with large catalogs, the startup screen will no longer disappear while work is still happening, preventing the app from appearing frozen.

  • Bug Fix Splash screen escalation replaces force-close for long operations

    If the startup progress window stays on one step for more than 2 minutes, you'll now see a "Still working" message with how long it's been running and a Cancel button. You can click Cancel if you believe it's stuck, or wait if you know the operation is still working (like downloading large updates).

  • Bug Fix Database switching now works on first click

    Switching between databases in the database menu now works immediately on the first click.

  • Bug Fix Database switch now responds to first click

    Switching databases from the database menu now works immediately on the first click.

  • Bug Fix Restore link copy confirmation now appears in strategy picker

    After copying a database restore link from the strategy picker, you'll now see a confirmation message letting you know the link was copied successfully and how long it remains valid.

  • Bug Fix Eliminated unobserved task exceptions in SQL diagnostics

    Fixed a diagnostic routine that left background socket connection attempts unobserved when testing SQL connections to dual-stack or multi-address servers that were unreachable. This caused delayed SocketExceptions to surface on the finalizer thread (fingerprint a6c90c8e, 16 occurrences across 6 stores). The connection test now uses a bounded 5-second timeout with proper cancellation, matching the pattern already used throughout the fleet for network probing, ensuring all pending attempts are properly observed and canceled.

  • Bug Fix Folder pickers now open at current location

    When browsing for Import, Export, or Network Import folders in Settings, the folder picker now opens at your currently configured location instead of the desktop.

  • Cloud Sync Cloud backup retention increased to 3 backups

    The system now keeps your 3 most recent cloud backups, so you have more restore points available if needed.

  • Cloud Sync Cloud backup retention increased to 3 backups

    Your last 3 cloud backups are now saved instead of just 1, giving you more restore points if you need to recover data.

  • Cloud Sync Private storage containers with SAS authentication

    Your cloud backups are now stored privately and can only be accessed with secure download links.

  • Cloud Sync Private blob storage containers with SAS authentication

    Cloud backup files are now stored securely and cannot be accessed without a special download link.

  • Cloud Sync Time-limited download links for cloud backups

    Download links for cloud backups now expire after 7 days for added security.

  • User Interface Clipboard confirmation for backup download links

    When you click the copy icon next to a cloud backup, you'll now see a message confirming the download link was copied to your clipboard and explaining it works for 7 days.

  • User Interface Backup Complete summary reorganized with tabs

    After a backup, local and cloud details are now on separate tabs for easier reading, and you can quickly copy the cloud download link with one click.

  • User Interface Backup Complete summary redesigned with tabs

    After a backup, the summary window now shows local and cloud details on separate tabs for easier reading, and you can copy the cloud download link with one click.

  • User Interface Restore dialog default name logic improved

    The restore screen now makes better decisions about what to name your restored database based on where the backup came from.

  • User Interface Updated Take Action menu in Support Tools

    The right-click menu on support issues now shows different options depending on whether you marked it resolved or support fully closed it.

  • User Interface Enhanced elapsed time display on splash screen

    The splash screen's "still working" elapsed timer now shows hours when operations exceed 60 minutes (format changes from "m:ss" to "h:mm:ss"), providing better visibility for exceptionally long operations.

  • User Interface Confirmation dialog before canceling long-running operations

    If you click Cancel during a long operation, you'll be asked to confirm whether you want to return to Margin Master, with a reminder that work will continue behind the scenes.

  • User Interface Restore Database window reorganized with lazy cloud scanning

    Restoring a backup is now clearer with Local and Cloud backups on separate tabs. Cloud backups are only scanned when you open that tab, making the window faster to load.

  • User Interface Restore Database dialog reorganized with Local/Cloud tabs

    When restoring a database, local and cloud backups now appear on separate tabs for easier navigation.

  • User Interface Copy link buttons in Restore Database screen

    Click the new copy link icon next to any cloud backup to get a secure download link that you can share with support or use on another computer.

  • User Interface Copy link buttons added to restore backup grids

    You can now click a copy button next to any cloud backup to get a secure download link.

  • User Interface Support Issues screen button visibility updated for issue states

    The Support Issues detail view now shows different action buttons based on whether an issue is user-resolved (Resolved status) or staff-closed (Closed/ClosedResolved statuses). The "Reopen Issue" button only appears for user-resolved issues, while "Create a new issue from this one" appears for staff-closed issues.

  • User Interface Copy link buttons in Strategy Restore picker

    Strategy backup downloads now use secure, expiring links that you can copy with one click.

CloudSync
2026.726.25444
July 26, 2026

Release notes aren't available for this version.

2026.725.42077
July 26, 2026

Release notes aren't available for this version.

2026.725.32452
July 25, 2026

Release notes aren't available for this version.

2026.723.39461
July 24, 2026

Release notes aren't available for this version.

2026.723.23865
July 23, 2026

Release notes aren't available for this version.

2026.625.23688
July 23, 2026

Reset Point of Sale Data command; Restore Backup button added to startup Database Setup window; Restore Backup option during startup.

Strategy & Pricing

  • New Feature CPP Reason column added to Ace Critical Pricing results

    The pricing grid now shows exactly why each item appears in your Ace Critical Pricing report, making it easier to understand which pricing rules each item violated without needing to manually compare prices.

  • New Feature Set PowerShell Execution Policy script

    When running PowerShell installation scripts manually (outside the app), Windows will no longer block them with "scripts cannot be loaded" errors.

  • New Feature View toggle system for upcoming screen redesigns

    Two screens now have "Use New View" and "Use Legacy View" buttons that let you switch between the current version and an upcoming redesigned version.

  • New Feature Complete V2 Strategy Manager implementation

    You can now use the new Strategy Manager to create and edit pricing strategies, reorder steps using toolbar buttons or keyboard shortcuts (Ctrl+click to move by 5, Alt+click to jump to top/bottom), manage custom product groups, configure SKU-level exceptions, and export strategies to Excel.

  • New Feature V2 Strategy Manager interface

    The Strategy Manager now responds immediately when you click on different pricing steps, making it much faster to review and edit your pricing strategy.

  • New Feature Inline condition value editor in V2 Strategy Manager

    Click the small pencil icon next to any condition (like "Department equals:" or "Vendor equals:") to open a list of all values. Click the red × button next to any value to remove it from the condition. If you remove all values, the entire condition is removed. Changes are tracked and can be saved or discarded normally.

  • New Feature Reset button in condition editor popup

    When editing pricing strategy conditions, you can now click the "Reset" button at the bottom of the popup to undo your changes and restore the original condition values. This is helpful if you've made changes and want to start over without closing the editor.

  • New Feature Reset button in condition editor popup

    When editing conditions in a pricing strategy step, you can now click the "Reset" button (located next to the "Close" button) to undo any changes you've made and restore the original values. This is helpful when experimenting with different settings and wanting to start over.

  • New Feature List Price column for MSRP data

    A new "List Price" column is now available to view manufacturer suggested retail prices. To see this column, open the Column View editor and add "List Price" to your visible columns. This is especially useful for tracking MSRP on products like Stihl where distributor pricing may not be visible.

  • New Feature List Price (MSRP) column added to Main Table

    You can now add a "List Price" column to your pricing views to see the manufacturer's suggested retail price for each item, which is especially helpful for analyzing pricing on products like Stihl equipment.

  • New Feature List Price added to pricing strategy targets

    When the List Price column is visible, you can now choose it as a target when setting up automatic pricing rules. The system will remember this choice when you reload your saved strategies.

  • New Feature Add/subtract price modifiers for SKU exceptions

    When creating SKU-level pricing exceptions, you can now adjust prices up or down by specific amounts or percentages, giving more flexibility than just setting fixed prices.

  • New Feature Cloud-based Strategy Backup

    A new "Backup Strategy to Cloud" option saves your pricing strategy settings to cloud storage, and "Restore Strategy from Cloud" retrieves them. These options appear in the Strategy menu below the local backup options.

  • New Feature Fixed retail price toggle for cost break levels

    In the cost break editor, you can now check "Fixed Price" for any cost range and enter a specific retail price. For example, items costing $5.00-$10.00 could all be priced at $12.99 instead of using a margin percentage.

  • New Feature Fixed retail price toggle for cost break levels

    In the cost break screen, each pricing level now has a "Fixed Price" checkbox and "Fixed $" field. Check the box to set an exact retail price for items in that cost range, or leave it unchecked to use margin-based pricing like before.

  • New Feature Charm pricing offset for increment rounding

    In the Rounding Editor's increment rounding section, a new "Subtract" field lets you automatically adjust rounded prices. Enter -$0.01 to create .99-ending prices, or use other values for different pricing patterns like .95 or .97 endings.

  • New Feature Charm pricing offset for increment rounding

    Added a "Subtract" field to the Increment Rounding configuration in the Rounding Editor. After rounding to the nearest increment (e.g., $10.00), the system now subtracts the specified offset amount, enabling charm pricing strategies. For example, with a $1.00 increment and $0.01 offset, prices round to $9.99, $19.99, etc. instead of $10.00, $20.00. The offset is stored as the second value in the rounding level's Points array and applied in the SQL pricing calculation.

  • New Feature Margin Master Diagnostic Tool standalone application

    The Diagnostics tool helps identify and fix common setup problems like missing SQL Server, network issues blocking cloud sync, incorrect POS file formats, and database connection errors.

  • New Feature SQL Server upgrade and installation tools

    The AI assistant can now walk you through upgrading your SQL Server to the latest version (2025 Express), installing or updating SQL Server Management Studio, and updating Margin Master itself. Just ask the AI for help and it will guide you through each step, including showing you any error messages if something goes wrong.

  • New Feature DIB-2 psychological rounding scheme added

    When using DIB-2 pricing, items will round to different price endings based on Do it Best's latest recommendations—for example, items between $10-$19.99 will only end in .49 or .99, and items between $20-$49.99 will only end in .99.

  • New Feature DIB-2 rounding scheme

    When calculating retail prices using the DIB-2 scheme, prices will round to psychological price points (like $4.99 or $19.49) based on December 2025 Do it Best guidelines.

  • New Feature MFG Cost field available in pricing strategy rules

    When building pricing rules or setting future prices, you'll now see "MFG Cost" as an option in the field dropdown, right below List Price. Use it the same way you would any other cost or price field.

  • New Feature MFG Cost field added to pricing grid

    A new "MFG Cost" column is now available in your pricing grid. You can show or hide it like any other column, and it will display manufacturer cost information when available.

  • New Feature Update failure detection and escalation

    When an update fails twice or Margin Master has sat on an old version for 3 days, you'll see a "Could Not Update" dialog explaining what went wrong. It only asks once a day, and stops appearing once an update goes through.

  • New Feature Added MAPP pricing display for Ace Hardware

    When looking up Ace Hardware items, you can now see MAP and iMAP pricing directly in the Catalog Lookup window.

  • New Feature Cloud strategy restore re-enabled

    From the Backup menu, you can now select "Restore Strategy from Cloud" to automatically download and apply your most recent cloud-saved pricing strategy. The app will restart with your restored settings.

  • New Feature AI-powered log analysis with Claude integration

    The tool can now automatically read your Margin Master logs and use AI to suggest what might be causing errors or sync problems.

  • New Feature Automated SQL Server 2025 upgrade workflow

    The AI will now automatically detect whether your SQL Server can be upgraded in-place or if a new instance is needed, and will explain what it's doing and why at each step.

  • New Feature Added MAPP pricing display for Ace Hardware items

    Ace Hardware products now show MAP and iMAP pricing restrictions when you look up catalog items.

  • New Feature Cloud restore for pricing strategies

    You can now restore your pricing strategy from your most recent cloud backup, similar to how database restore works.

  • New Feature Automatic strategy backups on key operations

    Strategy backups now happen automatically whenever you save changes to strategies, rounding rules, or exceptions—no need to manually back up after every change.

  • New Feature SQL Server installation detection and automated setup

    The tool automatically detects if SQL Server is installed and can install SQL Server 2022 Express for you if needed.

  • New Feature PowerShell execution policy script

    A new script in the Support Tools menu helps fix issues where Windows blocks PowerShell scripts from running.

  • New Feature Post-dialog actions and saved selection handling

    When you load a saved selection or custom group from the Strategy Manager and close the dialog, the main pricing grid automatically updates to show those items.

  • New Feature POS file format validation module

    You can now validate a POS export file before importing to see if it matches the expected format for your POS system — this helps catch file format issues early.

  • New Feature Network and cloud connectivity diagnostics

    The tool tests your network connection to the cloud sync server, POS systems, and checks if firewalls are blocking required ports.

  • New Feature PowerShell execution engine for advanced diagnostics

    Added PowerShellEngine service and PowerShellRunnerModule to execute ad-hoc PowerShell commands with real-time output capture. Used internally by other modules for Windows Firewall checks, service management, and WMI queries. Also available as a standalone module for support staff to run custom diagnostic scripts.

  • Improvement Background SKU reconciliation for MySQL Compass

    MySQL Compass imports now complete much faster because cleanup tasks run quietly in the background once per week instead of during every import.

  • Improvement Critical Pricing Protection reason display
  • Improvement Expanded character support for strategy names

    When creating or editing a strategy name, you can now type < and > characters. For example, you could name a strategy "Spring <2026> Promotion" or "Items >$100".

  • Improvement Optimized strategy reset query performance

    The "Reset Strategy" step before applying new pricing rules now completes much faster, especially for stores with large product catalogs.

  • Improvement Strategy backups upgraded to V2 format

    Strategy backups now save more of your settings and preferences, giving you better protection for your pricing configuration.

  • Improvement Automatic full strategy backup

    When you back up your pricing strategy, everything is now included automatically—no need to choose what to back up.

  • Improvement One-click strategy backup

    When you backup your strategy, it now happens immediately without asking what to include — just click and it's done.

  • Improvement Optimized IsDirty flag calculation in strategy grid

    Changed the IsDirty flag to be cached with a backing field instead of being recalculated on every access through service calls. This reduces over 834 redundant service calls down to a single cached value that updates only when the underlying data changes, dramatically improving grid rendering performance.

  • Improvement Cached dirty state tracking for strategy steps

    The grid now caches each step's "dirty" (unsaved changes) state instead of recalculating it every time the grid refreshes. The dirty indicator is only recalculated when a property actually changes, dramatically reducing unnecessary computation during scrolling and editing.

  • Improvement Optimized strategy grid rendering performance

    The strategy list grid now loads and displays much faster when you open the Manage Pricing Strategies dialog.

  • Improvement Faster dialog load time

    The Manage Pricing Strategies dialog now opens noticeably faster, especially for strategies with many steps.

  • Improvement High-performance step reordering in Pricing Strategy editor

    When you move pricing strategy steps up or down using the toolbar buttons or right-click menu, the movement now happens instantly without lag, even in strategies with hundreds of steps.

  • Improvement Instant step reordering in pricing strategies

    When you reorder pricing strategy steps using drag-and-drop or arrow keys, the moves now happen instantly without delays. Your changes are saved to the database when you click the Save button.

  • Improvement Simplified step editor data binding

    Clicking between strategy steps in the editor now happens instantly without any delay.

  • Improvement Automatic strategy continuation after view switch

    When you're running a strategy and the app suggests switching to a different view that has the fields you need, clicking "Yes" will now switch the view and continue running your strategy immediately — you no longer need to click the Run button again.

  • Improvement List Price added to price comparison dropdowns

    When viewing List Price in the pricing grid, you can now select it from the price comparison dropdowns to compare it against other pricing levels.

  • Improvement Batch processing for SKU-level exceptions

    When running pricing strategies with many SKU exceptions, the process now completes much faster — what previously took 10-15 minutes now finishes in under a minute.

  • Improvement Single-click inline editing for Future Price column

    Click once on any Future Price cell to start typing a new price directly in the grid—no need to open the full product details window.

  • Improvement Simplified rounding logic for pricing calculations

    Streamlined the rounding algorithms used in margin and markup calculations to ensure consistent results across all pricing screens and reports. This reduces edge cases where rounding differences could cause slight discrepancies in displayed values.

  • Improvement Alphabetical sorting for custom groups

    When viewing custom groups, they now appear in A-Z order by name, making it easier to quickly find a specific group using the browser's search feature.

  • Improvement Smart throttling for automatic cloud strategy backups

    The automatic backup system now compares the current pricing strategy content against the last uploaded version using a hash comparison. If the strategy content is identical and was uploaded within the past 4 hours, the cloud upload is skipped. Any genuine change to pricing strategies triggers an immediate upload regardless of timing. This reduces redundant cloud uploads while ensuring all meaningful changes are backed up promptly.

  • Improvement Smart throttling for automatic cloud strategy uploads

    The system now skips uploading your pricing strategy backup to the cloud if nothing has changed since the last upload within 4 hours, making the backup process more efficient.

  • Improvement Partial execution of strategy steps with missing category values

    When running a pricing strategy, if a step looks for categories that don't exist in your store (like a Department or Vendor Category that was removed or never imported), the step will now apply to the categories that do exist rather than stopping. You'll see a message showing which categories will be used and which are missing.

  • Improvement Abort now opens strategy editor for failed steps

    After aborting a failed strategy step, the strategy editor now opens automatically showing the problem step, so you can fix it immediately.

  • Improvement Strategy failure now loads selection for review without data refresh
  • Improvement Optimized future price reset query performance

    The "Reset Future Prices" operation in the pricing grid now runs significantly faster, especially noticeable in stores with tens of thousands of products.

  • Improvement Optimized SKU exception description updates using batch queries

    The SKU Level Exceptions screen now loads significantly faster, especially at stores with many SKU exceptions.

  • Improvement Optimized description cleanup for SKU exceptions
  • Improvement Cancellation support for background reconciliation

    The background SKU reconciliation process now properly supports cancellation when the application is closed, preventing potential database connection issues during shutdown. A dedicated cancellation token source ensures the background task terminates cleanly.

  • Improvement Added diagnostic logging for strategy switching

    Added detailed timing logs throughout the strategy switching process to measure performance at each step (event firing, saving dirty changes, cache hits vs database loads). This will help diagnose any future performance issues and provides visibility into how long each phase of the switch takes.

  • Improvement Enhanced strategy step count display

    The loading screen now shows how many items are in each pricing step as it loads (for example, "Loaded SKU exceptions (1,234 items)").

  • Improvement Faster strategy step parsing

    Strategy step parsing now executes entirely on a background thread between progress updates, rather than switching back to the UI thread for each of the 118 steps. This significantly improves load times while maintaining accurate progress reporting at 5% intervals.

  • Improvement Progress bar updates remain smooth during strategy loading

    The progress bar now updates smoothly when loading strategy steps, so you can see continuous progress instead of it appearing to hang.

  • Improvement Enhanced Critical Pricing transparency

    You can now instantly see whether an item was flagged for being priced below cost, above MAP, or violating IMAP rules, along with whether it was based on Current Price (CP) or Future Price (FP).

  • Improvement Simplified Do-It-Best pricing display to match web app

    Do-It-Best product pricing now shows a simpler view with just Suggested Retail, Level 1, and Level 2 prices, matching what you see in the web app.

  • Improvement Faster update checks after applying an update

    If the application updates itself, it will check for additional updates after 10 minutes instead of waiting a full hour, helping you get important follow-up fixes faster.

  • Improvement Faster update check after automatic updates

    After Margin Master updates itself, it will check for additional updates sooner (10 minutes instead of 1 hour), helping you get fixes faster.

  • Improvement Strategy deletion now removes all related data

    Deleting a pricing strategy now removes all associated configuration data, ensuring a cleaner removal.

  • Improvement Automatic execution policy checks in all installation scripts

    Installation scripts now configure themselves to run when launched manually, reducing setup friction for support staff.

  • Improvement Strategy Manager loading performance optimized

    The Strategy Manager dialog now opens noticeably faster, particularly for stores with complex pricing strategies.

  • Improvement Simplified strategy grid cell styling

    Reduced complexity in the XAML styling rules for strategy step rows by consolidating multiple conditional styles. Inactive rows show with gray background, unsaved changes show italic/bold text, and inactive steps with unsaved changes show purple background. The styling logic is now more efficient with fewer conditional checks.

  • Improvement Instant step selection with ViewModel hot-swapping

    Clicking between strategy steps in the grid now updates the detail panel instantly, with no loading spinner or delay.

  • Improvement Instant step reordering operations

    Moving pricing strategy steps up or down is now instant with no delay or screen flicker, even in strategies with many steps.

  • Improvement Optimized pricing strategy editor responsiveness

    The pricing strategy editor now feels more responsive when making changes to step order.

  • Improvement Optimized step dirty-checking logic

    Improved the performance of detecting unsaved changes in strategy steps by short-circuiting the expensive rule text comparison when step name or sequence has already changed. This reduces unnecessary text parsing operations during step manipulation.

  • Improvement Keyboard shortcuts for bulk step movement

    You can now quickly reorganize pricing steps using Alt+Arrow to jump to top/bottom or Ctrl+Arrow to move 5 positions at once.

  • Improvement Performance optimization for dirty state tracking

    Introduced a lightweight MarkDirty() method that sets the dirty flag and updates the UI without invoking the full instruction comparison logic. This improves responsiveness when moving multiple strategy steps, as the system no longer needs to regenerate and compare instruction text just to show the yellow highlight.

  • Improvement Added lightweight dirty marking for better performance

    Introduced a direct MarkDirty() method that sets the dirty flag without recalculating the entire instruction text, improving responsiveness when moving multiple steps in quick succession.

  • Improvement Pre-load first strategy step to eliminate click delay

    Clicking on the first pricing strategy step now responds instantly with no delay.

  • Improvement Saved selection loading moved to dialog

    If you have items selected when opening Pricing Strategy, the selection now loads inside the dialog with a progress message.

  • Improvement Faster deletion of pricing strategy steps

    Deleting a pricing strategy step now happens instantly and automatically selects the next step for editing.

  • Improvement Optimized change detection for pricing strategies

    The change tracking system now monitors specific user actions (move/delete operations, step property changes) and sets a dirty flag immediately, rather than recalculating the entire strategy state on every check. The flag is cleared after successful save operations or when switching between strategies.

  • Improvement Optimized change tracking for strategy steps

    Refactored the IsDirty property to use a backing field and only raise property change notifications when the value actually transitions from clean to dirty or vice versa, preventing redundant UI updates and evaluations.

  • Improvement Enhanced save operation logging

    Added PRE-SAVE and POST-SAVE log entries during the save-and-close operation to help diagnose any future issues with the save workflow timing and sequence.

  • Improvement Enhanced save diagnostics for close-after-save workflow

    Added diagnostic logging before and after save operations when closing the pricing strategy editor, making it easier to troubleshoot any issues with the save-and-close workflow.

  • Improvement Optimized cost break name loading performance

    The SKU-level exceptions screen will now load much faster, especially when viewing many exceptions at once.

  • Improvement Strategy manager now defaults to V2 view each session

    Each time you open Margin Master, the pricing strategy manager will open in the new view. If you switch to the legacy view, that choice will only last until you close the application.

  • Improvement Faster and more reliable scheme copying and deletion

    The Edit Rounding Scheme window no longer reloads the entire scheme cache after copy or delete operations, making these actions significantly faster. Copy operations now automatically select the newly created scheme and display a confirmation message. Delete operations navigate back through your selection history (similar to a browser's back button) rather than jumping to an arbitrary scheme.

  • Improvement Enhanced rounding scheme copy workflow

    Streamlined the copy scheme operation to update the in-memory cache automatically without requiring a full refresh of all schemes from the database, improving performance when duplicating rounding schemes.

  • Improvement Optimized single-row updates in Main Table grid

    Streamlined the grid update logic to refresh only the affected row rather than recreating the entire product collection. The existing PropertyChanged notification and RefreshRow mechanisms already handle the visual update correctly, making the collection recreation redundant.

  • Improvement Formula system enhanced for List Price support

    The pricing formula generation and parsing logic now handles List Price as a target level, ensuring strategies can be saved with List Price targets and correctly reloaded from stored formulas. This maintains consistency with existing price level options like Comp1-Comp5 and vendor-specific pricing fields.

  • Improvement List Price available in Set Future Price dialog

    Ace Hardware stores can now choose List Price as the target when setting future prices, making it easier to align pricing with vendor list prices.

  • Improvement Clearer countdown behavior in error dialogs

    Updated the countdown logic to be more explicit: the timer only runs for the IgnoreAndContinue action, which is the only safe option to auto-execute. This prevents potentially destructive actions (Abort) from running automatically without explicit user confirmation.

  • Improvement Added method to force rounding scheme list refresh

    Introduced a ReloadRoundingSchemes method in the Future Price panel that clears the cached rounding scheme data and triggers a UI refresh. This ensures the dropdown always displays current data after operations that modify or reload the scheme configuration.

  • Improvement Simplified detection logic for marker steps

    Streamlined the code that identifies special marker steps by removing an unreliable action-based check and relying solely on step name pattern matching, making the detection more robust and easier to maintain.

  • Improvement Enhanced batch logging for SKU exceptions

    Added detailed logging for each formula combination processed during SKU exception batching, recording the ActionType, RoundingScheme, and number of SKUs affected per combo. This improves troubleshooting capabilities when investigating performance or accuracy issues with SKU-level pricing exceptions.

  • Improvement Future Price column updates immediately when toggling edit mode

    When you enable or disable Future Price editing in Settings, the Main Table updates immediately to show or hide the editing capability.

  • Improvement Enhanced batch grouping for SKU exceptions
  • Improvement Enhanced batch grouping for SKU exceptions

    The batch execution engine now groups SKU exceptions by action type, rounding scheme, AND plus/minus modifier together. This ensures that exceptions with different adjustment formulas are processed separately with the correct SQL calculation logic, while still batching SKUs with identical settings for performance.

  • Improvement Enhanced batch processing for SKU exceptions

    SKU exceptions are now grouped by action type, rounding scheme, AND the add/subtract modifier, ensuring that all three factors are considered when optimizing batch updates. This prevents exceptions with different adjustment rules from being incorrectly grouped together while maintaining fast batch performance.

  • Improvement Added POS-specific import script support

    Import processing now checks for POS-specific InsertIntoMainTable.sql scripts (e.g., BisTrackInsertIntoMainTable.sql) before falling back to the generic import routine. When a POS-specific script exists, it bypasses the intermediate _Store table and reads directly from the _current table, allowing for optimized queries tailored to each POS system's data structure. The duplicate removal step is automatically skipped when using these optimized scripts since they guarantee no duplicates.

  • Improvement Better SQL timeout and connection error logging

    SQL timeouts and closed-connection errors are now logged as warnings instead of errors, reducing noise in logs during large data operations. These conditions are expected during intensive operations like syncing large catalogs and don't represent actual system failures.

  • Improvement Enhanced SKU resolution for custom group management

    Added a new SKU resolution method that searches across all main tables (by primary SKU first, then by AltSku) to ensure items are always stored using their canonical SKU identifier, regardless of which identifier format the user enters.

  • Improvement Enhanced SKU resolution logic in Custom Groups

    Improved the logic that checks whether a SKU already exists in a Custom Group by comparing resolved primary SKUs rather than the entered value, and added cleanup of stale database entries to maintain data consistency.

  • Improvement Preserved DIB-1 scheme for legacy support

    If you're already using DIB-1 pricing, nothing changes—your current price rounding will continue to work exactly as before.

  • Improvement Rounding scheme selection

    You can select either the older DIB-1 or newer DIB-2 rounding scheme when analyzing margins and calculating retail prices.

  • Improvement Enhanced strategy error messages for missing filter values

    Error messages during strategy execution are now clearer about whether a step will run with partial data or must be skipped entirely.

  • Improvement Ignore option consistently skips failed steps

    The "Ignore" option now always skips problem steps completely, making the behavior more predictable.

  • Improvement Better error logging for failed pricing strategies

    Strategy execution failures that occur before any steps complete will now properly write summary logs, making it easier to diagnose issues like database mapping problems or configuration errors that prevent strategy execution from starting.

  • Improvement Automatic cleanup of old strategy execution logs

    Strategy execution logs older than 30 days are now automatically purged when a new strategy execution begins. This prevents the logs directory from growing indefinitely while retaining recent history for troubleshooting.

  • Improvement Automatic log cleanup for strategy execution

    Strategy execution logs older than 30 days are now automatically purged when a new strategy run begins. This prevents log files from accumulating indefinitely and consuming disk space while retaining recent execution history for troubleshooting.

  • Improvement Unified numeric field handling for Falcon imports

    Created a shared helper function that consistently processes numeric fields (prices, costs, quantities, and sales history) across both Falcon CSV and Excel import paths. This ensures both import methods handle edge cases identically and prevents similar issues in the future.

  • Improvement Rounding scheme editor now shows saved rollback settings

    When you edit a custom rounding scheme that uses rollback rules, the rollback settings section will now appear automatically instead of staying hidden.

  • Improvement MFG Cost available in pricing strategies

    When creating pricing rules or strategies, you can now select "MFG Cost" as a price level to base your calculations on, giving you another option for automated pricing decisions.

  • Improvement Elevated logging for empty custom groups from Debug to Warning

    You'll now see a clear warning message if a custom group is set up but won't actually change any prices, helping you identify configuration mistakes.

  • Improvement Enhanced logging for empty custom groups

    Store managers will now see a clearer warning message when a custom pricing group is set up incorrectly and won't apply any changes.

  • Improvement User notification when updates are deferred

    If you trigger an update check manually while exporting prices or running a strategy, you'll see a friendly message explaining that the update will install automatically once you're done.

  • Improvement Active database targeting for maintenance dialog

    The Database Maintenance dialog now scopes operations to the currently active Margin Master database by name, rather than applying maintenance across all databases on the server. Combined with the ownership filter, this ensures maintenance operations are both targeted and safe.

  • Improvement Skip legacy data migration during strategy execution

    The system now skips old-format migration and deduplication processes during strategy execution. These one-time data cleanup operations are deferred to when the SKU Level Exceptions screen is opened directly, preventing them from blocking pricing operations.

  • Improvement Strategy definition filtering enhancement

    Strategy step loading now explicitly excludes 'PLACEHOLDER' entries from the GlobalFileConfig table, in addition to 'Custom Groups' and 'Sku Level Exceptions', ensuring only valid strategy steps are processed during execution.

  • Improvement Simplified Do-It-Best pricing display

    Do-It-Best pricing in Catalog Lookup now shows the three most important price points (Suggested Retail, Level 1, Level 2) without extra clutter.

  • Improvement Removed rarely-used restore options

    The restore dialog now shows only the most commonly needed options, making it simpler to choose what to restore.

  • Improvement Strategy Manager rendering optimized

    Strategy Manager opens faster when working with large pricing strategies.

  • Improvement Cached rounding scheme collections

    Rounding scheme dropdown lists are now cached instead of allocating new collections on every access, reducing memory allocations and improving responsiveness when editing strategy steps.

  • Improvement Cached rounding scheme collections

    Rounding scheme dropdown lists are now cached in the ViewModel instead of being recreated on every access, reducing memory allocations and improving UI responsiveness when interacting with the rounding settings.

  • Improvement Enhanced startup contention handling

    Increased database lock retry logic from 3 to 5 attempts with longer timeouts (10s instead of 3s) for GlobalFileConfigService operations during application startup. This prevents initialization failures when multiple services read configuration data concurrently, particularly when loading the Strategy Manager alongside other screens.

  • Improvement Added MarkClean method to strategy step display model

    Implemented a new MarkClean() method that directly clears the dirty flag on strategy steps without the expensive recalculation path, improving performance during save operations while ensuring accurate dirty state tracking.

  • Improvement Dramatically improve SKU Exceptions loading performance

    The SKU Level Exceptions screen now loads much faster, especially when you have many exceptions configured.

  • Improvement Enabled lazy loading for cost break values in Future Price panel

    Changed cost break values to load only when needed rather than immediately when the panel initializes. This reduces unnecessary database queries and improves overall responsiveness.

  • Improvement Strategy backups no longer include database connection data

    New strategy backups created going forward will not include the DatabaseConnections.json data, reducing backup file size and eliminating the possibility of accidentally restoring incorrect connection settings. This aligns strategy backups with the existing blob-backup behavior, which already excluded this machine-specific infrastructure data.

  • Improvement Enhanced backup restore verification

    Tested with a customer backup file containing 431 strategy steps across 5 strategies (DEFAULTSTRATEGY with 140 steps, JWN ACE 2021 with 147 steps, SKUCOUNTS with 137 steps, and others), verifying all strategies appear correctly in the UI with accurate step counts.

  • Improvement Future Price Panel rounding scheme validation improved

    Saved pricing selections will load correctly even if the rounding scheme name's capitalization has changed.

  • Improvement Extended timeout for variance recalculation

    Increased timeout protection for price variance recalculation and related maintenance operations to ensure these operations complete successfully on large datasets.

  • Improvement Backup file size reduced

    Removed 627 lines of dead code that attempted to serialize rounding schemes as entity objects. Rounding schemes now flow through the existing GlobalFileConfig backup mechanism, eliminating duplicate storage paths and reducing backup file complexity.

  • Improvement Enhanced SKU Level Exceptions execution logging

    The strategy execution log now shows detailed information about SKU-level exceptions processing, including how many exceptions were found and applied, making it easier to verify your pricing overrides are working.

  • Improvement Dynamic Future Price editing toggle

    Turning Future Price editing on or off in Options now takes effect immediately without restarting Margin Master.

  • Improvement Click-to-set Future Price feature now respects inline editing mode

    The existing click-to-set Future Price feature (which copies values from other columns) now properly defers to inline editing when that mode is enabled, preventing conflicts between the two editing methods.

  • Improvement Added support for additional pricing source columns in batch exceptions

    Enhanced the batch exception SQL generator to support additional pricing source columns including RETAILZONE, FUTUREPRICE, STORECOST, LISTPRICE, and Ace Hardware-specific fields (MSURetail, MapPriceAmt, ImapPriceAmt). This ensures that SKU-level exceptions can reference these columns when calculating exception prices.

  • Improvement Manual and automatic backups use consistent vendor identification

    Both user-initiated manual backups and automatic scheduled backups now consistently use the numeric vendor ID, ensuring all backups are properly categorized in the cloud storage system regardless of how they were triggered.

  • Improvement Enhanced cost break SQL generation

    The pricing calculation engine now checks if a cost break level uses fixed pricing before applying margin-based calculations. When a level has fixed pricing enabled with a valid price, the SQL generator creates a CASE statement that returns the fixed price directly. Warning messages for excluded levels now indicate whether the exclusion is due to zero margin or disabled fixed pricing.

  • Improvement Better handling of SQL timeout error logging

    Modified DatabaseService2 to log SQL timeout errors (error -2) and subsequent "connection is closed" errors as Warnings instead of Errors. These conditions are expected during large-table operations and do not represent actual failures, reducing false alarm noise in diagnostic logs while still recording the events for troubleshooting.

  • Improvement Enhanced SQL Server instance detection and recommendations

    The get_sql_instances_detail tool scans all local SQL instances, checks versions against the SQL 2025 target (version 17.x+), identifies MarginMaster-only vs. mixed-database instances, and provides a RecommendedAction field (run_sql_express_upgrade, run_sql_express_install, or none) with upgrade block reasons (e.g., "Contains non-MarginMaster databases"). The AI uses this data to guide users through the correct upgrade path.

  • Improvement Added safety net for rounding scheme misconfiguration

    While the underlying rounding schemes should be updated to cover the full price range of items they're applied to, this guard prevents catastrophic pricing errors when schemes are misconfigured or applied too broadly. A comment in the code notes that fixing the rounding scheme definition is the correct long-term solution.

  • Improvement Added safety documentation for rounding scheme configuration

    Added inline documentation noting that while the UpperLimit guard prevents incorrect prices, the underlying rounding scheme should be properly configured to cover the store's actual price ranges. The guard is a safety net, not a substitute for correct rounding scheme setup. Stores using custom schemes should verify their schemes cover all relevant price points.

  • Improvement Strategy detection query added for fresh installs

    Added a new database query that retrieves all existing strategy names from GlobalFileConfig during application startup. This query enables the auto-detection logic and runs only when no active strategy has been previously set, minimizing performance impact.

  • Improvement Enhanced support issue diagnostics

    When submitting a support issue (both quick submit and full issue forms), the system now automatically attaches the most recent strategy execution logs if available. The attachment collects all log files from the same execution run (within 60 seconds) and zips them together. If this attachment fails for any reason, the issue submission continues normally without interruption.

  • Improvement Strategy execution logs included in support submissions

    When you submit a support request, strategy run details are now automatically included to help the support team diagnose issues faster.

  • Improvement Auto-show exception column when relevant

    After running a pricing strategy that creates special item-level rules, the "*" column will automatically appear so you can immediately see which items were flagged—unless you've already customized where that column appears.

  • Improvement Enhanced diagnostic logging for strategy finalization

    Added logging at the start of each finalization sub-step (saving counts, resetting unchanged prices, configuring vendor SKU types, loading price changes) to improve troubleshooting when issues occur during strategy execution.

  • Improvement Standardized zone pricing table column widths

    Zone pricing columns (Retail, Level 1, Level 2, MSU Retail) now use consistent 80-pixel widths instead of proportional sizing for better readability and alignment.

  • Improvement Disabled automatic column width calculation

    Turned off BestFit column sizing which was measuring all rows on every render, contributing to slow grid display times without providing significant benefit.

  • Improvement Exposed ConvertConditions method in StrategyStepService

    Made the ConvertConditions method public and added it to the IStrategyStepService interface to support rebuilding display conditions after inline edits, enabling the ViewModel to refresh condition display after removing values.

  • Improvement Better user feedback for delete operations

    Delete operations now provide clear success or failure messages to the user. The system logs detailed information about the deletion process, including whether database records were found and whether the deleted scheme was the default.

  • Improvement Countdown stops when switching to Wait mode

    Changing your error handling choice to "Wait" immediately stops any countdown timer.

  • Improvement Enhanced SQL error handling to skip retries for permanent errors

    Modified database service to immediately stop retrying when encountering SQL errors 207 (Invalid column name) or 208 (Invalid object name), which indicate structural database problems that won't resolve with retries. This reduces unnecessary delays and log noise when database schema issues occur.

  • Improvement More accurate logging for SKU exception processing

    The "X SKUs applied" log message previously counted exception rows parsed rather than actual database rows updated, making it appear that exceptions were working when they were silently failing. The underlying count still reflects parsed rows, but the fix ensures those rows now translate to actual SQL updates.

  • Improvement Enhanced cost break level management

    Insert and delete operations for cost break levels now preserve the fixed price settings, copying UseFixedPrice and FixedPrice values when creating new levels above or below existing ones.

  • Improvement Enhanced pricing calculation SQL

    Updated the SQL-based rounding calculation engine to apply the offset amount after increment rounding is performed, ensuring the adjustment occurs at the correct stage of the pricing workflow.

  • Improvement PowerShell execution engine now prefers PowerShell 7

    The PowerShell engine now detects and uses PowerShell 7 (pwsh.exe) when available, falling back to Windows PowerShell 5.1 if not found. This eliminates CLIXML-serialized progress records that pollute stderr output in Windows PowerShell 5, resulting in cleaner captured output for AI analysis and user display.

  • Improvement Rounding preview now matches actual pricing run results

    The rounding scheme editor's "Check" preview now applies increment rounding using the same formula as the pricing run, ensuring the previewed price exactly matches what will be calculated during actual pricing operations.

  • Improvement Legacy pricing strategy rule migration

    Margin Master now starts faster when connecting to databases that have already had their pricing rules updated.

  • Improvement Execution policy handling in all scripts

    Updated all installation scripts (Install-SQLExpress.ps1, Install-SSMS.ps1, Install-OleDb12.ps1, Uninstall-SQLServer.ps1, Uninstall-SSMS.ps1, Upgrade-SQLExpress.ps1) to automatically check and set the execution policy to RemoteSigned if needed when run manually outside the app. This ensures scripts can run even if launched from Windows Explorer without requiring the user to manually bypass execution policy.

  • Improvement Extracted click-to-set price column mapping to dedicated method

    Refactored the 23-case switch statement that maps clicked column types to their source price values into a new TryGetClickToSetFuturePriceSource method, improving code readability and maintainability in the main click handler.

  • Improvement Downgraded strategy execution log levels for user-initiated stops

    Changed log severity from Error to Warning when users intentionally stop strategy execution due to load failures. This reduces alarm fatigue in logs since these are expected user decisions rather than system errors.

  • Improvement Support form pre-fill for update failures

    When you click "Contact Support" from the update dialog, the support form already has all the technical details filled in—you just add anything else you want to say and send it.

  • Improvement License verification now retrieves full license details

    When you verify your store number, you'll now see your license expiration date and the number of stores on your license.

  • Improvement User-driven update failures now surface immediately

    If you click "Update Now" and it fails, Margin Master shows you the "Could Not Update" dialog right away instead of just a notification you might miss.

  • Improvement Log analyzer now detects warnings in addition to errors

    The LogAnalyzerModule now parses [WRN]/[WARN] entries in addition to [ERR]/[ERROR], grouping and reporting warnings with appropriate severity. Serilog's optional source context prefix is stripped to improve deduplication and readability.

  • Improvement Database schema checks updated for current table names

    MarginMasterHealthModule now expects AceCatalogRecords instead of the obsolete Ace_Current table, and reads ApplicationSettings using current column names (Setting/Value instead of SettingKey/SettingValue). SQL version recommendations updated: SQL 2022 (v16) shows an Info-level message suggesting upgrade to SQL 2025; pre-2022 versions show a Warning-level message.

  • Improvement POS connectivity module classifies POS modes

    The POS connectivity diagnostic now understands which type of connection your POS system uses and only tests the relevant connections (FTP, direct database, or file share).

  • Improvement POS file format module reads configuration from database

    The POS file format checker now knows which POS system you use and opens the file picker to the right folder with the correct file type already selected.

  • Bug Fix Strategy finalization now shows progress updates

    When running a strategy, you'll now see progress messages during the final cleanup phase instead of the screen appearing stuck on the last step.

  • Bug Fix Eliminated strategy execution hang caused by SKU exception loading

    Pricing strategies now execute immediately without freezing, even at stores with thousands of SKU-level pricing exceptions.

  • Bug Fix Fixed multi-minute hang when processing SKU-level exceptions during strategy execution
  • Bug Fix Fixed reversed logic in no-decreases price guard

    When you enable "No Decreases" on a pricing strategy step, prices will now stay at or above their current price as intended. Previously, a bug was causing prices to decrease even when this option was checked.

  • Bug Fix Custom group minus rounding point actions now parse correctly

    When you create a custom pricing group and choose to subtract rounding points (e.g., "minus 2 points"), the pricing calculation will now correctly subtract those points instead of incorrectly adding them.

  • Bug Fix Settings migration duplicate key errors resolved

    Fixed errors that could occur during migration from the legacy GlobalFileConfig system to ApplicationSettings when duplicate configuration keys existed. The migration process now tracks keys added in the current batch and skips duplicates, preventing database constraint violations while still properly cleaning up old configuration entries.

  • Bug Fix Strategy switching no longer freezes application

    You can now switch between pricing strategies or rename them without the application freezing.

  • Bug Fix Strategy switching no longer freezes application

    Switching between pricing strategies now works smoothly without causing the application to freeze.

  • Bug Fix Eliminated UI deadlock during strategy switching

    The app will no longer freeze when you switch between pricing strategies, even when working with large datasets or multiple open screens.

  • Bug Fix Wait indicator now shows during strategy switching

    When you switch between pricing strategies, you'll now see the wait indicator showing that Margin Master is working, instead of the screen appearing frozen or unresponsive.

  • Bug Fix Splash screen progress now updates through SKU exceptions step

    The loading screen now shows "Updating display" after loading SKU exceptions, so you can see progress is still happening instead of appearing frozen.

  • Bug Fix UI responsiveness during strategy loading

    The application will no longer freeze or appear unresponsive when loading your pricing strategy at startup. The loading screen will remain animated and show smooth progress updates.

  • Bug Fix Eliminated UI freeze during pricing strategy display

    When you open a pricing strategy with many steps, the grid now appears instantly instead of freezing the application for several seconds.

  • Bug Fix Strategy switch now uses splash screen instead of busy overlay

    When you switch pricing strategies, you'll now see a full splash screen showing the progress instead of a dimmed overlay, making it clearer that the system is working.

  • Bug Fix Strategy switch splash screen not hiding

    When you switch between pricing strategies, the "Loading..." screen now disappears correctly every time, even when switching to a strategy you've used before.

  • Bug Fix Zone pricing icon displays correctly

    Products with Ace Hardware zone pricing now show the Ace icon in the "Z" column as expected.

  • Bug Fix Restore zone pricing Ace icon display

    The Ace Hardware icon now shows up correctly in the grid when items have zone pricing.

  • Bug Fix Plus/minus values now load correctly when opening saved strategy steps
  • Bug Fix Save confirmation dialog no longer loops when closing Pricing Strategies

    When you save changes to a pricing strategy and then close the window, you'll no longer see the save confirmation dialog pop up multiple times.

  • Bug Fix Fixed infinite save prompt loop in Pricing Strategy editor

    After saving changes to Custom Groups or SKU exceptions in the Pricing Strategies window, you can now close the window without being repeatedly prompted to save changes.

  • Bug Fix DIB Aux Retail strategy now uses correct catalog pricing

    When creating custom pricing groups with the "DIB Aux Retail" strategy, future prices will now match Do-It-Best's actual auxiliary retail prices instead of showing inflated amounts. For example, items that should be priced at $0.49 will no longer show future prices over $100.

  • Bug Fix DIB Aux Retail field now populated with correct catalog data

    When creating custom pricing groups that use "DIB Aux Retail" as the pricing strategy, the system will now use the correct auxiliary retail price from your Do-It-Best catalog instead of an incorrect inflated value.

  • Bug Fix Report scripts error blocking label printing

    If you were unable to print bin tags or price stickers and saw an error about "Report Scripts," this issue is now resolved. All label printing should work normally.

  • Bug Fix Application crash during cost break deletion

    You can now safely delete multiple cost break pricing models in sequence without the application crashing. After deleting a model, the next available model will load automatically.

  • Bug Fix Fixed grid display errors in Catalog Lookup

    The Catalog Lookup screen now displays properly without layout errors, and columns size appropriately for better readability.

  • Bug Fix Fixed grid column sizing errors in Catalog Lookup

    Resolved AutoWidth errors in the search results grid and zone pricing table that could cause display issues. Column widths are now set to fixed values or proportional sizing for more reliable display.

  • Bug Fix Excluded wildcard filters now generate correct SQL

    When you exclude items by wildcard pattern in a pricing strategy (e.g., "exclude all UPCs starting with 12345"), the filter now works correctly instead of failing silently.

  • Bug Fix Do-It-Best Level1-5 pricing missing on manually added catalog items

    When you add Do-It-Best items from the catalog, all five pricing levels now appear correctly in the pricing grid instead of showing blank or zero values.

  • Bug Fix SQL validation now allows hyphen character in WHERE clauses

    Fixed an issue where strategy filters containing hyphen characters (e.g., part numbers like "ABC-123") were incorrectly rejected as unsafe SQL, preventing strategies from executing. The SQL safety validator now properly allows hyphens in WHERE clause expressions.

  • Bug Fix Deleted pricing strategies no longer recreate themselves

    When you delete a pricing strategy, it will now stay deleted. Previously, the strategy could reappear if any SKU exceptions or custom groups were still referencing it.

  • Bug Fix Strategy Backup dialog now appears correctly

    Clicking "Backup Strategy" from the database menu now opens the backup dialog as expected instead of doing nothing.

  • Bug Fix Strategy Backup dialog now displays correctly

    When you click "Backup Strategy" in the File menu, you'll now see the backup options dialog where you can choose what to include in your backup.

  • Bug Fix Strategy Manager save performance

    Saving changes in Strategy Manager is now instant instead of freezing the screen for several minutes.

  • Bug Fix Strategy save operation freeze resolved

    Saving changes to your pricing strategies now takes just a few seconds instead of freezing the program for several minutes.

  • Bug Fix Strategy Manager save freeze resolved

    The Strategy Manager will no longer appear frozen when saving your pricing strategies, especially when working with strategies that have many steps.

  • Bug Fix Eliminated redundant processing during step reordering

    When reordering steps in your pricing strategies, the app no longer freezes or lags, especially in large strategies with many steps.

  • Bug Fix Fast step movement in pricing strategy V2 editor

    The pricing strategy editor no longer freezes when moving steps up or down, making it much faster to reorganize your pricing rules.

  • Bug Fix Dirty indicator now appears after moving strategy steps

    When you drag pricing strategy steps up or down to reorder them, the affected rows now turn yellow right away to show you have unsaved changes.

  • Bug Fix Dirty indicator now appears after moving pricing strategy steps

    When you drag a pricing rule up or down in the strategy list, the affected rows now turn yellow to remind you to click Save.

  • Bug Fix Close button now prompts to save unsaved pricing strategy changes

    When you click the X button to close the Manage Pricing Strategy window with unsaved changes, you'll now see a prompt asking if you want to save. Click "Yes" to save your changes or "No" to discard them.

  • Bug Fix Close button now prompts to save changes

    When you close the Pricing Strategy window with the X button, you'll now be asked if you want to save your changes instead of losing them.

  • Bug Fix Dialog now opens instantly with visible progress

    When you open Manage Pricing Strategies, the window appears right away and shows you what's loading, so you know the program is working instead of appearing frozen.

  • Bug Fix Pricing Strategy dialog opens immediately

    When you click to open the Pricing Strategy dialog, it now opens right away and shows a loading message instead of freezing the screen.

  • Bug Fix Restore pre-load initialization for pricing strategy dialog

    When opening the Manage Pricing Strategy dialog, you'll see the loading message on the main window before the dialog appears, rather than seeing a busy indicator inside the dialog itself.

  • Bug Fix Restore pre-load initialization for Pricing Strategy dialog

    When opening the Pricing Strategy manager, the app now loads all strategy information before the dialog appears, showing progress messages on the main screen.

  • Bug Fix Right panel displays correct step details when switching between steps

    When editing pricing strategies, selecting a different step in the left list now immediately shows the correct settings for that step in the right panel, including rounding options and min/max rules.

  • Bug Fix Strategy step right panel visibility restored

    When editing pricing strategies, the details panel on the right side of the screen now appears correctly instead of staying empty.

  • Bug Fix Restore visibility of strategy step details panel

    When you click on a pricing strategy step, the details panel on the right side of the screen now appears as expected, showing all step information and settings.

  • Bug Fix Step deletion now occurs instantly without database delay

    Deleting a pricing strategy step is now instant, and the selection automatically moves to the next step.

  • Bug Fix Eliminated UI deadlock when discarding pricing strategy changes

    When you close the pricing strategy window with unsaved changes and click "No" to discard them, you'll now see a brief "Discarding changes..." message and the window will close properly instead of freezing.

  • Bug Fix Fixed UI freeze on discard changes

    The pricing strategy window no longer freezes when you click "No" to discard your changes and close the window.

  • Bug Fix Improved condition value display in pricing strategies

    When setting up pricing rules with multiple category, vendor, or other condition values, they now display as "Hardware or Plumbing or Electrical" instead of in separate boxes, making it easier to understand which products the rule will affect.

  • Bug Fix Eliminated freeze when closing Pricing Strategy screen

    When you open and close the Pricing Strategy screen without making changes, it now responds instantly instead of freezing for several seconds, especially with large pricing strategies.

  • Bug Fix Fixed slow load/close performance in Pricing Strategy editor

    The Pricing Strategy screen now opens and closes immediately when you haven't made any edits, eliminating the previous delay.

  • Bug Fix Fixed infinite loop when closing with unsaved changes

    The "Save changes?" dialog now only appears once when closing the pricing strategy editor, and the window closes immediately after clicking Save or Discard.

  • Bug Fix Pricing Strategy editor infinite loop on close

    When closing the Pricing Strategy window with unsaved changes, you'll now see the save prompt only once, and the window will close properly after you choose to save or discard your changes.

  • Bug Fix Restored unsaved changes prompt in Pricing Strategy editor

    You'll now see a "Save changes?" prompt when trying to close the Pricing Strategy editor with unsaved work, preventing accidental data loss.

  • Bug Fix Fixed change tracking in Pricing Strategy editor

    The editor will now correctly enable or disable the Save button based on whether you've actually made changes, and won't incorrectly warn you about unsaved changes when there are none.

  • Bug Fix Condition editor popup binding crash resolved

    When editing conditions in a pricing strategy, the editor popup now opens and closes smoothly without errors.

  • Bug Fix Condition editor popup binding crash resolved

    The condition editor popup in pricing strategies will no longer cause crashes when it closes automatically.

  • Bug Fix Pricing strategy condition editor remove button now functional

    When editing pricing strategy conditions, the × button next to each value now properly removes that value from the list. Previously, clicking this button would do nothing.

  • Bug Fix Fixed non-functional buttons in Condition Editor popup

    When editing pricing strategy conditions, clicking the × button to remove individual values or the Close button to dismiss the editor now works as expected instead of being unresponsive.

  • Bug Fix Fixed crash when deleting pricing strategy conditions

    The strategy editor no longer crashes when you delete a condition from a pricing rule.

  • Bug Fix Resolved window closing infinite loop

    The Pricing Strategy window will now close properly when you choose to save or discard changes, instead of sometimes freezing or becoming unresponsive.

  • Bug Fix Closing flag now set before async operations

    When closing the Pricing Strategy dialog, the system now correctly ignores background updates that could previously cause the "unsaved changes" prompt to reappear.

  • Bug Fix Busy indicator now displays during save operations

    When you click Save or close the pricing strategy window with unsaved changes, you'll now see the busy indicator appear right away instead of the window appearing frozen.

  • Bug Fix Busy indicator now displays during pricing strategy saves

    When you save a pricing strategy, you'll now see the "Saving Strategy..." message appear immediately, confirming that your changes are being saved.

  • Bug Fix Loading indicator now displays before save operations

    When you click Save or close the pricing strategy window with unsaved changes, you'll now see the "Saving..." loading message immediately instead of the window appearing to freeze during the save.

  • Bug Fix Loading indicator now displays during pricing strategy saves

    When you save a pricing strategy, you'll now see the loading spinner right away instead of the screen appearing to freeze while the save completes.

  • Bug Fix Busy indicator clears prematurely during pricing strategy save

    When saving a pricing strategy, the loading spinner will now remain visible until the save is completely finished, instead of disappearing early while the save is still happening.

  • Bug Fix Busy indicator now stays visible during pricing strategy save

    When you save a pricing strategy, the busy spinner will now stay on screen until the save is completely finished, so you'll always know when it's safe to continue working.

  • Bug Fix Busy indicator now reliably displays during save operations

    The "Saving changes..." message will now always appear when you save a pricing strategy, so you'll know the system is working.

  • Bug Fix Busy indicator now displays correctly during save operations

    When you save a pricing strategy, you'll now reliably see the "Saving changes..." indicator appear on screen.

  • Bug Fix Fixed missing loading indicator in Pricing Strategy Manager

    The "Please wait..." loading spinner now displays properly when you're saving pricing strategies or performing other operations that take time to complete.

  • Bug Fix Improved loading indicator behavior in Pricing Strategy editor

    The "Please wait..." loading spinner now transitions smoothly when loading pricing strategies, without flickering or visual glitches.

  • Bug Fix Fix crash when opening Custom Groups screen

    Custom Groups screen no longer crashes when you try to open it.

  • Bug Fix Fixed Custom Groups crash due to missing style resource

    Custom Groups will now open without crashing.

  • Bug Fix Corrected rule numbering in Load Saved Selection dialog

    When loading saved pricing rules, the rule numbers shown in the dialog now match the correct order.

  • Bug Fix Corrected rule numbering in pricing strategy display

    When viewing your pricing strategy rules, they will now always be numbered in the correct order (1, 2, 3...) instead of appearing scrambled.

  • Bug Fix Variance column filters in strategies now work correctly

    If you created pricing strategies with rules like "select items where cost variance is greater than 125%", those rules will now correctly filter items instead of selecting almost everything.

  • Bug Fix Deleted rounding schemes now persist after restart

    When you delete a custom rounding scheme, it will now stay deleted even after closing and reopening Margin Master.

  • Bug Fix Rounding scheme deletion now persists to database

    When you delete a custom rounding scheme, it now stays deleted even after closing and reopening Margin Master.

  • Bug Fix Eliminated UI freeze during click-to-set Future Price operations

    When you click on a price column (like Current Price or Retail) to copy that value into Future Price, the app now responds immediately instead of freezing.

  • Bug Fix Removed unnecessary grid refresh when setting Future Price via click

    When you click on a price to set Future Price, the app now responds instantly instead of freezing with a progress bar.

  • Bug Fix Fixed store selection error in SKU exceptions for single-store customers

    Editing margin percentages for SKU exceptions now works correctly without error popups, even if your store only has one location.

  • Bug Fix StoreNumber missing from database queries in single-store mode

    The SKU detail screen now correctly identifies which store each item belongs to, even when the store column is hidden from the main pricing grid.

  • Bug Fix StoreNumber field now loaded even when hidden from grid

    Pricing changes and exceptions now save correctly even if your store doesn't display the Store Number column.

  • Bug Fix MAP and IMAP price levels now preserved in custom groups

    If you created a custom group using Ace MAP Price or Ace IMAP Price, it will now remember your selection when you reopen the group instead of resetting to "Not Set."

  • Bug Fix Eliminated splash screen race condition in click-to-set Future Price

    The loading splash will no longer appear when clicking price columns to set Future Price, making the feature feel more responsive and eliminating the freeze that occurred on the second click.

  • Bug Fix Eliminated splash screen lockup on rapid click-to-set future price

    You can now click on different SKUs quickly to set future prices without the app locking up. The splash screen no longer appears for this fast operation.

  • Bug Fix Remove orphaned store data on CounterWorks import

    If your store previously had multiple locations or migrated from another system, old pricing data from those setups will no longer interfere with your current prices. The Main Table pricing grid will now show accurate prices based only on your active store data.

  • Bug Fix Strategy restore no longer overwrites database connections

    If you restore an old strategy backup, your database connection will remain intact and you can continue working immediately. Previously, this could break your connection and show confusing error messages.

  • Bug Fix Strategy restore no longer overwrites database connections

    If you restore an old strategy backup, your database connection will remain intact and you won't see "Store Configuration Required" errors or need Brad to recreate your database.

  • Bug Fix ListPrice now populated in per-store imports for MySQL Compass

    List prices from your MySQL Compass POS system will now appear correctly in the pricing grid for all stores, even when store grouping is turned off.

  • Bug Fix List Price now imports from MySQL Compass

    When importing POS data from MySQL Compass, list prices will now correctly appear in your pricing grid. Previously, these prices were being skipped during the import process.

  • Bug Fix Restored pricing strategies now visible in UI

    Pricing strategies from backup files now appear in the Pricing Strategy screen immediately after restore, instead of being invisible even though they were restored.

  • Bug Fix Rounding scheme name lookups now case-insensitive

    If your rounding schemes were saved with different capitalization than how they appear in pricing strategies, those strategies will now work correctly instead of failing.

  • Bug Fix FuturePrice changes in SKU Detail dialog now persist

    When you open a SKU's detail window and change the future price for any store, that change will now be saved when you click "Save & Close" instead of being lost.

  • Bug Fix Future Price edits now persist correctly

    Previously, when you changed a Future Price for an item and clicked Save, your change would be lost. This now works correctly and your Future Price edits will be saved.

  • Bug Fix Case-insensitive rounding scheme lookup

    All rounding scheme name comparisons now use case-insensitive matching (StringComparison.OrdinalIgnoreCase). Previously, if a pricing strategy referenced a rounding scheme with different capitalization than how it was stored (e.g., "standard" vs "Standard"), the application would fail to find the scheme and display errors or apply incorrect pricing rules.

  • Bug Fix Strategy restore now preserves all pricing rules

    When you restore pricing strategies from a backup, all the strategy rules are now properly restored and the strategies work correctly.

  • Bug Fix ListPrice option now available for all Epicor POS users

    If your store uses Epicor POS, you'll now see the ListPrice option when setting future prices, regardless of whether you're affiliated with Ace Hardware, Do-It-Best, or another vendor.

  • Bug Fix List Price option missing from Future Pricing strategy processing

    Previously, if you selected "List Price" in Future Pricing settings and clicked Apply, nothing would happen. Now it works correctly and your strategies will save and reload properly.

  • Bug Fix List Price target level now works in Future Pricing

    When creating a Future Pricing rule and selecting "List Price" as your target price level, the rule will now calculate and apply prices correctly based on the List Price field from your vendor catalog.

  • Bug Fix Future Price panel now applies List Price selection

    When you select "List Price" as the target pricing level in the Future Price panel and click Apply, your selected items will now update correctly instead of being skipped.

  • Bug Fix ListPrice option now works in Future Price Panel

    When setting future prices, the ListPrice option now works correctly as a source for your pricing calculations.

  • Bug Fix Rounding schemes now included in V3 backups

    Your custom rounding schemes (like round to nearest nickel or dime) are now included when creating strategy backups.

  • Bug Fix Strategy backup restore now preserves rounding schemes

    When you restore a strategy backup with the "Rounding Schemes" option checked, your custom rounding rules will now be restored correctly. Previously, these settings were being lost during the restore process.

  • Bug Fix List Price option now saves correctly in custom groups

    When you edit a custom group and choose "List Price" as the future pricing method, that choice now appears correctly when you reopen the group for editing.

  • Bug Fix List Price selection now saves in custom groups

    When you select "List Price" as your pricing level in a custom group, it will now save properly instead of reverting to a default value.

  • Bug Fix Dialog now defaults to waiting for user input

    Error dialogs will now wait for you to make a decision instead of automatically closing after a countdown.

  • Bug Fix Dialog now defaults to waiting for user decision

    The error dialog will now stay open until you click Accept, giving you time to read the error and choose how to proceed.

  • Bug Fix Countdown timer removed from Abort action

    If you select "Abort" when a strategy load error appears, you must now click the Accept button to proceed — the dialog will not automatically close and abort your import.

  • Bug Fix Abort action no longer auto-executes with countdown

    If you previously saved "Abort" as your preference for handling data load errors, the dialog will no longer automatically close and abort — you'll need to click the Accept button to confirm the abort action.

  • Bug Fix Fixed layout clipping in strategy error dialog

    Radio button options in the strategy error dialog are no longer cut off and display their full text.

  • Bug Fix Strategy log column order corrected

    When viewing strategy execution logs, the "Skus" and "Changes" columns now appear in the correct order.

  • Bug Fix Fixed zone pricing sync timeouts on large store groups

    Corrected a programming error where database timeout values were not being passed correctly to SQL update commands. Commands that update Level1/Level2 pricing from Ace zone records, apply zone-specific retail pricing, recalculate price variances, and set vendor ownership flags were defaulting to a 30-second timeout instead of the intended 300-600 seconds. On large store groups (300,000+ rows), this caused these updates to fail silently, leaving pricing fields blank or set to zero after sync completed.

  • Bug Fix Rounding scheme dropdown now refreshes after database restore

    When you restore a backup, the rounding scheme dropdown in the pricing panel will now show all your saved rounding schemes correctly instead of appearing blank.

  • Bug Fix Rounding scheme dropdown not refreshing after strategy restore

    When you restore a saved pricing strategy or switch to a different store database, the rounding scheme dropdown will now show all available schemes instead of appearing blank.

  • Bug Fix Rounding scheme dropdown empty after backup restore

    If you restore a backup containing custom rounding schemes, those schemes will now appear in the future price panel dropdown and work correctly. Previously, they would be missing even though the restore completed successfully.

  • Bug Fix Rounding scheme headers now created during backup restore

    If you restore a backup that contains custom rounding schemes, those schemes will now appear correctly in Margin Master and be available for use in pricing strategies.

  • Bug Fix Extended timeout for cost field synchronization

    Fixed an issue where cost updates would fail for stores with large inventories.

  • Bug Fix Zone pricing timeout errors on large databases

    If you have a large Ace Hardware catalog, zone pricing updates will no longer fail partway through, ensuring all your pricing levels update correctly.

  • Bug Fix Restored Ctrl+F keyboard search in custom groups manager

    When managing custom groups, you can now press Ctrl+F on your keyboard to open a search box and quickly find groups by typing part of their name. Press Escape to close the search box.

  • Bug Fix Custom groups now display in correct order

    When viewing your custom groups, they now appear in the correct numerical order instead of randomly shuffled.

  • Bug Fix Rounding scheme backup and restore now functional

    When you back up your settings, rounding schemes are now included. When you restore from a backup, rounding schemes will be properly restored. Previously, rounding scheme settings were silently dropped.

  • Bug Fix Rounding scheme backup restored to correct format

    Removed incorrect code that attempted to backup rounding schemes as separate database entities. Rounding schemes are stored in the GlobalFileConfig table with Section='ROUNDING' and are now properly included in backups through that mechanism. The backup process was excluding ROUNDING entries from GlobalFileConfig while also failing to properly backup the entity format, causing rounding schemes to be lost during backup/restore operations.

  • Bug Fix Do-It-Best import table creation now runs on every startup

    If you restored Margin Master from a backup, Do-It-Best catalog imports would fail. This is now fixed—imports will work correctly after database restores.

  • Bug Fix DIBMailBox_ItemPricing table creation now runs unconditionally

    Importing Do-it-Best pricing data will now work correctly even if you've recently restored your database from a backup.

  • Bug Fix Corrected detection of legacy SKU Level Exceptions steps

    SKU-level price overrides in strategies imported from older systems will now apply correctly instead of causing errors.

  • Bug Fix Strategy execution no longer fails on legacy SKU exception steps

    If you imported pricing strategies from an older system and saw errors about "Not Future Price Setting to Load," those strategies will now run without errors. SKU-level exceptions will continue to work as expected.

  • Bug Fix Legacy SKU Level Exceptions step detection improved

    Pricing strategies with custom-named exception steps (often imported from older systems) will now run without errors. These exception steps are already processed separately, so the system now correctly skips them during the main strategy run.

  • Bug Fix Per-formula progress updates for SKU exception batches

    When Margin Master is applying SKU-level exceptions, the progress window now shows which formula is being processed (e.g., "SKU Exceptions: formula 2 of 7") and updates continuously, so you can see that the application is still working rather than appearing frozen.

  • Bug Fix Future Price column arrow key navigation restored

    You can now use arrow keys to move between rows when in the Future Price column, just like in other columns. Previously, arrow keys would change the price value instead of moving to the next item.

  • Bug Fix Future Price inline editing navigation restored

    You can now use arrow keys to move between cells while editing Future Prices directly in the pricing grid.

  • Bug Fix Rounding scheme deletion crash resolved

    Deleting or clearing a rounding scheme in the Rounding Editor now works smoothly without generating errors.

  • Bug Fix Null reference protection in Rounding Editor

    The Rounding Editor will no longer crash in certain edge cases when opening or switching between rounding schemes.

  • Bug Fix Corrected store number filtering in Ace zone pricing sync

    Ace Hardware zone pricing data will now sync correctly without database errors. Previously, sync may have failed when downloading zone pricing for specific stores.

  • Bug Fix Single-click editing now works for Future Price cells

    When Future Price editing is enabled, you can now click once on a Future Price cell to start editing instead of having to click twice.

  • Bug Fix Future Price inline editing now activates on single click

    When Future Price inline editing is turned on in settings, you can now click once on a Future Price cell to edit it immediately, just like other spreadsheet applications.

  • Bug Fix Single-click Future Price editing with custom templates

    When single-click Future Price editing is enabled in settings, clicking on Future Price cells now reliably opens the editor, even when the cells have special display formatting.

  • Bug Fix Single-click Future Price editing now works with custom cell template

    When you click once on a Future Price cell to edit it, the editor now opens immediately every time, instead of requiring a second click.

  • Bug Fix Future Price inline editor now visible when editing enabled

    When you enable Future Price editing in Settings and click to edit a Future Price in the Main Table, you can now see the editor box and the value you're typing. Previously, the editor was hidden behind the display template.

  • Bug Fix Future Price editor now visible when editing is enabled

    You can now see the Future Price values you're typing when editing prices directly in the grid. Previously, the editor was hidden behind other display elements.

  • Bug Fix Base prices now update during incremental Ace sync

    Previously, if Ace or Emery Jensen changed their catalog prices between full rebuilds, your base pricing columns wouldn't reflect the updates until you performed a complete data refresh. Now those prices stay current with every sync.

  • Bug Fix Base retail pricing now updates from Ace zone 99999

    If your store uses Ace zone 99999, base retail prices will now update correctly when you sync, ensuring your pricing analysis uses the most current data.

  • Bug Fix SQL backup crash with apostrophes in store name

    Database backups will no longer fail for stores with apostrophes in their name.

  • Bug Fix Missing database tables for PricingStrategy feature in existing installations
  • Bug Fix Backup dialog no longer crashes with missing pricing strategy tables

    The backup and restore dialogs will now open without errors, even if your database was restored from an older backup or experienced update issues in the past.

  • Bug Fix Backup failure when pricing strategy tables are missing

    Backups will now complete successfully even if your database doesn't have the pricing strategy feature tables, which could happen with older store databases.

  • Bug Fix SKU exceptions with LEVEL and ZONE action types now apply correctly

    If you previously created SKU exceptions that targeted Level 1-5 pricing or zone pricing columns, those exceptions will now work as expected when you run pricing strategies. Previously these exceptions appeared to load but had no effect on your prices.

  • Bug Fix Batch SKU exceptions now apply plus/minus adjustments
  • Bug Fix Plus/minus adjustments now apply in batch SKU exception mode

    If you set a SKU exception to use a margin or retail level plus an additional dollar amount or percentage (e.g., "Margin 30% + $2.00"), that adjustment will now be applied correctly when running the pricing strategy.

  • Bug Fix Excel import now works when file is open

    You can now import Excel spreadsheets without closing them first. Previously, if the file was still open in Excel, the import would fail silently and skip those products.

  • Bug Fix Strategy execution crash with malformed SKU exceptions

    Pricing strategies will no longer fail when encountering SKU exceptions with duplicate rule settings. The system now uses the first value and continues processing.

  • Bug Fix Prevent exception when parsing malformed pricing rule parameters

    Pricing rules with duplicate action settings will no longer cause the application to crash when applied to products.

  • Bug Fix Fixed OrderMultiple field to support decimal values

    Changed the OrderMultiple field from integer to decimal type to accommodate stores that use decimal order multiple values instead of whole numbers. This resolves data import errors and crashes when loading product data from POS systems that store fractional order multiples.

  • Bug Fix Ace catalog lookup crashes resolved

    Ace Hardware catalog lookups will no longer crash when viewing product details.

  • Bug Fix SKU exceptions for "Remain Current Price" now apply correctly

    When you set a SKU exception to "Remain Current Price," the pricing strategy will now correctly keep that item at its current price instead of calculating a new one.

  • Bug Fix SKU exceptions with CURRENTPRICE action now apply correctly

    If you set a SKU exception to "Keep Current Price," the pricing strategy will now correctly preserve the current price instead of calculating a new one.

  • Bug Fix Pricing strategy backup now reads from live data tables

    If you created new pricing strategies or edited existing ones after the initial software setup, those changes were not being saved in your backup files. This is now fixed — all strategies and any changes you make will be included in backups.

  • Bug Fix Strategy backup now captures current data instead of stale migration records

    Pricing strategy backups will now include all your current strategy changes. Previously, if you edited a strategy after initial setup, those edits weren't being saved in backups.

  • Bug Fix REMOVECHANGE exception now correctly preserves current price

    When you apply a REMOVECHANGE exception in a pricing strategy, the item's future price will now stay at its current price instead of being set to zero. This prevents accidentally marking items for a price change to $0.00.

  • Bug Fix REMOVECHANGE strategy now preserves current price

    When a pricing strategy uses the REMOVECHANGE action, items will now keep their current price instead of being incorrectly changed to $0.00.

  • Bug Fix Fixed crash when importing Epicor store information with missing dates

    Epicor store imports will no longer crash when date information is missing from the database.

  • Bug Fix Fixed DateTime overflow error during Epicor MySQL store import

    Fixed an error that could prevent the Epicor MySQL import from completing successfully.

  • Bug Fix Pricing strategy step deletion now persists correctly

    If you delete the last step in a pricing strategy, it will now stay deleted when you close and reopen Margin Master. Previously, the last step would come back after restarting the application.

  • Bug Fix Strategy deletion not triggering save state

    When you delete a step from your pricing strategy, the Save button will now activate correctly so you don't lose your work.

  • Bug Fix Strategy step deletion now persists correctly

    When you delete a step from a pricing strategy, that change now saves to the database correctly. Previously, deleted steps would come back the next time you opened the strategy.

  • Bug Fix Strategy step deletion now persists correctly

    When you delete a step from a pricing strategy and save, the change will now be properly saved to the database and remain deleted when you reopen the strategy.

  • Bug Fix ADDPOIN/SUBPOIN operations now processed correctly in batch mode

    When applying pricing exceptions that shift rounding levels (like SUBPOIN3 to drop 3 bracket levels or ADDPOIN2 to raise 2 levels), the batch processor now correctly adjusts prices instead of skipping them.

  • Bug Fix ADDPOIN/SUBPOIN rounding point shifts now work in batch mode

    When you create a SKU exception that adds or subtracts rounding points (like "shift up 3 points" or "shift down 6 points"), those point adjustments will now be applied correctly to your pricing. Previously, these were being ignored and all items were treated the same way.

  • Bug Fix Fixed store selection error for Epicor SKU exceptions

    When adding or editing special pricing for individual SKUs, Epicor users will no longer see an error message saying no stores are selected. The system now correctly identifies your store locations.

  • Bug Fix Empty strategy backup notification

    When you restore a backup file with no pricing rules, you'll see a warning icon and a message telling you "No pricing strategy rules were found in this backup file. Your existing strategy rules were not modified." This makes it clear your current pricing rules haven't been changed.

  • Bug Fix Added notification for empty pricing strategies during backup restore

    If you restore a backup file that doesn't have any pricing strategy rules saved in it, you'll now see a warning icon and a message explaining that your current pricing strategies weren't changed. This helps you understand exactly what was restored from the backup.

  • Bug Fix CPFPDif filter now handles price increases and decreases symmetrically

    When creating strategy rules that filter by dollar price change (CPFPDif), conditions like "less than $1" or "greater than $5" now correctly include both price increases and decreases that meet the criteria. Previously, these rules were incorrectly excluding all price decreases.

  • Bug Fix Backup now includes all pricing strategies from migrated databases

    If your store was migrated from an older system, your pricing strategies will now be properly included when creating backups, preventing potential data loss during restore operations.

  • Bug Fix Backup dialog now displays pricing strategies correctly

    When you open the backup options dialog, you'll now see your pricing strategies listed with accurate information about steps, custom groups, and SKU exceptions, rather than seeing "N/A" or missing data.

  • Bug Fix SqlDateTime overflow on strategy restore

    Backup files containing pricing strategies with missing creation dates can now be restored successfully without errors.

  • Bug Fix Eliminated row explosion during BisTrack mainTable import

    BisTrack pricing imports that previously processed tens of thousands of extra rows now only process the actual number of products, significantly reducing import time.

  • Bug Fix Strategy backup vendor identification restored

    If your store works with multiple vendors under the same store number, strategy backups to the cloud will now save to the correct vendor account without errors.

  • Bug Fix Strategy backup now includes vendor type

    Strategy backups sent to the cloud were missing the VendorType field in the request payload. This field has been restored to ensure backups are properly categorized by vendor (Ace Hardware, Do-It-Best, Emery Jensen, Orgill, or United Hardware) on the server. Both manual and automatic strategy backups now correctly include this information.

  • Bug Fix Strategy backup now uses correct vendor identification

    The cloud strategy backup system was incorrectly using vendor short names (like "ACE" or "DIB") instead of the numeric vendor ID when saving and retrieving pricing strategy backups. All backup operations now properly use the vendor ID, ensuring backups are correctly associated with the right vendor and can be reliably retrieved later.

  • Bug Fix Zero-price items now skip rounding calculations

    Items showing $0.00 in their pricing level (usually items that exist in your POS but not in the vendor catalog) will now keep their existing Future Price during rounding instead of being reset to $0.00.

  • Bug Fix Skip rounding for zero-price items

    Items with zero prices will now correctly skip the rounding process, ensuring only valid prices are rounded according to your rounding scheme settings.

  • Bug Fix Increment rounding now respects strategy step filters

    When using pricing strategies with dollar increment rounding (like YETI 2020 with $3 increments), prices set by earlier strategy steps will no longer be accidentally changed.

  • Bug Fix Strategy backup download timeout increased

    If you previously saw errors when trying to download strategy backups, especially larger ones, those downloads should now complete successfully.

  • Bug Fix Delayed busy spinner during cost break save

    The loading spinner now only appears during the actual save, not while you're entering or confirming the cost break name.

  • Bug Fix Increment rounding offset now persists correctly

    If you use increment rounding with a custom offset, that offset value will now be remembered after closing and reopening Margin Master.

  • Bug Fix Increment rounding offset now saves correctly

    When you set up increment rounding with an offset (e.g., round to nearest 99¢), that offset will now save correctly and reload when you reopen Margin Master.

  • Bug Fix Increment rounding offset now applies consistently

    When your pricing scheme uses increment rounding with offsets (like making prices end in .99), those offsets will now be applied correctly even if the price started at a whole dollar amount.

  • Bug Fix Strategy backup timestamps now display in local time

    When viewing available strategy backups to restore, the dates and times now show correctly for your time zone instead of being off by several hours.

  • Bug Fix Strategy backup dates now display in local time

    When restoring a pricing strategy from a backup, the dates now show in your local time instead of UTC, making it easier to find the right backup.

  • Bug Fix Fixed duplicate SKU entries in Custom Groups

    SKUs in Custom Groups now appear only once with the correct description, instead of showing duplicate entries.

  • Bug Fix Eliminated duplicate SKU entries in Custom Groups

    Each product now appears only once in Custom Groups instead of showing up multiple times.

  • Bug Fix Cost break summary now respects fixed price vs. margin mode

    When reviewing pricing strategy details, cost breaks now show the correct pricing values—either a dollar amount or a percentage—matching how each level is actually configured.

  • Bug Fix Cost break summary now respects fixed price setting

    When you set up cost breaks with fixed retail prices, the pricing summary will now show those dollar amounts instead of incorrectly showing margin percentages.

  • Bug Fix Rounding scheme sentinel values no longer applied as future prices

    If you have items over $200 using rounding schemes designed for lower-priced items, they will now show realistic future prices instead of jumping to $99,999.98.

  • Bug Fix Guard against rounding scheme UpperLimit sentinel in strategy execution

    If you use a pricing strategy with a custom rounding scheme that doesn't cover all price ranges, high-priced items will now show the correct calculated price instead of an overflow value like 99999.98.

  • Bug Fix Cost break dropdown now refreshes when loading strategy steps

    If you create a new cost break and then edit a saved pricing strategy that uses it, the cost break will now load correctly instead of appearing empty.

  • Bug Fix Custom group dialog now resolves alternate SKU formats

    Previously, typing your store's SKU number into the custom group dialog wouldn't find the item unless you used the exact vendor SKU. Now you can use either your store number or the vendor number, and the system will find the right item.

  • Bug Fix Cost break cache now refreshes when loading strategy steps

    If you create a new cost break and then try to use it in a pricing strategy step, it will now work immediately instead of showing an error message.

  • Bug Fix Custom group item lookup now supports alternate SKU formats

    When adding items to a custom group, you can now type either the regular SKU or the MI9 store number — both will work and find the correct item.

  • Bug Fix Remove stale custom group entries when adding resolved SKUs

    If you previously added an Ace store number to a custom group before that item was in your system, you can now re-add it after importing that product without creating duplicate entries. The old "Not in Database" entry will be automatically removed.

  • Bug Fix Stale alternate SKU entries cleaned up automatically

    If you add a SKU to a Custom Group before the catalog is loaded, then add it again later, you'll no longer see two entries for the same item.

  • Bug Fix License validation state now excluded from strategy backup restore

    If you restore a strategy backup that was created on a different computer, your license will continue to work correctly without triggering security errors.

  • Bug Fix License validation state excluded from strategy backups

    License validation state is now excluded from strategy backup restoration to prevent licensing conflicts when importing strategy files across different Margin Master installations. This ensures that each installation maintains its own license validation status independent of imported pricing strategies.

  • Bug Fix Strategy execution no longer skips steps with partially missing data

    If a pricing strategy references Department 30, 46, and 78, but Department 78 doesn't exist in your current data, the strategy will now apply to Departments 30 and 46 instead of skipping the step completely. A warning message shows which categories exist and which are missing before you continue.

  • Bug Fix Strategy execution now handles legacy Custom Groups step naming

    If you previously imported a pricing strategy from an older system and saw errors when running it, those strategies will now execute successfully. The Custom Groups pricing rules will apply correctly.

  • Bug Fix Migrate legacy Custom Groups step naming on strategy load

    If you imported a pricing strategy from an older system, Custom Groups steps will now be automatically corrected and work as expected without manual intervention.

  • Bug Fix Cloud backup failure notification added

    Previously, when the cloud strategy backup failed, the error was only written to the log file with no visible notification to the user. This meant users had no way to know their backup didn't reach the cloud. Now a warning dialog appears showing the specific error message and instructing users to check their internet connection or contact support if the problem persists. The strategy is still saved locally as a fallback.

  • Bug Fix Cloud backup failure feedback

    If your cloud backup doesn't work, you'll see a message explaining the problem and what to do next. Your work is still saved on your computer.

  • Bug Fix Strategy step names with apostrophes no longer cause database errors

    You can now name your pricing strategy steps with apostrophes (like "Update DIB SKU's" or "Frank's Pricing Rule") without encountering errors when applying prices.

  • Bug Fix SQL syntax error in pricing strategy step names

    You can now create and apply pricing strategy steps with apostrophes in their names without encountering database errors.

  • Bug Fix Corrected strategy rule tracking for MI9 member pricing

    For MI9 stores, items using member pricing now correctly show their actual pricing source instead of incorrectly displaying a strategy rule name.

  • Bug Fix Invisible characters now display in grid cells

    If your POS system data contains special invisible characters (like soft hyphens), they will now show up as numbers in the grid instead of appearing blank, so you know the cell has data in it.

  • Bug Fix Block strategy execution when all filter values are missing

    If a pricing strategy step tries to filter by categories or groups that don't exist in your current data, the system will now skip that step and show you a warning instead of accidentally applying prices to the wrong items.

  • Bug Fix Block strategy step when all filter values are missing

    When running a pricing strategy, if a step tries to filter by categories that don't exist in your current data (for example, departments that have been removed), the step will now be safely skipped instead of accidentally applying to items it shouldn't. You'll see a warning explaining that the step was skipped and should be re-run after importing updated data.

  • Bug Fix MI9 pricing rule labels now update correctly after strategy reruns

    If items were showing the wrong pricing rule name after a previous strategy update, re-running the pricing strategy will now correctly update the rule name shown in the pricing grid.

  • Bug Fix Corrected pricing rule tracking for MI9 systems

    The "governing rule" column in the pricing grid now shows the correct, most recent pricing strategy that was applied to each item, instead of sometimes showing an old or incorrect rule name.

  • Bug Fix Backup process memory optimization

    Creating backups will now work reliably even for stores with very large numbers of pricing strategies, and won't cause the application to run out of memory and crash.

  • Bug Fix Catalog data import now updates product information correctly

    Product information from Ace Hardware — including departments, pricing levels, vendor details, and velocity codes — now imports correctly for all Propello stores.

  • Bug Fix Strategy error abort action now opens editor

    When a pricing strategy step has an error and you click "Abort," the strategy editor will now open automatically so you can see and fix what went wrong.

  • Bug Fix Strategy abort now loads selection for review

    When a pricing strategy stops before completing, the affected items now appear in the main pricing grid for you to review, rather than opening the strategy editor right away.

  • Bug Fix Strategy backup memory usage reduced for large catalogs

    Strategy backups for large vendor catalogs will now complete successfully without causing the application to slow down or crash.

  • Bug Fix Bootstrapper closes Margin Master before installing updates

    If Margin Master is running when an update downloads, it will now close automatically before installing the update, so you don't need to remember to close it yourself.

  • Bug Fix Removed erroneous Do-It-Best price scaling logic

    Items from Do-It-Best that previously showed incorrect prices in the pricing grid will now display the correct retail and cost values from the vendor catalog.

  • Bug Fix Removed incorrect Do-It-Best UOM price scaling

    Previously, the system tried to automatically adjust vendor prices when it detected unit-of-measure differences (like per-foot vs. per-roll). This sometimes changed prices incorrectly. Now vendor prices display exactly as they appear in the vendor's catalog.

  • Bug Fix Prevent crash when strategy execution has no results

    Fixed an OverflowException that occurred when attempting to log strategy execution summary after a complete failure (such as when the CHAR() mapping bug causes group table build to fail). The system was attempting to calculate average duration per step by dividing by zero when no steps completed. The summary now displays "N/A" for average duration instead of crashing.

  • Bug Fix Prevent crash on empty strategy execution results

    Fixed a crash that could happen when running certain pricing strategies. The application now handles these cases gracefully.

  • Bug Fix Default to national pricing zone when store zone data is missing

    If your Ace store's department zone assignments haven't loaded yet, pricing will automatically use national pricing (zone 99999) instead of showing an error.

  • Bug Fix Selection tabs now reload after database restore

    Custom pricing fields now work correctly in strategies after restoring a backup.

  • Bug Fix View switching now properly updates cached view definition

    If you switched from one saved view to another and then tried to apply a pricing strategy that uses columns like Vendor, Comp5, Level2, or AverageCost, you would get an error saying the field wasn't available. This now works correctly.

  • Bug Fix Auto-select existing pricing strategy on new installation

    If you install Margin Master on a new computer and restore your database, your existing pricing strategy will now be automatically selected instead of requiring you to manually choose it from settings.

  • Bug Fix Auto-select existing pricing strategy on new installation

    If you restore a database backup or open Margin Master for the first time, the app will now automatically find and use your existing pricing strategies instead of creating a new blank one.

  • Bug Fix Ace Hardware rounding scheme compatibility

    If you're an Ace Hardware store using pricing strategies, rounding steps that were previously being skipped due to load failures will now work correctly.

  • Bug Fix Ace rounding scheme migration

    If your pricing strategies were not loading or applying correctly due to rounding configuration issues, they will now work as expected after this update.

  • Bug Fix Strategy execution tracking authentication restored

    Strategy execution data was not being posted to the cloud due to a missing authentication token in the API call. This has been fixed to properly include the Bearer token when sending execution tracking information.

  • Bug Fix Strategy execution tracking authentication retry

    Fixed an issue where strategy execution tracking could fail to upload when authentication tokens expired. The system now automatically retries with fresh authentication credentials, ensuring tracking data is reliably captured even during long-running operations.

  • Bug Fix BisTrack import now correctly loads vendor catalog data

    Previously, BisTrack imports would complete without error messages but leave the pricing grid empty with no vendor data or dropdown selections available. This is now fixed and all vendor catalog information imports correctly.

  • Bug Fix Strategy backup upload timeout increased

    If you previously saw error messages about strategy backups failing to upload to the cloud, these should now succeed even on slower internet connections.

  • Bug Fix Extended cloud upload timeout for large strategy backups

    If you previously experienced failed backup uploads with timeout errors, especially on slower internet connections, these uploads should now complete successfully with the extended 10-minute timeout window.

  • Bug Fix Corrected increment rounding for nearest and round-up methods

    If you use rounding schemes that round prices to the nearest dollar or other increment, the system will now calculate the correct rounded price every time, without skipping valid price points.

  • Bug Fix Check button now previews the correct rounding scheme

    When editing a rounding scheme, clicking Check now shows you how pricing will look with that specific scheme, not with whichever scheme happens to be active in your store.

  • Bug Fix Automatic correction of invalid increment rounding rules

    If a rounding scheme had an incorrect increment setting that prevented higher-priced items from rounding, it has been automatically fixed so all items in the price range now round properly.

  • Bug Fix Epicor store mapping setting now preserved across sessions

    If you use Epicor and have pricing strategies saved, your store selections will now work correctly after application restarts and updates, instead of mysteriously losing their settings.

  • Bug Fix Restore SKU-level exception icon rendering

    The "*" column now shows icons indicating which items have special pricing rules applied, making it easier to identify locked margins, plug retail prices, and custom group assignments at a glance.

  • Bug Fix Pre-Rounded column now updates for all MI9 pricing strategies

    When you apply pricing rules that don't use rounding on MySQL Compass stores, the Pre-Rounded column now shows the correct calculated price instead of an old value from a previous step.

  • Bug Fix Pre-Rounded column now updates for non-rounding MI9 pricing rules

    When you apply pricing rules that don't use rounding (such as setting prices to a specific level or margin), the Pre-Rounded column will now show the correct current price instead of an old value.

  • Bug Fix Falcon import now handles blank prices and costs

    When importing Falcon data, service items and products with missing prices or costs will now import successfully with zero values instead of causing the entire import to fail.

  • Bug Fix Duplicate SKU prevention in custom groups

    When you add the same item to a custom group twice, the system now handles it gracefully instead of failing silently in the background.

  • Bug Fix Prevented duplicate key errors in custom group SKU operations

    You can now add SKUs to custom groups without getting errors if the SKU is already in the group. The operation will succeed and skip any duplicates automatically.

  • Bug Fix Rollback rounding no longer orphans .98/.99 prices

    Items priced at amounts ending in .98 or .99 will now stay in the correct price group when your store uses round-down pricing rules, instead of unexpectedly jumping up by $10.

  • Bug Fix Rollback rounding now correctly handles gap cents (.98/.99)

    When using rounding schemes with rollback rules, items priced at amounts like $259.99 will now correctly round to $259.97 instead of incorrectly jumping up to $269.97.

  • Bug Fix Main table now rebuilds after startup vendor sync

    If you're prompted to download vendor data when opening Margin Master, the pricing grid will now show the correct current prices immediately after the download completes, instead of displaying old prices until you manually refresh.

  • Bug Fix Force rounding table regeneration after engine math changes

    Items with rollback rounding now price correctly after updates to the pricing engine, fixing cases where prices were still wrong even after the engine was fixed.

  • Bug Fix Automatic rounding table regeneration after engine fix

    When you open Margin Master after this update, all rounding schemes will automatically rebuild their internal tables to fix the band calculation issue, ensuring prices round correctly across all ranges.

  • Bug Fix SKU exception lock icon now displays after Execute

    When you run Execute with SKU-level exceptions, the grid now immediately shows the lock icon in the '*' column for affected products. Previously this icon was missing until you viewed the product's detail screen.

  • Bug Fix Restored lock icon display for SKU exceptions

    The batch SKU exception processing path introduced in May 2026 (MM-1193) carried forward pricing calculations and rule history but inadvertently omitted the [Lock] field update that drives the "*" column icon in the Main Table grid. This meant SKU exceptions processed during Execute Strategy would calculate correctly but show no visual indicator unless the user manually opened and closed SKU Detail for each item. The fix adds proper lock icon mapping (M for margin, R for set price, C for cost break, D for price levels) matching the original per-block behavior, restoring the audit trail that helps stores identify which items have active exceptions.

  • Bug Fix Blank Fixed Retail price no longer breaks custom pricing groups

    If you create a custom pricing group using Fixed Retail and forget to enter a price, the group will now save without errors instead of silently failing to update any items. Note: any existing groups that were saved with blank prices will need to be edited or deleted to work properly.

  • Bug Fix Blank Fixed Retail price no longer breaks custom group batch updates

    If you leave the Fixed Retail price blank when updating a custom group in the pricing panel, the system will now skip that action instead of failing the entire update for all items in the group.

  • Bug Fix Custom group skip guard now properly detects empty pricing actions

    If you configure a custom group with a pricing strategy like Fixed Retail but forget to enter a price, the system will now skip that group with a clear warning message instead of showing repeated error messages during processing.

  • Bug Fix Fixed custom group skip guard that could never trigger

    If you set up a custom group with an incomplete pricing strategy (such as choosing "Fixed Retail" but leaving the price blank), the system will now skip that group silently instead of logging error messages for each batch of items.

  • Bug Fix Auto-update restart now defers during active operations

    If an update is ready while you're running a strategy or exporting prices, you'll see a message explaining that the update will be applied automatically once your current operation finishes. Your work will no longer be interrupted.

  • Bug Fix Database Maintenance restricted to Margin Master databases

    Previously, when Margin Master connected to a shared SQL Express instance as sysadmin, the Database Maintenance dialog would enumerate and potentially operate on every user database on the server, including co-hosted POS system databases. The dialog now uses a fingerprint-based ownership check (matching the same signature tables used during install/upgrade/uninstall) to identify only Margin Master-owned databases. All maintenance operations—including Shrink Log Files, Rebuild Indexes, Update Statistics, Remove Unused Indexes, Remove Duplicate Indexes, Identify Missing Indexes, and Create Missing Indexes—are now restricted to the active Margin Master database.

  • Bug Fix Database maintenance scope restricted to owned databases

    When you run database maintenance on a shared server, the tool now automatically skips databases that belong to other software like your POS system.

  • Bug Fix SQL errors during strategy execution now display to user

    If something goes wrong during strategy execution, you'll now see an error message explaining the problem instead of the app appearing to freeze.

  • Bug Fix Corrected basic rounding no-decreases comparison

    Fixed the Rounding_Basic guard to compare the rounded price against CurrentPrice instead of FuturePrice, and to prevent decreases rather than cap increases. This now matches the correct pattern already used in the Rounding_PlusMinus and Rounding_Increment methods.

  • Bug Fix Custom pricing group subtract action parsing corrected

    Custom pricing groups that subtract an amount from prices will now work correctly when reopened or applied.

  • Bug Fix Export progress dialog now closes properly for Falcon, Mi9, Westlake, and Propello

    The progress dialog now closes automatically after exporting price changes to Falcon, Mi9, Westlake, or Propello systems instead of appearing stuck.

  • Bug Fix Export progress dialog now closes properly

    The "Exporting..." progress window now closes automatically when your export is complete.

  • Bug Fix Busy indicator now shows when switching strategies from any control

    The loading spinner now appears reliably every time you switch between pricing strategies, regardless of where you click.

  • Bug Fix Price lock status icons restored

    The lock column now shows the correct icon for each type of pricing rule applied to a product, making it easier to see at a glance which pricing method is in use.

  • Bug Fix Restore lock indicator icons

    Lock icons now display correctly in the grid showing which items have pricing locked and what type of lock is applied.

  • Bug Fix Automatic model reload after deletion

    After deleting a cost break model, the next model loads automatically so you can continue reviewing or deleting additional models without extra steps.

  • Bug Fix Added fallback wildcard conversion

    Added a defensive fallback that converts asterisk (*) wildcards to SQL percent (%) wildcards even when the "Like:" prefix is missing. This prevents wildcard filters from being treated as literal values if they bypass the normal conversion path.

  • Bug Fix Prevent infinite rebuild loop during concurrent sync and import

    Background sync operations will no longer cause the pricing grid to rebuild multiple times in a row, which previously made the application unresponsive during sync.

  • Bug Fix Wildcard filters now properly use SQL execution path

    Filters using wildcards (like "ABC*" to match all items starting with ABC) now work correctly in pricing strategies.

  • Bug Fix Corrected backup and restore menu item labels and commands

    The database menu now shows the correct labels for backup and restore options, making it clear which action each menu item performs.

  • Bug Fix Strategy Manager window close error

    Strategy Manager window now closes properly after saving changes without showing an error.

  • Bug Fix Fixed dirty tracking after moving strategy steps

    When you reorder strategy steps by moving them up or down, the dialog now correctly shows that changes need to be saved.

  • Bug Fix Renaming a strategy step now marks the strategy as dirty

    When you rename a pricing strategy step, the Save button will now activate and you'll be prompted to save changes if you try to close.

  • Bug Fix Strategy no longer marked as modified on open

    Opening a pricing strategy no longer triggers the "unsaved changes" warning when you close it without making any edits.

  • Bug Fix Fixed condition display not refreshing after edits

    When you edit or remove values from a pricing condition, the changes now appear immediately in the editor without needing to reopen the strategy.

  • Bug Fix Property change handler ignores events during close

    Added early return checks in the `OnPricingStrategyServicePropertyChanged` and `OnStepsChanged` event handlers to prevent processing property changes when the dialog is in the closing state. This prevents race conditions where events triggered by async save/reload operations could re-mark the dialog as dirty during shutdown.

  • Bug Fix Strategy rows no longer show as unsaved after successful save

    After you save changes to a pricing strategy, the rows will no longer appear highlighted as if they still have unsaved changes.

  • Bug Fix Dirty state properly cleared after successful save

    After saving changes to a pricing strategy, the editor will no longer incorrectly warn you about unsaved changes when you try to close the window.

  • Bug Fix Single-store fallback missing in SKU exceptions dialog

    Store selection dropdowns in the SKU exceptions screen now populate correctly for single-store locations instead of appearing empty.

  • Bug Fix Store selection fallback for SKU exceptions dialog

    The store selection dropdown in SKU Exceptions now populates correctly for all account types.

  • Bug Fix Added re-entrancy protection to click-to-set Future Price handler

    Rapid clicking on multiple items will now be handled safely—the second click is ignored until the first completes, preventing the application from becoming unresponsive.

  • Bug Fix Click-to-set now prevents unintended row selection

    Clicking a price column to set future price now only sets the price—it won't accidentally switch to a different product row.

  • Bug Fix Completed ListPrice import fix for all MySQL Compass configurations

    An earlier fix (MM-1169) added ListPrice mapping to the grouped-store import path, but multi-store setups without grouping use a different code path with separate MERGE scripts that were not updated. This change completes the fix by updating both SqlMergeMySqlStoreToStoreMainTable.sql scripts to include ListPrice in the SOURCE SELECT, UPDATE SET, INSERT columns, and VALUES clauses.

  • Bug Fix Ace Direct list prices now properly updated

    List prices will now import correctly whether you're using standard MySQL Compass or Ace Direct configurations.

  • Bug Fix Strategy step ordering corrected during restore

    Pricing strategy steps now appear in the correct order after restoring a backup, instead of appearing scrambled.

  • Bug Fix Strategy execution no longer terminates on scheme name mismatch

    Pricing strategies will run successfully even if rounding scheme names don't match exactly in capitalization.

  • Bug Fix Strategy step sequence numbering corrected during backup migration

    Pricing strategy steps are now restored in the correct order from older backup files.

  • Bug Fix Legacy V1 backup rounding schemes now migrate correctly

    Rounding schemes from older backups now restore correctly when upgrading from previous versions.

  • Bug Fix Legacy backup compatibility for rounding schemes maintained

    Rounding schemes from older backup files are now restored correctly, ensuring settings are preserved when upgrading or restoring from historical backups.

  • Bug Fix SKU exceptions now preserve List Price selection after save

    After saving a SKU exception with "List Price" selected, the form now correctly shows the saved state without incorrectly prompting you to save again.

  • Bug Fix SKU exception settings reload correctly after save

    After saving a SKU-level exception, the pricing settings will now display the correct saved values instead of showing outdated information.

  • Bug Fix Auto-apply setting no longer bypasses Wait preference

    If you've chosen to review errors manually, the dialog will always appear even when auto-apply is enabled.

  • Bug Fix Auto-apply preference now respects "Wait for User Input" setting

    Fixed an issue where the "auto-apply saved preference" setting would bypass the dialog even when the saved preference was set to "Wait for User Input". Now the dialog always appears when this preference is selected, honoring the user's explicit request to review each error.

  • Bug Fix Resolved dialog sizing conflicts

    Fixed conflicting size constraints where the dialog window specified Width=500 but the internal UserControl required MinWidth=580. The dialog now uses Width=560 with SizeToContent=Height and a MinHeight/MaxHeight range of 380-620 pixels, eliminating size conflicts and ensuring consistent display.

  • Bug Fix Strategy log time format simplified

    Strategy execution times are now easier to read, showing whole seconds for quick operations instead of detailed milliseconds.

  • Bug Fix Rounding scheme list correctly initializes on panel load

    Also fixed the initialization sequence during panel startup to ensure the rounding schemes list is properly cleared before being rebuilt, preventing similar issues when the panel first loads.

  • Bug Fix Rounding scheme restore fixed for all backup versions

    Applied the fix to both backup restore code paths: the newer V3 backup format (RestoreBackupDataModelV3Settings) and the legacy V1/blob restore path (RestoreBackupDataModelSettings). Both now seed RoundingScheme headers after restoring GlobalFileConfig ROUNDING entries, ensuring consistent behavior regardless of backup version.

  • Bug Fix Extended timeout for Ace Hardware MAP pricing updates

    Fixed an issue where Ace MAP pricing updates would fail to complete for stores with many products.

  • Bug Fix Settings Transfer now includes rounding schemes

    When transferring settings from another store's database, rounding schemes are now properly copied over.

  • Bug Fix Rounding scheme restore detection corrected

    The restore dialog now correctly shows which rounding schemes are available in a backup file.

  • Bug Fix SKU Detail changes now refresh Main Table grid immediately

    When you make pricing changes in the SKU Detail window, they now appear immediately in the main pricing grid as soon as you close the window. You no longer need to click "Refresh Data" to see your changes.

  • Bug Fix Main Table grid auto-refresh after SKU Detail edits

    When you make pricing changes or set exceptions in the SKU Detail window, those changes now show up immediately in the main pricing grid.

  • Bug Fix Future Price editing setting now applies immediately after changing Settings

    Changes to the Future Price editing option in Settings now take effect right away without needing to restart Margin Master.

  • Bug Fix Prevented accidental editing of non-Future Price columns

    Other pricing columns remain protected and cannot be accidentally edited, even when Future Price editing is enabled.

  • Bug Fix Improved editor activation logic for Future Price column

    Enhanced the ShowingEditor event handler to properly detect the Future Price column even when the Column property is null (which occurs with custom templates). The code now falls back to checking the TableView's FocusedColumn to determine if editing should be allowed.

  • Bug Fix Crash when saving new SKU-level exceptions

    The SKU Exceptions screen will no longer crash when saving changes in certain timing scenarios.

  • Bug Fix Reduce error logging severity for open issues retrieval

    Changed failed open issues retrieval from error-level to warning-level logging to reduce noise in logs when this non-critical operation fails.

  • Bug Fix Pricing strategy summary queries protected against missing tables

    The inventory backup service now ensures pricing strategy tables exist before generating summaries, preventing errors during the backup summary generation process.

  • Bug Fix Fixed crash when switching pricing strategies

    Fixed an error that could occur when quickly switching between pricing strategies on the SKU exceptions screen.

  • Bug Fix Prevented crashes in One-Click filters with null inventory values

    The One-Click screen will no longer crash when filtering by items with inventory or sales history when some products have missing data.

  • Bug Fix Pricing strategy filters now work with store groups

    Pricing strategies that use formula filters will now work correctly when applied to store groups instead of crashing.

  • Bug Fix SKU exceptions for "Ignore" action now clear price changes

    When you set a SKU exception to "Ignore," the strategy will now correctly clear any price change for that item.

  • Bug Fix SKU exceptions with REMOVECHANGE action now apply correctly

    If you set a SKU exception to "Ignore," the pricing strategy will now correctly remove any pending price changes for that item.

  • Bug Fix Pricing strategy restore now writes back to live data tables

    When restoring a backup, your pricing strategies' custom groups and SKU exceptions now properly appear in the application immediately after restore, instead of being invisible until manually recreated.

  • Bug Fix Fixed crash when exporting custom pricing groups after SKU import

    Exporting custom pricing groups to Excel will no longer crash after you've imported SKUs into those groups.

  • Bug Fix Fixed mixed-type data error in custom pricing groups Excel export

    Fixed an error that could occur when exporting custom pricing group strategies to Excel reports.

  • Bug Fix Corrected grouping logic for different POIN shift amounts

    Different rounding shift amounts are now kept separate during processing, ensuring each SKU exception gets the correct shift value applied.

  • Bug Fix Code quality improvements to prevent null reference issues

    Enabled nullable reference checking and resolved four pre-existing nullable warnings in the selection service to improve code safety and prevent potential runtime errors.

  • Bug Fix Backup now falls back to database when strategy steps are missing from configuration

    Pricing strategies with missing configuration data will now be backed up completely with all their pricing rules intact.

  • Bug Fix Corrected regression introduced by MM-1094 fix

    The March 2026 MM-1094 fix corrected the "no decreases" guard to compare against Current Price instead of Future Price. This exposed a latent bug where zero-price items were being incorrectly processed by rounding schemes. Items previously accidentally preserved by the old comparison logic are now explicitly and correctly skipped using the zero-price guard.

  • Bug Fix Increment-only rounding schemes now calculate prices correctly

    Pricing strategies that use only dollar increments (without specific price points) will now calculate prices correctly instead of showing $0.00.

  • Bug Fix Fixed database cleanup query column reference

    Corrected a SQL query in DatabaseUpdateService that attempted to delete obsolete "HasMultipleRSCs" setting using wrong column name [Key] instead of [Setting]. This cleanup operation was failing silently during database updates. The query now references the correct column and executes successfully.

  • Bug Fix Fixed persistent "Not in Database" errors

    SKUs that were stuck showing "Not in Database" errors will now be automatically corrected the next time you open the Custom Group.

  • Bug Fix Corrected "Not in Database" status for valid SKUs

    Products that exist in your system are no longer incorrectly shown with "Not in Database" errors in Custom Groups.

  • Bug Fix SKU exception pricing also protected from sentinel values

    Individual SKU exceptions will also show correct prices for high-value items instead of unrealistic sentinel amounts.

  • Bug Fix Rounding scheme overflow protection in SKU exceptions and column rules

    SKU exceptions and column-based pricing rules now handle prices outside the rounding scheme's range correctly, preventing unexpected overflow values in the pricing grid.

  • Bug Fix Runtime safeguard for unrecognized Custom Groups steps

    If a strategy contains a legacy Custom Groups step that wasn't migrated yet, it will be safely skipped during execution to prevent errors, and the system log will recommend reloading the strategy to fix it permanently.

  • Bug Fix Strategy history tracking with special characters

    The PSRuleHistory field, which tracks which pricing rules have been applied to each item, now correctly records step names containing apostrophes. This ensures accurate audit trails for pricing changes even when step names include special characters.

  • Bug Fix Prevented null prices when using competitor pricing levels

    Pricing strategies using competitor prices (Comp1-Comp5) now treat empty competitor prices as zero instead of producing blank future prices.

  • Bug Fix Correct property name in logging statement

    Fixed reference to ImportProcessing.ID property in logging (was incorrectly referencing .Id).

  • Bug Fix Zone-specific pricing now applies store-level overrides

    Stores with zone-specific pricing from Ace Hardware now receive their correct retail prices based on their assigned pricing zone.

  • Bug Fix Strategy error ignore action simplified

    When a pricing strategy step has an error and you click "Ignore," the step will be skipped completely and the strategy will continue with the next step.

  • Bug Fix Ace Hardware zone pricing import SQL error resolved

    Ace Hardware zone pricing will now import correctly without database errors.

  • Bug Fix Prevent overflow error in strategy execution timing

    Added bounds checking to the average-duration-per-step calculation in strategy execution logs. The value is now clamped before creating a TimeSpan to prevent OverflowException in edge cases where timing values could exceed maximum limits.

  • Bug Fix Guard against duration calculation overflow in strategy execution logs

    Fixed a rare crash in the Strategy Execution Logger when calculating average step duration. The system now validates that the calculated average is a finite number and clamps it to valid TimeSpan limits before formatting, preventing overflow exceptions in edge cases with unusual timing data.

  • Bug Fix Restore zone pricing marker icon

    The "Z" column now correctly shows which items have different prices for different store zones.

  • Bug Fix Custom group restore reliability

    Restoring custom groups from backup files now works correctly even if the backup contains duplicate items.

  • Bug Fix Improved custom group restoration from backup

    Restoring custom groups from backup files now works even if the backup contains duplicate SKU entries.

  • Bug Fix Rounding editor now displays rollback settings when reopening saved schemes

    When editing a saved rounding scheme that uses rollback rules, the rollback options now display correctly in the editor.

  • Bug Fix Resolved incorrect cost and retail display for DIB customers

    Items in the main pricing grid now display the correct current vendor costs and retail prices after a catalog sync, instead of showing prices from a previous version.

  • Bug Fix Corrected Shrink Log Files scope parameter

    The Shrink Log Files maintenance script was inadvertently receiving the server name instead of the database name, which caused it to run unscoped across all databases. The script now correctly receives the active database name and respects the ownership filter, ensuring it only shrinks log files for the connected Margin Master database.

  • Bug Fix Increased timeout for filter list database operations

    Added a 120-second command timeout to the UPDATE operation that resets negative or null future prices when applying filter lists. This prevents the operation from failing prematurely on large datasets or slower database connections.

  • Bug Fix Fixed post-rounding decrease removal WHERE clause

    Changed the decrease removal SQL from "WHERE FuturePrice > CurrentPrice" (which removes increases) to "WHERE FuturePrice < CurrentPrice AND FuturePrice > 0" (which correctly removes decreases). This cleanup step now properly enforces the no-decreases rule after all rounding has been applied.

  • Bug Fix Misleading MySQL import log message corrected

    Corrected a log message that appeared at the start of MySQL Compass POS imports. The message previously contained confusing text about stores not processing, when it should have simply indicated the import was beginning.

  • Bug Fix Help button repositioned on Pricing Strategy screen

    The help button on the Pricing Strategy screen is now positioned correctly next to the Export to Excel button.

  • Bug Fix Settings update no longer blocks progress reporting

    Changed the ApplicationSettings database write operation from asynchronous fire-and-forget to synchronous execution. Since the atomic MERGE completes in approximately 10ms, this preserves the UI thread context needed for progress updates while avoiding thread-switching issues that previously prevented progress from rendering.

  • Bug Fix PLACEHOLDER keys excluded from strategy step loading

    Strategy execution now excludes entries with the key 'PLACEHOLDER' when loading strategy steps from the database, preventing empty or invalid steps from being processed during strategy execution.

  • Bug Fix Automatic migration of pricing rules from old field to new field

    All existing pricing rules that used Auxiliary Retail continue to work automatically without needing to recreate them.

  • Bug Fix Automatic migration of existing pricing strategies

    Your existing pricing strategies that used Aux Retail will continue working automatically—no changes needed on your part.

  • Bug Fix Safer cost break level range validation

    Replaced unsafe index-based access in the cost break level property change handler with bounds-checked array access. This prevents crashes when background threads attempt to validate level ranges while the collection is being modified on the UI thread.

  • Bug Fix Allowed asterisk character in SQL validation

    Updated the SQL safety validation regex to permit the asterisk (*) character in WHERE clause expressions, preventing false-positive validation errors when wildcard patterns are used in strategy filters.

  • Bug Fix Managed indexes with missing columns now auto-disable gracefully

    Enhanced the managed index creation process to automatically disable indexes that reference columns no longer present in the database (such as Formula2/Formula3 after table rebuilds). Previously, these orphaned index definitions would cause recurring errors during diagnostics or optimization tasks. The system now detects SQL errors 207 and 1911 (invalid/missing column) and disables the affected index definitions automatically.

  • Bug Fix Removed non-functional restore option

    Removed the "Sort Options" checkbox from the restore dialog as it had no backing property and was never functional.

  • Bug Fix Manage Pricing Strategy save operation freeze

    Saving changes to a pricing strategy now completes instantly instead of freezing the window for several minutes.

  • Bug Fix Improved save and close sequence

    Refined the save-and-close process to properly synchronize step order changes and close the window only after saving completes, preventing potential data loss or incomplete saves when closing with pending changes.

  • Bug Fix Fixed discard changes behavior in strategy editor

    Clicking "No" when closing a pricing strategy now properly discards all your changes and shows the last saved version.

  • Bug Fix Fixed visual styling for inactive steps with unsaved changes

    Inactive pricing steps now display more clearly with gray text and background, while steps with unsaved changes show with yellow highlighting.

  • Bug Fix Null-safe string comparisons in SKU detail save

    Replaced instance .Equals() calls with static string.Equals() for SKU and StoreNumber property comparisons throughout the SKU detail save path. This prevents null reference exceptions when comparing potentially null values during record matching and filtering operations.

  • Bug Fix Improved string comparison reliability

    Replaced direct string equality checks with string.Equals() throughout SKU detail save operations to prevent potential null reference errors when comparing SKU and StoreNumber values.

  • Bug Fix Prevented unintended row selection during click-to-set Future Price

    Clicking a price column to set Future Price will no longer also select that row, preventing unexpected navigation while the update is in progress.

  • Bug Fix Hardened click-to-set against SQL errors from special characters

    Added apostrophe escaping to the SKU parameter in the UPDATE query to prevent SQL injection errors when processing SKUs that contain single-quote characters.

  • Bug Fix Rounding schemes now restore from GlobalFileConfig format

    Restoring a strategy backup now correctly brings back all your rounding scheme settings.

  • Bug Fix Fixed dialog appearing behind other windows

    Error dialogs will no longer appear hidden behind other windows on your screen.

  • Bug Fix Error dialog button caption now reflects selected action

    When a strategy loading error occurs, the action button now shows the correct label based on your selection (Ignore, Abort, or Accept) instead of always saying "Accept and Continue."

  • Bug Fix Strategy error dialog button caption corrected

    When a strategy encounters a load error, the action button now clearly shows what will happen when you click it ("Ignore and Continue" or "Abort Execution").

  • Bug Fix Settings transfer now includes rounding schemes

    Transferring settings between databases now correctly includes your custom rounding schemes.

  • Bug Fix False error logs when clearing cost break selection

    Eliminated spurious "NOT FOUND" error logs that appeared when clearing a cost break selection in the Future Price panel. Clearing the selection is valid behavior and no longer generates error telemetry.

  • Bug Fix Added validation for empty margin values in future pricing

    Future pricing rules will no longer create invalid margin settings if you leave the margin value blank.

  • Bug Fix Eight additional SKU exception actions now supported in batch mode

    Added missing SQL generation cases for RETAILZONE, FUTUREPRICE, STORECOST, LISTPRICE, ACE_MSURETAIL, ACE_MAPPRICEAMT, and ACE_IMAPPRICEAMT action types. These actions were previously ignored in batch mode but worked correctly in the per-block fallback path, creating inconsistent behavior. Batch mode now has full parity with the per-block execution logic.

  • Bug Fix Corrected obsolete settings cleanup query

    Fixed a SQL query in DatabaseUpdateService that referenced the wrong column name ('Key' instead of 'Setting') when removing the deprecated 'HasMultipleRSCs' setting.

  • Bug Fix Corrected property name and logging errors

    Fixed two build errors: corrected ImportProcessing.Id to .ID (property name typo) and added explicit string casts for dynamic MySQL connection identity fields in logging statements to resolve compiler warnings.

  • Bug Fix Bulk add-to-custom-group robustness

    Adding multiple items to a custom group from the main grid now correctly handles items that are already in the group.

  • Bug Fix Strategy steps list auto-selects first item after switch

    After switching strategies, the first step will now be automatically selected so you can immediately see its details instead of seeing a blank panel.

  • Bug Fix Better error handling for backup failures

    Added error message display when strategy backup fails, showing the specific error to the user and logging details for troubleshooting.

  • Bug Fix Window close error after saving strategy

    Clicking "Save and Close" in the strategy manager no longer shows an error message after saving.

  • Bug Fix Strategy step name changes now properly trigger save prompt

    The system now correctly prompts you to save when you've renamed a pricing strategy step.

  • Bug Fix Discard Changes now fully resets the pricing strategy

    Clicking "Discard Changes" when closing the pricing strategy editor now correctly cancels all your edits and reloads the original strategy.

  • Bug Fix Eliminated false "unsaved changes" prompts during scheme loading

    You'll no longer see incorrect "unsaved changes" warnings when switching between rounding schemes without making edits.

  • Bug Fix Fixed SQL injection vulnerability in Future Price update

    Escaped apostrophes in SKU values before interpolating them into the SQL UPDATE statement. SKUs containing apostrophes would previously cause the query to fail or behave unpredictably.

  • Bug Fix Click-to-set Future Price respects column editing mode

    Fixed MM-1174 by ensuring click-to-set Future Price functionality properly handles the Future Price column regardless of the inline editing setting. The hit-test logic now runs before checking the SetFuturePriceOnClick guard, preventing conflicts between the two modes.

  • Bug Fix Downgrade failures now detectable

    If you downgrade to an older version and it doesn't take, Margin Master now knows and tells you instead of pretending it worked.

  • Bug Fix Added early return for non-price column clicks

    The handler now returns immediately when clicking non-price columns (such as SKU, Department, etc.) rather than processing through the full switch statement and doing nothing. This prevents unnecessary work and potential edge-case errors.

  • Bug Fix Diagnostic logs cleared on startup to prevent confusion

    DiagnosticTool now deletes previous session log files on startup (DiagnosticTool-*.log), ensuring the log directory only contains the current session's logs. This prevents old error messages from being analyzed by the AI when troubleshooting current issues.

  • Cloud Sync SQL-based strategy backup system

    Strategy backups now POST to the Manager API and store JSON in a SQL database (RS_Data table) instead of Azure Blob Storage. The API tracks backup date, version (V1/V2/V3), trigger source, and file size. A migration utility (MarginMaster.BlobMigration) is available to import existing blob backups into the new system.

  • Cloud Sync Organization-scoped strategy backups

    Modified strategy backup API calls to support organization-level scope instead of vendor-specific scope. The system no longer sends vendor type when creating backups, allowing backups to be managed at the organization level across multiple stores.

  • Cloud Sync Optimized zone pricing update logic

    Enhanced the change-detection logic in the zone pricing update script to include base price columns in the WHERE clause, ensuring the UPDATE statement only executes when Retail, Level1, or Level2 values actually differ for zone 99999 records. This prevents unnecessary database writes while maintaining data accuracy.

  • Cloud Sync Improved sync detection for base pricing changes

    Enhanced the WHERE clause logic to detect when base pricing columns need updating from zone 99999, ensuring the sync process captures all relevant price changes and keeps the local database fully up to date.

  • Cloud Sync Strategy cloud backup commands connected

    Connected the existing STRATEGY_BACKUP_CLOUD and STRATEGY_RESTORE_CLOUD backend commands to the new menu items, allowing users to save their pricing strategy configuration to the cloud and retrieve it later. This complements the existing local backup/restore functionality.

  • Cloud Sync Simplified backup submission API

    Removed VendorType parameter from strategy backup submission since the server now automatically resolves the vendor from the store configuration. This simplifies the backup process and ensures consistency with the organization-scoped backup strategy.

  • Cloud Sync Improved server-side store resolution

    Updated both automatic and manual strategy backup workflows to pass the vendor type (VendorNameShort) alongside the store number. This allows the server to use the combination of store number and vendor name to resolve the unique Store record and correctly determine VendorId and OrganizationId for backup storage.

  • Cloud Sync API client method signature updated

    The SubmitStrategyBackupAsync method now requires the vendor type parameter to be passed explicitly, ensuring all backup submissions include complete metadata about the store's primary vendor configuration.

  • Cloud Sync Backup list retrieval now filters by vendor ID

    When viewing available strategy backups to restore from the cloud, the system now sends the vendor ID to properly filter the list. Previously, this could have resulted in seeing backups from the wrong vendor or missing valid backups.

  • Cloud Sync MFG Cost propagates to group tables during import

    MFG Cost values propagate from store main tables to group main tables during MySQL imports using MIN aggregation. The field is deliberately excluded from the SqlMergeMySqlStoreToGroupMainTable sync path to match List Price's existing behavior pattern.

  • Data Import Relocate DIB Aux Retail to Level3 field

    The Auxiliary Retail price from Do-It-Best now appears in the Level3 column instead of Level5Zone in the pricing grid.

  • Data Import DIB Aux Retail now imports to Level3 field

    Do-It-Best Aux Retail prices now appear in the Level3 column alongside your other pricing levels.

  • Data Import Improved auxiliary retail handling for multi-unit items

    Multi-unit display items (like boxes of screws) will now show correct per-unit auxiliary retail prices instead of the full box price.

  • Data Import Improved store number detection for single-store configurations

    Enhanced the database query logic to fall back to the main inventory table when the SelectionLists table doesn't contain store number entries. This situation occurs naturally for single-store customers since the system doesn't build selection dropdowns for fields with only one unique value.

  • Data Import Add single-store POS system detection

    Added logic to identify POS systems that don't support multi-store exports (currently CounterWorks). These systems hardcode all imported data to store number '0', so any other store numbers in the database represent stale legacy data that should be automatically removed during import to prevent data contamination.

  • Data Import Compass MySQL imports now capture List Price

    When you import data from Epicor Eagle, the system will now automatically capture and display List Price information if it's available in your POS system.

  • Data Import Extended timeout for price variance calculations

    Increased the timeout for the CurrentPriceVariances calculation from default (30 seconds) to 600 seconds (10 minutes) to accommodate the scalar UDF performance limitations on large datasets. This ensures variance calculations complete even when SQL Server cannot parallelize the query.

  • Data Import Added automatic migration for legacy SKU Level Exceptions steps

    Pricing strategies from older systems are automatically updated to work correctly when you load them, removing duplicate or incorrectly named exception steps.

  • Data Import Strategy restore process aligned with live data sources

    Restoring pricing strategies from backup will now properly restore all your strategy settings and custom groups.

  • Data Import Automatic migration of prefixed Custom Groups steps

    You no longer need to manually fix or recreate Custom Groups steps after importing pricing strategies from older systems.

  • Data Import Fixed vendor cost and retail price import accuracy

    Vendor pricing information in the main pricing grid now matches the actual values from Do-It-Best catalogs.

  • Data Import Simplified vendor data update process

    Streamlined the SQL update procedure by removing the PriceAdj common table expression and associated ratio calculations. All vendor pricing fields (Retail, Level1-5, DIB costs, and Cost2) now transfer directly from vendor data without intermediate calculations, improving import performance and data accuracy.

  • Data Import Automatic database migration at startup

    Added a one-time migration routine that runs during application startup to update strategy configuration data. The migration only runs for Ace Hardware stores and safely updates strategy rules without requiring manual intervention.

  • Data Import MFG Cost imported from MySQL Compass vendor catalogs

    MFG Cost values automatically import from your vendor catalog files during regular POS imports.

  • Data Import Strategy backups no longer capture database connection settings

    New strategy backups created after this fix will not include DatabaseConnections.json, consistent with the blob-backup feature which already excluded this file for the same reason. Legacy V1/V2 backups that contain this section will deserialize without error but the connection data will be ignored during restore.

  • Data Import Epicor Compass import now populates List Price

    Modified the Compass MySQL import process to extract the in_list_price value from the EAGLEDW.IN table and populate the new ListPrice column during data imports. The field is carried through all data transformation steps including table merges and group table operations.

  • Data Import MFG Cost imported from POS systems

    If your POS system tracks manufacturer cost, this information will now automatically appear in Margin Master after each data import.

  • User Interface Improved progress feedback for strategy step loading

    When switching pricing strategies, you'll now see the progress window update smoothly with item counts for each custom step, instead of appearing frozen near the end of the loading process.

  • User Interface Expanded rounding schemes documentation

    The rounding schemes help page is now easier to navigate and includes examples showing how to set up nickel rounding (5 cent), dime rounding (10 cent), and other common pricing patterns used by hardware stores.

  • User Interface Strategy execution progress shown in title bar

    You can now see which step is running in the window title when executing a strategy.

  • User Interface Strategy execution progress display in title bar

    When running a pricing strategy, you'll now see which step is currently processing in the window title bar, making it easier to track progress through long-running strategies.

  • User Interface Expanded allowed characters for strategy names

    When creating or renaming a pricing strategy, you can now include < and > symbols in the name (for example, "Clearance <50%" or "Premium > $100").

  • User Interface Help button alignment on strategy window

    The help button now appears in the correct position alongside the Export to Excel button.

  • User Interface Splash screen appears immediately when executing strategies

    When you click Execute Strategy, the progress window now appears right away instead of after a short pause, making the application feel more responsive.

  • User Interface Splash screen displays immediately on Execute Strategy

    When you click Execute Strategy, you'll now see the splash screen and status messages right away instead of waiting. This helps you know the system is processing your request.

  • User Interface Busy indicator for step reordering operations

    When you drag steps up or down in your pricing strategy, you'll now see a "Moving step..." message appear briefly while the change is being processed.

  • User Interface View toggle system for Strategy Manager and Options

    A "Use New View" button now appears on the Strategy Manager and Options screens, letting you switch to the updated interface. If you prefer the classic version, click "Use Legacy View" to switch back. Your choice is saved automatically.

  • User Interface Enhanced visual styling for inactive strategy steps

    Inactive pricing strategy steps are now easier to spot with a gray background color.

  • User Interface Clearer condition value formatting in pricing strategy detail panel

    Multi-value conditions in pricing strategies now show as readable text like "Vendor is ACE or DIB or Orgill" instead of separate boxes, making it clearer how the rule works.

  • User Interface Relocated legacy view toggle to hamburger menu

    The "Use Legacy View" button is now located in the hamburger menu (three lines icon) at the bottom, instead of on the main toolbar.

  • User Interface Disable all controls during busy operations

    All buttons and fields are now grayed out while pricing strategies are being saved, loaded, or calculated, preventing you from accidentally clicking anything until the operation finishes.

  • User Interface Disable all controls during busy operations

    The pricing strategy screen will now gray out and prevent edits while saving or loading, ensuring your changes aren't accidentally overwritten.

  • User Interface ListPrice added to price comparison dropdowns

    When choosing which prices to compare in the pricing grid, ListPrice now appears as an option in the dropdown menu.

  • User Interface Improved dialog layout

    Error messages and action choices in the Strategy Load Error dialog are now arranged vertically for easier reading.

  • User Interface Strategy log time format simplified

    Strategy execution logs now show simpler time formats like "5s" or "2m 15s" instead of including milliseconds.

  • User Interface Live progress updates during SKU exception batch processing

    When you apply pricing exceptions to thousands of SKUs, the splash screen will now show you which pricing formula is currently being applied and how many SKUs are being processed, giving you confidence that the operation is working and hasn't stalled.

  • User Interface Single-click Future Price editor activation

    You can now start editing Future Price values with a single click when the inline editing option is turned on.

  • User Interface Cloud strategy backup/restore menu items added

    Added two new menu items under the Strategy submenu: "Backup Strategy to Cloud" and "Restore Strategy from Cloud". These options appear below the existing local backup/restore options and use cloud upload/download icons to distinguish them from local operations. The underlying functionality was already implemented but previously inaccessible to users.

  • User Interface Store column added to restore strategy dialog

    The restore dialog now shows which store created each backup, making it easier to identify the right backup when multiple stores share access.

  • User Interface Documentation updated for fixed price mode in Cost Break Analysis

    The help documentation now explains how to use the fixed price option in Cost Break Analysis, which lets you set one price for all items in a cost range instead of using a margin percentage.

  • User Interface Busy spinner now appears after confirmation dialog

    The loading spinner will no longer cover up the "Update this Cost Break?" confirmation message, making it easier to read and respond to the prompt.

  • User Interface Pricing Strategy dropdown now shows code descriptions for Ace Hardware

    When you click to filter the Pricing Strategy column, the dropdown now shows descriptions like "S - Sensitive" and "C - Competitive" so you can see what each code means without memorizing them.

  • User Interface Improved Pricing Strategy grid performance

    The Pricing Strategy screen now responds immediately when switching between strategies, even those with hundreds of pricing rules.

  • User Interface Improved strategy step focus after switching

    After switching strategies, the first pricing step is automatically selected so you can immediately see its details in the right panel.

  • User Interface Plus/minus spinner now displays units directly
  • User Interface Added increment rounding feature clarification

    If you need prices rounded to the nearest nickel (5 cents) or dime (10 cents), use the Increment Rounding option in the rounding editor rather than trying to configure it with the penny rounding grid.

  • User Interface Window height reductions for smaller displays

    Configuration and database windows are now smaller and fit better on laptop screens.

  • User Interface Dialog window size optimization

    Several settings and configuration windows have been resized to fit better on your screen without excessive scrolling or extending off-screen.

  • User Interface Update DIB field labels for standard level columns

    Do-It-Best stores will see clearer column names that match the price types from Do-It-Best catalogs.

  • User Interface Updated DIB pricing field labels

    The pricing grid now shows clearer labels for Do-It-Best pricing columns (Aux Retail, Sug Retail, and EDLP).

  • User Interface Corrected menu labels for backup and restore operations

    The File menu now shows the correct labels: "Backup Database", "Restore Database", "Backup Strategy", and "Restore Strategy" each do what their names say.

  • User Interface Simplified restore dialog

    The restore screen now shows fewer, more useful options in a simpler layout, making it easier to restore your pricing strategy and settings.

  • User Interface Simplified restore dialog layout

    The restore dialog is now more compact and easier to read, with all options in a single list instead of split across two columns.

  • User Interface Simplified strategy grid cell styling

    Streamlined the visual styling logic for inactive and modified strategy steps by removing expensive FindAncestor data bindings and consolidating three multi-data triggers into two simpler data triggers plus one multi-trigger. Also removed a hidden IsDirty column that was triggering unnecessary style recalculations.

  • User Interface Strategy Manager V2 placeholder screen

    The new Strategy Manager screen is now accessible with a simplified toolbar layout. Full functionality including the optimized strategy grid will be available in the next update.

  • User Interface Pricing Strategy Manager V2 placeholder view

    The new Pricing Strategy Manager preview shows a placeholder screen with "coming soon" messaging — the current version remains fully functional.

  • User Interface Simplified step movement commands

    Step movement buttons and menu options now respond immediately when clicked, with no delay or loading indicator.

  • User Interface Added loading indicator during Manage Pricing Strategy window startup

    You'll now see a "Loading strategy steps..." message with a spinner while the Manage Pricing Strategy window opens, so you know the window is loading properly.

  • User Interface Loading indicator during startup

    You'll see a "Loading strategy steps..." message when opening the Pricing Strategy editor while it loads.

  • User Interface Remove in-dialog loading indicator

    You'll no longer see a "Please wait" message inside the Pricing Strategy dialog — all loading happens before the dialog opens.

  • User Interface Streamlined rounding scheme selector

    Replaced the custom rounding scheme selection control with a standard combo box that binds directly to the available rounding scheme names. The control is automatically enabled/disabled based on the "Use Rounding" checkbox state.

  • User Interface Improved performance when selecting pricing strategy steps

    Switching between pricing strategy steps is now faster and more responsive with no loading delays.

  • User Interface Strategy editor right panel

    Resolved issue MM-1145 where strategy step details were completely hidden in the right panel due to missing view model binding property.

  • User Interface Improved feedback during discard operation

    You'll now see a "Discarding changes..." message when you choose not to save your pricing strategy changes, so you know the app is working.

  • User Interface Condition editor button layout updated

    The condition editor popup now shows two buttons at the bottom: "Reset" to undo changes and "Close" to exit the editor.

  • User Interface Improved condition editor button layout

    The condition editor popup now shows Reset and Close buttons next to each other at the bottom, making it easier to find and use both options.

  • User Interface Improved event handler shutdown logic

    Added _isClosing guards to OnStepsChanged and OnPricingStrategyServicePropertyChanged event handlers to prevent them from updating UI state during the window close sequence, ensuring clean shutdown behavior.

  • User Interface Applied fix to both save actions

    Whether you click the Save button or close the window and choose "Yes" to save changes, the loading indicator will display correctly in both cases.

  • User Interface Remove development test button

    Removed an orange "Test Busy" button that was used during development to verify the busy indicator functionality. This was a temporary testing control not intended for production use.

  • User Interface Remove test button from toolbar

    Removed a development test button that was inadvertently left in the production interface.

  • User Interface Enable full row selection in SKU Level Exceptions grid

    In SKU Level Exceptions, the entire row now highlights when selected, making it easier to see which SKU you're working with.

  • User Interface V2 strategy manager now defaults at each startup

    Each time you start Margin Master, you'll see the modern pricing strategy manager by default. If you switch to the legacy view, that choice only lasts until you close the program.

  • User Interface Updated view switch dialog text

    The message when switching views now says "continue with the strategy" instead of "re-run" to match what actually happens.

  • User Interface Removed "Database Connections" option from restore dialog

    The restore options tree no longer shows a "Database Connections" checkbox. This option was misleading because restoring database connections from a backup always caused problems rather than helping users. Legacy backups that contain this data will still restore successfully—the connection settings are simply ignored.

  • User Interface Removed Database Connections option from restore dialog

    When you restore a strategy backup, you'll no longer see a "Database Connections" checkbox that could accidentally disconnect your database.

  • User Interface Improved error handling in pricing screens

    When editing pricing strategies or custom groups, the rounding scheme dropdown now correctly selects your saved scheme even if the capitalization has changed.

  • User Interface ListPrice added to Set Future Price options

    When setting future prices, you can now choose to set them to the vendor's ListPrice value automatically.

  • User Interface Improved dialog behavior for safer default actions

    The countdown auto-execute feature is now limited to the only safe action (Ignore and Continue). This prevents accidental data loss or import interruptions from auto-firing destructive actions like Abort when users have pre-saved their error handling preferences.

  • User Interface Enhanced dialog sizing behavior

    The Strategy Load Error dialog now automatically adjusts its size to fit the error message without unnecessary extra space.

  • User Interface Strategy log column order adjusted

    In strategy logs, the total number of SKUs now appears before the number of changes.

  • User Interface Search panel restored in Manage Custom Groups screen

    You can now press Ctrl+F to search for specific custom groups by name or other details in the Manage Custom Groups screen.

  • User Interface Double-click behavior refined for Future Price editing

    Double-clicking a Future Price cell while editing keeps the editor open instead of opening the item details window.

  • User Interface Improved Future Price column cursor feedback

    The mouse cursor now clearly shows whether Future Price cells can be edited or not.

  • User Interface Improved click-through behavior for Future Price template

    Made the Future Price cell template grid transparent to mouse clicks so that clicks pass through to the underlying grid cell element, improving the reliability of single-click editing activation.

  • User Interface Future Price column display updated

    The Future Price column now uses two different display modes: when editing is disabled, it uses the up/down arrow template for visual indication; when editing is enabled, it uses standard currency formatting (C2) to ensure the editor remains visible during data entry.

  • User Interface Menu Organization Enhancement

    The Strategy menu now clearly separates local file backups from cloud backups with a divider line, making it easier to choose the right option.

  • User Interface Cloud restore dialog with backup history

    When restoring from the cloud, you can now see a list of all your saved backups with dates and choose which one to restore.

  • User Interface Store number column added to restore dialog

    When you open the restore strategy dialog, you'll now see which store each backup came from in a new "Store" column.

  • User Interface Cost break grid columns for fixed pricing

    The cost break grid now displays two new columns: "Fixed Price" (checkbox) and "Fixed $" (dollar amount). The dollar amount field is only enabled when the Fixed Price checkbox is checked, preventing accidental entry when using margin-based pricing.

  • User Interface New columns in cost break grid

    The cost break pricing grid now displays two new columns: "Fixed Price" (a checkbox to toggle the pricing mode) and "Fixed $" (a currency input field that is only enabled when the checkbox is checked). These columns appear alongside the existing "Target Margin" column, allowing users to choose their preferred pricing method per level.

  • User Interface New subtract field in Rounding Editor

    The Rounding Editor's increment rounding panel now displays a "Subtract" input field below the "Above" field. This currency-formatted field accepts positive or negative decimal values and defaults to $0.00 when empty.

  • User Interface New offset input field in Rounding Editor

    Added a currency-formatted text field labeled "Subtract" to the Increment Rounding section of the Rounding Editor screen. The field accepts dollar amounts, defaults to $0.00, and displays with standard currency formatting (C2 mask).

  • User Interface Simplified fixed price and margin field visibility

    Cost break pricing rows now show only the pricing field you're actually using—you'll see either "Fixed Price" or "Target Margin" based on your selection, making it clearer which pricing method is active.

  • User Interface Fixed pricing column visibility in cost break grid

    The pricing grid now shows only the relevant column (Fixed Price or Target Margin) based on which pricing method you've selected, making it clearer which values are active.

  • User Interface Improved error messages for strategy steps with missing data

    Warning messages now clearly show which category values will be used and which are being skipped when running a pricing strategy.

  • User Interface Enhanced error messaging for strategy step validation

    When a strategy step has missing categories, you'll now see a clearer message explaining which categories will be used and which are missing, with options to continue or stop.

  • User Interface Improved error messaging for cloud operations

    The error dialog displays the specific failure reason from the cloud service and provides clear next steps: verify internet connectivity and try again, or contact support if issues persist. This replaces the previous silent failure behavior where users had to check log files to diagnose problems.

  • User Interface Improved error messaging

    The new error dialog displays the specific error reason when available, helping users and support staff diagnose cloud connectivity or authentication issues more quickly.

  • User Interface Reduced splash screen flicker during auto-continued strategy errors

    The screen no longer flickers when automatically skipping problem steps in a pricing strategy.

  • User Interface One-time notification for corrected in-use schemes

    If you use a rounding scheme that was corrected, you'll see a one-time message explaining the fix and asking you to verify the results using the Check button in the rounding editor.

  • User Interface Updated Epicor import options help text

    Removed the word "always" from the store mapping description on the Epicor settings screen to accurately reflect that store mapping is configurable rather than mandatory.

  • User Interface Update Problem dialog with repair install option

    The "Could Not Update" dialog shows you what version you're on, what version it tried to install, and why it failed. You can install it directly (Margin Master downloads the installer and runs it for you), send the problem to support with everything filled in, or wait 24 hours.

  • User Interface Prevented duplicate strategy switch triggers

    Added suppression logic to the pricing strategy combo box to prevent it from triggering redundant strategy switches when the selection is updated programmatically (as opposed to user clicks). This eliminates unnecessary processing and potential race conditions when the UI updates itself in response to strategy changes.

  • User Interface Improved scheme management instructions

    The help now explains how to make a copy of a built-in scheme like "Ace-1" so you can customize it for your store without starting from scratch.

  • User Interface Improved cloud restore feedback

    When restoring from the cloud, you'll see clear progress messages showing what's happening at each step.

  • User Interface Added busy indicators for move operations

    You'll now see a "Moving step..." message briefly appear when reordering strategy steps, confirming the action is in progress.

  • User Interface Consolidated Options menu item

    The Tools menu now shows only one "Options" entry instead of two separate menu items.

  • User Interface Toggle buttons added to legacy screens

    Adds "Use New View" buttons to both the legacy Pricing Strategy Manager (ManagePricingStrategyView) and legacy Options window (frmOptions) that switch the user to the new version and persist the preference via ApplicationSettingsService. When toggled, the current dialog closes and reopens with the alternate view.

  • User Interface Strategy grid with visual status indicators

    Strategy steps now display with visual cues: inactive strategies appear grayed out, and strategies with unsaved changes are clearly marked so you know when to save.

  • User Interface Lazy-loaded step detail panel

    The strategy step detail panel (right side of dialog) is now created only when the user first selects a step, rather than being created during dialog initialization. This optimization reduces memory usage and startup time.

  • User Interface Removed main window splash screen for strategy dialog

    The main window no longer shows a "Loading Pricing Strategies..." splash screen before opening the dialog. All loading feedback now appears within the dialog itself using its built-in busy indicator, providing a cleaner and more responsive user experience.

  • User Interface Improved condition value display

    Simplified the display of condition values in strategy steps to show values in a wrapped panel layout without unnecessary selection or delete controls for read-only items.

  • User Interface Simplified condition display in step details

    Updated the conditions section to use a cleaner ItemsControl with simple Border elements instead of a complex ListBoxEdit with selection and delete capabilities. Condition values are now displayed as read-only chips, matching their actual behavior in the interface.

  • User Interface Condition editor popup with value management

    Added a centered popup dialog displaying the condition name, operator (e.g., "equals", "contains"), and scrollable list of values. Each value has a remove button. The popup closes automatically when the last value is removed or when the user clicks the Close button.

  • User Interface Improved scheme selection and dirty tracking

    Decoupled the UI's selected scheme from the global service state using a local backing field. The active scheme in the service is now only updated when the window closes, preventing circular event cascades that previously caused unexpected behavior. Added an isLoadingScheme flag to suppress false dirty-state detection when switching between schemes programmatically during copy/delete operations.

  • User Interface Improved delete and navigation behavior in Rounding Editor

    After deleting a rounding scheme, the editor now automatically returns to the scheme you were viewing before, making it easier to manage multiple schemes.

  • User Interface List Price available in Selection Boxes for Ace stores

    When creating selection boxes for Ace stores, you can now include "List Price" as one of the displayed or filtered fields.

  • User Interface Improved dialog window focus behavior

    The error dialog will now reliably appear on top of other windows so you don't miss it.

  • User Interface Updated progress messaging

    When watching pricing strategies run, you'll see "batch mode" in the progress display for SKU exceptions.

  • User Interface Main Table screen interaction improvements

    The pricing grid is now easier to navigate and updates faster when you make changes through the SKU Detail window.

  • User Interface Improved Custom Groups screen reliability

    The Custom Groups screen now shows accurate SKU information without confusing duplicates or error messages.

  • User Interface Editor validation prevents saving unusable increment amounts

    The rounding editor now prevents you from saving an increment amount higher than $1,000, which would stop items from rounding correctly.

  • User Interface Improved Catalog Lookup grid column sizing

    Updated column width behavior throughout Catalog Lookup: search results grid changed from AutoWidth=True to fixed widths, SKU column uses MinWidth with auto-sizing, and zone pricing columns use consistent 80-pixel widths for Retail, Level 1, Level 2, and MSU Retail.

  • User Interface Improved loading status messages

    Loading messages now show more helpful information like "Loading 47 strategy steps..." instead of generic status text.

  • User Interface Removed unused styling rules

    Cleaned up obsolete strikethrough text decorations and a hidden "IsDirty" column that were no longer needed, further simplifying the grid rendering pipeline.

  • User Interface Integrated saved selection workflow

    You can now choose to load a saved selection or custom group directly after closing the Strategy Manager, saving navigation steps.

  • User Interface Improved SKU Exceptions grid navigation

    You can now use arrow keys to move between exception rows more easily in the SKU-level exceptions screen.

  • User Interface List Price available in Column View and Selection Box editors

    To see List Price in your pricing grid, open the Column View editor and add the "List Price" field. You can also use it as a filter criterion in your Selection Boxes.

  • User Interface Restore dialog now shows available rounding schemes

    In the Restore Backup dialog, the "Rounding Schemes" section will now show as available (not grayed out) when your backup file contains rounding scheme data.

  • User Interface MFG Cost appears in Main Table grid and selection tools

    MFG Cost is now available as a grid column in the Main Table view with currency formatting (c2), default column width matching other cost fields, and display text "MFG Cost" (short: "MC"). The field also appears in selection boxes, future price panels, and custom group configuration dialogs.

  • User Interface Simplified Options menu

    Removes the separate "Options (New)" menu item from the Edit menu, consolidating to a single "Options" entry that respects the user's view preference setting.

  • User Interface Direct step reordering with collection move

    Implemented a fast direct move operation (MoveStepDirect) that reorders steps by moving items within the ObservableCollection without triggering full grid rebinds or dirty-checking loops. This makes drag-and-drop reordering feel instantaneous.

  • User Interface Strategy grid rendering optimization

    Opening the Manage Pricing Strategy window now shows a "Rendering strategy grid..." message while loading, giving clearer feedback about what the app is doing.

  • User Interface Enhanced strategy management dialogs

    Added integrated dialog services for Strategy Name input, Custom Groups management, Rounding Scheme selection, and SKU Level Exceptions, all accessible from within the V2 Strategy Manager with consistent sizing and positioning.

  • User Interface Launch Diagnostics from Database Setup window

    You can now click "Launch Diagnostics" from the database setup screen if you're having trouble connecting.

  • User Interface AI tab auto-activates on selection and supports Enter key

    Pressing Enter in the AI chat box now sends your message—no need to click the Ask button.

  • User Interface Check for Updates in Database Setup window

    You can now check for and install Margin Master updates from the database connection screen before logging in.

  • User Interface Check for Updates in Database Setup

    You can now check for Margin Master updates from the startup screen before connecting to a database.

  • Database Add PricingStrategy table creation to database update routine

    Your database will automatically be updated to support advanced pricing strategies when you start the application. No manual action is required.

  • Database Automatic column migration for existing databases

    Implemented automatic database migration that adds the ListPrice column to all existing main tables on application startup. Uses a one-time flag (ListPriceColumnAdded) to ensure the column is added only once, following the same pattern as previous Ace MAP column additions.

  • Database Covering index for Ace Hardware zone pricing queries

    Zone pricing updates for Ace Hardware will now run significantly faster, especially the first table updated after opening Margin Master or after a catalog refresh.

  • Database Added table creation scripts for complete PricingStrategy schema
  • Database Added defensive table creation to backup operations

    Both BackupInventoryService and BackupService now call CreatePricingStrategyTables (which is idempotent using IF NOT EXISTS) at the start of any pricing strategy query operations, ensuring database consistency across all backup/restore workflows.

  • Database Track last cloud upload timestamp and content signature

    Two new application settings store the timestamp and SHA256 hash of the most recent successful strategy upload to the cloud. These values are used to determine whether a new upload is necessary based on content changes and elapsed time.

  • Database Improved PSRule and PSRuleHistory field handling

    Both the PSRule tracking field and PSRuleHistory audit trail now correctly handle special characters in strategy step names, ensuring accurate price change history even when step names contain quotes or apostrophes.

  • Database Added filtered index for future price operations

    Created a new filtered index (RSIX_*_FuturePrice) on the FuturePrice column that only indexes rows where a future price is actually set (not NULL and not 0). This targeted index dramatically reduces the number of rows the database must examine when resetting future prices.

  • Database Optimized DIBMailBox pricing integration for BisTrack

    The new BisTrack import script includes logic to detect whether the DIBMailBox_ItemPricing table exists and contains data, then performs a 3-table JOIN using a pre-aggregated subquery that returns only one row per item/store combination. This prevents the pricing mailbox from creating multiple rows for the same SKU when multiple price records exist, which was the root cause of the duplicate row problem.

  • Database Strategy backup metadata updated

    Added StoreNumber field to strategy backup list items to support displaying store information in the restore interface and enable organization-level backup management.

  • Database Backward-compatible cost break storage

    The new UseFixedPrice and FixedPrice fields are stored in the existing JSON configuration. Existing cost break configurations are unaffected as the new fields default to false and 0, maintaining current margin-based pricing behavior.

  • Database Extended increment rounding storage

    The increment rounding offset is stored in the second position of the Points array in RoundingLevel records. Existing records without this value automatically default to $0.00, maintaining full backward compatibility with previously configured rounding schemes.

  • Database Extended rounding level data model for offset storage

    Extended the IncrementRoundingModel and RoundingLevel classes to store and retrieve the offset amount. The offset is persisted as the second element in the Points array (Points[1]), while the rounding method index remains in Points[0]. The SQL rounding calculation now adds the offset to the final rounded price.

  • Database One-time migration regenerates existing increment scheme tables

    Added automatic per-database migration that regenerates the detail tables for all custom increment rounding schemes, removing the incorrectly baked increment values while preserving the increment rules themselves. This migration runs once when the application starts after this update, ensuring existing schemes produce correct results immediately.

  • Database MFG Cost column added to main tables

    Added MfgCost decimal(18,2) column to all mainTable variants via one-time startup migration. The migration runs once per database, tracked via the MfgCostColumnAdded application setting flag, and adds the column to all store and group main tables if not already present.

  • Database New application settings for view preferences

    Added UseLegacyStrategyManager and UseLegacyOptions boolean settings to ApplicationSettingKey enum, both defaulting to false (new views). These settings are persisted in the application settings table and checked when opening either the Strategy Manager or Options dialogs to determine which view to display.

  • Database Clear cost break cache when saving or deleting cost breaks

    Added cache invalidation to ensure the cost break names cache is properly cleared when cost breaks are saved, deleted, or cleaned up, preventing stale data from being displayed.

  • Database Automatic schema upgrade for existing databases

    The first time you start Margin Master after this update, the database will automatically update to support the new List Price column—no manual steps required.

  • Database Detection logic for identifying affected schemes

    Added logic to identify rounding schemes containing increment rules with the $99,999.99 sentinel value and determine whether each scheme is actively used by checking references in pricing strategies, custom groups, and SKU exceptions. Real increment values ($1, $3, $10, 5¢, etc.) used by other stores are correctly identified and left untouched by the correction process.

  • Database Automatic database migration for MFG Cost

    The application automatically adds the MfgCost column to all main tables (mainTable and store-specific tables) on first launch after upgrade. A new ApplicationSettingKey.MfgCostColumnAdded flag prevents duplicate migrations. The field is also included in all SQL scripts for creating new tables and merging data.

  • Database New StrategyBackupListItemDto model

    Added StrategyBackupListItemDto with Id, BackupDate, BackupType, TriggerSource, BackupVersion, and FileSizeBytes properties. Includes FormattedSize helper to display human-readable file sizes (KB/MB) in the restore dialog.

  • Database Legacy strategy rule migration

    Old pricing strategy rules are automatically updated to the new format when you open the app for the first time after this update.

  • Database Added LegacyStrategyRulesMigrated application setting

    Added `LegacyStrategyRulesMigrated` to the `ApplicationSettingKey` enum to track whether the one-time pricing strategy rule migration has been completed for a given database. This prevents redundant migration attempts on subsequent application starts.

  • Database Demo database settings

    Added two new application settings to track demo database state: IsDemoDatabase (bool) and DemoDatabaseVendor (string). These are stamped after restoring a demo database and allow the application to identify demo environments and provide vendor-specific demo data.

  • Architecture Modernized report event handling for security compliance

    Replaced 104 lines of deprecated embedded report scripts with 134 lines of compiled C# event handlers across all label report classes. The barcode hiding logic (which suppresses barcodes when no product code exists) now executes through BeforePrint event handlers wired up in each report's constructor, eliminating the security vulnerability associated with dynamic script execution while maintaining identical behavior.

  • Architecture Deferred step sequence persistence

    Added ReplaceStepOrder method to PricingStrategyService that accepts a reordered list of steps and synchronizes it to the internal model collection. The ManagePricingStrategyV2ViewModel now tracks pending move changes with a local flag and calls SyncStepOrderToService before saving, ensuring the correct step order is persisted without triggering expensive recalculations during the move operation itself.

  • Architecture Simplify viewmodel initialization sequence

    Removed deferred initialization logic (`InitializeOnLoadAsync`) from the pricing strategy dialog viewmodel and restored immediate initialization in the constructor. The "instant open with deferred load" pattern proved problematic for ensuring all services were ready before user interaction, so initialization now completes fully before the dialog is shown.

  • Architecture InstructionSet-based condition editing

    Implements safe condition editing by working through the InstructionSet architecture: parse Instructions to InstructionSet, call StrategyCondition.DeleteCondition(value) to remove the value, rebuild rule text via GetRuleText(), update model.Instructions, and rebuild display conditions. This approach ensures dirty detection and save/discard flows work automatically without modification.

  • Architecture Enhanced view model extensibility

    Made the IsBusy and BusyMessage properties virtual in ManagePricingStrategyV2ViewModel, allowing derived classes to override busy state behavior if needed for specialized pricing strategy implementations.

  • Architecture Parsing and grouping optimization

    SKU exceptions are now parsed once upfront into typed batch rows (action type, numeric value, rounding scheme) and grouped by their settings before database execution. This eliminates redundant parsing and allows the database to handle all SKUs with identical pricing rules in a single batch operation.

  • Architecture Per-combo SQL execution for SKU exception batches

    Split the single monolithic SQL batch operation into separate calls for each unique (ActionType, RoundingScheme) combination. Each call creates its own temporary table, processes only that combination's SKUs, and reports completion before moving to the next. This architectural change enables the UI progress updates while maintaining the performance benefits of batch processing (still ~1,665 individual SQL calls reduced to 7 combo calls, completing in under a minute for large exception sets).

  • Architecture Improved SKU exception batch grouping logic

    Modified the batch processing grouping key to use the raw ACTIONADDSUBTRACT value instead of the computed SQL modifier. This ensures that different POIN operations (like ADDPOIN3 vs ADDPOIN5 or SUBPOIN3 vs SUBPOIN6) are processed in separate batches with their distinct point shift values intact, while still allowing other modifiers like ADDDOLL or ADDPERC to batch efficiently.

  • Architecture Separated increment calculation from rounding table generation

    Moved increment rounding from the precomputed RoundingSchemeDetail table into a separate calculation step (RoundingEngine.ApplyIncrement). The table now stores only right/left/rollback/range rounding data, while increment rounding is applied via formula both in the pricing run (SQL) and the editor "Check" preview (C#). This prevents the 10,000-row table limit from being exceeded when using fine-grained increments.

  • Architecture Improved rounding scheme validation logic

    The startup validation now uses both configuration hash AND generation version to determine whether a scheme needs regeneration, instead of checking configuration alone. This ensures that when a build changes the rounding math without changing the rules, existing schemes automatically detect they're stale and regenerate. Schemes that are already correct after a version bump get their checksum re-stamped to avoid unnecessary validation on subsequent startups.

  • Architecture Template implementation refactored

    Migrated icon column templates from static XAML DataTemplates to dynamically-generated ControlTemplates with proper binding context. This change restores the legacy implementation approach that correctly binds to grid cell values, removing non-functional XAML template definitions.

  • Architecture Restore synchronous initialization pattern

    Removed the `InitializeOnLoadAsync()` method and `InitialSavedSelectionName` property that supported deferred initialization. The constructor now performs all necessary setup synchronously, with the view model fully initialized before the dialog is shown to the user.

  • Architecture Code cleanup for grid update logic

    Simplified the SKU Detail save logic by working directly with MainTableViewModel instances instead of converting to/from the underlying mainTable entity model, reducing complexity and improving maintainability.

  • Architecture Refactored SKU exception SQL generation

    The BuildColumnExprSql method now properly brackets table names and incorporates the adjustedExpr fix from main, ensuring SQL is correctly generated when combining column references with add/subtract modifiers. This merge resolves conflicts between two concurrent improvements to the pricing strategy execution engine.

  • Architecture Organization-scoped backup data model updated

    The StrategyBackupListItemDto model now includes StoreNumber to support displaying backups across an organization rather than just for a single store. This enables multi-store organizations to view and restore backups from any location with appropriate permissions.

  • Architecture View routing logic in MainMMViewModel

    Modifies `ManagePricingStrategy()` and `OptionsEditAsync()` methods to check ApplicationSettingKey values and route to either legacy or V2 implementations. Adds cross-navigation support so toggling views within a dialog closes the current one and reopens the alternate version seamlessly.

  • Architecture Eliminated StrategyStepViewModel from V2 editor

    Removed the StrategyStepViewModel layer entirely from the V2 pricing strategy editor. Reference data (rounding schemes, min/max strategies, SKU types) is now loaded once and shared across all steps, while computed properties (step name editability, rounding label text, min/max instructions) are refreshed only when the focused step changes. This reduces memory usage and eliminates the need for model swapping logic.

  • Architecture View model infrastructure for V2 Strategy Manager

    Implemented ManagePricingStrategyV2ViewModel with DI registration, dialog service configuration, and SwitchToLegacy property to support seamless toggling between views. The legacy ManagePricingStrategyViewModel received a corresponding SwitchToNewView property and UseNewView command for bidirectional navigation.

  • Architecture Diagnostic results support skip state

    DiagnosticResult now includes Skipped and SkipReason properties, allowing modules to gracefully exit when prerequisites are missing (e.g., no file selected, no POS type configured) without reporting failures. A new DiagnosticResult.Skip factory method simplifies creating skip results.

  • Performance Strategy step reordering now instant

    Moving pricing strategy steps up or down in the list now happens instantly.

  • Documentation Added detailed issue investigation notes

    Created comprehensive documentation of the investigation process, including code flow analysis, root cause identification, and testing procedures for the Future Price click-to-set hang issue (MM-1157).

  • Infrastructure Completed abandoned FuturePrice save feature

    Implemented the logic that was previously started but left incomplete (evidenced by the commented-out line at 847). The feature now properly iterates through all dirty SKU view models and persists FuturePrice changes to the database.

  • Infrastructure Support documentation for timeout issue investigation

    Added internal documentation (MM-1183) analyzing a complex sync timeout issue at a large Ace Hardware customer where Level 1 and Level 2 pricing failed to update after sync due to incorrect timeout parameter usage in database queries affecting 324,000+ SKU tables.

  • Infrastructure Enhanced diagnostic logging for pricing operations

    Added detailed logging for pricing calculations to help identify and resolve pricing discrepancies more quickly. This diagnostic information will aid in troubleshooting when users report unexpected margin or markup values.

  • Infrastructure Strategy backup upload tracking

    Added two new application settings to track the timestamp and content hash of the last successful cloud strategy upload. These values enable the throttling logic to determine whether a new upload is necessary.

  • Infrastructure Documentation index updated with fixed price keywords

    Updated search keywords and content excerpts in the documentation index to include "fixed retail price," "flat retail price," and "fixed price" terms, making it easier to discover this pricing option through search.

  • Infrastructure Improved backup performance for large datasets

    Changed BackupService to use JsonTextWriter with FileStream instead of JsonConvert.SerializeObject, keeping memory usage proportional to a single write buffer rather than the full backup file size. This particularly benefits stores with extensive pricing strategy data.

  • Infrastructure Rounding table integrity verification

    Added a one-time database verification step that regenerates every custom rounding scheme's pricing table and compares it against the stored version, logging whether each scheme is identical or has differences. This regression check confirms that recent rounding engine improvements (which moved increment rounding from precomputed tables to runtime calculation) did not inadvertently alter any existing non-increment pricing schemes. The verification runs once per database and logs results for diagnostics.

  • Infrastructure Fast-path validation now respects generation version

    Updated the rounding scheme integrity check to bypass the "fast path" (skipping validation when configuration is unchanged) if the generation version is outdated. This ensures schemes regenerate after a math fix even when their rules are identical, then get re-stamped with the current version so future startups can safely use the fast path again.

  • Infrastructure Added test coverage for lock icon mapping

    Added 14 new tests that verify each exception type produces the correct lock character, ensuring the batch path matches the behavior of the original per-SKU processing. Tests specifically prevent the system from accidentally using markers reserved for other features like Custom Groups.

  • Infrastructure Added lock icon mapping tests

    Created comprehensive test coverage pinning the correct lock character for each exception action type (MARGIN→M, SETPRICE→R, COSTBREAK→C, RETAIL/LEVEL→D). These tests guard against silent mislabeling that would stamp thousands of SKUs with plausible-but-wrong markers, and verify case-insensitivity and proper precedence rules (e.g., COSTBREAK must not fall through to the generic 'D' default).

  • Infrastructure Improved application settings database updates

    Replaced the UPDATE/INSERT pattern with a single MERGE statement for updating application settings in the database. This eliminates race conditions and ensures settings are always saved correctly whether they already exist or need to be created.

  • Infrastructure POS system import documentation

    Added comprehensive documentation for 22 POS systems covering import file formats, field mappings, pipeline details, and troubleshooting tips. Documentation includes detailed guides for RockSolid, RockSolid Max, Transact, Bistrack (5 variants), Catalyst, Epicor FTP, Epicor MySQL Compass, Falcon, Spruce, Paladin, MI9, ECS, Prosperity, and 10 additional systems. Each guide includes file format specifications, field-to-column mappings, import workflow explanations, and common questions.

  • Infrastructure Improved diagnostic logging for strategy loading
  • Performance Strategy Manager grid rendering optimized

    The Pricing Strategy Manager window now opens much faster and shows a progress message while loading your strategy steps.

  • Infrastructure Performance diagnostics added

    Added stopwatch timing and detailed logging throughout the strategy loading pipeline to measure database query times, model building, caching, and UI updates. This instrumentation will help identify bottlenecks in future performance investigations.

  • Infrastructure Enhanced save verification logging

    Added diagnostic logging that captures pricing step order at three key points: initial load, before save, and after save completion. Each log entry includes step sequence, name, rounding setting, and active status, enabling developers to verify that step ordering is preserved correctly through the save operation.

  • Infrastructure Improve MySQL connection logging type safety

    Added explicit string casting to MySQL server identity logging to improve type safety in diagnostic output.

  • Infrastructure Strategy backup upload now returns server timestamp

    The cloud backup upload now returns and stores the server-assigned backup timestamp instead of using the local system time, ensuring consistent backup history tracking across different time zones and system clock variations.

  • Infrastructure Comprehensive regression tests for rollback rounding

    Added thorough test coverage for the NEW WILMES rounding scheme including verification that .98/.99 prices stay in their proper groups, round-trip invariant validation between the table generator and direct rounding engine, and parser flag tests. Updated the legacy reference engine to mirror the fix so fleet validation continues to isolate only intentional increment-scheme differences. All 43 rounding tests pass.

  • Infrastructure Added comprehensive test coverage for rollback rounding

    Added test cases covering the "NEW WILMES" rounding scheme scenario and validating that rollback schemes generate correct pricing bands and maintain round-trip consistency between generated tables and direct price calculations.

  • Infrastructure Added regeneration gate tests

    New RoundingSchemeRegenerationGateTests lock in the version-gate behavior to prevent future math fixes from silently leaving customers on stale pricing bands. Tests verify that freshly stamped checksums skip regeneration, stale generation versions force regeneration even with unchanged config, and the gate properly handles missing checksums or changed configurations.

  • Infrastructure Test coverage for regeneration gating

    Added comprehensive unit tests that verify the generation-version gate works correctly: fresh schemes skip regeneration, schemes from prior builds with unchanged config are forced to regenerate, and the gate properly handles missing checksums or changed configurations. These tests lock in the behavior to prevent future math fixes from silently leaving customers with stale calculations.

  • Infrastructure Safety checks at multiple update stages

    The deferral logic now guards three distinct phases: the initial hourly auto-update check (skips the entire tick), the pre-download phase (for interactive updates), and post-download as a safety net if an operation started during the download. This multi-layered approach ensures no restart path can interrupt user work, and flags are cleared on application startup to prevent stale state from blocking legitimate updates.

  • Infrastructure UpdateRepairService for last-resort installer download

    When you choose "Download and Install Now," Margin Master downloads the installer, closes the background service that might be locking the folder, and lets you confirm before shutting down and running the installer.

  • Infrastructure SimpleMapper optimization

    Removed unused delegate creation code in SimpleMapper that was creating unnecessary overhead during property mapping operations.

  • Infrastructure Performance monitoring added

    Added detailed timing logs throughout the strategy loading pipeline to track database queries, model building, and UI updates. This enables faster diagnosis of any future performance issues.

  • Infrastructure Removed diagnostic timing logs

    Cleaned up temporary diagnostic logging and stopwatch timing code that was added during the performance investigation. This includes removal of timing logs from PricingStrategyService initialization, strategy loading, and dialog opening sequences.

  • Infrastructure Removed 600+ lines of dead rounding scheme code

    Eliminated obsolete code that attempted to backup and restore rounding schemes as full entity objects with separate rule tables. This code was never functional as rounding schemes have always been stored in GlobalFileConfig format in Margin Master.

  • Infrastructure Remove Azure Blob Storage dependencies for strategy backups

    Removed AzureBlobService calls from BackupService.SendStrategyToCloudAsync. BackupDataToCloudResult.URL field replaced with BackupDate. Cloud backup now returns server-assigned backup timestamp instead of blob URL. Local file backups continue to work as before.

  • Infrastructure Proper ViewModel lifecycle and resource cleanup

    Implemented IDocumentContent for dialog lifecycle management and IDisposable for proper event cleanup. The ViewModel now subscribes to service events (ActiveStrategyChanging, ActiveStrategyChanged, StrategyListChanged, StepsChanged, RefreshDisplayNeeded) during initialization and unsubscribes on disposal. The StrategyStepViewModel now also unsubscribes from model PropertyChanged events in its Dispose method and when swapping models, preventing memory leaks from abandoned event handlers.

  • Infrastructure Four PowerShell scripts bundled with DiagnosticTool

    Install-SQLExpress.ps1, Upgrade-SQLExpress.ps1, Install-SSMS.ps1, and the new Upgrade-SSMS.ps1 are now copied to the DiagnosticTool output directory at build time, allowing the AI tools to execute them without requiring the Scripts folder to be present on the target machine.

  • Code Quality Removed unused rounding definition property

    Removed the dead IncrementRounding_SelectedIndex property from RoundingDefinition, which was never read or used by the application.

  • Infrastructure SQL Developer upgrade script removed

    Removed the Upgrade-SQLDeveloper.ps1 script and its documentation. This script was designed for upgrading SQL Server Developer edition instances to SQL Server 2025, but Developer edition is rarely used in production hardware store environments. The equivalent Upgrade-SQLExpress.ps1 script remains available for the more common Express edition deployments.

  • Infrastructure Removed obsolete SQL Developer upgrade script

    Removed the "Upgrade SQL Developer" script from the Installation Scripts catalog, embedded resources, blob storage references, and documentation. This script was redundant as most Margin Master deployments use SQL Express, and the SQL Developer upgrade workflow is rarely needed in retail hardware store environments.

  • Infrastructure Diagnostic session logging and cloud reporting

    Implemented DiagnosticSessionLogger and DiagnosticApiClient to track diagnostic sessions, log module execution results, and optionally upload session data to marginmaster.com for support analysis. Each session is assigned a unique ID and includes machine identity, store number, vendor, and per-module issue/resolution tracking.

  • Infrastructure Store identity verification and token management

    Added StoreIdentityService to prompt for and verify store number/vendor against the cloud licensing API before running cloud-dependent modules. Implements token budget tracking for Claude API usage and displays remaining tokens in the status bar.

  • Infrastructure Code signing for MarginMasterDiagnostics.exe

    Extended the GitHub Actions publish workflow to sign MarginMasterDiagnostics.exe with the same certificate and metadata as MarginMaster.exe. The diagnostic tool is published into the same output directory and bundled in the Velopack installer package.

Imports & POS

  • New Feature Reset Point of Sale Data command

    If you need to start fresh with your POS data, you can now use Support Tools > Reset POS Data to completely clear your current POS information. After resetting, you'll need to re-import your POS data to see products in the main table again.

  • New Feature Falcon POS Excel import support

    Falcon stores can now import inventory directly from Excel spreadsheets. Place your Falcon export file (.xlsx) in the import folder and click Import Data — the system will read the file, show progress, and load all inventory into Margin Master.

  • New Feature Bulk SKU import from files

    Use Tools → Import File to select an Excel or text file containing SKUs. The system will automatically find matching catalog items and add them to your list.

  • New Feature Bulk SKU import from files

    Click Tools > Import File to upload an Excel or text file containing SKUs. The system will automatically find and add all matching catalog items to your list.

  • New Feature Bulk import from Excel and CSV files

    Use Tools > Import File to select an Excel or CSV file with SKUs. The system will automatically look up each SKU in your vendor's catalog and add matches to your list.

  • New Feature Bulk spreadsheet import for new products

    Place Excel files containing new product SKU numbers in C:\MarginMaster\NewProductImport and select "Import New Product Spreadsheets" from the Data menu. The system will validate each SKU, import the valid products, and create a log file showing what was imported and what couldn't be found.

  • New Feature Import New Product Spreadsheets menu option

    A new "Import New Product Spreadsheets" option appears in the Data menu. Place Excel files containing SKU lists in C:\MarginMaster\NewProductImport, click the menu option, and the system will automatically validate and import the products.

  • New Feature Ace zone display in Store Matchup

    The Store Matchup screen now shows which Ace pricing zone is assigned to each store.

  • New Feature BisTrack DIB6828 CSV format support

    Stores using the BisTrack DIB6828 export format can now import pricing data directly—the Import Manager automatically recognizes the format and processes it correctly.

  • New Feature INDecoded store character scanner
  • New Feature INDecoded store character scanner

    In the Settings > Connections tab, click "Scan INDecoded File" to automatically find all POS store codes in your Epicor file. A grid will appear showing each store code; enter the matching vendor store number for each one, then click "Save Store Mappings" to apply.

  • New Feature Automatic store reconciliation after MySQL Compass sync

    When you sync with Epicor/MySQL Compass, Margin Master will now tell you if new stores have been added or if existing stores are no longer found, helping you keep your store list up to date automatically.

  • New Feature Automatic Compass store discovery and reconciliation

    When you import data, the system now automatically adds any new stores it finds and alerts you about stores that are no longer in your POS system. New stores show "Needs Setup" and need a Vendor Store Number assigned before they'll be included in imports.

  • New Feature Scripts menu with Epicor store diagnostics

    You can now run diagnostic queries from the Scripts menu to troubleshoot store character issues in Epicor databases without writing SQL.

  • New Feature Shift-click store picker for selective POS imports

    When you need to refresh data for just a few stores instead of all of them, hold Shift when you click "Update Point of Sale Data." A window will appear where you can check the stores you want to update, then click Import.

  • New Feature Reset POS Data command

    You can now reset your Point of Sale data from the Tools menu if you need to clear everything and re-import from scratch. The system will ask you to confirm before deleting anything, and you'll need to re-import your POS data afterward.

  • New Feature Bulk SKU entry via paste

    Use Tools → Enter Bulk List to paste a comma-separated list of SKUs from your clipboard. The system will look them up and add any matches to your catalog item list.

  • New Feature Bulk SKU entry via paste

    Click Tools > Enter Bulk List to paste a list of SKUs from your clipboard or type them separated by commas or line breaks.

  • New Feature Bulk import from pasted SKU list

    Use Tools > Enter Bulk List to paste SKUs from emails, spreadsheets, or other sources. Separate SKUs with commas, spaces, or place one per line.

  • New Feature Re-import Epicor files without Eagle server connection

    When importing Epicor data, you'll now be asked if you want to re-import the last downloaded file instead of downloading fresh data from the Eagle server. This lets you refresh your pricing grid even when the Eagle server is offline.

  • New Feature Zone override capability

    You can now override the pricing zone for any Ace store by entering a different zone number in the "Zone Override" column.

  • New Feature BisTrack DIB6828 format support

    Stores using the DIB6828 export format from BisTrack can now import their data directly without manual conversion.

  • New Feature Streaming import mode for Epicor

    Turn on "Use Streaming Import" in Settings > Connections to reduce memory usage during Epicor imports, especially helpful for very large inventory files.

  • New Feature POS store number reassignment handling

    If you're removing a store because its POS number was reassigned to a different location, select "POS number reassigned" — this allows the new store with that number to import correctly without conflicts.

  • New Feature Vendor data freshness check before import

    Before importing store files, you'll now see a reminder to sync vendor data if it's more than a day old. Fresh vendor data ensures your pricing analysis and margins are calculated accurately.

  • New Feature Vendor data freshness prompt before import

    If your vendor catalog hasn't been updated recently, you'll see a prompt asking whether you want to sync it before importing store files. Syncing first ensures your pricing analysis uses the latest vendor cost and catalog information.

  • New Feature Unmapped Store Character Detection and Exclusion

    If the Epicor import finds store characters that aren't assigned to vendor store numbers, you'll get a notification listing them and can choose to automatically exclude them from future imports.

  • New Feature Unmapped store character detection and exclusion prompt

    If the INDecoded file contains stores you haven't mapped yet, you'll get a notification after import with the option to automatically exclude those unmapped stores from future imports, or you can assign store numbers to them in Options > Connections.

  • Improvement Fallback data source for import history display

    You can now see how many records exist for each store location even if the system hasn't tracked recent imports.

  • Improvement Data Aging displays per-store record counts from main tables

    You'll now see how many records each store has and when they were last updated, even if import history isn't tracked.

  • Improvement Session-based MySQL connection availability caching

    If your MySQL Compass server is unavailable, import operations will now complete much faster by skipping repeated connection attempts. To restore MySQL functionality, go to Tools > Options and use the Save & Test button.

  • Improvement BisTrack mainTable insert optimization

    BisTrack store imports now process inventory data more efficiently, reducing import time for large catalogs.

  • Improvement BisTrack bulk import with Sep library

    When importing multiple BisTrack store files, all files are now loaded together in one operation, making the import process much faster.

  • Improvement BisTrack bulk import performance optimization

    When importing multiple BisTrack CSV files, the system now uses Sep-based batch loading to combine all store files into a single staging table, performs data cleanup once instead of per-file, and creates a compound index on Store and SKU before processing. This significantly reduces import time when loading data for multiple store locations.

  • Improvement Simplified BisTrack batch import workflow

    Importing multiple BisTrack CSV files at once is now faster and more reliable.

  • Improvement BisTrack batch import engine rewrite

    Multi-store BisTrack imports are now much faster and more reliable.

  • Improvement Cross-file batching for faster BisTrack imports

    BisTrack data imports now complete much faster, especially when importing multiple files at once.

  • Improvement Optimized BisTrack preloaded import pipeline

    BisTrack imports for Do-It-Best stores now complete faster with less database overhead.

  • Improvement Automatic detection of store-specific New Product Form format

    When importing a New Product Form with a Yard # column, products will be added only to the store listed in the spreadsheet, not to all stores in your system.

  • Improvement Store-specific New Product Form detection

    The import process now recognizes when a New Product Form includes store identification (store number and name in the header). When detected, the system reads the store information and automatically assigns all imported products to that specific store location. This handles the updated BisTrack form format where store-specific forms include a "Yard #" column and shift the SKU column position.

  • Improvement SKU count column added to Epicor store scanner results

    When you scan an Epicor inventory file, you'll now see how many items each store code has. The stores with the most items appear first, which helps you match the codes to your actual store locations.

  • Improvement SKU count column added to store scanner grid

    The store mapping screen now shows how many products were found for each store code, making it easier to match codes to your actual store locations.

  • Improvement Epicor store mapping enabled by default

    When importing from Epicor, store numbers from your POS system will automatically be converted to match the store numbers used in vendor catalogs like Ace Hardware, making pricing comparisons more accurate without additional setup.

  • Improvement Epicor store mapping default changed to enabled

    Store number mapping for Epicor systems is now on by default. If your store doesn't use different store numbers between Epicor and Margin Master, you can turn this off in the Options settings.

  • Improvement File Transfer Progress Display

    File download progress now shows "Transferred 45.3 MB..." instead of large byte numbers.

  • Improvement Enhanced progress display during Epicor file download and processing

    During Epicor sync, you'll now see clearer progress messages showing file sizes in MB/GB and which store is being processed out of how many total stores.

  • Improvement Enhanced Epicor store character display

    When setting up Epicor store characters, you'll now see the actual symbol for extended characters alongside the numeric code, making it easier to identify which character you're working with.

  • Improvement Auto-create Store Manager Info entries for new Epicor stores

    When new stores are found during an Epicor import, they're automatically added to your Store Manager Info. You'll see a message listing the new stores and asking you to assign vendor store numbers in Options > Connections.

  • Improvement Automatic store detection and registration for Epicor imports

    When new store locations appear in your Epicor data, Margin Master will now add them to your store list automatically and remind you to assign vendor store numbers in the Connections settings.

  • Improvement Context-aware INDecoded file selection

    When you rescan Epicor stores, the system will now show you the date of your last downloaded file and ask whether you want to use it or get a fresh copy from the server. If the server isn't available, you can still use the existing file.

  • Improvement Automatic Epicor store ordinal migration at startup

    If you use Epicor and have binary store data, the app now automatically converts it to the correct format when it starts, preventing potential store mapping issues during imports.

  • Improvement Store deletion reason dialog for Epicor Eagle stores

    When you try to remove an Epicor store that still appears in your POS system, you'll see a dialog asking why you're removing it. Choose the option that best describes your situation before confirming the deletion.

  • Improvement Enhanced store number display for Epicor systems

    Extended the POS-to-Vendor store number mapping display to work with all Epicor store configurations. Previously, this feature only worked for stores using MySQL/Compass imports, but now applies to all Epicor stores since they all use the Store Manager for store number mapping.

  • Improvement Automatic retry for transient network errors during POS connection tests

    When testing your POS connection in Settings, brief network interruptions will no longer cause the test to fail immediately. The system will now automatically retry a few times before showing an error, making connection testing more reliable.

  • Improvement Automatic retry for transient connection failures

    When testing your POS connection in Settings, the test will now automatically retry if it hits a temporary network issue, making the test more reliable.

  • Improvement Chunked queries for large datasets

    The reconciliation process fetches remote SKUs in batches of 10,000 records to handle stores with large inventories efficiently, with progress logged for each batch. Orphaned records are deleted in batches of 1,000 to maintain database performance.

  • Improvement Added timeout protection for all POS bulk imports

    Import operations that would previously freeze the application will now time out after 30 minutes with a clear error message.

  • Improvement Better logging for bulk import diagnostics

    Added detailed logging throughout the bulk import process, including batch progress, FileHelpers parsing errors, timing information, and completion status. This will help identify and diagnose import issues more quickly in the future.

  • Improvement MySQL SKU reconciliation moved to background with weekly throttle

    MySQL Compass imports now complete much faster because SKU cleanup runs in the background instead of during the import process.

  • Improvement POS table fallback for stores without import history

    Stores that imported POS data before import tracking was added will now see when their POS data was last updated, instead of seeing no information.

  • Improvement POS data fallback when import history unavailable

    The Data Aging screen now shows POS data information even if detailed import history is missing.

  • Improvement Enhanced RockSolid import error handling

    Improved error messages for common RockSolid import failures including missing OLEDB drivers, file not found, locked files, and import timeouts. Each error now provides specific guidance on resolution.

  • Improvement Import record count now calculated for RockSolid

    The Data Aging View now shows exactly how many items were imported from RockSolid each time.

  • Improvement Faster pricing strategy grid loading

    The pricing strategy grid now loads noticeably faster when switching between strategies or opening the pricing screen.

  • Improvement Faster Excel file processing with progress tracking

    Excel imports now show detailed progress (rows imported, percentage complete) and run faster, especially for large files with tens of thousands of items.

  • Improvement Special POS system documentation

    Advanced import features like Bistrack DirectConnect (live database queries) and Epicor incremental sync are now fully documented with setup instructions.

  • Improvement Chunked bulk import with automatic retry for Excel files

    Large Excel imports are now more reliable and will continue even if temporary database issues occur.

  • Improvement Reduced MySQL connection timeout

    When MySQL Compass is unavailable, the system will now detect this within 10 seconds instead of waiting up to 5 minutes.

  • Improvement Automatic settings loading for newly visible tabs

    When POS tabs become visible after a POS type change, their settings are automatically loaded in the background, ensuring the tabs are ready to use immediately without requiring manual navigation or refresh.

  • Improvement Automatic settings cleanup on POS system change

    If you're viewing a tab that becomes hidden when you switch POS systems, the screen automatically moves you to a visible tab.

  • Improvement Switched to asynchronous database connection for Spruce imports

    The program will no longer freeze while connecting to the Spruce server—you can still interact with the application during the connection process.

  • Improvement Added detection and warnings for incomplete MySQL imports

    If an import doesn't bring in all your products, the system now alerts support staff with specific details about what went wrong and how to fix it.

  • Improvement Reduced unnecessary error logging for schema variations

    Changed error handling to log a single warning instead of repeated errors when the stext_ext_1 column is unavailable, reducing telemetry noise and making genuine errors easier to identify.

  • Improvement Reduced error logging severity for auto-update checks

    Auto-update check failures (due to SQL connection issues or network problems) are now logged as warnings instead of errors. Since the application continues working normally when update checks fail, these should not be reported as critical errors in telemetry, especially for stores with Named Pipes or other network configuration issues.

  • Improvement Skip redundant mainTable rebuild for BisTrack

    The import process now detects when BisTrack's InsertIntoMainTable.sql has already built the mainTable with pre-aggregated vendor data during import, and skips the redundant DROP+rebuild step in Process Store Data. This eliminates duplicate work and further speeds up the BisTrack import workflow.

  • Improvement Skip redundant mainTable rebuild for BisTrack

    For BisTrack systems using the DIB1040 layout, the import process now detects when the vendor catalog has already been merged into the mainTable during the SQL insert phase and skips the redundant Store-to-mainTable rebuild step, eliminating duplicate processing and improving import speed.

  • Improvement Manual catalog entries now expire after 7 days

    Manual catalog entries that don't appear in your import files within 7 days are automatically cleaned up to keep your data current.

  • Improvement Manual catalog items now expire after 7 days instead of immediately

    Manual catalog items will remain in the system for 7 days, giving you more time before they're automatically removed if they don't appear in your official store data.

  • Improvement Bulk insert operations replace row-by-row processing

    CSV data loading now uses Z.BulkOperations library with pre-compiled column setters instead of building DataTable objects with per-row dictionary lookups. Column mappings are computed once at the start of each file rather than looking up each cell individually, reducing CPU overhead during large imports.

  • Improvement Single-pass cleanup for BisTrack data

    Moved data normalization (quote stripping, store number formatting, deduplication) from per-file processing to a single cleanup operation after all files are loaded. This reduces the number of database operations from N operations (one per file) to a single batch operation, improving performance and consistency.

  • Improvement Optimized batch parameters for large BisTrack datasets

    Set batch flush threshold to 50,000 rows with 10,000-row bulk insert batches and extended timeout to 1 hour, specifically tuned for handling large multi-store BisTrack imports efficiently while maintaining responsive progress feedback.

  • Improvement Reduced import delays and improved UI responsiveness

    The application will remain more responsive during BisTrack imports, and imports will complete several seconds faster.

  • Improvement Reduced import thread delay

    Reduced the post-bulk-upload thread delay from 500ms to 50ms, providing a minor additional performance improvement during the import process without affecting stability.

  • Improvement Added format validation for BisTrack imports

    The system now warns you immediately if a BisTrack file is in an unexpected format, instead of appearing to complete successfully while importing no data.

  • Improvement Enhanced BisTrack import progress messages

    The import progress window now shows more detailed messages about what stage each store is in during import, making it easier to track progress.

  • Improvement Enhanced BisTrack store build status messages

    Progress messages during BisTrack imports now clearly show which step is running and how many rows are being processed for each store.

  • Improvement Enhanced import logging for store assignments

    Import logs now display the store number and name when processing store-specific spreadsheets, making it easier to verify which location's inventory is being updated during the import process.

  • Improvement Optimized duplicate removal during BisTrack cleanup

    Updated the deduplication logic to work directly with cleaned store and SKU fields rather than re-trimming them during duplicate detection, allowing the database to use indexes for faster processing.

  • Improvement Extended command timeouts as safety margin

    Increased command timeout limits during critical import operations: store rebuild timeout raised from 120 to 600 seconds, and the main table insert during RockSolid import raised from 30 to 300 seconds. These provide additional headroom for large datasets or constrained hardware environments, though the optimized vendor data join should keep actual execution times well below these limits.

  • Improvement Streaming import option for Epicor
  • Improvement Epicor import now works with existing files when FTP is unavailable

    You can now re-run Epicor imports using previously downloaded data files without needing to configure FTP settings.

  • Improvement FTP credentials no longer required for same-day Epicor reimports

    You can now reimport today's Epicor data without needing FTP credentials configured, as long as the file was already downloaded once today.

  • Improvement Store characters sorted by size for easier identification

    Stores are now listed with the largest ones first, so your main locations appear at the top of the list.

  • Improvement Enhanced MySQL connection diagnostics

    Connection testing now logs MySQL server identity information (hostname, version, current database) and attempts to list available databases when permission allows. This additional logging helps diagnose cases where the configured MySQL server IP routes to an unexpected Eagle instance or database.

  • Improvement Enhanced MySQL connection diagnostics

    Added diagnostic logging during MySQL connection testing to capture hostname, server version, current database name, and available databases. This information helps troubleshoot connection issues and verify the correct database is being accessed.

  • Improvement Epicor Import Progress Messages

    During Epicor import, you'll see exactly how much of the file has been processed with megabyte counts and percentages.

  • Improvement Reset logic now prevents duplicate processing of dropped tables

    The reset process now drops per-store tables first, then queries the database again to truncate remaining POS-specific tables. This ensures already-removed tables aren't processed twice and improves the efficiency of the reset operation.

  • Improvement Enhanced table cleanup logic

    The reset operation now uses a two-phase approach: first dropping per-store main tables, then truncating remaining POS-specific tables. This ensures dropped tables aren't visited twice and provides cleaner database state for fresh imports.

  • Improvement Dynamic human-readable descriptions for excluded stores

    When you enter store exclusions, the software now shows you exactly which stores you're excluding with their names and codes instead of just showing raw symbols.

  • Improvement Real-time display of excluded stores with readable labels

    When you enter stores to exclude, you'll now see a description below showing exactly which stores are being excluded in plain language.

  • Improvement Progress updates now visible during Epicor data processing

    The import progress screen now shows real-time status updates instead of appearing stuck.

  • Improvement POS reset logging now shows table cleanup count

    When using the POS data reset tool, you'll now see confirmation of how many tables were removed, helping you verify the cleanup worked correctly.

  • Improvement POS data reset now logs table counts

    When resetting POS data through Support Tools, the system now counts and logs how many per-store tables are being dropped. This diagnostic information helps troubleshoot data reset operations and confirm the expected tables were removed.

  • Improvement Enhanced progress feedback during MySQL Compass import

    The import progress window now displays which specific store's extended fields are being updated during post-import processing, making it easier to track progress and identify if a particular store is experiencing delays.

  • Improvement Enhanced import progress feedback for MySQL Compass

    The import screen now shows more detailed progress information, including which store is being processed during extended field updates.

  • Improvement Added offline and error handling for Epicor downloads

    Added three new service methods: FindMostRecentINDecodedFilePath (locates the latest cached file), CanConnectToFtpAsync (tests server connectivity), and DownloadAndDecodeINFileAsync (downloads and decodes the IN file without importing). These enable the Store Manager to make intelligent decisions about file availability and server connectivity before prompting the user.

  • Improvement Added FTP connectivity check before download attempts

    The Epicor FTP extractor service now tests server connectivity before attempting downloads. This allows the Store Manager to provide helpful messages when the server is unreachable and offer appropriate alternatives (use cached file or wait until connected).

  • Improvement Store Manager auto-heals unassigned store rows

    When you open the Store Manager and scan for Epicor stores, any previously unassigned stores will now be automatically mapped to the correct vendor store numbers.

  • Improvement Enhanced store discovery with automatic mapping

    When you scan for stores in the Store Manager, any new store numbers that match previously mapped stores will be assigned automatically.

  • Improvement Ongoing supplemental migration on startup

    The Store Manager will now automatically detect and add any missing store configurations each time you open Margin Master.

  • Improvement Store Manager initialization includes format migration

    The Store Manager screen now shows only active, correctly-formatted store mappings.

  • Improvement Enhanced store mapping supplement process

    Improved the GlobalFileConfig supplement routine to match stores by their position in the POS system (ordinal) rather than only by vendor store number. When a store row exists without a vendor store number assigned, the supplement process now updates that row with mapping data instead of creating a duplicate entry. This ensures RSC codes and Ace zone overrides are properly applied to discovered stores.

  • Improvement Store Manager now auto-saves on close

    Your store configuration changes will now save automatically when you close the Store Manager window, so you won't lose any edits.

  • Improvement Epicor Eagle stores protected from premature deletion

    If you try to delete an Epicor Eagle store that still exists in your POS system, Margin Master will mark it as Excluded instead and explain that the store would just come back on the next import.

  • Improvement Clearer messaging for Epicor store deletion attempts

    Warning messages when managing Epicor stores now clearly tell you which part of your Epicor system the store comes from.

  • Improvement Debugger mode protection for MySQL imports

    Added a safety check that prevents MySQL imports from running while the application is attached to a debugger, avoiding potential connection conflicts during development troubleshooting.

  • Improvement Smart handling based on deletion reason

    If you say a store number was reassigned to a different location, Margin Master will disconnect the old store from that POS number so the correct store can use it.

  • Improvement Added automatic single-store mapping for Epicor MySQL

    Single-store Epicor MySQL setups now configure themselves automatically without needing manual store matching.

  • Improvement Single-store automatic mapping and self-healing

    Single-store locations now require no manual store setup — the system automatically connects your Margin Master store to the correct Epicor MySQL store.

  • Improvement Enhanced CSV parsing for quoted fields with special characters

    The new CSV import logic uses RFC-4180 compliant parsing to correctly handle product descriptions containing commas, quotes, and other special characters (e.g., descriptions like "1,751" or "5/8" BANDING"). This prevents data corruption and ensures fields are parsed accurately even when they contain delimiter characters within quoted values.

  • Improvement Copy to Clipboard for query results

    Click "Copy to Clipboard" to copy query results as tab-separated text that can be pasted into Excel or emails.

  • Improvement Store number display/sort options now accessible to Compass users

    Compass users can now see and adjust how store numbers are displayed and sorted in store selection lists—these settings were previously hidden.

  • Improvement Enforce POS-to-vendor store number mapping for all Epicor stores

    Store number mapping is now always on—every POS store must have a Vendor Store # assigned in Store Manager for data import to work.

  • Improvement Store number display options now always visible for Epicor

    Store number display and sorting preferences are now always available in Epicor settings, making it easier to configure how store numbers appear in selection lists.

  • Improvement Store number display settings now always visible for Epicor users

    Settings for how store numbers are displayed and sorted are now always visible when using Epicor.

  • Improvement Enhanced yard detection in import spreadsheets

    The new-product import now looks for an explicit "Yard" or "Store #" column header anywhere in the spreadsheet, reading the yard value from either the metadata row or data rows. This is more robust than the previous fixed-cell layout and adapts if the SKU column position changes.

  • Improvement Malformed rows now logged as warnings with line numbers

    When rows are skipped during import, you'll see warning messages showing exactly which line numbers had problems and why.

  • Improvement Better error handling for import file validation

    The ImportFileIsValid method in RSImportFileHelperService now distinguishes between files that should be ignored (wrong format for the configured POS system) versus genuine fatal errors (locked files, I/O errors, type load failures). A sticky exception is no longer set when encountering files with mismatched columns or headers, preventing one bad file from poisoning the entire import pipeline.

  • Improvement Clearer status messages when non-POS files are skipped

    When a file is skipped because it doesn't match the expected POS format, the import status log now displays "No valid records found in file — ignoring (wrong format for this POS)" to clarify why the file was not processed.

  • Improvement Enhanced bulk import performance and diagnostics

    Replaced List-based duplicate checking with HashSet for O(1) lookups instead of O(n), significantly improving performance on large files. Added comprehensive progress logging including batch write counts, error summaries, and elapsed time tracking. Compiled type definitions are now preferred over Roslyn-compiled .map types to ensure field converters work correctly.

  • Improvement Expanded vendor data reset coverage

    The "Reset Vendor Data" command now clears all modern cloud sync tables for Ace Hardware (AceCatalogRecords, AceZoneRecords, AcePlanogramRecords, AceMappPricingRecords, etc.) and Do-It-Best (DIBCatalogRecords, DIBPriceLevelRoundingDetails, etc.) in addition to legacy tables. This ensures a complete reset of all vendor data and forces a full re-sync on the next cloud update.

  • Improvement Enhanced vendor data reset with modern sync tables

    The existing "Reset Vendor Data" feature has been expanded to include all modern cloud sync tables for Ace Hardware, Emery Jensen, and Do-It-Best, including catalog records, zone records, planogram records, taxonomy records, and pricing records. The feature now clears both legacy and modern sync metadata tables, ensuring a complete reset that forces a full re-sync on the next vendor data update.

  • Improvement Simplified demo database backup directory handling

    Streamlined the demo mode cloud database update process to use the configured backup directory directly instead of querying the SQL Server for its backup path, improving reliability and consistency with application settings.

  • Improvement Field mapping reference tables

    Each POS guide includes complete field mapping tables showing which POS fields map to which Margin Master columns, including max field lengths, data converters applied (MoneyConverter, HistoryConverter, TrimLeadingZeros), special handling (Ace Direct SKU suffix removal, zone pricing, MAP pricing), and notes on unique behaviors like Catalyst's comma-to-hyphen description cleaning or CounterWorks' margin percentage history fields.

  • Improvement Reduced per-store query timeout from 10 minutes to 2 minutes

    Each store's data will now timeout after 2 minutes instead of 10 minutes if the server isn't responding, making failed imports complete faster.

  • Improvement Enhanced retry logic with extended timeouts

    Replaced the standard database execution method with an enhanced version that includes automatic retry logic (up to 3 attempts), exponential backoff between retries, and extended command timeout (120 seconds, doubling on each retry up to 480 seconds). This ensures large imports can complete successfully even on slower hardware like SQL Server Express.

  • Improvement Better FTP connection error message

    If the Eagle server connection fails, you'll now see a clearer error message that directs you to the correct settings location.

  • Improvement Automated file management and logging

    Processed files are automatically organized into an "Imported" folder so you can track what's been imported, and a log file shows exactly what happened during each import.

  • Improvement Enhanced import logging for troubleshooting

    Reality check validation messages now clearly distinguish between "pre-sync" and "post-sync" checks, and include detailed statistics (row counts, percentages, and thresholds) to help diagnose import issues. The pre-sync threshold was adjusted from 80% to 50% to reduce false positives while still catching seriously incomplete data.

  • Improvement Enhanced logging for SKU Level Exceptions processing

    The strategy execution report now shows more detailed information about SKU Level Exceptions processing, including why exceptions were skipped or how many items were affected.

  • Improvement Reduced unnecessary database error retries

    The system now recognizes when database tables don't exist (SQL error 208) and immediately reports the issue instead of wasting time retrying the operation. Also added special handling for view-related migration errors (SQL error 4909).

  • Improvement Removed unnecessary delays during catalog import

    Catalog imports now complete more quickly without unnecessary pauses.

  • Improvement Removed unnecessary delays during bulk import

    Removed artificial 1-2 second delays after bulk insert operations that were slowing down the import process without providing user benefit, now that proper progress messages are displayed instead.

  • Improvement Store number tracking for batch imports

    The import service now maintains a map of which store each CSV file belongs to during batch processing, preserving store-level visibility throughout the import workflow. Store numbers are normalized to match the cleanup script's format (trimming quotes and leading zeros).

  • Improvement Optimized column mapping with pre-computed setters

    Replaced per-row dictionary lookups with pre-computed column setter actions, eliminating repetitive header-to-column resolution during bulk data loading. This micro-optimization reduces CPU overhead during high-volume CSV parsing.

  • Improvement Reduced memory usage during large BisTrack imports

    Implemented a 50,000-row buffer that flushes periodically during import, keeping memory usage bounded even when importing very large datasets across multiple files. This prevents memory spikes while maintaining fast import speeds.

  • Improvement Optimized BisTrack multi-file batch processing

    Importing multiple BisTrack CSV files is now significantly faster—all files are loaded in one batch before store tables are created, reducing processing time and preventing duplicate cleanup operations.

  • Improvement Added handler completion tracking for BisTrack imports

    Enhanced the Import Manager to track whether the BisTrack preload handler has already completed all store builds on its own service instance. When the handler completes successfully, individual files are now marked as imported and renamed without running additional SQL processing, improving efficiency and preventing conflicts.

  • Improvement Support for legacy raw-character store identifiers

    The store matching system now handles both modern ordinal format ("135") and legacy raw-character format ("W") for stored values, ensuring backward compatibility with older data while maintaining correct behavior across different MySQL character set configurations.

  • Improvement Enhanced Epicor Import Manager integration messaging

    If you're using Epicor with MySQL Import Manager, the settings screen now clearly explains that you need to set excluded stores in the Import Manager instead.

  • Improvement Enhanced STOREMATCHUP value format handling

    Updated the STOREMATCHUP migration logic to use PosStoreCharHelper.OrdinalToChar() for converting POS store identifiers, allowing it to correctly handle both ordinal format (e.g., "87") and legacy character format (e.g., "W") stored in GlobalFileConfig.Value. This ensures robust parsing regardless of how the original configuration was stored.

  • Improvement Enhanced store character conversion logic

    Introduced PosStoreCharHelper.OrdinalToChar to handle conversion of both numeric ordinals (e.g., "87") and legacy character values (e.g., "W") when processing STOREMATCHUP entries, making migration more robust across different configuration formats.

  • Improvement Renamed supplement method to reflect upsert behavior

    Renamed InsertMissingStorematchupEntriesAsync to UpsertMissingStorematchupEntriesAsync to accurately reflect that it now both inserts new entries and updates existing ones, rather than only inserting.

  • Improvement Active stores summary now excludes "Not Found" stores

    The store configuration summary now gives a more accurate count by excluding stores that no longer exist in your POS system.

  • Improvement Debugger mode protection

    Added a guard to prevent MySQL imports from running while the debugger is attached, matching the behavior of the standard Compass import path and preventing unexpected runtime behavior during development troubleshooting.

  • Improvement Automatic recovery from failed imports

    If an import fails to retrieve all products, the system will automatically try again with a full download before showing an error.

  • Improvement Store number normalization in Data Aging screen

    Store numbers shown in Data Aging now match the store numbers you use everywhere else in Margin Master.

  • Improvement Progress callback mechanism for index rebuild operations

    Added an optional progress callback parameter to RebuildAllManagedIndexesAsync that reports per-table progress, wired to the splash screen at the post-import call site. This is an additive change with no modification to the underlying rebuild logic or SQL.

  • Improvement Enhanced post-import feedback

    The loading screen now warns you when an operation might take several minutes, so you know to be patient.

  • Improvement Reduced telemetry noise from recoverable conditions

    Eliminated excessive error logging (62+ occurrences affecting Do-It-Best stores) from two scenarios that are recoverable and do not represent actual failures. These conditions now handle gracefully with appropriate warnings or auto-remediation.

  • Improvement Import file selection now prefers most recent export

    The system will always use your most recent export file, even if older files are still in the import folder.

  • Improvement Store matching logic improved for partial imports

    Enhanced the store-skipping logic to correctly identify stores by vendor store number (e.g., DIB numeric codes like "1818") in addition to single-character Epicor store identifiers, ensuring accurate subset filtering during partial imports.

  • Improvement Store mapping now mandatory for all Epicor users

    All Epicor stores now use the Store Manager to map POS store numbers to vendor store numbers—this is no longer optional.

  • Improvement Extended command timeout for catalog cleanup operations

    Increased the command timeout to 600 seconds for discontinued item cleanup queries to prevent timeouts when processing very large manual catalog item sets, particularly during concurrent import scenarios on SQL Express.

  • Improvement Added diagnostic logging throughout MySQL import pipeline

    Added logging at key steps: eligible store count, per-store update counts, date filters applied, Compass_IN row count after import, and warnings when zero SKUs are found. Also populated empty catch blocks with error logging. This makes it easier to diagnose silent import failures.

  • Improvement Enhanced MySQL Compass import logging

    Added comprehensive diagnostic logging throughout the MySQL Compass import process, including: total store count vs. eligible stores, per-store update counts with date filters, final Compass_IN row counts, and specific warnings when zero SKUs are found. Also added error logging with full exception details when INX processing fails. This will significantly improve troubleshooting for silent import failures.

  • Improvement Enhanced Add Catalog Items dialog layout

    Restructured the Add Catalog Items dialog to include a new menu bar at the top with the Tools menu, increasing the dialog height slightly to accommodate the additional functionality while maintaining the existing search and manual add workflows.

  • Improvement Batch SKU lookup optimization

    Implemented batched database queries that process up to 500 SKUs at a time when performing bulk lookups, preventing SQL parameter limit errors and improving performance for large imports. Query logic supports both Ace Hardware and Do-It-Best catalog formats.

  • Improvement Automatic duplicate handling in bulk imports

    When importing multiple SKUs, duplicates are automatically removed and you'll see a summary of what was added and what wasn't found.

  • Improvement Integrated rebuild workflow

    After importing new products, you'll be asked if you want to rebuild your data right away so the new items appear in your pricing grid immediately.

  • Improvement Enhanced error logging for data type issues

    Added specific logging for DateTime overflow errors and improved error messages to include entity type names, making it easier to diagnose data import problems and invalid date values.

  • Improvement Component license caching

    IPWorks runtime licenses are now cached locally using encrypted storage via RetailerSoft.ComponentLicensing. Cache is checked first on startup (avoiding API call), with automatic fallback to Blazor API fetch and appsettings.json base64 values. Added RefreshFromApiAsync method called by StartupCheckService when license validation fails, ensuring the next startup gets fresh keys. Also removes obsolete HasMultipleRSCs application setting (now computed on-demand from STORERSC global config).

  • Improvement Store Mapping Validation During Import

    The system now better validates which store data should be imported based on your store mapping configuration.

  • Improvement Removed connection test popup dialogs

    Connection test results no longer appear in popup windows that you have to close—everything stays visible on the settings screen.

  • Improvement New service methods for INDecoded file management

    Added three new methods to the Epicor FTP service: FindMostRecentINDecodedFilePath() locates the newest cached scan file, CanConnectToFtpAsync() tests server availability, and DownloadAndDecodeINFileAsync() downloads and decodes the IN file without importing. These enable smarter file handling throughout the application.

  • Improvement Consistent special-character handling across all MySQL queries

    Updated all MySQL Compass queries throughout the import pipeline—including inventory (IN), deleted items (dw_item), discontinued items (INX), group pricing, and orphan reconciliation—to use ASCII() for store character matching instead of UNICODE(). This ensures all queries use the same Windows-1252 byte key (matching MySQL ORD()) regardless of how the character is encoded in the local database.

  • Improvement Validation against live MySQL as canonical source

    Enhanced the store reconciliation logic to use the live MySQL database as the authoritative source of truth when recovering corrupted identifiers, ensuring recovered values are always validated against actual data rather than relying solely on string parsing.

  • Improvement Main Table Rebuild Progress Messages

    Sync progress now shows actual store numbers (e.g., "store 12345") instead of technical table names, making it easier to track which stores are being updated.

  • Improvement Main table rebuild now uses STOREMATCHUP as authoritative store list for Epicor

    When Epicor store mapping is enabled, the main table rebuild process now uses the store numbers defined in STOREMATCHUP configuration as the authoritative list, rather than scanning for distinct StoreNumber values in the Epicor table. This ensures main tables are created for all configured stores even if they temporarily have no data in the POS extract.

  • Improvement Handler registration and priority ordering

    Handlers are registered in `ServiceCollectionExtensions` with explicit priority: DIB6828 first (most specific headers), DIB1040 second (≥10 generic header matches), DirectConnect last (empty file list + valid config). The factory tests each handler's `CanHandleAsync` in registration order and returns the first match, ensuring the most specific handler wins when multiple formats could apply.

  • Bug Fix Import engine now handles native SQL libraries correctly

    POS file imports will no longer fail with compilation errors on computers where certain SQL Server support files are installed.

  • Bug Fix Fixed Paladin .map file compilation failure on .NET 10

    Paladin imports that were failing with compilation errors will now complete successfully.

  • Bug Fix Improved native DLL detection during Paladin .map compilation

    Fixed an error that prevented Paladin .map files from importing successfully on some computers.

  • Bug Fix RockSolid import no longer hangs during file processing

    If RockSolid imports were previously getting stuck with the app showing "Not Responding," they will now complete almost instantly.

  • Bug Fix RockSolid import no longer hangs on network paths

    If your RockSolid data file is stored on a network server and imports were freezing, they will now complete successfully. The import process is also faster and more reliable.

  • Bug Fix Settings migration duplicate key errors resolved

    Fixed a crash during application startup that could occur when migrating settings from older versions of Margin Master. When multiple legacy configuration entries shared the same setting name, the migration process could attempt to create duplicate database records, causing the application to fail to start. The migration now properly detects and skips duplicates within each batch of settings being converted.

  • Bug Fix Support issue pill now shows correct issue ID

    The title bar pill that displays open support issues now shows the actual issue ID (e.g., "MM-1099") instead of the hardcoded placeholder "#1". This makes it easier to identify and reference support issues directly from the main window.

  • Bug Fix Critical crash fix in data mapping system (MM-1105)

    Fixed a crash that could occur during data import.

  • Bug Fix Data Aging screen now displays accurate import record counts

    When you view the Data Aging screen, you'll now see the correct number of items that were imported from your POS system, making it easier to verify that imports are working properly.

  • Bug Fix Data Aging screen now displays correct import record counts

    When you view the Data Aging screen after importing POS data, you'll now see the actual number of records imported instead of zero.

  • Bug Fix Fixed broken file path in Epicor FTP download

    Stores using Epicor POS systems with FTP connectivity will no longer see "No Data Imported" errors caused by the download failing silently.

  • Bug Fix Corrected FTP download path construction for Epicor imports

    FTP downloads for Epicor POS data now save to the correct folder and complete successfully.

  • Bug Fix Corrected help button placement in Import Manager

    The help button on the Import Manager screen now appears next to the Import Path label instead of floating over the grid, making it easier to access without blocking your view of import files.

  • Bug Fix RockSolid imports now recorded in ImportProcessing table

    After importing from RockSolid, the Data Aging View now shows the correct number of records imported and when the import occurred.

  • Bug Fix RockSolid imports now recorded in import history

    After importing from RockSolid, you can now see when the last import occurred and how many records were imported in the Data Aging View.

  • Bug Fix Data Aging View now tracks Epicor INFILE imports

    When you import Epicor data, the Data Aging View will now show the correct import date and number of records processed for each store location.

  • Bug Fix Epicor import tracking in Data Aging View

    The Data Aging screen will now show the last import date and record counts for Epicor stores, making it easier to verify that your pricing data is current.

  • Bug Fix Order Indicator field now imports from MySQL Compass

    If you've renamed the PL field to "Order Indicator" (or any other name), the selection box will now show values after importing from MySQL Compass instead of appearing empty.

  • Bug Fix Order Indicator field now imports from Compass data

    The Order Indicator column now properly shows values like T, C, or S for items after importing Compass data.

  • Bug Fix Data Aging View now displays import history for MySQL Compass

    The Data Aging screen now correctly shows when your pricing data was last imported and how many items were imported for each store location.

  • Bug Fix Data Aging View now displays correct record counts for MySQL Compass Epicor

    When viewing the Data Aging screen after importing MySQL Compass Epicor data, you will now see the correct number of imported records for each store location instead of zero.

  • Bug Fix MySQL date filter now includes NULL timestamps

    Stores using MySQL Compass that had missing or NULL date stamps in their inventory data will now import successfully instead of silently skipping all records.

  • Bug Fix MySQL Compass import now handles NULL update timestamps

    Stores using MySQL Compass will now see all products imported successfully, even if some products are missing update timestamps in the database.

  • Bug Fix CounterWorks Excel import file format mismatch

    If you use CounterWorks POS, the Import Manager will now correctly find and process Excel export files from your system.

  • Bug Fix BCP version check now works without .map files

    Data imports will no longer fail with an error when certain internal configuration files are missing. The import process now finds the files it needs using a backup method.

  • Bug Fix BCP version check now works without mapping files

    Fixed an issue where Margin Master might fail to start properly with certain POS system types that don't require mapping files.

  • Bug Fix Fixed Excel file detection in Import Manager

    When clicking to select an import file, Excel files (.xlsx) now appear correctly in the file browser instead of being hidden.

  • Bug Fix Import file detection no longer requires .map files

    The Import Manager will now show available files to import for all supported POS systems. Previously, some systems would show an empty file list even when import files were present in the selected folder.

  • Bug Fix Import file detection for pre-compiled POS types

    When opening the Import Manager, all available files from your POS system will now be properly detected and displayed, regardless of how your system is configured.

  • Bug Fix Counterworks Excel import column mapping corrected

    If you import Counterworks data from Excel files, the import will now complete successfully instead of failing with column errors.

  • Bug Fix Fixed CounterWorks Excel column mapping

    When importing a CounterWorks Excel file, the product numbers (PARTNO) are now correctly recognized and imported as SKU numbers.

  • Bug Fix STORE column incorrectly named in COUNTERWORKS import

    Store numbers from COUNTERWORKS imports now correctly populate the STORE column in the pricing grid.

  • Bug Fix Epicor MySQL import crash resolved

    Fixed an error that prevented Epicor MySQL stores from importing their sales data — imports now work correctly.

  • Bug Fix Removed non-existent columns from BisTrack catalog insert

    Fixed an error that stopped Do-It-Best items from being added to your store's inventory when using BisTrack.

  • Bug Fix Removed unsupported DIB multiplier columns from catalog add operation

    Previously, trying to add Do-It-Best items from the catalog would fail with a database error on BisTrack systems. This now works correctly.

  • Bug Fix MySQL Compass connection test button restored

    You can now click "Test & Save Connection" to verify your MySQL Compass database settings are correct. The button will be disabled while the test is running.

  • Bug Fix Added cancel button support to Spruce data import

    If a Spruce data import is taking too long, you can now click the Cancel button on the progress screen to stop it instead of having to restart your computer.

  • Bug Fix SQL timeout during vendor data merge

    Stores with large catalogs will no longer experience failed imports that result in missing vendor pricing information.

  • Bug Fix Epicor + Do-It-Best main table data now displays correctly

    If you use Epicor and are a Do-It-Best member, your store data will now appear correctly in the pricing grid after import. Previously, the grid would be empty even after a successful import.

  • Bug Fix Fixed incremental import logic after database schema changes

    Pricing data from MySQL Compass stores will now fully reload automatically when the system detects the database needs maintenance, instead of showing incomplete inventory.

  • Bug Fix Fixed import order causing data loss during SQL Express upgrades

    After a database upgrade, the system will now automatically import your complete inventory from MySQL Compass instead of only importing recent changes, preventing missing products in your pricing grid.

  • Bug Fix Automatic cleanup of orphaned store data on import

    If your database had leftover data from old stores or a previous setup, those phantom stores will no longer appear in reports or affect your pricing calculations.

  • Bug Fix BisTrack import now handles commas in product descriptions

    If your BisTrack import was failing with an error about "Delimiter ',' not found," this fix resolves that issue. Product descriptions with commas (like brightness ratings or compound item names) will now import correctly.

  • Bug Fix Prevent SqlDateTime overflow in pre-compiled POS imports

    Imports from Paladin, Falcon, RockSolid, RockSolidMax, Transact, Bistrack, and Epicor will now complete successfully instead of failing silently.

  • Bug Fix Added database index to prevent timeout during group table creation

    Fixed a performance bottleneck that caused the application to freeze or timeout when working with pricing groups across multiple stores with large inventories.

  • Bug Fix Resolved store group creation timeout for MySQL Compass stores

    Large store groups (like RURAL items) will now save successfully without timeout errors when using Compass POS systems.

  • Bug Fix Display Summary panel shows all zeros after strategy execution

    After executing a pricing strategy, the Display Summary panel at the bottom left now correctly displays the totals for price increases, decreases, average change, and inventory value instead of showing all zeros.

  • Bug Fix Removed timeout limit on BisTrack main table imports

    Large BisTrack stores will now see their complete inventory imported into Margin Master instead of only a partial list.

  • Bug Fix Suppress confirmation dialog during automatic catalog item restoration

    When you import from BisTrack, manually-tracked catalog items are still restored automatically, but you won't see a pop-up message about it anymore.

  • Bug Fix BisTrack import no longer shows unnecessary SKU dialog

    You will no longer see an unexpected SKU selection popup after completing a BisTrack import.

  • Bug Fix Store number list fallback for unconfigured stores

    The system now correctly identifies your store number during catalog imports, even if store settings haven't been fully configured yet.

  • Bug Fix Import failure after database restore

    If you restored a database from backup, your next import from Paladin, RockSolid, or Transact may have failed silently. This is now fixed and imports will work properly after restoring backups.

  • Bug Fix Import history now excludes zero-record import attempts

    The Import History panel now shows only successful imports. Previously, failed import attempts with zero records could appear as your "most recent" import, making it unclear when your store data was actually last updated.

  • Bug Fix Automatic migration of legacy SKU Level Exceptions steps

    When loading a pricing strategy, the application now detects SKU Level Exceptions steps that were imported with prefixed names (such as "SP: Sku Level Exceptions" from legacy systems). If the canonical special step already exists, the duplicate is automatically removed. If no canonical version exists, the legacy step is migrated to the correct key and configuration format. This prevents the step from being incorrectly executed as a regular pricing step, which would cause strategy execution to fail.

  • Bug Fix Handle missing vendor store number column in Epicor MySQL

    Fixed an error that prevented some stores from importing data from Epicor POS systems with older database configurations.

  • Bug Fix Epicor MySQL import compatibility with older schemas

    If your Epicor system doesn't store vendor store numbers in its database, imports will now complete successfully instead of showing an error.

  • Bug Fix Data import no longer crashes on stores without DIB mailbox pricing table

    Importing data will no longer fail for Do-It-Best stores that aren't set up with mailbox pricing integration.

  • Bug Fix Paladin import now handles missing DIB mailbox table

    If your store uses Paladin and Do-It-Best but doesn't have DIB mailbox pricing data, imports will now work correctly instead of failing with an error.

  • Bug Fix Fixed Validate License button remaining disabled

    The Validate License button now becomes available as soon as you enter a store number and select your vendor and POS system, allowing you to proceed without getting stuck.

  • Bug Fix Import no longer fails when POS system is actively writing to file

    Imports will no longer fail with "file in use" errors when your POS system is writing data at the same time.

  • Bug Fix Guard against empty vendor store number during MySQL import

    The system now safely skips stores with missing vendor store numbers during import instead of crashing.

  • Bug Fix Import validation now checks for empty vendor store numbers

    If your Epicor system has stores with missing vendor numbers, the import will no longer crash—those stores will simply be skipped.

  • Bug Fix Skip malformed database tables during pricing analysis

    The pricing analysis tools will no longer crash when encountering incomplete store data from MySQL Compass imports—the system will skip the problematic data and continue working with valid store information.

  • Bug Fix SQL bracket protection for table names with dots

    The application will no longer crash when processing data for stores whose table names contain version numbers with dots.

  • Bug Fix Fixed Epicor import failures due to unbracketed table names

    Custom Groups and SKU Exceptions will now update correctly during Epicor imports without encountering database errors.

  • Bug Fix Propello long item code handling

    Propello imports will no longer fail when item codes are longer than 25 characters—they'll be automatically shortened to fit.

  • Bug Fix Propello import now handles long item codes and descriptions

    If your store uses long item codes or product descriptions, Propello imports will now complete successfully instead of showing an error. Item codes and descriptions will be shortened automatically if needed.

  • Bug Fix Mi9 competitor price filters now work correctly

    Competitor price filters (Comp1-Comp5) in Mi9 stores no longer cause database errors when applied to the pricing grid.

  • Bug Fix Automatic cleanup of manually-added catalog items after import

    When you manually add catalog items and they later show up in your regular store data, they're now automatically cleaned up so you don't see duplicates or unnecessary tracking entries.

  • Bug Fix Clean up manual catalog items after successful import

    Items you manually added to your catalog will automatically be removed from manual tracking once they show up in your regular vendor files, preventing duplicates.

  • Bug Fix Corrected BisTrack import column references
  • Bug Fix Corrected BisTrack column name references in import query

    Updated the SQL query that moves BisTrack data from staging into the main pricing table to use the correct shortened column names (Store instead of StoreNumber, PG instead of ProductGroup, Desc2 instead of Description2, H1-H12 instead of History1-History12, OM instead of OrderMultiple). Previously, the staging table schema was updated with abbreviated column names, but the insert query still referenced the old full names, causing import failures.

  • Bug Fix BisTrack imports now remove per-store manual catalog entries

    When items you've manually added to the catalog appear in your BisTrack store data, the manual entries are automatically removed to prevent duplicates.

  • Bug Fix BisTrack manual catalog cleanup now removes per-store entries

    If you manually added a catalog item for a BisTrack store, it will now be automatically removed once that item appears in your store's official import data.

  • Bug Fix BisTrack multi-store import progress counter now advances correctly

    The progress display during BisTrack imports now accurately shows which file is being processed (e.g., "5 of 20") instead of appearing stuck on the first file.

  • Bug Fix Fixed BisTrack preloaded import processing all stores per file

    BisTrack imports that were taking much longer than expected will now complete significantly faster.

  • Bug Fix Eliminated redundant store processing in BisTrack imports

    Multi-store BisTrack imports now complete much faster, especially noticeable for retailers with many store locations.

  • Bug Fix Whitespace-only fields now treated as empty in BisTrack imports

    When importing BisTrack data, fields that look empty (containing only spaces) are now correctly treated as empty instead of being imported with invisible space characters.

  • Bug Fix BisTrack whitespace handling corrected

    The BisTrack CSV import process now properly trims whitespace from all field values and treats whitespace-only cells as empty rather than storing them as single-space strings. This prevents phantom data in fields that appear empty but actually contain spaces.

  • Bug Fix Splash screen progress now updates during BisTrack preload

    When importing multiple BisTrack files, you'll now see the progress bar and status messages update during the entire import, including the initial file loading phase that previously appeared stuck.

  • Bug Fix BisTrack preload progress events not wired

    When importing BisTrack data, you'll now see progress updates on the loading screen instead of it appearing stuck or frozen.

  • Bug Fix BisTrack preload guard added for multi-file imports

    Fixed an issue where importing multiple files from certain POS systems could fail or behave incorrectly due to BisTrack-specific processing being applied to them.

  • Bug Fix BisTrack preload incorrectly triggered for other POS systems

    When importing multiple files from POS systems other than BisTrack, you will no longer see the preload screen that was meant only for BisTrack imports.

  • Bug Fix BisTrack SQL column name mismatch

    BisTrack imports no longer fail with column name errors.

  • Bug Fix Fixed BisTrack staging table column name mismatches

    BisTrack imports will no longer fail with column name errors.

  • Bug Fix Fixed critical async handling bug in BisTrack import handlers

    Corrected the WithEventsAsync method in BisTrack DIB 1040 and 6828 handlers to properly await asynchronous operations. The previous implementation was returning unawaited tasks, which could cause import failures or incomplete data loading during BisTrack POS imports.

  • Bug Fix Fixed async timing issue in BisTrack import handlers

    Corrected async/await implementation in BisTrack DIB 1040 and 6828 handlers that could cause import progress events to be missed or reported incorrectly during store builds.

  • Bug Fix Automatic detection of missing stores in BisTrack imports

    If you import BisTrack data and some store files are missing, Margin Master will now ask if you want to delete the old data for those stores. This prevents accidentally using outdated pricing information.

  • Bug Fix Missing store detection for BisTrack imports

    If you're importing BisTrack data and a store's files are missing, Margin Master will now warn you and ask if you want to remove that store's old data.

  • Bug Fix Fixed slow BisTrack per-store data processing

    BisTrack imports will now run significantly faster, particularly noticeable for stores with thousands of products or multiple store locations.

  • Bug Fix Pricing strategy backup restore now handles legacy date values

    Pricing strategies from older backups will now restore successfully without errors.

  • Bug Fix Import Manager now ignores NEWRETAILS.CSV export files

    If you export new retail prices to a NEWRETAILS.CSV file in your POS import folder, the Import Manager will no longer try to read it as a POS file and fail.

  • Bug Fix NEWRETAILS.CSV excluded from import file detection

    When selecting files to import from your POS system, NEWRETAILS.CSV will no longer appear in the list, making it easier to find the correct files.

  • Bug Fix Direct upload finalization now runs correctly

    Previously, some SpruceWareNet imports would appear to complete but show no data in the pricing grid or dropdown menus. This has been fixed, and all imports now display data correctly.

  • Bug Fix Transact import timeout resolved for SQL Express installations

    If your Transact import previously failed or left department/class dropdown boxes empty after importing, it will now complete successfully.

  • Bug Fix Mi9 column header whitespace tolerance

    Mi9 POS files with extra spaces in headers will now import successfully instead of showing column mismatch errors.

  • Bug Fix Mi9 import KeyNotFoundException crash resolved

    Stores with Mi9 systems can now reliably import data even when their POS export files have extra spaces around column names like "StoreNumber" or "ItemID".

  • Bug Fix Mi9 import now handles whitespace in column headers

    If your Mi9 POS system exported files with extra spaces around column names (like " StoreNumber"), the import would crash. This now works correctly.

  • Bug Fix MySQL Compass import timeout resolved

    If you previously experienced "timeout" errors when importing MySQL Compass data, especially with large inventory files, these imports will now complete successfully and much faster.

  • Bug Fix Resolved MySQL Compass inventory import timeout

    MySQL Compass inventory imports that were previously timing out or running very slowly will now complete successfully in a reasonable time.

  • Bug Fix Store number reading from import spreadsheets

    Import spreadsheets with store numbers entered as plain numbers (like 1, 2, 3) now work correctly instead of being ignored.

  • Bug Fix Cloud sync now validates connection before starting

    If cloud sync can't connect, you'll now see a clear error message instead of the app appearing to freeze.

  • Bug Fix UseAverageCost setting now works for MySQL Compass imports

    If you've enabled "Use Average Cost" in MySQL Compass settings, your pricing grid will now correctly show average cost values instead of replacement cost after importing data.

  • Bug Fix Use Average Cost setting now applies to MySQL Compass Epicor imports

    If your store has "Use Average Cost" enabled, margin calculations will now correctly use the average cost from your Epicor system instead of the last cost.

  • Bug Fix Splash screen now displays before processing large Epicor data files

    The progress window now appears correctly when importing Epicor data, so you'll always see that the import is running rather than the application appearing frozen.

  • Bug Fix Splash screen now displays when reprocessing Epicor INdecoded files

    Progress indicators now display correctly when reprocessing Epicor data that was already downloaded today.

  • Bug Fix Epicor store character encoding corrected for non-ASCII values

    If your Epicor system uses store codes with special or non-printable characters, those codes will now appear correctly in the store mapping screen and can be successfully mapped to vendor store numbers.

  • Bug Fix Epicor store character mapping now preserves all byte values

    If your Epicor system uses store codes that previously showed as garbled characters or question marks, you can now re-scan your INDecoded file and map them correctly.

  • Bug Fix Store number encoding now correctly scoped to Epicor only

    If you use RockSolid, Transact, BisTrack, Catalyst, Falcon, Paladin, or MySQL Compass, your store number mappings will now save correctly in the Store Match Up screen instead of being corrupted.

  • Bug Fix Store number display and storage corrected for non-Epicor POS systems

    If you use RockSolid, Transact, BisTrack, Catalyst, Falcon, Paladin, or MySQL Compass, store numbers in the Store Match-Up dialog will now display correctly instead of showing unexpected characters. Your store number assignments will save properly.

  • Bug Fix Data Aging View now displays all Epicor store numbers correctly

    When viewing data aging information, all Epicor stores now show their store numbers clearly instead of appearing as blank rows.

  • Bug Fix Epicor store number display in Data Aging View

    When viewing data age by store for Epicor imports, store numbers that previously appeared blank now display as readable numbers.

  • Bug Fix Extended Epicor store characters now visible in matchup dialog

    If your store uses Epicor with extended store designations beyond the standard range, you'll now see these displayed as numbers (like "128") instead of blank spaces in the POS Store Matchup screen.

  • Bug Fix Corrected display of extended ASCII store characters for Epicor

    When setting up store matching for Epicor, any stores using special or extended characters will now show up correctly instead of appearing blank or garbled.

  • Bug Fix Extended character display in Epicor store mapping

    In the Epicor store character matchup screen, special punctuation and symbols now appear correctly. Previously, characters like the dagger symbol or smart quotes would show up as numbers (like "135") or be invisible; now they display as the actual symbol.

  • Bug Fix Store matching now handles special characters correctly

    If your store identifier in Epicor uses a special character or symbol, it will now be recognized correctly when importing data.

  • Bug Fix Epicor store number display with mapping enabled

    If your store uses Epicor with store mapping turned on, the Data Aging View will now show the correct Ace store numbers instead of confusing numeric codes.

  • Bug Fix Data Aging View shows correct store numbers for Epicor

    When viewing import history in the Data Aging screen, you'll now see your actual Ace store numbers (like "13201") instead of confusing internal codes when store mapping is turned on.

  • Bug Fix Do-It-Best taxonomy data now loads correctly for Transact POS

    When viewing Do-It-Best items in the pricing grid, you'll now see the correct category and classification information in the taxonomy columns instead of blank fields.

  • Bug Fix DIB taxonomy data now loads correctly for Transact stores

    Do-It-Best product categories and classifications now appear properly in the pricing grid for Transact stores instead of showing blank.

  • Bug Fix MySQL queries now respect custom database configuration

    If your store uses a custom database name for Epicor MySQL Compass, imports will now work correctly using your configured database name.

  • Bug Fix Removed hardcoded EAGLEDW schema from MySQL queries

    If your store's MySQL Compass database is not named "EAGLEDW", imports will now work correctly instead of failing with database errors.

  • Bug Fix Skip import records with missing store numbers

    Fixed a crash during import that affected stores with incomplete configuration data.

  • Bug Fix Epicor backup file deletion resolved

    Backup files created during Epicor POS imports will no longer be accidentally deleted, providing better data safety and troubleshooting capability.

  • Bug Fix Epicor backup cleanup now working correctly

    When Epicor files are reprocessed, old backup copies are now properly deleted, freeing up disk space that was previously being consumed by unnecessary files.

  • Bug Fix Per-store tables are now fully deleted during POS data reset

    When using the "Reset POS Data" support tool, per-store main tables (which are created separately for each store location during import) are now completely dropped from the database instead of being truncated to empty tables. The staging table for each POS system continues to be truncated as before. This change prevents accumulation of orphaned table structures when stores are added and removed over time.

  • Bug Fix Reset POS Data drops per-store main tables

    When you reset POS data in Import Manager, the system now fully removes store-specific tables instead of just clearing them, which prevents potential errors when re-importing data.

  • Bug Fix Epicor import now runs in background to prevent UI freezing

    When importing large Epicor data files, the application will no longer freeze or appear to hang. You'll see progress updates throughout the import process instead of a frozen window.

  • Bug Fix Excel file export routing for Mi9

    When exporting to an Excel file in Mi9 mode, you'll now get a single file with all your data as expected, rather than the three-file branch export format.

  • Bug Fix Fixed Mi9 export triggering for wrong destinations

    Mi9 exports now only occur when you select Text File or Custom Text File as the export destination.

  • Bug Fix Data Aging screen displays correct counts after POS reset

    When you reset your POS data using the Reset POS Data tool, the Data Aging screen will now correctly show that you have zero records instead of displaying old counts from previous imports.

  • Bug Fix Data Aging screen now updates correctly after POS data reset

    After you reset your POS data in Settings, the Data Aging screen will now correctly show zero records instead of showing outdated counts from your previous imports.

  • Bug Fix MySQL Compass grouped stores rebuild after cloud sync

    If your store uses MySQL Compass with grouped pricing, your pricing tables will now update correctly after syncing from the cloud instead of remaining unchanged.

  • Bug Fix MySQL Compass rebuild now works after cloud sync

    If you use MySQL Compass with multiple stores, you can now successfully rebuild your pricing tables after syncing data from the cloud.

  • Bug Fix Removed phantom store 99999 for Epicor systems

    If you use Epicor, you'll no longer see a fake store "99999" appearing in your zone assignment list.

  • Bug Fix One Click Statistics now calculates correctly for all vendors and POS systems

    The One Click Statistics screen will now show accurate pricing level breakdowns for Ace Hardware and stores using Epicor, instead of displaying all zeros.

  • Bug Fix Prevented SQL timeout when updating extended fields during Compass import

    Added a composite database index (in_store, in_item_number) to the shared Compass_IN table to eliminate full table scans during per-store UserE1/E2/E3 updates. Previously, stores processed last in multi-store installations (~1.3 million rows across 10 stores) would experience SQL timeouts due to inefficient table joins. The index is created automatically before store processing begins.

  • Bug Fix Backup now handles large databases without running out of memory

    Creating backups for stores with large amounts of data will no longer freeze or crash the application.

  • Bug Fix Added missing database index for MySQL Compass imports

    MySQL Compass imports will no longer fail or time out when processing stores in multi-store setups, especially stores with large inventories processed later in the import sequence.

  • Bug Fix Corrected Epicor Store Manager menu detection logic

    When using Epicor POS, the menu now correctly shows "Manage Epicor POS/Vendor Store Info" and opens the right configuration screen.

  • Bug Fix Store Manager Rescan now offers smart file selection for Epicor

    When rescanning stores, Margin Master will now check if you have a recent scan file and ask if you want to use it or download a fresh copy from your Epicor server.

  • Bug Fix Auto-switch to Backup Files tab when no current files available

    If you open the Import Manager and there are no new files to import, you'll now automatically see your previously imported backup files instead of a blank screen.

  • Bug Fix Auto-map Epicor store identifiers after format change

    If you have Epicor POS and recently started seeing import warnings about unassigned stores, this update automatically fixes the problem by recognizing the new store identifiers without requiring you to manually re-configure your store mappings.

  • Bug Fix Auto-map Epicor INDecoded store characters after format change

    If your Epicor system recently changed how store numbers are formatted in downloaded files, Margin Master will now automatically transfer your existing store-to-vendor assignments to the new format instead of showing them as unmapped.

  • Bug Fix Store mapping migration now processes all legacy STOREMATCHUP entries

    Stores that were configured in your system but missing from the Store Manager screen will now be properly migrated and visible.

  • Bug Fix Missing STOREMATCHUP entries now properly migrated

    Stores configured in your system that were missing from the Store Manager will now appear correctly and be available for data import.

  • Bug Fix Auto-map vendor numbers before import starts

    After Epicor changes the inventory file format, your first import will now correctly process all inventory records instead of skipping them.

  • Bug Fix Epicor INDecoded store mapping format migration

    When you sync an Epicor INDecoded store, the system now automatically corrects store number mappings that were created in an older format, ensuring vendor catalogs link to the correct store numbers.

  • Bug Fix Epicor store ordinal migration now runs at startup

    For stores using Epicor, store numbers are now automatically converted to the correct format when you start Margin Master, before any data imports run. This happens in the background and prevents potential issues with store identification during imports.

  • Bug Fix Duplicate store rows no longer created during GlobalFileConfig import

    When the system imports vendor store mappings from GlobalFileConfig, it will now correctly update existing store entries instead of creating duplicate rows in the Store Manager.

  • Bug Fix NonCore items now show correct cost values after MI9 import

    Items marked as NonCore will no longer show blank cost fields after importing data. The system now correctly calculates and displays their average cost across all store locations.

  • Bug Fix MI9 NonCore items showing blank cost values

    When importing data from MI9 POS systems, items that are not stocked in your store (NonCore items) will now show their correct cost values instead of appearing blank in the pricing grid.

  • Bug Fix Eliminated duplicate store rows in Store Manager

    If you previously saw two rows for the same store in Store Manager (one with and one without a store number), those duplicates will now be automatically cleaned up and prevented from recurring.

  • Bug Fix Fixed store group import failure for MySQL Compass

    Imports will no longer fail unexpectedly when loading store information from MySQL Compass systems.

  • Bug Fix Fixed Epicor store number mapping in group processing

    Pricing strategies will now execute properly for Epicor stores during import operations.

  • Bug Fix Preserve configured Epicor stores with raw-byte ordinals

    Configured Epicor stores will no longer disappear from your store list after sync, even if they use numeric store codes between 0 and 31.

  • Bug Fix Epicor store numbers now display correctly for control-character identifiers

    Fixed a bug where Epicor stores using raw-byte ordinals (non-printable control characters) would appear with blank or invisible store numbers in the POS Store column. The system now automatically normalizes these invisible values to their numeric ordinal equivalents (e.g., store ordinal 5) so they are visible and identifiable in the store mapping grid. This correction applies during initial migration, automatic mapping, and new store creation during import.

  • Bug Fix Epicor raw-byte store ordinals now display correctly

    Epicor stores with special low-number store identifiers now show up correctly in store lists instead of appearing as blank entries.

  • Bug Fix MySQL Compass store numbers now display correctly

    If your store number appeared blank in the store manager, it will now show as a readable number.

  • Bug Fix Normalize invisible store numbers in MySQL discovery

    Store numbers from MySQL Compass now appear as readable numbers instead of blank spaces in the Store Manager.

  • Bug Fix Epicor store deletion now marks as Excluded instead

    If you try to delete an Epicor store that's still in your POS system, it will be marked Excluded instead to prevent it from coming back during the next import.

  • Bug Fix Store Manager delete button now functions correctly

    Corrected a technical issue where the delete button in the Store Manager grid was not properly connected to the selected store row, which prevented deletion from working.

  • Bug Fix Epicor store deletion guard now covers INDecoded path

    If you try to delete an Epicor store that still exists in your system, you'll now see a more accurate message explaining which data source it comes from (MySQL Compass or INDecoded file), and the store will be marked as Excluded instead of deleted.

  • Bug Fix Fixed delete guard for Epicor INDecoded stores

    When you try to delete an Epicor store that's still active in your system, Margin Master now correctly prevents the deletion and marks it as Excluded instead—whether you're using MySQL Compass or INDecoded imports.

  • Bug Fix Pre-flight connection validation for MySQL imports

    You'll now see an immediate, clear error message if MySQL isn't configured or can't be reached, instead of the import appearing to run but not actually importing anything.

  • Bug Fix Connection validation before MySQL import

    If MySQL isn't set up or can't be reached, you'll now see a helpful message right away instead of getting an error partway through the import.

  • Bug Fix Progress bar now reflects true overall import progress for MySQL Compass
  • Bug Fix Overall progress bar now tracks multi-store imports correctly

    When importing multiple stores from MySQL Compass, you'll now see the progress bar advance smoothly across the entire import process instead of appearing to reset for each store.

  • Bug Fix Added substatus messages during MySQL Compass merge operations

    When importing MySQL Compass data, you'll now see messages like "Merging data into store table..." and "Rebuilding SKU index..." instead of the screen appearing stuck.

  • Bug Fix Corrected MySQL query encoding for Epicor store character identifiers

    If your store uses a special character (like extended ASCII characters) as its Epicor store identifier, inventory imports from MySQL Compass will now work correctly instead of returning no items.

  • Bug Fix Corrected MySQL query encoding for Epicor store characters

    If your store identifier in Epicor contains special characters, the import process will now correctly pull your store's data instead of potentially missing items or pulling incorrect store data.

  • Bug Fix Vendor filter applied to post-sync reality check

    Stores using a primary vendor filter in MySQL Compass will no longer see false error messages about incomplete imports.

  • Bug Fix Missing vendor data after BisTrack import

    After importing data from BisTrack, all product and vendor information now appears correctly in the pricing grid instead of showing empty selection boxes.

  • Bug Fix Corrected store number recording during Epicor imports

    When importing Epicor POS data, your store numbers are now saved correctly in the system.

  • Bug Fix Corrected special character store handling in Store Manager

    Store Manager was incorrectly treating special Windows-1252 characters (bytes 0x80-0x9F, such as '‡' or '†') as two different stores—one keyed by the raw byte value (135) and another by the Unicode code point (8225). This caused duplicate entries to appear in the Store Manager screen that couldn't be removed, and excluding or deleting the wrong one would delete Compass_IN data for the actual store, resulting in zero SKUs imported. The reconciliation process now consistently uses Windows-1252 byte ordinals (the same method used throughout the rest of the import pipeline) to identify stores.

  • Bug Fix Corrected store character ordinal storage for Epicor MySQL

    Stores with numeric characters in their Epicor MySQL setup will now import inventory data correctly instead of showing 0 SKUs.

  • Bug Fix MySQL store ordinal persistence corrected

    Stores with numeric characters in their Epicor MySQL store identifiers will now import correctly instead of returning zero items.

  • Bug Fix Added validation to reject invalid multi-byte store characters

    When discovering Epicor MySQL stores, the system now detects and logs a warning if any store character has an ordinal value above 255, which indicates the MySQL IN.in_store column is incorrectly configured as UTF-8/multibyte instead of the expected latin1 encoding. These invalid stores are skipped during discovery and import, with a clear message explaining that the MySQL column collation needs to be latin1. Previously, such stores would silently fail to import any data.

  • Bug Fix MySQL Compass imports no longer fail on fresh stores

    Fixed "Invalid object name 'Compass_IN'" errors during MySQL Compass imports on new store databases. The import process now ensures the Compass_IN table exists before attempting to read from it, allowing imports to proceed successfully on fresh installations instead of logging errors and aborting.

  • Bug Fix Retry file deletion when export file is locked

    If you have the export file open in Excel or Notepad when running an export, the system will now retry automatically instead of immediately failing. If the file is still locked after a few attempts, you'll see a clear message asking you to close the file first.

  • Bug Fix Epicor store key collision in cloud sync

    If you use Epicor POS, store-specific settings like RSC codes and zone overrides will no longer get mixed up between different stores during cloud sync.

  • Bug Fix Cloud store settings now key on character ordinal for Epicor

    Previously, cloud store settings for Epicor stores used the POS store number string directly, which could cause mismatches when store identifiers contained control characters or when digit characters were ambiguous (e.g., the character '1' vs. control character 1). The system now uses the character's byte ordinal value (PosStoreCharOrdinal) as the canonical key for Epicor stores, ensuring unambiguous identification. For other POS systems (Mi9, RockSolid, etc.), the POS store number continues to be used as before.

  • Bug Fix Falcon CSV import restored after being silently skipped

    If your store exports Falcon data as a CSV file, the import will now work correctly instead of using old data or showing incomplete rows.

  • Bug Fix Falcon CSV import now properly recognized and processed

    If your Falcon system exports a CSV file instead of Excel, Margin Master will now import all your inventory rows correctly instead of only importing a partial set.

  • Bug Fix Epicor special-character stores now import correctly

    If your store uses a special character like ‡ or † as its store number, inventory will now import correctly instead of showing zero items.

  • Bug Fix Special-character Epicor store data not loading from MySQL

    If your store number contains special symbols like '‡' or '€', inventory imports from MySQL Compass will now work correctly. Previously these stores would appear to import zero records.

  • Bug Fix Partial store import now scopes rebuild to selected stores only

    When you Shift-click to import data for specific stores, only those stores will be updated — other stores keep their existing data.

  • Bug Fix Partial import now rebuilds only selected stores

    When you Shift-click to import only specific stores, the system now updates only those stores instead of rebuilding everything.

  • Bug Fix Store number mapping now works for all Epicor import methods

    If you use Epicor and import via FTP, store selection dropdowns will now properly show both your POS store number and vendor store number (e.g., "Store 01 (Vendor 123)") instead of just the vendor number.

  • Bug Fix Epicor store mapping no longer auto-enabled on every launch

    If you disabled store mapping in Epicor settings, your choice will now be remembered instead of being reset every time you open the app.

  • Bug Fix Eliminated slow imports from orphaned manual catalog items

    If you previously experienced very slow Do-it-Best imports (20+ minutes), this will now complete in seconds. The system automatically removes catalog items that were added for stores not configured on your machine.

  • Bug Fix Optimized discontinued manual catalog item cleanup

    Manual catalog items that are no longer in the vendor's catalog are now removed much faster during imports, preventing long delays.

  • Bug Fix Require valid yard for new-product imports at multi-yard stores

    If you're importing new products at a store with multiple yards and forget to include the Yard # in your spreadsheet (or enter an invalid yard), you'll now see a clear message telling you which yards are valid. Previously, the import would silently fail and show all items as already existing.

  • Bug Fix Automatic repair of corrupted store ordinals in multi-store Epicor accounts

    If your multi-store Epicor account previously showed empty selection boxes after importing data, the system will now automatically fix the underlying store configuration issue and imports will work correctly.

  • Bug Fix Automatic recovery of corrupted multi-store identifiers

    If your store identifiers were showing incorrectly or stores were missing from analysis, they will now automatically fix themselves during the next data import.

  • Bug Fix Import Manager no longer auto-displays non-importable backup files

    When you open the import window and there are no new files to import, you'll see a clear message explaining that your previous files were already imported and renamed to backups, rather than seeing a list of files that won't actually import.

  • Bug Fix Import window no longer surfaces already-imported backup files

    After importing all your files, the import window will now tell you "No new files to import" instead of showing backup files that can't be imported again.

  • Bug Fix Prevent foreign store identity adoption at startup

    If you switch between databases, Margin Master now correctly uses the store number from the database you opened, not a leftover number from a previous session.

  • Bug Fix Malformed CSV rows no longer block entire import

    If your POS export file has a few corrupted or incomplete data rows, the import will now succeed and load all the valid rows instead of failing completely.

  • Bug Fix Import scan no longer blocked by wrong-format files

    If you accidentally save unrelated CSV or text files in your import folder, the system will now skip them and continue importing your POS data normally. Previously, even one wrong file would stop all imports without showing an error.

  • Bug Fix Import scan no longer blocked by non-matching files in import folder

    If you accidentally copy a price-change CSV, text file, or export from a different system into your import folder, Margin Master will now skip over it and still import your correct POS files. Previously, that one wrong file would stop all imports without showing an error.

  • Bug Fix Data Aging view now detects partial import history

    If import history records are missing or incomplete for some stores, the Data Aging screen will now automatically read the actual store tables to show you complete, accurate counts instead of appearing to lose data.

  • Bug Fix Data Aging screen now detects incomplete import history coverage

    If you have multiple store locations, the Data Aging screen will now show accurate import counts for all stores instead of sometimes displaying data for only one or two locations.

  • Bug Fix Newly imported stores now receive RSC assignment automatically

    When you import POS data and the system discovers new store locations, those stores will now automatically show their correct RSC assignment in Store Manager instead of appearing blank. This means vendor pricing will sync correctly for all your locations right away.

  • Bug Fix Splash screen now closes reliably after New Product Import

    The loading splash screen will now close properly after importing new products and choosing to rebuild the database, instead of getting stuck on screen.

  • Bug Fix Splash screen teardown during New Product Import

    The loading screen will no longer get stuck on screen or appear on top of other windows when importing new products and choosing to rebuild data.

  • Bug Fix MySQL import log message corrected

    Corrected an incorrect error message that appeared in log files during data imports, making it easier to troubleshoot actual configuration issues.

  • Bug Fix Support issue pill now shows actual issue number

    When you have an open support issue, the notification bar now shows the actual issue number (like "#12345") instead of just "#1", making it easier to discuss issues with support.

  • Bug Fix Corrected download destination folder for Epicor files

    Fixed a secondary issue where downloaded files were being saved to a "temp" subfolder that the decoder never checked, which would have caused failures even after the path bug was fixed. Files now download directly to the expected folder where the decode step looks for them.

  • Bug Fix Aligned FTP and SFTP download behaviors for Epicor

    Epicor imports now work consistently whether your store uses FTP or SFTP connections.

  • Bug Fix Corrected 12-hour to 24-hour time format in MySQL queries

    Changed date format from `hh:mm:ss` (12-hour) to `HH:mm:ss` (24-hour) in all MySQL date filter queries. The 12-hour format was causing incorrect filtering for afternoon/evening timestamps, potentially excluding valid records.

  • Bug Fix Corrected date format in MySQL Compass queries

    Fixed incorrect 12-hour time format (hh:mm:ss) that should have been 24-hour format (HH:mm:ss) in all MySQL date filter queries. This could cause imports to skip products updated in the afternoon/evening hours due to incorrect timestamp comparisons.

  • Bug Fix Null store number crash prevention

    Imports no longer crash when encountering missing or invalid store numbers.

  • Bug Fix MySQL Compass import reality check

    MySQL Compass imports are now more reliable — if your local data is incomplete (like having only 19 items when you should have 28,000), the system automatically detects this and reimports everything correctly.

  • Bug Fix Removed command timeout limit for very large group operations

    Large pricing groups with many SKUs will now complete successfully instead of timing out partway through.

  • Bug Fix Fixed fallback import path timeout for BisTrack

    The fallback import method (used when RSC data is unavailable) was using a default 30-second timeout, which was also too short for large inventories. This path now also uses an unlimited timeout to ensure complete imports.

  • Bug Fix Do-It-Best catalog import for No-POS stores

    Do it Best catalog imports now successfully add items to your store instead of showing an error message that no items were added.

  • Bug Fix Skip execution of misidentified SKU Level Exceptions marker steps

    If a strategy execution encounters a SKU Level Exceptions step that was imported incorrectly, it will now skip over it gracefully instead of failing, and will log a recommendation to reload the strategy for a permanent fix.

  • Bug Fix Fixed Proceed button staying disabled after license validation

    The Proceed button now enables immediately after your license is validated, letting you continue creating your database without delays.

  • Bug Fix Null reference protection in SKU exceptions

    Added null coalescing operator (?? []) in SkuLevelExceptionsViewModel.QueryAsync to prevent NullReferenceException when the query returns null before OrderBy operations. This ensures the exception loading process completes successfully even when no records are found.

  • Bug Fix Fixed crash when pricing strategies have empty margin values

    Pricing strategies with missing margin values now show a clear error message instead of causing the application to crash.

  • Bug Fix Epicor table imports with version numbers in names

    Epicor data imports with version numbers in table names (like 1.07) now complete successfully without database errors.

  • Bug Fix BisTrack handler instance tracking

    BisTrack imports now run once per file as intended, completing faster and without duplicate processing.

  • Bug Fix Fixed BisTrack handler instance not completing multi-store builds

    BisTrack imports now complete faster and won't get stuck reprocessing the same files.

  • Bug Fix Removed "ALL" option from BisTrack catalog store list

    When adding catalog items in BisTrack, the store dropdown now only shows your actual store numbers instead of including an "ALL" option that didn't work.

  • Bug Fix Epicor MySQL vendor import handles missing creation dates

    Epicor vendor catalog imports will no longer fail when store information is missing creation dates.

  • Bug Fix Non-import file detection for Mi9 folders

    If you accidentally place a non-import file in your Mi9 import folder, it will be skipped with a warning instead of stopping the entire import.

  • Bug Fix Prevent products from being added to all stores unintentionally

    New products imported without a valid store number now default to your primary store instead of being accidentally added to every store in your system.

  • Bug Fix Auto-repair for corrupted Ace Hardware zone pricing tables

    Zone pricing data for Ace Hardware will now sync successfully even if your local database structure was corrupted.

  • Bug Fix Character encoding normalization for MySQL databases

    Added PosStoreCharHelper.MatchesMySqlStoreChar() method that normalizes both stored ordinal strings ("87", "135") and MySQL character values to Windows-1252 byte ordinals before comparison. This handles the difference between UTF-8 MySQL databases (where ORD() returns Unicode code points like 8225 for dagger U+2021) and Latin-1 MySQL databases (where ORD() returns raw byte values like 135), ensuring consistent matching across different database configurations.

  • Bug Fix Increased timeout for large catalog deduplication

    Fixed timeout errors that prevented stores with large vendor catalogs from completing imports.

  • Bug Fix Fixed store mapping validation during Epicor INDecoded import

    Epicor imports now correctly skip records from stores that haven't been assigned vendor store numbers in the connection settings.

  • Bug Fix Mi9 branch export success message count

    After exporting to Mi9 branch files, the success message now shows the correct number of items that were exported.

  • Bug Fix Corrected Mi9 export record count in success message

    The export success message now shows the correct number of items exported instead of zero.

  • Bug Fix Ace Hardware catalog import now updates product information correctly

    Ace Hardware catalog imports will now correctly update product departments, pricing, vendor details, and other catalog information that was previously being skipped.

  • Bug Fix Store Manager groups now apply consistently

    Store groups you assign in Store Manager will now always appear correctly in your pricing reports and filters.

  • Bug Fix Store Manager groups now applied during pricing rebuilds for Epicor

    Pricing rebuilds now correctly use your Store Manager group assignments for Epicor stores.

  • Bug Fix Corrected import log messages for file renaming

    Fixed logging to correctly show the original file path when renaming imported files to .bak format. Previously, the log message would incorrectly show the backup path for both the "from" and "to" names, making it difficult to trace which original file was processed.

  • Bug Fix Corrected logging for file rename operations

    Fixed logging messages during import file backup operations to display the correct original filename before the rename. Previously, the log would incorrectly show the new backup filename in both the "before" and "after" positions.

  • Bug Fix Missing store mappings are now auto-repaired on every startup

    If you previously had stores that weren't importing correctly, they will be automatically fixed the next time you open Margin Master.

  • Bug Fix Repair Store Manager display on open

    The Store Manager screen now shows correct vendor assignments after a format change, even before running another import.

  • Bug Fix Store mapping runs before imports and rebuilds

    Store numbers will now be correctly matched during imports, fixing issues where items might have been assigned to the wrong store location.

  • Bug Fix Automatic cleanup of existing duplicate store rows

    Any duplicate store rows that were previously created will be automatically cleaned up the next time you open the Store Manager.

  • Bug Fix Automatic repair of existing store records

    Existing stores with blank or invisible store numbers will be automatically fixed the next time you start Margin Master.

  • Bug Fix Repair existing stores with invisible store numbers

    Any existing stores that appeared blank in the Store Manager will now show readable store numbers after the next application restart.

  • Bug Fix Active stores count now excludes "not found" stores

    The store count at the top now shows a more accurate number by excluding stores that no longer exist in your POS system.

  • Bug Fix Removed confusing debug simulation messages

    Fixed an issue where the import progress would show store numbers being processed even when no actual import was happening.

  • Bug Fix MySQL zero-date rows now imported during full re-imports

    Full re-imports from MySQL Compass will now include all products, even those with invalid date stamps.

  • Bug Fix Auto-correction of legacy corrupted store numbers in Data Aging view

    If your Data Aging screen previously showed incorrect store numbers, it will now automatically correct itself by looking at your actual store data.

  • Bug Fix Added one-time repair for existing duplicate store entries

    A one-time automatic cleanup now runs on Store Manager initialization to soft-delete any existing StoreManagerInfo rows with invalid ordinal values above 255 (artifacts created by the previous bug). This repair is idempotent and will only remove the erroneous duplicates, preserving the legitimate store entries. Store 6484 had 7 such duplicate rows that have now been identified and will be cleaned up.

  • Bug Fix Prevented re-introduction of digit store character bug

    Added 121 regression tests that lock in the correct handling of store characters, especially digit characters like '1', '2', '9'. The tests verify that digit store character '1' is always stored as ordinal "49" (its ASCII code and MySQL ORD() value), never as "1". This prevents the MM-1272 bug from being re-introduced where the character was mistakenly stored as its numeric face value, causing the import filter to compare against the wrong value and pull zero rows.

  • Bug Fix Export-to-file handles locked files gracefully

    If you try to export pricing data while the output file is still open in Notepad or Excel, you'll now see a helpful message asking you to close the file instead of an error.

  • Bug Fix Ensure Compass_IN table exists during MySQL import

    The MySQL Compass import process now proactively creates the Compass_IN table if it doesn't exist, rather than failing with an error. This prevents import failures on fresh stores or after database resets where the table hasn't been created yet. The table creation is idempotent and safe to run multiple times.

  • Bug Fix Store reconciliation creating duplicate entries for special characters

    Special-character stores will no longer appear twice in the Store Manager with one entry showing the symbol and another showing a number.

  • Bug Fix Import history preservation for non-imported stores

    The Data Aging screen will now show correct import history for all stores, even when you only import some of them.

  • Bug Fix Import history preserved for non-imported stores

    Previously imported stores now remain visible in the Data Aging View even when you perform a partial import of different stores.

  • Bug Fix Improved discontinued catalog item cleanup performance

    The cleanup of discontinued catalog items during import is now much faster and won't fail with timeout errors on slower systems.

  • Bug Fix Added orphaned manual catalog item purge for multi-store systems

    Manual catalog items for unconfigured stores are now automatically removed, speeding up imports by skipping items that can't be used.

  • Bug Fix RSC assignment is backfilled without overwriting existing values

    If you've already manually assigned an RSC to a store, this fix won't change it—it only fills in missing RSC assignments.

  • Bug Fix Rebuild entry state hardening

    When the user chooses to rebuild all data after a New Product Import, the application now ensures the splash screen is fully closed before starting the rebuild operation. This prevents competing splash screen owners from causing UI issues during the lengthy rebuild process.

  • Bug Fix Bulk merge operations no longer leave orphaned records

    Previously, the bulk merge operation only inserted or updated records, meaning items deleted from Epicor would remain in Margin Master indefinitely. The new reconciliation step solves this by explicitly identifying and removing records that no longer exist in the source system.

  • Bug Fix Pre-create Compass_IN and Compass_INX tables before import

    Import Manager now ensures Compass_IN and Compass_INX tables exist before starting the store processing loop. Previously, if all stores returned zero updates, these tables would never be created, causing downstream errors when the Main Table tried to query them.

  • Bug Fix Compass tables now pre-created before import

    The pricing grid will now properly initialize even when there are no recent product updates from MySQL Compass.

  • Bug Fix Removed manual CSV conversion requirement for CounterWorks

    CounterWorks users no longer need to manually prepare files before importing—just use the file directly from your POS system.

  • Bug Fix Counterworks deduplication now includes STORE field

    Updated the deduplication logic in the finalization SQL to remove duplicates based on both SKU and STORE instead of just PARTNO, ensuring proper handling of multi-store environments where the same SKU may exist in different stores.

  • Bug Fix Improved duplicate detection for CounterWorks imports

    Updated the duplicate removal logic to check both SKU and STORE fields instead of only PARTNO, ensuring accurate deduplication when the same product appears multiple times in multi-store configurations.

  • Bug Fix Missing store data visibility in Data Aging

    Store data that was previously hidden due to missing import records is now visible in the Data Aging screen.

  • Bug Fix Improved fallback logic for missing import data

    The Data Aging screen is smarter about finding and displaying your store data when import tracking is incomplete.

  • Bug Fix Eliminated repeated timeout delays during import strategy execution

    Import operations will no longer freeze repeatedly when MySQL Compass is unavailable.

  • Bug Fix Fixed buttons not updating immediately after validation

    Buttons in the wizard now enable immediately when conditions are met, instead of requiring you to click or move your mouse to trigger the update.

  • Bug Fix Eliminated startup errors on fresh installations

    Starting Margin Master for the first time or launching multiple instances at once no longer generates error reports.

  • Bug Fix Simplified manual catalog cleanup logic

    Removed vendor-specific cleanup queries for Do-It-Best, Ace Hardware, and Emery Jensen that checked if items existed in store import data. This logic is now handled consistently during the import process for BisTrack, and age-based expiration handles all other cases.

  • Bug Fix Fixed Store='ALL' catalog items in BisTrack multi-store imports

    Added automatic purge of Store='ALL' ManualCatalogItems before BisTrack multi-store catalog re-import to prevent invalid fan-out. BisTrack imports own their SKU/Store data from POS CSV files, so Store='ALL' entries are invalid in this context and could cause incorrect data distribution across stores.

  • Bug Fix Automatic purge of invalid manual catalog items for BisTrack

    Manual catalog items are now properly scoped to individual stores during BisTrack imports instead of incorrectly applying to all stores.

  • Bug Fix Mi9 index creation idempotency

    If an Mi9 import is interrupted and restarted, it will continue successfully instead of failing on duplicate indexes.

  • Bug Fix Composite primary key handling in bulk sync operations

    RowVersionTableSync now correctly handles tables with multi-column primary keys by relying on the database constraint rather than the single-column AutoMapKeyName parameter. This prevents bulk merge operations from failing on tables with composite keys.

  • Bug Fix Corrected average cost setting lookup

    Fixed a build error where the "Use Average Cost" application setting was being retrieved using an obsolete method call. Now uses the standard GetValue<bool> pattern with the correct ApplicationSettingKey.

  • Bug Fix Corrected average cost setting lookup causing build failure

    Fixed a method call error where GetUseAverageCost() was called incorrectly. Changed to use the proper GetValue<bool> method with the UseAverageCost application setting key, resolving a compilation error in the Epicor import cost calculation logic.

  • Bug Fix Network scan button now functional

    The "Scan Network" button on the MySQL/Compass tab now works properly to discover MySQL servers on your local network.

  • Bug Fix Ace Hardware zone pricing now applies store-specific pricing correctly

    Ace Hardware zone pricing will now correctly update retail, level 1, and level 2 prices based on your store's assigned pricing zone instead of being skipped.

  • Bug Fix Removed silent fallback for MySQL connection failures

    If the MySQL Compass connection isn't available when you try to refresh store data, you'll now see a clear error message instead of the system silently using old data.

  • Bug Fix Store Manager Rescan requires active MySQL connection

    Rescanning stores now requires an active connection to your MySQL Compass database to ensure you get current data.

  • Bug Fix Delete button now functions correctly in store grid

    Corrected a CommandParameter binding issue that prevented the delete button from working properly in the store manager grid.

  • Bug Fix Changed store reconciliation to query live MySQL instead of local cache

    The Store Manager will now correctly detect available stores even after a failed import, allowing recovery from configuration errors.

  • Bug Fix Extended store matching for numeric vendor store numbers

    Generalized the store-skipping logic to match both single-character Epicor store numbers and multi-digit vendor store numbers (such as Do-It-Best numeric stores like "1818"). This ensures zone, MSU, and INX processing steps correctly skip non-imported stores regardless of store number format.

  • Bug Fix Accurate status reporting when yard doesn't match

    If you specify a yard that doesn't exist in the database, items will now clearly show "No matching store/yard" instead of incorrectly appearing as if they already exist.

  • Bug Fix Accurate row deduplication in bulk operations

    The bulk insert uses ROW_NUMBER deduplication on the catalog side to handle cases where multiple catalog records exist for the same SKU. This reproduces the single-row selection behavior of the per-item path, ensuring idempotency—re-running the operation inserts zero additional rows and prevents duplicate (SKU, StoreNumber) combinations in the main tables.

  • Bug Fix Changed duplicate detection to use HashSet for better performance

    Improved the efficiency of duplicate record detection during imports by switching from List to HashSet, which provides faster lookups on large datasets.

  • Bug Fix Bypass CSV validation for Excel files

    Excel imports no longer fail with "invalid file format" errors during the validation step.

  • Bug Fix Excel import validation bypass

    Excel import files are now handled correctly without false validation errors.

  • Bug Fix MMVendorData table/view conflict resolved

    Fixed a database conflict where legacy sync code attempted to create an MMVendorData TABLE even when a modern MMVendorData VIEW already existed (created by the modern sync's catalog builder). The legacy sync now detects the VIEW and skips the conflicting CREATE TABLE operation, allowing both sync systems to coexist gracefully during the transition period.

  • Bug Fix Resolved BisTrack import progress stuck at "1 of 20"

    BisTrack imports no longer get stuck at "1 of 20" files—you'll now see progress as each store file is processed.

  • Bug Fix Corrected store number sorting in Data Aging screen

    Store numbers in the Data Aging screen now appear in correct numeric order (1, 2, 3... 10, 11) instead of alphabetic order.

  • Bug Fix Fixed store number sorting in Data Aging screen

    Store numbers in the Data Aging screen now appear in the correct numerical order.

  • Bug Fix Database migration NULL handling

    Database updates that make fields required will now complete successfully even if some existing records have blank values.

  • Bug Fix Null price column handling in One-Click pricing analysis

    One-Click pricing analysis will no longer crash when some items have missing price data.

  • Bug Fix Store exclusion format now consistent across POS systems

    Updated the StoresToExclude setting to use pipe-delimited format for Epicor systems (matching other POS systems) instead of the legacy concatenated character format. This supports both single-character store codes and multi-digit vendor store numbers in the exclusion list. The setter now always writes pipe-delimited format regardless of POS system type.

  • Bug Fix Fixed unmapped store sentinel value handling in Store Manager

    The discovery sentinel value "99999" is now correctly recognized as indicating an unmapped store rather than being treated as a vendor store number. This ensures unmapped stores appear properly in the Store Manager interface awaiting assignment.

  • Bug Fix Improved error handling in INX processing

    Added error logging to the ProcessINXItemsAsync catch block that was previously empty, ensuring exceptions during INX processing are now captured in logs with store context.

  • Bug Fix Epicor/MySQL Compass import now satisfies database constraints

    Importing data from Epicor or MySQL Compass POS systems will no longer fail with database constraint errors.

  • Bug Fix Multi-RSC detection logic

    Stores with multiple distribution centers now have their RSC assignments detected automatically.

  • Cloud Sync Improved store identification logic

    Updated the cloud sync key generation in Store Manager to use a new CloudPosKey method that selects the appropriate identifier format based on POS system: Epicor stores use their character ordinal value (PosStoreCharOrdinal), while all other systems use the standard POS store number. This ensures consistent identification across save and retrieval operations.

  • Cloud Sync Improved store matching reliability

    Both saving and loading cloud store settings now use the same canonical key logic, ensuring that settings saved to the cloud will be correctly matched and retrieved during sync operations.

  • Cloud Sync Cloud store settings now normalize special-character keys

    Modified CloudPosKey generation and ApplyCloudStoreSettings to normalize PosStoreKey values greater than 255 back to Windows-1252 bytes. This ensures cloud-synced settings created by older builds (which stored code points) still match local stores after the fix, and the next save automatically heals the cloud row.

  • Cloud Sync Cloud settings normalized for special-character stores

    Enhanced cloud synchronization to normalize special-character store keys when saving and loading organization POS store settings. Keys stored as Unicode code points by older versions are automatically converted to Windows-1252 byte values, ensuring consistent cloud-to-local matching after upgrade.

  • Data Import Automatic SKU reconciliation after sync

    When you delete items from your Epicor system, those deletions will now automatically appear in Margin Master after the next data import completes.

  • Data Import Falcon POS Excel import with direct bulk loading

    When importing Falcon POS data, you'll now see detailed progress updates showing how many rows have been imported and the percentage complete.

  • Data Import Completed search index for POS import documentation
  • Data Import Direct Excel import for CounterWorks POS

    You can now drag CounterWorks Excel files directly into the Import Manager without converting them to CSV first.

  • Data Import Direct Excel import for CounterWorks POS

    You can now import CounterWorks data files directly without opening Excel and converting them to CSV first. Just select the .xlsx file in the Import Manager.

  • Data Import CounterWorks Excel file support

    When importing CounterWorks data through the Import Manager, you can now select Excel files (.xlsx) directly instead of having to save them as CSV files first.

  • Data Import Pre-sync incomplete data detection and recovery

    If your local inventory data is incomplete, the system will now automatically detect this before importing and start fresh to ensure all items are present.

  • Data Import Per-file merge pipeline for BisTrack imports

    When importing BisTrack data, each store's file is now processed individually with visible progress, and the system correctly handles items that have been added, changed, or removed since the last import.

  • Data Import Per-file merge strategy for BisTrack batch imports

    When you import multiple BisTrack store files, each file now processes individually with visible progress, making it easier to track which stores have been imported.

  • Data Import Added database index to BisTrack stage table

    Created a nonclustered index on Store and SKU columns in the BisTrack staging table. This index improves query performance during the import process, particularly when matching and updating products across multiple store locations with large catalogs.

  • Data Import Cross-file batch processing with detailed progress tracking

    BisTrack imports now accumulate rows across all CSV files and flush to the database in 50,000-row batches, with progress percentages that accurately reflect the current stage (reading files 0-85%, inserting rows 85-95%, cleanup 95-100%). This replaces the previous per-file database insertion approach that caused the progress dialog to freeze during large operations.

  • Data Import BisTrack preload table now stores numbers as typed decimals
  • Data Import Phase 2 builds all stores from typed preload data

    When importing data for multiple stores, Margin Master now processes all store files in one batch, then builds each store's tables from shared staging data instead of re-reading each file separately.

  • Data Import Improved assembly reference validation

    Added AssemblyName.GetAssemblyName() pre-validation check before creating Roslyn metadata references. This ensures only valid .NET assemblies are loaded during the dynamic compilation phase of import file matching, preventing lazy-load errors that would occur later during code emission.

  • Data Import Optimized Excel cell reading for faster imports

    The DevExpress Excel importer now reads cells directly into DataTables instead of using the double-copy DataTableExporter pattern, reducing memory overhead and improving performance for large Excel files. Progress is logged every 50,000 rows during the read phase.

  • Data Import Import tracking now captures mainTable rebuild results

    After MySQL Compass imports complete and the main pricing tables are rebuilt for each store, the system records the actual record counts from each store's mainTable (pattern: Epicor_{StoreNumber}_mainTable) into import history. This happens before the store mapping information is cleared, ensuring accurate tracking of what was successfully imported.

  • Data Import Import history tracking improved for multi-store MySQL Compass setups

    Import processing history is now recorded for each individual store location in MySQL Compass Epicor configurations. The system tracks record counts from each store's mainTable (named Epicor_{StoreNumber}_mainTable) and saves them to the ImportProcessing table after the import completes, ensuring accurate reporting in the Data Aging View.

  • Data Import Chunked bulk import with automatic retry

    Large Excel imports are now more reliable and will automatically retry if temporary errors occur, reducing the need to restart failed imports from scratch.

  • Data Import CounterWorks column header configuration

    Added JSON-formatted column header specification for Excel BCP import, defining all 22 expected columns including LINCODE, PARTNO, COST, DESCR, department fields (DM00-DM11), MULT, ORDQTY, PRCB, QOH, SUBLINE, and VENNO. This ensures Excel files are parsed correctly during bulk import operations.

  • Data Import Enhanced Excel import service to support column transformations

    Extended the Excel BCP import process to apply column mappings defined by each POS system's layout class. The service now supports renaming columns (e.g., PARTNO→SKU), dropping unwanted columns (e.g., VENNO), and adding new columns with default values (e.g., STORE='0') before performing the SqlBulkCopy operation.

  • Data Import Enhanced Excel import with flexible column mapping

    Added a new ExcelColumnMapping system that allows POS-specific import definitions to rename, drop, or add columns during Excel imports. This makes the import pipeline more flexible and handles cases where Excel column names differ from the expected database schema.

  • Data Import Added import completeness validation

    Post-import validation now compares the number of imported SKUs against the expected count from MySQL and logs an error if the imported count is less than 10% of expected. This helps detect and diagnose incomplete imports early, with guidance pointing to SQL Express upgrade scenarios as a common cause.

  • Data Import Automated spreadsheet processing workflow

    After import completes, processed Excel files are automatically moved to an "Imported" subfolder, and a detailed log file is created in the "Logs" subfolder showing which SKUs were imported and which were invalid.

  • Data Import Post-sync completeness verification

    After each inventory import completes, the system verifies that all your items were successfully imported and alerts support if anything is missing.

  • Data Import Added single-store detection for POS systems

    Introduced a new IsSingleStorePOS property to identify POS systems whose export format has no store column and hardcodes all rows to StoreNumber='0'. Currently applies to CounterWorks, with the infrastructure in place to easily flag other single-store systems if needed.

  • Data Import Improved import history ranking accuracy

    Each store now shows the date when inventory data was actually last imported, not when an import was attempted but failed.

  • Data Import Persistent BisTrack data table survives across import sessions

    BisTrack pricing data is now preserved between imports, so you only update what's changed rather than reloading everything each time.

  • Data Import Improved data quality for BisTrack imports

    Import validation logic now checks trimmed value length rather than just checking for null/empty, ensuring that CSV fields containing only whitespace characters don't populate database fields with meaningless space characters.

  • Data Import New two-phase BisTrack multi-store pipeline
  • Data Import DIB6828 format support with typed preload

    BisTrack DIB6828 export files are now fully supported — Margin Master automatically recognizes and imports them without manual configuration.

  • Data Import Store information logged during New Product Form import

    The import summary will now show which store the products are being added to when using the new format.

  • Data Import Column name cache now resets between files

    The Mi9 import service now clears its column index cache when processing each new file, preventing column position mismatches when importing multiple files with different structures in sequence.

  • Data Import Improved store designation handling for Epicor

    Added new helper method ToDisplayString() that intelligently formats store characters based on whether they're printable or control characters, and updated ToOrdinal() to correctly handle cases where the display value is already showing an ordinal number.

  • Data Import Improved messaging for unassigned store characters

    The warning message when new stores are found is now clearer about what you need to do next and where to find the settings.

  • Data Import Improved cost calculation logic for multi-store aggregation

    Changed the cost aggregation formula from filtering by "OnHand > 0" to using NULLIF to exclude only invalid zero-cost entries. This ensures that stores with valid cost data contribute to the average even when they currently have no inventory on hand. The original formulas are preserved as SQL comments for reference.

  • Data Import Improved store mapping cleanup during auto-detection

    Refined the automatic store mapping logic to properly remove obsolete raw-byte store entries when their ASCII counterparts are detected, preventing duplicate store rows after Epicor system migrations.

  • Data Import Auto-mapping distinguishes legacy from active raw-byte stores

    Enhanced the Epicor FTP auto-mapping logic to correctly differentiate between raw-byte ordinal rows that are legacy/pre-migration duplicates (which should be soft-deleted) versus stores that genuinely use raw-byte ordinals (which should be normalized and retained). This prevents accidental deletion of valid store configurations while still cleaning up obsolete duplicates.

  • Data Import Enhanced progress tracking for single-table and multi-table imports

    Both single-table and multi-table MySQL Compass import modes now pass store index and total store count through the import pipeline to enable accurate overall progress calculation. The progress bar updates incrementally as each block of inventory items is processed within each store.

  • Data Import Updated reality check and incremental sync queries for MySQL Compass

    Modified pre-sync SKU count verification and incremental update queries in the Import Manager to use corrected store identifier matching. This ensures the application can accurately detect partial imports and properly synchronize inventory changes for affected stores.

  • Data Import Improved store data reconciliation accuracy

    Enhanced the SKU reconciliation and deleted item detection processes to use the corrected character encoding, ensuring that the pre-sync reality check (which compares local SKU counts to MySQL counts) accurately identifies when a full reimport is needed.

  • Data Import New CSV parser handles Falcon's comma-delimited format

    The import now correctly handles special characters and formatting in product descriptions and pricing, preventing data corruption or missing items.

  • Data Import Store matching standardized on Windows-1252 byte values

    Standardized all Epicor store matching logic to use the MySQL ORD / Windows-1252 byte value (1-255) consistently. Updated all SQL merge scripts, import queries, deleted-item reconciliation, and store filters to use ASCII() in T-SQL instead of UNICODE(). Parameterized all MySQL queries that previously interpolated the store character directly into ORD() expressions to prevent SQL injection and ensure correct key binding.

  • Data Import Normalize legacy POS store character settings

    If you upgraded from an older version of Margin Master, your POS store matching settings are automatically fixed to work correctly with the current version.

  • Data Import Added optional trailing field to RockSolid mapping

    Added an optional `TrailingField` to the RockSolid data mapping to handle edge cases where extra columns appear at the end of exported data files, preventing parsing errors that could cause incomplete imports.

  • Data Import Updated Falcon import mappings for Excel format

    Falcon import configuration now expects Excel column headers ("Stock #", "Warehouse #", "On Hand") instead of CSV headers, with updated SQL scripts to handle the Excel BCP format. The import scripts now rename columns after bulk insert (Stock→SKU, Warehouse→StoreNumber) and use TRY_CONVERT for safer decimal conversions. Search pattern changed from "MM*.csv" to "*.xlsx".

  • Data Import Updated Falcon import mapping and SQL scripts

    Updated Falcon field mapping to match new Excel column structure: Stock # maps to SKU, Warehouse # to StoreNumber. Revised SQL finalization scripts to handle column renaming, remove duplicate records by SKU+Store, and properly trim leading zeros from warehouse numbers. Updated search pattern from "MM*.csv" to "*.xlsx" to match new file format.

  • Data Import Updated CounterWorks column mapping

    The CounterWorks import now correctly handles the native Excel format with 22 columns, mapping PARTNO to SKU, defaulting STORE to '0' for single-store operations, and properly processing the 12 department margin fields (DM00-DM11) along with cost, description, quantity, and vendor data.

  • Data Import Automatic cleanup of manual catalog items after BisTrack merge

    Manual catalog entries are automatically removed when those items appear in your BisTrack data, preventing duplicate or conflicting records.

  • Data Import Smart merge logic for incremental updates

    BisTrack imports now intelligently update only the data that has changed, keeping your pricing and inventory information in sync with your POS system while preserving records from other stores.

  • Data Import Simplified BisTrack data cleanup
  • Data Import ImportAsync short-circuits after Phase 2 completion

    Once `PostPreloadBuildAllStoresAsync` completes, subsequent `ImportAsync` calls return immediately without executing SQL. The per-file loop still runs to rename processed files to backup names, but all database work is finished. This eliminates ~100 redundant database operations across a typical 20-store import batch.

  • Data Import Unified DIB1040, MAP1, and MAP2 handler

    MAP1 and MAP2 store files now import using the same fast batch process as standard BisTrack files.

  • Data Import Import handler now reports successfully imported stores

    All three BisTrack import handlers (DIB1040, DIB6828, and DirectConnect) now expose which store numbers were successfully imported through a new ImportedStores property. This enables downstream validation and cleanup workflows to ensure data consistency across multi-store BisTrack installations.

  • Data Import Backward compatibility with existing New Product Form files

    New Product Form spreadsheets without the Yard # column (legacy format) continue to be processed normally, ensuring no disruption to existing workflows.

  • Data Import Do-It-Best taxonomy fields now populated during store rebuild

    The vendor data temp table now conditionally populates all eight DIB taxonomy fields (4 ID fields and 4 description fields) from DIB_Sku_4ClassificationLevel if that table exists in the database, ensuring complete catalog metadata is available in the main pricing table.

  • Data Import Epicor store conversions now correctly handle all byte values

    The data import process now correctly converts stored ordinal values back to single-character strings when comparing against incoming Epicor data, ensuring that all store codes—including those with byte values above 127—are properly matched and converted during import. Both the FTP-based Epicor import and MySQL Compass Epicor import services apply this conversion.

  • Data Import Improved Epicor import reliability for multi-store configurations

    Store number conversion during Epicor import now correctly handles the new ordinal storage format, ensuring that mapped POS store codes are accurately translated to vendor store numbers regardless of character type.

  • Data Import Duplicate store detection prevents re-adding existing entries

    Before inserting new store entries into StoreManagerInfo, the import process now queries for existing entries with matching PosStoreCharOrdinal values to avoid creating duplicates. Only truly new store characters are inserted into the database.

  • Data Import Normalize store numbers during Epicor data import

    When importing Epicor POS data and auto-creating new store records, raw-byte ordinals now generate readable PosStoreNumber values using the numeric ordinal instead of the control character.

  • Data Import New Epicor store creation handles raw-byte ordinals

    Updated the initial store creation process during Epicor MySQL Compass imports to properly handle raw-byte ordinals by storing the numeric ordinal value as a readable string, ensuring stores are immediately visible after first import.

  • Data Import Exclusion of not-found stores from import processing

    Stores marked as "Not Found" are automatically skipped during imports to prevent errors. If a store comes back in future imports, it will automatically be reactivated.

  • Data Import Improved Compass_IN cleanup to handle both MySQL character encodings

    When removing data for deleted or excluded stores, the cleanup process now matches both possible encodings of the store character in Compass_IN: the raw Windows-1252 byte and the UTF-8 display glyph. This ensures that data is deleted correctly regardless of whether the MySQL database stored the character as a single byte or as its UTF-8 equivalent, preventing accidental deletion of the wrong store's data.

  • Data Import Live MySQL store reconciliation before import

    The import process now validates store connections against live Epicor data each time, ensuring stores aren't incorrectly marked as missing.

  • Data Import Import Manager now selects most recent file when multiple formats present

    If you have both old and new export files in your import folder, Margin Master will automatically use the newest one.

  • Data Import Automatic repair of existing code-point artifacts

    Added one-time repair logic that rewrites StoreManagerInfo rows with PosStoreCharOrdinal > 255 back to the correct Windows-1252 byte value (e.g., 8225 → 135 for ‡). This preserves the mapped VendorStoreNumber so special-character stores import correctly after the fix. Cloud sync settings are also normalized on load and save, ensuring cloud PosStoreKey values are automatically corrected from code points to bytes.

  • Data Import Automatic repair of legacy special-character store mappings

    When you first open Margin Master after this update, any special-character stores that weren't working will be automatically fixed to load data correctly.

  • Data Import Repair persisted store matchup configuration

    After correcting a drifted store identifier, the system now updates the stored matchup configuration in the database to ensure the correct vendor store number association persists across future imports and prevents the corruption from reoccurring.

  • Data Import Added diagnostic text file backup for RockSolid

    While RockSolid now imports directly from Access to SQL, the intermediate RockSolidData.txt file is still written as a diagnostic backup for troubleshooting and compatibility purposes. This file is no longer used in the import pipeline but remains available for review if needed.

  • Data Import DirectConnect imports migrated to handler pattern

    BisTrack DirectConnect imports now show consistent progress messages and work the same way as file imports.

  • User Interface Catalog availability date display

    You can now see when the most recent vendor catalog became available in the "Catalog Available" field.

  • User Interface Help button repositioned in Import Manager

    The help button is now located right next to the "Import Path" field instead of the top corner, making it easier to find when you need help with imports.

  • User Interface Sync history table display on Data Aging View

    The Data Aging screen now shows a detailed list of vendor data tables with the number of records and last sync date for each, including Ace Catalog, Ace Zone Pricing, DIB Catalog, Planograms, and other vendor data sources.

  • User Interface Sync history table added to Data Aging View

    You can now see exactly when each vendor catalog (Ace, DIB, etc.) was last updated and how many items were downloaded.

  • User Interface POS import reference documentation

    The Help menu now includes detailed guides for your specific POS system showing exactly how to export files, which fields are imported, and how to troubleshoot common import issues.

  • User Interface MI9 data pipeline documentation

    Added detailed reference documentation to the Help system explaining the complete MI9 import-to-main-table pipeline. The guide walks through how MI9 export files (MM*.txt) are imported, how stores are grouped into teams (Core, NonCore, etc.), how per-store data is aggregated into team-level pricing tables, and how Ace catalog enrichment and calculated fields are applied. Includes field mapping tables for all 75+ import columns, aggregation logic explanations, and common troubleshooting scenarios.

  • User Interface Dialog windows now auto-size to content

    Import dialogs now appear smaller and better fitted to their content.

  • User Interface Enhanced bulk SKU input dialog

    When adding items by SKU, you'll now see an example showing how to format your SKU list with commas or spaces.

  • User Interface Help button added to Add from Catalog dialog

    Click the help button next to the search box to learn how to add items from the catalog, including how to import many items at once from Excel files or pasted lists.

  • User Interface Dynamic POS settings tab visibility

    POS-specific settings tabs (like Connections for Epicor, SpruceNet/RockSolid, NCR Counterpoint, and Bistrack) now appear or disappear right away when you change the POS system dropdown, making it faster to configure your system.

  • User Interface Dynamic POS configuration tabs in Settings

    The Settings screen now shows only the configuration tabs that apply to your selected POS system, making it easier to find the settings you need.

  • User Interface New product import results grid

    When you import new products from spreadsheets, you'll now see all results in one organized grid showing which SKUs were added, which already existed, and which weren't found in the catalog, instead of multiple pop-up messages.

  • User Interface Filter out zero-record imports from history

    You'll now see only successful imports in the import history — failed imports with no records won't appear in the list anymore.

  • User Interface Import Exclude moved to dedicated section

    The "Exclude Stores" setting now appears in its own section in Settings, making it easier to locate.

  • User Interface Import Exclude moved to dedicated section

    The Import Exclude setting is now easier to find in its own section in Settings.

  • User Interface Inline connection test results panel

    When you test your MySQL connection, detailed results now stay on screen showing which server you connected to, how many stores were found, and SKU counts for each store.

  • User Interface Unified Store Manager routing for all Epicor configurations

    All Epicor users now access the same modern store management screen from the Tools menu, making setup more consistent.

  • User Interface Store Grouping section hidden for all Epicor stores

    If you use Epicor, you'll now see a message in Options reminding you to manage store groups in Store Manager (under Tools menu) instead of on the Options screen.

  • User Interface Store grouping UI hidden for Epicor POS systems

    If you use Epicor, you'll no longer see the Store Grouping section in Settings. Instead, use Tools → Store Manager to assign stores to groups.

  • User Interface Auto-select Backup Files tab when no imports available

    If there are no new files to import, the screen will now automatically show you the backup files tab instead of an empty list.

  • User Interface Simplified POS Store column display

    Store numbers are now displayed more simply in the POS Store column, making them easier to read at a glance.

  • User Interface New deletion reason dialog for active POS stores

    When removing a store that's still in your Epicor system, you'll see a dialog asking you to pick why you're removing it: reassigned store number, closed, new ownership, not retail, or other reason.

  • User Interface Enhanced progress display for MySQL Compass imports

    When importing MySQL Compass data, you'll now see more detailed progress messages showing exactly what step is running and which store is being processed, making it easier to understand what's happening during lengthy imports.

  • User Interface Live progress during cost-field synchronization

    You'll now see which table is being processed during the cost-field sync step after importing data.

  • User Interface Live progress tracking during index rebuild

    When rebuilding indexes after an import, you'll see which table is currently being processed and how many remain, so you know the operation is still running.

  • User Interface Dynamic column headers in store import picker

    Column headers in the store picker now show your actual POS system name (like "Epicor" or "RockSolid") and vendor name (like "Ace" or "Orgill") instead of generic text.

  • User Interface Consolidated Epicor settings into single tab

    All Epicor connection settings are now on a single "Epicor" tab in the Options window. Check or uncheck "Connect via MySQL / Compass" to switch between the two connection modes.

  • User Interface Merge Epicor connection tabs into single "Epicor" tab

    Epicor users now find all connection settings under Options → Epicor. Toggle between MySQL/Compass and direct FTP by checking or unchecking "Connect via MySQL / Compass" at the top of the tab.

  • User Interface Removed obsolete Compass configuration checkboxes

    The Compass Options section in Epicor settings is now simpler, showing only the options you need to configure manually.

  • User Interface Removed redundant Compass import options from Epicor settings

    The Epicor settings screen now shows only the options you can actually change, making it clearer and less cluttered.

  • User Interface Added informational banner to Store Manager for unused vendor store numbers

    If you're using Epicor and see a new yellow warning at the top of Store Manager, it means the vendor store numbers you enter in that column aren't being used—your imports use the Epicor store number instead. Contact RetailerSoft before changing store mapping settings, as this affects how saved pricing strategies are matched to stores.

  • User Interface Warning notice for inactive vendor store mapping

    If you're using Epicor without store mapping enabled, you'll now see a warning that explains the vendor store numbers you enter aren't used during import. Your stores are identified by Epicor's own store numbers instead.

  • User Interface Epicor tab layout optimized for small screens

    The Epicor settings tab now displays all options on one screen on smaller monitors, making it easier to configure without scrolling.

  • User Interface Import history section added

    A new Import History section shows the latest POS file import for each store, including how many records were imported and when.

  • User Interface Streamlined Import Manager help access

    Consolidated two separate help/info buttons into a single, clearly positioned help button that provides access to data import documentation without cluttering the interface.

  • User Interface Removed redundant info button

    An older info button next to the Import Path field has been removed, as its functionality is now replaced by the repositioned help button that links to comprehensive import documentation.

  • User Interface Added friendly descriptions for Order Indicator codes

    When filtering by Order Indicator, you'll now see helpful descriptions like "Stock/Order Through - T" instead of just "T".

  • User Interface Improved loading message for pre-compiled import types

    The loading screen now shows a clearer message when searching for import files.

  • User Interface Improved Import Manager splash screen messaging

    The Import Manager now shows clearer status messages while loading, making it easier to understand what the application is doing.

  • User Interface Adaptive column headers in Data Aging screen

    The Data Aging screen now adjusts its column labels to match the type of data being shown.

  • User Interface Dynamic column headers in Data Aging import history

    The Data Aging screen adjusts what it shows based on what information is available.

  • User Interface Added instructional text to bulk SKU input dialog

    When entering multiple SKUs at once, you'll now see an example showing the correct format.

  • User Interface Improved column picker dialog

    When importing files with multiple columns, the column selection dialog is now clearer about what it's asking you to choose.

  • User Interface Conditional menu visibility for store-specific feature

    The new import menu option is only visible to Do it Best stores that have store number 1372 in their organization, ensuring the feature is accessible only where it's needed.

  • User Interface Added progress feedback during catalog field updates

    During imports, you'll now see status messages explaining what's happening even after the progress bar completes, so you know the system is still working.

  • User Interface Added progress feedback during catalog operations

    You'll now see messages explaining what's happening during catalog imports instead of just a blank loading screen.

  • User Interface Enhanced progress reporting for BisTrack imports

    The progress bar during BisTrack imports now shows accurate percentages and clearer messages about what step is currently running.

  • User Interface Removed "All" option from catalog item store selection for BisTrack

    When adding catalog items in BisTrack, you must now choose a specific store number instead of "All," since each BisTrack store has its own pricing.

  • User Interface Store mapping scan grid now shows both character and numeric code

    When you scan an Epicor INDecoded file, the store mapping grid now shows both the character (when printable) and its numeric code, making it easier to identify and map unusual store codes.

  • User Interface Enhanced store mapping grid with ordinal display

    When scanning an INDecoded file, you'll now see clearer labels for each store code, including the numeric value in parentheses.

  • User Interface Store Match Up dialog now handles POS system differences correctly

    The Store Match Up screen now correctly handles store numbers based on your POS system type, preventing data corruption when saving mappings.

  • User Interface Store Match-Up dialog now adapts encoding based on POS system type

    Added POS system type detection to the Store Match-Up screen (POSStoreNumberMatchUpViewModel) to conditionally apply character-to-ordinal encoding only when using Epicor, ensuring other systems handle store numbers as literal strings throughout the match-up workflow.

  • User Interface Loading overlay during connection test

    You'll now see a clear "Testing MySQL Connection..." overlay with a progress bar while the connection test runs.

  • User Interface Visual indicator for unmapped stores in Zone Assignment

    Stores that aren't set up in your point-of-sale system now appear crossed out in gray, with a message explaining why you can't change their zone pricing.

  • User Interface Updated menu text for Epicor store management

    The menu item text for Epicor users now reads "Manage Epicor POS/Vendor Store Info" (changed from "POS/Vendor Store MatchUp") to better reflect the expanded functionality of the new Store Manager, which handles store information beyond just store number matching.

  • User Interface Standardized Epicor menu visibility rules

    Updated the logic that controls which store configuration menu items are visible to Epicor users, ensuring consistency across all menu entry points by checking the actual POS system type rather than a database service flag.

  • User Interface Updated warning dialog for unmapped Epicor stores

    The warning message for new stores is now clearer about what action you need to take next.

  • User Interface Removed unnecessary Store Manager columns

    The Store Manager screen now focuses only on the information needed for store mapping, with unnecessary columns removed.

  • User Interface Display readable values for control-character store ordinals

    The POS Store column in the store manager will now show a readable number like "15" instead of appearing blank for stores using low-numbered codes.

  • User Interface Status column added to Store Manager screen

    A new Status column shows which stores need your attention—either because they're missing from Epicor or need their vendor store number assigned.

  • User Interface Status column and cleanup tool in Store Manager

    The Store Manager grid now shows a Status column that tells you which stores need attention. Use Tools → Remove Not Found Stores to clean up stores that are no longer active in your POS system.

  • User Interface Improved delete prevention message for Epicor stores

    The warning message now tells you whether the store would return from MySQL Compass or the INDecoded file, making it clearer why the store was marked Excluded instead of deleted.

  • User Interface Improved Import Manager feedback for multi-store processing

    The import screen now shows which store is being processed out of the total (like "Store 123 [2 of 5]") and what operation is running.

  • User Interface Live progress during managed index rebuild

    The application now shows which table's indexes are being rebuilt and displays a warning that this step can take several minutes, so you know the import hasn't stalled.

  • User Interface Progress indicator for cost field synchronization

    When syncing cost fields after import, you'll see a progress bar and table-by-table updates showing how much work remains.

  • User Interface Simplified store selection dialog

    The store selection window now shows cleaner information: your POS store numbers, vendor store numbers, and when each store was last imported.

  • User Interface Simplified POS store display for Epicor

    Epicor store numbers now display just the character (like "A" or "‡") without extra numbers in parentheses.

  • User Interface Updated Epicor settings help text for clarity

    Changed the Import Options help text on the Epicor settings tab from "POS store numbers are always mapped" to "POS store numbers are mapped" to reflect that store mapping is now optional rather than mandatory.

  • User Interface Improved messaging when no new import files are available

    You'll now get helpful instructions about exporting new files from your POS system when there's nothing new to import.

  • User Interface Added helpful guidance message when no new import files are available

    You'll now see a clear message explaining where your imported files went and what to do next, instead of an empty list or confusing backup files.

  • User Interface Improved splash screen lifecycle during catalog operations

    Changed from debounced (delayed) splash screen hiding to immediate synchronous teardown before modal dialogs. This ensures the splash screen is fully closed before showing results and prevents race conditions where competing splash screen operations interfere with each other across nested message pumps.

  • User Interface Date label clarification

    Date labels now clearly show "Last Synced" for vendor updates and "Last Import" for POS data updates.

  • User Interface Aligned help button with Export to Excel on Manage Pricing Strategies window

    Repositioned the help button to appear next to the Export to Excel button at the top right of the Manage Pricing Strategies screen for better visual alignment and consistency.

  • User Interface Enhanced selection box display formatting

    Added support for displaying alternative text after the main value in selection boxes (AltItemTextAfter property). This allows descriptions to be shown in the format "Code - Description" instead of only "Description - Code", improving flexibility for different field types.

  • User Interface Column picker dialog for Excel imports

    When importing from Excel files with multiple columns, you'll be asked to choose which column contains the SKUs.

  • User Interface Tools menu bar added

    Added a menu bar to the top of the Catalog Add Items dialog with a Tools menu containing Import File and Enter Bulk List options, providing clear access to the new bulk import features.

  • User Interface Enhanced column picker dialog instructions

    When importing files with multiple columns, the dialog now clearly explains why it's asking you to choose a column.

  • User Interface Dialog window sizing improvements

    Configured both dialogs to automatically size to their content, ensuring they display properly regardless of screen resolution or DPI settings.

  • User Interface Help button added to Add Catalog Items dialog

    Click the help button (?) next to the search box to learn how to use the catalog import features.

  • User Interface Optional data rebuild prompt after import

    After importing new products, you'll be asked if you want to rebuild the data now to see the new items in your pricing grid, or you can choose to do it later.

  • User Interface Enhanced Store Matchup screen for Ace Hardware

    Modified the Store Number Matchup screen to load zone data from AceStoreDepartmentZoneRecords on startup and save zone overrides when the user clicks Save. The new columns appear only for Ace Hardware customers and integrate seamlessly with the existing store matching workflow.

  • User Interface Enhanced progress messages during BisTrack import

    Progress dialog now displays specific stage-based messages like "Reading 3/12: store_045.csv", "Inserting 47,500 rows (8/12 files)...", and "Cleaning 245,000 rows across 12 stores..." with matching percentage values, replacing generic "Loading file..." messages.

  • User Interface Reorganized Connections tab layout
  • User Interface Connections tab layout improvements

    Redesigned the Connections tab to use a scrollable layout with reorganized sections: "Epicor FTP Connection", "Server Type", "Import Options", and the new "INDecoded Store Mapping Scanner". Increased design height from 450 to 600 to accommodate the new store mapping grid. Added a StoreCharMapping model to support data-binding for the editable POS store char → vendor store number grid.

  • User Interface Improved visual styling for Import Exclude descriptions

    Description text is now styled with italic font, smaller size (11pt), and gray color to visually distinguish helper text from input fields, improving readability and interface hierarchy.

  • User Interface Hidden redundant Ace Zone Pricing menu for Epicor users

    Epicor users no longer see a separate Ace Zone Pricing menu item since zone pricing is now handled directly in the main Store Manager screen.

  • User Interface Remove Not Found Stores menu option

    You can now quickly remove all stores that are no longer in your Epicor system using the "Remove Not Found Stores" option in the Actions menu.

  • User Interface Clearer MySQL configuration guidance

    When MySQL is not configured, the notification now directs users to "Tools > Options" to set up their MySQL connection settings, making it easier to resolve configuration issues.

  • User Interface New Store Delete Reason dialog

    Added a new dialog window (StoreDeleteReasonView) that displays on the Store Manager screen when deleting Epicor Eagle stores. The dialog shows context about which POS store number is affected and which system it exists in, followed by five radio button options for the deletion reason. The "Remove Store" button remains disabled until a reason is selected.

  • User Interface Validation requires reason selection

    The "Remove Store" button in the deletion reason dialog remains disabled until one of the five reason options is selected, ensuring users cannot proceed without providing context for the deletion.

  • User Interface MySQL Scripts Manager layout adjustments

    Added a menu bar to the top of the MySQL Scripts Manager window to accommodate the new Scripts menu. Adjusted grid row definitions to maintain proper spacing with the new menu bar.

  • User Interface Removed SKUs column from import picker

    The SKUs column has been removed from the store picker to simplify the view.

  • User Interface Enhanced database setup validation

    If Margin Master can't read your store number from a database, it now asks you to confirm the number instead of guessing.

  • User Interface Reconciliation progress display

    During import, the splash screen now displays "Reconciling SKUs for Store [X] [Y of Z]" to show reconciliation progress for each store location. The total number of deleted SKUs is logged for reference.

  • User Interface Improved reset confirmation and messaging

    When resetting vendor or POS data, you'll now see clearer messages explaining what will happen and what you need to do next to restore your data.

  • User Interface Improved reset confirmation and completion messaging

    Both the Reset Vendor Data and new Reset POS Data features now include more detailed confirmation dialogs that clearly explain what will be deleted and what actions are required afterward. Success messages explicitly state that the main table has been cleared and provide next-step guidance for re-syncing or re-importing data.

  • User Interface Dialog layout improvements

    Widened the Data Aging dialog from 800px to 950px to accommodate the new import history table, and added a scroll viewer to the POS data panel to handle multi-store environments with many import records.

  • User Interface Friendly display names for vendor sync tables

    Added a dictionary mapping internal table names to user-friendly display names, including "Ace Catalog" for AceCatalogRecords, "DIB SKU Classification" for DIBSkuProductClassificationRecords, "Planograms" for AcePlanogramRecords, and similar mappings for all synced vendor tables.

  • User Interface Fixed POS dropdown width for non-Ace/non-Orgill vendors

    When creating a database for Do-It-Best, Emery Jensen, or United Hardware, the POS system dropdown now uses the full width of the window for easier selection.

  • User Interface Per-file progress for BisTrack batch imports

    You'll now see real-time progress as each store file is imported, instead of waiting for all files to preload before seeing any feedback.

  • User Interface Progress reporting improvements for BisTrack imports

    BisTrack import progress now shows detailed file-by-file status during loading and per-store status during table creation, making it easier to track long-running imports.

  • User Interface Store selection UI now correctly encodes special characters

    Fixed the Store Manager matchup UI and MySQL store selection dialog to use PosStoreCharHelper.CharToWin1252Ordinal when setting the store character, replacing the previous (int)char cast that stored Unicode code points. Updated the legacy migration path to normalize historical UnicodeNumber values greater than 255 back to their Windows-1252 byte equivalents.

  • User Interface Updated debug import preview labels

    The debug import preview dialog now uses vendor-specific labels (e.g., "Ace Store #1715" instead of "Vendor #1715") to match the picker's dynamic labeling approach.

  • User Interface Improved status messages during partial import rebuild

    The import status messages now more accurately show what the system is doing during the import process.

  • User Interface Import status messages added

    The import screen now shows clearer status messages while processing your data.

  • User Interface Import dialog reflects direct database import

    The Import Manager splash screen for RockSolid now displays "Importing RockSolid Data..." instead of "Extracting RockSolid Data..." to better reflect that data is being imported directly to SQL Server rather than extracted to an intermediate file.

  • User Interface Enhanced progress reporting for Excel imports

    SqlBulkCopy operations now report progress every 1% (or minimum 1,000 rows), updating both the splash screen progress bar and status messages. The Import Files screen shows messages like "Loaded 150,000 rows from Excel — bulk inserting to SQL..." followed by per-batch progress updates.

  • User Interface Import failure notifications

    Added user-facing notification on the Import Manager splash screen when vendor data updates fail after all retry attempts, providing immediate visibility when imports encounter unrecoverable errors.

  • User Interface POS system dropdown now shows friendly names

    The POS system dropdown now shows easy-to-read names instead of technical codes.

  • User Interface Import Manager and Main Table adopt handler workflow

    Updated `ImportFilesViewModel` and `MainMMViewModel` to use `IPosImportHandlerFactory.ResolveAsync` instead of direct service calls. Both screens now route BisTrack imports through the handler pipeline, with progress updates flowing through a new `IPosImportProgress` adapter interface. Legacy file-by-file import path is preserved as a fallback when no handler matches.

  • Database SKU index creation during import

    Added automatic creation of a non-clustered index on the SKU column immediately after the initial product data merge. This index converts expensive full table scans into fast index lookups when joining vendor catalog data, reducing query time from over 30 seconds to under a few seconds even on large catalogs.

  • Database Added performance index for Compass store group operations

    Added a new managed index (RSIX_Compass_IN_in_store) on the in_store column of the Compass_IN table. This index is automatically created during data import to ensure fast JOIN performance when building store groups, preventing timeouts on stores with large inventories.

  • Database Standardized collation for Epicor store number fields

    Added explicit case-sensitive collation (Latin1_General_CS_AS) to the EpicorStoreNumber column in both the query JOIN condition and the table creation script to match the Compass database collation and prevent future comparison errors.

  • Database Persistent BisTrack import table

    Added BisTrackPointOfSaleDataImport as a persistent table (BisTrackPointOfSaleDataImportCreateTable.sql) that survives across import sessions. The table includes CreateDate and LastUpdate timestamps to track when records were first added and last modified, plus an index on Store and Sku for efficient merging.

  • Database Numeric columns stored as DECIMAL during preload

    The `BisTrackPointOfSaleDataImport` staging table schema changed: CurrentPrice, OnHand, H0–H12 (history months), Cost, and Comp1–5 columns are now DECIMAL(19,4) instead of NVARCHAR. The Sep CSV reader parses these fields to typed decimals immediately during Phase 1 bulk insert, eliminating all downstream TRY_CONVERT operations in `BCPToStoreImport.sql` and the new `BisTrackPreloadToCurrent.sql` script.

  • Database Enhanced Compass_IN table indexing strategy

    The indexing logic now creates two indexes on the Compass_IN table: a single-column index on in_store for general lookups, and a composite index on (in_store, in_db_update_datetime) specifically optimized for timestamp queries during incremental sync operations.

  • Database Cleanup of duplicate placeholder store records

    When re-pointing a corrupted store identifier to its correct value, the system now automatically removes any unmapped placeholder records that were previously created for that identifier, eliminating duplicate entries in the store manager.

  • Database New SyncHistorySummary model for Data Aging display

    Created a lightweight SyncHistorySummary model to hold per-table sync information, including table name, friendly display name, last sync date, record count, and status. This model uses a SQL query with ROW_NUMBER partitioning to efficiently retrieve only the most recent successful sync per table.

  • Database SyncHistorySummary model added

    Created a new lightweight model to efficiently query and display sync history summaries without loading full SyncHistory records, improving performance when displaying the Data Aging View.

  • Database Global SKU index seeding

    Added SKU to the list of critical columns that receive automatic indexes during database startup and maintenance operations. This ensures all store pricing tables have proper SKU indexes across all code paths, preventing the timeout issue from recurring in any import scenario.

  • Database BisTrack staging table cleanup script

    Added a new SQL script (BisTrackBCPFinalizeCleanup.sql) that strips quotes from all fields, normalizes store numbers, and removes duplicate SKU entries within the batch staging table without performing inserts, specifically designed for the Sep bulk import path.

  • Database IsNotFound column migration for existing databases

    The StoreManagerInfo table schema now includes an IsNotFound bit column (default false). For existing databases, an automatic ALTER TABLE migration adds this column during the EnsureStoreManagerTableAsync initialization step, ensuring seamless upgrade without data loss.

  • Database IsNotFound field added to StoreManagerInfo

    Added IsNotFound boolean field to the StoreManagerInfo table to track stores that exist in Store Manager but are no longer present in Compass_IN data. Includes automatic migration for existing databases. Stores with IsNotFound=true are excluded from VendorStoreNumber editing and import processing.

  • Database Store matchup discovery entries handled correctly

    Discovery entries (GlobalFileConfig with Key "99999") are now correctly processed as unmapped store placeholders rather than actual vendor store numbers, ensuring clean Store Manager records and proper single-store auto-mapping behavior.

  • Database New DIB6828 typed staging schema

    Added BisTrackDib6828PointOfSaleDataImport table with 25 typed columns—numeric fields (CurrentPrice, OnHand, H0-H12, Cost) stored as DECIMAL(19,4) to eliminate downstream TRY_CONVERT calls. Three new SQL scripts handle the DIB6828 pipeline: BisTrackDib6828PointOfSaleDataImportCreateTable.sql (persistent typed table with Store/Sku index), BisTrackDib6828PreloadToCurrent.sql (extracts single store from staging to _current working table), and BisTrackDib6828BCPFinalizeCleanup.sql (strips quotes, normalizes Store, deduplicates rows). RSImportFileHelperService adds PreloadBisTrackDib6828BcpAsync and PostPreloadBuildAllStoresFromDib6828Async methods with BisTrackDib6828BcpRow POCO for CSV mapping.

  • Database Capture server identity information

    Connection test now queries and stores the MySQL server hostname, version, and current database name from the identity query (@@hostname, @@version, DATABASE()), making this information available in the test result model and visible to users in the results panel.

  • Database DIB6828 SQL schema and pipeline scripts

    Added three new SQL scripts for DIB6828: `BisTrackDib6828PointOfSaleDataImportCreateTable.sql` (typed staging table with DECIMAL fields and Store/Sku index), `BisTrackDib6828BCPFinalizeCleanup.sql` (quote stripping, store normalization, deduplication), and `BisTrackDib6828PreloadToCurrent.sql` (per-store extraction from preload table to _current working table). Numeric columns are loaded as DECIMAL during CSV read, eliminating TRY_CONVERT calls in downstream queries.

  • Database BisTrack schema improvements

    BisTrackPointOfSaleDataImport table columns changed from NVARCHAR to DECIMAL(19,4) for CurrentPrice, OnHand, H0-H12, Cost, and Comp1-5. Added BisTrackPreloadToCurrent.sql for zero-cast fills from typed preload table. BisTrackInsertIntoMainTable.sql now references normalized column names (Description2, ProductGroup, OrderMultiple) instead of legacy aliases (Desc2, PG, OM). Updated nsoftware.IPWorksSSH package from 24.0.9545 to 24.0.9624.

  • Architecture BisTrack import handler interface

    Introduced `IPosImportHandler` interface and factory pattern to standardize all POS import workflows. Handlers use a consistent two-phase contract: `PreloadAsync` (load files into typed staging tables) and `BuildAllStoresAsync` (per-store SQL pipeline). The factory resolves the correct handler by testing CSV headers or DirectConnect configuration, allowing multiple format variants to coexist cleanly.

  • Architecture POS-specific import script framework

    Modified RSImportFileHelperService to check for and use POS-specific InsertIntoMainTable.sql scripts when available, falling back to the generic insert logic for other POS systems. The specialized script receives variables for the current table name, mainTable name, store number, and RSC filter condition, and bypasses the duplicate removal step when used.

  • Architecture BisTrack staging table now reused across files

    Refactored the BisTrack batch import process so the staging table is created once at the start, then each file's data is loaded, processed, and truncated before the next file begins. This ensures proper isolation between store files and eliminates the need for tracking "all stores processed" flags. Each file now deletes any existing data for its store before loading new data.

  • Architecture Handler-based POS import pipeline

    Introduced IPosImportHandler contract with factory-based resolution (IPosImportHandlerFactory) to replace direct ViewModel calls to import services. Three BisTrack handlers registered: BisTrackDib6828Handler (checks for DIB6828-specific headers), BisTrackDib1040Handler (requires ≥10 DIB1040/MAP1/MAP2 header matches), and BisTrackDirectConnectHandler (validates SQL configuration for live server queries). Handlers implement CanHandleAsync (format detection), PreloadAsync (batch file loading), and BuildAllStoresAsync (per-store table generation). ImportFilesViewModel and MainMMViewModel now resolve handlers through the factory and delegate progress reporting through IPosImportProgress adapters.

  • Architecture Shared enrichment for vendor data fields

    Extracted the logic that populates pricing levels, taxonomy categories, and vendor-owned flags from the MMVendorData view into a shared method (EnrichDibPosMainTablesFromMMVendorDataAsync). Both the interactive catalog-add workflow and the new bulk re-add process now use the same enrichment code, ensuring consistency and eliminating duplicate SQL update statements. The bulk path enriches via a set-based join instead of building large IN clauses with thousands of SKUs.

  • Architecture Extracted testable import history coverage logic

    Moved the "should we trust ImportProcessing or read the main tables" decision into a standalone `ShouldEnrichFromMainTables` method with 7 new unit tests covering the exact 1-of-22 scenario, full coverage being preserved, leading-zero store number equivalence, and the stale-store case the original guard was written for. This regression happened silently (the view simply showed a smaller number), so the logic is now pinned with direct tests.

  • Architecture Handler-based POS import resolution

    The Import Manager now automatically detects which BisTrack format your files use.

  • Architecture Enhanced store scanner service

    The EpicorFTPFileExtractorService.ScanStoreCharactersAsync method now returns a dictionary mapping store character ordinals to record counts instead of just a list of ordinals, enabling the UI to display both the character and its associated SKU count.

  • Architecture EpicorFTPFileExtractorService enhancements

    Added ScanStoreCharactersAsync() method to EpicorFTPFileExtractorService that reads an INDecoded binary file, extracts unique single-character POS store codes from byte offset 14, and returns them sorted. Modified DecodeEpicorINFileAsync() to support the new streaming import path with MergeIntoStoreTableAsync(), which uses BulkMerge with ColumnPrimaryKeyExpression on (StoreNumber, SKU) for upsert behavior. The method now branches based on the EpicorUseStreamingImport setting to choose between legacy (in-memory dedup + insert) and streaming (SQL-side dedup + merge) paths.

  • Performance Optimized BisTrack import speed

    Importing POS data from BisTrack is now faster, reducing wait time during the import process.

  • Performance Streamlined BisTrack import pipeline

    BisTrack data imports now run faster, especially for larger inventory files.

  • Performance Improved BisTrack import query efficiency

    BisTrack product data imports will now run faster, with the most noticeable improvement for stores with thousands of items.

  • Performance Typed staging table for BisTrack imports

    BisTrack imports now complete faster because price and quantity data is processed more efficiently.

  • Documentation New troubleshooting guide for Epicor zero-SKU imports

    When an Epicor import runs but brings in no inventory, this new guide shows you exactly what to check and how to fix it — usually a store mapping issue in Store Manager.

  • Performance Bulk re-add for large Do-It-Best catalogs on BisTrack

    If you have hundreds or thousands of manually tracked catalog items, they will now re-add almost instantly after a rebuild instead of taking many minutes.

  • Documentation Field mapping reference for MI9 imports

    Documented the complete set of MI9 import fields including all retail price levels (Retail, RetailLevel1-5, RetailZone variants), cost fields (StoreCost, AVGCost, ReplacementCost), 12 months of sales history, competitor pricing (Comp1-5, CompA), store product status codes, and vendor information. Explains how the "current price cascade" logic selects the active retail price from multiple available price levels, and how team aggregation chooses representative values when stores within a team have conflicting data.

  • Documentation Expanded Add from Catalog documentation with bulk import workflows

    The help documentation now explains how to import multiple SKUs at once using Excel files, CSV files, or by pasting a list of SKUs separated by commas or line breaks.

  • Infrastructure Code modernization and cleanup

    Removed over 290 lines of legacy code related to dynamic compilation and intermediate table handling, replacing it with a more efficient and maintainable implementation using modern CSV parsing libraries. The simplified codebase will be easier to maintain and debug going forward.

  • Performance Optimized duplicate SKU removal during BisTrack import

    Updated the duplicate SKU detection logic to work directly with indexed columns instead of applying string trimming functions during the comparison. This allows the database to efficiently identify and remove duplicate entries without scanning every row.

  • Infrastructure Enhanced store character conversion handling

    Added a new `ToDisplayString()` helper method that intelligently converts between stored ordinal values and display strings, with special handling for control characters and extended ASCII. The conversion also handles legacy formats where the ordinal may already be displayed as a number string.

  • Code Quality Removed unused file retention logic

    Removed 18 lines of dead code that was building a file dictionary and attempting to keep only the 3 most recent files, but this logic was never actually functioning. The simplified version now focuses only on removing empty backup directories.

  • Infrastructure Resolved nullable reference type warnings

    Fixed all C# nullable reference type warnings (CS8600, CS8602, CS8618, CS8622, CS8629, CS8632) across view models and services using appropriate null-coalescing operators and pragma directives. Added fallback to empty collections for database query results to prevent potential null reference issues in SKU-level exceptions, column editing, and selection box management.

  • Documentation Enhanced Store Manager documentation for Epicor matchup

    The Store Manager help now clearly explains how Epicor stores are matched up and what the status badges mean for your imports.

  • Infrastructure New helper method for store ordinal drift recovery

    Added PosStoreCharHelper.RecoverDriftedOrdinal method with comprehensive unit test coverage. This helper validates recovered ordinals against live MySQL data rather than trusting string parsing alone, ensuring the system never guesses at store mappings and only applies corrections when the recovered ordinal actually exists in the database.

  • Infrastructure Transient error classification for MySQL

    Added logic to identify and classify MySQL connection errors that are worth retrying (error codes 1040, 1042, 1043, 2002, 2003, 2006, 2013), such as "server temporarily unavailable" or "connection lost". The system logs warnings when retrying these transient errors to help diagnose intermittent connection issues.

  • Infrastructure Added comprehensive test coverage for Data Aging logic

    Added 8 unit tests documenting when the Data Aging screen should trust recorded import history versus reading actual table counts, including the specific regression scenario (one good history row out of 22 stores), full coverage validation, leading-zero handling, empty/zero-record scenarios, and stale history detection.

  • Infrastructure Issue tracking documentation

    Added documentation for four support issues (MM-1158 through MM-1161) covering SQL Server instance detection, database creation flows, MySQL import data integrity, and single-store SKU exception handling. These documents capture root cause analysis and proposed fixes for upcoming maintenance work.

  • Infrastructure Import handler store tracking

    All BisTrack import handlers now expose which store numbers were successfully imported during the most recent import operation. This data is used by the missing store detection feature to identify stores that may have been excluded from an import.

  • Infrastructure Added diagnostic timing for group table builds

    Added detailed timing logs around store group table building operations to help diagnose performance issues in future troubleshooting scenarios. Logs now show SKU count and elapsed time for each group table build.

  • Infrastructure Enable nullable reference types in Epicor extractor

    Added nullable reference type annotations to EpicorFTPFileExtractorService to improve code safety and prevent null reference exceptions during import operations.

  • Infrastructure Repeatable migration logic with safety checks

    The migration logic is safe to call multiple times — it exits immediately if no binary-format rows with vendor numbers exist, preventing unnecessary processing. The system only runs this migration for Epicor INDecoded configurations, never for MySQL Compass stores.

  • Infrastructure Added organization tracking to license validation

    Enhanced the license validation service to capture and store the organization ID from software license details. This supports multi-organization deployments and ensures organization-specific settings like store configurations are properly associated with the correct organization context.

  • Infrastructure Added Windows-1252 encoding support to test environment

    Registered the Windows-1252 code page encoding provider in the test project initialization to enable store character conversion tests to run. Modern .NET requires explicit registration of legacy code pages; the running application gets this transitively from dependencies, but the test host needed it added explicitly.

  • Documentation Updated Epicor MySQL import guide with store matchup details

    Revised Epicor MySQL Compass import documentation to explain store filtering using the store character ordinal, reference the Store Manager for configuration, and link to the new zero-SKU troubleshooting guide. Added technical details about the reconciliation process and how single-store setups auto-map.

  • Infrastructure Store Manager migration from legacy selector

    Removed EpicorMySqlStoreSelectorViewModel, MySqlStoreSelectionViewModel, EpicorMySqlStoreSelectorView, and the MySqlStoreSelectionViewModel DI factory (~680 lines). Replaced with lightweight StoreImportSelectorViewModel and StoreImportSelectionViewModel (~130 lines) that wrap StoreManagerInfo for display only—no database writes occur from the picker. The new architecture separates selection UI from store configuration management.

  • Infrastructure Remove redundant MySqlCompassTabViewModel wrapper class

    The thin wrapper view model (MySqlCompassTabViewModel) that hosted MySqlConnectionDetailViewModel has been removed. EpicorTabViewModel now directly owns MySqlConnectionDetailViewModel as its InnerViewModel property, eliminating one layer of indirection and simplifying the view model hierarchy.

  • Infrastructure Automatic enforcement of Import Manager for Compass stores

    When the Epicor tab loads settings for a Compass store, the application now automatically enables the Import Manager flag and saves this setting. This ensures consistent behavior across all Compass installations without requiring manual configuration.

  • Infrastructure Documentation search index expansion

    Updated docs/index.json with 147 new search entries covering POS systems category with subcategory "Import Guides". Each entry includes targeted search keywords (e.g., "bistrack", "direct connect", "dib1040"), audience tags (user, support), heading structure, and body excerpts for result previews.

  • Infrastructure New BisTrack cleanup SQL script

    Added BisTrackBCPFinalizeCleanup.sql, a cleanup-only version of the BCP finalization script that strips quotes, normalizes store numbers, and deduplicates records without performing INSERT operations. This script is specifically designed for the Sep batch load path where all stores are combined in a single staging table.

  • Infrastructure Enhanced batch import progress reporting

    Added detailed progress messages showing which file is being loaded (e.g., "Loading file 3 of 12") and summary statistics including total rows and store count. The import process now tracks a file-to-store mapping for better diagnostics and validation.

  • Infrastructure New PostPreloadBuildAllStoresAsync method
  • Infrastructure New BisTrackPreloadToCurrent.sql replaces type-casting logic

    Created new SQL script that fills per-store `_current` tables directly from the typed preload table using simple column mapping with no CAST or TRY_CONVERT operations. This replaces the conditional logic in `BCPToStoreImport.sql` that previously performed type conversion during per-store extraction. Quote-stripping operations removed from `BisTrackBCPFinalizeCleanup.sql` for numeric columns since they're already typed.

  • Documentation Expanded search keywords and index coverage

    Added search keywords across all updated documentation pages including "0 skus", "store matchup", "pos store character", "store not importing", "nothing imported", and "blank prices" to help users quickly find troubleshooting information when experiencing import issues.

  • Infrastructure Debug-only preview harness for store picker

    Added a debugger-only harness that lets developers preview the "Select Stores to Import" picker without requiring a live MySQL or Compass connection. When running under the debugger with Shift held, the picker sources rows from the local StoreManagerInfo table (falling back to sample data if empty) and reports what would be imported without executing a real import. This facilitates UI testing and QA on non-production machines.

  • Infrastructure Removed redundant ViewModels and Views

    Deleted the separate ConnectionsTabViewModel, MySqlCompassTabViewModel, and their corresponding views. The new EpicorTabViewModel composes the MySQL connection VM and exposes FTP settings, Store Manager, and store-number options in a single unified interface. Updated dependency injection, data templates, and documentation to reflect the single-tab architecture.

  • Documentation Update Epicor connection documentation for tab consolidation

    All user-facing documentation (getting-started/data-import.md, epicor-server-setup.md, import-epicor-ftp.md, import-epicor-mysql.md, mysql-compass-connection.md, troubleshooting-epicor-zero-skus.md) has been updated to reference the unified "Epicor" tab instead of separate "Connections" and "MySQL/Compass" tabs, and to explain the "Connect via MySQL / Compass" toggle.

  • Infrastructure Configurable reconciliation behavior

    A new application setting (ReconcileMySqlDeletedSkus) allows the reconciliation feature to be enabled or disabled. The feature is enabled by default in production and includes safety checks to prevent accidental data deletion if MySQL returns zero SKUs.

  • Infrastructure Remove deprecated DIB_Current cloud table code

    Removed all references to the deprecated DIB_Current cloud table, including the cloudDBDataContext, DIBCurrent entity class, and the UpdateDoitBestCostsAsync method body. This cloud table no longer exists—Do-It-Best cost data is now provided through the locally-synced DIBCatalogRecords table and exposed via the MMVendorData view. This cleanup eliminates dead code and prevents confusion.

  • Infrastructure Secrets management in CI/CD

    GitHub Actions publish workflow now injects component licenses (DapperPlus, IPWorks) and API keys from Azure Key Vault into appsettings.json at build time. Local development uses appsettings.secrets.json (gitignored). Removed separate publish-docs.yml workflow; documentation publishing now integrated into main publish.yml. Added RetailerSoft.ComponentLicensing project reference and checkout step in CI.

  • Documentation Updated Epicor FTP import guide

    Added documentation for the new re-import feature to the Epicor FTP import guide, including step-by-step instructions for renaming the INdecoded.bak file and using the re-import prompt.

Cloud Sync & Vendor Data

  • New Feature Persistent catalog item tracking

    When you add an item from the catalog, it's now permanently saved. Every time Margin Master rebuilds your data, these items are automatically added back in with the latest pricing from your vendor's catalog.

  • New Feature Persistent catalog item tracking

    When you add an item from the catalog, it now stays in your system permanently. Every time Margin Master rebuilds your data, these items are automatically re-added with the latest pricing from your vendor's catalog.

  • New Feature Catalog Lookup tool with typeahead search

    Use Help > Catalog Lookup to quickly search for any vendor item by typing part of the SKU or description—results appear as you type.

  • New Feature Catalog Lookup tool with cloud comparison

    Search for any SKU or item description and see complete catalog details including pricing and zone information. The tool shows if your local catalog matches the cloud data, helping identify sync problems.

  • New Feature Alternate code field added to vendor catalog items

    When viewing Ace Hardware or Do-It-Best items, you'll now see alternate codes displayed in parentheses if the vendor provides them, such as "12345 (ABC) - Product Name".

  • New Feature Excel import now detects and uses store numbers from files

    When importing an Excel file with both SKU and store number columns, items are now automatically added to the correct stores without needing to select the store from the dropdown first.

  • New Feature In-app Version History window

    Click Help > Version History to see a complete list of all Margin Master releases and when you installed each version on this computer. Click any version to read its release notes.

  • New Feature Version History window

    Click Help → Version History to see all Margin Master releases and what changed in each version. You can filter to show only versions you've installed, and click any version to read its full release notes.

  • New Feature Support for multiple demo databases per vendor

    Extended the demo mode system to support multiple demo databases for each vendor, each with its own unique database key for naming (e.g., "AceHardware" and "AceHardwareMAPP"). Added DemoVendorInfo DTO and a new v2 API endpoint (/api/v2/Demo/AvailableDatabases/v2) that returns demos grouped by vendor with hierarchical structure.

  • New Feature Multiple demo databases per vendor

    Each vendor can now provide multiple demo databases with unique names and descriptions (e.g., "Standard Demo (Epicor POS)" or "MAPP Pricing Demo"). The system tracks each demo with a DatabaseKey for local storage while maintaining backward compatibility with existing single-demo-per-vendor configurations.

  • New Feature Ace Hardware catalog detail display

    Ace vendors can view complete catalog details including product groups, pricing strategies, and zone-specific pricing for every item.

  • New Feature Search dropdown with instant selection

    When you search for a SKU, matching items appear in a dropdown list below the search box—just select one and press Enter or click "Lookup" to view its details.

  • New Feature Comprehensive data reset documentation added

    Added detailed user and support documentation covering both Reset Vendor Data and Reset POS Data utilities, including what each reset affects, step-by-step instructions, special considerations for Do it Best mailbox stores, common questions, and technical details about affected database tables. The documentation has been indexed for searchability with keywords covering common user scenarios like "clear data," "start over," and "empty main table."

  • New Feature Do it Best catalog detail display

    Do it Best stores see detailed cost tier pricing for Classic and Vision membership levels, along with recommended selling prices and margin information.

  • New Feature Copy SKU to clipboard button in detail header

    Click the clipboard icon next to the SKU to instantly copy it for pasting elsewhere.

  • New Feature Copy SKU to clipboard

    Click the clipboard icon next to any SKU to instantly copy it for pasting into other applications.

  • New Feature Cloud data comparison with sync verification

    The tool automatically checks if your local catalog data matches the cloud and shows a colored banner indicating sync status—green for matched, yellow/red for differences with details about what doesn't match.

  • New Feature Deep linking to web catalog with vendor, SKU, and store context

    "View in web" now opens directly to the SKU you're viewing with your store number already filled in, saving time switching between desktop and web.

  • New Feature View in web browser link

    Click "View in web" to open the item's detail page in your browser for sharing or additional information.

  • Improvement Help documentation links added to reset confirmation dialogs

    When you reset vendor or POS data, the confirmation message now includes a link to detailed help documentation explaining the process.

  • Improvement Alternate code display for vendor RSCs

    When viewing RSC codes from Ace Hardware or Do-it-Best, you'll now see an alternate code shown in parentheses (e.g., "ABC123 (XY) - Product Name") when that vendor provides one.

  • Improvement Filter Data Aging catalog list to store's RSCs

    Do-It-Best stores now see only the catalog files that apply to their specific RSC locations.

  • Improvement Vendor data staleness check refined for vendor update schedules

    If you're a Do it Best store and you synced vendor data on Friday, you won't see "stale data" warnings when importing POS files on Saturday or Sunday, since Do it Best doesn't update their catalog on weekends anyway.

  • Improvement Auto-populate RSC code from cloud settings

    If you change a store's vendor number and the RSC code field is empty, the system will now automatically fill it in based on your organization's cloud settings.

  • Improvement Live API fallback for RSC code lookup

    When you enter a vendor store number, the system will now contact the cloud to get the matching RSC code if it's not already stored locally, ensuring accurate data even with outdated local information.

  • Improvement Catalog sync status cache shortened to 2 hours

    If a vendor catalog is processing in the cloud, the status you see in the Data Aging View will now update within 2 hours instead of waiting up to a full day for the display to refresh.

  • Improvement Natural numeric sorting for all code lists

    Store numbers, vendor codes, and other numeric fields now appear in the correct numeric order in dropdown lists and tables.

  • Improvement Numeric-aware sorting for store and vendor code lists

    When viewing dropdown lists for store numbers, vendor codes, or other numeric identifiers, they now appear in proper numeric order. For example, store "2" will appear before store "10", and codes like "00001" and "00010" sort correctly by their numeric value.

  • Improvement Special warning for Do it Best mailbox stores during POS data reset

    If your Do it Best store uses mailbox downloads instead of a POS system, you'll now see a clearer warning when resetting POS data, explaining that you'll need to re-download from the DIB mailbox to restore your data.

  • Improvement Fixed Cost2 missing on Epicor imports

    Epicor stores will no longer see blank vendor catalog costs in the pricing grid when cost data is available from the POS system.

  • Improvement Cost sync progress indication

    You'll see a new "Synchronizing cost fields..." message during startup that shows the system is making sure all cost values match.

  • Improvement Enhanced CatalogFileStatus model with local sync tracking

    Added a LocalSyncDate property to the CatalogFileStatus model to store the last local sync timestamp. This property is populated by cross-referencing the cloud catalog's FriendlyName with the SyncHistory table, handling cases where multiple cloud files (like different Ace planogram formats or DIB Regional Service Center catalogs) map to the same local database table.

  • Improvement Map cloud catalog files to local sync tables

    Added intelligent mapping between cloud catalog file names and their corresponding local database tables. This handles complex scenarios where multiple cloud files (such as Ace Hardware's four planogram variants or Do-It-Best's eight RSC catalogs) all sync to the same local table, ensuring the correct sync date is displayed for each file.

  • Improvement Enhanced catalog item data population

    Items added from the catalog now include more detailed information like pricing strategies, velocity codes, and zone pricing data, making them identical to items imported from your POS system.

  • Improvement Explicit Lookup button and Enter key support added

    You can now press Enter or click the "Lookup" button to search for a SKU instead of waiting for auto-search.

  • Improvement Added BackupAll factory method for safer backup operations

    Introduced a new BackupRestoreOptions.BackupAll() factory method that creates a complete backup configuration including all pricing strategies, custom groups, SKU exceptions, rounding schemes, cost breaks, min/max strategies, application settings, custom views, and store configurations. This ensures auto-backup operations always capture complete data snapshots.

  • Improvement Catalog Add Items file import moved to toolbar

    The button to import Excel files is now easier to find at the top of the Catalog Add Items screen.

  • Improvement Network firewall guidance for SQL connectivity

    Error messages now include helpful troubleshooting steps when cloud sync can't connect to the database server.

  • Improvement Network error diagnosis

    Error messages now tell you exactly what's wrong — if the firewall is blocking the connection, the message will specifically mention checking port 1433 settings.

  • Improvement Added local sync status tracking to catalog file status

    Added a new IsLocalSyncCurrent property that compares the local sync date against the cloud processing date to determine if the current machine has the latest catalog data. The overall IsSuccess status now requires both cloud processing success and local sync currency.

  • Improvement Clearer error messages for network connection failures

    Error messages now clearly explain when a firewall is blocking sync and reassure you that the software will automatically try a different connection method.

  • Improvement Default store sort changed to POS store number

    Stores now appear in order by their POS store numbers (1, 2, 3, 4) instead of vendor store numbers.

  • Improvement Zone override field changed to numeric spinner

    The zone override field now has up/down arrows and only accepts valid numbers.

  • Improvement Automatic Ace zone validation on screen open

    Ace zone assignments now update automatically when you open Store Manager, based on your latest catalog data.

  • Improvement Ace Hardware zone validation

    Ace Hardware stores now automatically display the correct pricing zone when you open Store Manager.

  • Improvement Automatic remediation when post-sync reality check fails

    If a sync doesn't import all your items, Margin Master will now automatically retry importing everything to make sure your data is complete.

  • Improvement Enhanced error logging for DIB mailbox operations

    Mailbox connection and download failures are now logged at Error level (previously Warning) so they reach cloud telemetry, allowing support to diagnose remote issues. Each failure now includes the specific host, port, and username (but not password) along with the underlying exception details, making it possible to correlate "couldn't read the mailbox" reports with the actual FTPS connection errors.

  • Improvement Enhanced demo database metadata

    Demo databases now include display names, descriptions, default selection flags, and unique database keys separate from vendor keys. Database keys control the local SQL Server database naming (MarginMaster_Demo_{DatabaseKey}) to prevent conflicts when multiple demos exist for the same vendor.

  • Improvement Catalog search now uses debounced type-ahead

    The catalog add screen now searches as you type instead of loading thousands of items upfront, making it much faster to find products.

  • Improvement Automatic settings push to Manager server

    When settings are saved in the Options dialog, the application now automatically pushes the current store configuration (RSC codes, POS system type) to the Manager server in the background. This ensures the server stays synchronized with local store settings for better support and data accuracy without requiring a full application restart.

  • Improvement Zone override detection logic

    Added properties to detect when a zone number has been manually overridden versus using the Ace-assigned value. The system compares the current zone against the original Ace assignment and automatically removes the override flag if the user enters the original zone number.

  • Improvement Supplement process now fully populates store data

    The background supplement process that runs at startup now includes RSC codes and zone overrides when backfilling missing store entries from GlobalFileConfig. This ensures stores added through the supplement path are as complete as those migrated initially.

  • Improvement Dynamic zone lookup when vendor store number changes

    Changing an Ace store number now automatically updates the assigned zone for that store.

  • Improvement Store Manager waits for cloud save before closing

    Closing the Store Manager window now waits for your changes to finish saving to the cloud, preventing lost updates.

  • Improvement Auto-search with debouncing

    Implements 400ms debounced search with cancellation tokens to provide responsive type-ahead search without excessive database queries. Search status text updates to show "Searching...", result count, or "No results" feedback.

  • Improvement Deep linking to web Catalog Lookup

    Clicking "Open in Web" now opens your browser directly to the same product you're viewing in the desktop app, with your store information already filled in.

  • Improvement Restore Database launched directly from main app and startup

    Database restore is now accessible from the Database menu and automatically switches to the restored database after completion.

  • Improvement Mode switching clears opposite panel

    Switching between Search and Bulk modes automatically clears the other mode's input and results—Search text and results are cleared when switching to Bulk, and Bulk entry text is cleared when switching to Search—preventing confusion from stale data.

  • Improvement Documentation updated to reflect new workflow

    The help documentation has been restructured to explain Search and Bulk modes separately, with clearer guidance on when to use each method. The "Enter Bulk List" section has been replaced with "Bulk Mode" and "Bulk Entry Notes" sections reflecting the new inline workflow.

  • Improvement Catalog search query optimization

    Do-it Best catalog search now uses DISTINCT in subquery to eliminate duplicate SKU entries in search results, providing cleaner results when searching by SKU or description.

  • Improvement Internet connection check caching improved

    Modified ApiClientService to cache successful connection checks for 5 minutes (up from 30 seconds), reducing unnecessary network requests to Google when the application is online. Offline checks continue to retry every 30 seconds.

  • Bug Fix Cost fields now sync automatically after table rebuild

    The pricing grid will no longer show blank cost values when cost information is available from another source. All three cost columns (store cost, POS cost, and vendor catalog cost) now stay in sync automatically.

  • Bug Fix Cost field synchronization after table operations

    If one cost field has a value but another is blank, the system now automatically fills in the missing cost to keep everything consistent.

  • Bug Fix Data Aging view displays correct sync dates

    The Last Sync Date column in the Data Aging screen now shows the correct date and time when each table was last synchronized, instead of showing blank entries.

  • Bug Fix Fixed catalog item lookup for Do-It-Best stores

    When using "Add Item from Catalog," Do-It-Best SKUs are now found correctly and can be added to your store.

  • Bug Fix DIB catalog add now uses correct data source

    Adding Do-It-Best catalog items now pulls the correct product information including descriptions, pricing, and product categories.

  • Bug Fix Add from Catalog now displays errors instead of failing silently

    If adding items from the catalog fails for any reason, you'll now see an error message explaining what went wrong instead of the button appearing to do nothing.

  • Bug Fix Error messages now display when Add from Catalog fails

    You'll now see an error message if something goes wrong when adding items from a catalog, so you'll know the items weren't added and why.

  • Bug Fix Add from Catalog dialog crash resolved

    The Add from Catalog dialog now opens correctly without crashing. Double-clicking items in the search results continues to work as expected.

  • Bug Fix Catalog Add dialog double-click not working

    When searching vendor catalogs and double-clicking an item to add it to your store's pricing list, the item will now be added as expected instead of nothing happening.

  • Bug Fix ManualCatalogItems table creation now runs reliably

    The system now properly tracks items manually added to vendor catalogs on all databases.

  • Bug Fix Catalog Lookup SKU field now accepts text input

    You can now type SKU numbers directly into the Catalog Lookup search field without issues.

  • Bug Fix Catalog Lookup text input enabled

    You can now type directly into the Catalog Lookup search box without interference.

  • Bug Fix Fixed duplicate key error during batch creation

    Stores with multiple location numbers under one Do-It-Best account can now successfully create change batches without errors.

  • Bug Fix Fixed duplicate key error during batch creation

    You can now successfully create change batches even if your store has multiple location numbers registered under the same Do-It-Best member number.

  • Bug Fix Fixed null reference crash in automatic backup operations

    The app will no longer crash when automatically backing up your data during sync or after editing custom groups and exceptions.

  • Bug Fix Fixed sync timeout on cost field updates for large stores

    Stores with large product databases will no longer experience sync failures when updating cost information.

  • Bug Fix DIB Add to History now handles missing store configuration

    Adding Do-It-Best items to history will no longer fail if your store list isn't fully configured in settings.

  • Bug Fix Prevent SKU loss on first catalog add with immediate rebuild

    When you add a SKU from the Do-It-Best catalog and choose to rebuild, the item will now be saved correctly the first time instead of requiring you to add it twice.

  • Bug Fix Ace Zone columns now hide correctly for non-Ace vendors

    When setting up store numbers for vendors other than Ace Hardware, you'll no longer see unnecessary Ace Zone pricing columns in the matchup screen.

  • Bug Fix Ace Zone columns showing for all vendors in Store Matchup

    If your store uses Do-It-Best, Orgill, or other non-Ace vendors, you'll no longer see the confusing "Ace Zone" and "Zone Override" columns in the Store Matchup screen.

  • Bug Fix Store number filtering corrected for Ace Hardware zone sync

    Store department zone pricing for Ace Hardware locations will now download correctly during sync, even when cloud store numbers include leading zeros.

  • Bug Fix Forward slash now allowed in SKU filters

    You can now filter and search for Ace Hardware products with SKU numbers containing forward slashes without encountering errors.

  • Bug Fix Eliminate redundant "No items were added" message

    When you try to add items that are already in your system or can't be found, you'll now see just one clear message explaining why, instead of two confusing messages.

  • Bug Fix Populate all vendor fields when adding Do-It-Best catalog SKUs
  • Bug Fix Complete vendor data population for Do-It-Best manual additions

    Adding Do-It-Best items from the catalog now includes complete product information like pricing strategy codes, product category classifications, recommended order quantities, and velocity indicators—not just the basic price levels.

  • Bug Fix Cloud sync error detection and messaging

    If cloud sync fails because of network or firewall problems, you'll now see an error message explaining the issue instead of a confusing "No Changes Found" notification that made it look like everything worked.

  • Bug Fix Cloud sync failure notification

    If cloud sync can't reach the server (for example, due to firewall settings blocking port 1433), you'll now see a clear error message explaining what went wrong, rather than a message saying no changes were found.

  • Bug Fix Data Aging status icons now reflect local sync state

    If you see a dash in the "Local Sync" column, you'll now see an orange warning icon instead of a green checkmark, making it clear you need to run a sync to get the latest data.

  • Bug Fix Data Aging green check now requires completed local sync

    You'll now see the green check mark only after your computer has downloaded and applied the latest vendor catalog updates, not just when they're ready in the cloud.

  • Bug Fix Automatic API fallback when firewall blocks Azure SQL redirect ports

    If your firewall blocks certain database ports, Cloud Sync will now automatically detect the problem and retry using a different connection method that works on almost all networks. You'll see a message "Firewall detected — retrying sync via secure API..." during this process.

  • Bug Fix Quick Issue Submission now includes system information

    When submitting feedback or reporting issues through the Quick Issue tool, submissions will now complete successfully instead of failing with an error message.

  • Bug Fix Schema prefix normalization in cloud sync proxy

    Cloud sync will no longer fail with errors when updating vendor catalogs and pricing data.

  • Bug Fix Schema prefix handling in cloud sync proxy

    Fixed an issue that could cause cloud sync to fail for certain vendor catalogs.

  • Bug Fix RowVersion hex-to-byte conversion now handles JSON deserialization correctly

    Cloud Sync operations that were failing due to internal data format errors will now complete successfully.

  • Bug Fix Fixed RowVersion data type conversion in cloud sync

    Fixed an issue that could cause cloud sync to fail or not properly track which records have been updated.

  • Bug Fix Prevent phantom store 99999 for Epicor users

    Epicor users will no longer see an incorrect "99999" store entry when assigning Ace Hardware zone pricing.

  • Bug Fix RSC codes now preserved during store matchup migration

    For stores using multiple Do-It-Best RSC codes, the system will now correctly remember which RSC each store belongs to after upgrading.

  • Bug Fix RSC codes now migrate to Store Manager

    When migrating from legacy settings, RSC codes (STORERSC) are now properly transferred to the Store Manager for each vendor store number. Previously, stores would lose their RSC assignments during migration and supplementation.

  • Bug Fix Excluded store status now syncs from cloud

    If a store is marked as excluded in your cloud settings, it will now correctly appear as excluded after syncing.

  • Bug Fix Store Manager database call now properly awaited

    Fixed a missing await when updating database records in Store Manager's delete operation for stores that have been reassigned to a POS system. The update operation is now properly asynchronous, preventing potential race conditions or incomplete saves.

  • Bug Fix Vendor filter now applied to reality check counts

    The system will no longer incorrectly warn about missing items when you have vendor filters configured.

  • Bug Fix Startup window crash when closing during connection

    Fixed an InvalidOperationException that could occur if the startup window was closed while the application was still attempting to show it during database connection. The window now checks if it's still loaded before attempting to display.

  • Bug Fix Store Manager cloud save no longer fails silently

    If your store settings can't be saved to the cloud, you'll now see a warning message explaining why, and your changes will remain unsaved so you can try again once the issue is resolved.

  • Bug Fix Vendor dropdown now populates offline during store setup

    If your store has limited internet access or firewall restrictions, you can now complete the initial setup screen — the vendor selection dropdown will always show available vendors.

  • Bug Fix Vendor dropdown now works offline during store setup

    If your internet connection is down or blocked, you can still select your vendor from the dropdown when setting up Margin Master.

  • Bug Fix Identity column handling in API proxy sync path

    At stores where the firewall blocks direct database access, cloud sync would fail with "duplicate key" errors when downloading Ace Hardware taxonomy data. This is now fixed and sync will complete successfully.

  • Bug Fix Accurate error messages for mailbox download failures

    When you can't download a mailbox file, the error message now tells you exactly what went wrong—whether the file is no longer available, your connection failed, or something else—so you know whether to contact IT or simply refresh and try again.

  • Bug Fix More accurate DIB mailbox error messages

    When downloading from your Do it Best mailbox fails, you'll now see exactly what went wrong—whether it's a connectivity issue, a file that's no longer available, or simply nothing being selected—rather than always being directed to check firewall settings.

  • Bug Fix Fixed catalog SKU list population for Do-It-Best

    The full list of available Do-It-Best catalog items now displays correctly when opening the "Add Item from Catalog" dialog.

  • Bug Fix DIB + multi-store POS systems now insert to individual tables

    Adding catalog items now works correctly when your POS system tracks multiple stores in separate tables.

  • Bug Fix Corrected batch cleanup after creation errors

    Fixed an issue where batch IDs were captured before database insertion, causing the ID to be recorded as 0. This prevented proper cleanup when batch creation failed, leaving orphaned records. The system now captures the correct database ID and can properly clean up incomplete batches if an error occurs.

  • Bug Fix Improved batch cleanup on errors

    Fixed an issue where the batch ID was recorded before being saved to the database, causing cleanup routines to fail when errors occurred. Batch IDs are now captured after database insertion, ensuring that failed batch attempts are properly cleaned up and don't leave orphaned data.

  • Bug Fix Fixed sync timeout on Ace MAP pricing updates for large stores

    Ace Hardware stores with large product catalogs will no longer experience sync failures when updating MAP pricing.

  • Bug Fix RSC column visibility correction in Store Matchup

    Fixed the RSC (Retail Service Center) column visibility binding to use the correct format, ensuring it displays only when multiple RSCs are available in the dataset.

  • Bug Fix Store dropdown now always includes "ALL" option

    The Store dropdown now always shows "ALL" at the top, even if you only have one store.

  • Bug Fix Ace Hardware zone overrides now preserved during migration

    For Ace Hardware stores with manually set zone overrides, the zone assignments will now be preserved when upgrading to the new store manager system.

  • Bug Fix Ace Hardware zone overrides now migrate to Store Manager

    Zone number overrides for Ace Hardware stores are now correctly migrated from legacy GlobalFileConfig (ZONE_OVERRIDE) to the Store Manager. When multiple department-specific zone overrides exist for a store, department 1 takes precedence. Previously, these overrides were lost during migration.

  • Bug Fix Store sync now only updates changed stores

    Syncing store settings is now faster because only stores with actual changes are updated.

  • Bug Fix Zone validation now triggered for all stores

    Zone numbers are now properly validated for all stores, including excluded stores.

  • Bug Fix False error telemetry for Ace stores without zone data

    Ace Hardware stores that haven't synced zone pricing yet will no longer generate unnecessary error reports during store setup.

  • Bug Fix Store Manager now detects and reports cloud API failures

    If the cloud doesn't confirm your store settings were saved, you'll see a warning and can retry the save instead of losing your changes.

  • Bug Fix Automatic recovery for affected stores

    If your store previously had sync errors mentioning "AceTaxonomyRecords" or "duplicate key," the next sync will succeed automatically without requiring any action.

  • Bug Fix Eliminated duplicate Do-it Best search results

    When searching for Do-it Best catalog items, you'll no longer see the same item listed multiple times.

  • Bug Fix Bin tag printing script error resolved

    Bin tag printing now works correctly without showing script error messages. Barcodes still automatically hide when product codes are missing.

  • Bug Fix Store dropdown now always includes "ALL" option

    The Store dropdown now always shows "ALL" at the top, making it easier to add items to every store at once.

  • Bug Fix Support Issues empty state no longer conflicts with error messages

    When viewing a support ticket with an error, you'll no longer see the confusing "No messages yet" text at the same time as the error message.

  • Bug Fix Full re-import now handles MySQL zero-date rows correctly

    Full data imports will now correctly include all items, even those with missing or invalid update dates.

  • Bug Fix Fixed overflow errors with large store or vendor numbers

    Store or vendor numbers larger than 2 billion no longer cause sorting problems.

  • Bug Fix Database rename tolerates non-critical SQL messages

    Fixed the database rename RESTORE operation to distinguish between actual SQL errors and non-critical informational messages (version conversion notices, file relocation messages). The system now only fails if the database wasn't actually created, matching the behavior of the working RestoreDatabaseViewModel.

  • Bug Fix Duplicate department row cleanup

    Added logic to detect and remove duplicate department zone rows during initialization, ensuring each store/department combination appears only once in the assignment grid.

  • Bug Fix Removed broken sorting workaround for large store numbers

    Replaced the previous sorting implementation that used int.TryParse, which failed on store numbers larger than 2.1 billion and couldn't handle leading zeros correctly. The old PadLeft workaround has been removed and replaced with .NET's built-in numeric ordering that handles all numeric formats correctly.

  • Bug Fix Store number comparison now ignores leading zeros

    Items imported with store numbers like "06" will now correctly match store "6" in the system.

  • Bug Fix SKU column width in SKU Lookup

    Fixed excessively wide SKU column in the SKU Lookup view by changing from Auto width to fixed 110px width, improving the layout and making more room for other columns.

  • Bug Fix Store number validation accepts any digit count

    Store number fields now accept store numbers of any length (previously required at least 4 digits).

  • Bug Fix Catalog Lookup memory leak eliminated

    Removed manual CancellationTokenSource management from CatalogLookupViewModel. The new AutoSuggestSearchBehavior handles cancellation internally, preventing potential memory leaks from undisposed cancellation tokens.

  • Bug Fix Restore Database callable from main app

    Restoring a database from the main File menu now works consistently with the startup flow.

  • Bug Fix Splash screen visibility during database dialogs

    The loading screen no longer appears on top of database setup windows.

  • Bug Fix Fixed SKU lookup grid column width conflict

    Changed SkuLookupView GridColumn Width from "*" to auto to prevent conflict with AutoWidth property, avoiding layout calculation errors.

  • Cloud Sync Removed redundant vendor data update for Do-It-Best

    Do-It-Best catalog sync now completes faster—you'll no longer see the "Updating from vendor data..." progress message.

  • Cloud Sync Automatic HTTPS fallback for firewall-restricted networks

    If your network blocks cloud database connections, the sync will now automatically switch to a secure web-based method that works through standard HTTPS—you'll see a message confirming the switch, but sync will complete normally.

  • Cloud Sync Automatic HTTPS fallback for firewall-restricted networks

    If your network or firewall blocks database connections, cloud sync will now automatically switch to a secure web method without requiring any configuration changes or IT support.

  • Cloud Sync Automatic fallback to API proxy on network connection errors

    When your network or firewall blocks the normal sync connection, Margin Master will automatically switch to a backup connection method and complete the sync without you needing to do anything.

  • Cloud Sync Cloud-based store settings storage

    Your store settings (vendor numbers, RSC codes, zones) now sync with the cloud, so changes made on one computer will appear on others in your organization.

  • Cloud Sync Store Manager cloud synchronization

    Store Manager now loads and saves POS store settings to the cloud, including vendor store numbers, RSC codes, zone overrides, and exclusion flags. Settings are automatically downloaded when the screen opens and saved when it closes or when the Save button is clicked. This ensures store configuration is consistent across installations.

  • Cloud Sync RSC codes now retrieved from cloud Stores table

    When you enter a vendor store number, the RSC code will automatically fill in if it's available in your cloud account, reducing manual data entry.

  • Cloud Sync Catalog sync status refreshes more frequently

    When checking for new vendor catalog files, you'll now see newly published catalogs within 2 hours instead of waiting up to a full day.

  • Cloud Sync New cloud API endpoint for catalog SKU detail

    Added GET /api/v2/CatalogLookup/{vendorType}/{sku} endpoint to ApiClientService to fetch master catalog details from the cloud for comparison. Returns SKU details, description, pricing history, and zone pricing records when available.

  • Cloud Sync Defensive table name handling

    Added belt-and-suspenders protection against schema prefix mismatches by normalizing table names on the client side, complementing the server-side fix already deployed in Manager. This ensures sync reliability regardless of which server version stores are running.

  • Cloud Sync Improved table name compatibility

    The sync proxy now consistently handles both qualified ("dbo.AceCatalogRecords") and unqualified ("AceCatalogRecords") table names across all sync operations including schema retrieval, pending row counts, and batch fetching.

  • Cloud Sync Improved reliability of incremental sync operations

    This fix ensures the RowVersion-based incremental sync mechanism works correctly by properly handling the version tracking data sent from the cloud API. Without this fix, sync operations would fail when attempting to store RowVersion data in the local database.

  • Cloud Sync Improved RowVersion handling for incremental sync

    Enhanced the logic that processes RowVersion values received from the cloud API by checking the column name first, then properly extracting the hex string value regardless of whether it arrives as a JsonElement or plain string before converting it to the required byte array format.

  • Cloud Sync Version history cloud sync on startup

    The app now automatically downloads version history from the cloud when you start Margin Master and tracks which versions have been installed on your computer.

  • Cloud Sync Version history synchronization

    Margin Master now automatically downloads and saves version history in the background, so you can view release notes even if you're offline.

  • Cloud Sync Cache cloud settings for faster lookups

    Cloud store settings are now cached during initialization and reused when vendor store numbers change, improving responsiveness when editing multiple stores without requiring repeated cloud queries.

  • Cloud Sync Enhanced demo database management

    The demo reset and cloud upload features now correctly identify specific demo databases using the hierarchical DatabaseKey system. When updating the cloud demo database, the system matches against both the vendor key and specific database key to ensure the correct demo is uploaded or downloaded.

  • Cloud Sync RSC alternate code synchronization

    The cloud sync process now includes the AlternateCode field when downloading and updating retailer soft code records from the server, ensuring local data stays current with vendor-provided alternate identifiers.

  • Cloud Sync Alternate code synchronization enabled

    The cloud sync process now includes alternate codes when downloading and updating vendor catalog information from Ace Hardware and Do-It-Best.

  • Cloud Sync Settings changes pushed to Manager server

    When you save settings changes, they now automatically sync to the cloud in the background.

  • Cloud Sync Proxy-aware schema and key detection

    SchemaMirror and RowVersionTableSync now accept an optional ICloudSyncProxy parameter. When provided, schema introspection (column definitions, primary keys, identity flags) and row operations (count pending, fetch batch) use the proxy's HTTP endpoints instead of direct sys.columns and sys.indexes queries. Table key detection falls back to the schema endpoint's primary key metadata when operating in proxy mode.

  • Cloud Sync Network error detection now checks all connection failure types

    Expanded network connection error detection to recognize SQL error codes 53 (named pipes/server not found), 258 (TCP wait timeout), and -1 (network connection lost). Previously only error 53 triggered proxy fallback, which meant timeout failures on Azure SQL redirect ports would not trigger the automatic retry mechanism.

  • Cloud Sync Enhanced error detection for SQL network failures

    Expanded the network error detection logic to recognize additional SQL error codes: 53 (server not found), 258 (TCP wait timeout), and -1 (network connection lost). User-facing error messages now consolidate these errors and explain that Margin Master will automatically retry via the secure API.

  • Cloud Sync Zone overrides and exclusion flags applied from cloud

    Store exclusion settings and zone overrides from your cloud account now automatically sync to the Store Manager.

  • Cloud Sync Connection test with 5-second timeout

    Added CloudConnectionService.TestDirectConnectionAsync() to probe SQL connectivity before sync. Uses a 5-second timeout to avoid blocking the UI; failure triggers proxy mode activation.

  • Data Import Enhanced catalog field mapping

    Catalog items you add now include more complete information like pricing levels, velocity codes, and manufacturer details, giving you better analysis data.

  • Data Import Automatic cleanup of discontinued manual catalog items

    When updating your vendor catalog, items you manually added that are no longer available from the vendor will be automatically removed from your catalog.

  • Data Import Auto-cleanup discontinued manual catalog items

    Items you manually added to the catalog that have been discontinued by the vendor are now automatically removed when the catalog is rebuilt, keeping your data clean and up-to-date.

  • Data Import BisTrack import performance optimized with materialized vendor data

    Modified RSImportFileHelperService to materialize MMVendorData into a staging table (BisTrackVendorDataStaging) once at the start of the import process, then re-use it for all stores. Previously the view was re-evaluated for every store, causing expensive CROSS APPLY + BETWEEN range joins against DIBPriceLevelRoundingDetails (~327K rows). The staging table is indexed on (SKU, RSC) and dropped after import completes. Updated BisTrackInsertIntoMainTable.sql to reference the staging table via a new {vendorDataTable} variable (version bumped to 1.1).

  • User Interface Two-panel vendor and database selection

    When entering demo mode, you now first select a vendor, then choose from their available demo databases in a side-by-side view.

  • User Interface Hierarchical vendor and database selection

    The demo mode selection screen now shows vendors on the left and available demos on the right, making it easier to find the demo you want.

  • User Interface Added Local Sync column to Vendor Catalog Data table

    Each vendor catalog file now shows two dates: "Cloud Date" (when the file was last updated in the cloud) and "Local Sync" (when you last downloaded it). This makes it easy to see which catalogs need updating.

  • User Interface Add Local Sync column to catalog file listing

    When viewing data aging information, you'll now see two dates for each vendor file: the cloud processing date and the local sync date. This helps you understand if newer data is available in the cloud but hasn't downloaded to your computer yet.

  • User Interface Catalog Lookup screen redesigned to match web layout

    The Catalog Lookup screen now has a simpler layout with search results appearing in a dropdown instead of a separate side panel, making it easier to focus on product details.

  • User Interface Redesigned Catalog Lookup screen layout

    The Catalog Lookup screen now shows product details in a wider, easier-to-read layout that matches the web version, instead of splitting the screen between search results and details.

  • User Interface Modern auto-suggest search for catalog lookup

    The catalog search box now filters results as you type, with faster and more reliable text entry.

  • User Interface Catalog Lookup search redesigned with AutoSuggestEdit

    The Catalog Lookup search bar now shows matching items instantly as you type, with matching text highlighted in the dropdown suggestions.

  • User Interface Data Aging screen filtered to store's RSC catalogs

    If your store uses Do-It-Best, the Data Aging screen now shows only the catalogs you actually sync instead of all 8 regional catalogs.

  • User Interface Visual indicator for overridden zone assignments

    Zone numbers you've changed appear in blue bold text. Hover over them to see what Ace originally assigned.

  • User Interface Auto-clear search after adding catalog item

    When you add a catalog item, the search box now clears automatically so you can type the next SKU right away without having to delete the previous search.

  • User Interface Clear search box after adding catalog item

    When you add a catalog item, the search box now clears automatically so you can immediately start typing your next search without having to manually delete the previous text.

  • User Interface Search/Bulk mode toggle replaces Tools menu

    Instead of hunting for a Tools menu, you now see Search and Bulk buttons right at the top of the dialog. Click Bulk to paste a list of SKUs and add them all at once.

  • User Interface Mode toggle added to Add from Catalog dialog

    Click the "Search" or "Bulk" radio button at the top to choose how you want to add items—either by searching one at a time or by pasting a list of SKUs.

  • User Interface Simplified department view with toggle

    Zone overrides now apply to all departments at once by default. Check "Show by Department" if you need to set different zones for individual departments.

  • User Interface Split zone display into two columns

    You can now see both the Ace-assigned zone and your custom zone override in separate columns, making it easier to tell which stores have been manually adjusted.

  • User Interface Zone columns split into assigned and override

    You can now see both the Ace-assigned zone and your custom zone override in separate columns, making it easier to understand which value is being used.

  • User Interface Per-row delete button added to Store Manager grid

    You can now delete a store by clicking the red X button at the end of its row, instead of having to select it and use the delete button.

  • User Interface Per-row delete button added to Store Manager grid

    You can now delete a store by clicking the red X button at the end of its row, instead of selecting it and using the Delete Selected button.

  • User Interface Increased Add from Catalog dialog size

    The Add from Catalog window is now larger, making it easier to browse and select items.

  • User Interface Enlarged Add from Catalog dialog window

    The Add from Catalog window is now larger, making it easier to browse and select items.

  • User Interface Improved spacing in SKU search results

    Search results in the Ctrl+F dialog now have better spacing and are easier to read.

  • User Interface Improved Ctrl+F search result spacing

    Search results in the Ctrl+F quick search dialog now have better spacing, making highlighted matches easier to read.

  • User Interface Unified database screen navigation

    Database setup screens now have matching menus at the top. You can easily switch between connecting to an existing database, creating a new one, restoring from backup, or using the demo database without closing and reopening windows.

  • User Interface Database screen navigation consolidated

    Database setup screens now have File menus that let you switch between connecting, creating, restoring, or using a demo database without closing windows.

  • User Interface RSC location names added to catalog display

    Catalog names now show the warehouse location (like "Dixon, IL") so you can easily see which regional catalog you're viewing.

  • User Interface Display RSC location names in Data Aging screen

    Catalog names now show the distribution center location (e.g., "Dixon, IL") for easier identification.

  • User Interface More accurate freshness warnings during POS import

    You'll only see warnings about outdated vendor data when the vendor has actually published updates you haven't downloaded yet.

  • User Interface Bulk mode now includes inline text area

    When in Bulk mode, you can paste your SKU list directly into the text box and click "Look Up & Add" without opening another window.

  • User Interface Improved sync progress messaging for firewall detection

    The sync screen now shows a clear message when it detects a firewall and switches to the backup connection.

  • User Interface Visual zone-type badges in store list

    Stores now show colored badges: gray "N" means using national pricing, red "A" means using Ace's assigned zone, and orange "O" means a custom zone override is active.

  • User Interface Visual indicator for unmapped stores in Zone Assignment

    Stores that aren't mapped to your POS system are now shown with strikethrough text and you can't edit their zone assignments, making it clear which stores need setup.

  • User Interface Dynamic vendor-specific column header for store numbers

    The store number column now shows your vendor's name (like "Ace Store #" or "Do It Best Store #") instead of the generic "Vendor Store #".

  • User Interface Dynamic vendor-specific column header in Store Manager

    The vendor store number column now shows your vendor's name (like "Ace Store #" or "Do It Best Store #") instead of the generic label.

  • User Interface Store Manager Save and Close buttons upgraded to SVG icons

    Save and Close buttons in Store Manager now have sharper, higher-quality icons.

  • User Interface Fixed sorting in dropdown filter lists

    Dropdown lists with numeric values now show options in the correct numeric order, making it easier to find specific codes.

  • User Interface Updated sorting across multiple screens

    Store numbers and vendor codes in dropdown menus, filter lists, and summary screens now appear in intuitive numeric order throughout the application.

  • User Interface Clarified database connection instructions

    The initial database connection screen now has clearer instructions about where to enter your store information.

  • User Interface Improved guidance message for missing credentials

    When a database is missing vendor or store information, the app now gives clearer instructions on how to fix it.

  • User Interface Catalog Lookup dialog with split-pane layout

    The search results appear on the left side; click any SKU to see full details on the right including pricing, vendor information, and cloud sync status.

  • User Interface Redesigned Connect to Database screen

    The Connect to Database screen is now simpler with the Connect button right next to the database list.

  • User Interface Type-to-filter support added to dropdown lists

    You can now type to quickly filter dropdown lists like vendor names, POS systems, and SQL servers instead of scrolling through the full list.

  • User Interface Inline bulk entry replaces modal dialog

    You can now type or paste SKUs directly in the Bulk mode panel without opening a separate window.

  • User Interface Loading indicator added during file import and lookup

    The screen now shows a loading indicator when importing large Excel files or looking up many SKUs at once.

  • User Interface Dynamic dialog title and menu item renamed

    The Ace zone assignment window title now clearly indicates whether you're working with individual stores or store groups.

  • User Interface Help menu renamed from "What's New" to "Version History"

    The Help > What's New menu item has been renamed to Help > Version History and now opens the new in-app VersionHistoryView window instead of launching a web browser. The startup prompt that previously asked "View What's New?" now displays "View Version History" and opens the same in-app window. The "Show What's New at Startup" checkbox remains functional and controls whether the prompt appears after version updates.

  • User Interface Ace Zone Pricing dialog improvements

    The Ace zone pricing setup screen now shows color-coded badges (N, A, or O) to quickly identify which stores use national pricing, Ace zones, or custom overrides. You can also toggle between simple one-line-per-store mode and detailed per-department mode.

  • User Interface Zone Override uses numeric spinner control

    Zone overrides can now be adjusted using up/down arrows, and only valid numbers are accepted.

  • User Interface Store Manager default sort changed to POS Store Number

    Stores now appear in the same order as your POS system instead of by vendor store number.

  • User Interface Save button added to Store Manager

    Click the Save button in Store Manager to save your store settings to the cloud.

  • User Interface Active stores configuration summary in footer

    The bottom of the Store Manager now shows how many stores are fully set up (e.g., "8 of 10 stores fully configured") so you can see at a glance if any stores need attention.

  • User Interface Active store configuration summary footer

    The bottom of the Store Manager now shows how many of your stores have all required information filled in (e.g., "12 of 15 stores fully configured").

  • User Interface Corrected store number ordering in sync change summary

    After syncing, the list of stores with changes now appears in numeric order.

  • User Interface Clearer messaging for common mailbox scenarios

    If you try to download a file that's already been retrieved or has expired, the message now tells you that directly and suggests clicking Refresh, rather than suggesting firewall changes.

  • User Interface Dialog title shows full vendor name

    The Add from Catalog window now shows your vendor's full name in the title bar instead of an abbreviation.

  • User Interface Catalog add dialog column sizing improvements

    The "Add from Catalog" dialog now uses BestFitMode for automatic column sizing and disables AutoWidth, providing better readability for SKU and description columns in both the search results grid and the items-to-add grid.

  • User Interface Redesigned Restore Database screen

    The Restore Database screen now matches the look and feel of other database screens and includes a help button in the header.

  • User Interface Dialog height increased for better bulk entry visibility

    The dialog height was increased from 450 to 460 pixels to accommodate the mode toggle controls and provide more comfortable text entry space in Bulk mode.

  • User Interface Sync Dialog displays firewall detection status

    The sync screen will let you know if it's using the firewall-friendly connection method, so you understand why the initial connection test takes a few extra seconds.

  • User Interface Help menu reorganization

    The Help menu now says "Version History" instead of "What's New" and opens release notes inside Margin Master rather than your web browser.

  • User Interface Save button and auto-save on close

    A new Save button appears when you make changes to store settings. Changes are also automatically saved when you close the window.

  • User Interface Catalog Add dialog redesigned for search workflow

    The "Add Catalog Items" screen now has a search box at the top where you type to find products by SKU or description.

  • User Interface Auto-sized grid columns in catalog dialog

    Column widths in the Add from Catalog dialog now automatically adjust to fit the content, making it easier to read long SKUs and descriptions.

  • User Interface Type-to-filter enabled on all dropdowns

    All dropdown lists in database screens now let you type to filter options, making it faster to find what you need.

  • User Interface Store number validation relaxed

    Store numbers of any length are now accepted as long as they contain only digits.

  • User Interface Sync Dialog status messaging for proxy mode

    When the firewall fallback activates, the Sync Dialog now displays "Firewall detected — syncing via secure API..." to inform users the system is operating in HTTPS proxy mode. All vendor sync operations (Ace, DIB, EJ, Orgill, United) support the proxy path.

  • User Interface WebBrowser control with HtmlContent attached property

    Added WebBrowserHelper attached property to enable data-binding for WebBrowser.NavigateToString in WPF. The VersionHistoryView uses this to render PublicHtml release notes directly in the detail pane without external web navigation.

  • User Interface Database restore documentation added

    Adds comprehensive database-restore.md with user and support documentation covering backup location, available backups, backup metadata, restore settings, SQL authentication, tips, common questions, and technical details. Added to docs/index.json for search.

  • Database Local database schema update for RSC alternate codes

    Added AlternateCode column to the local Rscs table with automatic migration. The migration detects existing databases without the column and adds it seamlessly on next application startup.

  • Database Local database schema updated for alternate codes

    The Rscs table schema has been updated to include the AlternateCode column. An automatic migration adds this column to existing databases during the next sync or startup.

  • Database Add LocalSyncDate property to catalog status model

    Enhanced the CatalogFileStatus model to include a LocalSyncDate field, which is populated from the local SyncHistory table when the Data Aging view loads. This allows the application to cross-reference cloud catalog processing dates with local synchronization timestamps.

  • Database LocalVersionHistory table for install tracking

    Created a new LocalVersionHistory table with fields LocalVersionHistoryId, Version, PublishedAt, BriefSummary, PublicHtml, InstalledAt, and SyncedAt. The table is created automatically on first startup via CreateLocalVersionHistoryTable.sql script and uses a MERGE statement to sync cloud data while preserving local InstalledAt timestamps.

  • Database New OrgPosStoreSettingDto model

    Added a new data transfer object (OrgPosStoreSettingDto) to represent cloud-stored store settings, including PosStoreKey, VendorStoreNumber, RSCCode, ZoneOverride, and IsExcluded fields. This model is used by the new cloud sync API endpoints.

  • Database ManualCatalogItems tracking table

    New ManualCatalogItems table created with columns for ID, SKU, Store, VendorType, Description, and CreateDate. Includes unique index on (SKU, Store, VendorType) to prevent duplicate tracking entries. Table creation is idempotent and runs automatically during database updates.

  • Database LocalVersionHistory table

    Added new LocalVersionHistory table with fields for Version, PublishedAt, BriefSummary, PublicHtml, InstalledAt, and SyncedAt. Table is created automatically via SQL script on first run. Unique constraint on Version ensures no duplicates. InstalledAt is null for versions never installed on this machine, allowing distinction between cloud-synced releases and locally-installed versions.

  • Database New OrgPosStoreSettingDto for cloud API communication

    Added OrgPosStoreSettingDto to MarginMaster.Common as a data transfer object for the new GetOrgStoreSettingsAsync and SaveOrgStoreSettingsAsync API methods. The DTO includes PosStoreKey, VendorStoreNumber, RSCCode, ZoneOverride, and IsExcluded fields.

  • Database ManualCatalogItems table creation

    Added automatic creation of the ManualCatalogItems tracking table during database updates, with fields for SKU, Store, VendorType, Description, and CreateDate. Includes a unique index on (SKU, Store, VendorType) to prevent duplicate tracking entries.

  • Architecture ICloudSyncProxy abstraction for vendor catalog sync

    Introduced a new proxy interface that decouples the sync engine from direct SQL Server access. The ApiCloudSyncProxy implementation translates schema queries, row counts, and batch fetches into REST API calls. ProxySyncFilter replaces raw SQL filters with serializable parameters (zone, vendor, store numbers, RSC numbers, scheme IDs) that can be safely transmitted over HTTP and reconstructed server-side. All existing sync features—incremental RowVersion sync, batch size optimization, count validation, and out-of-scope pruning—work identically in proxy mode.

  • Architecture ICloudSyncProxy abstraction layer

    Introduced ICloudSyncProxy interface to decouple cloud data reads from direct SQL, implemented by ApiCloudSyncProxy which calls Manager API endpoints (/schema, /count, /rows). SchemaMirror and RowVersionTableSync now accept optional proxy and route all cloud queries through it when present.

  • Architecture Consolidated duplicate migration logic

    Refactored the migration code to share a common InsertMissingStorematchupEntriesAsync helper between the one-time migration process and the supplemental catch-up routine that runs on each startup. This ensures both code paths apply the same RSC and zone override population logic.

  • Architecture Typed exception handling for mailbox operations

    Introduced DIBMailboxFailureException with specific failure kinds (NothingSelected, Connection, FileNotInMailbox, TransferIncomplete) to distinguish between failure scenarios. This replaces generic exceptions that couldn't convey why an operation failed, enabling the UI to display contextually appropriate messages and guidance.

  • Architecture Backward compatibility with legacy demo API

    The application automatically falls back to the older flat demo list API if the new hierarchical vendor/database endpoint is unavailable, ensuring compatibility with older server versions during the transition period.

  • Architecture Multi-RSC support in Data Aging screen

    The Data Aging screen now properly handles stores configured to sync multiple RSC codes, mirroring the same logic used during actual sync operations to determine which RSCs apply to the store.

  • Architecture Catalog Add Items ViewModel refactored with testable file reader

    Extracted file-reading logic (Excel/text parsing, column detection, SKU extraction) from CatalogAddItemsViewModel into a new CatalogSkuFileReader class. Added a full xUnit test suite (CatalogSkuFileReaderTests and CatalogAddItemsViewModelTests) covering single-column files, multi-column auto-detection, header-row detection, store-column handling, and end-to-end import flows. Also added InternalsVisibleTo to make internal components testable without exposing them publicly.

  • Architecture Store settings retrieval enhanced with bundled data

    The cloud API now returns store settings bundled with a map of vendor store numbers to RSC codes from the Stores table. This bundle is cached in memory during Store Manager initialization and reused when vendor store numbers change, improving performance and reducing redundant API calls.

  • Architecture Version history service layer

    Introduced IVersionHistoryService with methods for table creation, cloud sync, installed version stamping, and querying history with optional filtering. Service integrates with ApiClientService (new GetVersionHistoryAsync endpoint with 24-hour cache TTL) and uses Dapper for local database operations.

  • Architecture Database screen navigation enum and service methods

    Adds DatabaseScreenNavigation enum (None, ConnectToDatabase, CreateNew, RestoreBackup, DemoDatabase) for cross-screen routing. DatabaseConnectionService now implements navigation loop pattern to show child screens without recursive ShowDialog nesting. CreateNewDatabaseViewModel and other VMs track NavigationRequest and IsStartupFlow properties to coordinate screen transitions.

  • Documentation Zone override instructions and guidelines

    Help documentation now explains how to change store zones and when you might need to do this.

  • Infrastructure ProxySyncFilter serializable filter model

    Added ProxySyncFilter class to safely translate table filter parameters (zone, vendor, RSC numbers, store numbers, scheme IDs) into HTTP query strings for the API proxy. This avoids sending raw SQL over the wire while preserving all filter intent for server-side reconstruction.

  • Infrastructure Session-level RSC caching

    Results from live RSC lookups are now cached in memory for the duration of the session. This prevents multiple API calls when processing multiple stores with the same vendor store number during a single work session.

  • Infrastructure Enhanced logging for mailbox connectivity issues

    Connection and login failures are now logged at Error level instead of Warning, ensuring they reach cloud telemetry. Each failure type (connection, missing file, incomplete transfer, or empty selection) is logged with detailed context including mailbox name, host, and port, making customer issues visible to support without requiring manual log collection.

  • Infrastructure Backward compatibility with flat API responses

    Maintains compatibility with older Manager API servers that return a flat list of demo databases by automatically grouping them by vendor when the v2 hierarchical endpoint is unavailable. Demo mode state now tracks both VendorKey and DemoDatabaseKey for accurate reset and cloud update operations.

  • Infrastructure License service enhanced with settings push capability

    Added a new RefreshLicenseSettingsInBackground method to the License Validation Service that pushes current store configuration (RSC and POS type) to the Manager server via the ValuesDictionary parameter in the license request. Unlike the startup license refresh, this method executes immediately since it's user-initiated. The RSC and POS system type are now included in all license validation calls to keep the server synchronized.

  • Infrastructure Server-side authentication configuration improved

    Root cause of 401 authentication errors was resolved server-side by adding Manager--JwtSettings--SecretKey to Azure Key Vault, ensuring proper JWT token validation.

  • Infrastructure Documentation updated for new UI

    Updated the Add from Catalog help document and search index to reflect the new Search/Bulk mode toggle UI, removing references to the Tools menu and Enter Bulk List modal, and adding guidance on the new inline workflow.

  • Infrastructure Auto-deploy tool now publishes to version history API

    The AutoUpdateDeploy tool now posts to /api/version-history after each build, submitting BriefSummary (auto-generated from top 3 items), PublicHtml (customer-facing release notes), AdminHtml (includes GitHub commit links), GitCommit hash, GitHubReleaseUrl, and JSON-serialized PosSystemsAffected/VendorsAffected arrays. This parallels the existing /api/releases endpoint and populates the new AppVersionRelease cloud entity.

  • Infrastructure Cloud API endpoints for store settings

    Added GetOrgStoreSettingsAsync and SaveOrgStoreSettingsAsync methods to ApiClientService, enabling retrieval and storage of organization-wide POS store settings via the api/v2/OrgStoreSettings endpoint.

  • Infrastructure Removed obsolete SemiNumericComparer class

    Deleted the legacy SemiNumericComparer helper class that has been superseded by the new NumericStringComparer. Added comprehensive unit tests to ensure the new comparer handles edge cases like leading zeros, very large numbers, and null values correctly.

  • Infrastructure WebBrowser HTML binding helper

    Added WebBrowserHelper attached property to enable XAML data binding for WebBrowser.NavigateToString, used in the Version History window to display HTML changelogs from view model bindings.

  • Documentation Add from Catalog feature guide

    Added comprehensive documentation covering the Add from Catalog feature, including how persistent tracking works, field mappings for both vendors, step-by-step usage instructions, and technical details about the tracking table structure.

  • Infrastructure AutoSuggestSearchBehavior added

    Created new AutoSuggestSearchBehavior (Xaml/Behaviors/AutoSuggestSearchBehavior.cs) to bridge AutoSuggestEdit's QuerySubmitted event to async search functions in ViewModels. AutoSuggestEdit requires ItemsSource to be set synchronously during the event (standard XAML binding doesn't work), so the behavior calls the ViewModel's search delegate and sets ItemsSource directly. Includes configurable debounce delay (default 300ms) and minimum character count (default 3).

  • Infrastructure DatabaseScreenNavigation enum added

    Added DatabaseScreenNavigation enum to support navigation between database setup screens (None, ConnectToDatabase, CreateNew, RestoreBackup, DemoDatabase). Child dialogs return navigation requests to the parent DatabaseConnectionService, which dispatches the next screen without recursive ShowDialog() nesting.

  • Infrastructure Unit testing framework added

    Added MarginMaster.Tests project with xUnit, Microsoft.NET.Test.Sdk, and ClosedXML dependencies. Integrated into the solution for automated testing of ViewModels and file-parsing logic.

  • Documentation Database Restore documentation added

    Added comprehensive documentation for the Restore Database feature at docs/marginmaster/getting-started/database-restore.md, covering backup sources (local files, cloud storage), restore settings, metadata display, and common troubleshooting scenarios.

  • Infrastructure AutoSuggestSearchBehavior for MVVM async search

    New reusable behavior bridges DevExpress AutoSuggestEdit (which requires synchronous ItemsSource setting) with async ViewModel search functions. Handles debouncing, cancellation, and minimum character requirements. Accepts SearchFunction delegate and SuggestionChosenCommand from ViewModel.

User Interface

  • New Feature Restore Backup option during startup

    When starting Margin Master, you can now click "Restore Backup" to restore your database from a backup file, which will automatically connect you to the restored database.

  • New Feature Support Issue History menu option

    Click "Support Issue History" in the Help menu to see all support tickets your store has submitted, including open and closed issues. You can add comments or reopen old issues if needed.

  • New Feature Issue Contact editor dialog

    When submitting support issues, you can now update your contact details (name, email, phone) by clicking Help > Support Issues > Issue Contact. The phone number field will automatically format your entry with parentheses and dashes.

  • New Feature Password-protected Support Scripts button in Database Setup

    Support technicians can now run database maintenance scripts from the initial setup screen without needing to fully connect to the database first.

  • New Feature Support Issues management screen

    Open the "Support Issues" screen from the Help menu or click the red notification badge to view and manage all your support tickets in one place with a chat-style interface.

  • New Feature SQL script clipboard copy in Installation Scripts

    Support staff can now copy the database creation script directly from the Installation Scripts screen and paste it into SSMS for manual database setup.

  • New Feature Auto Update options tab with configurable idle delay

    When an update is available, you can now choose how long the notification waits before installing automatically. Go to Tools > Options (New) > Auto Update and select from Never (manual only), 1 Minute, 5 Minutes, 30 Minutes (default), 1 Hour, or Update on Shutdown (installs silently when you close the app).

  • New Feature Auto Update options tab

    All update settings are now in one place: Tools > Options (New) > Auto Update tab.

  • New Feature Optional note field for issue description

    Type a note in the new "Note (optional)" field to explain what's wrong or provide additional context about the issue you're reporting.

  • New Feature Stable signed bootstrapper for installer downloads

    Created a small WPF launcher application (MarginMaster-Setup.exe) that downloads the full installer from Azure blob storage and displays a branded progress window with download speed and size. Because this bootstrapper's file hash remains stable across Margin Master version updates, it builds Windows SmartScreen reputation over time, reducing security warnings when users download the application.

  • New Feature File > Reconfigure Store menu option

    Click File > Reconfigure Store to update your store number, vendor, POS system, or RSC credentials without closing Margin Master.

  • New Feature Reconfigure Store menu option

    To change your store number or update credentials, click File > Reconfigure Store, enter your information, click Validate, and save. If you changed your store number, you'll need to restart Margin Master.

  • New Feature Schedule an Appointment menu item

    When support appointments are available, a new "Schedule an Appointment" option appears in the Help menu. Clicking it opens your web browser to book a time with the support team.

  • New Feature Schedule an Appointment menu item

    Look for "Schedule an Appointment" in the Help menu to book a one-on-one support session. This option only appears when support slots are available.

  • New Feature Scripts menu with pre-built diagnostic queries

    A new Scripts menu provides ready-to-run diagnostic queries to help troubleshoot MySQL Compass data issues, especially problems with store identifiers showing up incorrectly.

  • New Feature Configurable store number display format

    In Settings > Connections / Epicor, you can now choose how store numbers appear in dropdown lists—for example, showing "1715 (00042)" instead of "00042 (1715)" if you prefer to see your POS store number first.

  • New Feature Update failure tracking and visibility

    If an update won't install, Margin Master now tells you what went wrong and offers to fix it rather than silently staying on the old version.

  • New Feature Install OLEDB 12.0 driver script for RockSolid POS support

    A new script can install the OLEDB driver needed to import RockSolid POS data, automatically detecting and warning about conflicts with 32-bit Office.

  • New Feature Email-style contact editor for issues

    Click the new "Edit Contacts" button next to the contact list to add or remove people from an issue using an easy-to-use contact picker with removable name chips.

  • New Feature Add new contacts directly from issue submission

    When selecting contacts for a support issue, you can now click "Add Contact" to create a new contact on the spot instead of having to go to Settings first.

  • New Feature Issue description and comments panel

    You can now read the full issue description and comments in the right panel before downloading the customer's database.

  • New Feature Update on Shutdown mode

    Choose "Update on Shutdown" to have updates install automatically the next time you close Margin Master, without showing the update notification dialog during your workday.

  • New Feature Configurable auto-update idle delay

    Update notifications now auto-install after 30 minutes if left untouched (you'll see a 10-second countdown first). Change the delay or turn this off in Tools > Options (New) > Auto Update.

  • New Feature Custom file attachment support

    Click "Add Files..." to attach screenshots, Excel files, or other documents that help explain the issue. You can attach multiple files and remove any you don't need.

  • New Feature File attachment support for diagnostic submissions

    Click "Add Files..." to attach screenshots, Excel files, or other documents that help explain the issue you're reporting.

  • New Feature Copy results to clipboard

    A new "Copy to Clipboard" button lets you quickly copy query results to paste into Excel or share with support.

  • New Feature Configurable store number sort order

    The Store Number list can now sort by either your POS store numbers or vendor store numbers, whichever makes it easier to find the store you need.

  • New Feature One-click repair install

    Click "Download and Install Now" and Margin Master will close itself, download the installer, and run it for you—this fixes updates that won't install the normal way.

  • New Feature Edit existing contacts in-place

    You can now click the edit icon next to any store contact to update their name, email, or phone number right from the contact picker.

  • New Feature Rename option when restoring over existing database

    If a database with your restore name already exists, you can now choose to give it a different name instead of only being able to overwrite or cancel.

  • New Feature Update on Shutdown mode

    You can now set updates to install silently when you close Margin Master (Tools > Options (New) > Auto Update > "Update on Shutdown").

  • New Feature Save button for contact changes

    When editing a contact's information, click the new "Save" button to save your changes before moving forward.

  • New Feature Added Edit Contacts dialog with store/support toggle

    Created a new Edit Contacts dialog that allows users to manage which contacts should be notified about a specific support issue. The dialog features an email-To-style chip picker with selected contacts displayed as removable pills at the top, and a toggle to switch between viewing store contacts and support contacts. Selected contacts are shown as colored chips that can be clicked to remove them.

  • New Feature Delete contacts from contact picker

    You can now remove outdated store contacts by clicking the delete icon next to their name in the contact picker.

  • New Feature File attachment support for issue updates

    You can now attach files (like screenshots or documents) when updating support issues, making it easier to share information with the support team.

  • New Feature Require manual approval for auto-updates setting

    A new setting in Options lets you turn off automatic update installation. When checked, Margin Master will notify you about updates but wait for you to approve them instead of installing automatically.

  • New Feature Support Issues management screen

    Open the "Support Issues" screen from the Help menu or click the red notification badge to view and manage all your support tickets in one place with a chat-style interface.

  • New Feature File attachment support for issue updates

    You can now attach files (like screenshots or documents) when updating support issues, making it easier to share information with the support team.

  • Improvement Support scripts now download from cloud storage
  • Improvement Automatic script preloading with freshness detection

    Scripts download automatically in the background when you open the Installation Scripts dialog, so the latest versions are ready immediately when you need them.

  • Improvement Optional note field added to issue submission

    Add a description or notes about the issue you're reporting directly in the Quick Issue dialog.

  • Improvement Smart refresh of selection boxes after Options changes

    After changing how store numbers are displayed or sorted in Options, all store selection dropdowns will automatically update to show your new preference without needing to restart the app.

  • Improvement Background license validation suppressed in demo mode

    Added safeguards to prevent background license status checks from displaying error dialogs while in demo mode. Since demo mode uses a synthetic license that doesn't require validation, these checks are now bypassed entirely during demo sessions.

  • Improvement Demo mode license handling at startup

    License approval checks during application startup now recognize demo mode and skip standard validation, immediately approving the synthetic demo license. This prevents any license-related startup delays or dialog prompts when launching the application in demo mode.

  • Improvement Scripts copied to log folder for support re-execution

    Each executed PowerShell script is now automatically copied to the log folder alongside its execution log. This allows support staff to re-run the exact same script directly on the customer's machine without needing Margin Master, which is helpful for troubleshooting or repeating operations.

  • Improvement Scripts copied to log folder after execution

    When you run a support script, a copy of the script is now saved in the logs folder for your records.

  • Improvement Live issue polling and notification system

    The red support notification badge will now flash when support has responded to your issues or when there's new activity, so you won't miss important updates.

  • Improvement Auto-select issue when opening from notification pill

    Clicking the support issues notification now automatically opens the issue if you only have one, or shows your most recent issue if you have several.

  • Improvement Asynchronous loading of issue descriptions and comments

    Added LoadIssueDetailAsync method that fetches full issue descriptions and comments via GetIssueDetailForDevAsync when an issue is selected. This replaces the previous behavior of only showing attachment lists, providing developers with complete context about each customer issue before downloading files. The detail panel shows a loading indicator while fetching data and displays error messages if the load fails.

  • Improvement Connection window automatically hides during database setup

    The connection window now hides while you're creating or restoring a database, then comes back automatically when you're finished.

  • Improvement Added save verification logging for pricing strategy steps

    Added diagnostic logging to track pricing strategy step order at initial load, before save, and after save. This helps verify that step sequences, rounding settings, and active status are being preserved correctly during save operations. The logging also prevents the strategy from being marked as "dirty" during initial load, avoiding false save prompts.

  • Improvement Legacy/New Settings dialog preference handling

    The choice between the legacy and new Settings dialogs now resets each time you restart Margin Master, so you won't get stuck using one version if you click the preference button by mistake.

  • Improvement Added rename option when restoring to existing database name

    If you restore a backup with a name that already exists, you can now choose to rename it to something else instead of only being able to overwrite the existing database.

  • Improvement Enhanced restore dialog logging for backup file scanning

    The restore dialog now logs the raw count of .bak and .zip files found in the backup folder before processing, plus warnings for any files where header/metadata reads fail (including the file name, exception, and new HeaderStatus field). This gives a clear before/after picture in the log to help diagnose why backups might be missing or why a restore might fail.

  • Improvement Enhanced diagnostic logging for backup file scanning
  • Improvement Database creation script now available in UI

    The full Margin Master database creation script is now accessible through the Installation Scripts screen under the "SQL Server" category. The description clarifies that this script is retained for emergency and manual recovery scenarios, while normal database creation should use the built-in setup wizard. Staff can click "Copy to Clipboard", then paste and execute the script in SSMS to create a fresh database with all required tables, stored procedures, and seed data.

  • Improvement Consistent focus behavior for Reset Vendor Data workflow

    When using Reset Vendor Data, the main window will now properly come back to focus just like it does during regular sync operations.

  • Improvement Main table schema verification progress counter

    When verifying column schemas across multiple main tables (e.g., AceMainTable, OrgillMainTable), the splash screen now shows "Main table X of Y" to indicate progress through the collection, providing visibility when this step processes many vendor tables.

  • Improvement Faster backup file scanning with timeout protection

    The restore window now scans backup files much faster and won't freeze if it encounters a corrupted backup file.

  • Improvement Enhanced debug mode for update testing

    Improved debug mode simulation to allow developers to preview the update installation window without requiring a real update package or installed application. The debug mode now simulates an available update with a test version number and shows the full installation workflow including progress and window display.

  • Improvement .NET 10 Desktop Runtime installation script

    If Margin Master won't launch due to a .NET error, support can now run an automated installer from the Support Tools screen to fix the issue.

  • Improvement Auto-select first checked contact as primary

    When you check the first contact box, they'll automatically become the primary contact. Additional contacts you check will be CC'd on the issue.

  • Improvement Auto-show exception column when SKU overrides exist

    The exception icon column now appears automatically after running a pricing strategy that creates item-level overrides, making it easier to identify which items have special pricing rules.

  • Improvement Streamlined restore workflow at startup

    The restore process automatically configures the restored database as the active connection when initiated from startup, skipping the manual connection step. Progress messages and logging were added to track when databases are restored during the startup sequence.

  • Improvement Session-based password caching for Support Scripts

    You only need to enter the support password once per session instead of every time you open Support Scripts.

  • Improvement System information auto-trimmed from issue descriptions

    Issue descriptions now hide the technical system information when you're viewing your own issues, making them easier to read.

  • Improvement Added direct "Create New Database" command

    Added a new SwitchToCreateNewCommand that allows users to quickly switch to Create New mode from Connect Existing mode without losing their server connection settings. This command is exposed in the new File menu and is enabled only when in Connect Existing mode.

  • Improvement Enhanced attachment summary layout

    The attachments panel has been reorganized within the new layout to better fit the full-screen design, maintaining all existing functionality for viewing and processing database backups, screenshots, and log files while integrating seamlessly with the new detail panel.

  • Improvement Options screen toggle now resets each session

    The Options screen will now default to the new version each time you open Margin Master, but you can still click "Use Legacy" if you prefer the old layout for that session.

  • Improvement Enhanced splash screen display during database operations

    Replaced separate "ShowSplashScreen" and "SetSplashScreenState" calls with a single "ShowSplashScreenImmediate" method for database restore, strategy restore, and settings transfer operations. This ensures the splash screen appears immediately with the correct message and eliminates timing gaps.

  • Improvement Moved auto-update settings from Miscellaneous tab

    The "Automatically check for updates" and "Require approval before applying updates" checkboxes have been relocated from the Miscellaneous tab to the new Auto Update tab, providing a single location for all update-related configuration. The idle delay dropdown is automatically disabled when "Require approval" is checked, since the countdown would be irrelevant when manual approval is required.

  • Improvement Added automatic tab reload when switching between tabs

    Settings tabs now refresh automatically when you switch between them, ensuring you always see current data.

  • Improvement Automatic file compression

    Attached files are automatically compressed using ZIP if they're larger than 100KB and not already compressed (e.g., not .jpg, .pdf, .zip files). Compression progress is shown during upload. This reduces upload time and storage costs while handling already-compressed formats efficiently.

  • Improvement Rebuild respects cancellation between pipeline steps

    When you cancel a rebuild, the system now stops immediately and skips all remaining steps instead of continuing in the background.

  • Improvement Data Aging excludes all-stores aggregate table

    The Data Aging screen now skips the "99999" all-stores aggregate main table when enumerating real stores, preventing it from appearing as a separate store entry in the import history display.

  • Improvement Splash screen ownership tracking prevents conflicts during startup

    Added ownership tracking to the column loading routine so it only hides the splash screen if it was the one that showed it. This prevents one startup operation from closing a splash window that another operation is still actively using, which was a key contributor to the stranded splash issue.

  • Improvement Pre-filled support tickets for update failures

    If you choose "Contact Support" from the update dialog, we already know what failed—just add anything you want to say and send it.

  • Improvement Script execution logging with log viewer

    Script output is now saved to log files that you can view or send to support for troubleshooting.

  • Improvement "Require approval before applying updates" setting

    You can now choose to approve each update manually instead of having them install automatically.

  • Improvement Added File menu command for Create New mode

    Added SwitchToCreateNewCommand that allows users to quickly return to Create New Database mode from the File menu, complementing the existing mode-switching functionality. This command is only enabled when in Connect to Existing mode.

  • Improvement Improved dialog window positioning

    Updated Support Scripts dialogs to open centered over the Database Setup window (CenterOwner) rather than CenterScreen, providing better visual context. Also set the password prompt and scripts window to have the Database Setup as their owner window, improving focus management.

  • Improvement Auto-generated database names with availability checking

    The system now automatically creates your database name based on your store information and checks that it's available, so you don't have to worry about naming conflicts.

  • Improvement Multi-contact support for issues

    Issues can now have multiple people assigned to them, not just the original submitter.

  • Improvement Smart compression for uploaded files

    Attached files over 100KB are automatically compressed before upload, unless they're already in a compressed format (ZIP, JPEG, PNG, PDF, Office documents, etc.). The system displays upload progress with file size information, making large file uploads more transparent.

  • Improvement Show deleted contacts option

    Check "Show Deleted" to see contacts that were previously removed, which appear grayed out and crossed out.

  • Improvement Pre-population of store info from current database

    If you're creating a second database for your store, your store information is automatically filled in from your current database to save time.

  • Improvement Contact list refreshes after modifications

    After you add, edit, or delete a contact, the contact list updates automatically so you always see current information.

  • Improvement Auto-update settings moved from Miscellaneous tab

    Update settings have moved from the Miscellaneous tab to the new Auto Update tab in Options.

  • Improvement Update problem dialog throttled to once per day

    The "Could Not Update" dialog shows at most once a day so it doesn't keep interrupting you.

  • Improvement Downgrade failures now tracked

    If you downgrade to an older version and it doesn't work, Margin Master now tracks that the same way it tracks regular update failures.

  • Improvement Live issue polling and notification system

    The red support notification badge will now flash when support has responded to your issues or when there's new activity, so you won't miss important updates.

  • Improvement User-driven update failures shown immediately

    If you click "Update Now" and it fails, Margin Master shows you the fix-it dialog right away instead of just a notification.

  • Bug Fix Version display consistency across startup and main window

    The version number shown on the startup splash screen now matches the version displayed in the main window title bar.

  • Bug Fix Splash screen version display now matches main window

    The version number shown on the startup splash screen now matches the version displayed in the main window, eliminating confusion about which version of Margin Master is running.

  • Bug Fix Database rename now properly reports SQL errors

    The database rename feature was configured to receive SQL error messages but only checked for progress updates, causing actual errors during the restore step to be silently swallowed. Now properly collects and reports SQL errors using the same pattern as the backup service, and verifies the database actually exists after restore completes.

  • Bug Fix Demo mode license validation errors eliminated

    Demo mode now starts cleanly without showing incorrect license expiration warnings.

  • Bug Fix Demo mode license dialog suppression

    When using demo mode for training or demonstrations, you will no longer see pop-up warnings about license expiration or validation issues.

  • Bug Fix Fixed clipped buttons on startup and configuration dialogs

    You can now see and click all buttons on the Create Database, Store Configuration, Restore Database, and Database Connection screens, even on laptops with smaller screens.

  • Bug Fix Dialog windows now display all buttons and controls

    You can now see and click all buttons in the setup screens, even if you have a smaller monitor or lower screen resolution.

  • Bug Fix Support Scripts menu item now appears in Utilities menu

    You can now access Support Scripts from the Utilities menu as intended.

  • Bug Fix Fixed Support Scripts execution failure

    The "Support Scripts" screen now correctly runs SQL Server and OLEDB installation scripts when you click the Execute button.

  • Bug Fix Support Scripts execution error resolved

    The "Execute" button on Support Scripts now works correctly for all SQL Server and OLEDB installation scripts.

  • Bug Fix Corrected missing attachment button icon

    The attach file button now shows its icon correctly instead of appearing blank.

  • Bug Fix Fixed attach file button icon

    The attach file button in the Support Issues screen now displays the correct attachment icon instead of a generic action icon, making it more visually consistent with standard file attachment controls.

  • Bug Fix Send button now enables with attachments only

    When you attach files to a support request, the Send button will now activate immediately, letting you submit attachments without typing a message.

  • Bug Fix Submit Issue dialog now displays at correct size

    When you click "Create New Issue" from the Help menu, the window now opens at the correct size so you can see the full form including where to type your issue description and the submit button.

  • Bug Fix Dialog windows no longer pin above all applications

    When you open database setup, license configuration, database restore, or support tools windows, they will no longer cover your other open programs like web browsers or email. You can now easily switch between Margin Master dialogs and other applications on your computer.

  • Bug Fix MySQL Compass connection test button not functional

    You can now click the "Test & Save Connection" button in MySQL Compass settings to verify your database connection works before saving it.

  • Bug Fix POS system selection now saves correctly

    When you select your POS system in the Options screen, it will now save properly and remain selected when you restart Margin Master.

  • Bug Fix Settings persistence in Settings dialog

    When you change your POS system or set a primary store in Settings, those changes will now save correctly and persist after closing the dialog.

  • Bug Fix Splash screen now displays continuously during restore operations

    The progress window now stays visible during the entire restore process, showing you what's happening at each step.

  • Bug Fix Restore Database dialog message handling corrected

    When restoring a database backup, you'll now see proper error messages if something goes wrong and confirmation prompts when needed.

  • Bug Fix Submit Issue dialog handles missing database

    When submitting a support ticket without a database loaded, the database backup option is now grayed out and cannot be selected.

  • Bug Fix Restore dialog now lists all backup files regardless of SQL server permissions

    If you're connected to a remote SQL server or a named instance with restricted permissions, you'll now see all backup files in the restore list. Previously, the dialog would silently hide all backups when the SQL server couldn't read your backup folder.

  • Bug Fix Restore dialog now shows all valid backup files
  • Bug Fix Fixed buttons not unlocking after validation

    Resolved an issue where the "Validate License" and "Create Database" buttons would not unlock or become clickable after filling in required fields. The dialog now properly refreshes button states when database name availability is checked, store information is validated, or license validation completes.

  • Bug Fix Options dialog now activates properly

    When opening the Options window, it will now always appear on top where you can see and interact with it, instead of sometimes appearing behind the main window.

  • Bug Fix Fixed blank Retail Service Center dropdown on Store Information tab

    The Retail Service Center (RSC) dropdown was appearing empty when opening the Store Information tab. The tab now explicitly loads vendor and RSC data when initialized, ensuring the dropdown is properly populated.

  • Bug Fix Main window focus restored after splash screen

    After syncing or resetting data, Margin Master will now automatically come to the front of your screen instead of staying hidden behind other windows.

  • Bug Fix Main window focus restored after startup

    When you launch Margin Master, the main window now automatically appears ready to use without needing to click on it first.

  • Bug Fix Version History menu icon restored

    The Version History option in the menu now shows the correct icon instead of appearing broken or blank.

  • Bug Fix Restore What's New menu item

    You can now click Help → What's New to see the latest Margin Master updates in your web browser.

  • Bug Fix What's New menu item restored

    You can now find "What's New" in the Help menu to see recent updates and new features added to Margin Master.

  • Bug Fix One Click dialog splash screen no longer appears on main window

    Opening the One Click Pricing Strategy dialog no longer shows a loading indicator on the main window behind it.

  • Bug Fix One Click Statistics splash screen timing corrected

    The loading screen that appears when opening One Click Statistics will now disappear properly instead of staying visible over your results.

  • Bug Fix Fixed contact edit and delete operations in issue submission

    You can now successfully edit contact details and delete unwanted contacts when submitting an issue — these operations previously failed silently.

  • Bug Fix Store delete button restored

    You can now click the delete button (X icon) next to each store to remove it from your store list.

  • Bug Fix Quick Submit button restored to Support Issues header

    The Quick Submit button (with the lightning bolt icon) is now visible again in the Support Issues screen, allowing you to quickly report issues without filling out the full form.

  • Bug Fix Quick Submit button restored to Support Issues header

    You can now use the Quick Submit button at the top of the Support Issues screen to quickly report problems without going through the full issue creation form.

  • Bug Fix Selection boxes reload after database restore

    After restoring a backup, all dropdown menus and filter options automatically update to match the restored data without needing to restart Margin Master.

  • Bug Fix Local backup filtering by store number

    When "Show All Stores" is unchecked on a support machine, you'll now see only backup files that belong to your current store, making it easier to find the right backup to restore.

  • Bug Fix Data Aging screen displays correct store numbers

    When you open the Data Aging screen, you'll now see your actual store numbers (like "554") instead of confusing internal codes or blank values.

  • Bug Fix Support Reps tab now populates correctly

    The Support Reps tab in the Submit Issue screen will now show available support contacts instead of being blank.

  • Bug Fix Support reps now load correctly in Submit Issue dialog

    Support representatives now appear in the Support Contacts tab when submitting an issue.

  • Bug Fix Selection boxes now update immediately after changing store-number settings

    When you change how store numbers are shown (display mode) or sorted in the Settings > Connections tab, all dropdown lists throughout Margin Master will now update as soon as you close Settings. Before, you had to wait until the next sync to see the change take effect.

  • Bug Fix SKU-level exception icon now renders correctly

    When individual items have special pricing rules applied, the grid now correctly shows an icon in the "*" column indicating what type of override is in effect.

  • Bug Fix Status message no longer covers input fields

    When setting up your store configuration, all the fields (vendor, store number, POS system) are now visible. Previously a message box was covering them up so you couldn't type anything in.

  • Bug Fix Store Configuration dialog fields now visible

    When opening Store Configuration from startup or settings, all text boxes and dropdowns now appear correctly instead of being hidden.

  • Bug Fix Splash screen no longer gets stuck blocking the main window

    Fixed a race condition (MM-1327/MM-1311) where competing splash screen close attempts during startup could leave the splash window visible and blocking all input. The root cause was improper async/await handling when dispatching work to the UI thread — the code would resume execution before inner tasks completed, allowing multiple sections to simultaneously try to control the splash. Store 5645's logs documented this occurring for 27 minutes straight.

  • Bug Fix Compiler warning resolved in Falcon import

    Fixed a nullable reference annotation warning in the Falcon POS Excel import code that could have caused future build issues. This is a code quality improvement with no impact on functionality.

  • Bug Fix Fixed support scripts dialogs appearing behind window

    The password prompt and support scripts windows now appear in front of other windows instead of hiding behind them.

  • Bug Fix Fixed Thread view toggle clipping

    Adjusted padding and margins in the Support Issues view toggle bar to prevent the "Thread" radio button from being cut off at the right edge of the screen.

  • Bug Fix Fixed Connect window visibility during database setup

    The database connection window now stays out of the way while you're creating or restoring a database, then comes back automatically if you need to make changes.

  • Bug Fix Primary store designation now persists correctly

    Setting a store as your primary store will now save correctly and stay selected after closing and reopening the application.

  • Bug Fix Removed duplicate store validation check

    Removed an extra validation requirement that was preventing users from validating their license and creating databases even when all required information was correctly entered. The "Validate License" button now activates as soon as store number (digits only), vendor, and POS system are selected.

  • Bug Fix Fixed unassigned stores appearing when Store Grouping was disabled

    Stores were incorrectly appearing in the "Unassigned Stores" list even when Store Grouping was turned off. All three store grouping collections (groups, assigned stores, and available stores) are now properly cleared and hidden when the feature is disabled.

  • Bug Fix Window focus restored after vendor data updates

    After updating vendor data, the Margin Master window will automatically come back to the front so you can continue working.

  • Bug Fix Fixed delete button visibility and functionality

    The delete button for removing stores from the list now appears and works correctly in all situations.

  • Bug Fix Cancel button persists across all rebuild steps

    The cancel button now stays visible throughout the entire rebuild process, so you can stop the rebuild at any step, not just at the beginning.

  • Bug Fix Store Manager async database operation

    Deleting stores in Store Manager now runs more smoothly without freezing the interface.

  • Bug Fix Epicor multi-character store numbers preserved during import

    Epicor stores with multi-digit store numbers (like "554") will now show correctly throughout the application instead of being corrupted during import.

  • Bug Fix Restored automatic contact selection fallback logic

    When you open Submit Issue, a contact will always be pre-selected for you—either your store's primary contact or a default support representative—so you can submit issues faster.

  • Bug Fix Restored default support rep selection when no primary contact exists

    If your store doesn't have a primary contact set up, the system will now automatically select a default support representative when you submit an issue.

  • Bug Fix Escalation safety net now correctly triggers after repeated splash close failures

    Fixed the splash reaper's escalation counter, which was being incorrectly reset when the splash was re-shown. This made the three-strike escalation safety net unreachable when startup operations interleaved splash shows with failed closes. The counter now only resets when a close is actually verified successful, ensuring the watchdog can properly detect and recover from persistent splash problems.

  • Bug Fix Background license validation in demo mode

    Background license validation checks that run during normal application use now detect demo mode and suppress status change notifications. This prevents license warning dialogs from appearing mid-session when demonstrating the software to prospective customers.

  • Bug Fix Blob migration tool vendor name authentication

    Fixed vendor name resolution in the BlobMigration command-line tool to correctly map vendor abbreviations (Ace, EJ, DIB, Orgill, UH) to numeric vendor IDs for API authentication. Added proper error handling for 4xx HTTP responses to skip stores with bad data rather than treating them as tool errors.

  • Bug Fix Fixed startup window dismissal issue

    The database connection screen no longer closes unexpectedly when creating a new database or restoring a backup during first-time setup.

  • Bug Fix Fixed off-screen button rendering issue

    The Refresh and Cancel buttons now appear correctly at the bottom of the update window instead of being hidden off-screen.

  • Bug Fix Prevent auto-update loops during development

    Added safeguard to prevent automatic update application at startup when running in debug mode, avoiding interruption of normal development workflow while still allowing manual testing of update functionality.

  • Bug Fix Show All Stores toggle now refreshes local files

    Checking or unchecking "Show All Stores" now immediately updates both local and cloud backup files in the list.

  • Bug Fix Zone pricing icon column restored

    Items with zone-specific pricing now correctly show the "Z" indicator icon in the grid.

  • Bug Fix Splash screen properly hidden before message boxes in strategy restore

    Message boxes during strategy restore now appear properly without the loading screen visible behind them.

  • Bug Fix Improved startup cancellation error handling

    Changed startup cancellation to throw OperationCanceledException instead of a generic Exception when users cancel database or license configuration, providing clearer error handling and logging.

  • Bug Fix Store number list ordering corrected

    Fixed a fragile ordering mechanism that was re-sorting store numbers after building the dictionary. The list now sorts correctly by the chosen preference (vendor or POS number) using a single stable sort operation.

  • Bug Fix Proper async handling when showing dialogs during startup

    Fixed multiple locations in the startup sequence (OLEDB driver check, vendor data availability check) where modal dialogs were shown using Dispatcher.InvokeAsync incorrectly. The previous code would complete before the inner async work finished, allowing startup to continue while dialogs were still being processed. Now uses ExecuteOnDispatcherAsync to properly await the complete dialog workflow before proceeding.

  • Bug Fix Failed updates now visible instead of silent

    Margin Master used to stay on old versions without telling you when something went wrong—now it tells you the update failed and helps you fix it.

  • Bug Fix Fixed contacts display to show only issue-specific contacts

    Corrected the contacts display to show only contacts assigned to the currently selected issue rather than all store contacts. The contact summary now accurately reflects who will be notified about updates to that specific issue, with the text "No contacts assigned" shown when no contacts are linked to the issue.

  • Bug Fix Contact delete and edit operations in issue submission

    You can now delete contacts from your store's contact list directly in the support request form (after confirming). The "Continue" button is now disabled until you select at least one contact to notify.

  • Bug Fix Server selection validation in database setup

    Added null-check for selected server before attempting to load database list, preventing errors when the server dropdown is cleared or no server is selected.

  • Bug Fix Update problem dialog shown after startup completes

    The update problem dialog now waits until Margin Master finishes starting so it doesn't get stuck behind the splash screen.

  • Cloud Sync Available appointment check on startup

    The application now queries the RetailerSoft API during startup to check for available appointment slots, which controls the visibility of the Schedule an Appointment menu item. The check runs as part of deferred startup work to avoid impacting initial load time.

  • User Interface Support Issue History menu option

    Click "Support Issue History" in the Help menu to see all your past support tickets in your browser.

  • User Interface Support Issue History moved to submenu

    You can now find Issue History inside the Support Issues menu, right below Submit Issue.

  • User Interface Support menu reorganization

    The "Support Issue History" option is now found inside the Support Issues submenu instead of at the top level of the Help menu.

  • User Interface Type-to-filter enabled for all dropdown menus

    When you click any dropdown menu, you can now start typing to quickly find what you're looking for — for example, typing "org" in the vendor list will show only Orgill, or typing "rock" in the POS system list will show only RockSolid.

  • User Interface Type-to-filter enabled on all dropdown menus

    When clicking on any dropdown menu, you can now start typing to immediately filter the list and find what you're looking for—especially helpful for long lists like vendor catalogs or POS system options.

  • User Interface Redesigned Support Scripts dialog with master-detail layout

    Scripts are now organized by category in a tree on the left side. Click any script to see its full description before running it.

  • User Interface Support Scripts button added to Database Setup screen

    Support staff can now access diagnostic tools directly from the database setup screen by clicking the Support Scripts button (password required).

  • User Interface Enhanced SKU Lookup results display

    When searching for items using Quick Find, results now appear in a cleaner grid format with SKUs and descriptions in separate columns, making it easier to scan multiple matches.

  • User Interface Auto-select issue from notification pill

    Clicking the support issues notification now shows your issue immediately without extra clicks.

  • User Interface Redesigned contact selection in Support Issues screen

    When submitting a support issue, you'll see all your store contacts in a list. Check the boxes next to anyone who should receive updates about the issue. Click a contact to edit their information on the right side, or use the "Add Contact" button to create a new one.

  • User Interface Added menu bar to Database Setup window

    The database setup screen now has a menu at the top for faster access to create, restore, and support tools.

  • User Interface Removed obsolete database connection screens

    Deleted multiple deprecated database connection views and windows (DatabaseConnectionWindow, DatabaseConnectionView, and associated ViewModels) that were no longer being used. All database configuration functionality is now consolidated in the modern DatabaseSetupWindow. This cleanup removes over 1,200 lines of unused code and eliminates confusion from having multiple similar screens.

  • User Interface New dedicated Create New Database dialog

    Creating a new database now uses a separate, simpler screen that walks you through entering your store information, shows your auto-generated database name, and validates your license before proceeding.

  • User Interface Context help added to database configuration screens

    When setting up or creating a database, you can now click the help button in the window header to open instructions and guidance for that specific task.

  • User Interface Modernized Support Issues screen layout

    Redesigned the entire Support Issues screen with a card-style layout featuring a blue accent bar and shadow effects for better visual hierarchy. Action buttons (View Online, Mark Resolved, Create New Issue) have been moved to a colored header bar at the top of the screen for easier access. View Online is now blue with a white background, Mark Resolved is green, and Create New Issue uses the company's dark blue color scheme.

  • User Interface Redesigned Support Issues screen layout

    Action buttons are now at the top of the screen for easier access, and you can switch between bubble and threaded views using the View menu.

  • User Interface Full-screen master-detail layout for Support Issue dialog

    The Become Support Issue User dialog has been redesigned from a compact list-over-detail view to a side-by-side master-detail layout. The left panel contains the issue list with filter bar (status dropdown and search box) and status counts. The right panel shows the selected issue's header information, full description, comments thread, attachments list, and download actions. The dialog now opens maximized instead of auto-sizing to a fixed minimum size.

  • User Interface Full-screen master-detail layout for Support Issue dialog

    The Support Issue dialog now fills your screen and can be resized to fit your workflow.

  • User Interface Dialog window behavior improved

    Setup and configuration windows will no longer stay pinned on top of all your other programs, making it easier to switch between Margin Master and other applications when you need to look up information during setup.

  • User Interface Renamed database connection menu item

    The database menu option now says "Connect to Database" instead of "Manage Database Connections" to make it clearer what it does.

  • User Interface Renamed database connection menu item

    The menu option is now called "Connect to Database" instead of "Manage Database Connections" for easier understanding.

  • User Interface Moved "Use Legacy View" to hamburger menu

    To switch back to the older pricing strategy editor, click the hamburger menu (three lines) in the top-right and select "Use Legacy View" from the bottom of the menu.

  • User Interface New Options screen set as permanent default

    Removed the database setting that allowed routing back to the legacy Options screen on startup. The application now consistently launches with the new Options interface, though the "Use Legacy" button remains available as a session-only fallback for users who need temporary access to the old screen.

  • User Interface Always use new Options screen

    When you open Settings from the menu or at startup, you'll always see the updated Options screen design.

  • User Interface Improved splash screen continuity during restore operations

    The loading screen now stays visible continuously during restore operations instead of briefly disappearing between steps.

  • User Interface Granular splash screen progress messages during startup

    The splash screen now breaks down the previously monolithic "Verifying Database Configuration" step into 8 distinct sub-steps with specific messages: Verifying Rounding Tables, Verifying Field Mappings, Checking Rounding Schemes, Checking Configuration Integrity, Migrating zone data, Checking column schemas (with per-table progress like "Main table 3 of 12"), and Applying schema updates. This provides visibility into what the application is doing during startup and prevents the appearance of the application being frozen during database maintenance operations.

  • User Interface Inline cloud credential entry in restore dialog

    When restoring a cloud backup, you can now enter your vendor and store number right in the restore window if you haven't set it up yet.

  • User Interface Modern styling for update installation screen

    The update installation window now has a modern blue accent bar at the top and buttons with icons for easier recognition.

  • User Interface Update splash screen visual redesign

    The Velopack installation splash screen now features a blue-gray gradient background, a blue accent bar matching the application's DevExpress styling, Impact Bold title font per brand standards, a two-line subtitle explaining the update is installing and that the app will restart, and the full-color RetailerSoft logo with a bottom divider frame. This replaces the previous plain white background with simple text.

  • User Interface Update screen visual redesign

    The update installation dialog now features a blue accent bar at the top, improved typography with hierarchical font sizes and weights, and better-organized status messages. The layout has been adjusted to improve spacing and readability, with the wait indicator displaying "Margin Master Update" as a header followed by "Please wait…" and detailed status text below.

  • User Interface Custom branded update installation window

    Added a new custom WPF window that displays during update installation with Margin Master branding, a blue accent strip, and an indeterminate progress bar (#0078D4). The window shows the version being installed and explains that the app will restart automatically. This replaces the generic Velopack Update.exe progress window at all three update application points: manual update installation, startup auto-apply, and What's New dialog updates.

  • User Interface Custom update installation window

    When Margin Master installs an update, you'll now see a cleaner, branded window with clear information about which version is being installed.

  • User Interface New knowledge base article for download blocking issues

    Created a comprehensive help document titled "Microsoft Edge Download Block" in the Getting Started section. The article includes step-by-step instructions with screenshots-ready descriptions for getting past Edge's "This file can't be downloaded safely" warning and Windows Defender SmartScreen's "Windows protected your PC" dialog. It also provides a plain-English explanation of why SmartScreen flags software with limited download footprints, clarifies that the warnings are not virus alerts, and answers five common questions about the security prompts, IT policies, and auto-updates.

  • User Interface Improved update installation window visibility

    When Margin Master installs an update, you'll now see a cleaner transition to the installation window without the startup screen lingering in the background.

  • User Interface Removed Status column from Store Manager grid

    The Status column has been removed from the store list to make the screen cleaner and easier to read.

  • User Interface Cancel button appears immediately on rebuild start

    The cancel button now shows up right away when you start rebuilding data, so you don't have to wait to cancel if needed.

  • User Interface Store Manager button modernization

    The Save and Close buttons in the Store Manager window now have a more modern, polished appearance.

  • User Interface Click support rep rows to select as primary contact

    You can now click directly on a support representative's name to select them as the primary contact, just like you can with store contacts.

  • User Interface Enhanced contact selection methods

    You can now select who to send the issue to by clicking their checkbox or clicking on their name.

  • User Interface Legacy option identification in store number preferences

    When choosing how store numbers appear in the Settings screen, options marked "(legacy)" show stores the same way they appeared before this setting was added, making it easier to keep your familiar view.

  • User Interface Legacy options labeled in store number preferences

    When choosing how store numbers appear in Settings, options labeled "(legacy)" show stores the same way they appeared before this choice was added.

  • User Interface Streamlined submit button layout in Support Issues

    The "Quick Submit" button has been renamed to "Submit" and now shows a menu when clicked, making the toolbar more compact.

  • User Interface Quick Submit converted to dropdown menu

    Click the "Submit" button in Support Issues to see a menu of submission options.

  • User Interface Password-protected feature activation on Background Service tab

    A new "Enable (password)" button appears at the top of the Background Service settings. Support staff must enter the password to activate this feature on your machine. Once enabled, you'll see all the scheduling and configuration options. You can disable it anytime without a password.

  • User Interface Live download progress on auto-update splash screen

    When Margin Master checks for or downloads updates at startup, you'll now see clear status messages like "Contacting update server…" and live download percentages (e.g., "45%") so you know the app is working and not frozen.

  • User Interface Enhanced update progress feedback

    When Margin Master checks for updates at startup, you'll see more detailed information about what's happening, including download progress percentages and clearer messages about each step.

  • User Interface Developer build indicator on splash screen

    When running a developer build, the splash screen now displays "-DEVELOPER" after the version number, matching the indicator shown in the main window title bar.

  • User Interface Startup Database Setup button layout updated

    The Database Setup screen now shows a new "Restore Backup" button in the bottom-left corner.

  • User Interface Fixed text wrapping in issue resolution dialog

    The comments field in the issue resolved dialog now properly wraps text and includes a scrollbar, improving usability when entering longer resolution notes.

  • User Interface Enhanced dropdown navigation in Database Creation wizard

    When creating a new database, you can now type to quickly find your vendor or POS system instead of scrolling through the complete list.

  • User Interface Enhanced database setup dropdown menus

    When setting up a new database, you can now type to quickly find your vendor (like "Ace" or "Orgill") or POS system instead of scrolling through the entire list.

  • User Interface Standardized dialog window sizing behavior

    Dialog windows now consistently use dynamic sizing with a maximum height of 800 pixels, allowing them to adapt to their content while preventing them from exceeding reasonable screen boundaries. Scroll bars appear automatically if content still exceeds the available space.

  • User Interface Added scroll support to configuration screens

    If a setup screen is too tall for your monitor, you can now scroll down to see all the options and buttons.

  • User Interface Database Setup window height limit with scrolling

    The database setup screen now scrolls automatically on smaller monitors instead of extending off the screen.

  • User Interface Database Setup window height capped for smaller displays

    The database setup screen now fits better on smaller laptop screens by scrolling when needed.

  • User Interface Cleaner issue descriptions in Support Issues screen

    Issue descriptions are cleaner and easier to read, and the latest comments are always visible without scrolling.

  • User Interface Added menu bar to Database Setup window

    The Database Setup window now has a menu bar at the top with File and Tools menus, making it easier to find options like creating a new database or restoring from a backup.

  • User Interface Installation Scripts dialog auto-resizes to content
  • User Interface Fixed view toggle label clipping

    The "Thread" view option now displays fully without being cut off at the edge.

  • User Interface Simplified Database Setup window to focus on connection

    The Database Setup screen is now simpler and focused on just connecting to SQL Server and picking an existing database. To create a new database, you click the "Create New Database" button.

  • User Interface Added menu bar with view mode toggle

    Added a DevExpress BarManager menu bar to the top of the Support Issues screen with a View menu containing options to toggle between Bubbles and Thread chat display modes. This replaces the previous radio button controls and provides a more standard menu interface.

  • User Interface License configuration window positioning updated

    The license configuration window's positioning logic was simplified, removing the fallback behavior that would set the window as topmost when the main window wasn't available. The window will now properly center on screen without forcing itself above other applications.

  • User Interface Enhanced splash screen coverage during database switching

    When switching between databases, the loading screen now stays visible until all data is fully loaded.

  • User Interface Status message during script preload

    You'll see a status message showing which scripts are downloading while the dialog loads.

  • User Interface Improved Submit Issue dialog feedback

    The support form now clearly shows when database backup is not available by graying out the option.

  • User Interface Wire up What's New command

    Connected the previously unused BuildWhatsNewUrl() method to a new ShowWhatsNew() command that properly launches the browser. The command includes error handling to log any issues that occur when attempting to open the URL.

  • User Interface Help menu organization improved

    The What's New menu item has been positioned between "Catalog Lookup" and "Version History" in the Help menu for better organization and discoverability.

  • User Interface Improved text hierarchy during update installation

    Text during updates is now organized into clear sections showing the update title, status message, and detailed progress in an easy-to-read format.

  • User Interface Enhanced action buttons

    The Refresh and Cancel buttons have been updated to use DevExpress SimpleButton controls with icons, consistent sizing (30px height, 100px minimum width), and improved spacing. The buttons now include visual glyphs (refresh and close icons) for better recognition.

  • User Interface Branded download progress window

    When downloading Margin Master, you'll see a branded progress window showing download speed and file size.

  • User Interface Smart restart prompting after store reconfiguration

    If you change your store number using Reconfigure Store, you'll be prompted to restart Margin Master. Other changes (vendor, POS, RSC) don't require a restart.

  • User Interface Dynamic menu visibility based on availability

    The appointment scheduling option only appears when time slots are actually available, so you won't see it if the calendar is full.

  • User Interface Two-tab layout for store contacts vs. support representatives

    Store contacts and support representatives now appear in separate tabs, making it easier to find and select the right person for your issue.

  • User Interface Status column removed

    The Status column has been removed from the store list to simplify the view.

  • User Interface Primary contact visual indicator

    The main contact for your issue is now marked with a blue "(Primary)" label so you can easily see who will receive the issue.

  • User Interface Eliminate splash screen flashing during auto-continue strategy execution

    When running pricing strategies with auto-continue enabled, the loading screen stays visible throughout execution instead of flashing between steps.

  • User Interface Visual icons for backup source identification

    Backup files in the list now show an icon next to "Local" or "Cloud" to help you quickly identify where each backup is stored.

  • User Interface Optimized Options dialog performance

    Implemented a flag-based tracking system where individual Options tabs signal when they modify settings that require selection box updates. The Options dialog aggregates these flags and triggers a rebuild only when necessary, avoiding unnecessary work on routine open/close operations.

  • User Interface Softened installation window message

    The message shown just before the app restarts to complete an update is now friendlier and clearer about what's happening.

  • User Interface Clarified Installing Update window message

    The update installation screen now says "Finalizing" so you know the update is still processing before the automatic restart.

  • User Interface Improved Settings screen dropdown navigation

    In Settings screens, all dropdown menus now let you type to filter options — useful for quickly selecting mailbox numbers, cost types, and other configuration values.

  • User Interface Improved Settings screen dropdown menus

    In the Settings screens, you can now type to quickly filter options in any dropdown, making it faster to configure vendor preferences, cost types, and other settings.

  • User Interface Code cleanup for combo box controls

    Removed redundant AutoComplete, IncrementalFiltering, and ImmediatePopup properties from multiple combo box controls across Settings screens, as these are default behaviors in DevExpress controls.

  • User Interface Enhanced error messages for missing scripts

    Improved error reporting when an embedded script cannot be found, now showing only relevant script resources in the diagnostic output instead of all embedded resources.

  • User Interface SMS-style chat bubbles for issue comments

    Issue conversations now look like text messages, with your comments in blue on the right and support responses in gray on the left, making it easier to follow the discussion.

  • User Interface Contact selection redesigned with split-panel layout

    You can now select multiple contacts to notify about an issue using checkboxes, and add or edit contacts directly from the submission form.

  • User Interface SKU Lookup dialog auto-resizes to content
  • User Interface Redesigned chat area with phone-style interface

    The chat conversation area now displays in a phone-style container with a gradient header and pill-shaped message input field at the bottom, providing a more familiar messaging interface similar to modern chat applications.

  • User Interface Enhanced contact display with pill chips

    Contacts are now shown as colored pills with names and emails, making it easier to see who's assigned to each issue at a glance.

  • User Interface Status count display and enhanced filtering

    Added visual status counts in the filter bar to show the number of Open, Closed, and total issues at a glance. The filter bar now displays in the left panel above the issue list, making it easier to locate and filter issues while viewing details in the right panel.

  • User Interface Improved RSC and POS dropdown layout

    Fixed the side-by-side layout of RSC (Retail Support Center) and POS System dropdowns so that when RSC is hidden (for non-Ace/Orgill vendors), the POS dropdown expands to use the full width. Previously, both fields would stay half-width regardless of RSC visibility.

  • User Interface Quick Issue Submit dialog expanded and reorganized

    The Quick Issue window is slightly wider with clearer instructions about what you can include.

  • User Interface Startup-only UI hidden during reconfiguration

    The Store Configuration window now adapts its interface based on context. When opened via File > Reconfigure Store, startup-only buttons like "Back to Database Selection" are automatically hidden since they're not relevant when the application is already running.

  • User Interface Store Configuration dialog startup mode detection

    Modified StoreConfigurationWindow and its ViewModel to detect whether it's being opened during application startup or from the File menu. The new IsStartupMode property controls visibility of startup-specific UI elements, providing a cleaner experience when reconfiguring an already-running application.

  • User Interface Booking link generation with authentication

    Implemented secure booking link generation through the API authentication system, ensuring users are automatically logged in when accessing the appointment scheduling page. Failed API calls are logged as warnings but don't disrupt the user experience.

  • User Interface Updated delete button styling

    Replaced the custom red "✕" text button with a standard DevExpress close icon button for better consistency with the application's overall design and improved visual clarity.

  • User Interface Support Issues empty state messaging

    When viewing a support issue with no messages, you'll now see clearer messaging about whether the conversation is empty or if there's a temporary connection issue.

  • User Interface Primary contact badge in contact list

    The primary contact now shows a blue "(Primary)" label so you can easily see who will be submitting the issue.

  • User Interface Submit Issue contact step improvements

    Enhanced the Submit Issue dialog's contact selection step to ensure users can always submit issues without manually hunting for a contact. Both the initial load and the reload-contacts paths now use consistent logic for populating the Store Contacts and Support Reps tabs and selecting a default contact.

  • User Interface MySQL Query Utility screen enhancements

    The MySQL Query Utility screen now includes a menu bar at the top for accessing diagnostic scripts. The Scripts menu contains four pre-configured queries designed to help diagnose common MySQL Compass import issues related to character encoding and store identifier mapping.

  • User Interface Enhanced store number tooltips

    Hover over any store number to see both the vendor and POS store numbers, even when only one is displayed in the list.

  • User Interface Modal password dialog for feature authorization

    Implemented a programmatic password prompt dialog using ThemedWindow that appears when clicking the Enable button. The dialog includes a PasswordBoxEdit control and validates the entered password against the standard support password (case-insensitive). The dialog is modal, centers over the active window, and supports both Enter (OK) and Escape (Cancel) keyboard shortcuts.

  • User Interface Streamlined title bar notification behavior

    Clicking the red notification badge at the top of the window now opens the full Support Issues screen directly.

  • User Interface Auto-scroll comments to most recent message

    The conversation view in Support Issues now automatically scrolls to show the newest messages.

  • User Interface Database Setup window spacing refinements
  • User Interface Improved filter and action button positioning

    The status filter, search box, and action buttons have been repositioned to work optimally with the new left-right split layout, ensuring all controls remain easily accessible in the full-screen interface.

  • User Interface Capped window height at 780 pixels

    Added a maximum height constraint to prevent the Create New Database window from growing too tall on screens with many available options, ensuring the dialog remains fully visible and accessible.

  • User Interface Idle delay controls snooze dialog auto-trigger behavior

    The UpdateSnoozeViewModel now accepts an injectable `IdleDelayMinutes` property (previously hard-coded to 30) that controls when the auto-trigger countdown begins. When set to `null` (corresponding to "Never"), no idle timer starts and the progress bar is hidden. The idle progress bar now fills over the user-configured duration before the 10-second countdown begins. All six delay options are mapped from string values stored in application settings to integer minute values or special behaviors (null for Never, exit handler for OnShutdown).

  • User Interface What's New link in update notification

    The update notification now includes a "What's New in This Version" link to review the changes before updating.

  • User Interface Added loading indicators to all Options tabs

    A loading spinner now appears when opening or switching between settings tabs.

  • User Interface Updated validation and progress tracking

    You can now submit a report with just attached files, even if you don't include logs or a database backup.

  • User Interface Help link added to Auto Update options tab

    A "Help — Auto Update Configuration" button with info icon appears below the settings, linking to the updated auto-updates.md documentation that now includes full descriptions of all six idle delay options, the shutdown mode behavior, and the new centralized options location.

  • User Interface Enhanced license error display in store configuration

    License problems during setup now show a clearer error message with a warning icon.

  • User Interface Removed "Do Not Contact" checkbox

    If you don't want to be contacted about an issue, just leave all contacts unchecked.

  • User Interface Updated issue description display with card styling

    Replaced the plain description text box with a card-style layout featuring a blue accent bar on the left, drop shadow, and an icon for better visual presentation of the issue description.

  • User Interface Idle progress bar in update notification

    A progress bar in the update notification shows how much time remains before auto-install begins.

  • User Interface Adaptive window sizing for high-DPI displays

    Database setup windows (Connect, Create New, Store Configuration) now use screen-aware maximum heights instead of fixed pixel values, preventing windows from being cut off on laptops or displays with taskbars.

  • User Interface New update problem dialog and settings

    Added `UpdateProblemView.xaml` and `UpdateProblemViewModel` to present the three-choice dialog (repair install / contact support / remind me later). Added `UpdateRepairService` to download and launch the installer. Added five new `ApplicationSettingKey` values: `AutoUpdateConsecutiveFailures`, `AutoUpdateLastFailureUtc`, `AutoUpdateLastFailureTarget`, `AutoUpdateLastFailureReason`, and `AutoUpdateProblemPromptLastUtc` to persist the failure state across restarts.

  • User Interface SMS-style chat bubbles for issue comments

    Issue conversations now look like text messages, with your comments in blue on the right and support responses in gray on the left, making it easier to follow the discussion.

  • User Interface Streamlined title bar notification behavior

    Clicking the red notification badge at the top of the window now opens the full Support Issues screen directly.

  • Database Contact phone persistence

    Added ContactPhone property to ApplicationSettingsService to store and retrieve the contact person's phone number alongside existing contact fields (first name, last name, email).

  • Database Removed DatabaseSetupMode enum

    Deleted the DatabaseSetupMode enum (CreateNew/ConnectExisting) as the two-dialog approach eliminates the need for mode switching. DatabaseSetupAction enum remains for tracking user's final action (CreateNew, ConnectExisting, Cancel, RestoreBackup).

  • Database New AutoUpdateIdleDelay setting key

    Added new `ApplicationSettingKey.AutoUpdateIdleDelay` to store the user's preferred idle delay value (Never, 1Minute, 5Minutes, 30Minutes, 1Hour, OnShutdown). Default is 30Minutes.

  • Architecture Feature enablement logic moved from tab-level to control-level

    The Background Service tab is now always enabled in the Settings screen navigation, but the individual settings controls within the tab are gated by the IsFeatureEnabled flag. This allows users to see the Enable button and activate the feature without needing support to first enable it remotely via the database flag. The SetFeatureEnabledAsync method updates the ApplicationSettingKey.BackgroundServiceFeatureEnabled flag and refreshes service status and history when enabled.

  • Architecture Session-cached support authorization

    Support script authorization is cached in a static field shared across the application session. Once the support password is entered successfully, the user won't be prompted again until the application is restarted, streamlining repeated access for support scenarios.

  • Architecture Created CreateNewDatabaseViewModel with focused responsibilities

    New ViewModel contains all logic for store validation, database name generation with conflict checking, license validation, and database creation orchestration. Removed ~700 lines of intertwined logic from DatabaseSetupViewModel, including store validation methods, database name generation, license validation, and mode-switching code. The two ViewModels now have clear separation: setup handles connection, creation handles store config.

  • Architecture Framework-dependent .NET 10 single-file executable

    The bootstrapper is published as a framework-dependent single-file executable targeting .NET 10, keeping the file size small (441 KB) while requiring users to have the .NET runtime installed. The stable file structure and signing certificate help establish trust with Windows SmartScreen.

  • Architecture New IssueContactEditorViewModel

    Created a dedicated ViewModel (IssueContactEditorViewModel) to manage contact selection state with SelectableContact wrapper objects. Handles bidirectional synchronization between the checkable list and the selected chips display, automatic toggle handling between store/support contacts, and loading contacts from the API with support employee filtering.

  • Infrastructure Build warning cleanup

    Resolved a compiler warning in the Falcon Excel import code related to nullable reference type annotations, improving code quality without changing behavior.

  • Infrastructure Hide native Velopack update dialog

    Added Win32 helper function HideVelopackWindowAsync() that automatically hides the native Update.exe window after ApplyUpdatesAndRestart() is called, ensuring only the custom branded window is visible during the 3-5 second installation process. Runs in background for up to 5 seconds to catch the Velopack process when it appears.

  • Infrastructure Enhanced documentation search coverage

    Updated the documentation index with comprehensive search keywords including "edge blocked," "can't download safely," "windows protected," "smartscreen," "keep anyway," "run anyway," and related phrases. This ensures users encountering download warnings can quickly find the help article through the in-app documentation search or support portal.

  • Infrastructure Removed obsolete database connection screens

    Deleted eight unused files including DatabaseConnectionWindow (both startup and in-app versions), DatabaseConnectionView, DatabaseConnectionViewModel, and DatabaseConnectionAction enum. These screens were fully replaced by the newer DatabaseSetupWindow but remained in the codebase. Also removed their dependency injection registrations and dialog service references from MainMMWindow.

  • Infrastructure Enhanced debug mode testing for updates

    Modified debug mode behavior to simulate an available update (version "2026.DEBUG.TEST") during CheckForUpdatesAsync(), allowing the new installation window to be previewed and tested without requiring a real update or installed application. The window displays for 3 seconds then closes without restarting. AutoApplyUpdateAtStartupAsync now skips entirely in debug mode to avoid blocking normal development.

  • Infrastructure Automated bootstrapper build and signing pipeline

    Added GitHub workflow (publish-bootstrapper.yml) that automatically builds, code-signs with Azure Trusted Signing, and uploads the bootstrapper to Azure blob storage whenever the bootstrapper project changes. The workflow includes verification steps to ensure the signature is valid before publishing.

  • Infrastructure Reorganized script folder structure by category

    Scripts are now organized into category subfolders (scripts/SqlScripts/Powershell/, scripts/OLEDB/Powershell/) mirroring the UI categories. Updated the .csproj to embed scripts using a recursive glob pattern (**/*.ps1) and updated CLAUDE.md with a PR checklist for adding new scripts (requires .ps1, .md, catalog entry, support doc, and index entry).

  • Infrastructure Store number display formatter with unit tests

    Created StoreNumberDisplayFormatter helper class with comprehensive unit tests covering all four display modes and the fallback behavior when no POS mapping exists. This ensures display logic remains consistent and correct across future changes.

  • Infrastructure Updated documentation for two-dialog workflow

    Revised database-setup.md and database-creation.md to reflect the new two-dialog architecture, including updated screenshots, step-by-step instructions, and architectural diagrams showing the separation between connection setup and database creation flows.

  • Infrastructure Update health policy with test coverage

    Extracted the pure escalation logic into `UpdateHealthPolicy.ShouldPromptUser()` (static, no I/O, testable). Added `UpdateHealthPolicyTests.cs` with 16 test cases covering the failure threshold, behind threshold, snooze interactions, throttle behavior, and unparseable/future timestamps. Mirrors the design of `UpdateDeferralPolicy`.

  • Infrastructure Background service stop before repair install

    `UpdateRepairService.LaunchInstaller()` calls `BackgroundWindowsServiceController.TryStopServiceNoElevation()` before running Setup.exe. The background service executable lives inside `current\`, the folder the installer must replace, and is the most common cause of locked-folder update failures. Sets the restart sentinel only when a running service was actually stopped.

  • Infrastructure Documentation updated for update failure workflow

    `docs/marginmaster/getting-started/auto-updates.md` expanded with a "When an Update Will Not Install" section explaining the three-choice dialog, the repair install flow, the 24-hour throttle, and the most common causes (background service, antivirus, locked folders). Added search keywords: `update failed`, `could not update`, `stuck on old version`, `repair install`, `reinstall`, `folder locked`. Added new technical sections: "Update-Failure Detection and Escalation" and "Repair Install Flow" with implementation detail.

Reporting & Exports

  • Improvement Clear guidance for backup path permission errors

    If a backup fails because SQL Server can't reach the folder, you'll now see an explanation telling you to either choose a folder on the SQL Server's own hard drive, or grant the SQL Server service account permission to access the network location.

  • Improvement Debouncer cancellation support

    Added the ability to cancel pending debounced operations, allowing the application to immediately override scheduled actions when the desired state changes. This prevents stale operations from executing after they're no longer relevant.

  • Improvement Added confirmation dialog before removing stores

    Before removing any stores during a MySQL refresh, you'll now see exactly which stores will be removed and can choose whether to proceed.

  • Improvement Centralize update-marker tracking to prevent inconsistencies

    All four code paths that apply updates (startup auto-apply, two interactive apply paths, and the version downgrade tool) now route through a single `UpdatePendingSentinel` class that manages both halves of the tracking marker together. This architectural change prevents the target version and starting version from drifting out of sync, which would make the next launch's classification unreliable. Three separate clearing sites also now use the same centralized method.

  • Improvement Added detailed change summary after refresh

    After a MySQL refresh completes, you'll see a clear summary showing exactly what changed—which stores were added, reactivated, updated, or removed.

  • Improvement Settings screen now warns when Export Path is not writable

    The Settings screen now warns you immediately if you pick a folder that Windows won't let Margin Master write to, helping you choose a better location upfront.

  • Improvement One-time notification when fallback occurs

    If backups fall back to the default location, you'll see a notification explaining why and where to update your export path.

  • Improvement Improved reliability of MySQL refresh processing

    If there's a problem with one store during a MySQL refresh, the other stores will still be processed correctly instead of the whole operation failing.

  • Bug Fix Drop ship SKU suffix missing in newretails exports

    Drop ship items that should end with "D" were being exported without the "D" at the end. This has been fixed so the "D" suffix now appears correctly in your newretails export files.

  • Bug Fix Splash screen timing issue during fast exports

    When exporting a small number of records to a text file, the "Exporting changes" splash screen would sometimes get stuck on screen behind the success message. This has been fixed.

  • Bug Fix Splash screen stuck after export completion

    Fixed a bug where the loading screen would sometimes stay on screen after an export finished, blocking you from seeing whether the export succeeded. The loading screen will now properly disappear when operations complete.

  • Bug Fix Excel export crash when columns are hidden or filtered

    Exporting to Excel will no longer crash when you've hidden or filtered certain columns from the view.

  • Bug Fix Excel export no longer removes columns with matching field and header names

    When exporting pricing data to Excel, columns like SKU and Description will now appear correctly instead of being missing from the exported file.

  • Bug Fix Excel export column removal bug

    Some columns were being removed from your Excel exports by mistake. This has been fixed so all columns now export correctly.

  • Bug Fix Fixed MySQL refresh failing to restore deleted stores

    Stores that were previously removed but exist again in your POS system will now correctly reappear in Store Manager after a MySQL refresh.

  • Bug Fix Custom group strategy no longer errors when no future pricing actions configured

    Custom pricing groups with no future pricing actions will now process silently without logging errors.

  • Bug Fix Ace MAP pricing update now handles older database schemas

    Ace Hardware stores with older databases will no longer see errors during import or sync when MAP pricing is updated.

  • Bug Fix Automatic backup no longer crashes when Export Path is read-only

    Automatic backups will no longer fail silently if your Export Path points to a protected Windows folder.

  • Bug Fix Automatic fallback for read-only export paths

    Backups will no longer fail if your export folder becomes read-only or unavailable — they'll save to a safe default location automatically.

  • Bug Fix Schema errors now properly escalate to telemetry

    When the application encounters a missing database column or table (SQL errors 207/208), it was previously logging these as warnings, which could be filtered below the telemetry threshold and go unnoticed. These errors are now logged at Error level to ensure they reach telemetry systems, making it easier to identify and diagnose schema drift issues between the application and the database. This fix addresses a case at store 3875 where a genuine schema problem was being silently ignored.

  • Bug Fix Eliminate false update-failure alerts for machines updated by alternate paths

    If a technician or Windows service updates Margin Master while you're not using it, the app will now correctly recognize it's up to date instead of showing an incorrect update-failure message.

  • Bug Fix Database retry failures due to SQL parameter conflicts

    Fixed an error where database operations with automatic retry logic would fail on the retry attempt with "SqlParameter already contained by another SqlParameterCollection." The system now creates fresh parameter copies for each retry iteration, ensuring database commands can be safely retried without conflicts. This error was affecting store 6615.

  • Bug Fix Missing version tracking for new product line

    Resolved an issue where the new Margin Master 20.x line was not sending its version number during license validation, preventing the licensing server from recognizing that version 20 had run on a machine. This fix works in conjunction with RetailerSoft.Manager to enforce version compatibility and data integrity.

  • Bug Fix Version history file locking no longer crashes application

    Resolved UnauthorizedAccessException crashes (4 occurrences at store 1372) when the version history file was temporarily locked by antivirus software or other processes. The delete operation now retries a few times and treats persistent locks as non-fatal warnings instead of crashing.

  • Bug Fix Import validation now tolerates malformed data rows

    Importing a file with a few bad rows will now succeed instead of failing entirely, as long as most rows are valid.

  • Bug Fix Dropdown list failures due to database collation mismatches

    Dropdown menus for filtering and searching will now work correctly even if your database has mixed text comparison settings.

  • Bug Fix Ace MAP pricing updates now work on all database versions

    Ace MAP pricing updates will no longer fail on stores with older database structures.

  • Bug Fix SKU Detail dialog no longer crashes when MainTableList is null

    Opening SKU details will no longer crash in rare cases when the pricing grid hasn't fully loaded.

  • Bug Fix Database migration no longer fails on fresh installations

    Fixed a migration error (3 occurrences at store 119) where adding the IsNotFound column to StoreManagerInfo failed when the table didn't exist yet. The migration now checks for table existence before attempting the ALTER statement.

  • Bug Fix Custom group processing skips groups with no future-price actions

    Custom groups with no configured future-price actions are now treated as a benign no-op and skipped silently, rather than logging "Not Future Price Setting to Load" errors for every batch in the group.

  • Bug Fix SKU Detail dialog no longer crashes when opened

    The SKU Detail window will no longer crash when opening certain items.

  • Bug Fix Version history file cleanup now handles locked files gracefully

    The version history maintenance routine now retries file deletions when files are transiently locked (by antivirus, indexer, or multiple instances) and treats persistent locks as non-fatal warnings rather than failing the entire save operation.

  • Bug Fix StoreManagerInfo schema update now checks table existence

    The startup migration that adds the IsNotFound column to StoreManagerInfo now verifies the table exists before attempting the ALTER TABLE, preventing errors in edge-case database states.

  • Cloud Sync Application version reporting in license validation

    After upgrading to Margin Master 20, any older versions on your computer will be blocked from starting, preventing accidental data corruption from version conflicts.

  • Data Import Improved drop ship SKU handling for Ace vendors

    The Main Table screen now loads the necessary tracking columns (AltSKU and UserE1) when processing Ace Hardware or Emery Jensen data with drop ship SKU conversion enabled. This ensures the complete import/export pipeline preserves drop ship identifiers throughout the workflow.

  • User Interface One-time notification when backup falls back to default location

    You'll see a notification if backups are being saved to a different folder than expected, with instructions on where to fix the setting.

  • User Interface Export path validation warning in Settings

    When setting your export path in Options › Miscellaneous, you'll now see a warning if the folder can't be written to, letting you choose a different location.

  • Database Add AutoUpdatePendingFromVersion setting key

    A new application setting key `AutoUpdatePendingFromVersion` records the version running when an update attempt begins. This complements the existing `AutoUpdatePendingVersion` (the target) and enables three-way classification on the next launch. Markers written by older builds have no from-version and fall back to the original two-state logic, ensuring that upgrading to this build never hides a real failure.

  • Architecture Backup failures excluded from automated error reporting

    Created a new BackupFailedException type that is filtered out of telemetry reporting. Backup failures are almost always environmental (permissions, unreachable paths, disk space) rather than application defects, so they're now logged locally and shown to the user but not reported to the development team's error tracking system.

  • Architecture Background services can now request user notifications

    Added IUserNotificationService as a lightweight relay allowing background services (like AutoStrategyBackupService) to request toast notifications without depending on UI components. The main window routes these requests to the DevExpress NotificationService at startup.

  • Infrastructure Enhanced debouncer cancellation

    Added a Cancel() method to the Debouncer helper class that cancels pending scheduled work without triggering new actions. This allows immediate show/hide operations to cleanly abort any in-flight debounced operations, preventing timing conflicts in the UI.

  • Infrastructure User notification service for background operations

    Added a lightweight notification relay service that allows background services (like the automatic backup system) to request toast notifications without directly depending on UI components. The main window subscribes to these requests and displays them appropriately.

Performance & Reliability

  • Improvement Session-based MySQL connection caching

    Added a connection availability service that tracks MySQL reachability for the entire session. After the first connection failure, subsequent operations immediately skip MySQL attempts and use SQL Server cached data, eliminating repeated 10-second timeout delays during import operations and pricing analysis. Connection availability is restored when the user successfully tests the connection via Tools > Options > Save & Test.

  • Improvement Cost break level navigation safety

    Added bounds checking when navigating between prior and next cost break levels during property changes. This prevents index out of range errors when the collection size changes during background updates.

  • Improvement Reduced MySQL connection timeout

    Decreased the default MySQL connection timeout from 300 seconds (5 minutes) to 10 seconds to provide faster failure detection and improved responsiveness when the MySQL server is unreachable.

  • Improvement Extended SQL Express connection retry timing

    Database creation is now more reliable on slower computers or when SQL Server takes a few extra seconds to start up.

  • Improvement Enhanced logging during database initialization

    Added detailed logging to track how long SQL Server takes to bring the database online, including elapsed time reporting and timeout warnings. This helps diagnose setup issues on machines where database initialization is unusually slow.

  • Improvement Enhanced database creation logging

    Added detailed logging during the database online-check phase, including elapsed time tracking and user-facing status messages. If the 30-second timeout is reached, the application logs a warning and proceeds anyway, providing better diagnostics for support scenarios.

  • Improvement Simplified statistics loading process

    Opening the statistics view is now faster since it no longer needs to load all product data first.

  • Improvement Skip download when Margin Master is already installed

    If Margin Master is already installed, the launcher will skip downloading and just open the program immediately.

  • Improvement Automatic download resume for interrupted installations

    If your download is interrupted, you can restart the setup and it will pick up where it left off instead of starting over.

  • Improvement Permission errors now logged as warnings instead of errors

    When connecting to SQL Server instances with restricted permissions (error codes 229/300), these expected permission denials are now logged as warnings rather than errors. This reduces confusion in logs when running on locked-down database servers where certain administrative queries are intentionally blocked.

  • Improvement Reduced error logging noise for SQL permission checks

    SQL permission errors (error codes 229 and 300) are now logged as warnings instead of errors. These permission checks occur during normal operation when the application tests for optional SQL Server features, and do not indicate actual problems. This change reduces false alarms in error logs and support diagnostics.

  • Improvement Background timer cleanup

    Cost break deletion now properly stops the SKU data update timer and rebuild timer before clearing model data, preventing race conditions between timer threads and UI updates. Added null guards to prevent timer callbacks from running against empty data.

  • Improvement Added dedicated helpers for read-only database operations

    Created new ExecuteReadOnly and ExecuteReadOnlyAsync helper methods that execute database reads without acquiring application-level locks. SQL Server's built-in read consistency mechanisms are sufficient for SELECT operations, eliminating unnecessary serialization that caused performance bottlenecks on slower hardware.

  • Improvement Statistics available without loading main grid

    You can now view statistics immediately without waiting for the pricing grid to load first.

  • Improvement Download resume support for interrupted installations

    If your download is interrupted, the installer will resume from where it stopped instead of starting over from the beginning.

  • Improvement Automatic retry with exponential backoff on network failures

    The installer will now automatically retry up to 3 times if your internet connection is temporarily interrupted.

  • Improvement Enhanced SQL Server account detection compatibility

    The SQL Server service account detection now checks for both 'VIEW SERVER STATE' and 'VIEW SERVER PERFORMANCE STATE' permissions, improving compatibility with different SQL Server security configurations used in backup folder access verification.

  • Improvement Exclude filters now run at database level

    The "Exclude Zero OnHand" and "Exclude Zero Sales" options in the Statistics dialog now apply as SQL WHERE conditions during the database query rather than filtering in memory, improving both performance and consistency with other application filters.

  • Improvement Automatic retry with exponential backoff

    If the download fails due to network issues, the installer will automatically retry up to 3 times before giving up.

  • Improvement PE header verification before installer launch

    The setup tool now verifies the downloaded file isn't corrupted before running it.

  • Improvement Download integrity verification

    The installer now automatically checks that downloaded files aren't corrupted before running them.

  • Improvement Skip download if Margin Master is already installed

    If Margin Master is already installed, the setup tool will launch it immediately without downloading anything.

  • Improvement Direct download fallback link on permanent failure

    If automatic download fails repeatedly, you'll see a link to download the installer directly in your web browser.

  • Improvement Reduced error reporting noise from auto-updater

    Filtered out routine operational messages from the Velopack auto-updater in error reports to focus on actual application errors.

  • Bug Fix Prevent crash when loading empty saved selections

    Fixed a crash that could happen when loading certain saved filter selections. The app now handles empty or incomplete saved selections without errors.

  • Bug Fix Null reference protection in saved selection loading

    The application will no longer crash when loading saved selections that have empty or incomplete filter settings.

  • Bug Fix Application startup crash resolved

    The application will now start up successfully instead of crashing when launched.

  • Bug Fix Cost break deletion crash resolved

    You can now safely delete multiple cost break models without the application crashing. After deletion, the next available model will load automatically.

  • Bug Fix Fixed crash when deleting pricing strategy conditions

    Fixed a crash that could occur when deleting conditions from pricing strategies, especially when the condition text had special formatting.

  • Bug Fix Restore Database dialog crash resolved

    The Restore Database dialog will no longer crash when trying to show confirmation messages. The database restore process now works as expected.

  • Bug Fix Removed unnecessary locking from read-only configuration operations

    If you've experienced missing custom selection box views at startup or had to recreate your saved views after restarting the application, this issue is now resolved. Your custom views will load consistently, even during peak system usage.

  • Bug Fix Selection box views failing to load during startup

    Your saved custom selection box views (like "ACE SELECTION BOXES") will now load correctly when you open Margin Master, instead of falling back to default views that may be missing important columns.

  • Bug Fix Database Setup Window crash on unreachable SQL Server

    If your SQL Server connection is configured incorrectly, the Database Setup Window will now open properly so you can fix it. Previously, the app would crash before you could change the settings.

  • Bug Fix Backup service now handles optional cost break table gracefully

    BackupCostBreaksAsync and RestoreCostBreaksAsync were attempting to query the CostBreaks table unconditionally, but this table only exists at stores that have created cost break pricing rules. The service now checks for table existence before running queries, preventing SqlException errors with automatic retries at stores that have never enabled the cost break feature. This fix eliminates approximately 80 database errors reported across 10 stores in a 48-hour period.

  • Bug Fix Backup service now handles missing CostBreaks table gracefully

    Fixed a crash that could occur during backup or restore operations on certain older databases.

  • Bug Fix Fixed crash when editing prices with empty values in Main Table

    You can now clear or leave empty a cell in the pricing grid without causing an error.

  • Bug Fix Order Multiple field now supports decimal values

    Fixed a crash that occurred when importing inventory data from stores using decimal order multiples.

  • Bug Fix Automatic cleanup of orphaned databases after creation failures

    If database setup fails partway through, you can now click "Retry" and it will work — no need to call IT to manually delete the incomplete database first.

  • Bug Fix Eliminated double-close crash in Edit Columns dialog

    You can now safely close the Edit Columns dialog and choose to save your changes without encountering an error.

  • Bug Fix Prevented double-close crash in Edit Columns dialog

    The Edit Columns window will no longer crash when you save your changes while closing it.

  • Bug Fix Database initialization now waits for SQL Server to complete setup

    If you previously experienced "database creation failed" errors during first-time setup on a slower computer, this issue is now resolved. The setup process will wait as long as needed (up to 30 seconds) for SQL Server to be ready.

  • Bug Fix Database creation now waits for SQL Server Express readiness

    When setting up Margin Master for the first time on a computer with SQL Server Express, the application will now wait for the database to be fully ready before continuing, preventing setup failures.

  • Bug Fix StoreGroup field population timeout on large databases

    Margin Master will no longer fail to start on stores with very large inventories (300,000+ items).

  • Bug Fix StoreGroup initialization timeout resolved

    Stores with very large product databases will no longer see timeout errors when opening Margin Master or during store group verification.

  • Bug Fix Extended timeout for duplicate rounding scheme cleanup

    Increased the database timeout from 30 seconds to 300 seconds (5 minutes) when removing duplicate rounding scheme records. This prevents timeout errors in stores with large rounding scheme datasets during import operations.

  • Bug Fix Settings migration duplicate key error eliminated

    Fixed a database conflict that occurred when two instances of Margin Master started at exactly the same time. Previously, both instances would attempt to migrate the same settings data simultaneously, causing a duplicate key error on the unique ApplicationSettings index. The migration process now gracefully handles this scenario by detecting and ignoring duplicate key violations, allowing both instances to continue startup normally.

  • Bug Fix Settings migration duplicate key error handling

    Added error handling to catch and safely ignore duplicate key exceptions during settings migration (SettingsOptions, PersistentValues, and ConnectionSettings). This prevents crashes when multiple Margin Master instances start at the same time and attempt to migrate the same settings concurrently. The migration process now logs these duplicate key situations and continues normally.

  • Bug Fix Statistics dialog now works with large datasets

    The Statistics button now works instantly even for stores with tens of thousands of SKUs, without freezing or crashing.

  • Bug Fix Installer crash when canceling retry operation

    The installer no longer crashes if you close it while it's retrying a download.

  • Bug Fix Submit Issue dialog crash resolved

    If you previously encountered an error when trying to submit a support issue, this should now work without problems.

  • Bug Fix Submit Issue crash resolved

    The Submit Issue feature will now work reliably even on systems with restricted Windows management permissions or limited WMI access.

  • Bug Fix Fixed SQL syntax error in future price cleanup

    Corrected a SQL syntax error in the "Remove CP Equals FP All" operation where ISNULL function was missing its required second parameter. This would have caused the operation to fail with a database error.

  • Bug Fix Installation script preload handles missing blob paths

    The Support Tools screen will no longer crash when downloading installation scripts if some script records are incomplete.

  • Bug Fix Extended database operation timeout to prevent failures on large queries

    Database commands now use a 10-minute (600 second) timeout by default instead of SQL Server's 30-second default. This prevents timeout errors when processing large imports, generating complex reports, or performing bulk pricing updates that legitimately take longer to complete.

  • Bug Fix Increased database operation timeout to prevent failures

    The timeout for database operations has been raised from 30 seconds to 600 seconds (10 minutes). This prevents timeout errors during long-running operations such as large imports, complex pricing analysis calculations, or database maintenance tasks.

  • Bug Fix Loading overlay now dismisses before error dialogs

    If a database restore fails, you'll now see the error message immediately instead of the app appearing to freeze.

  • Bug Fix Restore crash with pre-metadata backup files

    You can now restore older database backup files without the application crashing during the restore process.

  • Bug Fix Diagnostic Tool launch failure resolved

    The Diagnostic Tool will no longer crash when launched for the first time or if log files have been cleaned up.

  • Bug Fix Corrected assembly version binding in build pipeline

    Build 2026.625.23688 introduced an assembly version override that propagated to MarginMaster.Common (which is pinned to version 1.0.0.0). This created a version mismatch where the main executable expected Common@20.26.625.23688 but the shipped library remained at 1.0.0.0, causing a FileNotFoundException during application startup before logging or auto-update could run. The build pipeline now only stamps FileVersion (used for dashboard reporting) while preserving AssemblyVersion stability to prevent binding failures.

  • Bug Fix Condition list now refreshes immediately after editing

    When you add or remove values from a pricing strategy condition, the condition list now updates immediately on screen instead of appearing unchanged until you close and reopen the editor.

  • Bug Fix Restored missing custom selection box views after startup timeout

    Your saved custom selection box views (like "ACE SELECTION BOXES") will now appear correctly in the selection box editor and remain active when running pricing strategies.

  • Bug Fix Fixed crash when applying pricing strategies with invalid price or margin values

    Pricing strategies with missing or invalid price/margin values now show a helpful error message instead of crashing.

  • Bug Fix Improved handling of missing database columns

    Modified SQL query error handling to immediately stop retrying when encountering "Invalid column name" errors (SQL error 207), treating them as permanent structural issues rather than transient failures. Previously, the system would exhaust all 3 retry attempts before logging the error, causing unnecessary delays and error log noise.

  • Bug Fix SQL timeout logging restored to error level

    Reverted a change that logged SQL timeouts as warnings instead of errors. Timeouts indicate the operation did not complete successfully and must remain visible as errors in diagnostic logs for proper troubleshooting.

  • Bug Fix Added guard against empty store numbers during import

    Imports will no longer fail if some records are missing store number information—they'll be safely skipped instead.

  • Bug Fix License dialog cross-thread crash resolved

    Fixed an error that could cause Margin Master to crash when checking your license at startup.

  • Bug Fix License validation dialog cross-thread exception

    Margin Master will no longer crash when showing license error messages during startup.

  • Bug Fix Fixed zero on-hand counts for Epicor stores in statistics

    Epicor stores now see accurate on-hand inventory counts in the Statistics dialog.

  • Bug Fix Unresponsive close button in installer

    The X button now always closes the installer window, even when showing an error or "already installed" message.

  • Bug Fix Prevented crashes when checking SQL Server backup folder permissions

    Added permission check before querying SQL Server service account information. Previously, on systems where the database user lacked VIEW SERVER STATE permission, the application would crash with a SqlException when attempting to configure backup folder access.

  • Bug Fix ZIP extraction errors are now properly reported

    When a backup ZIP file is corrupted or can't be extracted, you'll now see a clear error message explaining what went wrong.

  • Bug Fix Strategy execution errors due to missing fields

    Strategy execution will no longer fail with "missing field" errors after the application falls back to default views.

  • Bug Fix Fixed duplicate column name error when exporting to Excel

    Exporting reports to Excel no longer fails when column names are duplicated.

  • Bug Fix One-Click screen no longer crashes with null inventory values

    Fixed a crash that could occur on the One-Click screen when filtering items with missing On Hand or sales history data.

  • Bug Fix Fixed startup crash when importing POS data

    Moved the creation of the IsNotFound column on StoreManagerInfo table to run earlier in the startup sequence, before the store reconciliation process attempts to reference it. This prevents crashes during POS data import operations that occur immediately after application launch.

  • Bug Fix SQL Server 2022 permission model now supported

    The backup folder access check now recognizes SQL Server 2022's new VIEW SERVER PERFORMANCE STATE permission in addition to the older VIEW SERVER STATE permission. This ensures the feature works correctly on newer SQL Server versions where Microsoft split the permission into two separate grants.

  • Bug Fix All early-exit error paths now clear loading state

    Fixed multiple code paths in the restore process (cloud download failures, missing backup file) that could show error dialogs while the loading overlay was still active. All error conditions now properly dismiss the loading overlay before displaying error messages.

  • Bug Fix Fixed crash during application startup migration

    Corrected a duplicate key error that could occur during the automatic migration of persistent settings when upgrading the application. The migration process now properly tracks already-migrated settings to prevent conflicts.

  • Bug Fix Future Price rules validate margin values before saving

    Fixed an issue where saving a Future Price rule with an empty margin value could create invalid pricing strategies.

  • Bug Fix Fixed crash when running pricing strategies at startup

    Ensured the SkuExceptions table is created during startup initialization, before pricing strategies execute. Previously, strategies could attempt to query this table before it existed, causing startup failures.

  • Bug Fix Fixed crash when parsing pricing strategy rules with duplicate parameters

    Resolved an ArgumentException that occurred when pricing strategy rules contained duplicate parameter keys (e.g., multiple rounding specifications). The parser now handles duplicates by using the first occurrence.

  • Bug Fix Fixed crash in MySQL Compass store mapping lookup

    Corrected an InvalidOperationException in the MySQL Compass import process when the EpicorUseStoreMapping configuration was missing. The lookup now safely handles missing configuration values.

  • Cloud Sync Resilient cloud sync bulk upsert operations

    Cloud sync is now more reliable when handling large amounts of data, automatically recovering from temporary database busy conditions.

  • User Interface Modern frameless bootstrapper design

    The Margin Master installer now has a sleeker, more modern appearance with a green header and rounded window edges.

  • User Interface Modern bootstrapper design with green header bar

    Redesigned the bootstrapper window with a modern appearance featuring a green header bar with drag-to-move capability, rounded corners, drop shadow, and a borderless design. The window now matches the visual style of the main Margin Master application.

  • User Interface Connection test resets availability cache

    Successfully testing the MySQL connection in Tools > Options now resets the availability cache, allowing the system to resume querying MySQL directly for store and inventory data in the Import Manager.

  • User Interface Real-time statistics updates

    The statistics screen stays responsive when changing filter options, even with large product catalogs.

  • User Interface Enhanced download progress display

    You can now see how much time remains during download, and clicking the X button will cancel the download in progress.

  • Database Added table existence validation

    Both BackupCostBreaksAsync and RestoreCostBreaksAsync methods now query for table existence using SQL Server's OBJECT_ID function and skip the operation if the table is not present, returning an empty list or exiting early respectively.

  • Database Improved error classification and logging

    Refined error logging to distinguish between transient errors (which are retried and logged as warnings if they persist), permission-denied errors (logged as warnings for best-effort operations), and genuine SQL errors (logged as errors). This reduces log noise from temporary issues that resolve themselves while maintaining visibility into real problems that require attention.

  • Architecture SQL-based statistics calculation

    Statistics calculations are now faster and more responsive, particularly when analyzing large product selections.

  • Architecture Improved database read performance under load

    Eliminated application-level locking (semaphore) from all read-only GlobalFileConfig operations. SQL Server's native concurrency controls are sufficient for SELECT queries — only write operations (INSERT/UPDATE/DELETE) require application-level coordination. This prevents slow reads on SQL Express instances from blocking other operations throughout the application, improving responsiveness during startup and normal operation.

  • Architecture Lazy initialization for auto-update service

    Moved database-dependent initialization in AutoUpdateService from the constructor to a deferred EnsureInitialized() method that runs on first use. This prevents database queries during dependency injection resolution, allowing the application to start and display configuration dialogs even when the database is unreachable.

  • Architecture Separated save logic from dialog close handling

    Extracted the column view save logic into a new CommitSave() method that returns success/failure without attempting to close the dialog. This allows the same save logic to be used both during explicit saves (which should close the dialog) and during close-with-prompt scenarios (where WPF is already handling the close).

  • Infrastructure Automatic retry logic for transient SQL errors

    When the database is temporarily busy or the network connection hiccups, the app now automatically tries again instead of immediately showing an error.

  • Infrastructure Improved error logging for database timeouts

    Removed special handling that was downgrading SQL timeout errors to warnings. All database errors are now consistently logged at the Error level, making it easier to diagnose issues. The previous approach was masking real timeout problems that needed to be fixed at their source.

  • Infrastructure Removed System.Management dependency

    Eliminated the System.Management package reference from both the Common library and main application, reducing the application's dependency footprint and avoiding potential deployment issues with this library.

  • Infrastructure Removed System.Management dependency

    Eliminated the System.Management package dependency from both the Common and UI projects, reducing the application's attack surface and removing a potential source of deployment issues on locked-down systems.

  • Infrastructure Restored stable assembly binding behavior

    Removed the global AssemblyVersion property override from the publish workflow while retaining FileVersion and InformationalVersion stamping. This ensures the version reported to the dashboard (OrganizationComputers.MMVersion) remains accurate while preventing CLR binding failures that cause startup crashes.

Infrastructure & Internal

  • Improvement One-click restart installs latest version

    When you click "Restart to Update," the app now checks one final time for the newest version and installs it automatically—you no longer need to download updates multiple times if new versions are published quickly.

  • Bug Fix SQL backup fails when metadata contains apostrophes

    Database backups will no longer fail if your store name or other settings contain apostrophes (like "Joe's Hardware").

  • Bug Fix Fixed SQL datetime overflow error in timeout tracking

    SqlTimeouts records loaded from the database with NULL dates now initialize to the current UTC time instead of DateTime.MinValue, preventing "SqlDateTime overflow" errors when updating timeout records.

  • Bug Fix Automatic publish flag reset after deployment

    After each software update is deployed, the system now automatically makes it available to all stores without requiring manual intervention from the support team.

  • Bug Fix Prevent rebuild loops during concurrent sync and import operations

    Fixed an issue where concurrent sync or import operations could re-add rebuild requests to the processing queue while a rebuild was already in progress, causing the system to rebuild multiple times unnecessarily. The system now defers any rebuild requests that arrive during processing and schedules them for the next processing cycle instead.

  • Bug Fix Crash when saving new SKU-level exceptions

    The SKU Exceptions screen will no longer crash when saving a new exception in certain scenarios.

  • Bug Fix Eliminated settings migration crash on concurrent startup

    If two people open Margin Master at the exact same time, both will now start successfully without errors.

  • Bug Fix DIB catalog items now populate all price levels correctly

    Adding items from the Do-It-Best catalog will now immediately show all five price levels in the pricing grid without needing to wait for a rebuild.

  • Bug Fix Logging error when cost break value is null

    Future pricing panel will no longer encounter errors when cost break values are empty.

  • Bug Fix Fixed foreign key failures during schema updates

    Schema migration now creates all missing tables first before adding foreign key constraints. Previously, if a parent table and child table with a foreign key relationship were both missing, the foreign key creation would fail because it ran before the parent table was created.

  • Bug Fix Graceful fallback if latest version download fails

    If downloading the newest version fails during restart, the app will still install the previously downloaded update instead of canceling.

  • Bug Fix Database rename now uses accessible backup location

    Database rename operations now work more reliably on systems with restricted SQL Server backup folder permissions.

  • User Interface Quick Find SKU column now auto-sizes to content

    When searching for items using Quick Find, the SKU column will now automatically adjust to show the full SKU number without being cut off.

  • User Interface Progress indication during inline update download

    If a newer update is found when you click restart, you'll see a progress bar showing the download of the latest version before the app restarts.

  • Infrastructure Improved deployment reliability

    Added a fail-safe mechanism that ensures the update availability flag is properly reset at the end of every publish run, regardless of whether the deployment succeeded, failed, or was cancelled. The step includes error handling and will continue even if the API call fails, preventing one failure from blocking future deployments.

Other Changes

  • New Feature Restore Backup button added to startup Database Setup window

    If Margin Master can't find your database at startup, you can now click "Restore Backup" to load a saved backup file directly from the setup screen.

  • New Feature Multi-monitor detection and display information service

    Added comprehensive display detection that identifies all connected monitors, their resolutions, DPI scaling factors, and physical arrangement (left/right/above/below primary). The system properly handles high-DPI displays and accounts for taskbar positions when calculating available screen space.

  • New Feature Display configuration detection service

    Added a new service that detects monitor count, resolution, DPI scaling, working area (accounting for taskbars), and multi-monitor arrangement. This service automatically refreshes when monitors are connected or disconnected and provides DPI-aware sizing calculations for proper window placement on high-DPI displays.

  • New Feature Issue Contact editor dialog

    Click Help > Support Issues > Issue Contact to update the name, email, and phone number that will be used when you submit support issues.

  • New Feature Submit Issue tool added to Database Setup window

    If you encounter an error during setup, click the "Report this issue" link to quickly submit details to support without needing to complete database setup first.

  • New Feature Submit Issue from Database Setup window

    If you encounter an error while setting up your database connection, you can now click "Report this issue" to send details directly to support without completing the setup.

  • New Feature Item-level backup selection with tree view dialog

    When backing up or restoring, you can now expand categories like "Pricing Strategies" to select only the specific strategies you want, instead of including everything in that category.

  • New Feature V3 backup format with comprehensive configuration coverage

    Extended backup system to include cost breaks, min/max strategies, minimum margins, selection box views, column views, custom field names, custom sort orders, and store match-ups. These were previously scattered across GlobalFileConfig entries and are now organized into discrete, strongly-typed sections. Format version incremented to 3 with automatic backward compatibility for V1 and V2 formats.

  • New Feature SQL script support in Installation Scripts dialog

    Added a new script type system that distinguishes between PowerShell scripts (executable) and SQL scripts (clipboard-only). The dialog now dynamically shows either "Execute Script" or "Copy to Clipboard" buttons depending on the selected script type, preventing accidental automated execution of SQL commands.

  • New Feature Software installation detection

    The diagnostic assistant can now see what database and development software is installed on your computer to give better troubleshooting help.

  • New Feature Installed software inspection

    Added `get_installed_software` tool that reads Windows Registry to identify installed SQL Server instances, ODBC drivers (SQL Server, MySQL, PostgreSQL), and .NET Framework versions. The AI can now diagnose issues related to missing database drivers or SQL Server connectivity problems by checking what's actually installed on the machine.

  • New Feature AI-assisted SQL Server 2025 Express upgrades

    Ask the AI assistant to check your SQL Server version — it can upgrade you to SQL Server 2025 automatically, walking you through each step and handling any installation issues.

  • New Feature Network scanning for MySQL servers

    Click the search button next to the Server field to automatically find MySQL servers on your network.

  • New Feature Idle auto-trigger with 10-second countdown

    If you leave the update notification open for 30 minutes, it will count down from 10 seconds and then install the update automatically. Click Cancel during the countdown to wait another hour.

  • New Feature Quick Issue Submission dialog

    Support staff can now capture diagnostic files quickly through a streamlined form in the Support Issues window, with real-time progress updates during upload.

  • New Feature Unified Store Manager window

    Click "Open Store Manager" in Settings > Connections to manage all store mappings in one place. The grid shows your POS stores, vendor store numbers, zones, and import settings. For Epicor systems, store characters are displayed as "W (87)" format.

  • New Feature Store Manager screen

    Open Store Manager from Settings → Connections to view all stores, edit vendor store numbers and zones, enable/disable stores for import, and refresh store data from your POS system.

  • New Feature SQL Server edition detection

    When setting up your database, Margin Master now shows which version of SQL Server you're using (like "Express" or "Standard") and gives helpful advice based on that version.

  • New Feature System Diagnostics window

    A new System Diagnostics tool is now available under File > Utilities. This window shows you a complete overview of your system's health—database connection, license status, disk space, and recent errors—with one-click options to copy the information or send it to support for faster troubleshooting.

  • New Feature System Diagnostics window

    Click Support > System Diagnostics to view a complete overview of your Margin Master installation, including database status, license details, and recent errors.

  • New Feature Prerequisites category in Installation Scripts dialog

    Support staff will see a new Prerequisites section in the Installation Scripts dialog.

  • New Feature Delete submitted issues

    When viewing one of your previously submitted issues, you'll now see a "Delete Issue" button (in red) next to the "Update Issue" button. Clicking it will ask you to confirm, then permanently delete the issue from the system.

  • New Feature Show all toggle for organization-wide backup viewing

    Support technicians will see a new "Show all" checkbox next to the cloud scan button. Unchecking this box limits the backup list to only the current store, making it easier to find the right backup file.

  • New Feature Store number display format options

    In Settings → Connections, you can now choose how store numbers appear in dropdown lists. For example, you can display "1715 (00042)" instead of "00042 (1715)" if you prefer to see the POS store number first.

  • New Feature Window placement persistence across sessions

    When you close Margin Master, it remembers your window size, position, and which monitor you were using. The next time you open it, the window appears exactly where you left it—even if you have multiple monitors.

  • New Feature Window placement persistence

    The main window will now reopen at the same size and position where you left it, even on multi-monitor setups.

  • New Feature Added OLEDB 12.0 installer script for RockSolid POS support

    If you're setting up a new workstation for RockSolid POS data import, you can now install the required OLEDB driver directly from the Support Scripts menu instead of downloading it manually.

  • New Feature Demo Database download added to Database Setup window

    Click "Demo Database" to download sample data and explore Margin Master before connecting to your store's database. The demo database will be automatically selected once downloaded.

  • New Feature Demo Database download from Database Setup window

    You can now download a demo version of Margin Master directly from the connection screen to explore the software before setting up your store's data.

  • New Feature Support issue reopen capability

    You can now reopen support issues that were previously marked as resolved by clicking the "Reopen Issue" button in the Support Tools screen.

  • New Feature V3 backup format with comprehensive configuration coverage

    Backups now capture all pricing rules and view settings, including cost breaks, min/max strategies, and custom column layouts that were previously incomplete.

  • New Feature Backup history browser for cloud restore

    When restoring from the cloud, you can now see all your saved backups and choose which one to restore, rather than only getting the latest version.

  • New Feature Database creation script with clipboard workflow

    Support staff can now access the complete database creation script directly from the Support Tools menu, useful for troubleshooting or manual server setups.

  • New Feature Windows Package Manager integration

    The diagnostic tool can now help you install missing software like SQL Server automatically using Windows Package Manager.

  • New Feature Windows Package Manager (winget) integration

    Added `run_winget` tool allowing the AI assistant to execute winget commands (list, search, show) to check for available software updates or search for specific packages. This enables the AI to suggest installing missing dependencies or checking software versions through Windows Package Manager.

  • New Feature AI-assisted SSMS installation and upgrades

    The AI assistant can install or upgrade SQL Server Management Studio for you — just ask it to check your SSMS version.

  • New Feature Zone editing popup for Ace/EJ stores

    Click the "Edit" button in the Zone column to change a store's zone. You can override the Ace-assigned zone or clear your override to use the original assignment.

  • New Feature Start SQL Server Service button

    If SQL Server is installed but not running, you can now start it with one click directly from the database setup screen.

  • New Feature Optional SSMS installation and upgrade during setup

    If you don't have SQL Server Management Studio installed (or have an old version), Margin Master will now detect this and offer to install or upgrade it for you with a single click.

  • New Feature Detect existing installation and offer launch or reinstall

    If Margin Master is already installed, the installer will let you choose to launch it or reinstall a fresh copy. Reinstalling will automatically close Margin Master if it's running.

  • New Feature Install .NET 10 Desktop Runtime script

    When a workstation can't launch Margin Master due to missing .NET, support staff can run this script to automatically download and install the required runtime instead of doing it manually.

  • New Feature Add support representatives to contact list

    You can now add Margin Master support staff to your contact list using the "Add Support Representative" button.

  • New Feature Save button for editing existing contacts

    Added a Save button under Contact Details that allows you to update existing store contacts (name, email, phone). Previously, you could only create new contacts or delete existing ones. The save function works for both new contacts being created and existing contacts being modified, and all contact fields now refresh immediately after saving.

  • New Feature Store number sorting preference

    You can now sort the store number list by either vendor store numbers or POS store numbers, whichever makes more sense for your workflow.

  • New Feature Cloud backup access prompt when store information unavailable

    If you try to restore from cloud backup before connecting to a database, you'll now be asked to select your primary vendor and enter your store number so the system can find your backups.

  • New Feature Cloud backup access without active database connection

    You can now browse and restore cloud backups even if you don't have a database connected yet. If needed, you'll be asked to enter your vendor and store number once per session.

  • New Feature AI-assisted Margin Master updates

    The AI assistant can check for and install Margin Master updates — ask it to update the application and it will handle the process automatically.

  • New Feature Configurable authentication and SSL options

    If you see SSL or authentication errors, try selecting "SSL Disabled" or "Public Key Retrieval" from the Auth/SSL dropdown on the MySQL connection screen.

  • New Feature What's New button in update dialog

    Click "What's New in This Version" to see what changed in the update before deciding to install it.

  • New Feature Store detail popup

    Click the "Detail" button to view cloud sync information for a store, including whether it's open or closed and when it was last synced.

  • New Feature SQL Server Management Studio (SSMS) detection and installation

    Margin Master can now detect if SQL Server Management Studio is installed and help you install or upgrade it with guided progress tracking.

  • New Feature Add support representatives as contacts

    You can now add support representatives to your contact list using the "Add Support Representative" button.

  • New Feature Backup inventory service for item enumeration

    New BackupInventoryService queries the database before backup to build summary lists of pricing strategies (with step/group/exception counts), non-system rounding schemes, cost breaks, min/max strategies, selection box views, and column views. Powers the tree view population in the backup dialog and provides item-level filtering options.

  • New Feature Auth/SSL dropdown for MySQL 8+ compatibility

    A new Auth/SSL dropdown helps you connect to newer MySQL 8 servers that use different authentication methods.

  • New Feature Troubleshooting panel for installation failures

    If the installer encounters an error, you'll see options to retry, download directly, or contact support.

  • New Feature Remove Issue action

    Added ability to remove an issue from your local issue list via a new "Remove Issue" button in the action bar. This connects to the existing backend deletion API and removes the issue from both open and closed issue lists after confirmation.

  • New Feature Delete draft issues

    You can now delete a draft issue using the "Delete Issue" button on the review step when updating an issue.

  • Improvement Streamlined issue status filtering

    When viewing open issues in Support Tools, you'll see a simpler list focused on the most important status categories.

  • Improvement Support scripts download from cloud storage

    When you run a support script (like "Install SQL Express"), it now downloads the newest version from the cloud automatically, so you always get the latest bug fixes and improvements without needing to update Margin Master itself.

  • Improvement Local attachment staging with removal support

    After clicking the paperclip to attach a file, you'll see it listed in an amber-colored bar. You can remove any file by clicking the red X next to it before sending. Files are only uploaded when you click Send.

  • Improvement Deferred attachment uploads in Support Tools

    You can now add multiple attachments to a support ticket and remove any you don't want before clicking Send. Files appear in a yellow "Pending Attachments" section until you're ready to submit.

  • Improvement Automatic file compression for issue attachments

    Large files you attach to support requests are now automatically compressed before upload, reducing upload time and making submissions faster. You'll see a "Compressing..." message while this happens.

  • Improvement Automatic compression for large file uploads

    Large files you attach to support issues are now automatically compressed before upload, which speeds up the submission process and reduces bandwidth usage.

  • Improvement Connection validation gate for database operations

    The Create and Restore buttons are now grayed out until you successfully connect to a SQL Server. This ensures you can't accidentally try to create or restore a database on a server that isn't accessible.

  • Improvement Bulk cost break model deletion script

    If you've accumulated many cost break models (especially test models with names like "New Model 1", "New Model 2", etc.), your administrator can now use this script in SQL Server to delete multiple models at once. The script shows you what models exist and lets you delete them by pattern (like all models starting with "New") or by specific name. This is much faster than clicking through each model individually in the Cost Break View screen.

  • Improvement Database backups always compressed with metadata

    Every database backup is now automatically compressed to a ZIP file, reducing file size by approximately 70-80%.

  • Improvement SQL Server service status diagnostics

    Added Windows service checking to detect SQL Server installation and running status. When no servers are found during scanning or when a connection test fails, the system now examines SQL Server services (MSSQLSERVER and MSSQL$* instances) and provides one of three diagnostic messages: SQL Server is not installed (suggests installing SQL Server Express or connecting to a remote server), SQL Server is installed but the service is stopped (lists stopped services and suggests starting them from Windows Services), or SQL Server is running but unreachable (suggests verifying the server name matches the installed instance).

  • Improvement SQL Server service status detection

    When you can't connect to SQL Server, the window now tells you exactly what's wrong—whether SQL Server isn't installed, needs to be started, or has a different connection issue.

  • Improvement Smart issue pill visibility based on installed version

    If you're experiencing an issue that's been fixed in a newer version, the notification will remind you to update. After updating, the notification will automatically go away.

  • Improvement Issue notification timing improved

    Email notifications for new issues now include all your attached files and descriptions in the initial email, making it easier for support to see what you've sent.

  • Improvement Intelligent SQL Server instance detection and selection

    During initial setup, if you have both SQL Express and full SQL Server installed, the app will now automatically pick the right one that has your database.

  • Improvement Intelligent instance auto-selection

    If you have multiple SQL Server instances installed (like SQLEXPRESS and SQL2019), the setup wizard will now find and select the one with your MarginMaster databases automatically.

  • Improvement Organization-wide cloud backup discovery

    When you click "Scan Cloud Backups," the system now finds backup files from all your stores, not just the current one. A progress message shows which store is being scanned (e.g., "Scanning store ACE 12345 (2/5)...").

  • Improvement Organization-wide cloud backup discovery

    When you click "Scan Cloud Backups," the system now finds backups from all stores in your organization. You'll see a progress message showing which store is being scanned (e.g., "Scanning store ACE 12345 (3/8)..."). This makes it easier for multi-store operators to restore data from any of their locations.

  • Improvement Automatic Visual C++ Redistributable installation

    Both the Install-SQLExpress.ps1 and Upgrade-SQLExpress.ps1 scripts now include a new prerequisite verification step that checks for Visual C++ 2015-2022 x64 Redistributable v14.40 or newer (required by SQL Server 2025). If the installed version is older than 14.40 or missing entirely, the script automatically downloads the latest version from Microsoft's evergreen URL and installs it silently. This prevents SQL Server setup failures due to missing prerequisites.

  • Improvement SQL Server default instance updated for first-time setup

    If you're installing Margin Master for the first time, the database setup will now automatically find SQL Server Express without needing to change the server name.

  • Improvement Auto-detect large sector NVMe drives during SQL Express installation

    Install-SQLExpress.ps1 now checks the physical sector size of the target data drive before installation. If a 512e or 4Kn NVMe drive is detected (sector size > 4 KB), the script automatically enables trace flag 1800 and persists it as a SQL Server startup parameter. This prevents error 0x851A001A during setup, which previously required manual intervention or running the installer with special flags.

  • Improvement Automatic large sector drive detection and workaround
  • Improvement Batch processing for SKU-level exceptions

    When running pricing strategies with many SKU exceptions, the system now processes all exceptions together in one operation rather than one at a time, dramatically reducing wait time.

  • Improvement Extended timeout for open issues API call

    Increased the timeout from 10 to 30 seconds when loading open issues in the background. The previous 10-second timeout was too aggressive for this non-critical feature, causing 43 timeouts across 18 stores over a 48-hour period.

  • Improvement Extended timeout for open issues retrieval

    The timeout for loading open issues from the cloud has been increased from 10 to 30 seconds to accommodate slower network connections and larger datasets. This should reduce timeout failures when the server takes longer to respond.

  • Improvement Automatic multi-RSC detection

    The system now automatically determines if your stores use multiple RSCs instead of requiring you to check a box in settings.

  • Improvement Automatic multi-RSC detection

    You no longer need to check or uncheck the "Multiple RSCs" option in Settings — Margin Master now automatically detects this from your store assignments.

  • Improvement Local encrypted license cache for component keys

    IPWorks and Z.EntityFramework component licenses (Z.Dapper.Plus and Z.BulkOperations) are now stored in a local encrypted cache after first fetch. On subsequent startups, licenses load from the cache first, falling back to the API only when the cache is empty or stale, and finally to appsettings.json as a last resort. This three-tier approach reduces startup time and API dependency while maintaining security.

  • Improvement Connection settings persistence improved

    When setting up FTP or MySQL connections, your entered values are now saved even if the test fails, so you only need to fix what's wrong and test again.

  • Improvement Save connection settings before testing

    When setting up FTP or MySQL Compass connections, your settings are now saved even if the test fails, so you only need to fix the incorrect field instead of re-entering everything.

  • Improvement Multi-step connection diagnostics

    When testing your MySQL connection, the system now automatically tries multiple approaches and tells you exactly which method worked, making it easier to diagnose connection problems.

  • Improvement Manager API now coordinates auto-update checks

    Update checks will succeed even if your store's firewall blocks access to Azure cloud storage, because the app now checks through the Manager API first.

  • Improvement SQL Server version detection and validation

    You'll now see which version of SQL Server you're connecting to, with a warning if your server is older than SQL Server 2022.

  • Improvement Resume interrupted downloads automatically

    If your download is interrupted, the installer will pick up where it left off instead of starting over.

  • Improvement Enhanced update availability messaging

    The update checker will now show you more helpful information, like "check back soon" if a new version is currently being prepared, rather than just saying you're up-to-date.

  • Improvement Server-controlled status messages during update checks

    When you check for updates, you may see specific messages explaining why updates aren't currently available, such as during scheduled maintenance or while a new version is being published.

  • Improvement Bootstrapper no longer requires pre-installed .NET runtime

    Installing Margin Master on a new computer no longer shows confusing prompts about downloading .NET — the installer just runs.

  • Improvement Self-contained installer eliminates .NET runtime dependency

    You can now run the Margin Master installer on any Windows computer without needing to install additional software first.

  • Improvement Contact selection is now optional when submitting issues

    You can now skip selecting a contact when submitting an issue by checking "Do not contact me about this issue."

  • Improvement Optional contact information

    You can now check "Do not contact me about this issue" if you don't want to be contacted about a submitted issue.

  • Improvement Automatic retry for failed issue notifications

    When submitting an issue from the Support Tools screen, if the notification to RetailerSoft fails to send, the system now automatically retries once after a 4-second delay before giving up.

  • Improvement Automatic retry for issue submission notifications

    Issue submissions are now more reliable with an automatic retry if the notification doesn't send on the first attempt.

  • Improvement Enforce contact selection on issue submission

    When creating a support issue, you'll now see a warning if you try to continue without selecting a contact. The Submit button won't be available until you've chosen someone from your store contacts or a support rep.

  • Improvement Smart version mismatch handling

    When opening a database that was last used with a newer version of Margin Master, the app will now try to update itself automatically before asking you whether to continue or quit. This prevents accidental data issues from running an outdated version.

  • Improvement Intelligent view selection on database restore

    When you open a restored customer database, Margin Master will now automatically use the customer's custom view if there's only one, instead of defaulting to the standard view and showing warnings.

  • Improvement Smart view selection on database restore

    When you restore a database backup that contains your custom column layout, the application will now automatically use that layout instead of switching to the default columns, so you don't have to manually reselect your preferred view.

  • Improvement Database fallback for IPWorks component licenses

    The license retrieval system now includes a four-tier fallback: memory cache, cloud API, local database (new), and appsettings.json. When licenses are successfully retrieved from the cloud, they're now persisted to the local database. If the cloud service is unavailable on subsequent launches, the application will use the database-stored licenses instead of falling back immediately to the build-time defaults.

  • Improvement Descriptive backup file naming for support issues

    Backup files created when you submit support issues now show your store's vendor, number, and name in the filename, making them easier to identify.

  • Improvement Enhanced issue backup file naming

    When you submit a support ticket that includes a database backup, the backup file now includes your store information in its name, helping the support team identify and prioritize your issue more quickly.

  • Improvement Support machine cloud backup scope control

    When restoring a database on a support machine, you'll now see only the current store's backups by default. Check the "Show all" box to see backups from all stores in your organization.

  • Improvement Smart update installation

    You no longer need to click the update badge twice if a new version is published while you're working — one click always gets you the latest version.

  • Improvement Version tracking in license validation

    The system now prevents you from accidentally opening an old version of Margin Master after you've upgraded to the latest version, avoiding potential data compatibility issues.

  • Improvement Version detection fallback

    Added a fallback mechanism for local development builds that don't have CI-generated version information. If the preferred version metadata isn't available, the app will still derive a valid version number from assembly information, maintaining compatibility with local development scenarios.

  • Improvement Improved update restart safety logic

    Renamed the internal flag from `updateFailed` to `skipAutoApply` to more accurately reflect its purpose. The flag now prevents auto-apply in both success and failure scenarios: successful updates are blocked from chaining into another immediate update, and failed updates won't retry the same broken installation automatically.

  • Improvement Check server fallback flag before attempting blob upload

    The upload process now checks the FallbackToIssueAttachments flag returned by the server's upload-target endpoint. When this flag is set, the system skips blob storage entirely and uses the legacy HTTP upload path immediately, avoiding unnecessary retry delays.

  • Improvement Better error handling for attachment upload failures

    File uploads will complete successfully more often, even when there are temporary connectivity issues or server configuration changes.

  • Improvement Streamlined database recovery workflow

    Restoring a backup during startup now takes you directly into Margin Master once the restore finishes—no extra steps needed.

  • Improvement Enhanced Order Indicator dropdown display for Do-It-Best Epicor stores

    When filtering by Order Indicator, the dropdown now shows the code letter first (like "T - Stock/Order Through"), making it faster to find the option you need.

  • Improvement Remove button for attachments in local display

    You can click the red X next to any attachment to remove it from your view (this doesn't delete the file from the support ticket).

  • Improvement Remove attachment from display

    You can now click the X button next to any attachment to remove it from your view of the conversation.

  • Improvement Send button enabled for attachments-only submissions

    You can now send attachments to a support ticket without typing a comment—just attach the files and click Send.

  • Improvement Restore database dialog uses validated server credentials

    The Restore Database dialog now receives the SQL Server name and authentication credentials that were already validated in the Database Setup window, instead of defaulting to localhost. This ensures the restore operation targets the correct server without requiring users to re-enter connection information.

  • Improvement Single database backup per issue

    If you submit a database backup with a support request, any previously attached backup will be automatically replaced with the new one, ensuring support staff always have your latest data.

  • Improvement Single database backup enforcement

    When submitting multiple database backups with an issue, only the most recent backup is kept to avoid confusion.

  • Improvement Connection credentials passed to restore dialog

    When launching the Restore Database dialog from the Database Setup window, the validated server name and SQL authentication credentials (if using SQL Server authentication) are now automatically passed through, eliminating the need to re-enter connection information.

  • Improvement Increased minimum database timeout threshold

    Raised the adaptive timeout minimum floor from 200ms to 500ms for lightweight database operations in CentralSemaphoreRepository. This provides more breathing room during startup when multiple operations compete for database access, reducing the likelihood of transient timeout failures.

  • Improvement Warning dialog when custom views fail to load

    If your custom view fails to load (rare), you'll now see a warning message explaining what happened and how to fix it by restarting the application. Your saved views are never lost.

  • Improvement Direct condition manipulation

    Removing condition values now happens instantly without needing to understand or edit the rule syntax manually.

  • Improvement Enhanced download progress logging

    Cloud backup downloads now log progress at 25%, 50%, 75%, and 100% completion milestones, making it easier to track long-running downloads in the application logs without flooding the log file with continuous updates.

  • Improvement Automatic instance switching on Database Setup screen

    If your MarginMaster database moved to a different SQL Server instance, the setup screen will now detect this and switch automatically.

  • Improvement Smart instance switching on initial load

    If your databases were moved to a different SQL Server instance, the setup screen will detect this and switch to the correct instance automatically.

  • Improvement Enhanced prerequisite verification documentation

    Both SQL installation markdown documents now include the Visual C++ verification as an explicit step in the "What It Does" section, and the troubleshooting tables include a row explaining the "Version 14.40 or newer" error message with instructions to re-run the script or install manually.

  • Improvement Auto-detect large sector NVMe drives during SQL Express upgrade

    Upgrade-SQLExpress.ps1 now queries sys.master_files to identify the drive hosting existing SQL data files and checks its physical sector size. If a large-sector drive is detected, the script automatically enables trace flag 1800 for the upgrade and persists it as a startup parameter. This prevents upgrade failures on systems with newer NVMe hardware.

  • Improvement Removed obsolete trace flag 1800 logic from SQL Express scripts
  • Improvement Real-time performance metrics for batch operations

    The batch processing system now logs detailed performance metrics including total exceptions processed, SKUs affected, and processing mode ("Batch" vs. fallback). Strategy execution logs display the batch mode status and provide visibility into which approach was used.

  • Improvement Enhanced error reporting during database setup

    If database setup fails, you'll now see a clear explanation of what went wrong instead of a generic error message.

  • Improvement Increased connection retry attempts for new databases

    Increased retry attempts from 3 to 5 and retry delay from 500ms to 1000ms when connecting to newly-created databases. SQL Server Express sometimes requires additional time before accepting connections to databases created via master connection, and the longer retry window improves success rates on slower systems.

  • Improvement Automatic license recovery on validation failure

    When any component license (Z.Dapper.Plus, Z.BulkOperations, or IPWorks) fails validation during startup, the system now automatically invalidates the cached entry and attempts to refresh from the API. This ensures users aren't stuck with stale or corrupted license keys and reduces manual intervention needed for license issues.

  • Improvement Automatic license refresh on validation failure

    When a component license validation fails (e.g., due to expired or corrupted cache entry), the system automatically invalidates the cache and re-fetches fresh keys from the API. This self-healing mechanism ensures FTP/SFTP/ZIP operations and bulk database operations remain functional without manual intervention.

  • Improvement Simplified issue status logic

    Streamlined the logic that determines which support issues to display by removing the version comparison check. This makes the behavior more predictable and ensures stores always see the current status of their issues.

  • Improvement Reduced issue polling frequency and automatic stop

    The system now checks for support issue updates every 30 minutes instead of every 60 seconds, reducing unnecessary network traffic. Once all support issues are resolved or closed, the system automatically stops polling until the application is restarted, eliminating unnecessary background requests when no issues are open.

  • Improvement Optimized issue polling behavior

    Once your support issues are resolved, Margin Master will stop checking for updates automatically.

  • Improvement Actionable error messages with fix instructions

    Error messages now tell you exactly how to fix connection problems instead of just showing technical error codes.

  • Improvement Multi-step connection testing with smart error messages

    When a connection test fails, you'll now see specific instructions on how to fix the problem instead of technical error codes.

  • Improvement View settings cleanup added to migration process

    View-specific settings (grid layouts, column widths, etc.) that are now handled by a dedicated migration process are also marked for deletion from the legacy GlobalFileConfig table, preventing them from accumulating and slowing down future startups.

  • Improvement Action buttons disabled during processing

    Support issue action buttons are now properly disabled while an action is being processed, preventing duplicate submissions if the user clicks multiple times during the server request.

  • Improvement Enhanced support ticket context

    Support tickets now include 12 key data points about the user's environment (product version, operating system build, SQL Server edition and version, active database and server names, machine name, store configuration, vendor settings, and POS system type). This comprehensive snapshot enables faster troubleshooting and reduces back-and-forth communication.

  • Improvement Shared server advisory banner

    If you're connecting to a SQL Server that's shared with other programs, you'll now see a helpful reminder that Margin Master creates its own separate database and won't affect your other data.

  • Improvement Database size monitoring with Express edition warnings

    The diagnostics window now shows your database size with a visual progress bar and warns you if you're approaching the 10GB limit on SQL Server Express edition, so you can upgrade before running out of space.

  • Improvement Enhanced database size tracking

    The diagnostics window now warns you if your database is getting close to the 10GB limit for SQL Express, helping prevent database issues before they occur.

  • Improvement Persistent retry tracking across restarts

    If installation fails multiple times, you'll see helpful links to download directly or contact support, even if you close and reopen the installer.

  • Improvement Faster installation experience

    By removing the framework check parameter from the build process, the installer now runs more quickly and with fewer potential points of failure during deployment to retail stores.

  • Improvement Improved license expiration error message

    If you see a license expired error, the message now shows which store number failed and suggests checking if it's correct, making it easier to identify configuration issues.

  • Improvement Store Manager auto-saves on window close

    When you close the Store Manager window, your changes are now automatically saved—you don't need to click Save first.

  • Improvement Reduced bootstrapper download size

    Changed the bootstrapper executable from self-contained to framework-dependent deployment, reducing the initial download size from ~66MB to ~6MB. Users must have .NET Desktop Runtime installed, which is standard on modern Windows systems and is already required for the main application.

  • Improvement Automatic duplicate contact removal

    Duplicate contacts are now automatically removed from the contact list.

  • Improvement Clearer messaging for missing contact

    Changed the contact validation message from a Yes/No question to a direct warning that explains a contact is required and instructs users where to select one (Store Contacts tab or Support Rep dropdown). This eliminates confusion about whether contact selection is optional.

  • Improvement Corrected log messages for SQL user creation

    Fixed misleading log messages in the SQL user creation process. Success messages now correctly indicate "Created MarginMaster SQL user successfully" instead of suggesting it was already done. Failure messages now spell "SUCCESSFUL" correctly and provide clearer context about permission requirements.

  • Improvement Automatic filename sanitization for backup files

    Special characters and spaces in store names, vendor names, and POS system identifiers are automatically cleaned up and replaced with underscores in backup filenames, ensuring compatibility across different operating systems and file storage systems while maintaining readability.

  • Improvement Default cloud backup view restricted to current store

    By default, only the current store's backups will be shown, making it faster to find the right file to restore.

  • Improvement Refactored package directory resolution

    Package directory resolution logic was extracted into a shared GetPackagesDir() helper method to eliminate duplication between the logging and fallback recovery code paths.

  • Improvement Enhanced update failure logging

    Delta-patch failures are now logged as warnings with clearer messaging ("Delta update patch failed — retrying with the full package") rather than errors, making it easier to distinguish between recoverable update issues and genuine failures that require user intervention.

  • Improvement Confirmation prompt before removing stores from MySQL

    Store Manager now asks for confirmation and shows you exactly which stores will be removed before making any changes.

  • Improvement Store Manager now displays warnings when cloud save fails

    You'll now see a clear warning message if your store changes can't be sent to the cloud, and the changes will remain pending so you can retry.

  • Improvement Enhanced audit trail for store configuration

    Changes to store settings can now be traced back to the specific computer that submitted them, making it easier to troubleshoot configuration issues when multiple users manage store setups across different workstations.

  • Improvement Settings sections disabled until feature is enabled

    All vendor sync schedules, POS import schedules, service installation controls, and run history are now wrapped in an enabled/disabled state that reflects the BackgroundServiceFeatureEnabled database flag. This prevents configuration of a feature that isn't active on the current machine while keeping the tab accessible for viewing status.

  • Improvement Clear error messaging for oversized file uploads

    Error messages for failed uploads now clearly explain that your file was too large and couldn't be uploaded, instead of showing confusing technical errors.

  • Improvement Splash screen positioning on correct monitor

    The loading screen now appears on the same monitor where you last had Margin Master open, instead of appearing between monitors.

  • Improvement Multi-monitor splash screen placement

    The startup splash screen now appears on the correct monitor instead of spanning across multiple displays.

  • Improvement Added session-based password authentication

    After entering the support password once, you won't be asked for it again until you restart Margin Master.

  • Improvement Duplicate attachment filename detection

    If you try to attach a file with the same name as one already uploaded, you'll see a warning and the upload will be stopped.

  • Improvement Duplicate attachment prevention

    If you try to attach a file that's already been added to the issue, you'll see a warning message and the duplicate won't be uploaded.

  • Improvement Send button now processes text and files together

    You can now send attachments without typing a message, and the Send button shows upload progress when transmitting files.

  • Improvement Simplified Database Setup validation

    Connecting to an existing database is now faster — you don't need to re-enter store information if it's already saved in the database.

  • Improvement Increased timeout for store number updates

    Store number updates will no longer fail with timeout errors on large pricing databases.

  • Improvement Added retry logic for view loading

    If your saved views don't load immediately at startup, Margin Master will now automatically try again after a brief pause to make sure they're loaded correctly.

  • Improvement Enhanced SQL restore progress tracking

    The restore process now subscribes to SQL Server InfoMessage events to capture and log STATS restore progress messages, providing detailed visibility into the SQL restore phase in both the UI and log files.

  • Improvement Optimized UI responsiveness during cloud operations

    Replaced blocking Dispatcher.Invoke calls with BeginInvoke throughout the cloud backup scanning and download process, preventing UI freezes when loading cloud backup lists or downloading large files.

  • Improvement Enhanced connection test error reporting

    Connection test failures now trigger service diagnostics to supplement standard SQL error codes. Instead of only showing generic connection errors, the system combines SQL error information with service status to provide contextual guidance. For example, a connection timeout now differentiates between "service not running" versus "service running but not responding."

  • Improvement Detailed connection failure messages

    Error messages now tell you exactly which SQL Server service needs attention, including its current status like "Stopped" or "Paused."

  • Improvement Automatic V1/V2 to V3 conversion during restore

    Old backup files automatically convert to the new format when restoring, so you can still use backups created with previous versions.

  • Improvement Enhanced scanning progress messages

    You'll now see which store is being scanned and how many stores remain when searching for cloud backups across your organization.

  • Improvement Network-aware error messages

    Network errors (HttpRequestException, TaskCanceledException) now show a user-friendly message about checking internet connection, while other errors display a generic retry prompt. This helps users quickly identify whether the issue is local connectivity or a server-side problem.

  • Improvement Enhanced error messaging and troubleshooting

    The installation and upgrade documentation now includes troubleshooting guidance for Visual C++ prerequisite errors, explaining that the script handles this automatically and providing the manual download URL (https://aka.ms/vs/17/release/vc_redist.x64.exe) as a fallback. The script also handles multiple exit codes from the VC++ installer, including graceful handling when a newer version is already installed (exit code 1638).

  • Improvement Manual override for large sector fix

    Both scripts now accept a `-LargeSectorFix` parameter to force trace flag 1800 manually if auto-detection fails or if the user knows the drive requires special handling. The parameter is documented in usage examples and parameter tables.

  • Improvement Backup query now includes cost break configuration

    Added COSTBREAKVIEW section to the GlobalFileConfig backup query and excluded it from the catch-all configuration backup to prevent duplicate data. This ensures cost breaks are captured once with full detail rather than being missed or duplicated.

  • Improvement Six automatic backup trigger points

    The system now automatically backs up your pricing strategy whenever you make important changes, including when opening the program, saving strategies, updating rounding rules, or changing column layouts.

  • Improvement Expanded AI system knowledge

    Updated the AI assistant's system prompt to include SQL Server installation and configuration troubleshooting, SSMS usage, and general Windows IT support scenarios. This broadens the assistant's ability to help with database connectivity issues and environment setup problems.

  • Improvement Database schema inspection

    Added `get_table_schema` tool that queries INFORMATION_SCHEMA to retrieve column definitions, data types, and nullability for any table. This helps the AI understand database structure when diagnosing data-related issues or writing diagnostic SQL queries.

  • Improvement Epicor char-based store handling

    Enhances Epicor INDecoded and MySQL Compass store handling by storing both the character string (PosStoreNumber) and its Unicode ordinal value (PosStoreCharOrdinal) for all 256 possible byte values, including non-printable characters. Uses PosStoreCharHelper.ToDisplayLabel() for consistent "W (87)" style display throughout the UI. EpicorFTPFileExtractorService now sources store conversions and exclusions from StoreManagerInfo when UseStoreManagerInfo is enabled, falling back to legacy sources otherwise.

  • Improvement Better SQL Server instance scanning and version detection

    Enhanced SqlServerScannerService to query and display SQL Server product version strings (e.g., "16.0.1000.6") for each detected instance. Version information is now shown in server dropdowns and used to generate version warnings. Added GetServerVersion method that connects to each instance's master database to retrieve SERVERPROPERTY('ProductVersion'). Updated SqlServerInstance.DisplayName to include version labels with year mappings (e.g., "— SQL 2022 v16.x").

  • Improvement Enhanced version warnings

    SQL Server version warnings in the Database Setup Window are now edition-aware. When connecting to an older Standard/Enterprise server, the warning suggests contacting your IT administrator before upgrading a shared server. When connecting to Express edition, it recommends upgrading to SQL Server 2022 Express (a free upgrade) from microsoft.com.

  • Improvement Expanded debug startup profiles to 18 scenarios

    Extended the debug startup profile system from 14 to 18 scenarios, adding support for SSMS detection states (NotInstalled, NeedsUpgrade) and reconnection workflows with local SQL instances available. New profiles include "First DB — SSMS Missing", "First DB — SSMS Needs Upgrade", "Reconnect — Local SQL Available", and "DB Gone — Local SQL Ready". The debug chooser window now displays a fourth scenario row showing SSMS state, and appsettings.Development.json supports SsmsScenario configuration.

  • Improvement Local SQL Server instance detection in diagnostics

    The diagnostics window shows which versions of SQL Server are installed on your computer and whether SQL Server Management Studio needs to be installed or updated.

  • Improvement Enhanced license validation context messaging

    If your license needs attention, the store configuration screen now clearly explains what went wrong and what you need to do.

  • Improvement Consolidated RSC code lookup logic

    Created a unified helper method (LookupCloudRsc) that centralizes the logic for finding RSC codes from cloud data, eliminating duplicate code and ensuring consistent behavior across different parts of the Store Manager.

  • Improvement Simplified message compose area

    Replaced the pill-shaped chat input box with a standard labeled text area titled "Messages" (renamed from "Conversation"), providing a more conventional and accessible interface for composing support messages.

  • Improvement Simplified sender name display

    Message senders now show cleaner names without extra labels like "(Support)" or "(User)".

  • Improvement Detailed change summary after MySQL store refresh

    After refreshing stores from MySQL, you'll now see a summary showing exactly what changed (how many stores were added, updated, or removed).

  • Improvement Simplified combo box configurations

    Removed redundant AutoComplete, IncrementalFiltering, ImmediatePopup, and IsTextEditable properties from multiple combo boxes across Database Create, Do-It-Best options, Export options, Miscellaneous options, and Store Information views to simplify XAML and rely on default DevExpress control behavior.

  • Improvement Enhanced script execution logging

    After running a script, you can click "View Log" to see the full output or "Send to Support" to share the log file for troubleshooting.

  • Improvement Smart sender labels with role identification

    All support conversation messages now display formatted sender labels that combine the user's name with their role (e.g., "Brad Green (Support)" or "John Smith (User)"). If a name is missing or appears as a GUID, the system displays generic labels like "Support (Support)" or "User (User)" to ensure clarity. In thread view, sender initials are extracted and displayed in the avatar circle (e.g., "BG" for Brad Green).

  • Improvement Demo Mode supports startup workflow

    DemoModeViewModel now supports a startup mode (IsStartupMode) that accepts an override server name and returns the restored database name to the caller instead of triggering an automatic connection change. When opened from DatabaseSetupWindow, the demo database is restored and the setup form refreshes to display it in the database list.

  • Improvement Obsolete large sector parameter removed
  • Improvement Install and upgrade scripts now check hardware compatibility before downloading
  • Improvement Enhanced SQL Server instance analysis

    The `get_sql_instances_detail` tool provides comprehensive analysis of each SQL Server instance including version, year, database list, upgrade eligibility, and recommended action (upgrade vs. new instance). The tool identifies instances with mixed databases (MarginMaster + other apps) and blocks in-place upgrades to prevent data loss for other applications.

  • Improvement Zone assignment workflow

    For Ace and Emery Jensen stores, zones can now be viewed and overridden directly in the Store Manager grid or via the zone edit button, with clear indication of Ace-assigned vs. overridden zones.

  • Improvement First-run welcome experience

    New users now see a personalized welcome message when setting up Margin Master for the first time.

  • Improvement SQL service diagnostics and startup flow error handling

    Improved detection and display of SQL Server Windows service status during database setup. Enhanced CheckSqlServerServicesAsync to provide detailed diagnostics. Added TryStartWindowsServiceAsync method to programmatically start stopped SQL services with timeout handling. Changed startup flow to throw OperationCanceledException instead of generic Exception when users cancel database selection, improving error handling clarity.

  • Improvement Pre-fill support for issue submission dialog

    Enhanced SubmitIssueViewModel with PreFillTitle and PreFillDescription properties that override default title generation and pre-populate the description field when set before InitializeAsync. This enables the System Diagnostics window (and other tools) to open the support form with context-specific information already filled in, streamlining the support workflow.

  • Improvement Expanded debug startup profiles for SSMS scenarios

    Internal testing improvements — no user-facing impact.

  • Improvement Enhanced installer launch diagnostics

    Added detailed logging around the installer launch process, including process ID on success and specific Win32 error codes on failure. This improves troubleshooting capability when users report installation issues.

  • Improvement Smoother UI updates during restore

    Replaced blocking UI calls (Dispatcher.Invoke) with non-blocking calls (BeginInvoke) throughout the restore process, preventing UI freezes during cloud backup scanning and downloading.

  • Improvement Better state management for download operations

    Added caller-controlled loading state management to the download process, allowing the restore operation to maintain proper progress indicator visibility throughout the entire download-and-restore workflow.

  • Improvement Discrete section extraction from GlobalFileConfig

    V3 format separates previously lumped GlobalFileConfig entries into discrete sections: SelectionBoxViews (FIELDVIEW entries grouped by name), ColumnViews (SETTINGS/VIEWS and VIEWMANAGER entries), CustomFieldNames (VIEWMANAGER/NAMEMAPPINGS/USER), CustomSortOrders (PresetSortSequence entries), and StoreMatchUps (SETTINGS/STOREMATCHUP). Makes section-level and item-level restore filtering possible.

  • Improvement Database schema inspection

    Added get_table_schema tool allowing the AI to query and display the column structure of any database table, enabling more precise SQL troubleshooting and data investigation.

  • Improvement PowerShell 7 preferred for script execution

    The PowerShell engine now prefers PowerShell 7 (pwsh.exe) over Windows PowerShell 5.1 to avoid CLIXML-serialized progress records polluting captured output. Falls back to powershell.exe when PowerShell 7 is not installed.

  • Improvement Epicor char-based store handling

    Stores both PosStoreNumber (single char as string) and PosStoreCharOrdinal (Unicode ordinal 0-255) for Epicor INDecoded and MySQL Compass systems, ensuring unambiguous round-trip of all byte values including non-printable characters. PosStoreCharHelper.ToDisplayLabel() formats as "W (87)" for grid display. EpicorFTPFileExtractorService updated to read from StoreManagerInfo when UseStoreManagerInfo flag is true, extracting exclusions and store conversions.

  • Improvement Move migration to automatic startup

    Store data migration happens automatically in the background on first launch after update.

  • Improvement Prevented silent server switching on reconnect

    Auto-switching to a different SQL Server instance (when the selected one has no MarginMaster databases) now only occurs during first-run setup. When reconnecting after a connection failure, the application no longer silently redirects to a different server, avoiding user confusion.

  • Improvement Installation diagnostic logging

    The installer now logs detailed diagnostic information to %TEMP%\MarginMaster-Setup.log, including download attempts, errors, registry lookups, and process termination steps. This log file helps support staff diagnose installation issues more quickly.

  • Improvement Relaxed contact requirements for next step

    Removed the requirement to have a contact selected with first name and email before proceeding to the issue details step, allowing users to move forward even without selecting a contact (especially when using the "Do not contact" option).

  • Improvement Removed "Do not contact me" checkbox with warning flow

    If you try to continue without selecting a contact, you'll now see a warning asking you to confirm this choice.

  • Improvement Clearer sender labels in message timeline

    Updated how message senders are displayed: system-generated messages show as "Margin Master Tech Support," support team messages show as "RetailerSoft Support," and store messages show as "Store" (when no specific user name is available). Removed the redundant "(Support)" and "(User)" suffixes from sender names.

  • Improvement Format detection extended for V3 identification

    BackupFormatDetector now recognizes V3 format via explicit FormatVersion field (value >= 3) or presence of V3-specific fields (CostBreaks, MinMaxStrategies). Falls back to V2 detection (BackupPricingStrategies) or V1 detection (BackupGlobalFileConfigs) for legacy files. All restore paths automatically convert older formats to V3 internally.

  • Improvement Installation script logs accessible to AI

    The `get_sql_setup_logs` tool reads script transcript logs from the DiagnosticTool\Logs\Scripts directory, allowing the AI assistant to diagnose installation failures by analyzing the full PowerShell output, SQL Server Bootstrap logs, and error messages.

  • Improvement Added composite index for MySQL Compass imports

    Multi-store MySQL Compass imports now create a composite index on Compass_IN (in_store, in_item_number) to prevent timeout errors when updating extended fields on stores processed last in large installations.

  • Improvement One Click Statistics now respects current filter selections

    One Click Statistics now shows data for only the items you've filtered in the main screen, making the numbers more relevant to your current analysis.

  • Improvement POS connectivity diagnostic enhancements

    The POS connectivity module now classifies POS systems by connection mode (FTP-based, direct connection, file import only) and skips unnecessary network tests for file-import-only systems like RockSolid, Paladin, and TransAct. Added support for detecting 20+ POS system types.

  • Improvement POS file format diagnostic improvements

    The POS file format validator now reads the configured POS type and default import path from the database, pre-populates the file dialog with the correct folder and filter, and displays expected file format hints before file selection. The module now shows skip reasons when no file is selected instead of reporting a generic error.

  • Improvement Log analyzer warning detection

    The log analyzer module now detects both `[ERR]` and `[WRN]` level messages, groups warnings separately from errors, and reports issue severity accurately. Improved error key extraction strips Serilog source tags for better deduplication.

  • Bug Fix Version number alignment with updater

    Fixed a timezone-related mismatch where the version displayed in the app's About dialog and title bar differed from the version reported by the Velopack updater. The app now uses the CI-generated version (UTC-based) instead of deriving it from local build metadata (Eastern Time), ensuring consistency across all version displays. This prevents situations where users might see "version 26.317.5" in the app but the updater reports "26.316.5" due to timezone calculations.

  • Bug Fix Prevent update chaining after successful updates

    After installing an update, Margin Master will no longer immediately check for and install additional updates in a loop, preventing repeated unexpected restarts.

  • Bug Fix Automatic fallback to legacy upload when blob storage fails

    If the primary file upload method fails when you're submitting a support issue, the system now automatically tries an alternative upload method so your files still get attached successfully.

  • Bug Fix Automatic fallback to legacy upload when blob storage fails

    When you attach database or log files to a support request, the upload will now automatically try a backup method if the first attempt fails, making it much more likely your files will reach the support team successfully.

  • Bug Fix Database rename now detects restore failures

    The database rename operation now properly captures and reports SQL errors that occur during the backup restore step. Previously, certain SQL errors could be silently ignored, causing the rename process to appear successful when the restore had actually failed. The system now validates that the restored database actually exists on the server before proceeding.

  • Bug Fix Authentication token invalidation on database switch

    Fixed a critical bug where the JWT authentication token from the previous database was reused after switching stores, causing magic link authentication failures and API requests to be associated with the wrong store. The token is now properly cleared and regenerated when changing databases.

  • Bug Fix Fixed empty grid when StoreNumber filter absent from view

    If your view setup doesn't show the store number selector, the pricing grid will now display data from all stores instead of showing nothing.

  • Bug Fix Graceful handling of already-resolved support issues

    If you confirm a fix for an issue that was already marked as resolved, the confirmation window will now close normally instead of showing an error message.

  • Bug Fix Handle already-resolved issues gracefully during confirmation

    When you click "Confirm Fix" on a support issue that's already been marked as resolved, the dialog will close normally instead of showing an error message.

  • Bug Fix Support issue count excludes resolved issues

    The support badge number now accurately shows only issues that still need your attention, making it easier to know when you need to check the Support Tools screen.

  • Bug Fix Support badge count excludes resolved issues

    The notification badge will no longer show a count for support issues that have already been resolved or closed.

  • Bug Fix Wildcard conversion in excluded filters

    When you exclude items using a wildcard pattern (like "ABC*" to exclude all items starting with ABC), the filter now works correctly instead of failing to apply.

  • Bug Fix Quick Find SKU column now auto-sizes

    When you search for products using Quick Find, the SKU column now automatically widens to show the full SKU number, so you won't see partial SKUs cut off anymore.

  • Bug Fix Allow hyphens in filter values

    Filters on values with hyphens (like 'STORE-PACK') now work correctly on the Main Table.

  • Bug Fix Support issue resolution error fixed

    Marking support issues as resolved now works without showing an error message.

  • Bug Fix Saved selection box views lost on startup

    Fixed a problem where your custom saved views could disappear when opening Margin Master, forcing you back to the default Ace/DIB/Orgill selections and sometimes causing errors about missing fields.

  • Bug Fix Support issue comment author fallback

    When you submit a comment on a support issue, your name will now appear correctly even if your store hasn't set up a primary contact person.

  • Bug Fix Quick Find no longer auto-selects single search results

    When you search for an item and only one match appears, the search box stays active so you can keep typing. You'll need to click the result to select it, but you won't lose your search text anymore.

  • Bug Fix Quick Find search text preservation

    When typing a SKU in Quick Find, your text will no longer be replaced automatically. You can continue typing without interruption, or click a search result to select it.

  • Bug Fix Quick Find search no longer overwrites typed text

    When you select a SKU from the Quick Find dropdown and click "Show", the correct SKU now appears in the pricing grid or detail screen, even if you typed additional characters after selecting it.

  • Bug Fix Custom selection box views no longer silently fail at startup

    Your custom selection box view will now load reliably at startup, even when the database is busy. Previously, you might have noticed your custom view occasionally reverting to the default view without explanation.

  • Bug Fix Guard stale index removal during view fallback

    If the app can't load your saved selection box views at startup, it will now preserve all database indexes instead of accidentally removing ones you actually need. This prevents "field missing from view" warnings when running pricing strategies.

  • Bug Fix Selection box view startup reliability improved

    Dropdown menus for vendors and categories will now load reliably when opening Margin Master, even on slower systems or during busy startup periods.

  • Bug Fix Inactive row styling now renders correctly in Main Table

    When a product is marked as inactive, its entire row in the pricing grid will now display with strikethrough text and a gray color, making it immediately obvious which products are no longer active.

  • Bug Fix Restore Database window now closes after successful restore

    After successfully restoring a database backup, the window will now close automatically instead of staying open.

  • Bug Fix Restore Database window now closes after successful restore

    After restoring a database backup, the window will now close automatically instead of staying open, making the workflow smoother.

  • Bug Fix Notification emails now include attachment details

    When you submit a support ticket with attachments, the notification email now includes all your uploaded files instead of being sent too early.

  • Bug Fix Submit Issue dialog no longer hangs when no database is active

    If you submit a support ticket before loading a database file, the backup option will be grayed out automatically so your ticket can be sent without errors.

  • Bug Fix Store Configuration now initializes full database schema

    The Store Configuration dialog now properly sets up all required database tables when connecting to a new database, preventing errors on the next app launch.

  • Bug Fix Empty-state handling when no demo databases available

    If demo databases aren't available or can't be loaded, you'll now see a clear message explaining what happened and a Retry button to try again, instead of a blank screen.

  • Bug Fix Store Configuration bootstraps full schema on empty databases

    When you connect to a brand-new database and enter your store information, the app now fully sets up the database structure automatically. Previously, this could cause errors when trying to open the app again.

  • Bug Fix Automatic backup folder permissions grant

    If you see a UAC prompt on first launch asking to grant SQL Server access to the backup folder, click Yes — this fixes the issue where backup files would not appear in the restore dialog.

  • Bug Fix Automatic backup folder permissions for SQL Server

    When you first launch this version, you may see a Windows security prompt asking for administrator permission to grant SQL Server access to your backup folder. Approving this prompt will fix issues where database backups would disappear from the restore list.

  • Bug Fix Automatic Visual C++ Redistributable prerequisite handling

    SQL Server 2025's installer would halt with a cryptic error message when the Visual C++ 2015-2022 x64 Redistributable was present but older than version 14.40. The install and upgrade scripts now check the installed version before touching SQL Server, prompt the user, and automatically download and install the latest redistributable from Microsoft's evergreen URL if needed. Exit codes 0, 3010 (reboot recommended), and 1638 (newer already installed) are handled gracefully, while other errors provide a manual installation link.

  • Bug Fix Display Summary panel shows all $0.00 values

    After running a pricing strategy, the summary panel at the bottom left now correctly displays total increases, decreases, average change, histogram counts (H0-H12), and inventory value instead of showing all zeros.

  • Bug Fix Large sector NVMe drive compatibility check added to SQL Express scripts
  • Bug Fix SQL Express registry access failures no longer block database creation

    When the app attempts to determine the SQL Server default data path using xp_instance_regread, some SQL Express configurations deny this registry access. Previously this would abort database creation entirely. The app now catches this error, logs a warning, and falls back to using SQL Server's default file location.

  • Bug Fix Forward slash now supported in SKU filtering

    Previously, searching for products with slashes in their SKU (like NM6112/6) would fail. This now works correctly in the Main Table filtering.

  • Bug Fix Window sizing improved for smaller displays
  • Bug Fix Better error handling for database rename failures

    Improved how the application responds when it cannot rename database files, preventing crashes and providing clearer error messages to help diagnose issues. This addresses scenarios where file locks or permissions might prevent database operations from completing successfully.

  • Bug Fix Removed duplicate notification in Do-It-Best catalog import

    When a Do-It-Best catalog item can't be added due to a specific problem, you'll now see only the error explaining why, not an extra "No items were added" message.

  • Bug Fix Fixed crash during settings migration with duplicate keys

    Resolved an issue where migrating persistent values could fail if duplicate setting keys were encountered in a single migration batch. The system now tracks already-added keys in memory to prevent database constraint violations.

  • Bug Fix Database creation now succeeds on SQL Server Express

    Database setup now completes successfully on first-time installations without connection errors.

  • Bug Fix Added retry logic for initial database connection

    Database setup during first-time installation will now complete successfully without connection errors.

  • Bug Fix Automatic cleanup of orphaned databases after failed creation

    If database setup fails partway through, you can now click "Create" again immediately — the app will clean up the incomplete database automatically instead of showing "database already exists" errors.

  • Bug Fix Fixed memory leak in SKU Exceptions screen causing redundant loads

    Opening and closing the SKU Exceptions tab multiple times no longer causes the application to slow down or trigger duplicate loading screens.

  • Bug Fix PowerShell script launcher now handles special characters in file paths

    If your Windows username has an apostrophe in it (like O'Brien or D'Angelo), the installation scripts in the Support Tools screen will now launch successfully instead of showing an error.

  • Bug Fix PowerShell script launcher now handles special characters in paths

    If you store Margin Master or your installation scripts in a folder path containing an apostrophe (like "C:\John's Files\"), the scripts will now launch successfully instead of failing with an error.

  • Bug Fix SQL Error 447 resolved for numeric column filters

    Dropdown filter boxes now work correctly for numeric fields without causing database errors.

  • Bug Fix CPFPDif strategy filter now treats dollar changes as absolute values

    When you filter for price changes by dollar amount, the filter now finds both price increases and decreases that meet your criteria. Previously, it would miss price decreases.

  • Bug Fix Selection Box Views backup and restore now works correctly

    Custom selection box views you create will now be included in backups and restore correctly.

  • Bug Fix Cost break backup now reads from correct storage location

    When you back up your pricing data, cost breaks will now be included correctly in the backup file.

  • Bug Fix Issue notification pill clears on resolution

    The yellow notification bar at the top of the screen that alerts you to support issues will now disappear right away when we resolve the issue, instead of waiting until you update to a newer version.

  • Bug Fix Database setup now detects SQL Server Express for new installations

    If you're setting up Margin Master for the first time with SQL Server Express installed, the setup wizard will now correctly find and connect to your database server, allowing you to complete the initial setup process.

  • Bug Fix Database setup now prefers scanned server over generic placeholders

    If your saved database settings contained a generic server name, the database setup screen will now automatically select the correct SQL Server instance that was found on your computer, preventing errors when loading your existing databases.

  • Bug Fix Startup delay eliminated by cleaning up orphaned default settings

    If Margin Master was taking several minutes to start up, this update will restore normal startup times by removing unnecessary default settings that had accumulated in your database.

  • Bug Fix Default settings entries now deleted during cleanup

    Fixed an issue where GlobalFileConfig entries matching default values were being left in the database during the settings migration process. These orphaned entries accumulated over time, causing database bloat and slower startup performance. The cleanup process now marks these default-value entries for deletion, ensuring they are removed from GlobalFileConfig even when they don't need to be migrated to the new ApplicationSettings table.

  • Bug Fix System information now included in Quick Issue submissions

    When you submit a support ticket using the Quick Issue feature, your system details (like software version, store number, and POS system) are now automatically included, helping our support team assist you faster.

  • Bug Fix Installer corruption detection and automatic recovery

    The installer will now automatically detect and fix corrupted download files instead of failing with cryptic errors.

  • Bug Fix Store manager deduplication now works correctly

    When the system finds duplicate store manager entries, it now correctly removes the extras and keeps only one active record per store.

  • Bug Fix Store identity settings now update correctly during database re-initialization

    Your store number and related settings will now always update correctly when you reconfigure your store in the Store Configuration dialog, even if the database was previously used by a different store.

  • Bug Fix Store identity settings now update correctly during database initialization

    When you enter your store information in the Store Configuration dialog, your store number and other details will now always save correctly, even if the database was previously set up for a different store. This fixes an issue where some stores saw "license expired" errors because the app was checking licenses using an old store number instead of their own.

  • Bug Fix RSC code lookup now handles leading-zero variations in store numbers

    When you enter a vendor store number, the RSC code will now fill in automatically even if the store number in cloud data has more or fewer leading zeros.

  • Bug Fix Organization ID now captured from license response

    The license validation process now extracts and stores the Organization ID from the license server response. Previously, this ID was never populated, causing the Store Manager's cloud save feature to silently skip uploading changes (due to a null organization ID check).

  • Bug Fix Cached installer verification improved

    When checking for updates, Margin Master now properly re-downloads the installer if it can't verify the cached copy is current, preventing installation of outdated versions.

  • Bug Fix Fixed SQL Server service account detection on restricted environments

    The backup folder access check now gracefully handles environments where the sys.dm_server_services system view is unavailable (such as SQL Express or databases without VIEW SERVER STATE permission). Previously, this would generate false error telemetry; now it returns NULL without errors.

  • Bug Fix Fixed stale installer cache vulnerability

    The bootstrapper now discards any cached installer file when the ETag verification file is missing, not just when it mismatches. Previously, if Windows temp cleanup deleted the .etag file but left the installer file, the bootstrapper would incorrectly assume the cached installer was current based on file size alone. This could result in launching an outdated installer. The fix ensures fresh downloads whenever cache integrity cannot be verified.

  • Bug Fix SQL Server service account detection now handles restricted permissions

    The backup folder access service now checks if the sys.dm_server_services dynamic management view is available before querying it. In some SQL Server environments with restricted permissions, this DMV may not be accessible, which previously caused errors. The service now falls back gracefully when the view is unavailable.

  • Bug Fix Fixed contact deletion crash

    Added missing message box service that was causing contact deletion attempts to silently fail. The delete confirmation dialog now appears correctly and deletions are properly saved to the cloud.

  • Bug Fix Contact validation now enforced in Support Tools

    When submitting an issue, you'll now see a clear warning if you haven't selected a contact, and you won't be able to proceed until you choose someone from your Store Contacts or select a Support Rep.

  • Bug Fix Empty and placeholder contacts no longer appear in contact selector

    When selecting contacts for support tickets or issue reports, you'll no longer see empty or placeholder entries in the list—only valid contacts will appear.

  • Bug Fix Filter out empty and placeholder contacts from contact picker

    You will no longer see empty or "Add New" placeholder entries when picking contacts for support issues.

  • Bug Fix Resolve startup failures during Key Vault outages

    The application previously failed to start with licensing errors when Azure Key Vault was unreachable. Now, after successfully retrieving licenses from the cloud, they are persisted to the local ApplicationSettings database. On subsequent startups when Key Vault is unavailable, the app falls back to these cached database values before attempting the final appsettings.json fallback, ensuring the application can start even during network outages.

  • Bug Fix Store change summary query now uses correct database table

    Fixed error messages that appeared when building pricing summaries for store groups, especially after recent database updates.

  • Bug Fix Store change summary query corrected for non-MySQL POS systems

    Store change summaries now display correctly regardless of which POS system your store uses.

  • Bug Fix Installation Scripts dialog preload error resolved

    The Installation Scripts screen was attempting to download scripts from cloud storage even when those scripts were intentionally stored on local disk. This caused an error each time the dialog opened. The preload process now correctly skips locally-stored scripts and only attempts to download those actually hosted in cloud storage.

  • Bug Fix Suppress SQL permission error during database user creation

    When Margin Master attempts to create internal SQL database users (MarginMasterDataExtractor) at startup, it now gracefully handles situations where the connecting user lacks sysadmin or securityadmin permissions. Previously, SQL error 15247 was logged as an error and sent to telemetry. Now it's logged at debug level only and won't trigger alerts. The application also sets a guard flag to prevent retrying this operation on every startup.

  • Bug Fix Loading overlay now dismisses before error dialogs

    When a database restore fails, you can now see and click the error message instead of being stuck on a loading screen.

  • Bug Fix Cloud backup restore now filtered to current store

    When restoring from cloud backup, you'll now only see backup files for your own store, making it easier to find the right backup to restore.

  • Bug Fix Database restore compatibility with legacy backups

    You can now restore database backups created by older versions of Margin Master without encountering errors during the restore process.

  • Bug Fix Diagnostic Tool startup crash resolved

    The Diagnostic Tool will now open successfully every time, even on computers where it hasn't been used before.

  • Bug Fix Corrected ordinal calculation for special-character store identifiers

    Stores identified by special characters like '€' will now import SKUs correctly without creating duplicate database entries.

  • Bug Fix Auto-update recovery from delta patch failures

    If an update download gets corrupted, the app will now automatically clean up and retry with a fresh download instead of failing silently.

  • Bug Fix Automatic recovery from delta-patch checksum failures

    If an update download fails due to file corruption, the app now automatically cleans up the problem files and retries the download to complete the update successfully.

  • Bug Fix MySQL refresh now reactivates previously deleted stores

    If a store was removed but later reappears in your POS system, it will now be automatically restored in Store Manager.

  • Bug Fix Store Manager now resolves missing OrganizationId before cloud save

    If your store settings can't be sent to the cloud due to missing organization information, you'll now see a warning message and can retry after confirming your license is active.

  • Bug Fix Prevent adoption of foreign store identity at startup

    Fixed a critical issue where the app could incorrectly display pricing and data from a completely different store if an old database file was on your computer.

  • Bug Fix Clear explanations for backup folder access failures

    If your backup fails with a path error, the message will now explain that SQL Server needs access to the backup folder and suggest using a folder on the SQL Server machine itself or adjusting permissions.

  • Bug Fix Fixed "Invalid object name 'SkuExceptions'" startup error

    Startup will no longer fail with table errors when opening Margin Master after restoring a database backup.

  • Bug Fix Automatic recovery from corrupted updates

    If a bad automatic update breaks Margin Master, the app will now fix itself automatically when you try to open it, instead of staying broken until someone manually reinstalls it.

  • Bug Fix Wildcard selection now combines with other filters instead of replacing them

    When you exclude specific locations and also type a wildcard pattern (like "81*"), both filters now apply together. Before this fix, typing a pattern would erase your other selections.

  • Bug Fix Wildcard filter now combines with other selections instead of replacing them

    If you exclude specific locations (like 64 individual stores) and also use a wildcard pattern, both filters will now work together correctly instead of the wildcard erasing your other selections.

  • Bug Fix Support ticket upload errors now show meaningful messages

    If a support ticket or attachment upload fails, the error dialog will now show the actual reason from the server instead of appearing blank, making it easier to understand what went wrong and how to fix it.

  • Bug Fix Server error messages now display correctly for support ticket uploads

    If your support ticket upload fails, you'll now see a helpful error message explaining why instead of a blank error.

  • Bug Fix Large backup file upload failure now reported accurately

    If you try to submit a Quick Issue with a very large database backup and the cloud upload isn't working, you'll now see a clear error message right away instead of waiting for a long upload that will fail. This prevents losing your backup without knowing it.

  • Bug Fix Prevent silent failure when uploading large support attachments

    If you're submitting a support request with a large database backup and the upload fails, you'll now see a clear message explaining the file is too large (over 128 MB) rather than the upload appearing to succeed but actually failing silently.

  • Bug Fix False error message when creating new cost breaks

    When you click "<< New >>" to create a cost break, you'll no longer see a red error message saying "No Cost Break Models Found." The screen now opens directly to the editable grid where you can set up your new cost break. The warning message will only appear when viewing existing cost breaks if you haven't saved any yet.

  • Bug Fix Empty state message now respects cost break creation mode

    When you create a new cost break, you'll no longer see a confusing "No Cost Break Models Found" error message that didn't apply to what you were doing.

  • Bug Fix API response cache clearing on database switch

    Store-specific API data (contacts, support issues, release notes) is now cleared when switching databases. Previously, cached data from the old store would incorrectly appear in the new store's context.

  • Bug Fix Wildcard selection detection for excluded items

    Corrected the logic that detects when a wildcard filter is active to properly handle excluded selections. Previously, unchecked wildcard items were incorrectly bypassing wildcard conversion logic.

  • Bug Fix Correct wildcard filter processing

    Wildcard searches using asterisks now filter results correctly on the Main Table.

  • Bug Fix ZIP comment metadata persistence

    Fixed a bug where backup metadata was not being saved in the ZIP comment due to incorrect property ordering. The ArchiveFile property must be set before ZipComment for the IPWorks library to persist the comment correctly.

  • Bug Fix Fixed loading overlay timing during cloud restore

    The "Please Wait" screen now stays visible for the entire restore process instead of disappearing early.

  • Bug Fix Restore dialog backup file visibility

    Backup files will now appear consistently in the restore dialog instead of showing an empty list.

  • Bug Fix Explicit file path creation now has automatic fallback

    If CREATE DATABASE with an explicit file path and size specification fails (due to file system permissions or SQL Express MAXSIZE restrictions), the app now automatically retries using the simple CREATE DATABASE syntax, allowing SQL Server to use its own default locations and settings.

  • Bug Fix Better handling of timeout and network errors

    Timeout and network errors when loading open issues are now logged as warnings instead of errors and will no longer display alarming error messages. The application gracefully handles these situations by returning no issues rather than crashing or showing confusing error dialogs.

  • Bug Fix Reduced error noise from auto-updater

    Velopack auto-updater operational events are now filtered out of error reporting, preventing false alarms from routine update check activities.

  • Bug Fix Accurate error messages during database setup

    When database setup fails, you'll now see a clear explanation of what went wrong instead of a generic error message.

  • Bug Fix Batch execution now respects per-store assignments from exception rules

    SKU-level exceptions assigned to specific stores (e.g., "HURST ACE STORE 5") now only update pricing for those stores instead of incorrectly changing prices across all stores.

  • Bug Fix Empty value filtering corrected for all column types

    Selection boxes no longer show blank entries and properly exclude empty values for all field types.

  • Bug Fix CPFPDif exclude filters now work correctly

    When you exclude items by dollar price change amount, the filter now correctly excludes both large increases and large decreases.

  • Bug Fix Column Views backup and restore now works correctly

    Custom column views you create will now be included in backups and restore correctly.

  • Bug Fix Cost break restore now writes to correct storage location

    When you restore a backup, your cost breaks will now be properly restored and ready to use.

  • Bug Fix View settings entries now properly cleaned up

    View setting keys (like window positions and column widths) are now marked for deletion from GlobalFileConfig during migration, even though they're migrated separately by GetViewSettingsAsync. Previously, these entries were skipped but not cleaned up, causing duplicate storage of the same settings.

  • Bug Fix Fixed database setup window behavior after restore

    Resolved an issue where the database setup window could return early with a false result when DialogResult assignment threw InvalidOperationException. The window now properly closes and sets the active connection after successful database restore or demo installation.

  • Bug Fix RSC codes now appear immediately in the grid after auto-assignment

    When an RSC code is automatically filled in from cloud data, it now shows up right away in the grid instead of requiring a refresh.

  • Bug Fix Installer launch failures now properly reported

    Added Win32Exception handling around the installer launch process. Previously, failures during Process.Start were silently swallowed; now they are surfaced in both the error UI and the bootstrapper log with the specific Windows error code and message, making installation issues easier to diagnose.

  • Bug Fix Fixed SkuExceptions table validation crash

    Corrected the SkuExceptions Description column validation logic to properly check for table existence before attempting to add the column. Previously, if the table didn't exist, the system would attempt to alter a non-existent table, causing an error. The validation now only runs the ALTER TABLE command if both the table exists and the Description column is missing.

  • Bug Fix SKU exception validation guards against missing table

    The SKU exception description validation now verifies that the SkuExceptions table exists before attempting to add the Description column. This prevents errors during startup when working with older or incomplete database schemas.

  • Bug Fix Handle server-side contact validation

    If the server rejects an issue submission due to a missing contact (unlikely given UI enforcement), the dialog now navigates back to Step 2 with a clear error message rather than showing a generic failure.

  • Bug Fix Contact cache now correctly distinguishes between store and support employee lists

    Fixed a cache collision where store-only contact lists and lists that include support employees could incorrectly share cached data. The cache key now includes whether support employees are included, and cache invalidation clears both variants when contact data changes.

  • Bug Fix Fix support contacts cache invalidation

    Corrected a caching issue where support employee contacts were stored under a different cache key but not properly cleared when contact changes were made. The system now correctly invalidates both regular and support employee contact caches when contacts are modified.

  • Bug Fix Improved ZIP extraction error handling

    If a backup ZIP file is damaged or invalid, you'll now see a clear error message explaining what went wrong instead of the screen appearing frozen.

  • Bug Fix Restore POS store matching for stores upgraded from version 3.9.x

    Fixed store matching problems for customers who upgraded from older versions of Margin Master (3.9.x).

  • Bug Fix Fixed "There is already an object named 'GlobalFileConfigBackup'" migration error

    Settings migration will now complete successfully on all database configurations during startup.

  • Bug Fix Wildcard-only patterns no longer generate broken SQL operators

    Entering only wildcards (like "*" or "**") in a filter now correctly ignores the pattern instead of breaking the filter or returning zero results.

  • Bug Fix Wildcard patterns consisting only of asterisks are now ignored

    If you accidentally type only asterisks in a wildcard filter (like "*" or "**"), the filter will be ignored rather than causing unexpected results in your pricing grid.

  • Bug Fix Handle upload-target endpoint failures gracefully

    When the initial request to determine the upload destination fails, the system now falls back to the legacy upload method instead of returning an error to the user. This prevents attachment upload failures when the blob storage configuration endpoint is temporarily unavailable.

  • Bug Fix Cloud connection string refresh on database switch

    The cached cloud connection string is now invalidated when switching databases, ensuring each store uses its correct cloud database connection rather than the previous store's connection.

  • Bug Fix Removed invalid MSSQLSERVER named instance entry

    Corrected the local server scanner to stop treating "MSSQLSERVER" as a named instance. MSSQLSERVER is the Windows service name for the default SQL Server instance, not a valid named instance connection string. This prevented confusing connection attempts to non-existent server names.

  • Bug Fix Removed invalid MSSQLSERVER instance name

    Removed an incorrect hardcoded instance name pattern that could cause connection attempts to fail on systems with default SQL Server installations.

  • Bug Fix Individual ALTER DATABASE settings failures no longer block database creation

    The five ALTER DATABASE statements (RECOVERY SIMPLE, AUTO_CLOSE OFF, AUTO_SHRINK OFF, AUTO_CREATE_STATISTICS ON, AUTO_UPDATE_STATISTICS ON) are now executed independently with individual error handling. If one fails (e.g., AUTO_CLOSE OFF on certain Express editions), the remaining settings are still applied and database creation completes successfully.

  • Bug Fix Fixed crash when MySQL Compass store mapping setting is missing

    Fixed a crash that could occur when importing MySQL Compass data if certain configuration settings were not yet defined.

  • Bug Fix MySQL Compass toggle no longer reset on connection failure

    The "Use MySQL Compass" checkbox is no longer automatically unchecked when a MySQL connection test fails. The connection is marked unavailable but the user's choice to use MySQL Compass is preserved, allowing them to fix connection details without reconfiguring the entire setup.

  • Bug Fix MySQL Compass toggle no longer resets on test failure

    The "Use MySQL Compass" checkbox will stay checked even if the connection test fails, so you don't have to re-enable it after fixing connection problems.

  • Bug Fix Cleanup of temporary files after errors

    When an installation error occurs, the bootstrapper now deletes both the temporary installer file and its metadata, ensuring every retry starts with a completely clean download rather than potentially reusing corrupted files.

  • Bug Fix Duplicate contacts no longer appear in contact list

    You'll no longer see the same contact listed multiple times when selecting who to notify about an issue.

  • Bug Fix Store Manager dialog prevents premature close during cloud save

    The Store Manager dialog won't close until your store changes are fully saved to the cloud, preventing accidental data loss.

  • Bug Fix Wildcard patterns now generate correct SQL operators

    Wildcard filters (like "81*" or "*HARDWARE*") now work correctly to find matching items in the pricing grid.

  • Bug Fix Configuration and settings reset on database switch

    File-based configuration options, backup directory paths, and cached JSON settings are now properly reset when changing databases, preventing settings from one store from bleeding into another.

  • Bug Fix Real-time attachment polling

    When someone else adds an attachment to an issue you're viewing, it will now appear automatically in your conversation view.

  • Bug Fix Automatic database recovery on restore failure

    If a database restore fails, the system now automatically tries to fix the database so it can still be used.

  • Bug Fix Fixed database existence check security and performance

    The restore process now uses an asynchronous, parameterized SQL query to check if a database already exists, preventing potential SQL injection vulnerabilities and avoiding UI blocking during the check.

  • Bug Fix Missing function declaration in Upgrade-SQLExpress script

    The Upgrade-SQLExpress.ps1 script was referencing `Get-VCRedistVersion` but the function was not declared in the script body. The function has been added to properly detect and install the required Visual C++ Redistributable (v14.40 or newer) before attempting the upgrade.

  • Bug Fix Fixed Excel export crash with duplicate column names

    Fixed a crash when exporting to Excel if the data contained columns with the same name.

  • Bug Fix Improved SQL Server instance detection for fresh installations

    When no SQL Server instances are found, the setup window no longer adds a placeholder "." server to the list, correctly showing the "Install SQL Server" button instead. Debug mode now bypasses cached instance results when a test scenario is active.

  • Bug Fix Launch button error handling

    Added error handling around the "Launch" button in the installed app prompt. If launching the installed application fails, the error is now caught and displayed properly, and the retry counter is preserved for troubleshooting.

  • Bug Fix Improved error handling during MySQL refresh

    Each store operation during the refresh process is now isolated, so if one store fails to update, the refresh continues processing remaining stores instead of aborting entirely. Errors are logged with specific store details for troubleshooting.

  • Bug Fix Rounding schemes and validation state reset

    Database-specific caches including rounding schemes, SQL query hashes, store number lists, and validation flags are now fully cleared when switching databases, ensuring accurate data for the new store.

  • Bug Fix Fixed crash when pricing actions have empty or invalid values

    Fixed a crash when applying pricing strategies that had blank or invalid price or margin values.

  • Bug Fix Application settings query correction

    Fixed SQL query in `get_application_settings` tool to use correct column names (Setting, Value) instead of incorrect names (SettingKey, SettingValue), resolving errors when the AI attempted to retrieve user settings.

  • Bug Fix Clean exit when canceling database setup

    Canceling the database setup during first launch now closes the application cleanly instead of showing an error message.

  • Bug Fix Contact form visibility now updates correctly

    Fixed toggle behavior where the contact edit form and placeholder text visibility now correctly respond to the DoNotContact checkbox state and contact selection. The right panel now shows the appropriate content based on user actions.

  • Bug Fix Restore Database Cancel button now closes window

    The Cancel button in the Restore Database dialog now properly closes the window.

  • Bug Fix Fixed crash from duplicate keys in pricing strategy rules

    Fixed a crash when applying pricing strategies with duplicate action settings in the rule definition.

  • Bug Fix Fixed memory issues with large backup files

    Backup creation now streams JSON directly to disk instead of building the entire file in memory, preventing out-of-memory errors on stores with very large datasets.

  • Bug Fix Fixed crash when editing cells with null or whitespace values

    Fixed a crash that could occur when clearing a cell value or entering only spaces in the pricing grid.

  • Bug Fix Improved restored database naming

    The restore process now strips backup file extensions (.bak, .zip, .sql) from suggested database names, preventing databases from being created with names like "DIB_3932.bak".

  • Bug Fix Diagnostic log rotation

    DiagnosticTool now clears previous session log files on startup to prevent log accumulation and improve disk space usage.

  • Bug Fix ApplicationSettings column name corrections

    Fixed ApplicationSettings table queries to use the correct `Setting` and `Value` column names instead of legacy `SettingKey`/`SettingValue` naming. Corrected vendor setting name from `VendorType` to `RetailerSoftVendor`.

  • Cloud Sync SQL-based strategy backup with history tracking

    Your strategy backups are now saved to a more reliable system that keeps track of when each backup was created and why.

  • Cloud Sync Enhanced RSC code retrieval from cloud Stores table

    When you enter a vendor store number, the RSC code will now fill in automatically from the cloud database, making store setup faster and more accurate.

  • Cloud Sync Store-specific cloud backup visibility

    The cloud backup restore screen now shows only your store's backups, preventing confusion with backups from other store locations in your organization.

  • Cloud Sync Added computer name tracking for store settings updates

    When saving store settings to the cloud (such as POS-to-cloud store match-ups), the application now includes the submitting computer's machine name in the request. The cloud server records this information to track which workstation last modified each store configuration, improving audit capabilities and troubleshooting for multi-computer setups.

  • Cloud Sync Computer identification for store settings

    When saving organization store settings, the application now sends the computer name in the request header (X-Submitted-By-Machine). The server records this information to track which workstation last modified store match-up configurations, improving visibility for multi-user environments.

  • Cloud Sync Hidden issue flag

    Added an IsHidden flag to the issue submission API that marks issues as internal-only. These issues are excluded from the store's visible issue list, not shown as notification badges in the client, and store contacts are not notified when the issue is created or updated. This allows support staff to gather diagnostic data without creating customer-facing support tickets.

  • Cloud Sync Attachment list updates during polling

    New attachments uploaded by the support team will appear automatically without refreshing the screen.

  • Cloud Sync Cloud backup/restore updated to V3 format

    Both cloud upload and download operations now use the V3 backup format with the same tree-based selection dialog. Cloud-downloaded backups are automatically converted from V1/V2 if necessary before restoration. Maintains backward compatibility with existing cloud backups.

  • Cloud Sync Multi-RSC detection during sync

    Updated Cloud Sync logic to determine multi-RSC status by analyzing STORERSC global values before resolving which RSCs to sync. The sync process now automatically adapts to single or multi-RSC scenarios without requiring a stored configuration flag.

  • Data Import Updated cloud settings API to include store RSC mapping

    The API endpoint for retrieving organization store settings now returns both POS-specific store settings and a complete vendor-store-number-to-RSC-code map from the cloud Stores table. This enriched data bundle enables better fallback logic when local POS data is incomplete.

  • Data Import Update MySQL import pipeline for unified store management

    MySQL/Compass data imports now use the same store management system as other POS types.

  • Data Import Enhanced backup metadata and section tracking

    Added nine new BackupRestoreSectionType enum values (CostBreaks, MinMaxStrategies, MinimumMargins, SelectionBoxViews, ColumnViews, CustomFieldNames, CustomSortOrders, StoreMatchUps) for granular restore control. BackupRestoreOptions extended with per-section flags and item-level filter lists (SelectedStrategyNames, SelectedRoundingSchemeNames, etc.) to support partial restoration.

  • Data Import RSC assignment improvements

    Simplified store-to-RSC matching logic in POSStoreNumberMatchUpViewModel and StoreNumberMatchUpViewModel to always write RSC assignments to STORERSC global configuration, regardless of multi-RSC status. The viewmodels now calculate HasMultipleRSCs from the actual store data after loading mappings rather than reading it from settings.

  • Data Import Store Manager routing in import pipeline

    Import processes now automatically use your Store Manager settings for zone pricing and store mappings.

  • Data Import Restored Ace Hardware catalog and zone pricing import logic

    Re-implemented the SQL queries for importing Ace Hardware catalog data and zone pricing that were accidentally removed in a previous merge. Zone pricing now correctly applies store-specific zones when available, falling back to zone 99999 only when no store-specific zone is configured.

  • User Interface Order Indicator filter dropdown now shows decoded descriptions

    When you click the Order Indicator filter in the pricing grid, you'll see clear descriptions explaining what each code means (T for Stock/Order Through, C for Central Stock, S for Special Order), making it easier to filter products by fulfillment type.

  • User Interface Configurable alternate text display order in selection dropdowns

    Added AltItemTextAfter property to SelectionListItem that controls whether alternate text appears before or after the primary text in dropdown displays. When enabled, items display as "{ItemText} - {AltItemText}" instead of the previous "{AltItemText} - {ItemText}" format.

  • User Interface Redesigned Support Scripts dialog with categorized tree view

    When you open Support Scripts, you'll see scripts organized into categories on the left. Click any script to see its full description on the right before running it.

  • User Interface Enhanced Quick Find results display

    Search results in Quick Find now show in two separate columns (SKU and Description) that you can resize by dragging, making it easier to view long product descriptions.

  • User Interface iMessage-style bubble view for support conversations

    Support conversations now default to a modern bubble chat interface similar to iMessage. User messages appear right-aligned in blue bubbles (with white text), while support team responses appear left-aligned in light gray bubbles (with dark text). Each bubble displays the sender name and role above it (e.g., "Brad Green (User)" or "Support (Support)"), with a timestamp in the bottom corner. Bubbles have rounded corners with a subtle "tail" effect (flat bottom-right for user messages, flat bottom-left for support messages) and a light drop shadow for depth. Bubbles are limited to 75% of the chat area width to maintain readability.

  • User Interface iMessage-style chat bubbles for support conversations

    When viewing support ticket conversations, messages now appear in colored chat bubbles similar to text messages—your messages are blue on the right, support team responses are gray on the left.

  • User Interface Attachments bar added to Support Issues chat

    Attached files now appear in a dedicated section below the chat with their file sizes displayed.

  • User Interface Attachment display in Support Issues chat

    When viewing a support issue, you'll now see all attached files listed in the conversation area with their names and sizes.

  • User Interface Database creation and restoration gated behind valid connection

    The buttons to create or restore a database are now grayed out until you successfully connect to a SQL Server using the "Test Connection" button.

  • User Interface Cost break model cleanup script

    If you've accumulated many test or unused cost break models, IT staff can now run this script to clean them up. The script shows you what models exist before deleting anything, and includes examples for removing models by naming pattern (like "New..." or "Mi9-...") or by exact name.

  • User Interface Bulk delete SQL for cost break models

    If you have many cost break models to delete, you can now use SQL queries to remove them in bulk rather than deleting each one individually in the Cost Break Analysis screen.

  • User Interface Softer background color for inactive dirty rows

    When viewing items that are marked inactive but have unsaved changes in the pricing grid, they now appear with a softer, more subtle background color that's easier to read and less distracting.

  • User Interface Improved visual indicator for inactive rows with unsaved edits

    When you edit a row that's marked as inactive, it now highlights in a muted amber color instead of purple, making it easier to spot unsaved changes at a glance.

  • User Interface Strikethrough formatting added to inactive product rows

    When viewing the pricing grid, products marked as inactive will now show with a line through the text, making it much easier to see which items are no longer active.

  • User Interface Condition value editor popup

    Click the pencil icon next to any condition (like Vendor, Department, etc.) to see all its values in a popup. Click the red "×" next to any value to remove it from the condition.

  • User Interface Added download progress bar to cloud restore

    When restoring a database from the cloud, you'll now see a progress bar showing how much of the backup file has been downloaded.

  • User Interface Added visual progress bar for cloud backup downloads

    A progress bar now appears when downloading backups from the cloud, showing how much of the download has completed.

  • User Interface Extended visibility for resolved support issues

    If a support issue has been fixed in a newer version but you haven't updated yet, you'll continue to see the notification pill reminding you about the issue until you install the update.

  • User Interface Type-ahead search enabled for configuration dropdowns

    When selecting your primary vendor, RSC, or POS system during setup, you can now start typing (e.g., "Ace" or "Rock") and the dropdown will automatically highlight and jump to matching options.

  • User Interface Support issue pill color now indicates status

    The support issue notification now changes color to show you the status of your issue: blue means it's new, orange means it's being worked on, and purple means it's ready for you to test.

  • User Interface Color-coded support issue pill

    The support notification badge now shows blue when your issue is new, orange when we're working on it, and purple when a fix is ready for you to test.

  • User Interface Documented wildcard selection filter feature

    Created detailed documentation explaining how to use the `*Wildcard*` option that appears in selection boxes with more than 5 items. The documentation covers both include mode (left-click) and exclude mode (right-click), pattern syntax using the `*` character, and notes that wildcard selections are mutually exclusive with individual item selections.

  • User Interface Support Issues date display changed to last-updated

    When viewing support issues, you'll now see when each issue was last updated instead of when it was created, helping you quickly find issues that have recent activity or responses.

  • User Interface Display last-updated date for support issues

    When viewing support issues, you'll now see when each issue was last updated rather than when it was created. The most recently updated issues appear at the top of the list, making it easier to track ongoing conversations.

  • User Interface Support issue action feedback

    When you click buttons like "Mark Resolved" or "Confirm Fix" in Support Issues, you'll now see a "Processing..." message until the action completes, so you know it's working.

  • User Interface Wait indicator added for support issue actions

    When you click to mark an issue resolved, confirm a fix works, or reject a fix, you'll now see a "Processing..." message while the action completes instead of the screen appearing frozen.

  • User Interface Improved note field in Quick Issue Submit dialog

    The optional note field in Quick Issue Submit now appears as a clean multi-line text box without any extra buttons.

  • User Interface Enhanced startup splash screen progress detail

    You'll now see exactly what Margin Master is doing during startup with messages like "Verifying Rounding Tables..." and "Checking Configuration Integrity..." instead of just a generic loading screen.

  • User Interface SSMS detection limited to first-run setup only

    When reconnecting to your database, you'll no longer see messages about SQL Server Management Studio installation status—these only appear during initial setup.

  • User Interface Enhanced Database Setup screen for first-run scenarios

    When you first open Margin Master, the database setup screen now shows clearer instructions and helpful warnings if your SQL Server version is outdated. You can also start the SQL Server service with one click if it's not running.

  • User Interface Streamlined demo database selection during startup

    When setting up Margin Master for the first time, you can now browse and install demo databases more easily without selecting a vendor first.

  • User Interface Streamlined field-dropped warning message

    When loading a saved pricing strategy that references fields no longer present in the current dataset, the warning dialog now displays a more concise message. The redundant "This step will be skipped..." sentence was removed since the primary warning already clearly explains why the step cannot execute safely.

  • User Interface Simplified installer window header

    Replaced the full-height branded header (52px with icon and "Margin Master" text) with a minimal 36px green drag strip containing only the close button. The Margin Master logo is now displayed as a high-quality PNG image in the white body area above the status text, creating a cleaner and more professional installer appearance. The window height increased slightly from 260px to 280px to accommodate the new logo placement.

  • User Interface Removed Store Name column from Store Manager

    Store names no longer appear in the Store Manager grid.

  • User Interface Simplified Support Issues window layout

    Removed the dual-view toggle between iMessage-style bubbles and Twitter-style threads. The window now uses only the timeline view, which displays messages in a clean, chronological format with system activity entries (like status changes) appearing as centered timeline events labeled "Margin Master Tech Support."

  • User Interface Redesigned Support Issues conversation display

    Support conversations now appear in a single, easy-to-read format. System notifications like "Issue published" appear with a gray divider line, while messages from you and support staff show with profile circles and names.

  • User Interface Improved cloud unavailability messaging in Support Issues

    When viewing Support Issues, if details can't be loaded, you'll see a clearer message explaining the cloud service may be temporarily unavailable instead of being asked to check your internet connection.

  • User Interface Password-protected feature toggle added to Background Service tab

    When opening the Background Service tab, you'll see whether the feature is enabled or disabled. If disabled, click the "Enable (password)" button and enter the support password to activate scheduled background imports.

  • User Interface Issue resolution comments field improved

    The comments box in the Submit User Issue Resolved dialog now includes text wrapping and a vertical scrollbar, making it easier to read and edit longer multi-line comments.

  • User Interface Database Setup window margins tightened

    The Database Setup screen during first launch now fits better on smaller monitors without needing to scroll.

  • User Interface Twitter-style thread view as an alternative layout

    A new thread view option displays conversations in a full-width, social-media-style layout. Each message shows a circular avatar with the sender's initials, followed by the sender name with role label and timestamp in the header, then the full message text below. Messages are separated by horizontal dividers and fill the entire width of the chat area, making it easier to scan long technical discussions.

  • User Interface Dual view toggle between bubble and thread layouts

    You can now choose how support conversations are displayed by clicking "Bubbles" or "Thread" at the top of the conversation area—your choice is remembered next time you open the screen.

  • User Interface Staged attachments preview area

    Attachments you've selected appear in a yellow area below the message box, where you can review file names and sizes or remove files before sending.

  • User Interface More accurate support notifications

    When checking for open support issues, the application now properly distinguishes between issues that need attention versus those that have been resolved, providing a more accurate indicator of pending support matters.

  • User Interface Simplified Quick Find selection logic

    Removed unnecessary bidirectional binding between the search text field and selected search result. The search field now only triggers searches, while result selection is handled independently, eliminating a source of unexpected UI behavior.

  • User Interface Simplified SKU selection logic

    Removed unnecessary flag-based logic that was attempting to prevent search updates when selecting dropdown items. The search box and dropdown selection are now handled independently, eliminating the circular update issue that caused text to be overwritten.

  • User Interface Adaptive feedback panel in Database Setup

    The information panel at the bottom of the server selection area now adapts its appearance based on SQL Server status. The panel displays blue background and "Install SQL Server Express" button when no SQL Server is detected, but switches to orange background with service-specific guidance (and hides the install button) when SQL Server is installed but services are not running. The panel shows service names and their current status to help users identify which service needs attention.

  • User Interface Context-aware help messages in Database Setup

    The help message at the bottom of the Database Setup window now changes color and content based on what's actually wrong with your SQL Server connection, making it easier to know what action to take.

  • User Interface Tree view with item-level selection for backup/restore

    When backing up or restoring, you'll now see expandable categories where you can choose specific pricing strategies or rounding schemes by name instead of having to include everything at once.

  • User Interface Store number column added to backup list

    The backup list now shows a "Store #" column so you can quickly see which store each backup file came from.

  • User Interface Store number column added to backup list

    Cloud backups now show which store they came from in a "Store #" column, making it easier to find the right backup when multiple stores are displayed.

  • User Interface Error recovery in Demo Mode dialog

    The Demo Mode window now shows helpful error messages and recovery options instead of appearing blank when something goes wrong.

  • User Interface New prerequisite verification step in setup workflow

    A new "Step 2: Verifying Visual C++ Redistributable prerequisite" has been added to both installation and upgrade scripts. The script prompts for confirmation before downloading/installing the redistributable, reports the current installed version, and verifies the installation succeeded before proceeding. All subsequent steps (download, backup, install/upgrade) have been renumbered accordingly.

  • User Interface Clearer error messages for database operations

    You'll now see clearer error messages if the application has trouble working with its database files, making it easier to know what's wrong.

  • User Interface Multiple RSC checkbox removed from Settings

    The "Multiple RSC's" checkbox is no longer visible in Store Information settings.

  • User Interface Hidden multi-RSC checkbox

    The "Multiple RSCs" checkbox has been removed from the Store Information settings screen.

  • User Interface Improved server selection logic in database setup screen

    The Database Setup screen now intelligently handles cases where the saved server name is a generic local placeholder by keeping the server instance discovered during the automatic scan. This ensures the "Load Existing Database" operation can successfully connect to SQL Server even when the configuration file contains a fallback placeholder value.

  • User Interface Failed connection tests now show warnings instead of errors

    Failed connection tests now show a yellow warning message explaining that your settings were saved and you can fix any incorrect details and try again.

  • User Interface Updated error messages for failed connection tests

    When a connection test fails, the warning message now explains that your settings were saved and you can simply correct the mistake and test again.

  • User Interface Added wildcard pattern examples and syntax guide

    Documentation includes a pattern syntax reference table showing common examples like `A*` (starts with A), `*TOOL*` (contains TOOL), and `*0012` (ends with 0012). All patterns are case-insensitive and the `*` character matches any sequence of characters.

  • User Interface Idle progress bar

    A small progress bar shows how close the notification is to automatically updating — when it fills completely, the 10-second countdown begins.

  • User Interface Table schema verification progress tracking

    If you have multiple vendor catalogs, the startup screen now shows "Main table 3 of 8" (for example) so you can see progress through the verification process.

  • User Interface Removed SKU Count column from Store Manager

    The SKU Count column has been removed from the Store Manager screen.

  • User Interface Improved license expiration error message

    If you see a license expired error, the message now suggests checking that your store number is correct, since an incorrect store number can cause this error even when your license is valid.

  • User Interface Delete button styling and placement

    The "Delete Issue" button appears on Step 3 of the Submit Issue screen, positioned to the left of the "Update Issue" button. It uses red text (#C62828) to indicate its destructive nature and is hidden while submission operations are in progress to prevent accidental clicks.

  • User Interface Visible warning when issue notification cannot be sent

    You'll now see a clear warning if your support issue couldn't be sent, so you know to contact RetailerSoft directly instead of waiting for a response.

  • User Interface Visible warning when notification fails

    If your issue submission notification doesn't go through, you'll see a message telling you to contact RetailerSoft support directly instead of wondering if it worked.

  • User Interface Consolidated issue action buttons

    Moved all issue actions (View Online, Mark Resolved, Fix Works, Still Broken, and the new Remove Issue button) into a single row in the detail header, replacing the previous scattered layout with top-bar buttons and separate banners. Also removed the View menu that previously toggled between display modes.

  • User Interface Added ability to remove issues from your list

    You can now remove issues from your list if you no longer need to track them. Right-click an issue or use the remove button to hide it from your view.

  • User Interface Update progress during version check

    You'll see progress messages like "Checking for updates..." on the startup screen if the app needs to update itself before opening your database.

  • User Interface Improved fallback priority for selection box views

    Enhanced the view selection fallback hierarchy to prioritize a sole custom view (priority 0) before checking for vendor-specific default views (priority 1). This ensures customer-specific configurations are preserved during database operations while maintaining backward compatibility with the existing vendor default system.

  • User Interface Support machine notice banner in restore dialog

    Support staff will see an amber banner explaining when they're viewing backups across multiple stores.

  • User Interface Support machine notice banner added to restore dialog

    Support machines will see a yellow notice explaining that they can view backups from all stores in the organization.

  • User Interface Conditional visibility for support features

    Store computers will no longer see support-only options in the Restore Database screen.

  • User Interface Download progress shown during click-to-restart

    If a newer update needs to be downloaded when you click to restart, you'll see a progress bar showing the download status.

  • User Interface Added Issue Contact menu item

    Added a new "Issue Contact" menu item with a contact icon under the Help > Support Issues submenu, positioned below "Submit New Issue" for easy access to contact information management.

  • User Interface Quick Find dialog auto-sizes to content

    The Quick Find search box now automatically sizes itself to fit its content instead of using a fixed size.

  • User Interface Persistent view toggle with radio buttons

    Two radio buttons labeled "Bubbles" and "Thread" appear at the top-right of the chat area, allowing instant switching between the two conversation layouts. The selected view is saved via the new SupportCommentUseBubbleView setting and restored when reopening the Support Issues screen, so each user's preference persists across sessions.

  • User Interface Avatar initials and enhanced sender identification

    Messages now show who sent them more clearly, with support team messages labeled "(Support)" and your messages labeled "(User)".

  • User Interface Improved attachment upload feedback

    When sending multiple files, you'll see upload progress displayed, and if something goes wrong you'll be told which specific file had the problem.

  • User Interface Enhanced upload progress messages

    You'll now see detailed progress messages showing compression and upload status when attaching files to support requests.

  • User Interface Compression progress feedback

    The Support Tools screen now displays real-time compression progress when preparing large files for upload, showing both percentage complete and the original file size in megabytes. This provides transparency during what might otherwise appear as an unresponsive delay for very large attachments.

  • User Interface Store Information section now hidden until database selected

    The setup form is now simpler—just select your SQL Server and database to get started. Store details will appear after you connect.

  • User Interface Improved backup completion dialog

    The backup summary now has a "Show in Explorer" button that opens File Explorer and highlights your backup file, making it easier to find.

  • User Interface New support documentation for large sector drive compatibility
  • User Interface Updated progress messages for batch mode

    The Main Table progress display now shows "Processing X SKU Level Exceptions (batch mode)..." instead of "(X groups)..." to reflect the new processing approach, giving users clearer insight into the performance optimization in use.

  • User Interface Backup dialog now shows correct list of custom views

    When creating a backup, you'll now see all your custom views listed in the backup options.

  • User Interface Script action buttons now conditional

    The Installation Scripts dialog now shows different action buttons based on script type: PowerShell scripts show "Execute Script" with a launch icon, while SQL scripts show "Copy to Clipboard" with a copy icon. Status messages updated to guide users to paste and execute SQL scripts in SSMS after copying.

  • User Interface Enhanced issue tooltip

    The support issue pill tooltip now displays the issue status alongside the title and ID, making it easier to see the current state of each issue without opening the full support dialog.

  • User Interface Upgraded network scanner with response time display

    The network scan now shows all available MySQL servers at once with their response times, so you can pick the fastest one with a double-click.

  • User Interface Progress and error feedback

    The submission dialog shows clear progress and provides detailed feedback if any files fail to upload.

  • User Interface Download progress now shows speed and estimated time

    You can now see how fast the download is progressing and how much time is left.

  • User Interface Simplified POS Store Number display

    The POS Store column now shows store numbers in a simpler format.

  • User Interface Script documentation with troubleshooting guide

    The script includes built-in help and troubleshooting steps if the installation encounters problems.

  • User Interface Improved Store Manager RSC auto-population logic

    The Store Manager screen will now show RSC codes for more stores automatically, reducing manual data entry.

  • User Interface Close buttons now trigger auto-save

    Both the Close button and File → Close Window menu command in the Store Manager now use the new auto-save behavior, ensuring consistency across all exit paths from the screen.

  • User Interface Tabbed interface replaces hidden Shift-key mode

    Store contacts and support representatives now appear in separate tabs, making it easier to find and select the right person. You no longer need to hold Shift when opening the Submit Issue dialog.

  • User Interface Settings screen updated

    Look for the new "Store Number Display & Sorting" section on the Connections settings screen to customize how store numbers appear.

  • User Interface Visual feedback during automatic repair

    If the app needs to repair itself, you'll see a window explaining what's happening so you know the app is fixing itself and will reopen shortly.

  • User Interface Window placement validation

    Added validation to ensure saved window positions are still visible on current monitors. Windows are automatically repositioned if their saved location would be off-screen (e.g., after disconnecting a secondary monitor). Validation checks that at least 100 pixels of the window overlap a monitor's working area.

  • User Interface Visual feedback for connection validation state

    The Database Setup window now provides clear visual feedback about connection status through button states. Connection validation occurs automatically when testing connections, loading existing databases, or selecting servers from the dropdown.

  • User Interface Enhanced Database Setup window layout

    Reorganized the Database Setup window to show the store information panel only when connecting to an existing database with saved credentials. Added the new Demo Database and Submit Issue buttons to both the toolbar menu and the main action area. When an error occurs, a clickable "Report this issue" link now appears next to the error message for quick access to support.

  • User Interface Updated backup success message

    After backing up, you'll see a simpler confirmation message showing your local backup file and when it was saved to the cloud.

  • User Interface Enhanced startup diagnostics display

    The diagnostic screen now shows clearer information about your database connection and store license when it starts up.

  • User Interface Enhanced AI chat experience

    The AI chat tab now displays rotating "thinking" phrases (Computing, Reasoning, Cogitating, etc.) with elapsed time while the AI processes requests. Added prominent database connection status display showing active database and server name at startup. The terminal now shows detailed startup diagnostics including database connection, store identity, and license status.

  • User Interface Real-time connection test status

    You'll now see status updates while the connection test runs, showing exactly what step is being tested.

  • User Interface Updated update notification layout

    The update notification dialog has been redesigned to accommodate the idle progress bar, countdown panel, and What's New button. The dialog height increased from 280 to 340 pixels to fit all elements comfortably without crowding.

  • User Interface Consolidate store management dialogs

    Store Manager dialog now handles all store types using a single, consistent interface.

  • User Interface Warning shown for contacts missing email addresses

    Contacts without email addresses now show a "Please add email address" warning so you know which ones need updating.

  • User Interface Contact email validation warning

    Contacts missing an email address now show a warning message to help you identify incomplete contact information.

  • User Interface Show deleted contacts option

    You can now see previously deleted contacts by checking "Show Deleted" at the bottom of the Store Contacts tab.

  • User Interface DPI-aware window sizing and validation

    All window coordinates are now properly converted between physical pixels (used by Win32 APIs) and WPF device-independent pixels (DIPs). The system validates that saved window positions are at least partially visible on current monitors, with a minimum 100-pixel overlap requirement to prevent windows from appearing off-screen after monitor configuration changes.

  • User Interface Real-time connection test status display

    When testing your connection, you'll now see what step is being tested in real-time instead of just a generic "please wait" message.

  • User Interface Connections tab redesign

    The INDecoded scanner has been replaced with a "Store Manager" button that opens a dedicated screen for all store configuration tasks.

  • User Interface Layout improvements for startup dialogs

    Setup windows now handle long messages and lists better without cutting off important information or buttons at the bottom of the screen.

  • User Interface System Diagnostics submission integration

    When viewing System Diagnostics, you can click "Submit to Support" to automatically create a support ticket with all your system information already included.

  • User Interface Store grouping integration

    Enable "Use Store Grouping" to assign zones and manage multiple stores as a group. Zone changes in a group automatically apply to all member stores.

  • User Interface Fixed content overflow in startup dialogs

    Setup screens no longer have buttons pushed off the bottom when showing long error messages or status updates.

  • User Interface Renamed "Add New Contact" to "Create New"

    Changed the button label from "Add New Contact" to "Create New" for consistency and brevity in the updated interface layout.

  • User Interface Store identity verification improvements

    Store identity verification now uses the full license detail API endpoint, displaying license expiration date, store count, and validation status. Background verification confirms license status after the main window loads without blocking startup. Identity cached from the database now takes precedence over the fallback JSON cache.

  • User Interface Dynamic contact picker header text

    The contact picker dialog header text is now configurable, allowing different messages when selecting contacts to CC versus adding support representatives.

  • User Interface BackupRestoreStrategyOptionsViewModel tree mode initialization

    New InitializeV3ForBackupAsync() and InitializeV3ForRestore() methods build tree structure from database inventory or backup file contents. BuildOptionsFromTree() translates tree checkbox states into BackupRestoreOptions with item-level filters. UseTreeView property controls whether legacy flat checkbox list or new tree view is rendered.

  • User Interface AI assistant system prompt enhancements

    The Claude AI assistant's system prompt now includes detailed tool workflow documentation for SQL Express upgrades, SSMS installation, and Margin Master updates, with specific guidance on when to use each tool, how to handle UAC prompts, and how to diagnose common failures like NVMe sector size issues or missing C++ redistributables.

  • User Interface Settings tab integration

    Store exclusions are now managed in Store Manager instead of the old Import Exclude field in Settings.

  • User Interface Enter key sends AI messages

    Pressing Enter in the Claude AI input box now sends the message immediately instead of inserting a newline. Use Shift+Enter for multi-line input.

  • Database Updated default SQL Server instance name

    The default DatabaseConnections.json file now specifies ".\SQLEXPRESS" as the server name instead of "." (local default instance). This change only affects new installations or when the connection configuration is recreated, and better aligns with the typical SQL Server Express setup used by retail hardware stores.

  • Database Migrate MySqlStoreManagerInfo to StoreManagerInfo

    Store configuration now uses a single database table for all POS systems instead of separate tables for MySQL stores.

  • Database New Duplicate store status type

    The store status classification now includes a fourth option "Duplicate" (value 3) to identify stores that are duplicate entries. The existing status types (Open, Closed, Other) have been assigned explicit integer values (0, 1, 2) to prevent data corruption if the list is reordered in future updates.

  • Database Added contact phone number storage

    Extended ApplicationSettingsService to store and retrieve a contact phone number in addition to existing first name, last name, and email fields. This phone number is now saved to the database and persists across sessions.

  • Database Safe deletion workflow for cost break models

    The script enforces a safe workflow by providing SELECT queries first to preview what will be deleted, with all DELETE statements commented out by default. It includes a verification query to check remaining models after deletion, and warns users to close Margin Master before running to avoid database conflicts.

  • Database Prevent cascading index damage from degraded view state

    Added a check for the SavedViewsLoadFailed flag before running RemoveStaleIndexesAsync. This prevents cascading damage when the app is operating with a fallback selection box view that has fewer fields than the user's actual custom view. The stale index removal now only runs when the full set of saved views has been successfully loaded, ensuring index cleanup decisions are based on accurate field usage data.

  • Database Added version tracking to issue notifications

    Added ResolvedInVersion field to the OpenIssueOption data model to track which app version contains the resolution for each support issue, enabling version-aware filtering of issue notifications.

  • Database Added version tracking to issue records

    Added ResolvedInVersion field to the OpenIssueOption model to track which version of Margin Master resolved each issue, enabling version-aware filtering of issue notifications.

  • Database Seed data insertion now idempotent and safe for re-runs

    Rewrote the initial data insertion logic to use INSERT WHERE NOT EXISTS semantics for the About, GlobalFileConfig, and ApplicationSettings tables. This allows the schema initialization process to run safely against empty databases, partially-initialized databases, or fully-populated databases without creating duplicate rows or overwriting existing configuration.

  • Database Database initialization is now idempotent

    Rewrote the initial data insertion logic to use INSERT...WHERE NOT EXISTS semantics across the About, GlobalFileConfig, and ApplicationSettings tables. This makes schema bootstrapping safe to run against empty, partially-initialized, or fully-populated databases without creating duplicate rows or overwriting existing configuration. The new EnsureDatabaseSchemaInitializedAsync method can be safely invoked multiple times on the same database.

  • Database SQL service account detection

    Implemented automatic detection of the SQL Server service account by querying sys.dm_server_services at startup. The system recognizes well-known accounts like LocalSystem and NETWORK SERVICE that already have default access, and can identify custom service accounts (like "NT SERVICE\MSSQL$INSTANCE") that need explicit permission grants.

  • Database Standardized EpicorStoreNumber column collation

    Updated the MySqlStoreManagerInfo table creation script to explicitly set the EpicorStoreNumber column collation to Latin1_General_CS_AS, matching the collation used in Compass_IN tables. This ensures new database installations won't encounter the collation mismatch issue.

  • Database SQL Server 2022 support removed from upgrade script
  • Database Cost break data management

    Provides database administrators with a supported method for cleaning up cost break model data when needed during troubleshooting or data correction scenarios.

  • Database Add UpdateDate field to issue data model

    The OpenIssueOption data model now includes an UpdateDate property to track when issues are modified, supporting the updated display and sorting behavior in the Support Issues screen.

  • Database StoreManagerInfo table and migration

    Store configuration is now saved in a new unified database table, with automatic migration from your existing settings on first use.

  • Database Add license storage fields to ApplicationSettings

    Three new ApplicationSettingKey values (IPWorksLicenseFTP, IPWorksLicenseSSH, IPWorksLicenseZip) were added to store nsoftware IPWorks runtime licenses in the local database, enabling offline operation after the first successful cloud fetch.

  • Database New settings for license persistence

    Added three new application settings (IPWorksLicenseFTP, IPWorksLicenseSSH, IPWorksLicenseZip) to store runtime licenses locally. These are automatically populated whenever cloud licenses are successfully retrieved and used as a fallback tier when cloud services are unreachable.

  • Database Auto-disable orphaned managed indexes

    The system now automatically disables managed indexes that reference columns no longer present in the database (such as Formula2/Formula3 after table rebuilds) instead of attempting to recreate them on every startup. This prevents repeated SQL errors 207 and 1911 and improves startup performance.

  • Database Obsolete setting cleanup

    Added a database update routine that removes the obsolete HasMultipleRSCs entry from the ApplicationSettings table during startup. This cleanup runs automatically through June 19, 2026 to handle existing installations, after which the setting will no longer exist in any database.

  • Database System initialization markers remain idempotent

    Preserved the INSERT WHERE NOT EXISTS pattern for System configuration markers (Initialized, CreatedViaEFCore) in GlobalFileConfig, ensuring these timestamp-based values are not overwritten on re-initialization while store identity settings are properly updated.

  • Database Automatic database repair for legacy store matchup values

    Added automatic one-time repair logic (NormalizeLegacyStorematchupOrdinalsAsync) that runs at startup to normalize legacy STOREMATCHUP values in the GlobalFileConfig table from raw characters to ordinal format. The repair only updates rows that actually need normalization and logs each change for audit purposes.

  • Database Support comment tracking enhancement

    Added `IsFromSupport` boolean field to the `IssueCommentForDev` model to reliably distinguish between customer-originated and support team-originated comments, replacing the previous string-based comment type parsing logic. This provides more accurate message direction determination for the new chat bubble alignment and styling.

  • Database Obsolete setting cleanup

    DatabaseUpdateService now includes RemoveObsoleteSettingsAsync, which deletes the HasMultipleRSCs row from ApplicationSettings during startup for installations running before June 19, 2026. This cleanup is automatically performed during the field mappings update phase.

  • Database StoreManagerInfo table and automatic migration

    Your existing store mappings and settings are automatically transferred to the new Store Manager system.

  • Database Improved database existence check

    Database existence checks during restore now use async parameterized queries instead of synchronous string concatenation, improving security and preventing UI blocking.

  • Architecture Added complete-submission API endpoint call

    Introduced a new API call that the WPF client makes after uploading all attachments to signal the server to send the creation notification email. This two-phase submission process (create issue + upload attachments → trigger notification) ensures email accuracy.

  • Architecture New API endpoint for completing issue submission

    Added `CompleteIssueSubmissionAsync` method to the API client service that calls the `/api/issues/{issueId}/complete-submission` endpoint. This endpoint signals the server that all attachments have been uploaded and it's safe to send the creation notification. The workflow only applies to new issues; updates continue to send notifications immediately.

  • Architecture Remove MySqlStoreManagerInfoViewModel and related dialogs

    Deleted MySqlStoreManagerInfoViewModel, EpicorMySqlImportManagerViewModel, MySqlMissingRequiredInformationFixViewModel and their XAML views (4,157 lines removed). All MySQL store management now uses the unified StoreManagerViewModel and StoreManagerInfo entity, eliminating code duplication and simplifying maintenance.

  • Architecture Exposed condition conversion method

    Made the ConvertConditions method public in StrategyStepService to enable the view model to rebuild condition display models after programmatic modifications to the instruction set.

  • Architecture Discrete backup sections replace lumped configurations

    Introduced dedicated model classes (BackupCostBreak, BackupMinMaxStrategy, BackupMinimumMargin, BackupSelectionBoxView, BackupColumnView, BackupCustomFieldName, BackupCustomSortOrder, BackupStoreMatchUp) to replace generic GlobalFileConfig entries. Added BackupInventoryService to query available items from the database for population of the tree view. V2ToV3Mapper handles automatic conversion of legacy backups by extracting discrete sections from lumped V2 fields.

  • Architecture New schema initialization helper for existing databases

    Added EnsureDatabaseSchemaInitializedAsync method to DatabaseCreatorService that exposes EF migration application, seed data insertion, and schema verification as a standalone, idempotent operation. This helper can be invoked by any component that needs to ensure an existing database has the full MarginMaster schema without risking data loss or duplication.

  • Architecture Added public schema initialization method

    Introduced IDatabaseCreatorService.EnsureDatabaseSchemaInitializedAsync as a public interface for idempotently applying EF migrations and seed data to an existing database connection. This complements the existing CreateDatabaseAsync method (used by the New Database wizard) and enables other code paths—like the Store Configuration dialog—to ensure schema readiness without creating a new database file.

  • Architecture RSC detection logic consolidated

    All code paths that previously checked the HasMultipleRSCs setting now use the derived check (counting distinct RSC values in STORERSC data). This affects Cloud Sync, Data Aging analysis, vendor data sync, store matchup screens, and vendor data cleanup routines. The logic is consistent across 18 files including DatabaseService4, StoreDataService, CloudSyncServiceShim, and multiple ViewModels.

  • Architecture Support machine detection in settings service

    The IsSupportMachine flag, previously only tracked in MainMMViewModel, is now also stored in ApplicationSettingsService and set during startup. This allows the restore dialog and other components to check support machine status without coupling to the main view model.

  • Architecture Feature flag synchronization with UI state

    BackgroundServiceTabViewModel now tracks IsFeatureEnabled as a property mirroring the database flag, and provides SetFeatureEnabledAsync to persist changes. When enabled, the view model automatically refreshes service status and run history. The runtime coordination components (banner poller, Windows service) continue to key off the same database flag.

  • Architecture Window placement stored in local JSON files

    Window placement data is saved to local JSON files in the application data directory rather than the database. This eliminates potential deadlocks during application shutdown and ensures window positioning works even if database sync is in progress. The placement file is written synchronously during window close, making it safe and reliable.

  • Architecture Centralized backup metadata provider

    Created IBackupMetadataProvider service to consolidate metadata creation and ZIP compression logic. This ensures all backup operations capture consistent metadata (vendor, store, POS system, database name, version) and handle compression identically, eliminating code duplication across the five different backup scenarios.

  • Architecture Refactored comment display converters

    Removed separate CommentAlignmentConverter and CommentCornerRadiusConverter classes, consolidating message styling logic. Added CommentTemplateSelector to automatically choose between system activity templates and human message templates based on sender name. Streamlined CommentSenderLabelConverter to handle new naming conventions.

  • Architecture Synchronous placement save during shutdown

    Window placement is saved using synchronous file I/O during window close to avoid UI thread deadlocks during application shutdown. Placement data is stored in a local JSON file (last-mainwindow-placement.json) in the common application data folder, independent of the database.

  • Architecture IsFromSupport flag replaces comment-type parsing

    The API response model now includes an explicit IsFromSupport boolean flag on each comment, replacing the previous approach of parsing comment type strings to determine message alignment and styling. This simplifies the UI logic and makes the distinction between user and support messages more reliable. New converters handle alignment, colors, corner radius, initials, and sender labels based on this flag.

  • Architecture Refactored connection testing logic

    Moved connection testing logic from frmOptions code-behind into MySqlConnectionDetailViewModel, improving testability and separation of concerns. Added MySqlServerScanResult model to encapsulate scan results with response times.

  • Architecture Consolidated connection testing logic

    Removed approximately 100 lines of duplicated connection test code from frmOptions.xaml.cs. The legacy form now delegates save and test operations to MySqlConnectionDetailViewModel, ensuring both the old and new Options windows use identical validation and retry logic.

  • Architecture Store detail and zone edit popups

    Adds StoreDetailViewModel and StoreDetailView for read-only display of cloud store state (StoreStatus, IsPrimaryStore, CloudStoreId, StoreStatusLastSync). Adds StoreZoneEditViewModel and StoreZoneEditView for zone override editing with live preview of effective zone. Both are launched as modal dialogs from the Store Manager grid via dedicated view services.

  • Architecture BackupRestoreOptions extended with V3 section flags and item filters

    Added ProcessCostBreaks, ProcessMinMaxStrategies, ProcessMinimumMargins, ProcessSelectionBoxViews, ProcessColumnViews, ProcessCustomFieldNames, ProcessCustomSortOrders, ProcessStoreMatchUps flags. Added SelectedStrategyNames, SelectedRoundingSchemeNames, SelectedCostBreakNames, SelectedMinMaxStrategyNames, SelectedSelectionBoxViewNames, SelectedColumnViewNames nullable lists—null means include all, empty means none, populated means only named items.

  • Architecture Diagnostic result skip state

    DiagnosticResult now supports a `Skipped` state with a `SkipReason` field, allowing modules to report when they were skipped (e.g., user cancelled file selection) without reporting false failures.

  • Infrastructure Cost break model deletion script

    Added a SQL script to safely delete cost break models from the database. This administrative tool can be used for database maintenance tasks such as removing outdated or incorrect cost break configurations.

  • Infrastructure Optimized update package compression

    When Margin Master updates itself, the download will be smaller and faster than before.

  • Infrastructure Local encrypted license cache for third-party components

    Z.Dapper.Plus, Z.BulkOperations, and IPWorks licenses are now served from a local encrypted cache on startup, falling back to the API only on cache miss or validation failure. This eliminates unnecessary API calls on every application launch, speeds up startup, and improves offline reliability. When a license validation fails, the cache is automatically invalidated and refreshed from the API, ensuring the next startup receives fresh keys.

  • Infrastructure Removed automatic .NET runtime verification from installer

    The Velopack installer previously checked for and attempted to install the required .NET 10.0 desktop runtime during setup. This check has been removed to streamline the installation process and avoid conflicts with existing runtime installations. Users must ensure the appropriate .NET runtime is installed separately if not already present.

  • Infrastructure Support tools directory enhancement

    The script is stored in the scripts/SqlScripts directory and includes comprehensive inline documentation, safety instructions (requiring Margin Master to be closed before running), and a two-step process (preview first, then delete) to prevent accidental data loss.

  • Infrastructure Database lock contention handling enhanced

    Modified GlobalFileConfigService to use DataModification operation type instead of StandardQuery for critical startup paths. This change provides longer wait times for database locks that protect configuration data used throughout the application, particularly during the initialization phase when strategies and indexes are being loaded.

  • Infrastructure Reduced log severity for transient network failures

    Network timeouts and connection errors when fetching open issues now log as warnings instead of errors. Since open issues are a non-critical UI enhancement, temporary failures are expected and shouldn't be treated as application errors.

  • Infrastructure Added typed POST request support to API client

    Added PostAndGetAsync<TRequest, TResult> method to IApiClientService and ApiClientService to support strongly-typed POST requests with JSON request bodies and deserialized response objects. This provides a cleaner API for the new Manager update check-in endpoint and future typed POST operations.

  • Infrastructure Enum value stabilization

    Store status types now use explicit integer values to ensure data consistency. This prevents potential data mismatches if the enum order changes during future development.

  • Infrastructure Build pipeline updated for self-contained deployment

    The GitHub Actions workflow and project configuration were updated to publish the bootstrapper as a self-contained application, bundling the .NET runtime directly into the setup executable.

  • Infrastructure Backup failures excluded from telemetry

    Database backup path failures are now classified as environmental issues (specific to each store's network and SQL Server configuration) rather than application bugs. These errors are still logged locally and shown to the user, but are no longer reported to the error telemetry API, reducing noise in bug reports.

  • Infrastructure Startup self-heal service with minimal dependencies

    Created a new StartupSelfHealService that depends only on .NET BCL and WPF framework libraries, with no MarginMaster assembly references, since those assemblies may themselves be corrupted. The service integrates into three startup failure paths: App constructor exceptions, startup checks failures, and terminating AppDomain exceptions. A state file at the install root tracks repair attempts, and the counter is cleared on healthy startup.

  • Infrastructure SQL injection protection for wildcard characters

    Updated the SQL validation pattern to allow asterisk characters (*) in filter values, enabling proper wildcard support while maintaining security protections.

  • Infrastructure Critical-path database operations with retry logic

    Added new critical-path database operation methods to GlobalFileConfigService that use longer timeouts and exponential backoff retry logic for loading essential startup configuration like selection box views and column views. This prevents transient database lock contention from causing silent failures in critical user-facing features.

  • Infrastructure Parallel cloud container scanning with progress tracking

    Cloud backup scanning now processes multiple store containers concurrently (up to 4 at a time) with a semaphore-based throttling mechanism. The loading message dynamically updates to show "Scanning store {VendorShort} {StoreNumber} ({current}/{total})..." when scanning multiple stores, or the simpler "Scanning cloud backups..." for single-store scenarios.

  • Infrastructure Backup folder ACL caching

    Added three new application settings keys (BackupFolderAclAttemptedFor, BackupFolderAclAttemptedDate, BackupFolderAclGrantSucceeded) to track permission grant attempts. The system stores a fingerprint combining the SQL service account name and backup folder path, ensuring permission grants are retried only when the configuration changes, not on every application launch.

  • Infrastructure ACL inspection and elevation

    Added NTFS access control list inspection to verify existing folder permissions, and integrated icacls-based permission granting with UAC elevation. The system gracefully handles declined UAC prompts (Win32Exception 1223) and never blocks application startup if permission checks fail.

  • Infrastructure PowerShell script step renumbering

    Step numbers in both Install-SQLExpress.ps1 and Upgrade-SQLExpress.ps1 have been incremented to accommodate the new Visual C++ verification step (now Step 2), ensuring documentation and console output remain synchronized.

  • Documentation Added comprehensive large sector drive compatibility guide
  • Infrastructure Improved nullable reference type handling

    Updated DatabaseConnectionResult class to properly handle nullable reference types, improving code safety and eliminating potential null reference issues during database connection workflows.

  • Infrastructure Enhanced error logging for database cleanup operations

    Added detailed logging when dropping orphaned databases, including warnings if cleanup fails. This helps diagnose scenarios where manual SQL Server cleanup may still be required due to locked connections or permission issues.

  • Infrastructure Three-tier license fallback strategy

    Component licenses now follow a three-tier fallback: (1) local encrypted cache (fastest), (2) Blazor Manager API (fresh keys), and (3) appsettings.json base64 values (offline fallback baked in at build time). This ensures maximum reliability across network conditions while minimizing startup latency.

  • Infrastructure Component license cache service registration

    The new ComponentLicenseCache service is now registered in the dependency injection container and integrated with IPWorksLicenseService and StartupCheckService, providing a centralized encrypted storage mechanism for all third-party component licenses.

  • Infrastructure Added bootstrapper error telemetry

    The bootstrapper now automatically reports errors (exception type, message, stack trace fingerprint, OS version) to a telemetry endpoint. This enables the development team to diagnose installation failures in the field without requiring users to manually submit logs. No personally identifiable information is collected.

  • Infrastructure Server API integration for issue deletion

    Implemented new API endpoint integration at `/api/issues/{issueId}/delete-from-app` that sends store number and vendor ID for server-side ownership verification. The operation includes proper error handling, logging, and timeout configuration (15 seconds) consistent with other API operations.

  • Infrastructure Separate cache keys for support employee contacts

    Modified the cache key system to distinguish between regular store contacts and those that include support employees, ensuring proper cache management for different contact query types.

  • Infrastructure Support machine detection exposed to application settings

    The IsSupportMachine flag, previously only tracked in the main view model, is now exposed through the ApplicationSettingsService interface and set during startup. This allows other parts of the application to conditionally adjust behavior based on whether the installation is a support machine.

  • Infrastructure Added 15 unit tests for wildcard filter behavior

    Added WildcardFilterTests with 15 new test cases covering operator selection (LIKE vs NOT LIKE), preservation of plain value equality filters, and correct handling of wildcard-only patterns. Tests verify patterns like "81%" and "%ARD%" produce the correct SQL operators while bare wildcards are skipped, and that plain values retain their equality operators.

  • Infrastructure Debug startup profile chooser (developers only)

    Added a debug-only window that appears before the splash screen in Debug builds, allowing developers to simulate any startup scenario: new install with no SQL, stopped SQL service, expired license, missing database, no internet connection, multiple SQL instances, old SQL versions, etc. Developers can "remember" a profile to auto-apply it on subsequent launches, or hold Shift at startup to force the chooser to appear. This replaces the previous appsettings.json-based scenario flags with a visual selector that combines all three scenario types (connection, license, scanner) into 11 pre-built profiles like "Brand New Install," "SQL Stopped," "Expired License," and "Lost Server."

  • Infrastructure Display formatter with unit tests

    Created StoreNumberDisplayFormatter helper class with comprehensive unit tests to ensure display labels are correctly formatted for all four display modes and that missing POS mappings gracefully fall back to showing the vendor store number.

  • Infrastructure Reorganized script embedding and documentation structure

    PowerShell scripts are now organized in category subfolders (scripts/SqlScripts/Powershell/, scripts/OLEDB/Powershell/) and embedded using a recursive glob pattern. Each script now requires accompanying markdown documentation in both the scripts/ folder (developer reference) and docs/marginmaster/support/scripts/ (user-facing support docs), with corresponding index.json entries.

  • Documentation Support documentation updated with LargeSectorFix troubleshooting

    All four documentation files (two markdown docs in /docs/marginmaster/support/scripts/ and two in /scripts/SqlScripts/Powershell/) have been updated with new parameter descriptions, usage examples, and a troubleshooting row for error 0x851A001A. Users encountering setup failures related to LargeSectorSizeCheck will now find clear guidance to re-run with the fix enabled.

  • Infrastructure Blob migration utility

    Added MarginMaster.BlobMigration console project to migrate existing strategy backups from Azure blob storage to the new SQL system. Supports both ZIP and JSON blob files, auto-detects V1/V2/V3 formats, and preserves original backup timestamps during migration.

  • Infrastructure Documentation updates for auto-update behavior

    Updated auto-updates.md and search index to document the new idle auto-trigger, countdown, and What's New features. Added FAQ entries explaining how the countdown works and what happens when Cancel is clicked.

  • Infrastructure SSMS detection service and PowerShell script enhancements

    Added new ISsmsDetectionService and SsmsDetectionService that scan Windows registry uninstall keys to detect installed SSMS versions and validate against minimum version requirements (v22). Enhanced Install-SSMS.ps1 and Upgrade-SSMS.ps1 PowerShell scripts with new -LogFile parameter to support real-time transcript output for progress monitoring. Updated scripts to automatically reuse cached installers when running non-interactively from the WPF UI. Fixed SqlExpressMigrationService to properly hide elevated PowerShell windows using WindowStyle.Hidden.

  • Infrastructure SSMS detection debug scenario support

    Extended SsmsDetectionService with debug scenario infrastructure matching the existing patterns for connection, license, and SQL scanner testing. Added configuration support via appsettings.Development.json "SsmsScenario" key with values Normal, NotInstalled, and NeedsUpgrade.

  • Infrastructure Comprehensive restore logging

    Added detailed logging throughout the entire restore pipeline, including download milestones, SQL restore progress, error conditions, and recovery attempts for better troubleshooting and monitoring.

  • Infrastructure PowerShell script execution improvements

    Enhanced Install-SSMS.ps1 and Upgrade-SSMS.ps1 with -LogFile parameter support for real-time transcript tailing. Modified PowerShell invocation to use WindowStyle.Hidden instead of CreateNoWindow when UseShellExecute is enabled, properly suppressing console windows. Added automatic reuse of cached installers when running non-interactively from the WPF application.

  • Infrastructure Legacy class preservation

    Preserves MySqlStoreManagerInfo and STOREMATCHUP access for non-migrated users. StoreManagerInfoMigrated flag guards against re-migration. Cleanup of old classes planned for future release after migration verification period.

  • Infrastructure Added command-line debug profile support

    Debug builds can now auto-apply a startup profile via --debug-profile N command-line argument, skipping the debug chooser dialog entirely for automated testing scenarios.

  • Infrastructure PowerShell script embedding

    SQL Server and SSMS installation scripts (Install-SQLExpress.ps1, Upgrade-SQLExpress.ps1, Install-SSMS.ps1, Upgrade-SSMS.ps1) are now embedded as content files and copied to the DiagnosticTool output directory for reliable script execution.

RockSolidFalconPaladinTransactWestLakeCloudSyncDoitBestAceHardware
2026.722.40084
July 23, 2026

Release notes aren't available for this version.

2026.722.17634
July 22, 2026

Release notes aren't available for this version.

2026.721.40386
July 22, 2026

Release notes aren't available for this version.

2026.721.37083
July 22, 2026

Release notes aren't available for this version.

2026.716.26250
July 21, 2026

Automatic self-repair for corrupt installations; Automatic cloud backup of validated POS connections; Automatic cloud backup of validated POS connections.

Strategy & Pricing

  • New Feature Margin Master database connection cloud backup

    Your Margin Master database connection is now automatically saved to the cloud after importing data.

  • New Feature Per-store pricing support for Mi9 installations

    When single-table mode is enabled in Settings, Mi9 stores can now analyze and manage pricing individually for each location rather than being grouped by team, giving you finer control over store-specific pricing strategies.

  • New Feature MI9 single main table processing mode

    MI9 stores can now switch to a processing mode that lets each store have its own prices instead of sharing team prices.

  • New Feature Unpriced SKU report added to strategy execution logs

    After running a pricing strategy, the log file will now show you exactly which items didn't get priced and whether it's because they're missing a cost in your POS system or because your strategy doesn't have a step that matches them.

  • New Feature Unpriced SKU report after strategy execution

    After running a pricing strategy, the execution log will show how many items received no pricing rule and explain whether it's because they have no cost in your POS data or because no pricing step matched them.

  • New Feature Sort by Name button for custom groups

    Click the new "Sort by Name" button to arrange all custom groups alphabetically. This changes the order they run in, so remember to Save if you want to keep the new sequence.

  • New Feature Sort groups alphabetically by name

    You can now click "Sort by Name" to instantly arrange all your custom groups in alphabetical order.

  • New Feature Restore and apply Margin Master database

    Restoring a Margin Master database connection automatically switches you to that database and prompts you to restart the application to complete the change.

  • New Feature One-click Margin Master database restore and switch

    You can now restore your Margin Master database connection with one click — the app will switch to it and prompt you to restart.

  • Improvement Store matchup sourced from unified store manager

    When the StoreManagerInfo system is active, POS-to-vendor store number mappings are now read from StoreManagerInfo.VendorStoreNumber and PosStoreNumber instead of GlobalFileConfig STOREMATCHUP entries. The data is automatically shaped to match the existing format, ensuring all import readers continue working without changes while using the authoritative source.

  • Improvement Custom Groups load performance and progress feedback

    When opening Manage Custom Groups, you'll now see exactly how many groups are loading and the window won't freeze during the process.

  • Improvement Informative messages for Load SKU Exceptions

    When you click Load SKU Exceptions, you'll now get a clear message if no strategy is active or if the current strategy has no exceptions defined, so you know why nothing loaded.

  • Improvement Enhanced startup logging for vendor data checks

    Added detailed logging to the vendor data availability check at startup, recording why the system did or did not download/rebuild data. This provides clear audit trails showing whether the startup followed the fresh-install path (download + rebuild) or the upgrade path (data already present, freshness verified separately), making it easier to diagnose pricing-related issues from field logs.

  • Improvement Added heartbeat timer to show progress during long operations

    During long operations, you'll now see a running timer showing how long the operation has been working, so you know the system hasn't frozen.

  • Improvement Zone override configuration from unified store manager

    Zone number overrides during import now read from StoreManagerInfo.ZoneNumberOverride (applied across all nine departments per store) when the unified system is enabled. Previously, these overrides were stored only in GlobalFileConfig ZONE_OVERRIDE entries. This change centralizes zone pricing configuration alongside other store settings.

  • Improvement Defensive null handling in SKU write-back

    Added null-coalescing guards to all SKU Detail ViewModel collection accesses during the write-back phase, preventing potential crashes when the SkuViewModels collection is null during edge-case dialog lifecycle scenarios.

  • Improvement Dramatically faster saves when reordering custom groups

    Saving after reordering custom groups is now much faster, especially if you have many groups defined.

  • Improvement Custom Groups save optimized for reordering

    Reordering groups now saves much faster, and the window shows progress instead of freezing during save.

  • Improvement Better error messages for misconfigured strategy steps

    When viewing strategy execution logs, skipped steps now show clear instructions on what needs to be fixed, including exactly which setting to configure in the strategy editor.

  • Improvement Cloud sync fails fast when network or Manager API is unreachable

    When your store loses internet connection during sync, Margin Master will now detect this immediately and stop trying instead of slowly testing each table, making sync respond faster when you're offline.

  • Improvement Better feedback for Load SKU Exceptions

    Loading SKU Exceptions now tells you when there are no exceptions to load, instead of appearing to do nothing.

  • Improvement Zone pricing updates now display per-zone progress

    When updating zone pricing, you'll now see which specific zone is being processed instead of a blank screen for several minutes.

  • Improvement Auto-skip strategy steps with no matching data

    When a pricing step's filters don't match any items in your current data, the system will automatically skip it instead of stopping to ask what you want to do.

  • Improvement Sequence numbers now auto-heal gaps from deleted groups

    When custom groups are deleted, the ManageCustomGroupsViewModel now automatically renumbers the remaining groups to close gaps (e.g., 1,2,5,7 becomes 1,2,3,4) so the displayed sequence number always matches the row position. The normalized values reach the database on the next save.

  • Improvement Automatic sequence normalization on load

    Custom group sequences are now automatically normalized when the window opens, healing gaps and duplicates left by deleted groups (e.g., 1, 2, 5, 7 becomes 1, 2, 3, 4). This ensures the displayed sequence number always matches the row position without requiring manual intervention.

  • Improvement Enhanced save progress reporting

    When saving many custom groups at once, you'll see accurate progress counts showing how many groups have been saved.

  • Improvement Shared table name constants between import and UI

    Extracted Mi9 table names into a new shared Mi9TableConstants class in MarginMaster.Common to ensure the import engine and UI always reference identical table names. This prevents potential drift between the components that build and consume the Mi9 pricing tables.

  • Improvement Steps with no matching data now skip silently instead of prompting

    If a pricing strategy step is set to filter by a value that doesn't exist in your current data (for example, a step earlier in the strategy hasn't run yet to create it), the system will quietly skip that step instead of stopping to ask what you want to do—since it wouldn't have changed anything anyway.

  • Improvement Better error logging for group reordering

    Move Up and Move Down operations now log exceptions instead of silently swallowing them, making it easier to diagnose issues with group reordering.

  • Improvement Non-blocking cloud backup on close

    Closing the Manage Custom Groups window after saving is now instant instead of waiting for the cloud backup to finish.

  • Improvement Report when strategy execution runs with no rules defined

    Strategy execution now warns in the log when a strategy has zero pricing rule steps, and the execution summary explicitly states "no steps ran — no prices were changed" instead of showing a misleading "✓ COMPLETED SUCCESSFULLY" message. The log now separately reports rule step count vs. total phases to make empty strategies immediately visible.

  • Improvement Added comprehensive test coverage for Compass rebuild routing

    Added CompassRebuildRoutingTests with 7 tests covering both the routing logic and the safety guards, including specific tests that pin the exact failure scenario reported by store 6324 (four Compass stores losing all main tables on a fresh database).

  • Improvement Warn when active strategy is missing after restore

    If the saved active strategy name doesn't exist after database load (case- and whitespace-insensitively), the app now logs a warning identifying which strategy was requested, which are available, and which fallback was selected, instead of silently switching strategies.

  • Improvement Table name handling for single main table

    Updated table name parsing throughout the application (Cost Break, Implementation Plan, Profit Analyzer, store change summaries) to recognize Mi9_mainTable and return "All Stores" or the "ALL" token instead of attempting to split the table name. Prevents the literal string "mainTable" from being reported as a store number.

  • Bug Fix Corrected active PS Rule counting logic

    When viewing a pricing strategy with no active rules, you'll now see a clear message stating the strategy has no PS Rules, instead of seeing an execute button that doesn't work.

  • Bug Fix Automatic detection and repair of stale pricing data after upgrades

    If your pricing grid shows outdated vendor costs after upgrading, the application will now automatically detect and fix this on the next launch, showing a "Refreshing pricing data..." message during startup.

  • Bug Fix Splash screen now closes reliably after long startup operations

    The startup screen now closes properly every time, even when database maintenance takes longer than usual.

  • Bug Fix Splash screen now closes before modal dialogs appear

    When opening pricing strategies or data aging tools, the loading message now properly disappears before the next window opens, preventing the app from appearing stuck.

  • Bug Fix SKU Detail dialog crash with empty grid

    You can now safely edit SKU pricing details from QuickFind even while the main grid is still loading data or temporarily empty.

  • Bug Fix Zero-cost SKUs now consistently excluded from margin pricing steps

    Previously, items with no cost might have been repriced to $0.02 or silently skipped. Now all no-cost items are consistently excluded from pricing, and you'll see a report explaining why they received no pricing rule.

  • Bug Fix Zero cost now correctly treated as missing cost

    Previously, SKUs with StoreCost=0 and Cost=0 were silently excluded from margin pricing steps but received no explanation in logs. The system treated NULL cost as "missing" but zero cost as valid, causing inconsistent behavior. Now both zero and NULL are treated identically as "no cost," and these SKUs are excluded from margin calculations with clear reporting explaining why they received no pricing rule.

  • Bug Fix Custom group execution order now respects user sequence

    If you rearranged custom groups with the Up/Down buttons to control which pricing rules run first, those groups were actually running in alphabetical order instead. This meant overlapping groups could apply the wrong prices. Now groups run in exactly the order you set, and that order is preserved when you reopen the window.

  • Bug Fix Custom group order now persisted correctly

    When you reorder custom groups using the Up/Down buttons and save, those groups will now appear in the same order the next time you open the window. Previously, they would reset to alphabetical order.

  • Bug Fix Eliminated NullReferenceException in splash screen timer

    Fixed a rare crash that could happen when quickly closing and reopening dialogs like Manage Custom Groups.

  • Bug Fix Save button now works correctly after reordering groups

    The "Saving Changes..." message now appears and updates while custom groups are being saved, so you know the program is working.

  • Bug Fix Busy indicator now appears during save operation

    You'll now see a progress message when saving custom groups as you close the window, instead of the screen appearing frozen.

  • Bug Fix Pricing steps with exclusion filters no longer skipped after import

    If you use pricing strategy steps with "not equal to" conditions (like excluding certain vendor rules or brands), those steps will now correctly apply pricing after you import fresh data from your point-of-sale system. Previously, these steps might have been skipped, leaving items without the correct pricing.

  • Bug Fix Exclusion filter steps no longer incorrectly skipped
  • Bug Fix PSRule filter matching corrected for pricing strategy steps

    When configuring a pricing strategy step to only process items last touched by a specific earlier step (or to skip items from that step), the filter now works as intended instead of silently failing.

  • Bug Fix PSRule filters now match both step name and step index formats

    When you filter the pricing grid by a specific strategy step (like "Benjamin Moore"), it will now correctly show all items processed by that step, even if those items were originally processed months or years ago by an older version of the software.

  • Bug Fix Strategy steps with no pricing action now skip instead of crashing

    If a strategy step is missing its pricing instructions, the strategy will continue running instead of stopping completely. The step detail log will show "Skipped — No Pricing Action Configured" with instructions on how to fix the step by editing it and choosing a "Set Future Price To" option.

  • Bug Fix Strategy steps with no pricing action now skip instead of failing

    If a strategy step is missing its pricing instructions (no "Set Future Price To" level selected), Margin Master will now skip that step and continue running the rest of your strategy instead of stopping completely.

  • Bug Fix Inactive strategy steps now report accurate timing

    When a strategy step is disabled, it's added to the run results without executing. Previously, its duration was calculated at summary-write time, showing the elapsed time from step creation to summary (e.g., "6m 08s") instead of near-zero. Now inactive steps close immediately at construction, reporting "<1s" as expected.

  • Bug Fix Inactive strategy steps now report correct duration

    Previously, inactive steps accumulated phantom duration from when they were skipped until the summary was written, sometimes showing minutes of elapsed time. Now they are immediately closed at construction time and always report "<1s" duration.

  • Bug Fix Fixed store identification when parsing single-table names

    Reports and analysis screens now correctly identify stores when working with Mi9 pricing data in single-table mode.

  • Bug Fix Compass rebuild routing now uses consistent logic across all code paths

    Compass stores now correctly use MySQL Import Manager routing, ensuring pricing data is pulled from the right source.

  • Bug Fix Strategy backup now detects and prevents empty rule exports

    If your pricing strategy backup somehow captures no rules, you'll now see a warning instead of silently saving an empty file that could overwrite a good backup.

  • Bug Fix Detect and prevent empty strategy backups from displacing good history

    Fixed MM-1320, where a store's automatic strategy backups silently captured zero pricing rules for months while rules were in daily use. When the rules were eventually lost, every backup in cloud history was empty and worthless. The app now detects when a backup contains no steps, custom groups, SKU exceptions, cost breaks, min/max strategies, or minimum margins, logs a warning, writes the local file for inspection, but refuses to upload it to the cloud so it cannot push good backups out of retention.

  • Bug Fix PS Rule box consistency after strategy execution

    The PS Rule filter now shows the same list of rules whether you're looking at it before or after running a strategy.

  • Bug Fix Data Aging initialization errors now properly clear splash screen

    If an error occurs while loading the Data Aging screen, the loading message will now properly clear instead of staying visible indefinitely.

  • Bug Fix Window no longer freezes during cloud backup upload

    The Custom Groups window now closes immediately after saving your changes, without freezing during the cloud backup.

  • Bug Fix Deactivated or renamed strategy steps no longer generate invalid filter queries

    When a strategy step is renamed or deactivated, the filter can no longer resolve it to a numeric index. The old code would fall back to comparing against "0", which would silently match or exclude everything. The filter now compares against the original filter value directly in these cases, preventing silent failures and preserving the user's intent.

  • Bug Fix Inactive steps now display INACTIVE marker in summary log

    Run summaries now clearly show which strategy steps were skipped because they're disabled.

  • Bug Fix Inactive steps now display INACTIVE marker in processing logs

    The summary log's conditional logic has been corrected so that inactive steps display "*** INACTIVE — step is disabled in the strategy ***" instead of being treated as successfully executed with zero SKUs affected.

  • Bug Fix Eliminated double-counting in Mi9 pricing impact calculations

    Pricing impact numbers and inventory values now display correctly without inflation for stores using Mi9 single-table configuration.

  • Bug Fix Main table reconciliation no longer drops all tables when store list query fails

    The system will no longer delete all pricing tables if it can't properly verify which stores should exist.

  • Bug Fix Strategy restore no longer deletes rules it cannot replace

    Restoring a backup that contains no pricing rules will no longer delete your current working rules — your existing strategies will be left unchanged and you'll see a clear warning message.

  • Bug Fix Prevent restores from deleting pricing rules when backup has none

    Fixed a destructive restore behavior where importing a backup with an empty strategy would delete all existing live rules for that strategy and restore nothing. If a backup contains a named strategy but zero rules for it, the restore now skips that strategy entirely and leaves existing rules untouched, with a warning logged for each skipped strategy, custom group collection, and SKU exception collection.

  • Bug Fix PSRule filter selection box now refreshes after strategy runs

    When creating or editing a strategy step that filters by "PS Rule" or "PS Rule History," the dropdown will now correctly show available values even after running a strategy or rebuilding your data.

  • Bug Fix Fixed window freeze during Custom Groups loading

    The splash screen now updates smoothly with live status messages instead of appearing frozen until the load completes.

  • Bug Fix Window remains responsive during save operation

    The Manage Custom Groups window no longer appears frozen when saving—you'll see progress updates and the window stays responsive.

  • Bug Fix Special PSRule codes 'ME' and 'GI' remain filterable

    Manual Entry ('ME') and Group Inconsistency ('GI') codes are stamped directly into the PSRule field and never have a numeric index. The new logic correctly handles these special cases, ensuring they remain filterable as expected.

  • Bug Fix Rebuild now aborts early when POS table is missing

    If the source pricing table is missing, you'll now see a clear error message instead of the system appearing to succeed while actually failing.

  • Bug Fix Restore success message now accurately reports missing rules

    After restoring a pricing strategy backup, the success message will now tell you if the backup file contained no pricing rules, so you know your strategies weren't actually restored.

  • Bug Fix PSRule selection box now rebuilds after strategy execution

    Fixed an issue where the PSRule selection box (used to filter by pricing rule names) would cache an empty state at startup and never rebuild, making PSRule-filtered strategy steps permanently unloadable. PSRule is now marked as a "volatile field" that is reset by every strategy run, so its selection box always re-scans to pick up newly stamped rule names rather than caching emptiness.

  • Bug Fix Fixed duplicate "Not in Database" entries for valid SKUs

    Custom group SKU lists no longer show duplicate or incorrect "Not in Database" entries for SKUs that exist in your system.

  • Bug Fix Corrected Mi9 post-import record count validation

    Import completion messages for Mi9 systems now correctly display the number of SKUs imported instead of always showing zero.

  • Bug Fix Failed insert operations now logged as errors instead of successes

    Changed logging behavior so that when ExecuteAsync returns -1 (indicating a caught SQL exception), it's logged as an error and post-processing is skipped, rather than reporting "Inserted -1 rows" as if the operation succeeded. This prevents the reconcile logic from counting a failed rebuild as successful and makes troubleshooting much clearer.

  • Bug Fix Strategy execution now reports when no pricing steps exist

    If you run a pricing strategy that has no pricing rules defined, you'll now see a clear warning that nothing was priced, instead of a "success" message.

  • Bug Fix Active strategy fallback now logs when switching strategies

    If the pricing strategy you had selected is missing (for example, after a restore), you'll now see a warning telling you which strategy the system switched to instead.

  • Bug Fix MI9 impact calculation for single table mode

    Modified MI9 impact calculation SQL generation to handle both processing modes. Single-table mode passes a singleTable flag that adjusts the SQL to work without the @GroupName parameter since one table covers all groups.

  • Cloud Sync Margin Master database connection backup

    Your Margin Master database connection is now automatically saved to the cloud after each import, just like your POS connection.

  • Cloud Sync Enhanced connectivity error classification

    Added IsConnectivityFailure flag to TableSyncResult and logic to detect HttpRequestException, SocketException, and "Manager API base URL is unavailable" errors by walking the exception chain. MultiTableSyncService now uses this flag to abort remaining tables within a vendor and skip remaining vendors entirely when connectivity fails, preventing cascade failures.

  • Data Import Mode restructure service

    Added Mi9MainTableModeService to orchestrate switching between processing modes. The service drops existing main tables, rebuilds in the target mode by re-importing all store POS data (using forceSingleTable parameter), and only commits the setting after successful rebuild. Failed restructures leave the setting unchanged and prompt users to run a manual import.

  • User Interface Context-aware empty messages for PS Rule selection box

    When the PS Rule box is empty, you'll see a clear message explaining why—whether you need to run a strategy first, add rules to your strategy, or select a strategy.

  • User Interface Context-aware empty state for PS Rule filter box

    When the PS Rule filter box is empty, you'll now see helpful messages like "Execute the strategy to view affected items" or "No active strategy selected" instead of generic text, making it clearer what action to take.

  • User Interface Improved strategy status messaging

    The pricing strategy panel now accurately reflects whether a strategy can be executed, preventing wasted clicks on inactive strategies.

  • User Interface Two-tab restore connection window

    The restore window now has separate tabs for POS connections and Margin Master database connections, making it easier to find the connection you need.

  • User Interface Two-tab restore dialog for POS and database connections

    When restoring a connection, you'll now see separate tabs for your POS system and your Margin Master database.

  • User Interface Added live progress reporting to Custom Groups loading

    You can now see exactly how many groups have loaded and watch the progress bar advance instead of staring at a frozen screen.

  • User Interface New MI9 options tab

    A new MI9 tab in Settings lets you switch between team-level and store-level pricing modes.

  • User Interface Progress indicator updates during long operations

    The "Please Wait" spinner and status messages now update smoothly instead of appearing stuck.

  • User Interface Updated display names for single-table across analysis screens

    Analysis screens now show "All Stores" when viewing data from the Mi9 single table, making it clearer what data you're looking at.

  • User Interface Warn users when restoring a backup with no pricing rules

    The restore confirmation dialog now explicitly states when a backup file contained no pricing strategy rules, making it clear that settings and views were restored but no strategies were applied. Previously, the dialog reported plain success even when 100% of the store's pricing rules were missing from the backup.

  • User Interface Enhanced error logging for group reordering

    Added error logging to the Move Up and Move Down operations to help diagnose issues if group reordering fails.

  • Database Enhanced step skip detection for pricing strategies

    The system is now smarter about when to run or skip pricing steps when certain data values are temporarily missing, reducing unnecessary warnings while protecting against accidental over-pricing.

  • Database Added backward compatibility for legacy PSRule data formats

    The fix maintains compatibility with older databases that may still contain numeric step indexes in the PSRule column rather than step names. The filter resolution logic queries the active strategy configuration to translate between step names and their 1-based position indices, allowing filters to match data written by any version of the application. Special handling preserves manual entry ("ME") and group inconsistency ("GI") codes that are stamped directly without step indices.

  • Database Optimized indexing for single-table query performance

    Added store-number-specific indexes for single-table mode to handle the significantly larger dataset (verified at 2.8M rows across 131 stores vs. 279K rows in multi-table mode). Created a unique index on (StoreNumber, SKU) to enforce data grain integrity and a covering index on StoreNumber with frequently accessed columns (SKU, CurrentPrice, FuturePrice, Cost). Multi-table mode retains its existing AltSku-only index since StoreNumber is constant there.

  • Database Connection identity includes role designation

    Database connections are now tagged with a "ConnectionKind" field (either "POS" or "MMDatabase") that distinguishes point-of-sale data sources from the Margin Master application database. This allows both connection types to coexist in cloud storage for the same store and ensures each appears under the correct restore tab.

  • Database Parameterized SQL injection risk in CustomGroupSkus delete

    Changed the CustomGroupSkus DELETE statement from string interpolation to parameterized queries, eliminating a potential SQL injection vector where SKU values were embedded directly into SQL strings.

  • Database Single main table indexing strategy

    Created a curated index set for the single main table mode: a unique index on (StoreNumber, SKU) to guard the grain, a covering index on StoreNumber for per-store queries, and an AltSku index for impact calculations. DMV-based auto-indexing is disabled in single-table mode to prevent index proliferation on the larger table (~2.8M rows vs ~121K per team table).

  • Architecture Configurable empty-state text for selection boxes

    Selection boxes can now override their empty-state title and subtitle on a case-by-case basis, allowing context-specific guidance throughout the application rather than relying on a single generic message.

  • Architecture Added pre-flight validation for pricing action lists

    Created FuturePriceActionListHelper with HasExecutablePricingAction method that mirrors the modifier token stripping logic in ApplyFuturePriceActionsAsync. This prevents empty action lists (containing only ROUNDING/LOCK/STRATEGYSTEP/ADDSUBTRACT/NODECREASES modifiers) from reaching ApplyFuturePriceSqlAsync where they would fail. Includes comprehensive unit tests covering empty lists, modifier-only lists, and real pricing actions.

  • Architecture Connection identity expanded to include ConnectionKind

    The PosCredentialDescriptor model and all related DTOs (PosCredentialRequest, PosCredentialSummaryDto, PosCredentialSecretDto) now include a ConnectionKind property that defaults to "POS" but can be set to "MMDatabase" for the Margin Master database connection. This field is part of the server-side identity, allowing both connection types to coexist per store and be restored independently.

  • Performance Eliminated database bottleneck causing multi-minute loads

    Opening a pricing strategy with hundreds of custom groups now takes seconds instead of several minutes.

  • Infrastructure Added comprehensive test coverage for filter skip logic
  • Infrastructure Added unit tests for exclusion filter skip logic

    Added comprehensive test coverage (ExcludeFilterSkipTests) to verify the asymmetric behavior between inclusion and exclusion filters when selection box values are absent, preventing future regressions of this pricing-critical logic.

  • Infrastructure Added comprehensive test coverage for PSRule filter scenarios

    Added 8 unit tests covering Include/Exclude behavior, resolution of both name and index formats, handling of unresolvable values (renamed or deactivated steps), SQL injection prevention through quote escaping, and special codes like "ME" and "GI". Tests verify against real customer database patterns where PSRule='439' returned 0 rows while PSRule='BenjaminMoore' returned 1,288 rows, confirming the mismatch.

  • Infrastructure Added test coverage for inactive step summary behavior

    New unit tests verify that inactive steps report correct timing, display the INACTIVE marker, and don't affect active step output. Tests prevent regression of the phantom-duration and missing-label issues.

  • Infrastructure Added unit tests for inactive step summary behavior

    New test coverage ensures inactive steps are closed immediately, report sub-second duration, display the INACTIVE marker, and that active steps do not incorrectly display the marker.

  • Infrastructure Store selection routing policy

    Implemented StoreRoutingFilterPolicy to correctly handle store selections in both processing modes. In multi-table mode, the store selection is consumed by routing to specific tables and must be removed from filters. In single-table mode, the selection must be preserved and passed to the WHERE clause to prevent single-store operations from affecting all stores. Includes comprehensive unit tests to guard against accidental cross-store pricing changes.

  • Infrastructure Configurable empty-state messages for selection boxes

    Added EmptyTitle and EmptySubtitle properties to SelectionBoxDetail, allowing individual selection boxes to override the default "No Items Found / Verify data has been imported" message with context-specific guidance appropriate to each box's purpose.

  • Infrastructure Improved heartbeat animation reliability during long operations

    The splash screen heartbeat now runs independently on the thread pool rather than competing with the operation it's meant to monitor, ensuring it continues to animate even when other initialization phases are processing.

  • Infrastructure Removed unreachable legacy migration code

    Removed MigratePricingStrategiesAsync and two helper methods (347 lines) that were never called from anywhere in the application. This code path read from tables that were never populated (the root cause of the empty backups) and contained a scheduled deletion of the live GlobalFileConfig strategy sections 30 days post-migration that would have destroyed every pricing strategy fleet-wide if it had ever executed.

Imports & POS

  • New Feature Automatic cloud backup of validated POS connections

    When you successfully test any POS connection in Settings, it's now automatically backed up to the cloud in the background. You won't notice any difference, but the connection will be available to restore later.

  • New Feature Automatic cloud backup of validated POS connections

    Your POS connection details are now automatically saved to the cloud every time you test a connection or import data—no extra steps required.

  • New Feature MySQL Connection Troubleshooter

    Click "Troubleshoot Connection" on the Epicor Options screen to run a full connection health check. The troubleshooter will check everything from network reachability to login credentials to link speed, show you exactly what passed or failed, and provide specific instructions for fixing each problem. Click "Copy Report" to paste the full results into a support ticket.

  • New Feature MySQL connection troubleshooter with diagnostic report

    When your MySQL connection won't work, click "Troubleshoot Connection" to see a detailed checklist showing exactly what's wrong (e.g., "✗ Connection path: Remote Desktop session detected" or "⚠ Link quality: High latency may cause import timeouts"). Each failed or warning check includes a specific fix. Click "Copy Report" to copy the full diagnostic to paste into a support ticket.

  • New Feature Modern MySQL driver with beta toggle

    A new "Use new MySQL connector (beta)" checkbox appears in Settings under Epicor MySQL Options. Check it, click Test & Save, and the app will use a newer database driver that may resolve connection problems. Uncheck it to return to the previous driver instantly.

  • New Feature Store number conversion setting

    A new setting lets you control whether POS store numbers are matched to vendor store numbers. When turned on, stores without a matching POS number will be automatically excluded from data imports.

  • New Feature FTP connection troubleshooter with diagnostic report

    When you test your Epicor FTP connection, you'll now see a detailed checklist showing exactly which steps passed or failed (DNS lookup, port open, login successful, etc.), with specific remedies for any problems. You can copy the entire report to send to support.

  • New Feature FTP connection troubleshooter

    Click "Troubleshoot Connection…" in the Epicor FTP panel to run a comprehensive connection test that shows exactly where a connection problem occurs—whether it's missing settings, a firewall blocking the port, wrong login credentials, or a slow network link.

  • New Feature Interactive new-store mapping during Epicor import

    When a new Epicor store is found during import, you'll see a prompt asking you to enter its Vendor Store Number. Enter the number to map it, or click Cancel to skip it for now. You can always edit store mappings later under Data → Store Manager.

  • New Feature Activity badge with full lifecycle
  • New Feature MI9 processing mode selection

    When using MI9, a new MI9 tab in Settings lets you switch between team-level pricing (where all stores in a team share the same prices) and store-level pricing (where each store can have different prices for the same item). The default remains team-level pricing.

  • New Feature Restore POS connections from cloud backup

    Each POS Settings screen now has a "Restore from Cloud…" button. Click it to see all previously saved connections for that POS type, pick one, and have all the connection details (including password) filled in automatically — perfect for reinstalls or setting up a second machine.

  • New Feature One-click connection restore from cloud

    Click "Restore from Cloud…" on any POS settings screen to see all your previously saved connections and restore one with a single click—perfect for reinstalls or setting up a new machine.

  • New Feature Network Topology Detection

    The troubleshooter automatically detects whether you're connecting over a VPN, Remote Desktop session, or across the internet, and warns you when these connection types are causing slow imports or timeouts. The most reliable fix is to run Margin Master on a PC on the same local network as your Eagle server.

  • New Feature Troubleshoot Connection button for Epicor FTP

    The new "Troubleshoot Connection" button lets you test your FTP settings and get a diagnostic report without saving any changes to your configuration.

  • New Feature Automatic import folder cleanup

    Your import folder will automatically clean up old files after 7 days, so you don't have to manually delete old exports and backups anymore.

  • New Feature Link Quality and Timeout Risk Assessment

    The troubleshooter measures your connection speed to the MySQL server and warns you if it's slow enough to cause import timeouts, with specific suggestions on how to fix it.

  • New Feature Network topology detection and VPN/remote session identification

    The troubleshooter now detects if you're connecting over a VPN or Remote Desktop session and warns that this often causes connection timeouts. It recommends running Margin Master on a PC on the same network as the Eagle server for best performance.

  • New Feature Refresh Stores button now works for all POS systems

    You can now click "Refresh Stores" in Store Manager to automatically find new stores from your imported data, regardless of which POS system you use.

  • New Feature Store number conversion setting for non-Epicor systems

    Added a new "Use POS Store to Vendor Store Number Conversion" option in Store Manager for RockSolid, BisTrack, and NCR Counterpoint systems. This setting controls whether POS store numbers are converted to vendor store numbers during import matchup. Epicor systems always use character ordinal conversion and do not display this option.

  • New Feature Troubleshoot Connection now verifies Eagle IN export file exists
  • New Feature Link quality assessment and timeout risk prediction

    The troubleshooter measures connection speed and warns when your link is slow enough to cause import timeouts, with specific advice (like enabling streaming import or running imports at night) to work around slow connections.

  • Improvement Complete store list display in Store Manager
  • Improvement Vendor store assignment for imported POS stores

    When a new store appears after importing POS data, you can now assign it to the correct vendor store number even if it's marked as excluded. Simply edit the Vendor # field to match it up.

  • Improvement Vendor assignment for excluded stores

    If a store is marked as excluded in the Store Manager, you can now still edit its Vendor Store # to match it with the correct vendor or fix an incorrect assignment.

  • Improvement Configurable Epicor bulk operation timeout

    Added a new application setting "EpicorBulkOperationTimeoutSeconds" (default 600 seconds) that allows support staff to adjust the timeout for Epicor bulk database operations without requiring a software rebuild. This matches existing timeout configuration available for Mi9 and MySQL Compass systems.

  • Improvement Automatic self-healing for missing store tables

    If a store's pricing data goes missing, Margin Master will automatically restore it the next time you start the application.

  • Improvement Consistent error handling across MySQL connection points

    By consolidating on the existing ILocalNetworkService.TestMySqlConnectionAsync() method, MySQL connection testing now behaves consistently whether triggered from the import workflow or the settings screen, improving reliability and maintainability.

  • Improvement Faster failure detection for unreachable MySQL servers

    If your Epicor MySQL/Compass server is unreachable, you'll know within 3 seconds instead of waiting through a long timeout.

  • Improvement Extend orphaned store cleanup to more import paths

    Applied the existing orphan-prune logic (originally built for CounterWorks in MM-1166) to Ace Hardware Falcon imports and other single-store POS systems processed through the Super import path. The cleanup now runs automatically when the system detects exactly one store numbered "0" in the imported data, preventing phantom store entries across more vendor and POS combinations.

  • Improvement Added automatic retry logic for transient database blocks

    The Epicor bulk insert operation now includes retry logic to handle temporary database locks that occur when multiple store tables are being created or updated during import. This prevents import failures due to momentary resource contention.

  • Improvement Enhanced logging for file import header validation failures

    Added detailed warning logs when import files are rejected due to header validation failures, including the specific file name, import definition name, and how many columns matched versus how many were required. This helps with troubleshooting import issues.

  • Improvement Optimized post-import index rebuilding

    The "Finalizing" step after adding catalog items now completes much faster.

  • Improvement Import errors now display in clear error dialogs

    When an import fails, you'll now see a clear error message that stays on screen until you close it, instead of a brief flash that disappears.

  • Improvement Prefer raw .txt over .csv for BisTrack/Ace store 1178

    Store 1178: When both .txt and .csv files are in your import folder, Margin Master will automatically use the .txt file and ignore the .csv to prevent duplicate imports.

  • Improvement Automatic import folder cleanup

    Old import files and backups older than 7 days are now automatically removed from your import folder to keep it tidy.

  • Improvement Enhanced network scanner with MySQL handshake verification

    The "Scan for MySQL Servers" button now shows which discovered servers are actually MySQL (with version number) and whether your username/password work on each one, making it easier to pick the correct server when multiple hosts respond.

  • Improvement Driver identification in diagnostics

    The MySQL troubleshooter report now shows which database driver is active, making it easier for support to diagnose connection issues.

  • Improvement Store Manager dialog accessible for non-Epicor POS systems

    BisTrack, Falcon, Mi9, and TransAct users can now use the improved Store Manager screen to manage store settings, matching the experience already available to Epicor users.

  • Improvement Auto-exclude unmatched stores

    Stores that can't receive POS data (because they have no matching POS store number) are now automatically marked as excluded, preventing import errors.

  • Improvement Auto-exclude unmatched stores from imports

    Stores without matching POS store numbers are now automatically excluded from imports since they cannot receive data.

  • Improvement Context-specific remediation guidance for MySQL login failures

    Authentication denied messages now distinguish between three scenarios: blank password field (directs user to enter the password in settings), rejected password (indicates incorrect password or host not allowed), and generic access denied (provides GRANT command syntax for MySQL administrators). Each message includes the relevant username and local IP address for troubleshooting.

  • Improvement Automatic retry for transient MySQL errors

    If a MySQL query briefly times out due to network congestion, the application will automatically retry it instead of immediately failing.

  • Improvement Clearer connection test error messages

    Error messages during FTP/SFTP connection tests now provide clearer guidance about toggling the "Use Secure FTP" setting based on which protocol failed, helping users diagnose configuration issues more quickly.

  • Improvement One-at-a-time pipeline guards
  • Improvement Resilient column mapping prevents future import failures
  • Improvement Import failures now show actual connection errors
  • Improvement Enhanced splash screen lifecycle logging

    Added detailed logging at critical points in the interactive pipeline (import and vendor update workflows) to track splash screen state during operations. Previously, successful operations logged nothing between closing dialogs and finishing, leaving a 57-second gap in store 2596's logs that made diagnosis impossible. The new logging brackets pipeline endings and records splash state, phase text, and elapsed time to quickly identify any future stall points.

  • Improvement Enhanced error handling for Mi9 mode switching

    If something goes wrong while changing Mi9 settings, you'll now see a clear error message instead of the application crashing.

  • Improvement Better error handling for MI9 mode changes

    If an error occurs while changing MI9 processing mode, you now see an error message instead of the application closing unexpectedly.

  • Improvement Self-healing for missing store tables

    If a store's pricing data becomes corrupted or missing, the system will automatically rebuild it at the next startup.

  • Improvement Do-it Best mailbox connection reporting

    The Do-it Best mailbox FTP connection now reports to the cloud backup system at the moment the actual FTP connection succeeds during data retrieval (in DIBMailboxService), in addition to the manual "Test Connection" button in Settings. This ensures real working mailbox connections are preserved even if the user never explicitly tests from the Settings screen.

  • Improvement Reduced notification noise for existing unmapped stores

    You'll only see the unmapped store warning once when a new store is first discovered, not every time you import data.

  • Improvement Standardized error handling for BisTrack and DIB imports

    BisTrack and Do-It-Best import errors now show helpful error messages explaining what went wrong and how to fix it.

  • Improvement Better error handling for BisTrack Direct Connect

    If BisTrack import fails, the error message now tells you exactly what went wrong and how to fix it.

  • Improvement Store Manager handles unmatched stores

    Stores that haven't been matched between your vendor catalog and POS system now appear in Store Manager so you can complete the setup.

  • Improvement MySQL timeout telemetry reporting

    The error classifier now explicitly recognizes and reports MySqlConnector command timeouts to telemetry, ensuring persistent slow-query issues reach the error dashboard. The Settings screen's Test & Save path escalates timeout failures from Warning to Error severity so they're visible in Manager telemetry, while other test failures (bad password, wrong host) remain warnings. This ensures actionable slow-link issues are remedied while keeping noise low.

  • Improvement Added intermediate status message during table rebuild phase

    You'll now see a message explaining that pricing tables are being rebuilt after store data is imported, instead of the screen appearing stuck.

  • Improvement Copyable diagnostic report

    After troubleshooting completes, you can copy the full diagnostic report (including all test results and error details) directly to your clipboard to send to support.

  • Improvement Enhanced store reconciliation logging

    The MySQL/Compass store reconciliation now logs whether new stores were mapped via the interactive prompt or inherited from an existing mapping, providing clearer audit information about how store matchups were established.

  • Improvement Better troubleshooting guidance for secure FTP settings

    When connection tests fail, you'll get clearer instructions on whether to enable or disable the "Use Secure FTP" setting.

  • Improvement Better error handling for DIB price file imports

    DIB price file import errors now show a complete error message that you can read and share with support.

  • Improvement Enhanced MySQL Network Scan

    When you scan your network for MySQL servers, the scan now checks multiple ports on each machine, confirms that discovered servers are actually running MySQL (not just any open port), tells you the MySQL version, and shows whether your username and password work on each server found.

  • Improvement MySQL troubleshoot report shows active driver

    The MySQL diagnostic report (accessed via Troubleshoot button or diagnostics menu) now includes a "Driver" line showing which MySQL provider is currently in use (e.g., "MySqlConnector 2.6.1" or "MySql.Data 6.10.9"), helping support confirm the toggle state when investigating connection issues.

  • Improvement BisTrack cloud restore workflow

    The "Restore from Cloud" button is now disabled until you enable Direct Connect, making the required order of steps clearer.

  • Improvement Adaptive polling frequency
  • Improvement FTP troubleshooter validation logic

    The "Test & Save Connection" button now performs a more thorough validation before marking your FTP connection as verified, while the new "Troubleshoot Connection" button lets you diagnose issues without affecting your saved settings.

  • Improvement Credential backup integrated into all POS connection flows

    Every time you test a connection or import data, your connection is automatically backed up—no manual save required.

  • Bug Fix Store selection missing valid stores after rebuild

    All active stores with inventory data will now appear in the store selection dropdown, even after rebuilding the pricing database.

  • Bug Fix Main tables now reconcile against Store Manager for Epicor configurations

    If you exclude a store in Store Manager, it will no longer appear in the Main Table grid after the next rebuild or when you restart Margin Master.

  • Bug Fix Fast-fail MySQL connection test with actionable guidance

    If your Epicor MySQL connection fails, you'll now see a clear message explaining what to check (IP address, MySQL service status, or firewall settings) within a few seconds, making it much easier to troubleshoot connection problems.

  • Bug Fix Clearer MySQL connection error messages during import

    When the system can't connect to your Epicor MySQL/Compass database during import, you'll now get a quick response with clear instructions on what to check (IP address, server status, or firewall settings) instead of waiting through a long timeout.

  • Bug Fix Store Number dropdown displays extended Epicor store designations correctly

    If your store uses Epicor and has a special character designation (like ‡ or ™), it will now show up correctly in the Store Number dropdown instead of appearing blank.

  • Bug Fix Store Number box now displays extended Epicor designation characters

    If your store uses special symbols like ‡, ™, or • in Epicor designations, these will now show up correctly in the Store Number box instead of appearing blank.

  • Bug Fix Remove stale warehouse data during Falcon imports

    If your store previously had multiple warehouses but now operates as a single location on Falcon, old warehouse entries will no longer appear in your pricing grid.

  • Bug Fix Increased timeout for Epicor bulk insert operations

    Epicor imports that previously failed with timeout errors will now complete successfully, even when multiple stores are syncing data at the same time.

  • Bug Fix Extended timeout for Epicor bulk data operations

    Increased the batch timeout from default to 10 minutes (600 seconds) and disabled temporary table clustering to improve performance during large Epicor imports. Added automatic retry logic to handle transient database connection issues during the bulk insert process.

  • Bug Fix Prime Vendor and Fineline now populate for Falcon Ace customers
  • Bug Fix Falcon Prime Vendor and Fineline auto-population

    When using Falcon POS, the Prime Vendor and Fineline filter dropdowns in the pricing grid now populate automatically from Ace catalog data, making it easier to filter and analyze your inventory.

  • Bug Fix Propello import now shows error dialog instead of failing silently

    If you accidentally export the wrong report from Propello, you'll now see an error message telling you exactly what's wrong and how to fix it (export the full inventory report with all columns), instead of seeing nothing happen.

  • Bug Fix Propello import failures now show actionable error dialogs

    When a Propello spreadsheet doesn't import correctly, you'll now see a dialog box that stays on screen explaining exactly what's wrong and how to fix it by running the full inventory export from Propello with all columns included.

  • Bug Fix Auto-exclude unmapped Epicor stores at discovery

    New Epicor stores without vendor assignments are now clearly marked as excluded in the store list, making it easier to see which stores need configuration.

  • Bug Fix Eliminated index thrashing during catalog imports

    Catalog imports that appeared frozen at "Finalizing" will now complete normally, especially on stores with many locations or large product databases.

  • Bug Fix Import errors now show persistent error dialogs

    When a data import fails, you'll now see a clear error message dialog instead of text that briefly flashes and disappears in the splash screen.

  • Bug Fix NCR Counterpoint imports now automatically rebuild main tables

    After importing from NCR Counterpoint, your pricing data now appears immediately in the main grid without needing to click the Rebuild button.

  • Bug Fix BisTrack raw .txt export files now import directly

    If you use BisTrack, you can now import the raw .txt file that BisTrack generates without opening it in Excel first. This prevents Excel from corrupting your data by removing trailing zeros or turning SKU numbers into scientific notation.

  • Bug Fix Import raw BisTrack .txt files without Excel conversion

    You can now drop the raw BisTrack export file (.txt) directly into the import folder without opening it in Excel first. The system will automatically use the .txt file and ignore any old .csv versions.

  • Bug Fix Store number matchup edits now save correctly

    Store number, zone, and RSC changes are now saved correctly when you edit them through the Settings menu.

  • Bug Fix Store Manager displays complete store list for non-Epicor systems

    If you use BisTrack, Falcon, Transact, or similar POS systems, the Store Manager will now show your complete store list instead of only one or two stores.

  • Bug Fix Repair corrupted POS store numbers in StoreManagerInfo

    If you have multiple store locations, the system will now correctly match each store to its pricing data, fixing problems where updates wouldn't apply to the right stores.

  • Bug Fix Repaired POS store numbers corrupted by legacy migration

    Store numbers now display correctly in Store Manager for RockSolid, BisTrack, and NCR Counterpoint systems.

  • Bug Fix MySQL authentication errors now identify root cause

    The MySQL connection test now tells you exactly what's wrong: "Password field is blank" if you forgot to enter a password, or "password was rejected" if the password is incorrect or your PC isn't allowed to connect.

  • Bug Fix MySQL command timeout enforcement on slow connections

    When testing your MySQL Compass connection in Settings or running an import over a slow network, queries will now be given enough time to complete instead of failing after 30 seconds.

  • Bug Fix Import splash screen remains responsive during Epicor MySQL imports

    The import progress screen now updates smoothly during Epicor imports instead of freezing on a stale frame.

  • Bug Fix Prompt to remove excluded store data tables

    When a MySQL Epicor store was imported and then later excluded in Store Manager or had its vendor store number cleared, its data table remained in the database. These orphaned tables never appeared in the Data Aging view but still fed store selection dropdowns, creating confusing phantom store entries. After each import rebuild, Margin Master now detects these leftover tables and prompts whether to remove each one. Clicking "Yes" drops the table and cleans up its related index and import history records; "No" leaves it untouched; "Cancel" stops prompting. This prompt never appears in automated/headless mode—removal requires explicit user confirmation.

  • Bug Fix Prompt to clean up excluded store data tables

    If you exclude a store in Store Manager, Margin Master will now ask if you want to remove its old pricing data. Click "Yes" to clean it up and prevent the store from showing in your store lists. Click "No" to keep the data (you'll be asked again next import). Click "Cancel" to stop being asked about any remaining excluded stores.

  • Bug Fix Connection test now matches actual import protocol

    If your store uses Epicor with "Use Secure FTP" enabled (most common for port 22), connection tests will no longer incorrectly report failures or take a minute to timeout.

  • Bug Fix Connection test protocol mismatch resolved

    When testing your Epicor FTP connection in Settings with "Use Secure FTP" checked, the test will now work properly instead of timing out or showing false errors.

  • Bug Fix Propello import now handles Do it Best export format changes
  • Bug Fix Propello DIB import now handles renamed classification columns

    If your Do-It-Best Propello import recently stopped bringing in data, it will now work correctly. The system automatically detects whether you're using an old or new export file format.

  • Bug Fix Epicor INFILE import now uses correct FTP server address
  • Bug Fix Loading splash screen no longer freezes after imports

    If you were experiencing freezes where the loading screen got stuck on "Finalizing…" and wouldn't go away, forcing you to close Margin Master from Task Manager, this is now fixed. The loading screen will automatically close even if something goes wrong internally.

  • Bug Fix Paladin 'None' location normalized to blank

    Items imported from Paladin that show 'None' as their location are now treated as having no location, so pricing rules that exclude or include items with blank locations will work correctly.

  • Bug Fix Paladin 'None' location now treated as no-location marker

    Items showing "None" as their location in Paladin will now be properly treated as having no location, so rules that exclude blank locations will work correctly.

  • Bug Fix Mi9 Options tab crash when applying processing mode

    The Settings screen will no longer crash when you change Mi9 processing mode options.

  • Bug Fix MI9 Options tab crash when applying processing mode

    Changing between MI9 single-table and multi-table modes in Settings no longer crashes the application.

  • Bug Fix Automatic cleanup of orphaned store tables

    Excluded or removed stores no longer leave behind empty data tables, keeping the database clean and improving startup performance.

  • Bug Fix NCR Counterpoint imports now rebuild the main pricing grid

    After importing NCR Counterpoint data, the main pricing grid now automatically updates with the new data — you no longer need to manually rebuild tables to see your imported items.

  • Bug Fix Zone pricing lookup corrected for non-Epicor stores

    Zone pricing now correctly applies each store's specific zone instead of defaulting to the first zone found.

  • Bug Fix Zone assignment lookup now uses correct store identifier
  • Bug Fix Chunked database writes prevent import failures

    Epicor imports will complete successfully more often, especially during busy times when the database is under heavy load.

  • Bug Fix Improved numeric field handling for Propello imports

    Propello imports are now more reliable when price or quantity fields contain unexpected values—the system will use zero for any field it can't read rather than skipping the entire product.

  • Bug Fix Strategy location filters display BLANK option when needed

    Pricing strategies that filter by blank locations will now load and apply correctly even if blank locations aren't currently visible in the location list.

  • Bug Fix Strategy filter honors 'BLANK' sentinel even when not in selection list

    Pricing strategies that reference "BLANK" values will now work reliably, even when no blank items were previously visible in the selection list.

  • Bug Fix Store Manager dialog opening from Settings

    The "Open Store Manager" button in POS Settings now works reliably. Clicking it closes the Settings window and opens Store Manager from the main screen.

  • Bug Fix Activity badge now appears when feature enabled mid-session
  • Bug Fix Eliminated redundant splash screen re-display during finalization

    Removed unnecessary splash screen re-activation during the post-import processing phase. When ImportPOSData called ProcessStepsAfterPopulateMainDataset with an empty queue, it would re-show the splash purely to display "Finalizing…" with no actual work to do. The method now returns early when there are no pending steps, preventing the display of an empty progress indicator while still maintaining the contract that all eight callers can rely on the splash being closed upon return.

  • Bug Fix Fixed Store Manager dialog launch from Options screens

    Opening Store Manager from POS Options screens now works reliably.

  • Bug Fix Import block query timeout defaults

    Import operations will no longer hang indefinitely if a MySQL query encounters an issue—they'll timeout after 10 minutes and report the problem.

  • Bug Fix Persist settings before troubleshooting to diagnose actual configuration

    The troubleshooter now calls PersistSettingsAsync() before running checks, ensuring it diagnoses exactly what the user entered on-screen rather than stale saved settings, matching the Test & Save behavior where settings are saved before the test runs.

  • Cloud Sync Auto-populate stores during vendor sync

    After syncing vendor pricing, your store list is automatically updated with all stores from your organization account.

  • Cloud Sync Automatic store seeding during vendor sync
  • Cloud Sync Manager API integration for POS credential storage

    Implemented three new Manager API endpoints in ApiClientService: POST /api/pos/credentials (submit), GET /api/pos/credentials/{storeNumber} (list), and GET /api/pos/credentials/{id}/secret (fetch with password). The submit endpoint is called fire-and-forget after every successful POS connect; the list and secret endpoints are called on-demand during restore. All credential transport uses new DTOs (PosCredentialRequest, PosCredentialSubmitResponse, PosCredentialSummaryDto, PosCredentialSecretDto) defined in PosCredentialModels.cs. Passwords and extras are encrypted at rest server-side; descriptor fields (server, database, username, auth mode) are stored plain for listing/filtering.

  • Data Import New-store vendor mapping prompt during Epicor import

    When Margin Master finds a new Epicor store during import, you'll see a prompt asking for its Vendor Store Number. Enter the number to include it next time, or press Cancel to skip it for now. You can always change this later under Data → Store Manager.

  • Data Import Improved error handling for Epicor data uploads

    Wrapped the bulk insert operation with transient retry logic to automatically recover from temporary database connectivity issues, making the Epicor import process more resilient.

  • Data Import File import validation failures now logged to application log

    All import definitions (not just Propello) now write a warning to the application log when header validation fails, recording the file name, import definition name, number of matched columns, and required column count. This ensures every validation failure is recorded for troubleshooting, even if the UI feedback is missing.

  • Data Import Auto-add POS stores during import

    When you import POS data, any new store numbers are automatically added to your store list.

  • Data Import Import Manager now cleans up before building store selection lists

    The cleanup prompt runs immediately after rebuilding per-store main tables and before populating store selection dropdowns, ensuring excluded stores never appear as selectable options in the Import Manager or other screens.

  • Data Import Clean up import history for removed stores

    When an orphan store table is removed after user confirmation, the system now also cleans up related records in the ImportProcessing table (Data Aging view) and the ManagedIndexes registry. This ensures a complete cleanup with no stale metadata left behind.

  • Data Import Provider-agnostic MySQL error handling

    Introduced MySqlErrorHelper to inspect MySQL error codes from either driver's MySqlException type, replacing direct casts that would fail during migration. All connectivity retry logic, transient error detection, and diagnostic failure analysis now work regardless of which driver is active. Added MySqlConnectionFactory and MySqlErrorHelper unit tests to verify toggle behavior and error-code extraction.

  • Data Import Improved Epicor import resilience

    Both the standard insert and streaming merge operations in the Epicor FTP import process now benefit from the configurable timeout and chunked write improvements, making the entire import pipeline more robust against database performance issues.

  • Data Import Auto-mapped stores now marked as included

    When the Epicor import auto-maps a new store (single-store case or inherited from binary ordinal), it now clears the Excluded flag and persists the matchup to GlobalFileConfig immediately, ensuring RefreshStoreModels and the Store Manager UI resolve the mapping. Previously, some auto-mapped stores remained marked excluded until manually edited.

  • Data Import Column definition expanded for new Propello DIB format

    Added Category Code, Sub Category, Sub Category Code, Product Group, and Product Group Code to the Propello DIB staging definition. The staging table now captures all columns from both old and new DIB exports, though the finest Product Group tier is not yet mapped to a main-table field.

  • Data Import Regression tests added for blank location handling

    Added automated tests to verify that the BLANK location sentinel is properly recognized and handled in selection filters, preventing future regressions of this issue.

  • Data Import Automatic POS store detection during import
  • User Interface ECI VPN requirement documentation

    The documentation explains why connection attempts might fail even with correct credentials—the VPN tunnel must be active first. It clarifies that file-based imports (like RockSolid MAX Data.txt files) do not require the VPN, only direct database connections do.

  • User Interface New documentation page for ECI VPN requirement

    Added a help page that explains the VPN requirement and walks you through what your IT team needs to set up the connection to ECI.

  • User Interface Added "Open Store Manager" button to additional POS tabs
  • User Interface Updated Spruce and RockSolid MAX import documentation

    Import guides now clearly explain when you need the VPN tunnel and when you don't.

  • User Interface PS Rule filter box now shows helpful hint when empty
  • User Interface PS Rule filter empty-state hint

    The PS Rule filter now shows a helpful message reminding you to run a pricing strategy first, instead of appearing blank and confusing.

  • User Interface Clarified "New Stores Found" notification

    The warning about new Epicor stores now explains more clearly that their data wasn't imported and won't appear repeatedly on future imports.

  • User Interface Settings checkbox for driver selection

    Added "Use new MySQL connector (beta)" checkbox to the Epicor settings tab with a tooltip explaining it switches between the modern MySqlConnector and legacy MySql.Data driver. The active driver is shown in the MySQL diagnostic/troubleshoot report under "Driver".

  • User Interface Store Manager matching workflow clarification

    Added a new CanEditMatchup property that controls editability based only on hard states (deleted/not-found), separate from the general CanEdit property that also considers exclusion status. This ensures vendor store assignments can always be corrected when needed while maintaining appropriate restrictions for deleted or invalid stores.

  • User Interface Updated Store Manager grid permissions

    Added a new CanEditMatchup permission that controls editability of the Vendor Store # field independently from the general CanEdit permission. This allows vendor re-matching operations even on excluded stores while maintaining appropriate read-only protection for deleted and not-found stores.

  • User Interface Fixed progress bar alignment on splash screen

    The progress bar on the import screen is now properly aligned below its status message.

  • User Interface Diagnostic progress overlay

    When testing or troubleshooting the FTP connection, you'll see a progress indicator showing which step is running and how far along the test is.

  • User Interface Simplified Epicor settings screen

    The Epicor settings screen is now simpler with one less option to configure, since all Epicor servers use the same type.

  • User Interface Explicit apply button with destructive-action confirmation

    Switching processing modes rebuilds your main tables from scratch and may take several minutes. The system warns you exactly which tables will be removed and reminds you that you'll need to re-run your pricing strategies afterward. A progress bar shows the rebuild status.

  • User Interface New restore connection picker dialog

    A new dialog shows all your saved cloud connections in a list—select one and click Restore to fill in your connection settings automatically.

  • User Interface Progress overlay during FTP connection testing

    When testing your FTP connection, you'll now see a progress bar and status messages showing exactly which check is currently running.

  • User Interface Never auto-remove store data in headless mode

    In automated fix-pipeline (headless) scenarios, the system will log detected orphan tables but skip the removal prompt entirely. This safety guard ensures store data is never automatically deleted without explicit human confirmation.

  • User Interface Server Type option hidden on Epicor settings

    The "Server Type" selector (SCO/Linux) has been hidden from the Epicor settings screen since all stores use Linux servers. The underlying code remains functional and defaults to Linux.

  • User Interface Conditional tab visibility

    The MI9 tab appears only when the POS type is set to MI9 in Store Information and disappears when switching to a different POS system. The tab is registered in all six required wiring points: dependency injection, ViewModel initialization, tab visibility map, XAML DataTemplate, view code-behind, and the UpdatePosTabVisibilityAsync live-switching logic.

  • User Interface Improved new-store exclusion messaging

    The INFILE import's auto-exclusion warning now directs operators to "Data → Store Manager" instead of the older "Manage Epicor POS/Vendor Store Info" button reference, and the splash screen is hidden before showing the new-store prompt so modal dialogs are never covered.

  • User Interface Diagnostic Report Display

    After running the troubleshooter, you'll see a checklist of every connection check with clear pass/warning/error icons and specific instructions for fixing any problems. Click "Copy Report" to copy the entire diagnostic to your clipboard for pasting into emails or support tickets.

  • User Interface Diagnostic checklist display in Epicor settings

    Added a collapsible "Connection Diagnostics" section to the Epicor settings tab that appears after running the troubleshooter, displaying an overall verdict line (color-coded green for pass, orange for warnings, red for failures) followed by an ItemsControl-bound checklist of diagnostic steps, each with a status glyph, step name, detail message, and (when relevant) a remedy in italic orange text. The section includes a "Copy Report" button to copy the plain-text diagnostic to the clipboard.

  • User Interface Improved Store Manager column header styling

    Fixed Zone Override column header styling in Store Manager to match other columns with centered, semi-bold text. The column header dynamically changes to "Group Zone #" when Store Grouping is enabled.

  • User Interface Non-modal status window
  • User Interface Progress overlay enhancements for long-running operations

    Enhanced the Epicor settings testing overlay to support both indeterminate (spinning) and determinate (percentage-based) progress modes with configurable overlay titles, switching to percentage progress during network scans and the troubleshooter to show scan completion (e.g., "Scanned 147/254 hosts..."). The ProgressPercent and ProgressIsIndeterminate properties are bound to a single ProgressBar that adapts its mode.

  • Database Automatic one-time repair on startup

    Added RepairGenericPosOrdinalCorruptionAsync that runs during Store Manager initialization for non-Epicor databases. The repair is idempotent (safe to run multiple times) and only updates rows that still contain corrupted ordinal values, restoring the PosStoreNumber field from the PosStoreCharOrdinal field and clearing the ordinal.

  • Database Durable Epicor store discovery audit trail

    A new append-only EpicorStoreImportHistory table records every Epicor POS store encountered on each import run (known, unknown, mapped, and excluded) with SKU/record counts, timestamps, and source (MySQL or INFILE). This permanent audit trail ensures an unknown store that appeared on a specific date is never lost after daily log files roll off, unlike the previous ImportProcessing table that was wiped every import.

  • Database Durable store-discovery audit trail

    A new EpicorStoreImportHistory table records every Epicor store encountered on each import run (MySQL and INFILE), capturing the import date, source, POS store character, vendor mapping, SKU/record count, and whether the store was already known and whether it was excluded. Unlike the daily log files or the ImportProcessing table, this append-only audit trail is never truncated, providing a permanent record of when each store first appeared and how it was handled.

  • Database Added ImportFolderCleanup setting key

    Added a new ApplicationSettingKey to track the last time import folder cleanup ran, ensuring the cleanup operation executes at most once per day.

  • Database New setting key for import folder cleanup tracking

    Added ApplicationSettingKey.ImportFolderCleanup to track when the last cleanup operation ran, ensuring it executes at most once per day.

  • Database Store list maintained proactively

    The StoreManagerInfo table now serves as the authoritative, always-current source for per-store configuration. Previously, this table was only populated when the user opened the Store Manager dialog. With this change, it's maintained automatically in the background, preparing the foundation for upcoming store-specific pricing and analysis features.

  • Database Diagnostic report model with structured steps

    Created MySqlDiagnosticReport, MySqlDiagnosticStep, MySqlDiagnosticRequest, and DiagnosticStatus classes to model the troubleshooter's structured output, with the overall status calculated as the worst outcome across all steps (Fail > Warn > Pass > Skipped) and a ToPlainText() method that renders a paste-ready support report with headers (store number, machine name, app version, endpoint) and step-by-step results with timing and remedies.

  • Architecture Centralized Store Manager launch logic
  • Architecture Shared store rebuild logic for consistency

    Extracted per-store main table build logic (drop, recreate, insert, AceDirectSkus conversion, MAP pricing) into a reusable BuildSingleAceMainTableAsync method, ensuring both the full rebuild process and the new self-healing reconciliation use identical logic.

  • Architecture Provider-agnostic MySQL connection layer

    All MySQL connection creation (~20 call sites across 8 services) now routes through a single IMySqlConnectionFactory that returns DbConnection instead of MySqlConnection, allowing both drivers to be used interchangeably. Added MySqlErrorHelper to normalize error code extraction across both providers' MySqlException types, used in EpicorStoreNumberService and LocalNetworkService for connectivity failure detection.

  • Architecture Shared store table management

    Created a new StoreManagerInfoWriter service that ensures the StoreManagerInfo table schema is consistent across all code paths (sync, import, and dialog). All automatic updates use idempotent, backfill-only logic that never overwrites values the user has already configured. This prevents data loss while keeping the store list current.

  • Architecture Extracted single-store rebuild logic

    Refactored the per-store main table build process into a shared BuildSingleAceMainTableAsync method that is used by both the full rebuild loop and the new reconciliation self-heal logic, reducing code duplication and ensuring consistency.

  • Architecture Stable POS connection identity via descriptor factories

    A new PosCredentialDescriptor model with POS-type-specific factory methods (ForEpicorMySql, ForEpicorFtp, ForSpruceRockSolid, ForSqlServerPos, ForDoItBestMailbox) ensures the server-side connection identity (PosSystemType + ServerName + DatabaseName + Username + AuthMode) never drifts between submit and restore paths. POS-type-specific extras (e.g., MySQL port, FTP "UseSecureFtp" flag) are serialized to JSON and round-trip but are not part of the identity. This eliminates duplicate connections and ensures restored credentials map back to the correct settings fields.

  • Architecture Generalized connection diagnostic report model

    Refactored MySqlDiagnosticReport and MySqlDiagnosticStep to ConnectionDiagnosticReport and ConnectionDiagnosticStep with parameterized provider-specific strings (SubjectNoun, ReportHeading), allowing the same diagnostic infrastructure to serve both MySQL and FTP troubleshooters. All existing MySQL diagnostic tests pass unchanged, confirming byte-identical output for the MySQL path.

  • Architecture Unified connection diagnostic framework

    Refactored the MySQL connection diagnostic models (`MySqlDiagnosticReport` and `MySqlDiagnosticStep`) into provider-neutral classes (`ConnectionDiagnosticReport` and `ConnectionDiagnosticStep`) with configurable labels, allowing both MySQL/Compass and FTP troubleshooters to share the same diagnostic engine, report formatting, and UI patterns. Added `FtpDiagnosticRequest` to mirror the MySQL request model.

  • Architecture Centralized POS credential descriptor mapping

    Introduced PosCredentialDescriptor, a canonical model that encapsulates the POS-type-specific connection identity (PosSystemType + ServerName + DatabaseName + Username + AuthMode) and extra fields (e.g., MySQL port, FTP SSL flag). Static factory methods (ForEpicorMySql, ForEpicorFtp, ForSpruceRockSolid, ForSqlServerPos, ForDoItBestMailbox) enforce stable, one-way mapping from each POS configuration to the server's identity schema, ensuring submit and restore always produce matching descriptors. ExtrasJson is a compact JSON blob for POS-specific fields that round-trip but are not part of the identity (e.g., port, auth plugin, connection number).

  • Infrastructure Modern MySQL driver option

    A new checkbox in Settings > Epicor tab labeled "Use new MySQL connector (beta)" lets stores switch to a more modern MySQL driver. After enabling and saving settings, the Troubleshoot report will confirm which driver is active.

  • Infrastructure Added automated tests for MySQL authentication diagnostics

    Added comprehensive test coverage for all three authentication failure scenarios, including verification that the password marker detection is case-insensitive and handles various error message formats from the MySQL driver.

  • Infrastructure Compatibility validation via unit tests

    Added 13 new unit tests (MySqlConnectionFactoryTests and MySqlErrorHelperTests) verifying the toggle correctly selects the intended driver, MySqlConnector accepts production connection strings (including "Convert Zero Datetime", SslMode=None, AllowPublicKeyRetrieval), and error-handling helpers work across both providers. Full test suite (186 tests) passes with zero build warnings.

  • Infrastructure Improved diagnostic logging for Epicor connections
  • Infrastructure Fixed test suite compatibility with git worktrees

    Corrected ContractTestHelpers.RepoRoot detection to recognize git worktrees, where .git is a file rather than a directory. This previously caused the entire ViewModelContracts test suite (24 tests) to fail with "Repo root not found" when running from worktrees, which the standard fix-issue workflow uses. All contract tests now pass successfully from both normal clones and worktrees.

  • Infrastructure PosCredentialService and restore coordinator

    Added PosCredentialService (IPosCredentialService), which orchestrates fire-and-forget backup via ReportConnectionAsync and on-demand list/fetch via ListAsync/GetSecretAsync. ReportActivePosConnectionAsync builds the descriptor from the active POS type's persisted settings (useful after successful import). Added PosConnectionRestoreCoordinator (IPosConnectionRestoreCoordinator), which drives the UX: fetches the list, shows the picker window, handles user selection, and returns the full secret DTO or null on cancel. Both services are registered as singletons in ServiceExtension.cs.

  • Infrastructure Pure Network Topology Helpers and Unit Tests

    Extracted network classification logic into pure, testable helper classes: NetworkSubnetHelper (for subnet relation classification and VPN adapter detection) and MySqlDiagnosticReport (for report aggregation and plain-text rendering). Added 25 new unit tests covering subnet classification, RFC-1918 private IP detection, VPN adapter heuristics, diagnostic status roll-up, and report formatting. All tests pass.

  • Infrastructure Network topology helper utilities

    Implemented NetworkSubnetHelper with unit-testable, pure-function methods for classifying server-to-local-machine subnet relationships (same /24, different subnet, public IP), RFC-1918 private address detection, and VPN adapter identification via name/description keyword matching, avoiding live network calls so the classification logic is fully testable. Added comprehensive unit tests covering subnet classification, private IP ranges, and VPN detection heuristics.

  • Infrastructure Extended MySQL scan result model

    Enhanced MySqlServerScanResult to include Port, IsMySqlConfirmed (handshake success), ServerVersion (reported by the server), and ConnectedWithCredentials (authentication success) fields, with an enriched DisplayText that shows "MySQL 8.0.34 · ✓ credentials" or "port open (no MySQL handshake)" to clarify scan findings.

Cloud Sync & Vendor Data

  • New Feature Store upsert capability

    Added infrastructure to create or update store records directly through the API. The new AddOrUpdateStoreAsync method can insert new stores (when StoreId is null or 0) or update existing stores (when StoreId is provided). The system automatically invalidates cached store data after updates to ensure the next sync reflects changes. Includes detection for store number conflicts when a store belongs to another organization (returns a "Claimed" flag).

  • Improvement Enhanced Do it Best mailbox timeout error messages

    If the Do it Best mailbox times out (usually due to a firewall), you'll see a detailed message explaining exactly what your IT person needs to allow in the firewall, including the host name, port number, and connection type.

  • Improvement Enhanced logging for proxy sync retry attempts

    When a transient failure occurs, the system now logs the specific reason (HTTP status code or exception type), attempt number, and retry delay to help diagnose intermittent sync issues for stores routing through the HTTPS proxy.

  • Improvement Clear firewall error messages in Do it Best Mailbox Manager

    You'll now see a helpful message explaining when your firewall is blocking the Do it Best mailbox connection, and you can still work with files you've already downloaded.

  • Improvement Add splash screen phase logging

    Added breadcrumb logging that records each splash screen phase transition (e.g., "Loading data", "Finalizing") to help diagnose future hang reports. When a customer reports being "stuck at X", the log file will now show exactly which phase was active, making issues pinpointable without requiring reproduction.

  • Improvement Add splash screen phase logging for diagnostics

    Each splash screen status change is now logged as a breadcrumb, making it easier to identify where the application stalled if a hang is reported. The log will show the last splash screen phase reached, helping support diagnose "stuck at" issues without flooding logs with repetitive entries.

  • Improvement Enhanced splash screen reliability with automatic recovery

    Added a safety mechanism that monitors the splash screen every second and automatically closes it if it becomes stranded over the main window. This "reaper" provides a last line of defense against splash screen issues, with a 5-second grace period to avoid interfering with legitimate operations. All splash screen operations are now verified complete before continuing.

  • Improvement Escalation mechanism drops input block after repeated close failures

    Even if the splash screen still can't close after multiple attempts, Margin Master will now allow you to continue working rather than completely freezing.

  • Improvement Backward compatibility with older saved filters

    Maintained compatibility with filter selections saved in previous versions of Margin Master by checking both the new value-based format and the legacy text-based format during restoration.

  • Improvement Better error handling for manager initialization failures

    Added explicit error handling and logging when the DIB Mailbox Manager fails to open. If initialization fails for any reason, the app now logs the error, hides the splash screen, and displays a clear error message instead of leaving the splash screen orphaned. This prevents the app from appearing frozen if future issues arise.

  • Improvement Protected critical dialogs from splash screen conflicts

    Routed all modal dialogs through a new protected pipeline that guarantees the splash screen is closed before opening. This includes the cloud sync error dialog, excluded store prompts, OLEDB warnings, auto-update notifications, and data aging screens. Each protected modal logs breadcrumbs for diagnostics.

  • Improvement Local DIB files still shown after mailbox connection failure

    If the mailbox can't be reached, you can still see and process any DIB files that were already downloaded to your computer.

  • Bug Fix Do it Best Mailbox Manager no longer freezes when firewall blocks FTP

    If your firewall blocks the Do it Best FTP connection, the Mailbox Manager window will now stay responsive and show you a clear message instead of freezing for several minutes.

  • Bug Fix DIB mailbox window no longer freezes during blocked FTPS connections

    When your firewall blocks the DIB mailbox connection, the window now responds within 45 seconds instead of freezing for several minutes. The progress animation keeps running so you know the app hasn't crashed.

  • Bug Fix DIB Mailbox Manager window opens correctly

    When you click Data > Manage Mailbox Data, the DIB Mailbox Manager window now opens immediately instead of hanging on a loading screen.

  • Bug Fix DIB Mailbox Manager constructor compatibility restored

    The Do-It-Best Mailbox Manager window now opens properly when selected from the menu.

  • Bug Fix Splash screen no longer blocks modal dialogs after vendor data updates
  • Bug Fix Remove phantom "99999" vendor store number entries

    If you previously saw a store numbered "99999" in the Store Manager grid, it will be automatically removed the next time you open Margin Master.

  • Bug Fix Splash screen now correctly dismisses after vendor sync

    When updating vendor data, the "Finalizing…" message will now properly disappear when the update completes, instead of occasionally staying on screen and blocking your work.

  • Bug Fix Prevent splash screen from covering catalog add dialogs

    When adding SKUs from the Do-It-Best catalog, the loading screen will now properly close before showing completion messages, so you won't get stuck with a frozen "Finalizing" message.

  • Bug Fix Prevent splash screen from covering dialogs during catalog addition

    When adding Do-It-Best catalog items, confirmation messages will now always appear on top of the screen instead of being hidden behind the progress screen.

  • Bug Fix Splash screen no longer blocks dialogs during sync operations

    The app will no longer freeze on "Finalizing…" during catalog updates. All dialogs and message boxes now open properly even during long sync operations.

  • Bug Fix Splash screen watchdog now stays armed until close is verified

    If the splash screen failed to close properly (due to timing issues during sync or import operations), Margin Master would appear frozen with the splash stuck on screen. The app now automatically detects and retries failed closes until the splash is successfully removed.

  • Bug Fix Filter restoration now matches both display text and item values

    When you save filters for specific stores or Ace Hardware categories and restart Margin Master, those selections will now reappear correctly in the filter boxes instead of being silently dropped.

  • Bug Fix Prevented instant sync failure during server maintenance windows

    Stores that sync through the HTTPS proxy will no longer see entire vendor syncs fail due to brief server maintenance or connection drops.

  • Bug Fix Mailbox connections now load on manager startup

    The DIB Mailbox Manager now shows your mailbox files immediately when opened, instead of showing "No Mailboxes found."

  • Bug Fix Child view models now properly initialized

    Mailbox connections now load correctly when opening the manager, and the Options toggle button works without errors.

  • Bug Fix Hardened Pricing Strategy dialogs against splash screen conflicts
  • Bug Fix Added automatic splash screen recovery mechanism

    If the splash screen ever gets stuck for any reason, it will now automatically clear itself within one second.

  • Bug Fix Prevented user cancellation from triggering false retries

    The retry logic correctly distinguishes between genuine transient failures (worth retrying) and intentional user cancellation (not retryable), ensuring that clicking Cancel during sync stops immediately without unnecessary retry attempts.

  • Bug Fix Improved error handling for loading failures

    If the mailbox manager fails to load, you'll now see a clear error message instead of the window appearing frozen.

  • Bug Fix Corrected typo in error logging

    Fixed a typo in catalog error logging that previously read "Add Items To Catalag" instead of "Add Items To Catalog".

  • Bug Fix Typo correction in error logging

    Fixed a typo in error log message from "Add Items To Catalag" to "Add Items To Catalog".

  • Bug Fix Splash heartbeat can always re-arm after unexpected termination

    Previously, if the background monitoring task crashed, no future splash screens would be monitored for hangs. This is now automatically recovered.

  • Bug Fix Removed plaintext password logging from Do it Best mailbox operations

    Removed two log lines that were writing Do it Best mailbox passwords in plaintext, improving security and compliance with credential handling best practices.

  • Bug Fix Data aging screen now opens after cloud sync completes

    The data aging screen now appears properly after cloud sync finishes, without hanging the application.

  • Bug Fix Resume splash operation now guards against re-showing an open splash

    When resuming a splash screen after closing a dialog or message box, certain timing conditions could leave the splash unmonitored and prone to hanging.

  • Bug Fix Splash status timer now renders correctly during long operations

    The "still working" timer that shows elapsed time during long sync or import operations now displays correctly instead of appearing frozen.

  • Cloud Sync Automatic retry with backoff for HTTPS proxy connections

    If a network hiccup or brief server restart occurs during sync, Margin Master will now automatically retry the connection up to 3 times before reporting an error, reducing spurious sync failures.

  • Cloud Sync Automatic retry logic for proxy HTTP requests

    If Cloud Sync encounters a temporary network problem while syncing, it will automatically try again a few times before giving up, making sync more reliable during brief connection issues.

  • Cloud Sync Single-call organization store fetch

    When syncing store data, Margin Master now attempts to retrieve all stores for an organization in one API call instead of fetching each store individually. This reduces network overhead and improves sync speed, especially for organizations with many stores. The system automatically falls back to the legacy per-store method if the new endpoint is unavailable, ensuring backward compatibility.

  • Cloud Sync Fail-fast behavior when Manager API is unreachable

    When your internet connection is down or the cloud service can't be reached, sync now stops immediately instead of trying each table separately, making the sync process faster when offline.

  • Cloud Sync Connectivity failures logged as warnings instead of errors

    Syncing while offline no longer creates error reports — the app recognizes this as a temporary connection issue rather than a problem that needs investigation.

  • Cloud Sync Real-time status updates during connectivity-triggered abort

    During sync, you'll see specific messages explaining when tables are being skipped because the internet connection is unavailable.

  • Data Import Do it Best mailbox credentials now reported on every connection attempt

    The Do it Best mailbox connection credentials are now reported to the cloud POS-credential API on every connection attempt, not only on successful connections. For non-POS Do it Best stores where the mailbox login is the POS connection, this ensures the most current credentials are always on file even when the mailbox is temporarily unreachable.

  • Data Import DIB mailbox credentials now saved even when connection fails

    For stores using DIB as their primary POS system (non-POS DIB stores), mailbox credentials are now reported to the cloud credential backup service on every connection attempt rather than only on success. This ensures customer credentials remain on file even when their mailbox is temporarily unreachable due to network or firewall issues.

  • Data Import Store address standardization tracking

    Added fields to track whether a store's address has been standardized and USPS-confirmed during the upsert process. This ensures address quality and consistency across the platform.

  • User Interface Fixed Zone Override column header formatting

    The Zone Override column heading now looks consistent with the rest of the table, making the Store Manager screen easier to read.

  • User Interface Improved DIB Mailbox Manager error dialogs

    The DIB Mailbox Manager now shows clearer error messages when connection problems occur, and reminds you that files already downloaded are still available even if the mailbox can't be reached.

  • User Interface Actionable firewall help message for DIB mailbox connection failures

    If the DIB mailbox can't connect, you now see a detailed message explaining what went wrong and exactly what to ask your IT person to fix — including the specific host and port to allow in the firewall.

  • User Interface Improved sync failure messages for connectivity issues

    When sync fails due to no internet connection, you'll now see a clear message telling you to check your connection, making it easier to understand what went wrong.

  • Database Store location coordinates support

    The RSStore model now supports storing latitude and longitude coordinates for stores. This data is included in both the fetch and upsert operations, enabling future location-based features such as mapping or regional analysis.

  • Infrastructure Add sentinel vendor number validation to startup repair sequence

    Added RepairSentinelVendorNumbersAsync to the Store Manager initialization repair sequence. This mirrors the current behavior in UpsertGenericMatchupsAsync which never stores "99999" as a vendor store number. The repair was found to affect 4 databases (MM-1258/1259/1266/1291), each with 1 phantom row.

  • Infrastructure Added debouncer behavior tests

    Added comprehensive tests documenting how the splash screen's debouncer component behaves under concurrent operations. These tests pin the specific conditions that can cause splash screen hide requests to be lost, ensuring future changes to this component are deliberate and visible.

  • Infrastructure Comprehensive test coverage for splash arming state machine

    Added 12 new tests including a seeded fuzz test that asserts the critical invariant (never allow an on-screen splash with a disarmed watchdog) after every state transition. Four scenario tests reproduce the exact conditions from store 1372's four recurrences of MM-1302/1304/1311/1314 and were verified to fail against the old semantics before passing with the fix. Full test suite now 381/381.

User Interface

  • Improvement Added elapsed-time heartbeat to splash screen

    When Margin Master is performing lengthy operations during startup, you'll now see a timer showing how long it's been working (e.g., "still working (2:45)"), so you know the program hasn't frozen.

  • Improvement Enhanced MySQL/Compass connection panel

    MySQL/Compass connection settings now show a "Show Password" checkbox so you can verify what you typed. The "Reset to Defaults" button restores standard Eagle/Compass settings if needed. Test results now appear in a clear popup window with a Copy button to share with support.

  • Improvement Splash screen heartbeat monitoring

    Added a safety-net heartbeat monitor that detects stranded splash screens and automatically closes them after a 5-second grace period. The monitor runs every second and checks whether the splash is visible when no operation has declared busy intent, preventing permanent deadlock even if splash teardown fails through an unexpected code path.

  • Improvement Added safeguards to prevent future dialog occlusion issues

    All modal dialog code paths now verify that the main window is not topmost before opening a dialog, and log a warning if they ever find it set. This provides a safety net at the boundary that matters most and ensures that if a future code change reintroduces the topmost timing issue, the next report will identify the specific code path responsible rather than requiring extensive log analysis.

  • Improvement Added safety check before opening modal dialogs

    Extra safeguards now prevent dialogs from ever opening behind the main window, even if future updates introduce new ways to bring the window to the front.

  • Improvement Added per-zone status messages during zone pricing updates

    During startup, the loading screen now shows exactly which store and pricing zone is being updated, helping you understand why startup might take longer than usual.

  • Improvement Redesigned Do-it Best tab with mailbox enablement

    Do-it Best settings now show a checkbox for "This store uses a Do-it Best mailbox." Most stores with a POS system don't need mailbox features—when unchecked, those sections are hidden to reduce clutter. Cost Code settings remain available for all stores.

  • Improvement Do-it-Best mailbox configuration improvements

    The Do-it-Best Options tab now clearly indicates whether your store uses a mailbox. If you don't use a mailbox (pricing comes from your POS), those fields are now hidden to avoid confusion.

  • Improvement MySQL connection field improvements

    MySQL connection setup is easier: default values auto-fill, you can reveal the password to verify it, and you can quickly reset to defaults if needed.

  • Bug Fix Sort Sequence dialog now includes all current columns

    If you add a column to your pricing grid (like History 12), you can now immediately use it in your sort settings. Previously, you had to restart Margin Master before new columns would show up in the "Sort by" dropdown.

  • Bug Fix Sort field list now updates when columns are added to view

    If you add a new column to your pricing grid (like History 12), you can now sort by it right away. Previously, you had to close and reopen Margin Master before the new column would show up in the sort options.

  • Bug Fix Fixed splash screen getting stuck after startup

    The loading screen will now properly close when Margin Master finishes starting up, even after lengthy startup operations.

  • Bug Fix Fixed non-functional buttons throughout Options window

    Fixed buttons in the Options window that appeared clickable but didn't do anything when you clicked them. This affected connection testing, cloud restore, background service controls, and several other features.

  • Bug Fix Restored functionality to non-working Options buttons

    Previously broken buttons in Options now work correctly, including Test Mailbox Connection, Restore from Cloud, Run Vendor Now, Run POS Now, Test & Save, and others across multiple vendor/POS tabs.

  • Bug Fix Splash screen properly closes after background operations

    Fixed a bug where the loading screen could get stuck covering the app and prevent you from clicking anything.

  • Bug Fix Edit Columns dialog now updates immediately after view operations

    The grid in Edit Columns now correctly updates right away when you copy, create, or delete a column view, without needing to close and reopen the dialog.

  • Bug Fix Edit Columns dialog now refreshes properly after copy or create operations

    You can now edit columns immediately after copying or creating a column view—no need to close and reopen the Edit Columns dialog anymore.

  • Bug Fix Splash screen deadlock during long operations

    Fixed freezing issues where the app appeared stuck on "Finalizing…" or other splash messages. Margin Master now properly closes the splash screen before showing any pop-up dialogs.

  • Bug Fix Reconfigure Store menu item now responds to clicks

    The "Reconfigure Store..." menu option was not doing anything when clicked. It now properly opens the store configuration screen.

  • Bug Fix Print button enable/disable logic now works

    The Print button now properly disables when there's no pricing data loaded, preventing accidental clicks that would produce empty reports.

  • Bug Fix Splash screen watchdog now properly armed after failed close attempts

    The application now correctly tracks whether the splash screen is actually closed versus only requested to close. Previously, when a splash screen close operation was requested but failed, the monitoring system (watchdog) would incorrectly disable itself before verifying the splash was actually gone. This left the splash screen permanently visible and blocking all input, requiring users to force-quit the application. The watchdog now stays active and retries the close operation until it verifies the splash screen is actually removed. A comprehensive test suite with over 200 lines of unit tests now prevents this issue from recurring.

  • Bug Fix Modal dialogs no longer open behind main window

    When you launch Margin Master, pop-up windows like the "Data Aging" prompt will now always appear in front where you can see and interact with them, instead of getting stuck behind the main window and making the app look frozen.

  • Bug Fix Modal dialogs no longer open behind main window

    If the app appeared frozen at startup with no windows you could click on, it was likely this bug. Modal dialogs like Data Aging now always appear in front of the main window where you can interact with them.

  • Bug Fix Fixed missing icon in Take Action menu button

    The "Take Action" menu button now shows a proper hamburger icon and is better positioned in the issue details header.

  • Bug Fix Added safety net to detect and recover stranded splash screens

    Added automatic detection and recovery if the loading screen ever fails to close properly.

  • Bug Fix Theme selector now updates display immediately

    When you change the application theme in Settings, the selection now updates on screen immediately to confirm your choice.

  • Bug Fix Splash screen heartbeat properly re-arms after unexpected failures

    Fixed an issue where the splash screen monitoring loop could silently fail and never restart, making all subsequent splash screens un-closable for the lifetime of the application. The heartbeat timer now properly cleans up its state when the monitoring loop exits unexpectedly, and automatically re-arms if a splash screen is still visible. Added proper exception handling to ensure failures are logged and the system can recover.

  • Bug Fix Auto-update dialog now waits for splash to close

    Auto-update notifications now appear correctly even if they arrive during a sync or other long operation.

  • Bug Fix Splash screen status timer now displays correctly

    Fixed the "still working (m:ss)" elapsed time indicator on the splash screen, which was being updated every second by the heartbeat but never actually displayed to users due to missing property change notifications. This made long-running operations appear frozen even when they were progressing normally, contributing to user reports that matched the symptoms of the permanent splash screen bug.

  • Bug Fix Fixed false-positive pricing data rebuild on startup

    Fixed an issue where the application spent several minutes "Verifying pricing data" on every startup, even when nothing had changed. Startup is now much faster, and pricing data only rebuilds when actually needed.

  • Bug Fix Cloud sync error dialogs now wait for splash to close

    Cloud sync error messages and excluded store prompts now use verified splash teardown, ensuring these modal dialogs are never hidden behind a lingering splash screen.

  • User Interface Redesigned Support Issues window layout

    Issue actions (like "Mark Resolved", "View Online", and "Remove Issue") are now organized in a single "Take Action" button, making them easier to find and use.

  • User Interface Formatted HTML rendering in support issue comments

    When viewing support issues, comments now display with proper text formatting including bold, italic, and clickable web links instead of showing HTML code tags.

  • User Interface Renamed and restyled issue creation button

    The button to create a new support issue is now clearly labeled "Create Support Issue" and appears in green.

  • User Interface Consolidated store management menu entries

    When you click "Store Manager" in the Data menu, you can now manage both your POS/vendor store matchup and Ace zone assignments in one dialog instead of navigating to two different menu items.

  • User Interface Fields-to-Show mode preserved when refreshing sort list

    Your sort settings and view preferences remain intact when opening the Edit Sort Sequence dialog, even after adding new columns to your grid.

  • User Interface Improved system activity notifications

    System notifications (like status changes and tech support updates) now have a light gray background, making them easier to distinguish from regular comments.

  • User Interface Redesigned "Take Action" menu with status-aware options

    The "Take Action" button now shows different, clearer options depending on whether an issue is open, awaiting your confirmation, or already resolved.

  • User Interface New connection report dialog for MySQL test results

    When you test a MySQL connection, results now appear in a dedicated popup window that you can copy to the clipboard for support tickets.

  • User Interface Added conditional action visibility

    Action buttons now automatically show or hide based on the issue's current status, so you only see the options that make sense for that issue.

  • User Interface Redesigned "New" issue button

    The button for creating new support issues is now labeled "New" instead of showing just a "+" symbol.

  • User Interface Renamed Messages panel to "Issue Conversation"

    The tab showing issue comments is now called "Issue Conversation" instead of "Messages."

  • User Interface Removed obsolete "Use Legacy Sync" option from Ace Hardware tab

    Removed the "Use Legacy Sync for Vendor Data" checkbox from the Ace Hardware settings tab, matching its removal from the Do-it Best tab. This option was only used for troubleshooting and is no longer needed.

  • User Interface Minor UI fixes across Options tabs

    Fixed the Auto Update tab help icon display. Corrected Export Options tab Add/Remove arrow button glyphs to show proper left/right arrows instead of generic move icons.

  • User Interface Removed obsolete "Use Legacy Sync" toggle from Ace Hardware tab

    The Ace Hardware Options tab is simplified—the obsolete "Use Legacy Sync" option has been removed.

  • Architecture Consolidated view state refresh logic

    Created a centralized RefreshAfterViewChange method that invalidates all cached view state (current view, view list, and row data) and raises property change notifications for all related properties. This ensures the UI bindings for editability (CanEditView), default view status (IsDefault), and grid rows (ViewData) all re-evaluate correctly.

  • Architecture Centralized view state refresh logic

    Introduced a RefreshAfterViewChange method that comprehensively resets the ViewModel's cached state (CurrentColumnView, ColumnViewList, ViewData) and raises property change notifications for all bindings. This ensures the UI stays synchronized with the ViewManager after copy, create, and delete operations.

  • Architecture Added dedicated state machine for splash screen lifecycle management

    Introduced a new `SplashReaperArming` class that encapsulates the critical invariant: a splash screen that is on-screen must always have an armed watchdog monitoring it. This pure, testable component separates arming logic from UI concerns and is validated by fuzzing tests that assert the invariant holds after every state transition. The state machine tracks splash visibility, watchdog arm status, close attempt count, and provides escalation logic when repeated closes fail.

  • Infrastructure Removed unused dialog code

    Deleted three dialog service accessors (SQLConnectionConfigurationView, RestoreCloudBackupView, RestoreDatabaseFileView) that were never used—their corresponding XAML declarations were commented out or absent. This cleanup removes dead code and eliminates potential confusion.

  • Performance Optimized startup pricing data freshness check

    Margin Master starts faster and no longer incorrectly rebuilds pricing data when nothing has changed, especially on databases with multiple stores.

  • Infrastructure Debouncer behavior characterization tests

    Added comprehensive unit tests documenting the Debouncer component's behavior, specifically the shared cancellation token and forced invocation characteristics that led to the splash deadlock. These tests exist to ensure future changes to debouncing behavior are deliberate and visible rather than accidental.

  • Infrastructure Auto Update help link modernization

    Replaced the old SimpleButton-based help link in the Auto Update tab with the standardized HelpButton control that links to the online documentation (getting-started/auto-updates).

Reporting & Exports

  • Improvement MySQL grant guidance now shows the correct host address

    The MySQL troubleshooting guidance now shows the correct server address that your database admin needs to grant access to, which is especially helpful when connecting through complex networks.

  • Improvement MySQL grant guidance now shows the correct host address

    The MySQL diagnostic's suggested fix command now shows the correct host address that needs to be granted access in your MySQL server, especially important if your network uses routing or NAT.

  • Improvement Enhanced error diagnostics for backup zip creation failures

    When backup zip creation fails, the system now logs comprehensive diagnostic information including source and target file paths, directory existence and writability status, whether the export path used a fallback location, and whether a valid zip license is present. This enables faster troubleshooting of backup issues without exposing sensitive license information. The system now actively tests directory write permissions rather than just checking if the directory exists.

  • Bug Fix MySQL authentication diagnostics now report accurate password status

    When MySQL connection tests fail in Support Tools, you'll now see the correct reason: either that you need to enter a password, or that the password you entered was rejected. Previously, it always said the password was blank even when you had entered one.

  • Bug Fix MySQL authentication diagnostic now reports correct password status

    When testing your MySQL/Compass connection, the diagnostic report now correctly identifies whether you entered a password, fixing cases where it wrongly said the password field was blank.

  • Bug Fix License service outages no longer treated as invalid licenses

    If the Management service is temporarily down or unreachable, you'll see an informational message but can continue working. You won't be forced to reconfigure your license.

  • Bug Fix Corrected zip file path calculation for custom export locations

    Fixed a bug where the backup zip filename was calculated using a whole-path string replacement instead of just changing the file extension. This caused failures when customers configured a custom export path with "json" in the directory name (e.g., "D:\jsonexports\StrategyBackups") because the system would incorrectly target a non-existent "D:\zipexports\StrategyBackups" folder. Now uses proper extension replacement that works regardless of folder naming.

  • Bug Fix Improved error message accuracy for licensing service issues

    When the licensing service can't be reached, you'll now see a clear message asking you to retry, instead of confusing technical error text.

  • Bug Fix More precise detection of store/vendor configuration errors

    Refined the logic that identifies invalid store or vendor numbers to only trigger when the server explicitly reports a store or vendor as "not found." Previously, any server error containing "not found" would incorrectly blame the customer's store configuration.

  • Architecture Consolidated duplicate zip creation code

    Eliminated three identical copies of zip creation logic spread across V1, V2, and V3 backup strategies by consolidating into a single shared method. This ensures the path fix and diagnostic improvements apply uniformly across all backup formats and reduces future maintenance burden.

Performance & Reliability

  • Improvement Extended demo database connection timeout

    Demo mode now waits longer for the database to be ready, which helps on slower computers or when setting up large demo databases.

  • Improvement Extended demo database initialization timeout

    Demo mode is now more reliable on slower computers, giving the system more time to set up the demo database before timing out.

  • Improvement Delete Skus prompts now show store group names

    Before deleting, you now see clear descriptions like "Group NonCore" or "Store 500" instead of technical table names.

  • Bug Fix Startup crash when non-deployed theme selected

    Fixed a problem where choosing certain visual themes would cause Margin Master to crash when you opened it again. The theme menu now only shows themes that are actually available.

  • Bug Fix Application crash on startup due to missing theme assemblies

    The app will no longer crash on startup if you had previously selected a theme that isn't available. The theme selector now only shows themes that are actually installed.

  • Bug Fix Crash in SKU detail dialog

    QuickFind will no longer crash when opening item details in certain scenarios.

  • Bug Fix Splash screen heartbeat timer stability

    Fixed a rare crash that could happen when Margin Master was starting up and displaying the splash screen.

  • Bug Fix Cross-thread crash in selection box creation

    Fixed a crash that could happen when the main table was loading selection box tabs, particularly after background sync or data reload operations.

  • Bug Fix Fixed cross-thread crash in selection box creation

    Fixed an occasional crash that could happen when the application was building selection boxes in the Main Table screen, especially after background sync or import operations completed.

  • Bug Fix Delete Skus no longer crashes for store-grouped customers

    If you use store grouping, clicking Delete Skus no longer silently fails — it now works correctly and shows which store groups will be affected.

  • Bug Fix Fixed crash during SKU deletion in multi-table POS configurations

    Fixed an error that prevented SKU deletion from working properly in some multi-store setups.

  • Bug Fix Corrected splash screen ownership during startup

    Fixed a bug where the application could freeze on the splash screen during startup, forcing you to close it with Task Manager.

  • Bug Fix Improved reliability for store-reported crash

    Resolved crash fingerprint 29d96abd reported by store 5179 (Schnarr's Hardware). The crash manifested when selection boxes were being built during operations that started off the UI thread, such as background coordination reloads. Callers using ExecuteOnDispatcherAsync were unaffected because they always resumed on the UI thread.

  • Bug Fix Enhanced exception handler coverage
  • Bug Fix Delete Skus now prevents accidental deletion from all stores

    Delete Skus now correctly limits deletions to your selected stores, preventing accidental deletion from all stores.

  • Bug Fix Added error handling to Delete SKUs operation

    Delete SKUs button now properly shows error messages when something goes wrong instead of silently failing.

  • Bug Fix Improved splash screen failure tracking

    The splash screen watchdog (which detects when the splash fails to close) now correctly remembers previous close failures even if the splash screen is shown again. Previously, re-showing the splash would reset the failure counter, preventing the escalation logic from ever firing. This made certain types of splash-related hangs undetectable.

  • Bug Fix Prevented UI blocking during startup error dialogs for RockSolid users

    Four startup error dialogs (OLEDB driver warnings and vendor data availability checks) now properly close the splash screen before displaying, preventing a situation where the dialog could block the UI thread and prevent the splash screen watchdog from running its cleanup logic.

  • Bug Fix Delete Skus errors now display properly

    If Delete Skus fails, you now see an error message explaining what went wrong instead of the button simply doing nothing.

  • Architecture Introduced table scope detection for routing policy

    Added IsAllStoresTable and AnyAllStoresTable helper methods to StoreRoutingFilterPolicy to distinguish between per-store routed tables (like "StoreGroup_NonCore_mainTable") and all-stores tables (like "Mi9_mainTable" and the global "mainTable"). This allows the system to correctly determine whether the store selection was consumed by table routing or must be preserved in the WHERE clause, fixing the long-standing ambiguity between the Mi9UseSingleMainTable flag and actual routing behavior.

  • Infrastructure Native crash capture for silent terminations
  • Infrastructure Theme deployment validation service

    Added DeployedThemeService to scan the application directory for actually-deployed DevExpress theme assemblies and restrict theme selection to only those files present on disk. This service provides a safe fallback mechanism and prevents the application from attempting to load theme assemblies that aren't included in the deployment package.

  • Infrastructure Improved crash diagnostics
  • Infrastructure Added regression test for splash screen failure tracking

    Added automated test to verify that the splash screen's close-attempt counter correctly survives re-show events, ensuring the 3-strike escalation mechanism remains reachable when shows and failed closes are interleaved.

Infrastructure & Internal

  • Bug Fix Fix filter rejection for ampersand in product descriptions

    Filtering by Do-It-Best categories with ampersands in the name (like "Paints & Treatments") will now work correctly.

  • Data Import Downgrade file-not-found errors to warnings

    Missing POS export files will still show error messages to you, but won't create reports on the support dashboard.

  • Database Backup failures logged as warnings

    Auto-strategy backup failures and database rename backup failures now log as warnings since they're typically caused by path or permission issues on the SQL Server machine rather than application bugs.

  • Infrastructure Error telemetry classifier

    Added ErrorClassifier that distinguishes genuine code bugs from expected conditions like garbled import files, missing database files, SQL connection drops, backup device failures, and user-cancelled operations. The classifier is consulted before sending errors to the cloud dashboard. SQL execution timeouts are still reported since persistent timeouts can indicate real performance or indexing problems.

  • Infrastructure Unit tests for error classification

    Added comprehensive unit tests that lock in the rules for which errors should reach telemetry and which should be handled locally. Also added regression tests for the SQL filter pattern to prevent future false rejections of legitimate product descriptions.

Other Changes

  • New Feature Automatic self-repair for corrupt installations

    Implemented a self-healing system that detects when the application fails to start due to corrupt or mismatched assemblies (typically from a failed auto-update). When detected, the system automatically downloads the latest full package from the update server and reinstalls it via the updater, eliminating the "bricked install" scenario where users couldn't launch the application to even trigger a repair. The service includes safeguards to prevent infinite repair loops (maximum 2 attempts per version) and only triggers when assembly-load failures occur at startup.

  • New Feature Silent automatic app updates

    In Settings > Background Service > Automatic App Updates, you can enable scheduled update checks that run daily at a specific time or every N hours. When a new version is published, Margin Master downloads and installs it automatically overnight without interrupting your work.

  • New Feature Silent automatic app updates

    Margin Master will now check for updates on a schedule you set and install them automatically when the app isn't running. You'll always have the latest version without needing to download or install updates yourself.

  • New Feature Automatic remediation script generation for restricted SQL environments

    If your store's SQL Server requires DBA approval for login creation, Margin Master will now create a script file that your IT team can run to finish the setup.

  • New Feature Automatic DBA remediation script generation

    If SQL setup requires administrator help, the application will create an instruction file that your database administrator can run to complete the setup.

  • New Feature Background Service documentation

    Added comprehensive getting-started documentation (background-service.md) covering service installation, scheduling, account selection guidance, run history, and technical details. The documentation clarifies that Local System is the recommended setup and explains when the Advanced account option is needed.

  • Improvement 7-day maximum deferral window on available updates

    If a new version has been available for 7 days, Margin Master will install it automatically the next time it checks, even if you clicked "Snooze 1 Week" multiple times. This keeps your store's software current with the latest bug fixes and improvements.

  • Improvement 7-day maximum update deferral enforced

    If you postpone an update, it will automatically install after 7 days to keep your system current. You can still choose "1 Hour," "1 Day," or "1 Week" when the update notification appears, but updates won't wait longer than a week.

  • Improvement Enhanced MySQL authentication failure messages

    When a MySQL connection test fails due to login issues, you'll now see a clear explanation of whether you need to enter a password in the settings or correct an incorrect password.

  • Improvement Automatic service permission repair at startup

    When the background service feature is enabled, the app now checks whether the service has the necessary permissions for silent updates (allowing unattended stop/start during updates). If the permission is missing—typically on installations from early testing—the app will prompt once for elevation to repair it. The check runs in the background and is skipped once confirmed, so it never delays startup.

  • Improvement Improved selection list caching strategy

    Filter dropdowns that have no values now load instantly at startup instead of re-checking the database every time.

  • Improvement Credential-free Background Service installation

    When installing the Background Service, you no longer need to enter a Windows account and password. Just click the Install button—the service runs as Local System and works with typical database setups.

  • Improvement Simplified Background Service installation

    You no longer need to enter a username and password when installing the Background Service — just click Install and it works with your database.

  • Improvement Enhanced freshness verification for auto-updates

    The update system now performs multiple layers of verification to prevent installing outdated versions. When checking for updates, it cross-references the update feed against the Manager API's authoritative latest version and retries with fresh data if the feed appears stale. When actually installing an update that was detected more than 10 minutes ago (such as snoozed updates or install-on-shutdown scenarios), it re-verifies the feed to ensure no newer version was published in the meantime. This prevents intermediary caches (like customer-site proxies) from hiding freshly published releases.

  • Improvement Cache-busting for update manifest checks

    Update checks now append unique timestamps to feed requests and send strict no-cache headers to prevent intermediary caches (customer-site proxies, CDNs) from serving stale update manifests. Each check fetches a fresh view of available versions, ensuring newly published releases are immediately visible.

  • Improvement Smart SQL Express instance detection and collision avoidance

    If you already have a SQL Express database installed (for example, by your POS system like RockSolid), Margin Master will now install its own separate database instance automatically instead of stopping or potentially interfering with your existing software.

  • Improvement Added permission pre-check before login creation

    The application will now detect permission issues upfront rather than encountering confusing errors.

  • Improvement Added diagnostic logging for load failures

    Previously-ignored exceptions during the Restore Database window load are now logged as warnings, making it easier to diagnose future initialization problems.

  • Improvement Main table freshness logging

    The application now provides better visibility into pricing data health checks that run automatically when you start the program.

  • Improvement No-elevation service control for unattended updates

    Automatic updates now complete entirely in the background without prompting you for administrator permission.

  • Improvement Forced refresh for PSRule filter after strategy execution

    After running a pricing strategy, the PSRule filter will automatically show the new rule values without needing to reset your filters.

  • Improvement Cache-busting for update manifest downloads

    All update manifest fetches now include cache-busting query parameters and HTTP no-cache headers to prevent intermediary caches from serving stale update information. This ensures that every update check sees the true latest available version, even in environments with aggressive proxy caching. Package downloads themselves retain normal caching behavior since they are version-stamped and immutable.

  • Improvement Cross-check feed against Manager API

    When the Velopack update feed returns a version older than what the Manager API reports as latest (indicating a stale cached manifest), the system automatically retries up to 2 times with fresh cache-busting tokens before proceeding. This prevents installing an outdated version when a newer one has just been published.

  • Improvement Index maintenance operations now fail fast when tables are busy

    All four index creation methods (RebuildManagedIndexesForTableAsync, RebuildAllManagedIndexesAsync, EnsureSelectionBoxFieldIndexesAsync, and AutoCreateHighImpactIndexesAsync) now route through a new OpenIndexMaintenanceConnectionAsync helper that configures appropriate timeouts. When a lock timeout occurs (SQL error 1222), the operation logs a debug message and continues rather than blocking startup indefinitely.

  • Improvement Repair state tracking and loop prevention

    Implemented persistent state tracking that records repair attempts (target version, attempt count, timestamp) to prevent infinite repair loops if the latest version itself is corrupt. After a successful startup, the repair counter is automatically reset for future incidents.

  • Improvement Consolidated SQL login creation logic

    Moved SQL user creation logic from RSQueryBuilder to a centralized SqlUserCreator helper with improved error handling, permission detection, and remediation workflow. This ensures consistent behavior for both the MarginMaster and MarginMasterDataExtractor logins.

  • Improvement Warning for remote SQL with Windows authentication

    When installing as Local System with a remote SQL Server using Windows authentication detected, the system displays an advisory message explaining that Local System may lack login rights and suggesting the Advanced account option. The warning is informational only and does not block installation.

  • Improvement Cache location fallback is logged once at startup

    When the fallback to per-user storage is triggered, the application now logs a single informational message at startup indicating that the shared ProgramData location is not writable and that the per-user cache location is being used instead. This replaces the previous behavior where every cache write would log an UnauthorizedAccessException, creating excessive noise in support logs while providing no clear indication of the root cause.

  • Improvement Re-verify updates before installation

    If you snooze an update or schedule it to install on shutdown, the system will automatically check for an even newer version right before installing to ensure you get the latest available.

  • Improvement Separate Margin Master SQL instance installation when a foreign instance exists

    If another program is already using SQL Server on your computer, Margin Master will install its own separate copy and won't interfere with the other program's database.

  • Improvement Added diagnostic logging for filter operations

    Added detailed logging to the grid filter application process, recording which filters are active, which tables are searched, which stores are included, and the generated SQL WHERE clauses. This will aid in diagnosing future filtering issues and performance optimization.

  • Improvement Background service restart logic after updates

    Added a new sentinel setting (AutoUpdateRestartBackgroundService) that is set only when applying an update stops a RUNNING background service. This ensures the service restarts on the new build after a successful update, but never enables a service the user deliberately disabled or never installed. The check runs outside the pending-version block so a failed update that clears the pending version doesn't strand the service stopped until reboot.

  • Improvement Better diagnostic logging for SQL login operations

    Enhanced logging to clearly distinguish between successful login creation, permission-denied scenarios (with remediation script paths), and other SQL errors. This makes it easier to diagnose SQL setup issues without generating misleading error messages in the log.

  • Improvement Store Manager dialog now available for BisTrack, RockSolid, and NCR Counterpoint

    BisTrack, RockSolid, and NCR Counterpoint users can now open the improved Store Manager from the POS Options tab to configure store matchup, zones, and RSC settings in one place—just like Epicor.

  • Improvement Remote SQL Server advisory warning

    If you're using a remote SQL Server with Windows authentication, you'll see a helpful warning when installing as Local System, with guidance on using the Advanced option if needed.

  • Bug Fix Fixed MarginMasterDataExtractor login creation failure

    The MarginMasterDataExtractor SQL login was never successfully created because the CREATE LOGIN command was executed against the application database instead of the SQL Server master database. This caused SqlException 5001 ("User must be in the master database") which was silently swallowed. The login creation now correctly switches to the master database context before creating the login, then back to the application database for user and role assignment.

  • Bug Fix SQL login creation no longer fails with error 5001

    Fixed an issue where Margin Master would encounter error 5001 or other permission-denied errors when attempting to create the MarginMasterDataExtractor SQL login. The application now proactively checks whether it has the required server-level permissions (sysadmin or securityadmin) before attempting login creation, and gracefully handles permission-denied scenarios rather than generating errors.

  • Bug Fix Resolved UI thread deadlock during first-time setup

    The Restore Database window was deadlocking when opened on a fresh installation (before any store or vendor was configured). The vendor dropdown loading code was blocking the UI thread while waiting for a file read operation that also needed the UI thread, creating a circular wait that froze the entire window. The vendor loading process is now fully asynchronous, allowing the window to remain responsive during initialization.

  • Bug Fix Automatic main table refresh on upgrade

    If your pricing grid shows outdated costs after an upgrade, Margin Master will now automatically detect and fix this during startup, ensuring you always see current vendor catalog pricing.

  • Bug Fix Prevent sentinel value from creating phantom store entry

    If your store list previously showed a strange store numbered "99999," this will be properly excluded during the next data repair.

  • Bug Fix Store Manager ordinal repair no longer creates phantom stores

    Fixed a flaw in the Store Manager's corruption repair routine that could resurrect the 99999 sentinel value (used internally to mark unmatched stores) as an actual POS store number. The repair logic now correctly nulls out the sentinel value so these stores are properly marked as excluded, while real store numbers are restored correctly. This primarily affects stores using generic POS types where older migration issues had incorrectly stored the sentinel value.

  • Bug Fix Empty filter dropdowns no longer trigger full table scans at startup

    Filter dropdowns that have no options (like PSRule before running a pricing strategy) will no longer cause the app to slow down during startup.

  • Bug Fix Service outages no longer invalidate active licenses

    If the licensing server is temporarily down, you'll see a simple "Unable to connect" message but can continue working with your existing license instead of being forced to reconfigure.

  • Bug Fix Auto-update now recovers from corrupted or incomplete downloads

    If an update download was interrupted or failed previously, the app will now automatically clean up and retry instead of staying stuck on that version forever.

  • Bug Fix API cache fallback for restricted user accounts

    On computers where you don't have administrator permissions, Margin Master's cache will now work correctly, making the application load much faster by avoiding unnecessary downloads each time you start it.

  • Bug Fix API cache now works on machines with restricted Windows permissions

    On machines where your Windows account doesn't have full permissions, Margin Master will now properly save downloaded vendor and pricing data locally, making the application load faster on subsequent launches instead of re-downloading everything each time.

  • Bug Fix Added timeout protection for database index creation during startup

    If the database is busy during startup (for example, during a large import or sync), the app will now skip index optimization and continue starting up normally instead of freezing. Index optimization will be automatically retried the next time the app starts.

  • Bug Fix Hard-block removal of non-Margin Master SQL instances

    If your computer has another application's SQL Server (like RockSolid POS), Margin Master will now detect it and install its own separate instance instead of touching the existing one.

  • Bug Fix SQL instance ownership verification prevents accidental removal of other applications' databases

    If your computer has SQL Server installed for another program (like RockSolid POS), Margin Master will now detect it and leave it completely alone—it will never upgrade or remove it.

  • Bug Fix PowerShell script compatibility restored for Windows PowerShell 5.1

    Installation scripts that were failing with syntax errors during initial Margin Master setup now run successfully.

  • Bug Fix Selection boxes now filter on database values instead of display text

    When you filter the pricing grid by store number or Ace category, the application now correctly finds matching items instead of showing an empty grid.

  • Bug Fix Selection box filtering corrected for stores and Ace hierarchy

    When filtering the pricing grid by store number or Ace product categories, the filters now work correctly instead of showing no results.

  • Bug Fix Automatic background service shutdown before updates

    If you have the background service enabled, updates will now work correctly. The service will restart automatically after the update completes.

  • Bug Fix MySQL error code detection for wrapped exceptions

    Fixed detection of MySQL error codes when the authentication plugin wraps the actual failure in an outer exception with error code 0. The system now correctly recurses through nested exceptions to find the true error code (such as 1045 for access denied).

  • Bug Fix Per-field refresh now bypasses cache correctly

    After running a pricing strategy that changes PSRule values, the PSRule filter dropdown now updates to show the new values immediately.

  • Bug Fix Improved license error message accuracy

    You'll no longer see confusing "store not found" errors when the licensing server has temporary technical problems.

  • Bug Fix Clipboard operations no longer crash when another app holds the clipboard

    Copying SKUs, SQL scripts, connection strings, or other text will no longer crash if another program is using the clipboard—instead you'll see a brief message that the copy failed.

  • Bug Fix Failed update detection and error reporting

    If an update fails to install, you'll now see a clear error message explaining what went wrong instead of the app silently staying on the old version.

  • Bug Fix Fresh install main table rebuild

    New installations will now populate the pricing grid immediately after downloading vendor data, rather than showing empty or stale pricing.

  • Bug Fix Cloud sync now detects and reports damaged .NET framework installations

    If your .NET installation is damaged, cloud sync will now tell you exactly what's wrong and how to fix it, instead of showing a generic database error.

  • Bug Fix Handle versions with no release notes

    If release notes aren't available for a version, you'll see a clear message explaining why instead of a blank screen.

  • Bug Fix Prevented accidental version downgrades during auto-update

    The normal auto-update path now disables version downgrades to prevent stale cached manifests from incorrectly appearing as legitimate downgrades. Explicit downgrade functionality (for troubleshooting) remains available through the dedicated downgrade workflow.

  • Bug Fix Eliminated compiler warning for unused field

    Resolved compiler warning CS0649 that was being generated for an unused field in the broken Group SKU Variance feature. The application now builds with zero warnings.

  • Bug Fix Headless service license validation

    Added a headless flag to the startup check service that prevents the license configuration window from attempting to open during background service runs. If license validation fails during a headless run (session 0, no desktop), the service now fails fast and logs the error instead of hanging indefinitely trying to show a dialog that can't be displayed.

  • Bug Fix Prevent version downgrades from stale caches

    Disabled automatic version downgrade in the normal update path. Only explicit administrator-initiated downgrades (via specific version download) can move backward. This prevents a stale cached manifest from appearing as a legitimate downgrade and rolling users back to older versions.

  • Bug Fix Fixed detail pane clipping on right edge

    The Version History window now displays correctly without cutting off content on the right side.

  • Bug Fix Application uninstaller refuses substring matches on generic SQL identifiers

    The `ApplicationUninstallerService` now maintains a blocklist of dangerously generic identifiers (`SQL`, `SQL Server`, `Microsoft SQL Server`, etc.) and refuses substring fallback matching for them. An uninstall request for "SQL Server" without an exact display name or product code now fails safe rather than potentially matching shared SQL components (ODBC, OLE DB, VSS Writer) or an unrelated application's SQL instance. Callers must supply a precise identifier for SQL-related removals.

  • Cloud Sync Single-call organization store fetch

    The sync process now attempts to retrieve all stores for an organization in one API call (GET /api/v2/Organization/{orgId}/Stores) instead of fetching each store individually. If the new endpoint is unavailable, the system automatically falls back to the legacy per-store fetch method, ensuring backward compatibility and uninterrupted operation during server upgrades.

  • Cloud Sync Store upsert API support

    Added AddOrUpdateStoreAsync method that allows Margin Master to save or update store information to the cloud via POST /api/v2/Organization/{orgId}/Stores. The method automatically invalidates the 30-day organization-store cache on success to ensure subsequent fetches reflect the latest changes. Returns detailed result information including whether the store was newly created or claimed by another organization.

  • Cloud Sync SQL Express migration service ownership gates

    When setting up SQL Server, if another application is already using SQL Server, you'll be prompted to install Margin Master's own separate instance that won't interfere with the other application.

  • Cloud Sync Version History syncs from cloud when local data is empty

    Release notes now load correctly the first time you open Version History, even if the background sync hasn't finished yet.

  • Data Import Improved store matching logic for non-Epicor systems

    Enhanced the cleanup process for stores that don't have a matched POS store number, particularly affecting organizations using non-Epicor POS systems that went through legacy data migrations. Real POS store numbers are still correctly restored, while unmatched stores remain properly flagged.

  • Data Import Latitude and longitude support for stores

    RSStore model now includes Latitude and Longitude fields to support round-tripping geocoding data between Margin Master and the cloud. The new StoreUpsertRequest DTO captures complete store details including geographic coordinates, address standardization flags, and USPS confirmation status for enhanced location data management.

  • Data Import Ace category hierarchy filters now work correctly

    Filtering by Ace categories (Supergroup, Convenience, Number, Ultimate) now correctly shows matching items in the pricing grid.

  • User Interface Added "New" menu bar for issue creation

    Creating a new support issue is now done through a "New" menu in the top-right corner, which shows both regular and quick submit options.

  • User Interface Release highlights added to version list

    You can now see what changed in each version directly in the list, without having to click on each one.

  • User Interface Release highlights in version list

    You can now see what changed in each version without having to click on it first—a short description appears under each version in the list.

  • User Interface Removed Group SKU Variance menu item and dialog

    The "Show Group Store Retail Variances" option has been removed from the Server menu. This feature was not working—if you tried to use it, the store dropdown would be empty and the window would not show any data.

  • User Interface Self-repair progress dialog

    Added a dedicated progress window that displays during the repair process, informing users that a damaged update was detected and the application is downloading and reinstalling the latest version. This provides transparency during what would otherwise appear as an application hang.

  • User Interface Streamlined issue actions with context-sensitive "Take Action" menu

    When viewing an issue, all available actions are now in a single "Take Action" menu that shows only options that make sense for the current issue status.

  • User Interface Removed "1 Month" snooze option from update notification dialog

    The update notification no longer offers a "1 Month" snooze option — the longest you can postpone is now 1 Week.

  • User Interface Removed "1 Month" snooze option

    The "Snooze 1 Month" button has been removed from update notifications. You can now snooze for up to one week.

  • User Interface Update schedule configuration in Settings

    In Settings > Background Service, you can now enable automatic updates and choose when they should check for new versions—either at a specific time each day (like 4:00 AM) or every few hours.

  • User Interface Account credentials moved to Advanced section

    The account and password fields are now hidden in an "Advanced" section you only need for special database configurations. Most stores can ignore this section entirely.

  • User Interface Advanced account option for remote SQL scenarios

    Account and password fields are now hidden under an Advanced section — you only need them if your database is on a remote server with Windows authentication.

  • User Interface Release notes now display with proper formatting

    Release notes now appear with color-coded categories and clear formatting instead of plain text or blank space.

  • User Interface Styled release notes display

    Release notes now appear with proper colors and formatting, making them easier to read.

  • User Interface Settings > Database Configuration now displays instance ownership status

    The SQL install screen now clearly shows which SQL instances belong to Margin Master and which belong to other programs, so you know what will and won't be changed.

  • User Interface Store number filter now returns results in single-store mode

    The store number filter in single-store mode now works properly and displays your selected store's pricing data.

  • User Interface Improved message thread readability

    The conversation history in each issue now reads more naturally from top to bottom, with system messages appearing inline with your comments instead of centered.

  • User Interface Cleaner error messages during service issues

    Error messages about licensing service problems are now clearer and more actionable instead of showing technical details.

  • User Interface Empty state added for versions without notes

    If a version has no release notes, you'll see an explanation instead of a blank screen.

  • User Interface Auto-updates documentation updated

    The auto-updates documentation now explains the 7-day maximum ignore window, clarifies that updates can install automatically after this period, and removes references to the discontinued "1 Month" snooze option. Adds new search keywords (maximum snooze, forced update, required update, weekly update) and documents the `AutoUpdateDeferredSince` setting key.

  • User Interface Update schedule configuration in Settings

    The Background Service settings screen now has a section for automatic updates, showing when the last check occurred and letting you control when updates should install.

  • User Interface Improved window sizing

    The Version History window now has a minimum size (700×480) to ensure release notes remain readable, replacing the previous fixed size of 900×600.

  • User Interface Settings screen SQL installation prompts

    Database Configuration tab (DatabaseConfigurationTab_SqlInstallViewModel) now shows a mandatory confirmation dialog when InstallSeparateInstance is recommended, explaining that a foreign SQL instance was detected and Margin Master will install its own separate instance without modifying the existing one. Installation cannot proceed without explicit support tech acknowledgment.

  • Database Improved handling of unmatched store records

    The automatic repair routine now includes logic to distinguish between legitimate POS store numbers that need to be restored and the special 99999 marker that should remain null. This ensures unmatched stores flow through to the follow-up exclusion process correctly rather than appearing as phantom stores with an invalid 99999 store number.

  • Database Margin Master database fingerprint system

    Introduced MarginMasterDatabaseSignature in Common constants defining the canonical ownership test: a database is Margin Master's when it contains at least 4 of 8 core tables (About, mainTable, Store, RoundingScheme, RoundingSchemeDetail, SkuExceptions, MinimumMargins, GlobalFileConfig). Fleet-validated on 118 Margin Master databases across all vendors and POS systems (100% match rate, 0% false positives). Deliberately excludes AceCatalogRecords which is Ace-only and caused Do-It-Best databases to be misclassified.

  • Database New settings for permission tracking

    Added two application settings to track the permission state: one to record when the service permissions are confirmed correct (short-circuiting future checks), and one to timestamp the last repair attempt (enabling the once-per-day throttle).

  • Database Added AutoUpdateDeferredSince setting

    Introduced a new `AutoUpdateDeferredSince` application setting key that stores an ISO-8601 timestamp marking when the currently-available update was first seen. This anchor is set once per release (on first detection) and cleared once the app is up to date, ensuring the 7-day clock restarts cleanly for each new version rather than carrying forward from an older release.

  • Database Machine-wide encryption key migration for headless runs

    License validation keys have been migrated from per-user (CurrentUser DPAPI scope) to machine-wide (LocalMachine scope, stored in ProgramData). This allows both the interactive application and the LocalSystem background service to decrypt the same license validation state, enabling offline operation of scheduled jobs. Existing keys are automatically migrated on first run, preserving all encrypted data.

  • Database New settings keys for update scheduling

    Added six new ApplicationSettingKey entries: BackgroundCheckUpdatesEnabled, BackgroundCheckUpdatesMode, BackgroundCheckUpdatesIntervalHours, BackgroundCheckUpdatesDailyTime, BackgroundCheckUpdatesLastRunUtc, and MarginMasterInstalledVersion. The installed version is persisted on each interactive app startup so the service's pre-check can compare against the feed without launching the app.

  • Database Canonical Margin Master database fingerprint constant

    Introduced `MarginMaster.Common.Constants.MarginMasterDatabaseSignature`, the single source of truth for determining whether a SQL Server database belongs to Margin Master. A database matches the fingerprint when it contains at least 4 of 8 core tables (`About`, `mainTable`, `Store`, `RoundingScheme`, `RoundingSchemeDetail`, `SkuExceptions`, `MinimumMargins`, `GlobalFileConfig`). The fingerprint was derived from a fleet scan of 123 databases and deliberately excludes `AceCatalogRecords` (Ace-only; absent in Do it Best databases) to prevent misclassification. This constant is referenced by the C# discovery/migration services, the PowerShell support scripts, and comprehensive unit tests to lock the ownership logic.

  • Database Update schedule settings

    Added six new ApplicationSettingKey entries for the Updates job schedule: BackgroundCheckUpdatesEnabled, BackgroundCheckUpdatesMode, BackgroundCheckUpdatesIntervalHours, BackgroundCheckUpdatesDailyTime, BackgroundCheckUpdatesLastRunUtc, and MarginMasterInstalledVersion (persisted on each app startup for the feed pre-check).

  • Architecture Enhanced selection box value tracking

    Added a new ValuesCurrentlySelected property to SelectionBoxDetail that maintains the list of selected items using their filter values rather than display text. This ensures filter persistence and restoration works correctly for boxes where value differs from display. The ItemValue property from the database is now properly carried through the selection list item lifecycle.

  • Architecture Service permissions for unattended operation

    Modified the service installation to grant Authenticated Users start/stop/query permissions via a custom security descriptor, allowing the silent update flow to stop the service before the Velopack swap and restart it afterward without triggering a UAC prompt. The update process relaunches with a lightweight `--post-update-start-service` step that restarts the service on the new build.

  • Architecture Consolidated SQL login creation logic

    Removed duplicate login creation code from RSQueryBuilder.CreateUser and routed all SQL login creation through the shared SqlUserCreator utility, which correctly handles database context switching and permission validation. Both the MarginMaster and MarginMasterDataExtractor logins now follow the same hardened creation path.

  • Architecture Store upsert data transfer objects

    Introduced StoreUpsertRequest and StoreUpsertResult DTOs to support the Store API integration. StoreUpsertRequest accepts all store properties (vendor, location, contacts, geocoding) with StoreId null/0 for new stores or a specific ID for updates. StoreUpsertResult returns the operation outcome including Created, Claimed, and ErrorMessage flags to help handle edge cases like store number conflicts between organizations.

  • Architecture Headless update installer

    Added UpdateInstaller and a new `--install-updates` headless command that checks for updates, downloads, stops the background service (to unlock the installation folder), applies via Velopack, and relaunches with `--post-update-start-service` to restart the service. Records the run to BackgroundJobRunHistory as BackgroundJobType.Updates, following the same pipeline-lock and status-reporting patterns as vendor/POS imports.

  • Architecture Comprehensive freshness testing

    Added 11 unit tests covering cache-busting URL construction, no-cache header injection, numeric version comparison logic, and all edge cases to ensure the "always latest" behavior is protected against regressions.

  • Architecture Headless update installer flow

    Implemented UpdateInstaller service and two new headless commands (--install-updates and --post-update-start-service). The install-updates command acquires the pipeline lock, checks/downloads via AutoUpdateService, stops the background service, then calls ApplyUpdatesAndRestart with a restart argument that triggers the post-update command. The post-update step simply restarts the service on the new build and exits, avoiding a full host/database initialization. Writes run history records to BackgroundJobRunHistory as BackgroundJobType.Updates.

  • Infrastructure Permission check throttling

    The self-heal permission repair is throttled to once per day, so if a user cancels the elevation prompt, they won't be nagged repeatedly. Once the correct permissions are confirmed, the check is permanently skipped on future launches.

  • Infrastructure Path resolution with write permission verification

    Added PathHelper.GetWritableApplicationDataSubPath() method that prefers the shared ProgramData location (so all users on a machine can share cached data) but verifies writability by actually creating a probe file—ACL checks alone are insufficient because write failures only surface during the actual write operation. When ProgramData is not writable, the method automatically returns the per-user LocalAppData path. This approach is appropriate for cache data (which is already encrypted per-user with DPAPI) but intentionally not used for data that must be shared across users, such as DatabaseConnections.json.

  • Infrastructure Added write permission detection with automatic fallback

    Implemented PathHelper.GetWritableApplicationDataSubPath method that intelligently selects between shared (ProgramData) and per-user (LocalAppData) storage locations based on actual write permission testing. The method performs a real write probe by creating a temporary file rather than just checking folder existence or ACLs, since the permission failures only surface during actual write operations. Added PathHelper.IsDirectoryWritable to test writability without throwing exceptions, and PathHelper.GetLocalApplicationDataRetailerSoftApplicationSubPath to provide the per-user fallback location. All methods include comprehensive unit tests covering normal operation, fallback scenarios, and edge cases.

  • Infrastructure Database ownership fingerprint validation

    Added Get-InstanceOwnership function that inspects SQL instances to determine if they belong to Margin Master by checking for core database tables (About, mainTable, Store, RoundingScheme, RoundingSchemeDetail, SkuExceptions, MinimumMargins, GlobalFileConfig). An instance is considered owned by Margin Master only if it contains at least 4 of these 8 signature tables and no foreign databases. This mirrors the logic in MarginMaster.Common and ensures the installer fails safe—any doubt results in treating the instance as foreign.

  • Infrastructure Enhanced script validation process

    Identified gap in deployment validation where PowerShell 7 was used for syntax checking but failed to catch encoding issues that only appear in Windows PowerShell 5.1. All installation scripts have been validated to contain zero non-ASCII characters, ensuring compatibility with the PowerShell version actually used in the field.

  • Infrastructure Cleaned up non-functional backend code

    Removed approximately 800 lines of defunct code including GroupSkuVarianceViewModel, GroupSkuVarianceView, and related SQL generation logic. The feature was targeting per-store Compass_IN_{store} tables that no longer exist after the Epicor single-table migration in December 2024. Database artifacts (GroupPricingDiscrepancies table and EpicorStoreGroupVendorTableView) are left in place as inactive remnants to avoid migration risk.

  • Infrastructure New UpdateDeferralPolicy helper with unit tests

    Adds a pure `UpdateDeferralPolicy.IsExpired` static method that calculates whether a given ISO-8601 timestamp anchor is at least 7 days old relative to the current time. Includes full unit test coverage for null/empty/unparseable anchors, boundary conditions, and future-dated clock skew scenarios.

  • Infrastructure Added UpdateDeferralPolicy and unit tests

    Created a pure policy class (`UpdateDeferralPolicy.IsExpired`) that calculates whether the 7-day window has elapsed, along with comprehensive unit tests covering normal cases, edge cases (unparseable dates, future anchors, clock skew), and the exact 7-day boundary. The policy is applied during the background auto-update check in `MainMMViewModel.ExecuteAutoUpdateTaskSafeAsync`.

  • Infrastructure Update feed pre-check to minimize overhead

    Added UpdateFeedChecker service that performs a lightweight HTTP check of the Velopack releases manifest (releases.{channel}.json) and compares the latest full-release version against the installed version. This allows the background service to skip launching the full WPF app when no update is available, reducing unnecessary CPU and memory usage during scheduled checks. Includes unit tests for version parsing and comparison logic.

  • Performance Eliminated redundant startup queries

    The app now launches faster because it no longer wastes time checking empty filter lists over and over.

  • Infrastructure Shared machine-wide encryption key

    The application encryption key used for license validation has been moved from a per-user location to a machine-wide location (ProgramData) and is now protected with DPAPI LocalMachine scope instead of CurrentUser scope. This allows both interactive user sessions and the LocalSystem background service to decrypt the same license state, preventing offline license validation failures that would have blocked headless service runs. A one-time automatic migration preserves existing keys byte-for-byte so current installs continue working without re-validation.

  • Infrastructure Comprehensive test coverage for permission fallback

    Added five new tests (PathHelperWritableFallbackTests) verifying that the writable path resolver returns directories that can actually be written to, that the per-user path is always under LocalApplicationData, that directory writability detection works correctly for both writable and unusable paths, that probe files are properly cleaned up via DeleteOnClose, and that the method handles illegal paths without throwing exceptions.

  • Infrastructure Automatic free instance name selection

    Added Get-FreeInstanceName function that generates non-colliding SQL instance names for Margin Master installations. It tries MARGINMASTER first, then MMSQLEXPRESS, then numbered variations (MARGINMASTER2, MARGINMASTER3, etc.) until it finds an available name, ensuring that Margin Master's dedicated instance never overwrites another application's SQL Server installation.

  • Infrastructure Update feed pre-check to minimize app launches

    Created UpdateFeedChecker to perform a cheap, Velopack-free HTTP check of the release manifest (releases.{channel}.json) and compare the latest full-release version against the locally-installed version. The service only launches the full headless WPF app when a newer version actually exists, reducing unnecessary process startup overhead. The installed version is persisted to ApplicationSettings on each interactive app startup so the service can read it.

  • Infrastructure Permission detection without elevation

    Added non-elevated permission checking via Windows security descriptor parsing, allowing the app to verify the service's start/stop grant is present without requiring administrator rights. This prevents unnecessary elevation prompts when permissions are already correct.

  • Infrastructure Added test coverage for error detection logic

    Introduced CorruptPackageDetectionTests (7 tests) to pin recognition of every corrupt-package shape (truncated downloads, failed delta patches, size mismatches) and MissingFrameworkAssemblyTests (5 tests) to verify detection of damaged .NET runtime installs, ensuring these recovery paths remain robust.

  • Infrastructure Comprehensive unit test coverage for update freshness logic

    Added automated tests covering cache-bust URL construction, HTTP header handling, and the version comparison algorithm that cross-checks the update feed against the Manager API's authoritative latest version.

  • Infrastructure Uninstall-SQLServer.ps1 ownership classifier

    The SQL uninstall support tool now shows which SQL instances belong to Margin Master and which belong to other applications, and only allows removing Margin Master's instances.

  • Infrastructure Enhanced PowerShell support scripts with ownership guards

    The `Install-SQLExpress.ps1`, `Upgrade-SQLExpress.ps1`, and `Uninstall-SQLServer.ps1` support scripts now incorporate the same ownership verification logic as the application. The uninstall script now classifies every instance as `MarginMaster` (removable), `Foreign` (contains non-MM databases), `Empty` (no databases), or `Unknown` (offline/unreadable), and hard-blocks removal of protected instances with no override. The install and upgrade scripts refuse to modify an instance that isn't Margin Master's and offer alternative actions. All three scripts use the canonical `MarginMasterDatabaseSignature` constant to ensure they can never drift from the application's logic.

  • Infrastructure Simplified headless update service control

    Removed redundant background service stop logic from the headless update installer, since ApplyUpdatesAndRestart now handles this automatically. The headless path now relies on the same invariant as interactive updates, eliminating code duplication and ensuring consistent behavior across all update paths.

  • Infrastructure Headless startup license validation guard

    Added fail-fast behavior for license validation failures during headless (background service) runs. When running unattended without an interactive desktop, license configuration windows cannot be displayed, so the service now exits cleanly with an error log instead of hanging indefinitely.

  • Documentation Updated auto-update help article

    Revised `docs/marginmaster/getting-started/auto-updates.md` to document the 7-day maximum ignore window, remove references to the "1 Month" snooze option, clarify that force-install overrides both snooze and "Require approval," and add technical notes on `AutoUpdateDeferredSince` and the `UpdateDeferralPolicy` flow. Search keywords expanded to include "maximum snooze," "7 days," "forced update," "required update," and "weekly update."

  • Documentation Background Service setup guide

    Added comprehensive documentation explaining Background Service installation, account selection (Local System vs. specific Windows user), scheduling configuration, and troubleshooting. The guide clarifies when credentials are needed and explains the coordination between interactive and service runs.

  • Infrastructure Application uninstaller service safety guards

    ApplicationUninstallerService now refuses substring matching on generic SQL identifiers (SQL, SQL Server, Microsoft SQL Server, SQL Express, Server, Microsoft) to prevent hitting shared SQL components or other applications' SQL instances. Only exact displayName or productCode matches are honored for these terms.

MI9PaladinDoitBestCloudSyncAceHardware
2026.720.41308
July 21, 2026

Release notes aren't available for this version.

2026.719.17366
July 19, 2026

Release notes aren't available for this version.

2026.718.38252
July 19, 2026

Release notes aren't available for this version.

2026.718.32104
July 18, 2026

Release notes aren't available for this version.

2026.715.22883
July 15, 2026

Release notes aren't available for this version.

2026.715.16736
July 15, 2026

Release notes aren't available for this version.

2026.714.39211
July 15, 2026

Release notes aren't available for this version.

2026.714.22267
July 14, 2026

Release notes aren't available for this version.

2026.710.25782
July 10, 2026

Release notes aren't available for this version.

2026.709.40905
July 10, 2026

Release notes aren't available for this version.

2026.708.33799
July 8, 2026

Release notes aren't available for this version.

2026.708.20868
July 8, 2026

Release notes aren't available for this version.

2026.706.17681
July 6, 2026

Release notes aren't available for this version.

2026.705.40742
July 6, 2026

Release notes aren't available for this version.

2026.705.35352
July 6, 2026

Release notes aren't available for this version.

2026.703.37152
July 4, 2026

Release notes aren't available for this version.

2026.702.27644
July 2, 2026

Release notes aren't available for this version.

2026.701.36122
July 2, 2026

Release notes aren't available for this version.

2026.701.26298
July 1, 2026

Release notes aren't available for this version.

2026.630.42109
July 1, 2026

Release notes aren't available for this version.

2026.630.38651
July 1, 2026

Release notes aren't available for this version.

2026.630.29190
June 30, 2026

Release notes aren't available for this version.

2026.629.24466
June 29, 2026

Release notes aren't available for this version.

2026.625.28531
June 25, 2026

Release notes aren't available for this version.

2026.625.17255
June 25, 2026

Release notes aren't available for this version.

2026.624.22773
June 24, 2026

Release notes aren't available for this version.

2026.623.29692
June 23, 2026

Release notes aren't available for this version.

2026.623.26136
June 23, 2026

Release notes aren't available for this version.

2026.623.22436
June 23, 2026

Release notes aren't available for this version.

2026.622.41792
June 23, 2026

Release notes aren't available for this version.

2026.622.32577
June 22, 2026

Release notes aren't available for this version.

2026.620.38139
June 21, 2026

Release notes aren't available for this version.

2026.620.35280
June 20, 2026

Release notes aren't available for this version.

2026.619.42129
June 20, 2026

Release notes aren't available for this version.

2026.619.34215
June 19, 2026

Release notes aren't available for this version.

2026.619.25491
June 19, 2026

Release notes aren't available for this version.

2026.619.21736
June 19, 2026

Release notes aren't available for this version.

2026.619.19122
June 19, 2026

Release notes aren't available for this version.

2026.618.42254
June 19, 2026

Release notes aren't available for this version.

2026.617.22137
June 17, 2026

Release notes aren't available for this version.

2026.616.42389
June 17, 2026

Release notes aren't available for this version.

2026.616.34899
June 16, 2026

Release notes aren't available for this version.

2026.616.27515
June 16, 2026

Release notes aren't available for this version.

2026.615.41495
June 16, 2026

Release notes aren't available for this version.

2026.615.39565
June 16, 2026

Release notes aren't available for this version.

2026.615.24066
June 15, 2026

Release notes aren't available for this version.

2026.615.19906
June 15, 2026

Release notes aren't available for this version.

2026.614.41345
June 15, 2026

Release notes aren't available for this version.

2026.614.38449
June 15, 2026

Release notes aren't available for this version.

2026.613.40053
June 14, 2026

Release notes aren't available for this version.

2026.613.21567
June 13, 2026

Release notes aren't available for this version.

2026.612.36581
June 13, 2026

Release notes aren't available for this version.

2026.612.31268
June 12, 2026

Release notes aren't available for this version.

2026.612.21429
June 12, 2026

Release notes aren't available for this version.

2026.611.18275
June 11, 2026

Release notes aren't available for this version.

2026.611.16641
June 11, 2026

Release notes aren't available for this version.

2026.610.41619
June 11, 2026

Release notes aren't available for this version.

2026.610.39490
June 11, 2026

Release notes aren't available for this version.

2026.610.28461
June 10, 2026

Release notes aren't available for this version.

2026.610.24561
June 10, 2026

Release notes aren't available for this version.

2026.610.17857
June 10, 2026

Release notes aren't available for this version.

2026.610.51
June 10, 2026

Release notes aren't available for this version.

2026.607.22734
June 7, 2026

Release notes aren't available for this version.

2026.606.41221
June 7, 2026

Release notes aren't available for this version.

2026.606.38475
June 7, 2026

Release notes aren't available for this version.

2026.606.35914
June 7, 2026

Release notes aren't available for this version.

2026.606.27242
June 6, 2026

Release notes aren't available for this version.

2026.606.22857
June 6, 2026

Release notes aren't available for this version.

2026.606.21463
June 6, 2026

Release notes aren't available for this version.

2026.606.18773
June 6, 2026

Release notes aren't available for this version.

2026.605.22098
June 5, 2026

Release notes aren't available for this version.

2026.604.39231
June 5, 2026

Release notes aren't available for this version.

2026.604.38315
June 5, 2026

Release notes aren't available for this version.

2026.604.36418
June 5, 2026

Release notes aren't available for this version.

2026.604.29660
June 4, 2026

Release notes aren't available for this version.

2026.603.31077
June 3, 2026

Release notes aren't available for this version.

2026.602.17261
June 2, 2026

Release notes aren't available for this version.

2026.602.16192
June 2, 2026

Release notes aren't available for this version.

2026.601.29170
June 1, 2026

Release notes aren't available for this version.

2026.529.20827
May 29, 2026

Release notes aren't available for this version.

2026.529.18756
May 29, 2026

Release notes aren't available for this version.

2026.529.15986
May 29, 2026

Release notes aren't available for this version.

2026.528.32894
May 28, 2026

Release notes aren't available for this version.

2026.527.32326
May 27, 2026

Release notes aren't available for this version.

2026.526.37855
May 27, 2026

Release notes aren't available for this version.

2026.526.24162
May 26, 2026

Release notes aren't available for this version.

2026.523.25959
May 23, 2026

Release notes aren't available for this version.

2026.522.26011
May 22, 2026

Release notes aren't available for this version.

2026.522.19262
May 22, 2026

Release notes aren't available for this version.

2026.521.35243
May 21, 2026

Release notes aren't available for this version.

2026.521.19729
May 21, 2026

Release notes aren't available for this version.

2026.518.30815
May 18, 2026

Release notes aren't available for this version.

2026.518.26689
May 18, 2026

Release notes aren't available for this version.

2026.515.35634
May 16, 2026

Release notes aren't available for this version.

2026.515.33975
May 15, 2026

Release notes aren't available for this version.

2026.514.29472
May 14, 2026

Release notes aren't available for this version.

2026.514.25819
May 14, 2026

Release notes aren't available for this version.

2026.513.30566
May 13, 2026

Release notes aren't available for this version.

2026.512.27183
May 12, 2026

Release notes aren't available for this version.

2026.509.38651
May 10, 2026

Release notes aren't available for this version.

2026.509.34728
May 9, 2026

Release notes aren't available for this version.

2026.509.22570
May 9, 2026

Release notes aren't available for this version.

2026.506.39790
May 7, 2026

Release notes aren't available for this version.

2026.506.38524
May 7, 2026

Release notes aren't available for this version.

2026.506.18409
May 6, 2026

Release notes aren't available for this version.

2026.505.21230
May 5, 2026

Release notes aren't available for this version.

2026.505.15991
May 5, 2026

Release notes aren't available for this version.

2026.504.24748
May 4, 2026

Release notes aren't available for this version.

2026.504.22288
May 4, 2026

Release notes aren't available for this version.

2026.504.19258
May 4, 2026

Release notes aren't available for this version.

2026.502.33814
May 2, 2026

Release notes aren't available for this version.

2026.502.30449
May 2, 2026

Release notes aren't available for this version.

2026.502.28241
May 2, 2026

Release notes aren't available for this version.

2026.501.24512
May 1, 2026

Release notes aren't available for this version.

2026.501.22177
May 1, 2026

Release notes aren't available for this version.

2026.501.18585
May 1, 2026

Release notes aren't available for this version.

2026.430.20659
April 30, 2026

Release notes aren't available for this version.

2026.429.17628
April 29, 2026

Release notes aren't available for this version.

2026.429.16223
April 29, 2026

Release notes aren't available for this version.

2026.427.38765
April 28, 2026

Release notes aren't available for this version.

2026.427.28407
April 27, 2026

Release notes aren't available for this version.

2026.427.25039
April 27, 2026

Release notes aren't available for this version.

2026.426.17819
April 26, 2026

Release notes aren't available for this version.

2026.425.30792
April 25, 2026

Release notes aren't available for this version.

2026.423.30682
April 23, 2026

Release notes aren't available for this version.

2026.423.28119
April 23, 2026

Release notes aren't available for this version.

2026.423.14775
April 23, 2026

Release notes aren't available for this version.

2026.422.29643
April 22, 2026

Release notes aren't available for this version.

2026.416.30491
April 16, 2026

Release notes aren't available for this version.

2026.416.29022
April 16, 2026

Release notes aren't available for this version.

2026.415.34220
April 15, 2026

Release notes aren't available for this version.

Connect with us

Margin Master by RetailerSoft, Inc. © 2026. All rights reserved.

Loading...

Reconnecting to the server...

This usually takes a few seconds.