private async Task <List <SectionReference> > CreateIntercoContractOnUpdateContract(UpdatePhysicalContractCommand request,
                                                                                            Section section, List <SectionReference> sectionReferences)
        {
            string counterpartyCode = (request.Type == ContractType.Purchase) ? request.SellerCode : request.BuyerCode;
            var    counterparty     = await _masterDataService.GetAllByCounterpartyIdAsync(request.CompanyId, counterpartyCode);

            if (counterparty != null && counterparty.FirstOrDefault() != null &&
                counterparty.FirstOrDefault().CompanyId != request.CompanyId &&
                counterparty.FirstOrDefault().IsCounterpartyGroupAccount)
            {
                if (section != null && !section.IsInterco &&
                    (section.Type == ContractType.Purchase || section.Type == ContractType.Sale) &&
                    (section.SectionOriginId == 0) && (section.InvoicingStatusId == (long)InvoicingStatus.Uninvoiced))
                {
                    var dataVersionId = await _systemDateTimeService.GetCompanyCurrentDataVersionId(request.IntercoCompanyId);

                    var intercoPhysicalFixedPricedContract = _mapper.Map <Section>(section);
                    intercoPhysicalFixedPricedContract.CompanyId             = request.IntercoCompanyId;
                    intercoPhysicalFixedPricedContract.TraderId              = request.IntercoTraderId;
                    intercoPhysicalFixedPricedContract.DepartmentId          = request.IntercoDepartmentId;
                    intercoPhysicalFixedPricedContract.Type                  = (request.Type == ContractType.Purchase) ? ContractType.Sale : ContractType.Purchase;
                    intercoPhysicalFixedPricedContract.DataVersionId         = dataVersionId;
                    intercoPhysicalFixedPricedContract.ContractDate          = DateTime.UtcNow;
                    intercoPhysicalFixedPricedContract.PaymentTerms          = section.PaymentTermCode;
                    intercoPhysicalFixedPricedContract.ContractTerms         = section.ContractTermCode;
                    intercoPhysicalFixedPricedContract.ContractTermsLocation = section.ContractTermLocationCode;

                    string supplierCode = (section.Type == ContractType.Purchase) ? section.SellerCode : section.BuyerCode;
                    intercoPhysicalFixedPricedContract.Costs = (await _costRepository.LoadSectionCostsAsync(intercoPhysicalFixedPricedContract.SectionId,
                                                                                                            request.CompanyId, request.DataVersionId)).Where(c => c.SupplierCode == supplierCode).ToList();

                    // only one contract has to be always created
                    intercoPhysicalFixedPricedContract.NumberOfContract = 1;
                    intercoPhysicalFixedPricedContract.SectionId        = 0;

                    var intercoReferences = (await _tradeRepository.CreatePhysicalContractAsImageAsync(intercoPhysicalFixedPricedContract)).ToList();

                    foreach (var intercoItem in intercoReferences)
                    {
                        if (intercoItem.SectionId > 0 && intercoPhysicalFixedPricedContract.Costs.Any())
                        {
                            foreach (var intercoCostItem in intercoPhysicalFixedPricedContract.Costs)
                            {
                                intercoCostItem.CostId          = 0;
                                intercoCostItem.CompanyId       = intercoPhysicalFixedPricedContract.CompanyId;
                                intercoCostItem.SectionId       = intercoItem.SectionId;
                                intercoCostItem.DataVersionId   = dataVersionId;
                                intercoCostItem.CostDirectionId = (intercoCostItem.CostDirectionId == 1) ? 2 : 1;
                            }

                            // check the business rule for PriceUnitId.
                            await _costRepository.AddCostsAsync(intercoPhysicalFixedPricedContract.Costs, intercoPhysicalFixedPricedContract.CompanyId, dataVersionId);
                        }
                    }

                    var childSectionsDto = await _sectionQueries.GetTradeChildSectionDataAsync(request.CompanyId, request.SectionId, null, null);

                    // request.ChildSections would not be null if only it is Imaging the trade and we have selected Image Splits/tranche option as well
                    if (childSectionsDto != null && childSectionsDto.Any())
                    {
                        IEnumerable <SectionDeprecated> childSections = MapChildSections(childSectionsDto);

                        CreateSplitCommand splitRequest = new CreateSplitCommand();
                        splitRequest.ChildSections    = childSections;
                        splitRequest.CompanyId        = request.IntercoCompanyId;
                        splitRequest.OriginalQuantity = request.Quantity;
                        splitRequest.Quantity         = request.Quantity;
                        var sectionTrancheContract = _mapper.Map <SectionDeprecated>(splitRequest);
                        sectionTrancheContract.SectionId     = intercoReferences.FirstOrDefault().SectionId;
                        sectionTrancheContract.ContractLabel = intercoReferences.FirstOrDefault().ContractLabel;
                        foreach (var splitTrancheItem in sectionTrancheContract.ChildSections)
                        {
                            splitTrancheItem.SectionId             = 0;
                            splitTrancheItem.ContractId            = intercoReferences.FirstOrDefault().PhysicalContractId;
                            splitTrancheItem.SectionOriginId       = (int)intercoReferences.FirstOrDefault().SectionId;
                            splitTrancheItem.BuyerCode             = intercoPhysicalFixedPricedContract.BuyerCode;
                            splitTrancheItem.SellerCode            = intercoPhysicalFixedPricedContract.SellerCode;
                            splitTrancheItem.Memorandum            = string.Empty;
                            splitTrancheItem.CounterpartyReference = string.Empty;
                            splitTrancheItem.DeliveryPeriodEndDate = intercoPhysicalFixedPricedContract.DeliveryPeriodEndDate.Value;
                            splitTrancheItem.DepartmentId          = intercoPhysicalFixedPricedContract.DepartmentId;
                            splitTrancheItem.Status        = ContractStatus.Unapproved;
                            splitTrancheItem.PricingMethod = intercoPhysicalFixedPricedContract.PricingMethod;
                        }

                        bool isTradeImage          = true;
                        var  splitTranchReferences = await _tradeRepository.CreateTrancheSplitAsync(sectionTrancheContract, request.IntercoCompanyId, isTradeImage);

                        // Inserting cost while creating an Image of a trade,if available
                        foreach (var childItem in splitTranchReferences)
                        {
                            int index = 0;
                            childItem.Costs = (await _costRepository.LoadSectionCostsAsync(childSectionsDto.ToList()[index].SectionId,
                                                                                           request.CompanyId, request.DataVersionId)).Where(c => c.SupplierCode == supplierCode).ToList();

                            if (childItem.Costs != null)
                            {
                                foreach (var costItem in childItem.Costs)
                                {
                                    costItem.CostId          = 0;
                                    costItem.CompanyId       = intercoPhysicalFixedPricedContract.CompanyId;
                                    costItem.SectionId       = childItem.SectionId;
                                    costItem.DataVersionId   = dataVersionId;
                                    costItem.CostDirectionId = (costItem.CostDirectionId == 1) ? 2 : 1;
                                }

                                await _costRepository.AddCostsAsync(childItem.Costs, request.IntercoCompanyId, dataVersionId);
                            }
                            index++;
                        }
                    }

                    // Update Reference & Memo Details
                    var sourceDataVersionId = await _systemDateTimeService.GetCompanyCurrentDataVersionId(request.CompanyId);

                    await UpdateReferenceAndInternalMemo(sourceDataVersionId,
                                                         request.PhysicalContractId,
                                                         request.IntercoCompanyId.ToUpper() + "/" + intercoReferences.FirstOrDefault().ContractLabel,
                                                         dataVersionId,
                                                         intercoReferences.FirstOrDefault().PhysicalContractId,
                                                         request.CompanyId.ToUpper() + "/" + section.ContractLabel,
                                                         request.Type);

                    sectionReferences.AddRange(intercoReferences);
                }
            }
            if (section != null && section.IsInterco && request.IsRemoveInterco)
            {
                await _tradeRepository.DeleteReferenceAndInternalMemoAsync(section.PhysicalContractId);
            }

            return(sectionReferences);
        }
        public async Task <IEnumerable <SectionReference> > Handle(UpdatePhysicalContractCommand request, CancellationToken cancellationToken)
        {
            List <SectionReference> sectionReferences = new List <SectionReference>();

            _unitOfWork.BeginTransaction();
            try
            {
                var companyDate = await _systemDateTimeService.GetCompanyDate(request.CompanyId);

                if (request.ContractDate.Date > companyDate.Date)
                {
                    throw new AtlasBusinessException($"Contract date cannot be in the future. Contract date: {request.ContractDate.Date}. Company date: {companyDate}.");
                }

                if (request.DataVersionId != null)
                {
                    var freezeDate = await _freezeRepository.GetFreezeNotClosedAsync(request.CompanyId, request.DataVersionId.Value);

                    if (freezeDate == null)
                    {
                        throw new AtlasBusinessException($"Contracts cannot be updated in a freeze if the month is closed.");
                    }
                }

                var physicalFixedPricedContract = _mapper.Map <Section>(request);
                var company = await _masterDataService.GetCompanyByIdAsync(request.CompanyId);

                if (company.IsProvinceEnable)
                {
                    physicalFixedPricedContract.ProvinceId = company.DefaultProvinceId;
                    physicalFixedPricedContract.BranchId   = company.DefaultBranchId;
                }
                else
                {
                    physicalFixedPricedContract.ProvinceId = null;
                    physicalFixedPricedContract.BranchId   = null;
                }

                var section = await _sectionRepository.GetSectionById(request.SectionId, request.CompanyId, request.DataVersionId);

                if (section.EstimatedMaturityDate == physicalFixedPricedContract.EstimatedMaturityDate &&
                    (section.DeliveryPeriodStartDate != physicalFixedPricedContract.DeliveryPeriodStartDate ||
                     section.DeliveryPeriodEndDate != physicalFixedPricedContract.DeliveryPeriodEndDate ||
                     section.PaymentTermCode != physicalFixedPricedContract.PaymentTermCode ||
                     physicalFixedPricedContract.BlDate != section.BlDate ||
                     section.InvoiceDate != physicalFixedPricedContract.InvoiceDate ||
                     section.PositionMonthType != physicalFixedPricedContract.PositionMonthType ||
                     section.MonthPositionIndex != physicalFixedPricedContract.MonthPositionIndex))
                {
                    physicalFixedPricedContract.EstimatedMaturityDate = null;
                }

                physicalFixedPricedContract.EstimatedMaturityDate = await CalculateEstimatedMaturityDate(physicalFixedPricedContract, request.CompanyId);

                if (section.IsClosed)
                {
                    throw new AtlasBusinessException($"Closed trade cannot be updated.");
                }

                physicalFixedPricedContract.IsInterco = request.IsInterco;
                await _tradeRepository.UpdatePhysicalContractAsync(physicalFixedPricedContract, request.CompanyId);

                List <Cost> newCosts = new List <Cost>();
                foreach (var item in physicalFixedPricedContract.Costs)
                {
                    item.SectionId     = physicalFixedPricedContract.SectionId;
                    item.CompanyId     = request.CompanyId;
                    item.DataVersionId = request.DataVersionId;
                    if (item.CostId != 0)
                    {
                        await _costRepository.UpdateCostAsync(item, request.CompanyId);
                    }
                    else
                    {
                        newCosts.Add(item);
                    }
                }

                if (newCosts.Count > 0)
                {
                    await _costRepository.AddCostsAsync(newCosts, request.CompanyId, request.DataVersionId);
                }

                if (request.IsInterco)
                {
                    sectionReferences = await CreateIntercoContractOnUpdateContract(request, section, sectionReferences);
                }

                if (request.DataVersionId != null)
                {
                    await InsertFreezeRecalcProcessQueue(request.SectionId, request.DataVersionId, request.CompanyId);
                }

                _unitOfWork.Commit();
                _logger.LogInformation("Section with id {Atlas_SectionId} updated.", physicalFixedPricedContract.SectionId);
                return(sectionReferences);
            }
            catch
            {
                _unitOfWork.Rollback();
                throw;
            }
        }