public async Task <IEnumerable <SectionReference> > Handle(CreatePhysicalFixedPricedContractCommand request, CancellationToken cancellationToken) { List <SectionReference> sectionReferences = new List <SectionReference>(); _unitOfWork.BeginTransaction(); try { if (request.ContractReference?.Length > 0) { request.ContractReference = request.ContractReference.PadLeft(7, '0'); } 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 created in a freeze if the month is closed."); } if (request.ContractReference == null) { throw new AtlasBusinessException($"Contract reference is mandatory in a frozen database."); } } await PhysicalContractCommonRules.ValidatePhysicalContract(request, _identityService, _masterDataService, _userService, _systemDateTimeService); var user = _identityService.GetUserName(); request.CreatedBy = user; 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; } // At least one contract has to be always created physicalFixedPricedContract.NumberOfContract = (request.NumberOfContracts > 0) ? request.NumberOfContracts : 1; physicalFixedPricedContract.IsInterco = request.IsInterco; if (!string.IsNullOrWhiteSpace(physicalFixedPricedContract.OtherReference)) { physicalFixedPricedContract.EstimatedMaturityDate = null; } physicalFixedPricedContract.EstimatedMaturityDate = await CalculateEstimatedMaturityDate(physicalFixedPricedContract, request.CompanyId); var references = (await _tradeRepository.CreatePhysicalContractAsImageAsync(physicalFixedPricedContract)).ToList(); sectionReferences.AddRange(references); foreach (var item in references) { if (item.SectionId > 0 && item.Quantity > 0 && physicalFixedPricedContract.Costs.Any()) { foreach (var costItem in physicalFixedPricedContract.Costs) { costItem.CompanyId = request.CompanyId; costItem.SectionId = item.SectionId; costItem.DataVersionId = item.DataVersionId; } // check the business rule for PriceUnitId. await _costRepository.AddCostsAsync(physicalFixedPricedContract.Costs, request.CompanyId, request.DataVersionId); } // request.ChildSections would not be null if only it is Imaging the trade and we have selected Image Splits/tranche option as well if (request.ChildSections != null) { if (item.SectionId > 0 && request.ChildSections.Any()) { CreateSplitCommand splitRequest = new CreateSplitCommand(); splitRequest.ChildSections = request.ChildSections; splitRequest.ChildSections.ToList().ForEach(section => section.OriginalQuantity = 0); splitRequest.CompanyId = request.CompanyId; splitRequest.OriginalQuantity = request.Quantity; splitRequest.Quantity = request.Quantity; var sectionTrancheContract = _mapper.Map <SectionDeprecated>(splitRequest); sectionTrancheContract.SectionId = item.SectionId; sectionTrancheContract.ContractLabel = item.ContractLabel; foreach (var splitTrancheItem in sectionTrancheContract.ChildSections) { splitTrancheItem.SectionId = 0; splitTrancheItem.ContractId = item.PhysicalContractId; splitTrancheItem.SectionOriginId = (int)item.SectionId; splitTrancheItem.EstimatedMaturityDate = physicalFixedPricedContract.EstimatedMaturityDate; } bool isTradeImage = true; var splitTranchReferences = await _tradeRepository.CreateTrancheSplitAsync(sectionTrancheContract, request.CompanyId, isTradeImage); // Inserting cost while creating an Image of a trade,if available foreach (var childItem in splitTranchReferences) { if (request.ChildSections.First().Costs != null) { var childCosts = request.ChildSections.First().Costs; foreach (var costItem in childCosts) { costItem.CompanyId = request.CompanyId; costItem.SectionId = childItem.SectionId; costItem.DataVersionId = childItem.DataVersionId; } await _costRepository.AddCostsAsync(childCosts, request.CompanyId, request.DataVersionId); } } } } if (request.IsInterco) { sectionReferences = await CreateIntercoContractOnCreateContract(request, physicalFixedPricedContract, references, sectionReferences); } if (request.DataVersionId != null) { // this might be incorrect. This is due to the code that is written above where you can create multiple contracts in your Current db with Image await InsertFreezeRecalcProcessQueue(references[0].SectionId, request.DataVersionId, request.CompanyId); } } _unitOfWork.Commit(); _logger.LogInformation("New physical contract with id {Atlas_ContractLabel} created.", references[0].ContractLabel); return(sectionReferences); } catch { _unitOfWork.Rollback(); throw; } }
internal static async Task ValidatePhysicalContract(CreatePhysicalFixedPricedContractCommand command, IIdentityService identityService, IMasterDataService masterDataService, IUserService userService, ISystemDateTimeService systemDateTimeService) { // department var departments = await masterDataService.GetDepartmentsAsync(command.CompanyId); if (!departments.Any(d => d.DepartmentId == command.DepartmentId)) { throw new AtlasBusinessException($"The department {command.DepartmentId} does not belong to the {command.CompanyId} company."); } // trader if (command.TraderId != null) { var trader = await userService.GetUserByIdAsync(command.TraderId.Value); if (trader == null && !command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "TraderId").IsMandatory) { throw new NotFoundException("User", command.TraderId); } } // counterparties - buyer and seller var counterparties = await masterDataService.GetCounterpartiesAsync(command.CompanyId); if (!counterparties.Any(c => c.CounterpartyCode == command.BuyerCode) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "BuyerId").IsMandatory) { throw new AtlasBusinessException($"The buyer {command.BuyerCode} does not belong to the {command.CompanyId} company."); } if (!counterparties.Any(c => c.CounterpartyCode == command.SellerCode) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "SellerId").IsMandatory) { throw new AtlasBusinessException($"The seller {command.SellerCode} does not belong to the {command.CompanyId} company."); } // commodity var commodities = await masterDataService.GetCommoditiesAsync(command.CompanyId); if (!commodities.Any(c => c.CommodityId == command.CommodityId) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "CommodityId").IsMandatory) { throw new AtlasBusinessException($"The commodity {command.CommodityId} does not belong to the {command.CompanyId} company."); } // quantity code var weightUnits = await masterDataService.GetWeightUnitsAsync(command.CompanyId); if (!weightUnits.Any(w => w.WeightUnitId == command.WeightUnitId) && command.FieldsConfigurations.DefaultIfEmpty().FirstOrDefault(field => field?.DisplayName == "WeightUnitId").IsMandatory) { throw new AtlasBusinessException($"The quantity code {command.WeightUnitId} does not belong to the {command.CompanyId} company."); } // contract term var contractTerms = await masterDataService.GetContractTermsAsync(command.CompanyId); if (!contractTerms.Any(c => c.ContractTermCode == command.ContractTerms) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "ContractTermId").IsMandatory) { throw new AtlasBusinessException($"The contract term {command.ContractTerms} does not belong to the {command.CompanyId} company."); } // port term var ports = await masterDataService.GetPortsAsync(command.CompanyId); if (!ports.Any(p => p.PortCode == command.ContractTermsLocation) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "ContractTermLocationId").IsMandatory) { throw new AtlasBusinessException($"The port term {command.ContractTermsLocation} does not belong to the {command.CompanyId} company."); } // port of origin if (command.PortOfOrigin != null) { if (!ports.Any(p => p.PortCode == command.PortOfOrigin)) { throw new AtlasBusinessException($"The port of origin {command.PortOfOrigin} does not belong to the {command.CompanyId} company."); } } // port of destination if (command.PortOfDestination != null) { if (!ports.Any(p => p.PortCode == command.PortOfDestination)) { throw new AtlasBusinessException($"The port of destination {command.PortOfDestination} does not belong to the {command.CompanyId} company."); } } // arbitration if (command.Arbitration != null) { var arbitrations = await masterDataService.GetArbitrationsAsync(command.CompanyId); if (!arbitrations.Any(a => a.ArbitrationCode == command.Arbitration)) { throw new AtlasBusinessException($"The arbitration {command.Arbitration} does not belong to the {command.CompanyId} company."); } } // currency var currencies = await masterDataService.GetCurrenciesAsync(); if (!currencies.Any(c => c.CurrencyCode == command.CurrencyCode) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "CurrencyCode").IsMandatory) { throw new AtlasBusinessException($"The currency {command.CurrencyCode} does not belong to the {command.CompanyId} company."); } // price code var priceUnits = await masterDataService.GetPriceUnitsAsync(command.CompanyId); if (!priceUnits.Any(p => p.PriceUnitId == command.PriceUnitId) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "PricingMethodId").IsMandatory) { throw new AtlasBusinessException($"The price code {command.PriceUnitId} does not belong to the {command.CompanyId} company."); } // payment term var paymentTerms = await masterDataService.GetPaymentTermsAsync(command.CompanyId); if (!paymentTerms.Any(p => p.PaymentTermsCode == command.PaymentTerms) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "PaymentTermId").IsMandatory) { throw new AtlasBusinessException($"The payment term {command.PaymentTerms} does not belong to the {command.CompanyId} company."); } // period type var periodTypes = await masterDataService.GetPeriodTypesAsync(command.CompanyId); if (!periodTypes.Any(p => p.PeriodTypeId == command.PeriodTypeId) && command.FieldsConfigurations.FirstOrDefault(field => field?.DisplayName == "PeriodTypeId").IsMandatory) { throw new AtlasBusinessException($"The period type {command.PeriodTypeId} does not belong to the {command.CompanyId} company."); } }
private async Task <List <SectionReference> > CreateIntercoContractOnCreateContract(CreatePhysicalFixedPricedContractCommand request, Section physicalFixedPricedContract, List <SectionReference> references, List <SectionReference> sectionReferences) { // Create Interco Trade if available if (request.IsInterco) { string counterpartyCode = (physicalFixedPricedContract.Type == ContractType.Purchase) ? physicalFixedPricedContract.SellerCode : physicalFixedPricedContract.BuyerCode; var counterparty = await _masterDataService.GetAllByCounterpartyIdAsync(request.CompanyId, counterpartyCode); if (counterparty != null && counterparty.FirstOrDefault() != null && counterparty.FirstOrDefault().CompanyId != request.CompanyId && counterparty.FirstOrDefault().IsCounterpartyGroupAccount) { var dataVersionId = await _systemDateTimeService.GetCompanyCurrentDataVersionId(request.IntercoCompanyId); var intercoPhysicalFixedPricedContract = _mapper.Map <Section>(request); intercoPhysicalFixedPricedContract.CompanyId = physicalFixedPricedContract.IntercoCompanyId; intercoPhysicalFixedPricedContract.TraderId = physicalFixedPricedContract.IntercoTraderId; intercoPhysicalFixedPricedContract.DepartmentId = physicalFixedPricedContract.IntercoDepartmentId; intercoPhysicalFixedPricedContract.Type = (physicalFixedPricedContract.Type == ContractType.Purchase) ? ContractType.Sale : ContractType.Purchase; intercoPhysicalFixedPricedContract.DataVersionId = dataVersionId; intercoPhysicalFixedPricedContract.ContractDate = DateTime.UtcNow; intercoPhysicalFixedPricedContract.Costs = physicalFixedPricedContract.Costs.Where(r => r.SupplierCode == counterpartyCode); // At least one contract has to be always created intercoPhysicalFixedPricedContract.NumberOfContract = 1; 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.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); } } // Update Reference & Memo Details var sourceDataVersionId = await _systemDateTimeService.GetCompanyCurrentDataVersionId(physicalFixedPricedContract.CompanyId); await UpdateReferenceAndInternalMemo(sourceDataVersionId, references.FirstOrDefault().PhysicalContractId, request.IntercoCompanyId.ToUpper() + "/" + intercoReferences.FirstOrDefault().ContractLabel, dataVersionId, intercoReferences.FirstOrDefault().PhysicalContractId, request.CompanyId.ToUpper() + "/" + references.FirstOrDefault().ContractLabel, request.Type); sectionReferences.AddRange(intercoReferences); } else { throw new AtlasBusinessException($"Invalid Counterparty for Interco Contract."); } } return(sectionReferences); }