Takazudo Modular Docs

Type to search...

to open search from anywhere

l-addac-price-list-convert

l-addac-price-list-convert

Convert an ADDAC System retail pricelist PDF/HTML into structured JSON for the ADDAC Order Calculator app.

Usage

/l-addac-price-list-convert <path-to-pdf-or-html>

The source file should be an ADDAC System Retail Pricelist (PDF or HTML conversion). If given a PDF, use the Read tool to extract its contents. If the PDF is not readable, convert it to HTML first (e.g., via pnpm dlx pdf-to-html or similar) and save to __inbox/.

Steps

  1. Read the source file using the Read tool. For large files, read in chunks.

  2. Identify all sections by their headings. The pricelist is organized into:

    • Module sections (under “STANDALONE” and “MODULES” headings)
    • Frame sections (under “FRAMES & 19” RACK UTILITIES” heading)
    • Accessory sections (under “ACCESSORIES & OTHER” heading)
  3. Extract all product items from each table. Each row contains:

    • SKU (first column)
    • Name (second column)
    • Price columns (varies by section type, see below)
    • MSRP (last column)
  4. Map discount tiers per section type:

    Modules (discountType: “modules”)

    5 price columns: lt3 (<3, 15% off), gte3 (>=3, 20%), gte5 (>=5, 23%), gte7 (>=7, 26%), gte10 (>=10, 30%)

    Applies to sections:

    • standalone - “STANDALONE”
    • addac10x - “ADDAC10X Series”
    • addac20x - “ADDAC20X Series”
    • addac30x - “ADDAC30X Series”
    • addac40x - “ADDAC40X Series”
    • addac50x - “ADDAC50X Series”
    • addac60x - “ADDAC60X Series”
    • addac70x - “ADDAC70X Series”
    • addac80x - “ADDAC80X Series”
    • addac90x - “ADDAC90X Series”

    Frames (discountType: “frames”)

    2 price columns: lt5 (<5, 10% off), gte5 (>=5, 13%)

    Applies to sections:

    • frames-busboards - “Busboards”
    • frames-portable - “Portable Frames”
    • frames-flat - “Flat Frames”
    • frames-tabletop - “Tabletop Frames”
    • frames-monster - “Monster Frames”
    • frames-wheeled-carts - “Wheeled Carts”
    • frames-rack-3u - ‘19” Rack 3U’
    • frames-rack-utilities - “Rack Utilities”

    Accessories (discountType: “accessories”)

    2 price columns: lt3 (<3, 10% off), gte3 (>=3, 15%)

    Applies to sections:

    • accessories - “Accessories”
    • accessories-stands - “Stands”

    Cable Holders (discountType: “cable-holder”)

    2 price columns: lt3 (<3, 15% off), gte3 (>=3, 20%)

    Applies to sections:

    • accessories-cable-holder - “Cable Holders”
  5. Parse prices as numbers. Strip the currency symbol (e.g., “€252.00” -> 252.00). Remove comma separators (e.g., “€1,258.00” -> 1258.00).

  6. Mark discontinued items with "discontinued": true. Look for the CSS class discontinued or “(DISCONTINUED …)” in the name. Extract the discontinuation note into the notes field and remove it from the name.

  7. Write the output to: sub-packages/addac-order/src/data/addac-products.json

Output JSON Schema

type DiscountType = 'modules' | 'frames' | 'accessories' | 'cable-holder';

interface ModulePrices {
  lt3: number;   // <3 individual (15% off MSRP)
  gte3: number;  // >=3 (20%)
  gte5: number;  // >=5 (23%)
  gte7: number;  // >=7 (26%)
  gte10: number; // >=10 (30%)
}

interface FramePrices {
  lt5: number;   // <5 individual (10% off)
  gte5: number;  // >=5 (13% off)
}

interface AccessoryPrices {
  lt3: number;   // <3 (10% off)
  gte3: number;  // >=3 (15% off)
}

interface CableHolderPrices {
  lt3: number;   // <3 (15% off)
  gte3: number;  // >=3 (20% off)
}

interface ProductItem {
  sku: string;
  name: string;
  msrp: number;
  prices: ModulePrices | FramePrices | AccessoryPrices | CableHolderPrices;
  discontinued?: boolean;
  notes?: string;
}

interface Section {
  id: string;          // kebab-case slug
  name: string;        // display name
  discountType: DiscountType;
  items: ProductItem[];
}

interface ProductData {
  source: string;      // e.g. "ADDAC System Retail Pricelist - February 2026"
  generatedAt: string; // ISO date string
  sections: Section[];
}

PDF Quirks

  • Module tables have 8 columns: SKU, Name, 5 price tiers, MSRP
  • Frame/accessory/cable-holder tables have 5 columns: SKU, Name, 2 price tiers, MSRP
  • The ADDAC90X series appears twice: once under Modules (power delay modules) and once under Frames (busboards). They are different products
  • Cable Holders have their own discount structure (15%/20%) distinct from other accessories (10%/15%)
  • Stands use the accessories discount type (10%/15%), not frames
  • Some SKUs contain spaces (e.g., “ADDAC814 JACKS+CONTROLS”, “ADDAC901M 15U”)
  • Product names may contain HTML entities in source (& -> &, > -> >)
  • Discontinued items may have “(DISCONTINUED <date>)” appended to their name - extract this to notes and clean the name

Verification

After generating, verify:

  • Total section count matches expected (currently 21)
  • Total item count matches the source (currently 145)
  • Discontinued items are correctly flagged
  • Price values are numbers, not strings
  • Each section has the correct discountType and price field structure

Step 8: Check for missing product URLs

After writing addac-products.json, check which SKUs are missing from the URL mapping:

  1. Read src/data/addac-urls.json (the SKU → official product page URL mapping)
  2. Compare all SKUs in the newly written sub-packages/addac-order/src/data/addac-products.json against the URL map
  3. If any SKUs are missing from addac-urls.json:
    • List the missing SKUs
    • Web-search for each missing SKU: site:addacsystem.com {SKU} (e.g. site:addacsystem.com ADDAC999)
    • Find the official product page URL on https://www.addacsystem.com/
    • Add any found URLs to src/data/addac-urls.json, keeping the JSON alphabetically sorted by SKU
  4. If no SKUs are missing, confirm: “All SKUs have URL mappings.”

This ensures addac-urls.json stays up to date whenever new products appear in the pricelist.