@@ -2804,6 +2804,114 @@ func (s *SubscriptionHandlerTestSuite) TestRateCardTaxSync() {
28042804 }
28052805}
28062806
2807+ func (s * SubscriptionHandlerTestSuite ) TestInAdvanceInstantBillingOnSubscriptionCreation () {
2808+ ctx := s .Context
2809+ clock .FreezeTime (s .mustParseTime ("2024-01-01T00:00:00Z" ))
2810+
2811+ // Given
2812+ // we have a subscription with a single phase with an in advance fee
2813+ // When
2814+ // we start the subscription
2815+ // Then
2816+ // the gathering invoice will automatically be invoiced so that the in advance fee is billed (those are always flat fees)
2817+
2818+ subsView := s .createSubscriptionFromPlanPhases ([]productcatalog.Phase {
2819+ {
2820+ PhaseMeta : s .phaseMeta ("first-phase" , "" ),
2821+ RateCards : productcatalog.RateCards {
2822+ & productcatalog.UsageBasedRateCard {
2823+ RateCardMeta : productcatalog.RateCardMeta {
2824+ Key : "in-advance" ,
2825+ Name : "in-advance" ,
2826+ Price : productcatalog .NewPriceFrom (productcatalog.FlatPrice {
2827+ Amount : alpacadecimal .NewFromFloat (6 ),
2828+ PaymentTerm : productcatalog .InAdvancePaymentTerm ,
2829+ }),
2830+ },
2831+ BillingCadence : isodate .MustParse (s .T (), "P1D" ),
2832+ },
2833+ & productcatalog.UsageBasedRateCard {
2834+ RateCardMeta : productcatalog.RateCardMeta {
2835+ Key : s .APIRequestsTotalFeature .Key ,
2836+ Name : s .APIRequestsTotalFeature .Key ,
2837+ Feature : & s .APIRequestsTotalFeature ,
2838+ Price : productcatalog .NewPriceFrom (productcatalog.UnitPrice {
2839+ Amount : alpacadecimal .NewFromFloat (10 ),
2840+ }),
2841+ },
2842+ BillingCadence : isodate .MustParse (s .T (), "P1D" ),
2843+ },
2844+ },
2845+ },
2846+ })
2847+
2848+ s .NoError (s .Handler .HandleSubscriptionCreated (ctx , subsView , clock .Now ()))
2849+
2850+ invoices , err := s .BillingService .ListInvoices (ctx , billing.ListInvoicesInput {
2851+ Customers : []string {s .Customer .ID },
2852+ Expand : billing .InvoiceExpandAll ,
2853+ })
2854+ s .NoError (err )
2855+ s .Len (invoices .Items , 2 )
2856+
2857+ var gatheringInvoice * billing.Invoice
2858+ var instantInvoice * billing.Invoice
2859+
2860+ for _ , invoice := range invoices .Items {
2861+ if invoice .Status == billing .InvoiceStatusGathering {
2862+ gatheringInvoice = & invoice
2863+ continue
2864+ }
2865+
2866+ instantInvoice = & invoice
2867+ }
2868+
2869+ s .NotNil (gatheringInvoice , "gathering invoice should be present" )
2870+ s .NotNil (instantInvoice , "instant invoice should be present" )
2871+
2872+ s .DebugDumpInvoice ("gathering invoice" , * gatheringInvoice )
2873+ s .DebugDumpInvoice ("instant invoice" , * instantInvoice )
2874+
2875+ // Gathering invoice should have the UBP line
2876+ s .expectLines (* gatheringInvoice , subsView .Subscription .ID , []expectedLine {
2877+ {
2878+ Matcher : recurringLineMatcher {
2879+ PhaseKey : "first-phase" ,
2880+ ItemKey : s .APIRequestsTotalFeature .Key ,
2881+ },
2882+ Price : mo .Some (productcatalog .NewPriceFrom (productcatalog.UnitPrice {
2883+ Amount : alpacadecimal .NewFromFloat (10 ),
2884+ })),
2885+ Periods : []billing.Period {
2886+ {
2887+ Start : s .mustParseTime ("2024-01-01T00:00:00Z" ),
2888+ End : s .mustParseTime ("2024-01-02T00:00:00Z" ),
2889+ },
2890+ },
2891+ InvoiceAt : []time.Time {s .mustParseTime ("2024-01-02T00:00:00Z" )},
2892+ },
2893+ })
2894+
2895+ // Instant invoice should have the in advance fee
2896+ s .expectLines (* instantInvoice , subsView .Subscription .ID , []expectedLine {
2897+ {
2898+ Matcher : recurringLineMatcher {
2899+ PhaseKey : "first-phase" ,
2900+ ItemKey : "in-advance" ,
2901+ },
2902+ Qty : mo.Some [float64 ](1 ),
2903+ UnitPrice : mo.Some [float64 ](6 ),
2904+ Periods : []billing.Period {
2905+ {
2906+ Start : s .mustParseTime ("2024-01-01T00:00:00Z" ),
2907+ End : s .mustParseTime ("2024-01-02T00:00:00Z" ),
2908+ },
2909+ },
2910+ InvoiceAt : []time.Time {s .mustParseTime ("2024-01-01T00:00:00Z" )},
2911+ },
2912+ })
2913+ }
2914+
28072915func (s * SubscriptionHandlerTestSuite ) expectValidationIssueForLine (line * billing.Line , issue billing.ValidationIssue ) {
28082916 s .Equal (billing .ValidationIssueSeverityWarning , issue .Severity )
28092917 s .Equal (billing .ImmutableInvoiceHandlingNotSupportedErrorCode , issue .Code )
0 commit comments