Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion openmeter/billing/adapter/invoicelinemapper.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,8 @@ func (a *adapter) mapInvoiceLineWithoutReferences(dbLine *db.BillingInvoiceLine)
Type: dbLine.Type,
Currency: dbLine.Currency,

TaxConfig: lo.EmptyableToPtr(dbLine.TaxConfig),
TaxConfig: lo.EmptyableToPtr(dbLine.TaxConfig),
RateCardDiscounts: lo.FromPtrOr(dbLine.RatecardDiscounts, nil),
Totals: billing.Totals{
Amount: dbLine.Amount,
ChargesTotal: dbLine.ChargesTotal,
Expand Down
4 changes: 4 additions & 0 deletions openmeter/billing/adapter/invoicelines.go
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ func (a *adapter) UpsertInvoiceLines(ctx context.Context, inputIn billing.Upsert
create = create.SetTaxConfig(*line.TaxConfig)
}

if len(line.RateCardDiscounts) > 0 {
create = create.SetRatecardDiscounts(lo.ToPtr(line.RateCardDiscounts))
}

switch line.Type {
case billing.InvoiceLineTypeFee:
create = create.SetQuantity(line.FlatFee.Quantity).
Expand Down
21 changes: 21 additions & 0 deletions openmeter/billing/httpdriver/deprecations.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ type flatFeeRateCardParsed struct {
PaymentTerm productcatalog.PaymentTermType
Quantity alpacadecimal.Decimal
TaxConfig *billing.TaxConfig
Discounts productcatalog.Discounts
}

func mapAndValidateFlatFeeRateCardDeprecatedFields(in flatFeeRateCardItems) (*flatFeeRateCardParsed, error) {
Expand Down Expand Up @@ -165,11 +166,19 @@ func mapAndValidateFlatFeeRateCardDeprecatedFields(in flatFeeRateCardItems) (*fl
}
}

var discounts productcatalog.Discounts
if in.RateCard.Discounts != nil {
discounts = lo.Map(*in.RateCard.Discounts, func(d api.DiscountPercentage, _ int) productcatalog.Discount {
return productcatalog.NewDiscountFrom(productcataloghttp.AsPercentageDiscount(d))
})
}

return &flatFeeRateCardParsed{
PerUnitAmount: perUnitAmount,
PaymentTerm: productcatalog.PaymentTermType(paymentTerm),
Quantity: qty,
TaxConfig: taxConfig,
Discounts: discounts,
}, nil
}

Expand Down Expand Up @@ -244,6 +253,7 @@ type usageBasedRateCardParsed struct {
Price *productcatalog.Price
TaxConfig *billing.TaxConfig
FeatureKey string
Discounts productcatalog.Discounts
}

func mapAndValidateUsageBasedRateCardDeprecatedFields(in usageBasedRateCardItems) (*usageBasedRateCardParsed, error) {
Expand Down Expand Up @@ -285,9 +295,20 @@ func mapAndValidateUsageBasedRateCardDeprecatedFields(in usageBasedRateCardItems
}
}

var discounts productcatalog.Discounts
if in.RateCard.Discounts != nil {
discounts, err = productcataloghttp.AsDiscounts(*in.RateCard.Discounts)
if err != nil {
return nil, billing.ValidationError{
Err: fmt.Errorf("failed to parse discounts: %w", err),
}
}
}

return &usageBasedRateCardParsed{
Price: price,
TaxConfig: mapTaxConfigToEntity(in.RateCard.TaxConfig),
FeatureKey: *in.RateCard.FeatureKey,
Discounts: discounts,
}, nil
}
29 changes: 18 additions & 11 deletions openmeter/billing/httpdriver/invoiceline.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,9 @@ func mapCreatePendingFlatFeeLineToEntity(line api.InvoiceFlatFeePendingLineCreat
End: line.Period.To,
},

InvoiceAt: line.InvoiceAt,
TaxConfig: rateCardParsed.TaxConfig,
InvoiceAt: line.InvoiceAt,
TaxConfig: rateCardParsed.TaxConfig,
RateCardDiscounts: rateCardParsed.Discounts,
},
FlatFee: &billing.FlatFeeLine{
PerUnitAmount: rateCardParsed.PerUnitAmount,
Expand Down Expand Up @@ -195,8 +196,9 @@ func mapCreatePendingUsageBasedLineToEntity(line api.InvoiceUsageBasedPendingLin
End: line.Period.To,
},

InvoiceAt: line.InvoiceAt,
TaxConfig: rateCardParsed.TaxConfig,
InvoiceAt: line.InvoiceAt,
TaxConfig: rateCardParsed.TaxConfig,
RateCardDiscounts: rateCardParsed.Discounts,
},
UsageBased: &billing.UsageBasedLine{
Price: rateCardParsed.Price,
Expand Down Expand Up @@ -525,8 +527,9 @@ func mapSimulationFlatFeeLineToEntity(line api.InvoiceSimulationFlatFeeLine) (*b
End: line.Period.To,
},

InvoiceAt: line.InvoiceAt,
TaxConfig: rateCardParsed.TaxConfig,
InvoiceAt: line.InvoiceAt,
TaxConfig: rateCardParsed.TaxConfig,
RateCardDiscounts: rateCardParsed.Discounts,
},
FlatFee: &billing.FlatFeeLine{
PerUnitAmount: rateCardParsed.PerUnitAmount,
Expand Down Expand Up @@ -573,8 +576,9 @@ func mapUsageBasedSimulationLineToEntity(line api.InvoiceSimulationUsageBasedLin
End: line.Period.To,
},

InvoiceAt: line.InvoiceAt,
TaxConfig: rateCardParsed.TaxConfig,
InvoiceAt: line.InvoiceAt,
TaxConfig: rateCardParsed.TaxConfig,
RateCardDiscounts: rateCardParsed.Discounts,
},
UsageBased: &billing.UsageBasedLine{
Price: rateCardParsed.Price,
Expand Down Expand Up @@ -641,7 +645,8 @@ func lineFromInvoiceLineReplaceUpdate(line api.InvoiceLineReplaceUpdate, invoice
},
InvoiceAt: v.InvoiceAt,

TaxConfig: rateCardParsed.TaxConfig,
TaxConfig: rateCardParsed.TaxConfig,
RateCardDiscounts: rateCardParsed.Discounts,
},
FlatFee: &billing.FlatFeeLine{
PerUnitAmount: rateCardParsed.PerUnitAmount,
Expand Down Expand Up @@ -683,7 +688,8 @@ func lineFromInvoiceLineReplaceUpdate(line api.InvoiceLineReplaceUpdate, invoice
},
InvoiceAt: v.InvoiceAt,

TaxConfig: rateCardParsed.TaxConfig,
TaxConfig: rateCardParsed.TaxConfig,
RateCardDiscounts: rateCardParsed.Discounts,
},
UsageBased: &billing.UsageBasedLine{
Price: rateCardParsed.Price,
Expand Down Expand Up @@ -734,6 +740,7 @@ func mergeLineFromInvoiceLineReplaceUpdate(existing *billing.Line, line api.Invo
existing.InvoiceAt = v.InvoiceAt

existing.TaxConfig = rateCardParsed.TaxConfig
existing.RateCardDiscounts = rateCardParsed.Discounts

existing.FlatFee.PerUnitAmount = rateCardParsed.PerUnitAmount
existing.FlatFee.Quantity = rateCardParsed.Quantity
Expand Down Expand Up @@ -777,7 +784,7 @@ func mergeLineFromInvoiceLineReplaceUpdate(existing *billing.Line, line api.Invo
existing.InvoiceAt = v.InvoiceAt

existing.TaxConfig = rateCardParsed.TaxConfig

existing.RateCardDiscounts = rateCardParsed.Discounts
existing.UsageBased.Price = rateCardParsed.Price
existing.UsageBased.FeatureKey = rateCardParsed.FeatureKey

Expand Down
18 changes: 17 additions & 1 deletion openmeter/billing/invoiceline.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,8 @@ type LineBase struct {
Status InvoiceLineStatus `json:"status"`
ChildUniqueReferenceID *string `json:"childUniqueReferenceID,omitempty"`

TaxConfig *TaxConfig `json:"taxOverrides,omitempty"`
TaxConfig *TaxConfig `json:"taxOverrides,omitempty"`
RateCardDiscounts productcatalog.Discounts `json:"rateCardDiscounts,omitempty"`
Copy link
Member Author

@turip turip Apr 3, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We would collide with the Line's Discounts, if we don't name it RateCardDiscounts. For now this is fine, but after the discount entity is there we need to refactor the internal Line entity, but that's a bigger lift.


ExternalIDs LineExternalIDs `json:"externalIDs,omitempty"`
Subscription *SubscriptionReference `json:"subscription,omitempty"`
Expand Down Expand Up @@ -219,6 +220,8 @@ func (i LineBase) Clone() LineBase {
out.TaxConfig = &tc
}

out.RateCardDiscounts = i.RateCardDiscounts.Clone()

return out
}

Expand Down Expand Up @@ -475,11 +478,24 @@ func (i Line) Validate() error {
if err := i.ValidateFee(); err != nil {
errs = append(errs, err)
}

price := productcatalog.NewPriceFrom(productcatalog.FlatPrice{
Amount: i.FlatFee.PerUnitAmount,
PaymentTerm: i.FlatFee.PaymentTerm,
})

if err := i.RateCardDiscounts.ValidateForPrice(price); err != nil {
errs = append(errs, fmt.Errorf("rateCardDiscounts: %w", err))
}
case InvoiceLineTypeUsageBased:
if err := i.ValidateUsageBased(); err != nil {
errs = append(errs, err)
}

if err := i.LineBase.RateCardDiscounts.ValidateForPrice(i.UsageBased.Price); err != nil {
errs = append(errs, fmt.Errorf("rateCardDiscounts: %w", err))
}

default:
errs = append(errs, fmt.Errorf("unsupported type: %s", i.Type))
}
Expand Down
15 changes: 15 additions & 0 deletions openmeter/ent/db/billinginvoiceline.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions openmeter/ent/db/billinginvoiceline/billinginvoiceline.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions openmeter/ent/db/billinginvoiceline/where.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading