// Some of the commands should only be applied once per product or once per purchase etc. // Putting this logic into business rule matchers would violate SRP, since each business rule matcher should take // care only of a particular case for particular command, not for particular command as a whole. // We need another layer taking care of removing duplicate commands. Multiple approaches can be taken here, // for this Kata purpose I'm using a simple approach with comparer. // This method serves as an extension point and can easily be altered later to include more complex rules and checks. private IPurchaseProcessingCommand[] FilterCommands(PurchaseBusinessRulesProcessingContext context) { IPurchaseProcessingCommand[] filteredCommands = context.Commands.ToArray(); IReadOnlyCollection <IPurchaseProcessingCommandComparer> comparers = _commandComparerRepository.GetRuleComparers(); foreach (IPurchaseProcessingCommandComparer comparer in comparers) { filteredCommands = comparer.Filter(filteredCommands); } return(filteredCommands); }
public PurchaseCommandSet ProcessPurchase(Purchase purchase) { PurchaseBusinessRulesProcessingContext context = new PurchaseBusinessRulesProcessingContext(purchase); IReadOnlyCollection <IBusinessRuleMatcher> ruleMatchers = _businessRuleMatcherRepository.GetRuleMatchers(); CreateCommands(ruleMatchers, context); var filteredCommands = FilterCommands(context); PurchaseCommandSet ret = new PurchaseCommandSet(filteredCommands, purchase); return(ret); }
public IPurchaseProcessingCommand[] MatchPurchaseCommands(PurchaseBusinessRulesProcessingContext context) { IEnumerable <Product> products = context.Purchase.Products.Where(p => p.ProductName.DefaultEquals(ProductNameToSearchFor)); if (!products.Any()) { return(new IPurchaseProcessingCommand[0]); } // Only one per purchase. return(new IPurchaseProcessingCommand[] { new AddFreeProductToPurchaseCommand(context.Purchase, GetFreeProduct()), }); }
public IPurchaseProcessingCommand[] MatchPurchaseCommands(PurchaseBusinessRulesProcessingContext context) { Product[] productsWithComission = context.Purchase.Products .Where(p => _evaluator.IsBook(p) || _evaluator.IsPhysical(p)) .ToArray(); if (!productsWithComission.Any()) { return(new IPurchaseProcessingCommand[0]); } Payment payment = CalculateAgentsComissionPayment(productsWithComission); InitiatePaymentCommand paymentCommand = new InitiatePaymentCommand(context.Purchase, payment); return(new IPurchaseProcessingCommand[] { paymentCommand }); }
public IPurchaseProcessingCommand[] MatchPurchaseCommands(PurchaseBusinessRulesProcessingContext context) { IPurchaseProcessingCommand[] ret = context.Purchase.Products.Where(p => _evaluator.IsBook(p)) .Select(p => new CreateDuplicatePackingSlipCommand(context.Purchase, p)).ToArray(); return(ret); }
private static void CreateCommands(IReadOnlyCollection <IBusinessRuleMatcher> ruleMatchers, PurchaseBusinessRulesProcessingContext context) { foreach (IBusinessRuleMatcher matcher in ruleMatchers) { IPurchaseProcessingCommand[] commands = matcher.MatchPurchaseCommands(context); context.AddCommands(commands); } }
public IPurchaseProcessingCommand[] MatchPurchaseCommands(PurchaseBusinessRulesProcessingContext context) { IPurchaseProcessingCommand[] ret = context.Purchase.Products.Where(p => _evaluator.IsMembershipActivation(p)) .Select(p => new ActivateMembershipCommand(context.Purchase, p)).ToArray(); return(ret); }
public IPurchaseProcessingCommand[] MatchPurchaseCommands(PurchaseBusinessRulesProcessingContext context) { IPurchaseProcessingCommand[] ret = context.Purchase.Products.Where(p => _evaluator.IsMembershipUpgrade(p)) .Select(p => new MembershipChangeEmailNotificationCommand(context.Purchase, p)).ToArray(); return(ret); }