implement material stock endpoints
This commit is contained in:
parent
3ae6fa0882
commit
777aff085e
|
|
@ -40,6 +40,12 @@ public class GetMaterialsRequest : PagedRequest
|
||||||
public string? EmployeeNumber { get; set; }
|
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
|
public class GetMaterialPriceRequest : PagedRequest
|
||||||
{
|
{
|
||||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
[StringLength(10, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||||
|
|
|
||||||
|
|
@ -9,25 +9,6 @@ using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
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<T>
|
public sealed class SapODataResponse<T>
|
||||||
{
|
{
|
||||||
[JsonPropertyName("d")]
|
[JsonPropertyName("d")]
|
||||||
|
|
@ -40,7 +21,7 @@ public sealed class SapODataResult<T>
|
||||||
public List<T> Results { get; set; } = new();
|
public List<T> Results { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed class CustomerLedgerDto
|
public sealed class IntegrationCustLedgerHttpResponse
|
||||||
{
|
{
|
||||||
[JsonPropertyName("company")]
|
[JsonPropertyName("company")]
|
||||||
public string Company { get; set; } = string.Empty;
|
public string Company { get; set; } = string.Empty;
|
||||||
|
|
@ -64,6 +45,24 @@ public sealed class CustomerLedgerDto
|
||||||
public DateTime OverdueDate { get; set; }
|
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<DateTime>
|
public sealed class SapODataDateConverter : JsonConverter<DateTime>
|
||||||
{
|
{
|
||||||
// Matches "/Date(1783641600000)/" and the rarer offset form "/Date(1783641600000+0600)/"
|
// Matches "/Date(1783641600000)/" and the rarer offset form "/Date(1783641600000+0600)/"
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,6 @@ public class GetMaterialResponse
|
||||||
public string BrandCode { get; set; }
|
public string BrandCode { get; set; }
|
||||||
public string BrandName { get; set; }
|
public string BrandName { get; set; }
|
||||||
public string SalesOrg { get; set; }
|
public string SalesOrg { get; set; }
|
||||||
public decimal StockQuantity { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public class GetMaterialPriceResponse
|
public class GetMaterialPriceResponse
|
||||||
|
|
@ -220,4 +219,11 @@ public class GetPaymentTermResponse
|
||||||
public DateTime StartDate { get; set; }
|
public DateTime StartDate { get; set; }
|
||||||
public DateTime EndDate { get; set; }
|
public DateTime EndDate { get; set; }
|
||||||
public string PaymentTermType { 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; }
|
||||||
}
|
}
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -7,10 +8,10 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
|
||||||
|
|
||||||
public interface IIntegrationHttpService
|
public interface IIntegrationHttpService
|
||||||
{
|
{
|
||||||
Task<CustomerLedgerDto?> GetCustomerLedgerAsync(string customerNumber, string companyCode,
|
Task<IntegrationCustLedgerHttpResponse?> GetCustomerLedgerAsync(string customerNumber, string companyCode,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
Task<IntegrationMaterialStockHttpResponse?> GetMaterialStockAsync(string plantCode, string materialCode,
|
Task<IList<IntegrationMaterialStockHttpResponse>> GetMaterialStockAsync(string plantCode,
|
||||||
CancellationToken cancellationToken = default);
|
CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ public interface IMobileMasterDataService
|
||||||
Task<MarketHeirarchyByEmpResponse> GetMarketHeirarchiesByEmpAsync(GetMarketHeirarchyByEmpRequest request);
|
Task<MarketHeirarchyByEmpResponse> GetMarketHeirarchiesByEmpAsync(GetMarketHeirarchyByEmpRequest request);
|
||||||
Task<PagedResult<GetBrandResponse>> GetBrandsAsync(GetBrandsRequest request);
|
Task<PagedResult<GetBrandResponse>> GetBrandsAsync(GetBrandsRequest request);
|
||||||
Task<PagedResult<GetMaterialResponse>> GetMaterialsAsync(GetMaterialsRequest request);
|
Task<PagedResult<GetMaterialResponse>> GetMaterialsAsync(GetMaterialsRequest request);
|
||||||
|
Task<PagedResult<GetMaterialStockReponse>> GetMaterialsStockAsync(GetMaterialStockRequest request);
|
||||||
Task<PagedResult<GetMaterialPriceResponse>> GetMaterialPricesAsync(GetMaterialPriceRequest request);
|
Task<PagedResult<GetMaterialPriceResponse>> GetMaterialPricesAsync(GetMaterialPriceRequest request);
|
||||||
Task<PagedResult<GetCustomerResponse>> GetCustomersAsync(GetCustomersRequest request);
|
Task<PagedResult<GetCustomerResponse>> GetCustomersAsync(GetCustomersRequest request);
|
||||||
Task<GetAttendanceByEmpResponse> GetAttendanceByEmpAsync(GetAttendanceByEmpRequest request);
|
Task<GetAttendanceByEmpResponse> GetAttendanceByEmpAsync(GetAttendanceByEmpRequest request);
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ using Microsoft.Extensions.Logging;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Json;
|
using System.Net.Http.Json;
|
||||||
|
|
@ -22,7 +23,7 @@ public class IntegrationHttpService : IIntegrationHttpService
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<CustomerLedgerDto> GetCustomerLedgerAsync(string customerNumber, string companyCode, CancellationToken cancellationToken = default)
|
public async Task<IntegrationCustLedgerHttpResponse> GetCustomerLedgerAsync(string customerNumber, string companyCode, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -36,7 +37,7 @@ public class IntegrationHttpService : IIntegrationHttpService
|
||||||
_logger.LogError("Customer ledger call failed: {StatusCode} — {Body}", response.StatusCode, body);
|
_logger.LogError("Customer ledger call failed: {StatusCode} — {Body}", response.StatusCode, body);
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
var payload= await response.Content.ReadFromJsonAsync< SapODataResponse<CustomerLedgerDto>>(cancellationToken: cancellationToken);
|
var payload= await response.Content.ReadFromJsonAsync< SapODataResponse<IntegrationCustLedgerHttpResponse>>(cancellationToken: cancellationToken);
|
||||||
|
|
||||||
return payload?.D.Results.FirstOrDefault();
|
return payload?.D.Results.FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
@ -46,11 +47,11 @@ public class IntegrationHttpService : IIntegrationHttpService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<IntegrationMaterialStockHttpResponse> GetMaterialStockAsync(string plantCode, string materialCode, CancellationToken cancellationToken = default)
|
public async Task<IList<IntegrationMaterialStockHttpResponse>> GetMaterialStockAsync(string plantCode, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
try
|
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);
|
var response = await _httpClient.GetAsync(requestUri, cancellationToken);
|
||||||
|
|
||||||
|
|
@ -61,7 +62,9 @@ public class IntegrationHttpService : IIntegrationHttpService
|
||||||
response.EnsureSuccessStatusCode();
|
response.EnsureSuccessStatusCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
return await response.Content.ReadFromJsonAsync<IntegrationMaterialStockHttpResponse>(cancellationToken: cancellationToken);
|
var payload = await response.Content.ReadFromJsonAsync<SapODataResponse<IntegrationMaterialStockHttpResponse>>(cancellationToken: cancellationToken);
|
||||||
|
|
||||||
|
return payload?.D.Results;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,9 @@
|
||||||
using Ease.NetCore.DataAccess.SQL;
|
using Ease.NetCore.DataAccess.SQL;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using MySqlX.XDevAPI.Common;
|
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Integrations;
|
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Integrations;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
|
||||||
|
|
@ -154,9 +152,9 @@ public class MobileMasterDataService : IMobileMasterDataService
|
||||||
UnitConversionValue = dr.GetDecimal(8),
|
UnitConversionValue = dr.GetDecimal(8),
|
||||||
BrandCode = dr.GetString(9),
|
BrandCode = dr.GetString(9),
|
||||||
BrandName = dr.GetString(10),
|
BrandName = dr.GetString(10),
|
||||||
SalesOrg = dr.GetString(11),
|
SalesOrg = dr.GetString(11)
|
||||||
StockQuantity = Random.Shared.Next(1, 100)
|
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
dr.Close();
|
dr.Close();
|
||||||
|
|
||||||
|
|
@ -183,6 +181,36 @@ public class MobileMasterDataService : IMobileMasterDataService
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<PagedResult<GetMaterialStockReponse>> GetMaterialsStockAsync(GetMaterialStockRequest request)
|
||||||
|
{
|
||||||
|
PagedResult<GetMaterialStockReponse> 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<PagedResult<GetMaterialPriceResponse>> GetMaterialPricesAsync(GetMaterialPriceRequest request)
|
public async Task<PagedResult<GetMaterialPriceResponse>> GetMaterialPricesAsync(GetMaterialPriceRequest request)
|
||||||
{
|
{
|
||||||
PagedResult<GetMaterialPriceResponse> response = new();
|
PagedResult<GetMaterialPriceResponse> response = new();
|
||||||
|
|
|
||||||
|
|
@ -763,12 +763,12 @@ public class OrderService : IOrderService
|
||||||
MaterialName = dr.GetString(3),
|
MaterialName = dr.GetString(3),
|
||||||
UnitPrice = dr.GetDecimal(4),
|
UnitPrice = dr.GetDecimal(4),
|
||||||
SalesUnit = dr.GetString(5),
|
SalesUnit = dr.GetString(5),
|
||||||
PromoQuantity = dr.GetDecimal(6),
|
PromoQuantity =dr.IsDBNull(6)? null : dr.GetDecimal(6),
|
||||||
OrderQuantity = dr.GetDecimal(7),
|
OrderQuantity = dr.IsDBNull(7)? null : dr.GetDecimal(7),
|
||||||
ValidatedQuantity = dr.GetDecimal(8),
|
ValidatedQuantity = dr.IsDBNull(8) ? null : dr.GetDecimal(8),
|
||||||
ApprovedQuantity = dr.GetDecimal(9),
|
ApprovedQuantity = dr.IsDBNull(9) ? null : dr.GetDecimal(9),
|
||||||
DiscountPercentage = dr.GetDecimal(10),
|
DiscountPercentage = dr.IsDBNull(10) ? null : dr.GetDecimal(10),
|
||||||
DiscountAmount = dr.GetDecimal(11),
|
DiscountAmount = dr.IsDBNull(11) ? null : dr.GetDecimal(11),
|
||||||
IsFocItem = dr.GetInt32(12) > 0,
|
IsFocItem = dr.GetInt32(12) > 0,
|
||||||
LineTotalValue = dr.GetDecimal(13)
|
LineTotalValue = dr.GetDecimal(13)
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -120,6 +120,32 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Login using your credential data retrieve from SqlServer
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// </remarks>
|
||||||
|
/// <param name="request"></param>
|
||||||
|
/// <response code="200">If login successful Return Material List</response>
|
||||||
|
[HttpGet("MaterialsStock")]
|
||||||
|
[IgnoreAntiforgeryToken]
|
||||||
|
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetMaterialStockReponse))]
|
||||||
|
public async Task<IActionResult> GetMaterialsStock([FromQuery] GetMaterialStockRequest request)
|
||||||
|
{
|
||||||
|
PagedResult<GetMaterialStockReponse> response = new();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
response = await _service.GetMaterialsStockAsync(request);
|
||||||
|
return Ok(MobileResponseBase<PagedResult<GetMaterialStockReponse>>.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<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Login using your credential data retrieve from SqlServer
|
/// Login using your credential data retrieve from SqlServer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user