コード例 #1
0
        public JobApprovalDecision EvaluateRule(JobSheet jobSheet)
        {
            // Hard-coded, take as parameter
            var tenPercent     = 10;
            var fifteenPercent = 15;

            var tenPercentTotal     = ((jobSheet.TotalCost / 100) * tenPercent) + jobSheet.TotalCost;
            var fifteenPercentTotal = ((jobSheet.TotalCost / 100) * fifteenPercent) + jobSheet.TotalCost;

            if (jobSheet.ReferenceTotalPrice < tenPercentTotal)
            {
                return(new JobApprovalDecision(JobApprovalDecisionEnum.Approved));
            }

            if (jobSheet.ReferenceTotalPrice > tenPercentTotal && jobSheet.ReferenceTotalPrice <= fifteenPercentTotal)
            {
                return(new JobApprovalDecision(JobApprovalDecisionEnum.Refered, "Reference price exceed 10%."));
            }

            if (jobSheet.ReferenceTotalPrice > fifteenPercentTotal)
            {
                return(new JobApprovalDecision(JobApprovalDecisionEnum.Declined, "Reference price exceed 15%."));
            }

            return(new JobApprovalDecision(JobApprovalDecisionEnum.Declined));
        }
コード例 #2
0
 public void Setup()
 {
     _jobSheet = new JobSheet
     {
         Id = Guid.Parse("2ce22be0-98cc-423b-9446-d7a5cf9e6756"),
         ReferenceHoursInMin = new Random().Next(5, 9),
         ReferenceTotalPrice = new Random().Next(500, 1000),
         LaborHourCost       = 45,
         Items = new List <Item>()
     };
 }
        public JobApprovalDecision EvaluateRule(JobSheet jobSheet)
        {
            var labourHours = jobSheet.Items.Sum(x => x.ItemTime);

            if (jobSheet.ReferenceHoursInMin > labourHours)
            {
                return(new JobApprovalDecision(JobApprovalDecisionEnum.Declined, "Reference hours exceed the actual labour hours."));
            }

            return(new JobApprovalDecision(JobApprovalDecisionEnum.Approved));
        }
コード例 #4
0
        public JobApprovalDecision EvaluateRule(JobSheet jobSheet)
        {
            var exhaust = jobSheet.Items.Where(x => x.GenericCategory == "Exhaust").ToArray();


            if (exhaust.Any())
            {
                if (exhaust.Count() > 1)
                {
                    return(new JobApprovalDecision(JobApprovalDecisionEnum.Declined, "More than one Exhaust."));
                }
            }

            return(new JobApprovalDecision(JobApprovalDecisionEnum.Approved));
        }
コード例 #5
0
        public JobApprovalDecision EvaluateRule(JobSheet jobSheet)
        {
            var breakPads = jobSheet.Items.Where(x => x.GenericCategory == "Break Pads").ToArray();
            var discs     = jobSheet.Items.Where(x => x.GenericCategory == "Discs").ToArray();

            var missingPads  = (!breakPads.Any() && discs.Any());
            var missingDiscs = (breakPads.Any() && !discs.Any());

            if (missingPads || missingDiscs)
            {
                return(new JobApprovalDecision(JobApprovalDecisionEnum.Declined, "Missing pads or discs."));
            }

            return(new JobApprovalDecision(JobApprovalDecisionEnum.Approved));
        }
コード例 #6
0
        public JobApprovalDecision EvaluateRule(JobSheet jobSheet)
        {
            var tyres = jobSheet.Items.Where(x => x.GenericCategory == "Tyres").ToArray();


            if (tyres.Any())
            {
                var noOfTyres = tyres.Count();
                var notInPair = (noOfTyres % 2) != 0;

                if (notInPair || noOfTyres > 4)
                {
                    return(new JobApprovalDecision(JobApprovalDecisionEnum.Declined, "Tyres are either not in Pairs or more than 4."));
                }
            }

            return(new JobApprovalDecision(JobApprovalDecisionEnum.Approved));
        }
コード例 #7
0
        public JobApprovalDecision EvaluateAllJobRules(JobSheet jobSheet)
        {
            _rules.Add(new TyresChangedInPairsAndMaxFour());
            _rules.Add(new BreakPadsAndDiscsChangeTogether());
            _rules.Add(new OneExhaust());
            _rules.Add(new ReferenceHoursNotExceedTotalHoursOfLabour());
            _rules.Add(new OverallDecision());

            JobApprovalDecision evalResult = new JobApprovalDecision();

            foreach (var rule in _rules)
            {
                evalResult = rule.EvaluateRule(jobSheet);

                if (evalResult.JobApprovalDecisionEnum == JobApprovalDecisionEnum.Declined)
                {
                    return(evalResult);
                }
            }

            return(evalResult);
        }
コード例 #8
0
        /// <summary>
        /// Validate Job Sheet by business rules
        /// </summary>
        /// <returns>Approval object with approval satus, code and validation messages</returns>
        public Approval Approve(JobSheet jobSheet)
        {
            List <string> validationMessages = new List <string>();

            // checking if any data is sent at all
            if (jobSheet == null)
            {
                return(new Approval()
                {
                    ApprovalStatusCode = 3,
                    ApprovalStatusMessage = "Rejected",
                    ApprovalResponseCode = 200,
                    ApprovalValidationMessages = new List <string>()
                    {
                        "Missing parameters"
                    },
                    ApprovalTime = DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)
                });
            }

            #region Common validation
            // Here starts common validation
            // 1. Rule: total amount <= 0
            // Checking if total amount is less or equals to zero
            if (jobSheet.TotalAmount <= 0)
            {
                validationMessages.Add("Total amount cannot be less or equal to 0");
            }

            // 2. Rule: jobs amount <= 0
            // Checking if total jobs amount is greater than zero
            if (jobSheet.References == null)
            {
                validationMessages.Add("Jobs amount cannot be less or equals to 0");
            }
            else if (jobSheet.References.Count == 0)
            {
                validationMessages.Add("Jobs amount cannot be less or equals to 0");
            }
            #endregion

            #region business logic
            // Here starts business logic
            // 3. Rule: 2 or 4 tyres
            var tyresCount = jobSheet.References.Count(r => r.ItemID == 1);
            if ((tyresCount > 0 && tyresCount % 2 != 0 && tyresCount < 4) || tyresCount > 4)
            {
                validationMessages.Add("Tyres must be changed in pairs, min 2, max 4");
            }

            // 4. Rule: Brake discs and pads has to be replaced at the same
            var brakeDiscs = jobSheet.References.Count(r => r.ItemID == 2);
            var brakePads  = jobSheet.References.Count(r => r.ItemID == 3);
            if (brakeDiscs != brakePads)
            {
                validationMessages.Add("Brake pads and disks must be changed at the same time");
            }

            // 5. Rule: maximum 1 exhaust
            var exhaustCount = jobSheet.References.Count(r => r.ItemID == 5);
            if (exhaustCount > 1)
            {
                validationMessages.Add("A Job Sheet can only include a maximum of 1 exhaust");
            }

            // 6. Rule: Total hous labour must not exceed the reference number of hours labour
            var labourTotalTime = jobSheet.References.FindAll(l => l.ItemID == 6).Sum(s => s.UnitTime);
            var totalTime       = jobSheet.References.FindAll(l => l.ItemID != 6).Sum(s => s.UnitTime);
            if (labourTotalTime > totalTime)
            {
                validationMessages.Add("Total hours labour must not exceed the reference number of hours labour");
            }
            #endregion

            #region conditional logic
            // To Do:
            // but at existing moment shows principles of validation

            // Here goes conditional logic, when we get Approve/Refer/Declive statuses
            //       total price < 10% => Approve (status code 1)
            // 10% < total price < 15% => Refer   (status code 2)
            // 15% < total price       => Decline (status code 3)
            // 7. Rule:
            // Total price range less than 10% => Approve
            // Total price range more than or equals 10% and Total price range less than 15% => Refer
            // Total price range more than or equals 15% => Decline
            var TotalReferencePrice = jobSheet.References.FindAll(l => l.ItemID == 6).Sum(s => (s.UnitTime * s.UnitCost));
            var TotalPrice          = jobSheet.References.FindAll(l => l.ItemID != 6).Sum(s => (s.UnitTime * s.UnitCost));

            // Generating difference in percents
            //var TotalPriceDifferenceInPercent = (TotalPrice - TotalReferencePrice) / TotalReferencePrice * 100;
            var TotalPriceDifferenceInPercent = (TotalReferencePrice - TotalPrice) / TotalPrice * 100;

            // Validating if there are no errors and TotalPriceDifferenceInPercent < 10
            if (validationMessages.Count == 0 && TotalPriceDifferenceInPercent < 10)
            {
                validationMessages.Add("Total difference is less than 10%");

                // setting up approved status
                return(new Approval()
                {
                    ApprovalStatusCode = 1,
                    ApprovalStatusMessage = "Approve",
                    ApprovalResponseCode = 200,
                    ApprovalValidationMessages = validationMessages,
                    ApprovalTime = DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)
                });
            }
            // Validating if there are no errors and TotalPriceDifferenceInPercent < 15
            else if (validationMessages.Count == 0 && TotalPriceDifferenceInPercent < 15)
            {
                validationMessages.Add("Total difference is less than 15%");

                // setting up refered status
                return(new Approval()
                {
                    ApprovalStatusCode = 2,
                    ApprovalStatusMessage = "Refer",
                    ApprovalResponseCode = 200,
                    ApprovalValidationMessages = validationMessages,
                    ApprovalTime = DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)
                });
            }
            // otherwise reject
            else
            {
                if (validationMessages.Count == 0)
                {
                    validationMessages.Add("Total difference is more than or equals 15%");
                }

                // setting up rejected status
                return(new Approval()
                {
                    ApprovalStatusCode = 3,
                    ApprovalStatusMessage = "Rejected",
                    ApprovalResponseCode = 200,
                    ApprovalValidationMessages = validationMessages,
                    ApprovalTime = DateTime.UtcNow.ToString("o", CultureInfo.InvariantCulture)
                });
            }
            #endregion
        }
コード例 #9
0
        public JobApprovalDecision ApproveJobSheet([FromBody] JobSheet jobSheet)
        {
            JobRulesEvaluator jobRulesEvaluator = new JobRulesEvaluator();

            return(jobRulesEvaluator.EvaluateAllJobRules(jobSheet));
        }
コード例 #10
0
        public JobApprovalDecision EvaluateBreakPadsAndDiscsChangeTogetherRule(JobSheet jobSheet)
        {
            IJobApprovalRule rules = new BreakPadsAndDiscsChangeTogether();

            return(rules.EvaluateRule(jobSheet));
        }
コード例 #11
0
 public MainWindow()
 {
     CurrentJobSheet = new JobSheet();
     InitializeComponent();
 }
コード例 #12
0
 public Approval Approve([FromBody] JobSheet jobSheet)
 {
     return(_approvalService.Approve(jobSheet));
 }
コード例 #13
0
        public JobApprovalDecision EvaluateTyresChangedInPairsAndMaxFourRule(JobSheet jobSheet)
        {
            IJobApprovalRule rules = new TyresChangedInPairsAndMaxFour();

            return(rules.EvaluateRule(jobSheet));
        }
コード例 #14
0
        public JobApprovalDecision EvaluateReferenceHoursNotExceedTotalHoursOfLabourRule(JobSheet jobSheet)
        {
            IJobApprovalRule rules = new ReferenceHoursNotExceedTotalHoursOfLabour();

            return(rules.EvaluateRule(jobSheet));
        }
コード例 #15
0
        public JobApprovalDecision EvaluateOverallDecisionRule(JobSheet jobSheet)
        {
            IJobApprovalRule rules = new OverallDecision();

            return(rules.EvaluateRule(jobSheet));
        }
コード例 #16
0
        public JobApprovalDecision EvaluateOneExhaustRule(JobSheet jobSheet)
        {
            IJobApprovalRule rules = new OneExhaust();

            return(rules.EvaluateRule(jobSheet));
        }
コード例 #17
0
        public Repository()
        {
            _jobSheets = new List <JobSheet>();

            var tyreOne = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Tyres",
                UnitCost        = 200,
                ItemName        = "Tyre",
                ItemTime        = 30
            };

            var tyreTwo = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Tyres",
                UnitCost        = 200,
                ItemName        = "Tyre",
                ItemTime        = 30
            };

            var tyreThree = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Tyres",
                UnitCost        = 200,
                ItemName        = "Tyre",
                ItemTime        = 30
            };

            var tyreFour = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Tyres",
                UnitCost        = 200,
                ItemName        = "Tyre",
                ItemTime        = 30
            };

            var breakPads = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Break Pads",
                UnitCost        = 50,
                ItemName        = "Pads",
                ItemTime        = 60
            };

            var discs = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Discs",
                UnitCost        = 90,
                ItemName        = "Discs",
                ItemTime        = 100
            };

            var oil5Liters = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Oil",
                UnitCost        = 20,
                ItemName        = "Oil 5 Lt",
                ItemTime        = 30
            };

            var oil10Liters = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Oil",
                UnitCost        = 40,
                ItemName        = "Oil 10 Lt",
                ItemTime        = 30
            };

            var exhaust = new Item
            {
                ItemId          = Guid.NewGuid(),
                GenericCategory = "Exhaust",
                UnitCost        = 175,
                ItemName        = "Exhaust",
                ItemTime        = 240
            };

            var tyresBreakPadsDiscs = new List <Item>
            {
                tyreOne,
                tyreTwo,
                tyreThree,
                breakPads,
                discs
            };

            var js1 = new JobSheet
            {
                Id = Guid.Parse("00000000-0000-0000-0000-000000000001"),
                ReferenceHoursInMin = tyresBreakPadsDiscs.Sum(x => x.ItemTime),
                ReferenceTotalPrice = (_labourCostHour * tyresBreakPadsDiscs.Sum(x => x.ItemTime) / 60) + (tyresBreakPadsDiscs.Sum(x => x.UnitCost)),
                LaborHourCost       = _labourCostHour,
                Items = tyresBreakPadsDiscs
            };

            var exhaustOilTyres = new List <Item>
            {
                exhaust,
                oil5Liters,
                tyreOne,
                tyreTwo
            };

            var js2 = new JobSheet
            {
                Id = Guid.Parse("00000000-0000-0000-0000-000000000002"),
                ReferenceHoursInMin = exhaustOilTyres.Sum(x => x.ItemTime),
                ReferenceTotalPrice = (_labourCostHour * exhaustOilTyres.Sum(x => x.ItemTime) / 60) + (exhaustOilTyres.Sum(x => x.UnitCost)),
                LaborHourCost       = _labourCostHour,
                Items = exhaustOilTyres
            };

            var breakPadsDiscsOil5LitersTyres = new List <Item>
            {
                breakPads,
                discs,
                oil5Liters,
                tyreOne,
                tyreTwo
            };

            var js3 = new JobSheet
            {
                Id = Guid.Parse("00000000-0000-0000-0000-000000000003"),
                ReferenceHoursInMin = breakPadsDiscsOil5LitersTyres.Sum(x => x.ItemTime),
                ReferenceTotalPrice = (_labourCostHour * breakPadsDiscsOil5LitersTyres.Sum(x => x.ItemTime) / 60) + (breakPadsDiscsOil5LitersTyres.Sum(x => x.UnitCost)),
                LaborHourCost       = _labourCostHour,
                Items = breakPadsDiscsOil5LitersTyres
            };

            _jobSheets.Add(js1);
            _jobSheets.Add(js2);
            _jobSheets.Add(js3);
        }
コード例 #18
0
        /// <summary>
        /// Get all reference items generated randomly
        /// </summary>
        /// <returns>item containing references and total amount</returns>
        public JobSheet GetItem()
        {
            // Initiating random generator
            Random rng = new Random();

            // Generating random Job Sheet
            List <Reference> references = Enumerable.Range(1, rng.Next(1, 5)).Select(index => new Reference
            {
                ItemID      = index,
                ItemTitle   = Titles[rng.Next(Titles.Length)],
                UnitTime    = rng.Next(30, 240),
                UnitCost    = (float)rng.Next(20, 200),
                MustInclude = false
            }).ToList <Reference>();

            // Updating Item IDs and Labor property
            references.ForEach(delegate(Reference reference)
            {
                reference.ItemID      = Array.IndexOf(Titles, reference.ItemTitle) + 1;
                reference.MustInclude = (reference.ItemTitle == "Labor" ? true : false);
            });

            //// Getting Labor if any exist
            //List<Reference> labours = references.FindAll(l => l.ItemID == 6);
            //// if none, add one
            //if (labours.Count == 0)
            //{
            //    references.Add(new Reference()
            //    {
            //        ItemID = 6,
            //        ItemTitle = "Labor",
            //        UnitTime = 60,
            //        UnitCost = 45.00f,
            //        MustInclude = true
            //    });
            //}

            // Add labor as it has to have at least one labor
            references.Add(new Reference()
            {
                ItemID      = 6,
                ItemTitle   = "Labor",
                UnitTime    = 60,
                UnitCost    = 45.00f,
                MustInclude = true
            });

            // Genarating job sheet with random property values and total amount
            JobSheet jobsheet = new JobSheet()
            {
                TotalAmount = references.Sum(s => s.UnitTime * s.UnitCost),
                References  = references
                              //References = new List<Reference>() {
                              //    new Reference
                              //    {
                              //        ItemTitle = "Tyre",
                              //        UnitTime = 30,
                              //        UnitCost = 200.00f
                              //    },
                              //    new Reference
                              //    {
                              //        ItemTitle = "Brake Discs",
                              //        UnitTime = 90,
                              //        UnitCost = 100.00f
                              //    },
                              //    new Reference
                              //    {
                              //        ItemTitle = "Brake Pads",
                              //        UnitTime = 60,
                              //        UnitCost = 50.00f
                              //    },
                              //    new Reference
                              //    {
                              //        ItemTitle = "Oil",
                              //        UnitTime = 30,
                              //        UnitCost = 20.00f
                              //    },
                              //    new Reference
                              //    {
                              //        ItemTitle = "Exhaust",
                              //        UnitTime = 240,
                              //        UnitCost = 175.00f
                              //    }

                              //}
            };

            return(jobsheet);
        }