@@ -2,24 +2,15 @@ package service
22
33import (
44 "context"
5- "slices "
5+ "fmt "
66
77 "github.com/openmeterio/openmeter/openmeter/billing/charges/creditpurchase"
88 "github.com/openmeterio/openmeter/openmeter/billing/charges/lineage"
9+ "github.com/openmeterio/openmeter/openmeter/billing/charges/meta"
910 "github.com/openmeterio/openmeter/pkg/clock"
1011)
1112
12- var activePromotionalCreditPurchaseStatuses = []creditpurchase.Status {
13- creditpurchase .StatusCreated ,
14- creditpurchase .StatusActive ,
15- }
16-
17- func (s * service ) onPromotionalCreditPurchase (ctx context.Context , charge creditpurchase.Charge ) (creditpurchase.Charge , error ) {
18- // Prevent re-processing of the charge
19- if ! slices .Contains (activePromotionalCreditPurchaseStatuses , charge .Status ) {
20- return creditpurchase.Charge {}, creditpurchase .ErrCreditPurchaseChargeNotActive .WithAttrs (charge .ErrorAttributes ())
21- }
22-
13+ func (s * service ) grantPromotionalCredit (ctx context.Context , charge creditpurchase.Charge ) (creditpurchase.Charge , error ) {
2314 ledgerTransactionGroupReference , err := s .handler .OnPromotionalCreditPurchase (ctx , charge )
2415 if err != nil {
2516 return creditpurchase.Charge {}, err
@@ -47,14 +38,54 @@ func (s *service) onPromotionalCreditPurchase(ctx context.Context, charge credit
4738 }
4839 }
4940
50- charge .Status = creditpurchase .StatusFinal
41+ return charge , nil
42+ }
43+
44+ type PromotionalCreditpurchaseStateMachine struct {
45+ * stateMachine
46+ }
47+
48+ func NewPromotionalCreditPurchaseStateMachine (config StateMachineConfig ) (* PromotionalCreditpurchaseStateMachine , error ) {
49+ if err := config .Validate (); err != nil {
50+ return nil , fmt .Errorf ("validate: %w" , err )
51+ }
52+
53+ if config .Charge .Intent .Settlement .Type () != creditpurchase .SettlementTypePromotional {
54+ return nil , fmt .Errorf ("charge %s is not promotional" , config .Charge .ID )
55+ }
5156
52- updatedBase , err := s . adapter . UpdateCharge ( ctx , charge . ChargeBase )
57+ stateMachine , err := newStateMachineBase ( config )
5358 if err != nil {
54- return creditpurchase. Charge {} , err
59+ return nil , fmt . Errorf ( "failed to create promotional credit purchase state machine: %w" , err )
5560 }
5661
57- charge .ChargeBase = updatedBase
62+ out := & PromotionalCreditpurchaseStateMachine {
63+ stateMachine : stateMachine ,
64+ }
65+ out .configureStates ()
5866
59- return charge , nil
67+ return out , nil
68+ }
69+
70+ func (s * PromotionalCreditpurchaseStateMachine ) configureStates () {
71+ s .Configure (creditpurchase .StatusCreated ).
72+ Permit (meta .TriggerNext , creditpurchase .StatusFinal )
73+
74+ s .Configure (creditpurchase .StatusActive ).
75+ Permit (meta .TriggerNext , creditpurchase .StatusFinal )
76+
77+ s .Configure (creditpurchase .StatusFinal ).
78+ OnEntry (func (ctx context.Context , _ ... any ) error {
79+ return s .GrantPromotionalCredit (ctx )
80+ })
81+ }
82+
83+ func (s * PromotionalCreditpurchaseStateMachine ) GrantPromotionalCredit (ctx context.Context ) error {
84+ charge , err := s .Service .grantPromotionalCredit (ctx , s .Charge )
85+ if err != nil {
86+ return fmt .Errorf ("grant promotional credit: %w" , err )
87+ }
88+
89+ s .Charge = charge
90+ return nil
6091}
0 commit comments