MI9 Data Pipeline — Import to Main Table - Margin Master

Margin Master Handbook

Introduction
Part I · Installing
Part II · Introducing the Main Window
Part III · Initial Configuration
Part IV · Customizing the Workspace
Part V · Basic Application Functionality
Part VI · Learning Margin Master
Part VII · Advanced Topics
Part VIII · Updates, Troubleshooting & Help
Appendix
Part III · Chapter 7 — Point of Sale: Connect, Configure, Import, TroubleshootUpdated 2026-08-20

MI9 Data Pipeline — Import to Main Table

What is this?

This document walks through the complete MI9 data pipeline — from the tab-delimited export files your MI9 system produces, through import and team-based aggregation, to the final main table that Margin Master uses for pricing analysis.

MI9 is unique among Margin Master's supported POS systems: instead of building one main table per store, it aggregates all stores into team-based main tables (e.g., Core, NonCore). This means you analyze pricing at the team level rather than the individual store level.

Overview

MM*.txt files (one per team, from MI9)
       |
       v
  [Import & Parse]
       |
       v
  Mi9PointOfSaleData table (raw per-store rows)
       |
       v
  [Team Aggregation]
       |
       v
  StoreGroup_{TeamName}_mainTable (one per team)
       |
       v
  [Ace Catalog Enrichment]
       |
       v
  Final main table (ready for pricing analysis)

Step 1: Prepare Your MI9 Export Files

File Requirements

Property Value
File pattern MM*.txt (e.g., MM_Team1.txt, MM_Team2.txt, MM_Unsequenced.txt)
Delimiter Tab
Header Yes (first row)
Encoding UTF-8
Total fields 75+ per row

Place your MI9 export files in the configured import folder (set in Options > Miscellaneous > Default Import Path). Margin Master discovers all files matching the MM*.txt pattern in that folder.

Import File Fields

Every row in the file represents one SKU at one store. The complete set of fields in the import file:

Identifiers

Field Description
StoreNumber MI9 branch code identifying the store
SKU Store-level SKU
AceSku Ace Hardware stock number (takes priority over SKU when present)
AltSKU Alternate SKU
UPC Universal Product Code

Product Information

Field Description
Description Product description
Department Store department code
Class Product class
ProductGroup Product group
Location Planogram / bin location
MfgNumber Manufacturer part number
PrivateLabel Private label indicator

Retail Price Levels

Field Description
Retail Base retail price
RetailLevel1 Price level 1
RetailLevel2 Price level 2
RetailLevel3 Price level 3
RetailLevel4 Price level 4
RetailLevel5 Price level 5 (MAPP pricing)
RetailZone Zone retail price
Level1Zone through Level5Zone Zone-level prices

Future Pricing

Field Description
FuturePrice Planned future retail price
FuturePriceMain Future price at the main level
FuturePriceMainDate Effective date for main-level future price
FuturePriceLevel2 Future price at level 2
FuturePriceLevel2Date Effective date for level 2 future price

Cost

Field Description
CurrentPrice Current selling price
StoreCost Store cost
AVGCost Average cost (weighted)
ReplacementCost Current replacement cost from vendor

Vendor

Field Description
PrimeVendor Primary vendor code
VendorNumber Vendor number
VendorName Vendor name
AVendor Alternate vendor code
Buyer Buyer code and name
VendorOwner Vendor owner code
P_Vendor P-vendor code

Competitive Pricing

Field Description
Comp1 through Comp5 Competitor price levels
CompA Competitor A price
CompMemo Competitor memo/notes
TaxRate Tax rate

Inventory & Sales History

Field Description
OnHand Current on-hand quantity
History1 through History12 Monthly sales units (12 rolling periods)
SalesUnits Total sales units
ItemWeight Item weight

Status & Flags

Field Description
ProductStatus Product-level status code
ProdStatus Product status (alternate field)
StoreProductStatus Store-level product status (see status codes below)
BlockedAutoChanges When set, prevents automatic price changes during strategy execution
Discontinued Discontinued flag
DiscontinuedDate Date item was discontinued
AceStopItem Ace stop-stock indicator
VelocityCode Velocity classification code
PricingStrategy Assigned pricing strategy code

User-Defined Fields

Field Description
UserS User string field S
UserO User string field O
UserP User string field P
UserE1 through UserE5 Extended user fields 1-5

Dates

Field Description
CreateDate Record creation date
LastUpdate Last record update date
LastPriceChange Date of last price change
LastCostChange Date of last cost change (optional field)

Discovery & Other

Field Description
DiscoveryC, DiscoveryN, DiscoveryS, DiscoveryU Ace Discovery tier codes
HDLChg Handle change flag
OrderMultiple Order multiple quantity
OrderMultipleSKU Order multiple SKU reference
StoreName Name of the MI9 store
StoreType Store type classification
TheTeam MI9 team assignment from export

Store Product Status Codes

The StoreProductStatus field uses these single-character codes:

Code Meaning
A Item shut off (store heading into conversion)
B Special Order SKU (one-time, not maintained)
C Live item (ordering and selling)
D Special Order Master SKU (not maintained)
N Not used
R Restricted by state/city (cannot sell)
S Store requested stop stocking (sell-down mode)
W Dead item (no stock, no longer maintained)
X Merged with another item

Step 2: Import Reads Files Into Staging Table

When you click Import Data, Margin Master:

  1. Discovers all MM*.txt files in the import folder
  2. Creates the Mi9PointOfSaleData staging table (drops and recreates each import)
  3. Parses each file row by row using high-performance tab parsing
  4. Maps each row to the data model using hardcoded field mappings
  5. Bulk-merges rows in batches of 10,000 into Mi9PointOfSaleData
  6. Creates indexes for fast lookups after all files are loaded

The staging table has a composite primary key of (StoreNumber, SKU) with duplicate-key handling, so if the same store+SKU appears in multiple files, the last value wins.

Large file handling: Files are processed in batches of 50,000 records for memory efficiency. Failed batches automatically retry up to 5 times with increasing wait times.

Step 3: Store Manager Controls Team Assignment

Before team tables are built, Margin Master checks the Mi9StoreManager table to determine which stores belong to which team.

Mi9StoreManager Field Purpose
BranchCode MI9 store identifier — must match StoreNumber in import files
GroupName Team name (e.g., "Core", "NonCore")
VendorStoreNumber Your Ace Hardware or vendor store number
Excluded If checked, this store is skipped during import
ZoneNumberAssigned Pricing zone assignment
ZoneNumberOverride Zone override (takes priority over assigned zone)

Team assignment: By default, store 500 is assigned to "NonCore" and all other stores to "Core". Your support team can customize these assignments.

Step 4: Team Aggregation Builds the Main Table

This is the key step that makes MI9 different from other POS systems. Instead of one main table per store, Margin Master groups all stores in a team together and produces one row per SKU per team.

For each team (e.g., Core, NonCore), a StoreGroup_{TeamName}_mainTable is created.

How Fields Are Aggregated

Since multiple stores may carry the same SKU, fields must be combined. Here is exactly how each main table field is populated:

Identifiers

Main Table Field Source Aggregation Notes
SKU AceSku or SKU Uses AceSku if present, otherwise original SKU
AltSKU SKU Always the original MI9 SKU (for traceability)
StoreNumber (literal) Always set to "G" (represents the group, not an individual store)
StoreGroup GroupName MAX Team name from Mi9StoreManager
UPC UPC MIN Takes the lowest UPC value across stores

Product Information

Main Table Field Source Aggregation
Description Description MAX
Dept Department MAX
Class Class MAX
ProductGroup ProductGroup MAX
Location Location MAX

Pricing — CurrentPrice Cascade

The CurrentPrice field uses a priority-based cascade across all stores carrying the item. Margin Master picks the first non-zero value in this order:

  1. FuturePriceLevel2 — if a Level 2 future price is set and > 0
  2. FuturePriceMain — if a main-level future price is set and > 0
  3. RetailLevel3 — if retail level 3 is > 0
  4. RetailLevel2 — if retail level 2 is > 0
  5. RetailLevel1 — default fallback

The result is the MAX value across all stores in the team for the winning priority level.

Pricing — Other Fields

Main Table Field Source Aggregation Notes
Comp1 RetailLevel1 MAX Competitor price level 1
Comp2 RetailLevel2 MAX Competitor price level 2
Comp3 RetailLevel3 MAX Competitor price level 3
Comp4 RetailLevel4 MAX Competitor price level 4
Comp5 RetailLevel5 MAX MAPP pricing
FuturePrice FuturePrice MAX Planned future retail
MemberRetail FuturePrice MAX Defaults to future price
TaxRate TaxRate MAX

Cost Fields

Cost fields are averaged only across stores that have inventory on hand:

Main Table Field Source Aggregation Condition
StoreCost AVGCost AVG Where OnHand > 0
Cost AVGCost AVG Where OnHand > 0
AverageCost AVGCost AVG Where OnHand > 0
ReplacementCost ReplacementCost MAX Where OnHand > 0
AverageCostInventoryValue AVGCost * OnHand SUM Total inventory value

Why only stores with inventory? Averaging cost across stores that don't carry the item would dilute the true cost. Only stores with on-hand inventory contribute to cost calculations.

Inventory & Sales (Summed Across All Stores)

Main Table Field Source Aggregation
OnHand OnHand SUM
History1 History1 SUM
History2 History2 SUM
... ... SUM
History12 History12 SUM

These are summed because you want to see total movement and total inventory across all stores in the team.

Vendor

Main Table Field Source Aggregation
PrimeVendor PrimeVendor (fallback: Vendor) MAX
AVendor AVendor (fallback: VendorNumber) MAX
Vendor Vendor MAX

User-Defined Fields

MI9 remaps user fields for its multi-store context:

Main Table Field MI9 Source Aggregation What It Means
User1 Buyer MAX Reformatted as "##-BuyerName" (e.g., "05-Smith")
User2 UserE2 MAX Extended user field 2
User3 StoreProductStatus MAX Representative status code for the SKU (see status codes above)
User4 (computed) "Y" if any store has a future price date in the future or a price change that took effect within the last 60 days, "N" otherwise
User5 BlockedAutoChanges "Y" if blocked, "N" otherwise
UserE5 (copy of User5) Duplicate of the blocked-auto-changes flag
UserS Buyer (reformatted) MAX
UserO UserO MAX
UserP UserP MAX

Date Fields

Main Table Field MI9 Source Logic
LastUpdate FuturePriceLevel2Date or FuturePriceMainDate Uses Level2 date if RetailLevel2 > 0, otherwise Main date. Only future dates. Displayed as "MI9 $ Change Date"
UserDatetime1 FuturePriceLevel2Date or FuturePriceMainDate Same source as LastUpdate, but keeps past dates too — the effective date of the most recent (or next) price change. Displayed as "Mi9 $ Effective Date"
LastPriceChange AceZoneRecords (post-build) Filled by the Ace catalog enrichment with the Ace vendor price-change date. Displayed as "Last Ace $ Change"
CreateDate CreateDate MAX, defaults to current date if null

Step 5: Ace Catalog Enrichment

After the team tables are built, Margin Master enriches each row with data from the Ace Hardware cloud catalog (synced separately via Cloud Sync).

Post-Build Updates

Main Table Field Source Table Logic
VendorOwned AceCatalogRecords "VEND" if the SKU exists in the Ace catalog, "NON" otherwise
Dept2 AceCatalogRecords Ace department
Class2 AceCatalogRecords Ace merchandise class
ProductGroup2 AceCatalogRecords Ace product group
VendorNumber AceCatalogRecords Ace vendor number
VendorName AceCatalogRecords Ace vendor name
PricingStrategy AceCatalogRecords Ace pricing strategy code
Ace_MapPriceAmt AceMappPricingRecords MAP (Minimum Advertised Price) amount
Ace_ImapPriceAmt AceMappPricingRecords IMAP price amount
Ace_MapLastUpdate AceMappPricingRecords MAP last update date

Zone Pricing (If Applicable)

If your stores have zone pricing configured, Margin Master applies zone-specific overrides from AceZoneRecords:

Main Table Field Source
RetailZone Zone retail price
Level1Zone through Level5Zone Zone-level prices
Ace_MSURetail MSU retail from zone data
Ace_AceRetailNew Ace retail new price

Step 6: Calculated Fields

After enrichment, Margin Master computes additional analysis fields:

Field Calculation
CMargin Current margin: (CurrentPrice - Cost) / CurrentPrice
FMargin Future margin: (FuturePrice - Cost) / FuturePrice
Last12 Sum of History1 through History12
Impact Revenue impact: (FuturePrice - CurrentPrice) * Last12
CPAceRetailVar Variance: CurrentPrice vs Ace Retail
FPAceRetailVar Variance: FuturePrice vs Ace Retail
CPFPVar Variance: CurrentPrice vs FuturePrice
CPFPDif Difference: FuturePrice - CurrentPrice

Impact Calculation (MI9-Specific)

For MI9, impact is calculated by joining the team table back to the per-store staging data using the AltSKU field. This gives a more accurate picture because it uses each store's actual current price and sales history rather than the aggregated values.

Per-SKU Impact = SUM across stores of:
    (Team FuturePrice - Store CurrentPrice) * Store Last12

Tips

"G" store number: In the main table, you'll see StoreNumber = "G" on every row. This is normal for MI9 — it means the row represents the entire store group (team), not an individual store.

AceSku takes priority: When the import file includes an AceSku value, that becomes the primary SKU in the main table. The original MI9 SKU is preserved in the AltSKU field for traceability.

Blocked auto-changes: If the BlockedAutoChanges field is set for a SKU, it appears as User5 = "Y" in the main table. During strategy execution, these SKUs are skipped — their prices won't be automatically changed.

Store not appearing? Check the Mi9StoreManager configuration. The store's BranchCode must match the StoreNumber in the import files, and the Excluded flag must not be checked.

Common Questions

Q: Why do I see "Core" and "NonCore" as my teams? A: By default, Margin Master assigns store branch 500 to "NonCore" and all other branches to "Core". Your support team can customize team assignments in the Mi9StoreManager configuration.

Q: How are costs calculated when some stores don't carry the item? A: Costs are averaged only across stores that have the item on hand (OnHand > 0). Stores with zero inventory don't contribute to the cost calculation, preventing artificial dilution.

Q: What is the CurrentPrice cascade? A: MI9 has multiple price levels. Margin Master picks the first non-zero value in priority order: FuturePriceLevel2 > FuturePriceMain > RetailLevel3 > RetailLevel2 > RetailLevel1. This ensures you always see the most relevant current price.

Q: Where does vendor catalog data come from? A: Vendor catalog fields (Dept2, Class2, ProductGroup2, VendorNumber, VendorName, MAP pricing) come from the Ace Hardware cloud catalog, which syncs separately via Cloud Sync. These fields are populated after the team tables are built.

Q: Can I add custom fields? A: MI9 imports support User fields (UserS, UserO, UserP, UserE1-E5). These map to User1-User5 and UserE1-UserE5 in the main table. Contact support if you need to customize what data appears in these fields.

Connect with us

Margin Master by RetailerSoft, Inc. © 2026. All rights reserved.

Loading...

Reconnecting to the server...

This usually takes a few seconds.