@@ -42,21 +42,44 @@ export function getParcelForWeight(totalWeightLb: number) {
4242 * Expects items that carry either variant_weight_oz or product_weight_oz (both in oz).
4343 * Falls back to 2 oz per item if neither is set.
4444 */
45- export function calculateTotalWeightLb ( items : Array < {
46- quantity : number
47- variant_weight_oz ?: number | null
48- product_weight_oz ?: number | null
49- } > ) : number {
50- const totalOz = items . reduce ( ( acc , item ) => {
51- const weightOz =
52- ( item . variant_weight_oz && item . variant_weight_oz > 0 )
53- ? item . variant_weight_oz
54- : ( item . product_weight_oz && item . product_weight_oz > 0 )
55- ? item . product_weight_oz
56- : 2 // default 2oz fallback
57- return acc + weightOz * item . quantity
58- } , 0 )
59- return totalOz / 16
45+ export function calculateTotalWeightLb (
46+ items : Array < {
47+ quantity : number ;
48+ variant_weight_oz : number | null ;
49+ product_weight_oz : number | null ;
50+ } >
51+ ) : number {
52+ let totalOz = 0 ;
53+
54+ for ( const item of items ) {
55+ // Validate quantity
56+ const qty = Math . max ( 1 , item . quantity || 1 ) ;
57+
58+ // Get weight with validation
59+ let weightOz = item . variant_weight_oz ?? item . product_weight_oz ?? 2 ;
60+
61+ // Safety checks
62+ if ( isNaN ( weightOz ) || weightOz <= 0 ) {
63+ console . warn ( `Invalid weight detected for item, using 2oz fallback:` , item ) ;
64+ weightOz = 2 ;
65+ }
66+
67+ // Cap at 160oz (10 lbs) per item to prevent calculation errors
68+ if ( weightOz > 160 ) {
69+ console . warn ( `Unusually heavy item detected (${ weightOz } oz), capping at 160oz` ) ;
70+ weightOz = 160 ;
71+ }
72+
73+ totalOz += weightOz * qty ;
74+ }
75+
76+ // Convert to pounds
77+ const totalLbs = totalOz / 16 ;
78+
79+ // Log for debugging
80+ console . log ( `[Weight Calc] Total: ${ totalOz } oz = ${ totalLbs . toFixed ( 2 ) } lbs from ${ items . length } items` ) ;
81+
82+ return totalLbs ;
6083}
6184
6285export function calculateShippingRate (
@@ -65,12 +88,12 @@ export function calculateShippingRate(
6588 config : any ,
6689 type : 'standard' | 'express' | 'intl_standard' | 'intl_express'
6790) : { cost : number ; name : string ; minDays : number ; maxDays : number } {
68- // Free shipping check (US only)
91+ // Free shipping check (US domestic only)
6992 const freeThreshold = parseFloat ( config . free_shipping_threshold ?? '100' ) ;
7093 if ( type === 'standard' && subtotal >= freeThreshold ) {
7194 return {
7295 cost : 0 ,
73- name : config . standard_label || 'Free Standard Shipping' ,
96+ name : config . standard_label || 'Free Standard Shipping 🎁 ' ,
7497 minDays : 3 ,
7598 maxDays : 5 ,
7699 } ;
@@ -85,33 +108,35 @@ export function calculateShippingRate(
85108 switch ( type ) {
86109 case 'standard' :
87110 brackets = config . weight_brackets || DEFAULT_US_STANDARD_BRACKETS ;
88- name = config . standard_label || 'USPS Ground Advantage (3-5 Days )' ;
111+ name = config . standard_label || 'USPS Ground Advantage (US )' ;
89112 minDays = 3 ;
90113 maxDays = 5 ;
91114 break ;
92115 case 'express' :
93116 brackets = config . express_weight_brackets || DEFAULT_US_EXPRESS_BRACKETS ;
94- name = config . express_label || 'USPS Priority Mail (1-3 Days )' ;
117+ name = config . express_label || 'USPS Priority Mail (US )' ;
95118 minDays = 1 ;
96119 maxDays = 3 ;
97120 break ;
98121 case 'intl_standard' :
99122 brackets = config . intl_weight_brackets || DEFAULT_INTL_STANDARD_BRACKETS ;
100- name = 'USPS Priority Mail International' ;
123+ name = 'USPS Priority Mail International 🌍 ' ;
101124 minDays = 6 ;
102125 maxDays = 10 ;
103126 break ;
104127 case 'intl_express' :
105128 brackets = config . intl_express_weight_brackets || DEFAULT_INTL_EXPRESS_BRACKETS ;
106- name = 'USPS Priority Mail Express International' ;
129+ name = 'USPS Priority Mail Express International 🚀 ' ;
107130 minDays = 3 ;
108131 maxDays = 5 ;
109132 break ;
110133 }
111134
112- // Find matching bracket (first bracket where weight <= max_lb)
135+ // Find matching bracket
113136 const matchingBracket = brackets . find ( ( b ) => weightLb <= b . max_lb ) ;
114- const cost = matchingBracket ? parseFloat ( String ( matchingBracket . rate ) ) : parseFloat ( String ( brackets [ brackets . length - 1 ] ?. rate ?? 15.99 ) ) ;
137+ const cost = matchingBracket
138+ ? parseFloat ( String ( matchingBracket . rate ) )
139+ : parseFloat ( String ( brackets [ brackets . length - 1 ] ?. rate ?? 15.99 ) ) ;
115140
116141 return { cost, name, minDays, maxDays } ;
117142}
0 commit comments