@@ -60,73 +60,90 @@ export function calculateTotalWeightLb(items: Array<{
6060}
6161
6262export function calculateShippingRate (
63- totalWeightLb : number ,
64- subtotal : number ,
65- config : any ,
66- option : 'standard' | 'express'
63+ weightLb : number ,
64+ subtotal : number ,
65+ config : any ,
66+ type : 'standard' | 'express' | 'intl_standard' | 'intl_express '
6767) : { cost : number ; name : string ; minDays : number ; maxDays : number } {
68- const freeThreshold = parseFloat ( config . free_shipping_threshold ?? "100" ) ;
69-
70- if ( option === 'express' ) {
71- const brackets = ( config . express_weight_brackets && config . express_weight_brackets . length > 0 )
72- ? config . express_weight_brackets
73- : [
74- { max_lb : 1 , rate : 9.99 } ,
75- { max_lb : 3 , rate : 14.99 } ,
76- { max_lb : 999 , rate : 19.99 }
77- ] ;
78-
79- // Find the first bracket where weight <= max_lb
80- const bracket = brackets . find ( ( b : any ) => totalWeightLb <= b . max_lb ) || brackets [ brackets . length - 1 ] ;
81-
82- return {
83- cost : bracket ? parseFloat ( bracket . rate . toString ( ) ) : parseFloat ( config . express_rate ?? "19.99" ) ,
84- name : config . express_label || "USPS Priority Mail (1-3 Days)" ,
85- minDays : 1 ,
86- maxDays : 3
87- } ;
88- }
89-
90- // Standard Option
91- if ( subtotal >= freeThreshold ) {
92- return {
93- cost : 0 ,
94- name : "Free Standard Shipping" ,
95- minDays : 3 ,
96- maxDays : 5
97- } ;
98- }
99-
100- // Bracket evaluation
101- const brackets = ( config . weight_brackets && config . weight_brackets . length > 0 )
102- ? config . weight_brackets
103- : [
104- { max_lb : 0.5 , rate : 4.99 } ,
105- { max_lb : 1 , rate : 6.99 } ,
106- { max_lb : 2 , rate : 8.99 } ,
107- { max_lb : 5 , rate : 12.99 } ,
108- { max_lb : 999 , rate : 15.99 }
109- ] ;
110-
111- const bracket = brackets . find ( ( b : any ) => totalWeightLb <= b . max_lb ) || brackets [ brackets . length - 1 ] ;
112- if ( bracket ) {
113- return {
114- cost : parseFloat ( bracket . rate . toString ( ) ) ,
115- name : config . standard_label || "USPS Ground Advantage (3-5 Days)" ,
116- minDays : 3 ,
117- maxDays : 5
118- } ;
119- }
120-
121- // Fallback to flat rate
68+ // Free shipping check (US only)
69+ const freeThreshold = parseFloat ( config . free_shipping_threshold ?? '100' ) ;
70+ if ( type === 'standard' && subtotal >= freeThreshold ) {
12271 return {
123- cost : parseFloat ( config . standard_rate ?? "7.99" ) ,
124- name : config . standard_label || "USPS Ground Advantage (3-5 Days)" ,
125- minDays : 3 ,
126- maxDays : 5
72+ cost : 0 ,
73+ name : config . standard_label || 'Free Standard Shipping' ,
74+ minDays : 3 ,
75+ maxDays : 5 ,
12776 } ;
77+ }
78+
79+ // Select bracket config
80+ let brackets : Array < { max_lb : number ; rate : number } > = [ ] ;
81+ let name = '' ;
82+ let minDays = 3 ;
83+ let maxDays = 5 ;
84+
85+ switch ( type ) {
86+ case 'standard' :
87+ brackets = config . weight_brackets || DEFAULT_US_STANDARD_BRACKETS ;
88+ name = config . standard_label || 'USPS Ground Advantage (3-5 Days)' ;
89+ minDays = 3 ;
90+ maxDays = 5 ;
91+ break ;
92+ case 'express' :
93+ brackets = config . express_weight_brackets || DEFAULT_US_EXPRESS_BRACKETS ;
94+ name = config . express_label || 'USPS Priority Mail (1-3 Days)' ;
95+ minDays = 1 ;
96+ maxDays = 3 ;
97+ break ;
98+ case 'intl_standard' :
99+ brackets = config . intl_weight_brackets || DEFAULT_INTL_STANDARD_BRACKETS ;
100+ name = 'USPS Priority Mail International' ;
101+ minDays = 6 ;
102+ maxDays = 10 ;
103+ break ;
104+ case 'intl_express' :
105+ brackets = config . intl_express_weight_brackets || DEFAULT_INTL_EXPRESS_BRACKETS ;
106+ name = 'USPS Priority Mail Express International' ;
107+ minDays = 3 ;
108+ maxDays = 5 ;
109+ break ;
110+ }
111+
112+ // Find matching bracket (first bracket where weight <= max_lb)
113+ 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 ) ) ;
115+
116+ return { cost, name, minDays, maxDays } ;
128117}
129118
119+ // Default brackets (fallback if DB config missing)
120+ const DEFAULT_US_STANDARD_BRACKETS = [
121+ { max_lb : 0.5 , rate : 4.99 } ,
122+ { max_lb : 1 , rate : 6.99 } ,
123+ { max_lb : 2 , rate : 8.99 } ,
124+ { max_lb : 5 , rate : 12.99 } ,
125+ { max_lb : 999 , rate : 15.99 } ,
126+ ] ;
127+
128+ const DEFAULT_US_EXPRESS_BRACKETS = [
129+ { max_lb : 1 , rate : 9.99 } ,
130+ { max_lb : 3 , rate : 14.99 } ,
131+ { max_lb : 999 , rate : 19.99 } ,
132+ ] ;
133+
134+ const DEFAULT_INTL_STANDARD_BRACKETS = [
135+ { max_lb : 1 , rate : 19.99 } ,
136+ { max_lb : 3 , rate : 29.99 } ,
137+ { max_lb : 5 , rate : 39.99 } ,
138+ { max_lb : 999 , rate : 59.99 } ,
139+ ] ;
140+
141+ const DEFAULT_INTL_EXPRESS_BRACKETS = [
142+ { max_lb : 1 , rate : 49.99 } ,
143+ { max_lb : 3 , rate : 69.99 } ,
144+ { max_lb : 999 , rate : 89.99 } ,
145+ ] ;
146+
130147export async function createShippingLabel ( order : any ) {
131148 const apiKey = process . env . SHIPPO_API_KEY ;
132149 if ( ! apiKey ) {
0 commit comments