@@ -26,6 +26,7 @@ export interface CreateInvoiceResponse {
2626 hostedInvoiceUrl : string | null ;
2727 dashboardUrl : string ;
2828 amountCents : number ;
29+ subtotalCents : number ;
2930 ptbInvoiceId : string ;
3031}
3132
@@ -173,16 +174,8 @@ export class InvoicingManager {
173174 } ) ;
174175
175176 // 5. Create the invoice (in draft mode)
176- const periodStart = startDate . toLocaleDateString ( "en-US" , {
177- month : "short" ,
178- day : "numeric" ,
179- year : "numeric" ,
180- } ) ;
181- const periodEnd = endDate . toLocaleDateString ( "en-US" , {
182- month : "short" ,
183- day : "numeric" ,
184- year : "numeric" ,
185- } ) ;
177+ const periodStart = startDate . toISOString ( ) . split ( "T" ) [ 0 ] ;
178+ const periodEnd = endDate . toISOString ( ) . split ( "T" ) [ 0 ] ;
186179
187180 const invoice = await stripe . invoices . create ( {
188181 customer : stripeCustomerId ,
@@ -200,6 +193,7 @@ export class InvoicingManager {
200193
201194 // 6. Create invoice items with discounts applied
202195 let totalAmountCents = 0 ;
196+ let totalSubtotalCents = 0 ;
203197
204198 for ( const item of spendResult . data ) {
205199 const baseSubtotalUsd = parseFloat ( item . cost ) ;
@@ -216,11 +210,13 @@ export class InvoicingManager {
216210
217211 const discountPercent = findDiscount ( discounts , item . model , item . provider ) ;
218212 const totalUsd = subtotalUsd * ( 1 - discountPercent / 100 ) ;
213+ const subtotalCents = Math . round ( subtotalUsd * 100 ) ;
219214 const amountCents = Math . round ( totalUsd * 100 ) ;
220215
221216 if ( amountCents <= 0 ) continue ;
222217
223218 totalAmountCents += amountCents ;
219+ totalSubtotalCents += subtotalCents ;
224220
225221 const promptTokens = parseInt ( item . prompt_tokens , 10 ) || 0 ;
226222 const completionTokens = parseInt ( item . completion_tokens , 10 ) || 0 ;
@@ -240,21 +236,39 @@ export class InvoicingManager {
240236 } ) ;
241237 }
242238
243- // 7. Record in ptb_invoices
244- const ptbResult = await dbExecute < { id : string } > (
245- `INSERT INTO ptb_invoices (organization_id, stripe_invoice_id, start_date, end_date, amount_cents, notes)
246- VALUES ($1, $2, $3, $4, $5, $6)
239+ // 7. Record in ptb_invoices (with fallback if subtotal_cents column doesn't exist yet)
240+ let ptbResult = await dbExecute < { id : string } > (
241+ `INSERT INTO ptb_invoices (organization_id, stripe_invoice_id, start_date, end_date, amount_cents, subtotal_cents, notes)
242+ VALUES ($1, $2, $3, $4, $5, $6, $7 )
247243 RETURNING id` ,
248244 [
249245 this . orgId ,
250246 invoice . id ,
251247 startDate ,
252248 endDate ,
253249 totalAmountCents ,
250+ totalSubtotalCents ,
254251 `Auto-created invoice for ${ orgName } ` ,
255252 ]
256253 ) ;
257254
255+ // If subtotal_cents column doesn't exist yet, fall back to insert without it
256+ if ( ptbResult . error && JSON . stringify ( ptbResult . error ) . includes ( "42703" ) ) {
257+ ptbResult = await dbExecute < { id : string } > (
258+ `INSERT INTO ptb_invoices (organization_id, stripe_invoice_id, start_date, end_date, amount_cents, notes)
259+ VALUES ($1, $2, $3, $4, $5, $6)
260+ RETURNING id` ,
261+ [
262+ this . orgId ,
263+ invoice . id ,
264+ startDate ,
265+ endDate ,
266+ totalAmountCents ,
267+ `Auto-created invoice for ${ orgName } ` ,
268+ ]
269+ ) ;
270+ }
271+
258272 if ( ptbResult . error ) {
259273 console . error ( "Failed to record invoice in ptb_invoices:" , ptbResult . error ) ;
260274 }
@@ -266,6 +280,7 @@ export class InvoicingManager {
266280 hostedInvoiceUrl : null ,
267281 dashboardUrl,
268282 amountCents : totalAmountCents ,
283+ subtotalCents : totalSubtotalCents ,
269284 ptbInvoiceId : ptbResult . data ?. [ 0 ] ?. id || "" ,
270285 } ) ;
271286 } catch ( error : any ) {
0 commit comments