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  }