flamingo.me/flamingo-commerce/v3@v3.11.0/cart/domain/validation/restrictionService.go (about) 1 package validation 2 3 import ( 4 "context" 5 "math" 6 7 "go.opencensus.io/trace" 8 9 "flamingo.me/flamingo/v3/framework/web" 10 11 "flamingo.me/flamingo-commerce/v3/cart/domain/cart" 12 "flamingo.me/flamingo-commerce/v3/product/domain" 13 ) 14 15 type ( 16 // RestrictionService checks product restriction 17 RestrictionService struct { 18 qtyRestrictors []MaxQuantityRestrictor 19 } 20 21 // RestrictionResult contains the result of a restriction 22 RestrictionResult struct { 23 IsRestricted bool 24 MaxAllowed int 25 RemainingDifference int 26 RestrictorName string 27 } 28 29 // MaxQuantityRestrictor returns the maximum qty allowed for a given product and cart 30 // it is possible to register many (MultiBind) MaxQuantityRestrictor implementations 31 MaxQuantityRestrictor interface { 32 // Name returns the code of the restrictor 33 Name() string 34 // Restrict must return a `RestrictionResult` which contains information regarding if a restriction is 35 // applied and whats the max allowed quantity. Might expect item id from context in implementation. 36 Restrict(ctx context.Context, session *web.Session, product domain.BasicProduct, cart *cart.Cart, deliveryCode string) *RestrictionResult 37 } 38 ) 39 40 // Inject dependencies 41 func (rs *RestrictionService) Inject( 42 qtyRestrictors []MaxQuantityRestrictor, 43 ) *RestrictionService { 44 rs.qtyRestrictors = qtyRestrictors 45 46 return rs 47 } 48 49 // RestrictQty checks if there is an qty restriction present and returns an according result containing the max allowed 50 // quantity and the quantity difference to the current cart. Restrictor might expect item id in context 51 func (rs *RestrictionService) RestrictQty(ctx context.Context, session *web.Session, product domain.BasicProduct, currentCart *cart.Cart, deliveryCode string) *RestrictionResult { 52 ctx, span := trace.StartSpan(ctx, "cart/RestrictionService/RestrictQty") 53 defer span.End() 54 55 restrictionResult := &RestrictionResult{ 56 IsRestricted: false, 57 MaxAllowed: math.MaxInt32, 58 RemainingDifference: math.MaxInt32, 59 } 60 61 for _, r := range rs.qtyRestrictors { 62 currentResult := r.Restrict(ctx, session, product, currentCart, deliveryCode) 63 64 if currentResult.IsRestricted { 65 restrictionResult.IsRestricted = true 66 67 if currentResult.MaxAllowed < restrictionResult.MaxAllowed { 68 restrictionResult.MaxAllowed = currentResult.MaxAllowed 69 restrictionResult.RestrictorName = currentResult.RestrictorName 70 } 71 72 if currentResult.RemainingDifference < restrictionResult.RemainingDifference { 73 restrictionResult.RemainingDifference = currentResult.RemainingDifference 74 } 75 } 76 } 77 78 return restrictionResult 79 }