public async Task <List <SupportingDocumentModel> > BuildSupportingDocuments(IStageDetails stageDetails, CostType costType, IEnumerable <string> stageKeys, Guid costStageRevisionId, bool totalCostIncreased = false) { var stageDetailsForm = stageDetails.Data.ToModel <PgStageDetailsForm>(); var rules = (await _ruleService.GetCompiledByRuleType <SupportingDocumentRule>(RuleType.SupportingDocument)).ToArray(); var supportingDocs = new List <SupportingDocumentModel>(); var previousRevision = await _costStageRevisionService.GetPreviousRevision(costStageRevisionId); foreach (var stage in stageKeys) { var supportingDocRule = new SupportingDocumentRule { BudgetRegion = stageDetailsForm.BudgetRegion?.Key, ContentType = stageDetailsForm.ContentType?.Key, CostStage = stage, ProductionType = stageDetailsForm.ProductionType?.Key, CostType = costType.ToString(), TotalCostIncreased = totalCostIncreased, PreviousCostStage = previousRevision != null ? previousRevision?.Name : string.Empty }; List <SupportingDocumentModel> output; Func <SupportingDocumentRule, Rule, List <SupportingDocumentModel> > matched = (supportingDocumentRule, rule) => { var ruleDefinition = JsonConvert.DeserializeObject <SupportingDocumentRuleDefinition>(rule.Definition); return(new List <SupportingDocumentModel> { new SupportingDocumentModel { CanManuallyUpload = ruleDefinition.CanManuallyUpload, Name = ruleDefinition.Name, Key = ruleDefinition.Key ?? string.Empty, Generated = true, Required = ruleDefinition.Mandatory } }); }; Func <List <SupportingDocumentModel>, List <SupportingDocumentModel>, List <SupportingDocumentModel> > aggregator = (total, result) => { total.AddRange(result); return(total); }; _ruleService.TryMatchRule(rules, supportingDocRule, matched, aggregator, out output); if (output != null) { supportingDocs.AddRange(output); } } return(supportingDocs); }
public async Task UpdateTechnicalFeeLineItem(Guid costId, Guid latestRevisionId) { var currentRevision = await _efContext.CostStageRevision .Include(x => x.Approvals) .ThenInclude(x => x.ApprovalMembers) .ThenInclude(x => x.CostUser) .ThenInclude(x => x.UserBusinessRoles) .ThenInclude(a => a.BusinessRole) .FirstOrDefaultAsync(x => x.Id == latestRevisionId); var costConsultantApprovals = currentRevision.Approvals?.Where(x => x.Type == ApprovalType.IPM && x.ValidBusinessRoles?.Contains(Constants.BusinessRole.CostConsultant) == true) .ToList(); var costConsultantSelected = costConsultantApprovals .Any(x => x.ApprovalMembers .Any(m => m.CostUser.UserBusinessRoles.Any(a => a.BusinessRole.Value == Constants.BusinessRole.CostConsultant))); var costLineItems = await _efContext.CostLineItem.Where(x => x.CostStageRevisionId == latestRevisionId).ToListAsync(); var techFeeLineItem = costLineItems.FirstOrDefault(x => x.Name == Constants.CostSection.TechnicalFee); if (techFeeLineItem != null) { // tech fee is applicable, let's see if we need to recalculate the value if (costConsultantSelected && costConsultantApprovals.Any()) { // currently there is a cost consultant selected var fee = await GetTechnicalFee(costId); if (fee != null && fee.ConsultantRate != 0) { // we got a CC rate, but we only save it if current value is 0 if (techFeeLineItem.ValueInDefaultCurrency == 0) { // calculate values based on FX rate var feeCurrency = await _currencyService.GetCurrency(fee.CurrencyCode); if (feeCurrency != null && !feeCurrency.DefaultCurrency) { // only calculate fx rate for foreign currencies var defaultFxRate = await _costExchangeRateService.GetExchangeRateByCurrency(costId, feeCurrency.Id); techFeeLineItem.ValueInDefaultCurrency = fee.ConsultantRate * defaultFxRate.Rate; } else { techFeeLineItem.ValueInDefaultCurrency = fee.ConsultantRate; } var localCurrency = await _currencyService.GetCurrency(techFeeLineItem.LocalCurrencyId); if (localCurrency != null && !localCurrency.DefaultCurrency) { var localFxRate = await _costExchangeRateService.GetExchangeRateByCurrency(costId, techFeeLineItem.LocalCurrencyId); techFeeLineItem.ValueInLocalCurrency = techFeeLineItem.ValueInDefaultCurrency / localFxRate.Rate; // reverse conversion } else { techFeeLineItem.ValueInLocalCurrency = techFeeLineItem.ValueInDefaultCurrency; } _efContext.Update(techFeeLineItem); await _efContext.SaveChangesAsync(); } } } else if (techFeeLineItem.ValueInDefaultCurrency > 0) { // cost consultant is not selected, but there is a fee - let's set the rate to 0 if previously we don't have any approved revisions/stages with tech fee var previousRevision = await _costStageRevisionService.GetPreviousRevision(currentRevision.Id); if (previousRevision != null) { var previousCostLineItems = await _costStageRevisionService.GetCostLineItems(previousRevision.Id); var prevTechFeeLineItem = previousCostLineItems.FirstOrDefault(x => x.Name == Constants.CostSection.TechnicalFee); if (prevTechFeeLineItem == null || prevTechFeeLineItem.ValueInDefaultCurrency == 0) { // we don't have a value - let's set it to 0 await SetToZeroAndSave(techFeeLineItem); } } else { // we don't have a previous review - let's set it to 0 await SetToZeroAndSave(techFeeLineItem); } } } }