public async Task <string> ConvertToSubmissionAsync(CancellationToken cancellationToken, long ukprn, string collectionName)
        {
            using (IFundingClaimsDataContext context = _fundingClaimsContextFactory())
            {
                var submission = await GetSubmissionAsync(cancellationToken, context, ukprn, null, collectionName);

                if (submission == null)
                {
                    throw new ArgumentException($"no submission found for submission for ukprn : {ukprn}, collection Name : {collectionName}, can not proceed with submission");
                }

                var contractsAllocations =
                    await _fundingClaimsReferenceDataService.GetContractAllocationsAsync(
                        cancellationToken,
                        submission.Ukprn,
                        submission.Collection.CollectionYear);

                var fundingStreamPeriodCodes = context.SubmissionValue
                                               .Where(x => x.SubmissionId == submission.SubmissionId)
                                               .Select(x => x.FundingStreamPeriodCode)
                                               .Distinct();

                foreach (var value in fundingStreamPeriodCodes)
                {
                    var contract = contractsAllocations?.FirstOrDefault(x => x.FundingStreamPeriodCode.Equals(value));

                    if (contract != null)
                    {
                        submission.OrganisationIdentifier = contract.OrganisationIdentifier;

                        submission.SubmissionContractDetail.Add(new SubmissionContractDetail()
                        {
                            SubmissionId            = submission.SubmissionId,
                            FundingStreamPeriodCode = value,
                            ContractValue           = contract.MaximumContractValue,
                        });
                    }
                }

                // Mark as submitted
                submission.IsSubmitted          = true;
                submission.SubmittedBy          = submission.CreatedBy;
                submission.SubmittedDateTimeUtc = _dateTimeProvider.GetNowUtc();
                submission.Declaration          = true;
                submission.Version = await GetLatestSubmissionVersionAsync(cancellationToken, ukprn);

                await context.SaveChangesAsync(cancellationToken);

                _logger.LogInfo($"Successfully converted to funding claims submission for submission Id :{submission.SubmissionId}");

                return(submission.SubmissionId.ToString());
            }
        }
        public async Task UpdateCovidDeclaration(CancellationToken cancellationToken, long ukprn, string collectionName, bool?value)
        {
            using (IFundingClaimsDataContext context = _fundingClaimsContextFactory())
            {
                var submission = await GetSubmissionAsync(cancellationToken, context, ukprn, null, collectionName, false);

                if (submission == null)
                {
                    throw new ArgumentException(
                              $"no submission found for submission for ukprn : {ukprn}, collection Name : {collectionName}, can not proceed with submission");
                }

                submission.CovidDeclaration = value;

                await context.SaveChangesAsync(cancellationToken);
            }
        }
        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);
        }