public async Task <Dictionary <string, StageModel> > GetStages(Guid costId)
        {
            var cost = await _efContext.Cost
                       .Include(c => c.LatestCostStageRevision)
                       .ThenInclude(r => r.CostStage)
                       .Include(c => c.LatestCostStageRevision)
                       .ThenInclude(r => r.CostLineItems)
                       .Include(c => c.LatestCostStageRevision)
                       .ThenInclude(d => d.StageDetails)
                       .Include(c => c.LatestCostStageRevision)
                       .ThenInclude(r => r.ProductDetails)
                       .FirstAsync(c => c.Id == costId);

            var stageDetails      = _costStageRevisionService.GetStageDetails <PgStageDetailsForm>(cost.LatestCostStageRevision);
            var productionDetails = _costStageRevisionService.GetProductionDetails <PgProductionDetailsForm>(cost.LatestCostStageRevision);
            var revisionTotals    = await _pgCostService.GetRevisionTotals(cost.LatestCostStageRevision);

            var stageRule = new PgStageRule
            {
                ProductionType     = stageDetails.ProductionType?.Key,
                ContentType        = stageDetails.ContentType?.Key,
                BudgetRegion       = stageDetails.BudgetRegion?.Key,
                CostType           = cost.CostType.ToString(),
                TargetBudgetAmount = stageDetails.InitialBudget.GetValueOrDefault(),
                IsAIPE             = stageDetails.IsAIPE,
                TotalCostAmount    = revisionTotals.total
            };

            return(await GetStages(stageRule, productionDetails?.DirectPaymentVendor?.Id));
        }
        public async Task <Dictionary <string, StageModel> > GetStages(PgStageRule stageRule, Guid?vendorId = null)
        {
            var rules = new List <CompiledRule <PgStageRule> >();

            var commonStageRules = await _ruleService.GetCompiledByRuleType <PgStageRule>(RuleType.Stage);

            rules.AddRange(commonStageRules);
            if (vendorId.HasValue)
            {
                rules.AddRange(await _ruleService.GetCompiledByVendorId <PgStageRule>(vendorId.Value, RuleType.VendorStage, null));
            }

            return(GetStages(stageRule, rules));
        }
Exemple #3
0
        private async Task <Dictionary <string, StageModel> > GetStages(PgStageDetailsForm stageDetailsForm, CostType costType)
        {
            var testStageRule = new PgStageRule
            {
                BudgetRegion       = stageDetailsForm.BudgetRegion?.Key,
                ContentType        = stageDetailsForm.ContentType?.Key,
                ProductionType     = stageDetailsForm.ProductionType?.Key,
                CostType           = costType.ToString(),
                TargetBudgetAmount = stageDetailsForm.InitialBudget.GetValueOrDefault()
            };
            var stages = await _pgStageBuilder.GetStages(testStageRule);

            return(stages);
        }
        /// <summary>
        /// Build Stage and its rules
        /// <para>Required: Cost revision must have data of Cost Line Item / Stage Details / Production Details</para>
        /// </summary>
        public async Task <Dictionary <string, StageModel> > GetStages(CostType costType, CostStageRevision costStageRevision)
        {
            var stageDetails      = _costStageRevisionService.GetStageDetails <PgStageDetailsForm>(costStageRevision);
            var productionDetails = _costStageRevisionService.GetProductionDetails <PgProductionDetailsForm>(costStageRevision);
            var revisionTotals    = costStageRevision.CostLineItems.Sum(cli => cli.ValueInDefaultCurrency);

            var stageRule = new PgStageRule
            {
                ProductionType     = stageDetails.ProductionType?.Key,
                ContentType        = stageDetails.ContentType?.Key,
                BudgetRegion       = stageDetails.BudgetRegion?.Key,
                CostType           = costType.ToString(),
                TargetBudgetAmount = stageDetails.InitialBudget.GetValueOrDefault(),
                IsAIPE             = stageDetails.IsAIPE,
                TotalCostAmount    = revisionTotals
            };

            return(await GetStages(stageRule, productionDetails?.DirectPaymentVendor?.Id));
        }
        private Dictionary <string, StageModel> GetStages(PgStageRule stageRule, List <CompiledRule <PgStageRule> > rules)
        {
            var matchFunc = new Func <PgStageRule, Rule, PgStageRuleDefinition>((t, r) =>
                                                                                (PgStageRuleDefinition)JsonConvert.DeserializeObject(r.Definition, typeof(PgStageRuleDefinition))
                                                                                );

            var aggregator = new Func <PgStageRuleDefinition, PgStageRuleDefinition, PgStageRuleDefinition>((acc, r) =>
            {
                // Add stages/transitions according to the rule
                foreach (var stage in r.Add.Stages.Keys)
                {
                    if (!acc.Add.Stages.ContainsKey(stage))
                    {
                        acc.Add.Stages.Add(stage, r.Add.Stages[stage]);
                    }
                    else
                    {
                        // Override stage
                        acc.Add.Stages[stage] = r.Add.Stages[stage];
                    }
                }

                foreach (var stage in r.Add.Transitions.Keys)
                {
                    if (!acc.Add.Transitions.ContainsKey(stage))
                    {
                        acc.Add.Transitions.Add(stage, r.Add.Transitions[stage]);
                    }
                    else
                    {
                        // Add additional transitions
                        acc.Add.Transitions[stage] = acc.Add.Transitions[stage].OrderedMerge(r.Add.Transitions[stage]);
                    }
                }

                // Remove stages/transitions according to the rule
                foreach (var stage in r.Remove.Stages)
                {
                    if (acc.Add.Stages.ContainsKey(stage))
                    {
                        acc.Add.Stages.Remove(stage);
                    }

                    if (acc.Add.Transitions.ContainsKey(stage))
                    {
                        acc.Add.Transitions.Remove(stage);
                    }
                }

                foreach (var key in acc.Add.Transitions.Keys.ToArray())
                {
                    acc.Add.Transitions[key] = acc.Add.Transitions[key].Except(r.Remove.Stages);
                }

                foreach (var key in r.Remove.Transitions.Keys)
                {
                    if (acc.Add.Transitions.ContainsKey(key))
                    {
                        acc.Add.Transitions[key] = acc.Add.Transitions[key].Where(v => !r.Remove.Transitions[key].Contains(v));
                        if (!acc.Add.Transitions[key].Any())
                        {
                            acc.Add.Transitions.Remove(key);
                        }
                    }
                }

                return(acc);
            });

            PgStageRuleDefinition definition;

            _ruleService.TryMatchRule(rules, stageRule, matchFunc, aggregator, out definition);

            // Sort stages in reverse topological order
            var stages = Sort(ToStageModes(definition));

            return(stages);
        }