Cotton PO Template — Fixes Plan
Sheet: Cotton PO Template 16Gx-N9HK35MSLZfz5DAGJ6FhHN6u2VLdruwmiXIL4lE
Apps Script: scriptId 1BV0ubVbA5xMr5-IL3oPpPxuXwWG5CVZN5M3qkY3QoYoAcCWJiboAxHy8, deploy via clasp push from ~/ai-projects-local/cotton-po-scripts/rb-cotton-po/
Related memory: [[cotton-po-clasp-and-overrides]], [[rbd-collection-ordering-tiers]]
Objective
Fix four defects in the Cotton PO generator so the Feb-2027 (081526) collection POs total correctly and price correctly, without breaking the override columns or the clasp deploy path.
Decisions locked with Cole (2026-08-11 Q&A)
- Dropship units → excluded from Ship-to-RBD columns only; still counted in the row-35 mill PO grand total (mill still makes them).
- Panels → both the yardage math AND the rate/surcharge are wrong; some of it is expected to be hand-edited by Sabrina (so leave editable, don't fully hardcode).
- Rates → base per-yard rate is FINE; only the D/R surcharge is wrong.
- D/R surcharge mechanism → driven by the PO's mill/vendor, which already lives in the Data and Collections tabs (reuse it — no new manual tag).
- Surcharge build → one Standard surcharge everywhere + a Taihan override (only Taihan differs today).
Root causes found (verified in-sheet + in code)
Two divergent column layouts (drives Fix 1)
- Master Template / Template (canonical):
M=# bolts ·N–T=Ship-to-RBD (15 D/R, 10 D/R, ROT, Laminate, …) ·U–Y=Dropship slots (row 8 = "PO #") ·Z=Rate ·AA=Amount ·AB/AC=D/R 15/10 Surcharge ·AD=Laminate Surcharge ·AE=Total. Grand total = row 35. - Generated tabs (e.g. HOORAYUSA-081526): shifted ~2 cols left, 27 cols, no dropship region, no laminate col — Ship-to-RBD =
L–P, Total =U, grand total = row 34. Dropship POs.jsinserts columns at hardcodedSTART_COL = U1 = 21and copies the formula from col U. On a generated tab col U = Total, so the insertion lands on the pricing/total block → corrupts the row-35 grand total and mis-aligns Ship-to-RBD. Same hardcoded-index fragility class as theDATA_COLconstants.
Rates.js drops the surcharge (drives Fix 3)
buildSimplePricingLookup_()readssurcharge(Simple Pricing col Q) into the lookup, butupdateBaseRates()writes onlymatch.rateto Data "Base Rate". The surcharge is never written. Per-line D/R 15/10 surcharge (template cols AB/AC) is computed by in-sheet formula, not by mill.
Exact formula-level diagnosis (Master Template, verified 2026-08-11)
Data cols: AJ=Item(matchkey), AL=D/R or Units(qty), AQ=Laminate, AR=CP10, AT=CP15, BC=Vendor(mill), BD=PO#, BG=Base Rate, BI=Rate.
Master sections: Cotton 12–34 (TOTAL 35) · PRECUTS 39–52 · DESIGN BOARDS 56–67 · KIT 68–81 / 82–94 · casepack sub-table 70–93 · precut breakout 109–220. Panels (1P-) are excluded from the cotton QUERY — need to confirm where 1P lands + whether it gets a base-rate lookup.
Root cause A — grand total row 35 breaks on dropship insert.
Every row-35 cell = =SUM(INDIRECT("AE12:AE"&ROW()-1)) — hardcoded column LETTER inside INDIRECT. INDIRECT does not follow column insertions. Dropship inserts at col U push the pricing block (Rate/Amount/Surcharge/Total, Z–AE) one col right to AA–AF, but AE35's INDIRECT still sums old col AE (now a surcharge col) → grand total wrong.
→ Fix: make each row-35 sum reference its OWN column: =SUM(INDIRECT("R12C"&COLUMN()&":R"&(ROW()-1)&"C"&COLUMN(),FALSE)). Robust to both row inserts (ROW()) and column inserts (COLUMN()).
Root cause B — Ship-to-RBD (N/O) + surcharges (AB/AC) miss dropship cols.
N12/O12/AB12/AC12 subtract dropship via FILTER(U12:X12, LEFT(U$10:X$10,4)="CP15"…) — hardcoded 4-col range U:X, but the dropship block is U–Y (5) and GROWS when the script inserts more. Columns past X aren't subtracted → Ship-to-RBD overstated (includes dropship it should exclude) and surcharge base misses those units.
→ Fix: replace U:X with a range spanning the whole dropship block = U through the col left of "Rate" (anchor right edge via MATCH("Rate",$11:$11,0)), using INDIRECT so it self-extends as columns are inserted.
Root cause C — D/R-10 surcharge rate is a flat literal.
AB12 = (…)*0.15 (D/R-15, correct everywhere). AC12 = (…)*0.2 (D/R-10) — hardcoded 0.2, never Taihan's 0.17.
→ Fix: AC12 = (…) * IF(INDEX(Data!BC:BC,MATCH($A12,Data!AJ:AJ,0))="TaiHan Textile Co., Ltd.", 0.17, 0.2). D/R-15 (AB, 0.15) stays literal — identical for all mills.
Panels (Fix 2): ensure the panel (1P-) section carries a base-rate lookup INDEX(Data!BG:BG, MATCH(sku,Data!AJ:AJ,0)); size (24/36/56) + qty stay manual for Sabrina.
Implementation plan
Fix 1 — Dropship no longer breaks grand total / Ship-to-RBD
- Re-anchor
Dropship POs.jsinsertion point dynamically instead of hardcodedU=21: locate the dropship region by label (row 8 "PO #" run, or a fixed marker column relative to the "Rate" header) so it works regardless of whether the tab has a Laminate column. - Make the row-35 grand total and Ship-to-RBD sums reference columns by structure/label so inserted dropship columns don't shift them.
- Accounting: grand total (mill PO) SUMs cotton + precut + kit incl. dropship; Ship-to-RBD SUMs exclude the dropship slot columns. Verify both after a dropship insert.
- Apply the same fix to the precut and kit Ship-to-RBD sub-totals (Cole flagged those specifically).
Fix 2 — Panels
- Yardage math: correct the
yds/pnls(col L) → Total-yds conversion for panel SKUs (1P-prefix). [OPEN: exact correct rule — see Open Items.] - Rate/surcharge: panels should not carry the per-yard cotton rate + D/R surcharge blindly. [OPEN: correct panel rate rule.] Leave the panel rate/qty cells editable so Sabrina can override.
Fix 3 — D/R surcharge by mill (Standard + Taihan override)
- Build a small, readable Standard vs Taihan surcharge reference (D/R 15 + D/R 10 values).
- Wire the template's D/R 15/10 surcharge (cols AB/AC) to pick Standard vs Taihan based on the PO's vendor/mill from Data/Collections (vendor already populated per line via Data col BC / Collections).
- Leave
updateBaseRates()writing base rate as-is (base rate is correct); the surcharge change is formula-side keyed on mill.
Answers (2026-08-11, round 2) + revised approach
Approach: update the corrected Master Template layout into each collection sheet, then add functionality to the supporting sheets (Simple Pricing surcharge table + mill logic). Not a from-scratch rebuild.
Surcharge values (per-yard, multiplied by the D/R yardage):
- Standard (all mills): D/R-15 = $0.15/yd, D/R-10 = $0.20/yd
- Taihan override: D/R-15 = $0.15/yd, D/R-10 = $0.17/yd
- → Only the D/R-10 rate differs for Taihan (.20 → .17). D/R-15 identical everywhere. So the override is a single conditional on the D/R-10 surcharge.
- Taihan vendor string:
TaiHan Textile Co., Ltd.(match against Data/Collections vendor).
Panels: per-panel; sizes vary (24" / 36" / 56") — messy, so keep manual for Sabrina. But base rate must pull in (currently suspected NOT pulling). Confirm panel SKUs (1P-/P) get a base rate from Simple Pricing; leave size/qty editable.
Still open
- ☐ Propagation method — edit each existing collection tab in place vs. re-push corrected master (affects whether Sabrina's in-progress qty/overrides survive). ← next question
- ☐ Confirm which tabs are live vs. TEST/Copy scratch.
Sequencing
- Fix 1 (dropship/totals) — highest blast radius, unblocks correct PO totals.
- Fix 3 (D/R surcharge by mill) — pricing correctness.
- Fix 2 (panels) — partly manual; do after 1 & 3, coordinate editable cells with Sabrina.
Verification
- clasp workflow:
clasp pull→ edit →node --check *.js→clasp push -f. - After each fix, regenerate one collection tab (e.g. HOORAYUSA) + one with dropships and one Taihan PO; confirm: row-35 grand total, Ship-to-RBD (incl. precut/kit), and D/R surcharge all tie out. Snapshot before/after.
- Do NOT write to the live sheet while Cole/Sabrina is editing (sheet-level lock causes API timeouts).
Risks / guardrails
- Live pricing sheet — verify each formula reproduces expected values on a sample before rolling across tabs (batik-retrofit gate pattern).
- Hardcoded
DATA_COLindices in Apps Script break on any Data column insert — re-audit against live headers if touched. - Never commit
.claude/; clasp auth in~/.clasprc.json.
~/ai-projects/mission-control/plans/cotton-po-fixes.md