From 769e973f48a0d996033168e1fff1149b5f0b7f59 Mon Sep 17 00:00:00 2001 From: dibakor Date: Wed, 29 Jul 2026 13:09:07 +0600 Subject: [PATCH] chaange format of Material Price Endpoints --- .../Enums.cs | 2 +- .../IntegrationMaterialFreeGoodsRequest.cs | 4 + .../IntegrationMaterialPriceRequest.cs | 21 +- .../Integrations/IntegrationService.cs | 179 ++++++++++++++---- 4 files changed, 154 insertions(+), 52 deletions(-) diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Enums.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Enums.cs index f6aa9aa..3ff2522 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Enums.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Enums.cs @@ -724,7 +724,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models BasePrice = 1, Discount = 2, VatPrice = 3, - SourceTaxPrice = 4, + SlabBasedDiscount = 4, } public enum UserPlatFormType : short diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationMaterialFreeGoodsRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationMaterialFreeGoodsRequest.cs index 1b3c19e..ea41442 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationMaterialFreeGoodsRequest.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationMaterialFreeGoodsRequest.cs @@ -10,6 +10,10 @@ public class IntegrationMaterialFreeGoodsRequest { Slabs = new List(); } + + [Required(ErrorMessage = "Condition Record No is Required")] + public int ConditionRecNo { get; set; } + [StringLength(10, MinimumLength = 1, ErrorMessage = "SalesOrg must be between 1 and 10 characters.")] public string SalesOrg { get; set; } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationMaterialPriceRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationMaterialPriceRequest.cs index ef89495..5faefed 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationMaterialPriceRequest.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/Integrations/IntegrationMaterialPriceRequest.cs @@ -12,6 +12,9 @@ public class IntegrationMaterialPriceRequest Slabs = new List(); } + [Required(ErrorMessage = "Condition Record No is required.")] + public int ConditionRecNo { get; set; } + [StringLength(4, ErrorMessage = "Sales Org cannot exceed 4 characters.")] public string? SalesOrg { get; set; } @@ -24,9 +27,8 @@ public class IntegrationMaterialPriceRequest [StringLength(10, ErrorMessage = "Customer Group Code cannot exceed 10 characters.")] public string? CustomerGroupCode { get; set; } - [Required(ErrorMessage = "Material Code is required.")] [StringLength(10, ErrorMessage = "Material Code cannot exceed 10 characters.")] - public string MaterialCode { get; set; } + public string? MaterialCode { get; set; } [Required(ErrorMessage = "Condition Type is required.")] [StringLength(4, ErrorMessage = "Condition Type cannot exceed 4 characters.")] @@ -36,26 +38,23 @@ public class IntegrationMaterialPriceRequest [StringLength(1, ErrorMessage = "Calculation Type cannot exceed 1 character.")] public string CalculationType { get; set; } - [Required(ErrorMessage = "Pricing Unit is required.")] [StringLength(1, ErrorMessage = "Pricing Unit cannot exceed 1 character.")] - public string PricingUnit { get; set; } + public string? PricingUnit { get; set; } - [Required(ErrorMessage = "Unit Of Measure is required.")] [StringLength(3, ErrorMessage = "Unit Of Measure cannot exceed 3 characters.")] - public string UnitOfMeasure { get; set; } + public string? UnitOfMeasure { get; set; } public IList Slabs { get; set; } } public class IntegrationMaterialPriceItemRequest { - [Required(ErrorMessage = "Scale Value is required.")] - [Range(typeof(decimal), "0", "999999999999999999.99", ErrorMessage = "Scale Value must be greater than or equal to 0.")] - public decimal ScaleValue { get; set; } + [Range(typeof(decimal), "0", "999999999999999999.99", ErrorMessage = "Scale Value must be greater than or equal to 0.")] + public decimal? ScaleValue { get; set; } - [Required(ErrorMessage = "Valid From date is required.")] + [Required(ErrorMessage ="Valid From is Required")] public DateTime ValidFrom { get; set; } - [Required(ErrorMessage = "Valid To date is required.")] + [Required(ErrorMessage = "Valid To is Required")] public DateTime ValidTo { get; set; } [StringLength(1, ErrorMessage = "Status cannot exceed 1 character.")] diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs index e5cccb5..bbe6943 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs @@ -11,6 +11,7 @@ using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems; using System; +using System.Collections.Generic; using System.Data; using System.Linq; using System.Threading.Tasks; @@ -291,48 +292,22 @@ public class IntegrationService : IIntegrationService { var materialPriceType = await GetMaterialPriceTypeAsync(tc, request.ConditionType) ; - if(materialPriceType.PriceType == MaterialPriceTypeEnum.BasePrice) + + var validationMessages = Validate(request, materialPriceType.PriceType); + + if(validationMessages.Any()) { - if (string.IsNullOrWhiteSpace(request.SalesOrg) || string.IsNullOrWhiteSpace(request.DistributionChannel)) - throw new Exception("For Discount, Customer Group is required."); + throw new Exception(string.Join(", ", validationMessages)); } - if(materialPriceType.PriceType == MaterialPriceTypeEnum.Discount) + IntegrationMaterialPriceResponse meterialPrice = null; + + meterialPrice = await GetMaterialPriceByRecordNoAsync(tc, request.ConditionRecNo, materialPriceType.PriceType); + + if (meterialPrice != null && !string.IsNullOrWhiteSpace(meterialPrice.ConditionType)) { - if(string.IsNullOrWhiteSpace(request.CustomerGroupCode)) - throw new Exception("For Base Price, Sales Organization, and Distribution Channel are required."); - } - - DateTime? fromValid = null; - DateTime? toValid = null; - - if(request.Slabs != null && request.Slabs.Count>0) - { - fromValid = request.Slabs.Max(x => x.ValidFrom); - toValid = request.Slabs.Max(x => x.ValidTo); - } - - IntegrationMaterialPriceResponse meterialPrice = await GetMaterialPriceByCodeAndConditionTypeAsync(tc, - new GetMaterialPriceByCodeRequest() { MaterialCode = request.MaterialCode, ConditionType = request.ConditionType, - SalesOrg=request.SalesOrg, CustomerNumber = request.CustomerNumber,CustomerGroupCode = request.CustomerGroupCode, - DistributorChannelCode = request.DistributionChannel,ValidFrom = fromValid, ValidTo = toValid}); - - InactiveMaterialPriceByCodeAndConditionType(tc, - new GetMaterialPriceByCodeRequest() - { - MaterialCode = request.MaterialCode, - ConditionType = request.ConditionType, - SalesOrg = request.SalesOrg, - CustomerNumber = request.CustomerNumber, - CustomerGroupCode = request.CustomerGroupCode, - DistributorChannelCode = request.DistributionChannel, - ValidFrom = fromValid, - ValidTo = toValid - }, materialPriceType.PriceType); - - if (meterialPrice != null && !string.IsNullOrWhiteSpace(meterialPrice.MaterialCode)) - { - UpdateMaterialPrice(tc, request); + DeleteMaterialPriceByRecordNo(tc, request.ConditionRecNo); + CreateMaterialPrice(tc, request); response.IsUpdated = true; } else @@ -1225,6 +1200,52 @@ public class IntegrationService : IIntegrationService return response; } + private async Task GetMaterialPriceByRecordNoAsync( + TransactionContext tc, int? conditionRecordNo, MaterialPriceTypeEnum priceType ) + { + IntegrationMaterialPriceResponse response = new IntegrationMaterialPriceResponse(); + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam("@ConditionRecNo", SqlDbType.Int, conditionRecordNo), + SqlHelperExtension.CreateInParam("@PriceType", SqlDbType.Int,(int) priceType), + ]; + + using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetMaterialPriceByConditionRecordNo", parameterValues: p)) + { + if (dr.Read()) + { + response = new IntegrationMaterialPriceResponse() + { + MaterialPriceId = dr.GetInt32(0), + SalesOrg = dr.IsDBNull(1) ? null : dr.GetString(1), + DistributionChannel = dr.IsDBNull(2) ? null : dr.GetString(2), + CustomerNumber = dr.IsDBNull(3) ? null : dr.GetString(3), + CustomerGroupCode = dr.IsDBNull(4) ? null : dr.GetString(4), + MaterialCode = dr.IsDBNull(5) ? null : dr.GetString(5), + ConditionType = dr.GetString(6), + CalculationType = dr.GetString(7), + PricingUnit = dr.IsDBNull(8) ? null : dr.GetString(8), + UnitOfMeasure = dr.IsDBNull(9) ? null : dr.GetString(9), + ValidFrom = dr.GetDateTime(10), + ValidTo = dr.GetDateTime(11), + Status = dr.IsDBNull(12) ? null : dr.GetString(12), + ConditionValue = dr.GetDecimal(13) + }; + } + dr.Close(); + } + } + catch (Exception ex) + { + throw DBCustomError.GenerateCustomError(ex); + } + + return response; + } + private bool DeleteMaterialPriceByCodeAndConditionType(TransactionContext tc, GetMaterialPriceByCodeRequest request) { bool response = false; @@ -1251,6 +1272,27 @@ public class IntegrationService : IIntegrationService return response; } + private bool DeleteMaterialPriceByRecordNo(TransactionContext tc, int recordNo) + { + bool response = false; + + try + { + SqlParameter[] p = + [ + SqlHelperExtension.CreateInParam("@ConditionRecNo", SqlDbType.Int, recordNo), + ]; + + _ = tc.ExecuteNonQuerySp("dbo.DeleteMaterialPriceByRecordNo", parameterValues: p); + } + catch (Exception ex) + { + throw DBCustomError.GenerateCustomError(ex); + } + + return response; + } + private bool InactiveMaterialPriceByCodeAndConditionType(TransactionContext tc, GetMaterialPriceByCodeRequest request, MaterialPriceTypeEnum priceType) { bool response = false; @@ -1301,7 +1343,8 @@ public class IntegrationService : IIntegrationService SqlHelperExtension.CreateInParam("@ValidFrom", SqlDbType.DateTime, item.ValidFrom), SqlHelperExtension.CreateInParam("@ValidTo", SqlDbType.DateTime, item.ValidTo), SqlHelperExtension.CreateInParam("@Status", SqlDbType.NVarChar, item.Status), - SqlHelperExtension.CreateInParam("@ConditionValue", SqlDbType.Decimal, item.ConditionValue) + SqlHelperExtension.CreateInParam("@ConditionValue", SqlDbType.Decimal, item.ConditionValue) , + SqlHelperExtension.CreateInParam("@ConditionRecNo", SqlDbType.Int, request.ConditionRecNo) , ]; _ = tc.ExecuteNonQuerySp(spName: "dbo.InsertIntegrationMaterialPrice", parameterValues: p); @@ -1339,7 +1382,8 @@ public class IntegrationService : IIntegrationService SqlHelperExtension.CreateInParam("@ValidFrom", SqlDbType.DateTime, item.ValidFrom), SqlHelperExtension.CreateInParam("@ValidTo", SqlDbType.DateTime, item.ValidTo), SqlHelperExtension.CreateInParam("@Status", SqlDbType.NVarChar, item.Status), - SqlHelperExtension.CreateInParam("@ConditionValue", SqlDbType.Decimal, item.ConditionValue) + SqlHelperExtension.CreateInParam("@ConditionValue", SqlDbType.Decimal, item.ConditionValue), + SqlHelperExtension.CreateInParam("@ConditionRecordNo", SqlDbType.Int, request.ConditionRecNo) ]; _ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateIntegrationMaterialPrice", parameterValues: p); @@ -1817,4 +1861,59 @@ public class IntegrationService : IIntegrationService } #endregion + private IList Validate(IntegrationMaterialPriceRequest request, MaterialPriceTypeEnum priceTypeEnum) + { + var errors = new List(); + + if (request == null) + { + errors.Add("Request cannot be null."); + return errors; + } + + switch (priceTypeEnum) + { + case MaterialPriceTypeEnum.BasePrice: + Require(request.SalesOrg, nameof(request.SalesOrg), errors); + Require(request.DistributionChannel, nameof(request.DistributionChannel), errors); + Require(request.MaterialCode, nameof(request.MaterialCode), errors); + Require(request.CalculationType, nameof(request.CalculationType), errors); + Require(request.PricingUnit, nameof(request.PricingUnit), errors); + Require(request.UnitOfMeasure, nameof(request.UnitOfMeasure), errors); + break; + + case MaterialPriceTypeEnum.Discount: + Require(request.CustomerGroupCode, nameof(request.CustomerGroupCode), errors); + Require(request.MaterialCode, nameof(request.MaterialCode), errors); + break; + + case MaterialPriceTypeEnum.SlabBasedDiscount: + Require(request.CustomerGroupCode, nameof(request.CustomerGroupCode), errors); + break; + + case MaterialPriceTypeEnum.VatPrice: + Require(request.MaterialCode, nameof(request.MaterialCode), errors); + break; + + default: + errors.Add($"Unsupported Condition Type '{request.ConditionType}'."); + break; + } + + if (request.Slabs == null || !request.Slabs.Any()) + { + errors.Add("At least one slab is required."); + return errors; + } + + return errors; + } + + private static void Require(string? value, string fieldName, IList errors) + { + if (string.IsNullOrWhiteSpace(value)) + { + errors.Add($"{fieldName} is required."); + } + } }