From 3aea7dee2ce4c2dd45cf90528e6981626d9fa580 Mon Sep 17 00:00:00 2001 From: dibakor Date: Sun, 26 Jul 2026 18:04:49 +0600 Subject: [PATCH] change discount material, password policy, material price endpoint response --- .../Enums.cs | 4 +- .../Requests/MobileApp/OrderRequest.cs | 1 + .../MobileApp/MobileMasterDataResponse.cs | 8 +-- .../Integrations/IntegrationService.cs | 10 ++-- .../MobileApp/MobileMasterDataService.cs | 10 ++-- .../Services/MobileApp/OrderService.cs | 8 ++- .../Mobile/MobileAuthController.cs | 51 ++++++++++++++++++- 7 files changed, 75 insertions(+), 17 deletions(-) diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Enums.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Enums.cs index c406aec..900b2cb 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Enums.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Enums.cs @@ -733,8 +733,10 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models OrderValidator = 2, [Description("OrderApprover")] OrderApprover = 3 , + [Description("ApproverWithoutValidate")] + OrderApproverWithoutValidated = 4, [Description("SAP User")] - SapUser = 4 , + SapUser = 5 , } public enum OrderStatusEnum : short diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/MobileApp/OrderRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/MobileApp/OrderRequest.cs index 1126abd..f2b2e99 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/MobileApp/OrderRequest.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/MobileApp/OrderRequest.cs @@ -19,6 +19,7 @@ public class SaveOrderRequest public int? CustomerId { get; set; } public string CustomerCode { get; set; } public string CustomerName { get; set; } + public string PlantCode { get; set; } public int? EmployeeId { get; set; } public string EmployeeCode { get; set; } public string? ReferenceTxtNo { get; set; } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/MobileApp/MobileMasterDataResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/MobileApp/MobileMasterDataResponse.cs index 86a386e..ca46f33 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/MobileApp/MobileMasterDataResponse.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/MobileApp/MobileMasterDataResponse.cs @@ -113,6 +113,7 @@ public class GetMaterialPriceResponse public string CustomerCode { get; set; } public string MaterialCode { get; set; } public decimal BasePrice { get; set; } + public decimal? VatPercentage { get; set; } } public class GetCustomerResponse @@ -180,6 +181,7 @@ public class GetDiscountMaterialResponse public string MaterialCode { get; set; } public string UnitOfMeasurement { get; set; } public string CalculationType { get; set; } + public decimal ScaleValue { get; set; } public decimal DiscountValue { get; set; } public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } @@ -230,11 +232,11 @@ public class GetMaterialStockReponse public class GetPasswordPolicyResponse { - public int MinLength { get; set; } - public int MaxLength { get; set; } + public int? MinLength { get; set; } + public int? MaxLength { get; set; } public bool IsUppercase { get; set; } public bool IsLowercase { get; set; } public bool IsNumber { get; set; } public bool IsSpecialCharacter { get; set; } - public int PasswordLife { get; set; } + public int? PasswordLife { get; set; } } \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs index 1b7ff1f..84e125b 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationService.cs @@ -1628,11 +1628,11 @@ public class IntegrationService : IIntegrationService SqlParameter[] p = [ - SqlHelperExtension.CreateInParam("@BillingNumber", SqlDbType.NVarChar, request.BillingDocumentNumber), - SqlHelperExtension.CreateInParam("@SalesOrderNo", SqlDbType.NVarChar, request.SalesOrderReferenceNumber), - SqlHelperExtension.CreateInParam("@BillingDate", SqlDbType.DateTime, request.BillingDate), - SqlHelperExtension.CreateInParam("@DeliveryNumber", SqlDbType.NVarChar, request.DeliveryReferenceNumber), - SqlHelperExtension.CreateInParam("@BillingItems", SqlDbType.Structured, itemTable) + SqlHelperExtension.CreateInParam("@BillingNumber", SqlDbType.NVarChar, request.BillingDocumentNumber), + SqlHelperExtension.CreateInParam("@SalesOrderNo", SqlDbType.NVarChar, request.SalesOrderReferenceNumber), + SqlHelperExtension.CreateInParam("@BillingDate", SqlDbType.DateTime, request.BillingDate), + SqlHelperExtension.CreateInParam("@DeliveryNumber", SqlDbType.NVarChar, request.DeliveryReferenceNumber), + SqlHelperExtension.CreateInParam("@BillingItems", SqlDbType.Structured, itemTable) ]; _ = tc.ExecuteNonQuerySp(spName: "dbo.InsertBillingDocument", parameterValues: p); diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/MobileMasterDataService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/MobileMasterDataService.cs index 0b33d6b..a8d3ad9 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/MobileMasterDataService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/MobileMasterDataService.cs @@ -238,7 +238,8 @@ public class MobileMasterDataService : IMobileMasterDataService SalesOrgCode = dr.GetString(0), CustomerCode = dr.GetString(1), MaterialCode = dr.GetString(2), - BasePrice = dr.GetDecimal(3) + BasePrice = dr.GetDecimal(3), + VatPercentage =dr.IsDBNull(4) ? null: dr.GetDecimal(4), }); } dr.Close(); @@ -787,6 +788,7 @@ public class MobileMasterDataService : IMobileMasterDataService DiscountValue = dr.GetDecimal(5), StartDate = dr.GetDateTime(6), EndDate = dr.GetDateTime(7), + ScaleValue = dr.GetDecimal(8), }); } dr.Close(); @@ -997,13 +999,13 @@ public class MobileMasterDataService : IMobileMasterDataService { response=new GetPasswordPolicyResponse() { - MinLength = dr.GetInt32(0), - MaxLength = dr.GetInt32(1), + MinLength =dr.IsDBNull(0) ? null: dr.GetInt32(0), + MaxLength = dr.IsDBNull(1) ? null : dr.GetInt32(1), IsUppercase = dr.GetInt32(2) >0, IsLowercase = dr.GetInt32(3) > 0, IsSpecialCharacter = dr.GetInt32(4) > 0, IsNumber = dr.GetInt32(5) > 0, - PasswordLife = dr.GetInt32(6), + PasswordLife = dr.IsDBNull(6) ? null : dr.GetInt32(6), }; } dr.Close(); diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/OrderService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/OrderService.cs index fb8105a..df9659a 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/OrderService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/OrderService.cs @@ -54,7 +54,6 @@ public class OrderService : IOrderService request.OrderId = (existingOrder != null && existingOrder.OrderId > 0) ? existingOrder.OrderId : 0; - if (existingOrder is not null && existingOrder.OrderId > 0 && (existingOrder.OrderStatus == OrderStatusEnum.Approved || existingOrder.OrderStatus == OrderStatusEnum.CancelledByApprover || @@ -199,7 +198,12 @@ public class OrderService : IOrderService return true; } - if (UserRoleTypeEnum.OrderApprover == roleId && (OrderStatusEnum.InOrderApproval == orderStatus || OrderStatusEnum.CancelledByApprover == orderStatus || OrderStatusEnum.Approved == orderStatus)) + if (UserRoleTypeEnum.OrderApprover == roleId && (OrderStatusEnum.CancelledByApprover == orderStatus || OrderStatusEnum.Approved == orderStatus)) + { + return true; + } + + if (UserRoleTypeEnum.OrderApproverWithoutValidated == roleId && (OrderStatusEnum.CancelledByApprover == orderStatus || OrderStatusEnum.Approved == orderStatus)) { return true; } diff --git a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/Mobile/MobileAuthController.cs b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/Mobile/MobileAuthController.cs index 206ac8e..b7537ad 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/Mobile/MobileAuthController.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/Mobile/MobileAuthController.cs @@ -15,9 +15,11 @@ using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth; +using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems; using System; using System.IdentityModel.Tokens.Jwt; +using System.Linq; using System.Security.Claims; using System.Text; using System.Threading.Tasks; @@ -35,13 +37,14 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers /// /// /// + /// [Authorize] [ApiController] [ApiVersion("1.0")] [ValidateAntiForgeryToken] [Route("api/mobile/v{version:apiVersion}/auth")] public class MobileAuthController(IUserService service, IOptions appSettings, IEaseCache cache, ILogger logger, - IRefreshTokenService refreshTokenService) : ControllerBase + IRefreshTokenService refreshTokenService, IMobileMasterDataService masterService) : ControllerBase { private readonly ILogger _logger = logger; private readonly IEaseCache _cache = cache; @@ -49,6 +52,8 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers private readonly IRefreshTokenService _refreshTokenService = refreshTokenService; private readonly AppSettings _appSettings = appSettings?.Value; private readonly DateTimeOffset _options = Helper.CreateEaseCacheOptions(); + private readonly IMobileMasterDataService _masterService = masterService; + /// @@ -284,12 +289,23 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers AppChangePasswordResponse response = new(); try { - if(request.Password.Equals(request.ConfirmPassword)) + + if (request.Password.Equals(request.ConfirmPassword)) { string msg = $"You can't use your old password as your new password."; _logger.LogError(message: msg); return BadRequest(MobileResponseBase.Failure(msg, StatusCodes.Status400BadRequest)); } + GetPasswordPolicyResponse passwordPolicy = await _masterService.GetPasswordPolicyAsync(); + + string passValidationResponse = ValidatePassword(request.ConfirmPassword, passwordPolicy); + + if(!string.IsNullOrEmpty(passValidationResponse)) + { + string msg = passValidationResponse; + _logger.LogError(message: msg); + return BadRequest(MobileResponseBase.Failure(msg, StatusCodes.Status400BadRequest)); + } string ipAddress = Request.HttpContext.GetIpAddress(); response = await _service.ChangePasswordAsync(request, ipAddress); @@ -303,5 +319,36 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError)); } } + + private string ValidatePassword(string password, GetPasswordPolicyResponse policy) + { + if (policy == null) + throw new ArgumentNullException(nameof(policy)); + + if (string.IsNullOrEmpty(password)) + { + return "Password cannot be empty."; + } + + if (policy.MinLength.HasValue && password.Length < policy.MinLength.Value) + return $"Password must be at least {policy.MinLength.Value} characters long."; + + if (policy.MaxLength.HasValue && password.Length > policy.MaxLength.Value) + return $"Password must not exceed {policy.MaxLength.Value} characters."; + + if (policy.IsUppercase && !password.Any(char.IsUpper)) + return "Password must contain at least one uppercase letter."; + + if (policy.IsLowercase && !password.Any(char.IsLower)) + return "Password must contain at least one lowercase letter."; + + if (policy.IsNumber && !password.Any(char.IsDigit)) + return "Password must contain at least one digit."; + + if (policy.IsSpecialCharacter && !password.Any(c => !char.IsLetterOrDigit(c))) + return "Password must contain at least one special character."; + + return string.Empty; + } } } \ No newline at end of file