using Hcs.Client.Api.Payload.HouseManagement; using Hcs.Client.Api.Request.Exception; using Hcs.Client.Internal; using Hcs.Service.Async.HouseManagement; using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace Hcs.Client.Api.Request.HouseManagement { internal class ImportSupplyResourceContractDataRequest(ClientBase client) : HouseManagementRequestBase(client) { protected override bool CanBeRestarted => false; internal async Task ExecuteAsync(ImportSupplyResourceContractDataPayload payload, CancellationToken token) { ThrowIfPayloadIncorrect(payload); // http://open-gkh.ru/HouseManagement/SupplyResourceContractType.html var contract = new importSupplyResourceContractRequestContract { TransportGUID = Guid.NewGuid().ToString(), Item1 = GetContractFromPayload(payload) }; // http://open-gkh.ru/HouseManagement/importSupplyResourceContractRequest.html var request = new importSupplyResourceContractRequest { Id = Constants.SIGNED_XML_ELEMENT_ID, version = "11.3.0.5", Contract = [contract] }; var result = await SendAndWaitResultAsync(request, async asyncClient => { var response = await asyncClient.importSupplyResourceContractDataAsync(CreateRequestHeader(), request); return response.AckRequest.Ack; }, token); result.Items.OfType().ToList().ForEach(error => { throw RemoteException.CreateNew(error.ErrorCode, error.Description); }); var importResults = result.Items.OfType(); var commonResults = GetCommonResults(importResults); foreach (var commonResult in commonResults) { if (commonResult.ItemElementName == ItemChoiceType26.ImportSupplyResourceContract) { if (commonResult.Item is getStateResultImportResultCommonResultImportSupplyResourceContract importedContract) { return importedContract; } } } return null; } private void ThrowIfPayloadIncorrect(ImportSupplyResourceContractDataPayload payload) { if (string.IsNullOrEmpty(payload.contractNumber)) { throw new ArgumentException($"{nameof(payload.contractNumber)} is empty"); } if (payload.signingDate.Equals(default) || payload.effectiveDate.Equals(default)) { throw new ArgumentException($"{nameof(payload.signingDate)} OR/AND {nameof(payload.effectiveDate)} are default"); } if (!payload.comptetionDate.HasValue && payload.automaticRollOverOneYear) { throw new ArgumentException($"{nameof(payload.comptetionDate)} is null but {nameof(payload.automaticRollOverOneYear)} has value"); } if (payload.period == null && (payload.volumeDepends.HasValue && payload.volumeDepends.Value || payload.meteringDeviceInformation.HasValue && payload.meteringDeviceInformation.Value)) { throw new ArgumentException($"{nameof(payload.period)} is null but {nameof(payload.volumeDepends)} OR/AND {nameof(payload.meteringDeviceInformation)} have value"); } if (payload.indicationsAnyDay && payload.period == null) { throw new ArgumentException($"{nameof(payload.indicationsAnyDay)} has value but {nameof(payload.period)} is null"); } // TODO: Add counterparty check if (payload.plannedVolumeType.HasValue && !payload.isPlannedVolume) { throw new ArgumentException($"{nameof(payload.plannedVolumeType)} has value but {nameof(payload.isPlannedVolume)} is false"); } if (payload.contractSubject == null || payload.contractSubject.Length == 0) { throw new ArgumentException($"{nameof(payload.contractSubject)} is empty"); } if (payload.contractSubject != null && payload.contractSubject.Length > 100) { throw new ArgumentException($"{nameof(payload.contractSubject)} exceeds its limit ({payload.contractSubject.Length} of 100)"); } if (payload.countingResource.HasValue && (!payload.accrualProcedure.HasValue || payload.accrualProcedure.Value == SupplyResourceContractTypeAccrualProcedure.O)) { throw new ArgumentException($"{nameof(payload.countingResource)} has value but {nameof(payload.accrualProcedure)} is null OR has inappropriate value"); } // TODO: Add noConnectionToWaterSupply check if (payload.objectAddress == null || payload.objectAddress.Length == 0) { throw new ArgumentException($"{nameof(payload.objectAddress)} is empty"); } // TODO: Add quality check // TODO: Add otherQualityIndicator check // TODO: Add temperatureChart check if (payload.billingDate == null && (payload.counterparty is not SupplyResourceContractTypeOrganization || payload.meteringDeviceInformation.HasValue)) { throw new ArgumentException($"{nameof(payload.billingDate)} is null but {nameof(payload.meteringDeviceInformation)} has value"); } if (payload.billingDate != null && payload.oneTimePayment.HasValue && payload.oneTimePayment.Value) { throw new ArgumentException($"{nameof(payload.billingDate)} has value but {nameof(payload.oneTimePayment)} is true"); } if (payload.paymentDate == null && payload.counterparty is not SupplyResourceContractTypeOrganization && payload.isContract && payload.oneTimePayment.HasValue && !payload.oneTimePayment.Value) { throw new ArgumentException($"{nameof(payload.paymentDate)} is null but should have value"); } if (payload.paymentDate != null && payload.oneTimePayment.HasValue && payload.oneTimePayment.Value) { throw new ArgumentException($"{nameof(payload.paymentDate)} has value but {nameof(payload.oneTimePayment)} is true"); } if (payload.providingInformationDate == null && payload.counterparty is SupplyResourceContractTypeOrganization && payload.countingResource.HasValue && payload.countingResource.Value == SupplyResourceContractTypeCountingResource.R && payload.isContract) { throw new ArgumentException($"{nameof(payload.providingInformationDate)} is null but should have value"); } if (!payload.meteringDeviceInformation.HasValue && payload.countingResource.HasValue && payload.countingResource == SupplyResourceContractTypeCountingResource.R) { throw new ArgumentException($"{nameof(payload.meteringDeviceInformation)} is null but should have value"); } if (payload.volumeDepends.HasValue && (payload.counterparty is SupplyResourceContractTypeOrganization || payload.oneTimePayment.HasValue && payload.oneTimePayment.Value)) { throw new ArgumentException($"{nameof(payload.volumeDepends)} has value but should have not one"); } if (payload.oneTimePayment.HasValue && payload.counterparty is SupplyResourceContractTypeOrganization) { throw new ArgumentException($"{nameof(payload.oneTimePayment)} has value but {nameof(payload.counterparty)} has inappropriate value"); } // TODO: Add accrualProcedure check } private SupplyResourceContractType GetContractFromPayload(ImportSupplyResourceContractDataPayload payload) { // http://open-gkh.ru/HouseManagement/SupplyResourceContractType.html var contract = new SupplyResourceContractType(); if (payload.isContract) { var isContract = new SupplyResourceContractTypeIsContract() { ContractNumber = payload.contractNumber, SigningDate = payload.signingDate, EffectiveDate = payload.effectiveDate }; contract.Item = isContract; } else { var isNotContract = new SupplyResourceContractTypeIsNotContract() { ContractNumber = payload.contractNumber, SigningDate = payload.signingDate, SigningDateSpecified = true, EffectiveDate = payload.effectiveDate, EffectiveDateSpecified = true }; contract.Item = isNotContract; } var items = new List(); var itemsElementName = new List(); if (payload.indefiniteTerm) { items.Add(payload.indefiniteTerm); itemsElementName.Add(ItemsChoiceType9.IndefiniteTerm); } if (payload.automaticRollOverOneYear) { items.Add(payload.automaticRollOverOneYear); itemsElementName.Add(ItemsChoiceType9.AutomaticRollOverOneYear); items.Add(payload.comptetionDate.Value); itemsElementName.Add(ItemsChoiceType9.ComptetionDate); } if (items.Count > 0 && itemsElementName.Count > 0) { contract.Items = [.. items]; contract.ItemsElementName = [.. itemsElementName]; } if (payload.period != null) { contract.Period = payload.period; } if (payload.indicationsAnyDay) { contract.IndicationsAnyDay = true; contract.IndicationsAnyDaySpecified = true; } if (payload.contractBase != null && payload.contractBase.Length > 0) { contract.ContractBase = payload.contractBase; } contract.Item1 = payload.counterparty; contract.IsPlannedVolume = payload.isPlannedVolume; if (payload.plannedVolumeType.HasValue) { contract.PlannedVolumeType = payload.plannedVolumeType.Value; contract.PlannedVolumeTypeSpecified = true; } contract.ContractSubject = payload.contractSubject; if (payload.countingResource.HasValue) { contract.CountingResource = payload.countingResource.Value; contract.CountingResourceSpecified = true; } contract.SpecifyingQualityIndicators = payload.specifyingQualityIndicators; if (payload.noConnectionToWaterSupply) { contract.NoConnectionToWaterSupply = true; contract.NoConnectionToWaterSupplySpecified = true; } contract.ObjectAddress = payload.objectAddress; contract.Quality = payload.quality; contract.OtherQualityIndicator = payload.otherQualityIndicator; contract.TemperatureChart = payload.temperatureChart; contract.BillingDate = payload.billingDate; contract.PaymentDate = payload.paymentDate; contract.ProvidingInformationDate = payload.providingInformationDate; if (payload.meteringDeviceInformation.HasValue) { contract.MeteringDeviceInformation = payload.meteringDeviceInformation.Value; contract.MeteringDeviceInformationSpecified = true; } if (payload.volumeDepends.HasValue) { contract.VolumeDepends = payload.volumeDepends.Value; contract.VolumeDependsSpecified = true; } if (payload.oneTimePayment.HasValue) { contract.OneTimePayment = payload.oneTimePayment.Value; contract.OneTimePaymentSpecified = true; } if (payload.accrualProcedure.HasValue) { contract.AccrualProcedure = payload.accrualProcedure.Value; contract.AccrualProcedureSpecified = true; } contract.Tariff = payload.tariff; contract.Norm = payload.norm; return contract; } } }