public async Task <FundingClaimsData> GetSubmissionDetailsAsync(CancellationToken cancellationToken, long ukprn, Guid?submissionId = null, string collectionName = null)
        {
            var result = new FundingClaimsData();
            var items  = new List <FundingClaimsDataItem>();

            try
            {
                using (IFundingClaimsDataContext context = _fundingClaimsContextFactory())
                {
                    var submission = await GetSubmissionAsync(cancellationToken, context, ukprn, submissionId, collectionName);

                    if (submission == null)
                    {
                        _logger.LogDebug($"submission not found for submission id : {submissionId} and ukprn : {ukprn}");
                        return(result);
                    }

                    result.CovidDeclaration = submission.CovidDeclaration;

                    items = await context.SubmissionValue.Where(x => x.SubmissionId == submission.SubmissionId)
                            .Select(x => new FundingClaimsDataItem()
                    {
                        ContractAllocationNumber = x.ContractAllocationNumber,
                        DeliverableCode          = x.FundingStreamPeriodDeliverableCode.DeliverableCode,
                        DeliverableDescription   = x.FundingStreamPeriodDeliverableCode.Description,
                        DeliveryToDate           = x.DeliveryToDate,
                        ExceptionalAdjustments   = x.ExceptionalAdjustments,
                        ForecastedDelivery       = x.ForecastedDelivery,
                        FundingStreamPeriodCode  = x.FundingStreamPeriodCode,
                        StudentNumbers           = x.StudentNumbers,
                        TotalDelivery            = x.TotalDelivery,
                    })
                            .ToListAsync(cancellationToken);

                    result.FundingClaimsDataItems = items;
                }
            }
            catch (Exception e)
            {
                _logger.LogError(
                    $"error getting submission detail for ukprn : {ukprn}, submission id : {submissionId} ", e);
                throw;
            }

            _logger.LogInfo($"return submission detail for ukprn : {ukprn}, submission id : {submissionId}");

            return(result);
        }
        public async Task <bool> SaveSubmissionAsync(CancellationToken cancellationToken, FundingClaimsData fundingClaimsData)
        {
            try
            {
                using (IFundingClaimsDataContext context = _fundingClaimsContextFactory())
                {
                    var today = _dateTimeProvider.GetNowUtc();

                    var submission = await GetSubmissionAsync(cancellationToken, context, fundingClaimsData.Ukprn, null, fundingClaimsData.CollectionName, false);

                    //find unique FSPs
                    var fundingStreamPeriodCodes = fundingClaimsData.FundingClaimsDataItems
                                                   .Select(x => x.FundingStreamPeriodCode).Distinct();

                    var deliverableCodes = await context.FundingStreamPeriodDeliverableCode.ToListAsync(cancellationToken);

                    if (submission == null)
                    {
                        submission = new Submission
                        {
                            SubmissionId       = Guid.NewGuid(),
                            Ukprn              = fundingClaimsData.Ukprn,
                            Collection         = await context.CollectionDetail.SingleOrDefaultAsync(x => x.CollectionName == fundingClaimsData.CollectionName, cancellationToken),
                            CreatedBy          = fundingClaimsData.UserName,
                            CreatedDateTimeUtc = today,
                        };

                        var latestSubmission = await GetSubmissionAsync(cancellationToken, context, fundingClaimsData.Ukprn, null, fundingClaimsData.CollectionName, true);

                        if (latestSubmission != null & fundingStreamPeriodCodes.All(x => x != _fundingStreamPeriodCodes[fundingClaimsData.CollectionYear].Ilr16To19))
                        {
                            submission.SubmissionValue = context.SubmissionValue.Where(x => x.SubmissionId == latestSubmission.SubmissionId &&
                                                                                       x.FundingStreamPeriodCode == _fundingStreamPeriodCodes[fundingClaimsData.CollectionYear].Ilr16To19)
                                                         .ToList();
                        }

                        context.Submission.Add(submission);
                    }
                    else
                    {
                        //find and remove values
                        context.SubmissionValue.RemoveRange(context.SubmissionValue.Where(x =>
                                                                                          x.SubmissionId == submission.SubmissionId &&
                                                                                          fundingStreamPeriodCodes.Contains(x.FundingStreamPeriodCode)));
                        context.ChangeLog.RemoveRange(
                            context.ChangeLog.Where(f => f.SubmissionId == submission.SubmissionId));

                        _logger.LogInfo(
                            $"removed funding claims draft data submission detail for ukprn : {fundingClaimsData.Ukprn}, collectionName: {fundingClaimsData.CollectionName}");
                    }

                    submission.IsSigned             = false;
                    submission.SubmittedDateTimeUtc = null;
                    submission.SubmittedBy          = null;
                    submission.SignedOnDateTimeUtc  = null;
                    submission.Version = 0;

                    foreach (var value in fundingClaimsData.FundingClaimsDataItems)
                    {
                        var deliverableCode = deliverableCodes.Single(x => x.DeliverableCode == value.DeliverableCode && x.FundingStreamPeriodCode == value.FundingStreamPeriodCode);

                        submission.SubmissionValue.Add(new SubmissionValue()
                        {
                            SubmissionId                       = submission.SubmissionId,
                            ContractAllocationNumber           = value.ContractAllocationNumber,
                            ExceptionalAdjustments             = value.ExceptionalAdjustments.GetValueOrDefault(),
                            FundingStreamPeriodCode            = value.FundingStreamPeriodCode,
                            ForecastedDelivery                 = value.ForecastedDelivery.GetValueOrDefault(),
                            DeliveryToDate                     = value.DeliveryToDate.GetValueOrDefault(),
                            StudentNumbers                     = value.StudentNumbers.GetValueOrDefault(),
                            TotalDelivery                      = value.TotalDelivery.GetValueOrDefault(),
                            FundingStreamPeriodDeliverableCode = deliverableCode,
                        });
                    }

                    submission.ChangeLog = new List <ChangeLog>
                    {
                        new ChangeLog
                        {
                            SubmissionId       = submission.SubmissionId,
                            UserEmailAddress   = fundingClaimsData.EmailAddress,
                            UpdatedDateTimeUtc = today,
                        },
                    };

                    await context.SaveChangesAsync(cancellationToken);

                    _logger.LogInfo(
                        $"saved funding claims draft data submission for ukprn : {fundingClaimsData.Ukprn}, collectionPerioId : {fundingClaimsData.CollectionName} ");
                }
            }
            catch (Exception e)
            {
                _logger.LogError(
                    $"error getting submission detail for ukprn : {fundingClaimsData.Ukprn}, collectionPerioId id : {fundingClaimsData.CollectionName} ",
                    e);
                throw;
            }

            return(true);
        }