public async Task <ServiceResult <CalculationResponse> > Calculate(Guid costStageRevisionId, CalculationRequest request)
        {
            if (request == null)
            {
                return(ServiceResult <CalculationResponse> .CreateFailedResult("Invalid request."));
            }

            //Get the contract period
            var usageForm = await _costFormService.GetCostFormDetails <BuyoutDetails>(costStageRevisionId);

            var contract  = usageForm.Contract;
            var startDate = contract.StartDate;
            var endDate   = contract.EndDate ?? DateTime.UtcNow;

            //Build the financial years based on start and end date
            var contractPeriodResult = await _financialYearService.Calculate(BuType.Pg, startDate, endDate);

            var model = new CalculationResponse();

            var costStageRevision = await _efContext.CostStageRevision
                                    .Include(c => c.CostLineItems)
                                    .Include(c => c.BillingExpenses)
                                    .Include(c => c.CostStage)
                                    .FirstOrDefaultAsync(c => c.Id == costStageRevisionId);

            var billingExpenses = costStageRevision.BillingExpenses;

            //Build the Billing Expense
            model.Data = _builder.BuildExpenses(costStageRevision.CostStage, request.Cells, contractPeriodResult.Result);

            //Calculate items in the Billing Expense
            await _calculator.CalculateExpenses(usageForm.Contract.ContractTotal, model.Data, billingExpenses);

            //Update/Interpolate any related cost line items
            model.CostLineItems = await _interpolator.InterpolateCostLineItems(costStageRevision.CostStage.CostId, costStageRevisionId, model.Data);

            return(ServiceResult <CalculationResponse> .CreateSuccessfulResult(model));
        }
        public async Task <ServiceResult <BillingExpenseViewModel> > Get(Guid costStageRevisionId)
        {
            //Get the contract period
            var usageForm = await _costFormService.GetCostFormDetails <BuyoutDetails>(costStageRevisionId);

            var contract  = usageForm.Contract;
            var startDate = contract.StartDate;
            var endDate   = contract.EndDate ?? DateTime.UtcNow;

            //Build the financial years based on start and end date
            var financialYears = await _financialYearService.Calculate(BuType.Pg, startDate, endDate);

            var model = new BillingExpenseViewModel();

            //Get the payment currency from the stage details form
            var stageForm = await _costStageRevisionService.GetStageDetails <PgStageDetailsForm>(costStageRevisionId);

            var paymentCurrency = await _efContext.Currency.FirstOrDefaultAsync(c => c.Code == stageForm.AgencyCurrency);

            model.PaymentCurrency = paymentCurrency;

            var billingExpenses = await _efContext.BillingExpense.Where(be => be.CostStageRevisionId == costStageRevisionId).ToListAsync();

            //Build the billing expenses
            var costStage = await _efContext.CostStageRevision
                            .Where(c => c.Id == costStageRevisionId)
                            .Select(c => c.CostStage).FirstOrDefaultAsync();

            model.Data     = _builder.BuildExpenses(costStage, billingExpenses, financialYears.Result);
            model.Modified = billingExpenses.Count > 0 ? billingExpenses.Max(b => b.Modified) : null;
            model.Saved    = model.Modified != null;

            //Perform any calculations
            await _calculator.CalculateExpenses(usageForm.Contract.ContractTotal, model.Data, billingExpenses);

            return(ServiceResult <BillingExpenseViewModel> .CreateSuccessfulResult(model));
        }