예제 #1
0
        // 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);
        }
예제 #2
0
        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()), });
        }
예제 #4
0
        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);
 }
예제 #6
0
 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);
 }