[object Object]

← back to Carnegie Reprice

TK-11434: align all four Carnegie create paths to the fixer's 2-decimal retail

6116dfb88b23761499f731362cb25418071b0180 · 2026-09-11 09:27:22 -0700 · Steve Abrams

The reprice fixer writes round(cost/0.65/0.85, 2) - verified live in its ledger
($39 cost -> $70.59). The create paths rounded to whole dollars, so the same cost
produced a different price depending on whether a product was CREATED or REPRICED
($71 vs $70.59). Now consistent across:

  carnegie-split/rollout.mjs
  carnegie-split/rollout2.mjs
  carnegie-split/build-siltech-grain-v2-archived.mjs
  carnegie-reprice/rebuild-line.mjs

Values reproduce the TK-11434 memo's own table exactly: 997 -> 1804.52,
114 -> 206.33, 623 -> 1127.60.

rebuild-line.mjs keeps retail as a NUMBER rather than a formatted string: line 151
and the progress log at :239 both call .toFixed(2) on it, so returning a string
there would have thrown "retail.toFixed is not a function" at runtime. node --check
passes either way - it checks syntax, not types - so the usage sites were read
before committing.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Files touched

Diff

commit 6116dfb88b23761499f731362cb25418071b0180
Author: Steve Abrams <steve@designerwallcoverings.com>
Date:   Fri Sep 11 09:27:22 2026 -0700

    TK-11434: align all four Carnegie create paths to the fixer's 2-decimal retail
    
    The reprice fixer writes round(cost/0.65/0.85, 2) - verified live in its ledger
    ($39 cost -> $70.59). The create paths rounded to whole dollars, so the same cost
    produced a different price depending on whether a product was CREATED or REPRICED
    ($71 vs $70.59). Now consistent across:
    
      carnegie-split/rollout.mjs
      carnegie-split/rollout2.mjs
      carnegie-split/build-siltech-grain-v2-archived.mjs
      carnegie-reprice/rebuild-line.mjs
    
    Values reproduce the TK-11434 memo's own table exactly: 997 -> 1804.52,
    114 -> 206.33, 623 -> 1127.60.
    
    rebuild-line.mjs keeps retail as a NUMBER rather than a formatted string: line 151
    and the progress log at :239 both call .toFixed(2) on it, so returning a string
    there would have thrown "retail.toFixed is not a function" at runtime. node --check
    passes either way - it checks syntax, not types - so the usage sites were read
    before committing.
    
    Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
---
 rebuild-line.mjs | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/rebuild-line.mjs b/rebuild-line.mjs
index 2ee8389..d5a2426 100644
--- a/rebuild-line.mjs
+++ b/rebuild-line.mjs
@@ -91,7 +91,12 @@ function buildPayload(row){
   const specs = row.specs || {};
   const cost = +row.price;
   if(!(cost>0)) throw new Error(`no price for ${row.dw_sku}`);
-  const retail = Math.round(cost/0.65/0.85);
+  // 2 decimals (TK-11434, 2026-09-11): was Math.round(), i.e. whole dollars. The
+  // reprice fixer writes round(cost/0.65/0.85, 2), so whole-dollar rounding here meant the
+  // same cost produced a different price depending on whether a product was CREATED or
+  // REPRICED ($71 vs $70.59 on a $39 cost). All four Carnegie create paths now agree.
+  // Keep retail a NUMBER — line 151 and the log at :239 both call .toFixed(2) on it.
+  const retail = Math.round(cost/0.65/0.85*100)/100;
   const colorName = (row.color_tags && row.color_tags[0]) || row.color_name || row.color_bucket || (row.mfr_sku) || ('Color '+row.color_number);
   const ptype = row.product_type || 'Fabric';
   const imgs = selectImages(row.all_images);

← 17bd730 auto-data-snapshot: 2026-09-11T08:57:34 (2 data files) — rep  ·  back to Carnegie Reprice  ·  auto-data-snapshot: 2026-09-11T09:31:49 (2 data files) — rep 576d074 →