Skip to content

Commit 797c1b7

Browse files
svenefftingeroboquat
authored andcommitted
[usage] support multiple entries on invoices
1 parent d0ccc7f commit 797c1b7

File tree

2 files changed

+480
-18
lines changed

2 files changed

+480
-18
lines changed

components/usage/pkg/apiv1/billing.go

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -290,10 +290,25 @@ func (s *BillingService) FinalizeInvoice(ctx context.Context, in *v1.FinalizeInv
290290
logger.WithError(err).Error("Failed to retrieve invoice from Stripe.")
291291
return nil, status.Errorf(codes.NotFound, "Failed to get invoice with ID %s: %s", in.GetInvoiceId(), err.Error())
292292
}
293+
usage, err := InternalComputeInvoiceUsage(ctx, invoice)
294+
if err != nil {
295+
return nil, err
296+
}
297+
err = db.InsertUsage(ctx, s.conn, usage)
298+
if err != nil {
299+
logger.WithError(err).Errorf("Failed to insert Invoice usage record into the db.")
300+
return nil, status.Errorf(codes.Internal, "Failed to insert Invoice into usage records.")
301+
}
302+
303+
logger.WithField("usage_id", usage.ID).Infof("Inserted usage record into database for %f credits against %s attribution", usage.CreditCents.ToCredits(), usage.AttributionID)
304+
return &v1.FinalizeInvoiceResponse{}, nil
305+
}
293306

307+
func InternalComputeInvoiceUsage(ctx context.Context, invoice *stripe_api.Invoice) (db.Usage, error) {
308+
logger := log.WithField("invoice_id", invoice.ID)
294309
attributionID, err := stripe.GetAttributionID(ctx, invoice.Customer)
295310
if err != nil {
296-
return nil, err
311+
return db.Usage{}, err
297312
}
298313
logger = logger.WithField("attributionID", attributionID)
299314
finalizedAt := time.Unix(invoice.StatusTransitions.FinalizedAt, 0)
@@ -304,18 +319,16 @@ func (s *BillingService) FinalizeInvoice(ctx context.Context, in *v1.FinalizeInv
304319

305320
if invoice.Lines == nil || len(invoice.Lines.Data) == 0 {
306321
logger.Errorf("Invoice %s did not contain any lines so we cannot extract quantity to reflect it in usage.", invoice.ID)
307-
return nil, status.Errorf(codes.Internal, "Invoice did not contain any lines.")
322+
return db.Usage{}, status.Errorf(codes.Internal, "Invoice did not contain any lines.")
308323
}
309324

310325
lines := invoice.Lines.Data
311-
if len(lines) != 1 {
312-
logger.Error("Invoice did not contain exactly 1 line item, we cannot extract quantity to reflect in usage.")
313-
return nil, status.Errorf(codes.Internal, "Invoice did not contain exactly one line item.")
326+
var creditsOnInvoice int64
327+
for _, line := range lines {
328+
creditsOnInvoice += line.Quantity
314329
}
315330

316-
creditsOnInvoice := lines[0].Quantity
317-
318-
usage := db.Usage{
331+
return db.Usage{
319332
ID: uuid.New(),
320333
AttributionID: attributionID,
321334
Description: fmt.Sprintf("Invoice %s finalized in Stripe", invoice.ID),
@@ -325,16 +338,7 @@ func (s *BillingService) FinalizeInvoice(ctx context.Context, in *v1.FinalizeInv
325338
Kind: db.InvoiceUsageKind,
326339
Draft: false,
327340
Metadata: nil,
328-
}
329-
err = db.InsertUsage(ctx, s.conn, usage)
330-
if err != nil {
331-
logger.WithError(err).Errorf("Failed to insert Invoice usage record into the db.")
332-
return nil, status.Errorf(codes.Internal, "Failed to insert Invoice into usage records.")
333-
}
334-
335-
logger.WithField("usage_id", usage.ID).Infof("Inserted usage record into database for %d credits against %s attribution", creditsOnInvoice, attributionID)
336-
337-
return &v1.FinalizeInvoiceResponse{}, nil
341+
}, nil
338342
}
339343

340344
func (s *BillingService) CancelSubscription(ctx context.Context, in *v1.CancelSubscriptionRequest) (*v1.CancelSubscriptionResponse, error) {

0 commit comments

Comments
 (0)