diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/MobileApp/MobileMasterDataRequest.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/MobileApp/MobileMasterDataRequest.cs index 58c83a6..9d0620c 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/MobileApp/MobileMasterDataRequest.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Requests/MobileApp/MobileMasterDataRequest.cs @@ -40,6 +40,12 @@ public class GetMaterialsRequest : PagedRequest public string? EmployeeNumber { get; set; } } +public class GetMaterialStockRequest : PagedRequest +{ + [StringLength(10, MinimumLength = 1, ErrorMessage = "Plant Code must be between 1 and 10 characters.")] + public string PlantCode { get; set; } +} + public class GetMaterialPriceRequest : PagedRequest { [StringLength(10, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")] diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationHttpResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationHttpResponse.cs index eff3d37..6a3ff56 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationHttpResponse.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/Integrations/IntegrationHttpResponse.cs @@ -9,25 +9,6 @@ using System.Text.RegularExpressions; namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; -public class IntegrationCustLedgerHttpResponse -{ - public string Company { get; set; } - public string Customer_no { get; set; } - public decimal Current_Balance { get; set; } - public decimal Overdue_Amount { get; set; } -} - -public class IntegrationMaterialStockHttpResponse -{ - public string Plant { get; set; } - public string Material { get; set; } - public decimal Available_Stock { get; set; } - public string UOM { get; set; } -} - - - -// Reusable envelope for any SAP OData V2 collection response: { "d": { "results": [...] } } public sealed class SapODataResponse { [JsonPropertyName("d")] @@ -40,7 +21,7 @@ public sealed class SapODataResult public List Results { get; set; } = new(); } -public sealed class CustomerLedgerDto +public sealed class IntegrationCustLedgerHttpResponse { [JsonPropertyName("company")] public string Company { get; set; } = string.Empty; @@ -64,6 +45,24 @@ public sealed class CustomerLedgerDto public DateTime OverdueDate { get; set; } } +public sealed class IntegrationMaterialStockHttpResponse +{ + [JsonPropertyName("plant")] + public string PlantCode { get; set; } = string.Empty; + + [JsonPropertyName("material")] + public string MaterialCode { get; set; } = string.Empty; // stays string — SAP customer numbers can carry leading zeros + + [JsonPropertyName("available_stock")] + [JsonNumberHandling(JsonNumberHandling.AllowReadingFromString)] + public decimal AvailableStock { get; set; } + + [JsonPropertyName("uom")] + public string UOM { get; set; } = string.Empty; + +} + + public sealed class SapODataDateConverter : JsonConverter { // Matches "/Date(1783641600000)/" and the rarer offset form "/Date(1783641600000+0600)/" diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/MobileApp/MobileMasterDataResponse.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/MobileApp/MobileMasterDataResponse.cs index 5041c4b..1fc30af 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/MobileApp/MobileMasterDataResponse.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Models/Responses/MobileApp/MobileMasterDataResponse.cs @@ -105,7 +105,6 @@ public class GetMaterialResponse public string BrandCode { get; set; } public string BrandName { get; set; } public string SalesOrg { get; set; } - public decimal StockQuantity { get; set; } } public class GetMaterialPriceResponse @@ -220,4 +219,11 @@ public class GetPaymentTermResponse public DateTime StartDate { get; set; } public DateTime EndDate { get; set; } public string PaymentTermType { get; set; } +} + +public class GetMaterialStockReponse +{ + public string PlantCode { get;set; } + public string MaterialCode { get; set; } + public decimal AvailableStock { get; set; } } \ No newline at end of file diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationHttpService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationHttpService.cs index 19f6939..db7a12a 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationHttpService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/Integrations/IIntegrationHttpService.cs @@ -1,5 +1,6 @@  using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -7,10 +8,10 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations; public interface IIntegrationHttpService { - Task GetCustomerLedgerAsync(string customerNumber, string companyCode, + Task GetCustomerLedgerAsync(string customerNumber, string companyCode, CancellationToken cancellationToken = default); - Task GetMaterialStockAsync(string plantCode, string materialCode, + Task> GetMaterialStockAsync(string plantCode, CancellationToken cancellationToken = default); diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/MobileApp/IMobileMasterDataService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/MobileApp/IMobileMasterDataService.cs index e0485b1..f869c08 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/MobileApp/IMobileMasterDataService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Contracts/MobileApp/IMobileMasterDataService.cs @@ -11,6 +11,7 @@ public interface IMobileMasterDataService Task GetMarketHeirarchiesByEmpAsync(GetMarketHeirarchyByEmpRequest request); Task> GetBrandsAsync(GetBrandsRequest request); Task> GetMaterialsAsync(GetMaterialsRequest request); + Task> GetMaterialsStockAsync(GetMaterialStockRequest request); Task> GetMaterialPricesAsync(GetMaterialPriceRequest request); Task> GetCustomersAsync(GetCustomersRequest request); Task GetAttendanceByEmpAsync(GetAttendanceByEmpRequest request); diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationHttpService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationHttpService.cs index e7dc82f..12c35f7 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationHttpService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/Integrations/IntegrationHttpService.cs @@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations; using System; +using System.Collections.Generic; using System.Linq; using System.Net.Http; using System.Net.Http.Json; @@ -22,7 +23,7 @@ public class IntegrationHttpService : IIntegrationHttpService _logger = logger; } - public async Task GetCustomerLedgerAsync(string customerNumber, string companyCode, CancellationToken cancellationToken = default) + public async Task GetCustomerLedgerAsync(string customerNumber, string companyCode, CancellationToken cancellationToken = default) { try { @@ -36,7 +37,7 @@ public class IntegrationHttpService : IIntegrationHttpService _logger.LogError("Customer ledger call failed: {StatusCode} — {Body}", response.StatusCode, body); response.EnsureSuccessStatusCode(); } - var payload= await response.Content.ReadFromJsonAsync< SapODataResponse>(cancellationToken: cancellationToken); + var payload= await response.Content.ReadFromJsonAsync< SapODataResponse>(cancellationToken: cancellationToken); return payload?.D.Results.FirstOrDefault(); } @@ -46,11 +47,11 @@ public class IntegrationHttpService : IIntegrationHttpService } } - public async Task GetMaterialStockAsync(string plantCode, string materialCode, CancellationToken cancellationToken = default) + public async Task> GetMaterialStockAsync(string plantCode, CancellationToken cancellationToken = default) { try { - var requestUri = $"http/get_available_stocks?plant={Uri.EscapeDataString(plantCode)}&material={Uri.EscapeDataString(materialCode)}"; + var requestUri = $"http/get_plantwise_available_stocks?plant={Uri.EscapeDataString(plantCode)}"; var response = await _httpClient.GetAsync(requestUri, cancellationToken); @@ -61,7 +62,9 @@ public class IntegrationHttpService : IIntegrationHttpService response.EnsureSuccessStatusCode(); } - return await response.Content.ReadFromJsonAsync(cancellationToken: cancellationToken); + var payload = await response.Content.ReadFromJsonAsync>(cancellationToken: cancellationToken); + + return payload?.D.Results; } catch (Exception) { diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/MobileMasterDataService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/MobileMasterDataService.cs index 74a7512..27182ba 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/MobileMasterDataService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/MobileMasterDataService.cs @@ -2,11 +2,9 @@ using Ease.NetCore.DataAccess.SQL; using Microsoft.Data.SqlClient; using Microsoft.Extensions.Options; -using MySqlX.XDevAPI.Common; using OnlineSalesAutoCrop.CoreAPI.Models.Global; using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp; using OnlineSalesAutoCrop.CoreAPI.Models.Responses; -using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations; using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations; using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp; @@ -154,9 +152,9 @@ public class MobileMasterDataService : IMobileMasterDataService UnitConversionValue = dr.GetDecimal(8), BrandCode = dr.GetString(9), BrandName = dr.GetString(10), - SalesOrg = dr.GetString(11), - StockQuantity = Random.Shared.Next(1, 100) + SalesOrg = dr.GetString(11) }); + } dr.Close(); @@ -183,6 +181,36 @@ public class MobileMasterDataService : IMobileMasterDataService return response; } + public async Task> GetMaterialsStockAsync(GetMaterialStockRequest request) + { + PagedResult response = new(); + try + { + //var httpStockResponse = await _httpService.GetMaterialStockAsync(request.PlantCode); + + //response.Items = httpStockResponse.Select(p => new GetMaterialStockReponse + //{ + // MaterialCode = p.MaterialCode, + // PlantCode = p.PlantCode, + // AvailableStock = p.AvailableStock, + //}).ToList(); + + var materialResponse = await GetMaterialsAsync(new GetMaterialsRequest()); + + foreach (var item in materialResponse.Items) + { + response.Items.Add( + new GetMaterialStockReponse() { PlantCode = request.PlantCode, MaterialCode = item.MaterialCode, AvailableStock = Random.Shared.Next(5, 500) }); + } + } + catch (Exception) + { + throw; + } + + return response; + } + public async Task> GetMaterialPricesAsync(GetMaterialPriceRequest request) { PagedResult response = new(); diff --git a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/OrderService.cs b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/OrderService.cs index 40c8d2d..48006fb 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/OrderService.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI.Services/Services/MobileApp/OrderService.cs @@ -763,12 +763,12 @@ public class OrderService : IOrderService MaterialName = dr.GetString(3), UnitPrice = dr.GetDecimal(4), SalesUnit = dr.GetString(5), - PromoQuantity = dr.GetDecimal(6), - OrderQuantity = dr.GetDecimal(7), - ValidatedQuantity = dr.GetDecimal(8), - ApprovedQuantity = dr.GetDecimal(9), - DiscountPercentage = dr.GetDecimal(10), - DiscountAmount = dr.GetDecimal(11), + PromoQuantity =dr.IsDBNull(6)? null : dr.GetDecimal(6), + OrderQuantity = dr.IsDBNull(7)? null : dr.GetDecimal(7), + ValidatedQuantity = dr.IsDBNull(8) ? null : dr.GetDecimal(8), + ApprovedQuantity = dr.IsDBNull(9) ? null : dr.GetDecimal(9), + DiscountPercentage = dr.IsDBNull(10) ? null : dr.GetDecimal(10), + DiscountAmount = dr.IsDBNull(11) ? null : dr.GetDecimal(11), IsFocItem = dr.GetInt32(12) > 0, LineTotalValue = dr.GetDecimal(13) }); diff --git a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/Mobile/MobileMasterDataController.cs b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/Mobile/MobileMasterDataController.cs index 79f98e0..d51e0c9 100644 --- a/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/Mobile/MobileMasterDataController.cs +++ b/Api/OnlineSalesAutoCrop.CoreAPI/Controllers/Mobile/MobileMasterDataController.cs @@ -120,6 +120,32 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers } } + /// + /// Login using your credential data retrieve from SqlServer + /// + /// + /// + /// + /// If login successful Return Material List + [HttpGet("MaterialsStock")] + [IgnoreAntiforgeryToken] + [ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetMaterialStockReponse))] + public async Task GetMaterialsStock([FromQuery] GetMaterialStockRequest request) + { + PagedResult response = new(); + try + { + response = await _service.GetMaterialsStockAsync(request); + return Ok(MobileResponseBase>.Success(response)); + } + catch (Exception ex) + { + string msg = $"Exception occur on MaterialsStock endpoint with plant request - {request?.PlantCode} "; + _logger.LogError(exception: ex, message: msg); + return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError)); + } + } + /// /// Login using your credential data retrieve from SqlServer ///