completed order summary endpoint

This commit is contained in:
dibakorroyme 2026-07-18 18:55:29 +06:00
parent 97a07bd216
commit 38e557fbfd
10 changed files with 195 additions and 166 deletions

View File

@ -65,4 +65,16 @@ public class SaveOrderPromotionRequest
public decimal ValidatedFocQty { get; set; }
public decimal ApprovedFocQty { get; set; }
public int PromotionType { get; set; }
}
public class GetOrderSummaryRequest : PagedRequest
{
public string? SalesOrgCode { get; set; }
public string? EmployerCode { get; set; }
public string? OrderNo { get; set; }
public string? UUID { get; set; }
public string? CustomerCode { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public OrderStatusEnum? OrderStatus { get; set; }
}

View File

@ -105,6 +105,7 @@ 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

View File

@ -21,51 +21,44 @@ public class OrderBasicResponse
public OrderStatusEnum OrderStatus { get; set; }
}
public class GetOrderByUUIDResponse
public class GetSalesOrderResponse
{
public int OrderId { get; set; }
public int OrderId { get; set; }
public Guid Uuid { get; set; }
public string OrderNo { get; set; }
public DateTime OrderDate { get; set; }
public DateTime? ExpectedSalesDate { get; set; }
public Guid UUID { get; set; }
public DateTime OrderDate { get; set; }
public string SalesOrgCode { get; set; }
public int CustomerId { get; set; }
public string CustomerCode { get; set; }
public string CustomerName { get; set; }
public int EmployeeId { get; set; }
public string EmployeeCode { get; set; }
public string EmployeeName { get; set; }
public string PaymentTermCode { get; set; }
public string? ReferenceTxtNo { get; set; }
public decimal GrossValue { get; set; }
public string EmployeeCode { get; set; }
public DateTime? ExpectedDeliveryDate { get; set; }
public string PaymentTermCode { get; set; }
public string DiscountCode { get; set; }
public string FocCode { get; set; }
public decimal DiscountValue { get; set; }
public decimal FOCValue { get; set; }
public decimal GrossValue { get; set; }
public decimal NetValue { get; set; }
public string OrderStatus { get; set; }
public string SAPReferenceOrderNo { get; set; }
public int OrderStatus { get; set; }
public List<GetOrderItemResponse> Items { get; set; } = new();
public List<GetOrderPromotionResponse> Promotions { get; set; } = new();
public List<GetSalesOrderItemResponse> Items { get; set; } = new();
}
public class GetOrderItemResponse
public class GetSalesOrderItemResponse
{
public int ItemId { get; set; }
public int OrderID { get; set; }
public int MaterialId { get; set; }
public int OrderId { get; set; }
public Guid UUID { get;set; }
public string MaterialCode { get; set; }
public string MaterialName { get; set; }
public decimal UnitPrice { get; set; }
public string SalesUnit { get; set; }
public decimal PromoQuantity { get; set; }
public decimal OrderQuantity { get; set; }
public decimal ValidatedQuantity { get; set; }
public decimal ApprovedQuantity { get; set; }
public decimal DiscountPercentage { get; set; }
public decimal DiscountValue { get; set; }
public bool IsFOCItem { get; set; }
public decimal OrderFocQuantity { get; set; }
public decimal ValidatedFocQuantity { get; set; }
public decimal ApprovedFocQuantity { get; set; }
public decimal DiscountAmount { get; set; }
public bool IsFocItem { get; set; }
public decimal LineTotalValue { get; set; }
}

View File

@ -1,5 +1,7 @@

using OnlineSalesAutoCrop.CoreAPI.Models.Requests;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using System.Threading.Tasks;
@ -8,4 +10,5 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
public interface IOrderService
{
Task<SaveOrderResponse> SaveOrderAsync(SaveOrderRequest request, int userId);
Task<PagedResult<GetSalesOrderResponse>> GetSalesOrdersSummary(GetOrderSummaryRequest request, int userId);
}

View File

@ -150,7 +150,8 @@ public class MobileMasterDataService : IMobileMasterDataService
UnitConversionValue = dr.GetDecimal(8),
BrandCode = dr.GetString(9),
BrandName = dr.GetString(10),
SalesOrg = dr.GetString(11)
SalesOrg = dr.GetString(11),
StockQuantity = Random.Shared.Next(1, 100)
});
}
dr.Close();

View File

@ -6,6 +6,7 @@ using Microsoft.Extensions.Options;
using OnlineSalesAutoCrop.CoreAPI.Models;
using OnlineSalesAutoCrop.CoreAPI.Models.Global;
using OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses;
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
@ -31,36 +32,6 @@ public class OrderService : IOrderService
_masterService = masterService;
}
//public async Task<SaveOrderResponse> SaveOrderAsync(SaveOrderRequest request)
//{
// SaveOrderResponse response = new();
// try
// {
// using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode,true);
// GetOrderByUUIDResponse order= await GetOrderByUUIDAsync(tc, request.UUID);
// tc.End();
// }
// catch(Exception)
// {
// throw;
// }
// return new SaveOrderResponse()
// {
// OrderId = 12345,
// OrderDate = DateTime.Now,
// OrderNo = "Ord-000001-" + DateTime.Now.ToString("HH-mm-ss"),
// UUID = request.UUID,
// IsNewOrder =true
// };
//}
public async Task<SaveOrderResponse> SaveOrderAsync(SaveOrderRequest request, int userId)
{
SaveOrderResponse response = new();
@ -81,7 +52,18 @@ public class OrderService : IOrderService
}
var existingOrder = await GetExistingOrderIdAsync(tc, request.UUID);
request.OrderId = (existingOrder != null && existingOrder.OrderId > 0)? existingOrder.OrderId : 0;
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 ||
existingOrder.OrderStatus == OrderStatusEnum.CancelledByValidator))
{
throw new Exception($"Order with UUID '{request.UUID}' has already been {existingOrder.OrderStatus.ToString()} and cannot be modified.");
}
foreach (var item in request.Items)
{
@ -164,7 +146,7 @@ public class OrderService : IOrderService
OrderFocQty = (request.OrderStatus == OrderStatusEnum.Draft || request.OrderStatus == OrderStatusEnum.InOrderValidation) ? focItem.OrderQuantity : 0,
ValidatedFocQty = (request.OrderStatus == OrderStatusEnum.CancelledByValidator || request.OrderStatus == OrderStatusEnum.InOrderApproval) ? focItem.OrderQuantity : 0,
ApprovedFocQty = (request.OrderStatus == OrderStatusEnum.CancelledByApprover || request.OrderStatus == OrderStatusEnum.Approved) ? focItem.OrderQuantity : 0,
PromotionType = 1,
PromotionType = 2,
});
// 5. Insert or update
@ -220,111 +202,6 @@ public class OrderService : IOrderService
}
private async Task<GetOrderByUUIDResponse> GetOrderByUUIDAsync(TransactionContext tc, Guid uuid)
{
GetOrderByUUIDResponse response = null;
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@UUID", pType: SqlDbType.UniqueIdentifier, pValue: uuid)
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetOrderDetailsByUUID", parameterValues: p))
{
if (dr.Read())
{
response = new GetOrderByUUIDResponse
{
OrderId = dr.GetInt32(0),
OrderNo = dr.GetString(1),
OrderDate = dr.GetDateTime(2),
ExpectedSalesDate = dr.IsDBNull(3) ? null : dr.GetDateTime(3),
UUID = dr.GetGuid(4),
SalesOrgCode = dr.GetString(5),
CustomerId = dr.GetInt32(6),
CustomerCode = dr.GetString(7),
CustomerName = dr.GetString(8),
EmployeeId = dr.GetInt32(9),
EmployeeCode = dr.GetString(10),
EmployeeName = dr.GetString(11),
PaymentTermCode = dr.GetString(12),
ReferenceTxtNo = dr.IsDBNull(13) ? null : dr.GetString(13),
GrossValue = dr.GetDecimal(14),
DiscountValue = dr.GetDecimal(15),
FOCValue = dr.GetDecimal(16),
NetValue = dr.GetDecimal(17),
OrderStatus = dr.GetString(18),
SAPReferenceOrderNo = dr.IsDBNull(19) ? null : dr.GetString(19)
};
}
if (response != null && dr.NextResult())
{
while (dr.Read())
{
GetOrderItemResponse item = new()
{
ItemId = dr.GetInt32(0),
OrderID = dr.GetInt32(1),
MaterialId = dr.GetInt32(2),
MaterialCode = dr.GetString(3),
MaterialName = dr.GetString(4),
UnitPrice = dr.GetDecimal(5),
SalesUnit = dr.GetString(6),
OrderQuantity = dr.GetDecimal(7),
ValidatedQuantity = dr.GetDecimal(8),
ApprovedQuantity = dr.GetDecimal(9),
DiscountPercentage = dr.GetDecimal(10),
DiscountValue = dr.GetDecimal(11),
IsFOCItem = dr.GetBoolean(12),
OrderFocQuantity = dr.GetDecimal(13),
ValidatedFocQuantity = dr.GetDecimal(14),
ApprovedFocQuantity = dr.GetDecimal(15),
LineTotalValue = dr.GetDecimal(16),
};
response.Items.Add(item);
}
}
if (response != null && dr.NextResult())
{
while (dr.Read())
{
GetOrderPromotionResponse promotion = new()
{
ItemId = dr.GetInt32(0),
OrderID = dr.GetInt32(1),
MaterialId = dr.GetInt32(2),
PromotionCode = dr.GetString(3),
DiscountPercentage = dr.GetDecimal(4),
DiscountValue = dr.GetDecimal(5),
ForQuantity = dr.GetDecimal(6),
OrderFocQuantity = dr.GetDecimal(7),
ValidatedFocQuantity = dr.GetDecimal(8),
ApprovedFocQuantity = dr.GetDecimal(9),
PromotionType = dr.GetInt32(10),
};
response.Promotions.Add(promotion);
}
}
dr.Close();
}
}
catch (Exception)
{
throw;
}
return response;
}
private async Task<UserRoleDto?> GetUserRoleAsync(TransactionContext tc, int userId)
{
try
@ -743,6 +620,8 @@ public class OrderService : IOrderService
SqlHelperExtension.CreateInParam(pName: "@EmployeeCode", pType: SqlDbType.VarChar, pValue: request.EmployeeCode ),
SqlHelperExtension.CreateInParam(pName: "@EmployeeName", pType: SqlDbType.VarChar, pValue: request.EmployeeCode ),
SqlHelperExtension.CreateInParam(pName: "@PaymentTermCode", pType: SqlDbType.VarChar, pValue: request.PaymentTermCode),
SqlHelperExtension.CreateInParam(pName: "@DiscountCode", pType: SqlDbType.VarChar, pValue: request.DiscountCode),
SqlHelperExtension.CreateInParam(pName: "@FOCCode", pType: SqlDbType.VarChar, pValue: request.FocCode),
SqlHelperExtension.CreateInParam(pName: "@ReferenceTxtNo", pType: SqlDbType.VarChar, pValue: request.ReferenceTxtNo ),
SqlHelperExtension.CreateInParam(pName: "@GrossValue", pType: SqlDbType.Decimal, pValue: request.GrossValue),
SqlHelperExtension.CreateInParam(pName: "@DiscountValue", pType: SqlDbType.Decimal, pValue: request.DiscountValue),
@ -790,6 +669,8 @@ public class OrderService : IOrderService
SqlHelperExtension.CreateInParam(pName: "@OrderId", pType: SqlDbType.Int, pValue: orderId),
SqlHelperExtension.CreateInParam(pName: "@ExpectedDeliveryDate", pType: SqlDbType.DateTime, pValue: request.ExpectedDeliveryDate ),
SqlHelperExtension.CreateInParam(pName: "@PaymentTermCode", pType: SqlDbType.VarChar, pValue: request.PaymentTermCode),
SqlHelperExtension.CreateInParam(pName: "@DiscountCode", pType: SqlDbType.VarChar, pValue: request.DiscountCode),
SqlHelperExtension.CreateInParam(pName: "@FOCCode", pType: SqlDbType.VarChar, pValue: request.FocCode),
SqlHelperExtension.CreateInParam(pName: "@ReferenceTxtNo", pType: SqlDbType.VarChar, pValue: request.ReferenceTxtNo ),
SqlHelperExtension.CreateInParam(pName: "@GrossValue", pType: SqlDbType.Decimal, pValue: request.GrossValue),
SqlHelperExtension.CreateInParam(pName: "@DiscountValue", pType: SqlDbType.Decimal, pValue: request.DiscountValue),
@ -808,4 +689,115 @@ public class OrderService : IOrderService
throw;
}
}
public async Task<PagedResult<GetSalesOrderResponse>> GetSalesOrdersSummary(GetOrderSummaryRequest request, int userId)
{
PagedResult<GetSalesOrderResponse?> response = null;
List<GetSalesOrderResponse> orders = new();
List<GetSalesOrderItemResponse> orderItems = new();
try
{
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode);
try
{
SqlParameter[] p =
[
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue:request.SalesOrgCode) ,
SqlHelperExtension.CreateInParam(pName: "@EmployeeCode", pType: SqlDbType.VarChar, pValue:request.EmployerCode) ,
SqlHelperExtension.CreateInParam(pName: "@OrderNo", pType: SqlDbType.VarChar, pValue: request.OrderNo ),
SqlHelperExtension.CreateInParam(pName: "@UUID", pType: SqlDbType.VarChar, pValue: request.UUID ),
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.VarChar, pValue: request.CustomerCode ),
SqlHelperExtension.CreateInParam(pName: "@OrderStatus", pType: SqlDbType.Int, pValue: (int?)request.OrderStatus ),
SqlHelperExtension.CreateInParam(pName: "@StartDate", pType: SqlDbType.DateTime, pValue: request.StartDate ),
SqlHelperExtension.CreateInParam(pName: "@EndDate", pType: SqlDbType.DateTime, pValue: request.EndDate ),
SqlHelperExtension.CreateInParam(pName: "@PageNumber", pType: SqlDbType.Int, pValue: request.PageNumber ),
SqlHelperExtension.CreateInParam(pName: "@PageSize", pType: SqlDbType.Int, pValue: request.PageSize )
];
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetOrderSummaryPaginated", parameterValues: p))
{
// --- Result set 1: order header ---
while (dr.Read())
{
orders.Add( new GetSalesOrderResponse
{
OrderId = dr.GetInt32(16),
Uuid = dr.GetGuid(0),
OrderNo = dr.GetString(1),
OrderDate = dr.GetDateTime(2),
ExpectedDeliveryDate = dr.IsDBNull(3) ? null : dr.GetDateTime(3),
SalesOrgCode = dr.GetString(4),
CustomerCode = dr.GetString(5),
CustomerName = dr.GetString(6),
ReferenceTxtNo = dr.IsDBNull(7) ? null : dr.GetString(7),
EmployeeCode = dr.GetString(8),
PaymentTermCode = dr.GetString(9),
DiscountCode = dr.IsDBNull(10) ? string.Empty : dr.GetString(10),
FocCode = dr.IsDBNull(11) ? string.Empty : dr.GetString(11),
DiscountValue = dr.GetDecimal(12),
GrossValue = dr.GetDecimal(13),
NetValue = dr.GetDecimal(14),
OrderStatus = dr.GetInt32(15)
});
}
// --- Result set 2: order items ---
if (orders.Count >0 && dr.NextResult())
{
while (dr.Read())
{
orderItems.Add(new GetSalesOrderItemResponse
{
OrderId = dr.GetInt32(0),
UUID = dr.GetGuid(1),
MaterialCode = dr.GetString(2),
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),
IsFocItem = dr.GetInt32(12) > 0,
LineTotalValue = dr.GetDecimal(13)
});
}
}
dr.Close();
}
tc.End();
foreach (var order in orders)
{
order.Items = orderItems.Where(i => i.OrderId == order.OrderId).ToList();
}
response = new PagedResult<GetSalesOrderResponse>
{
Items = orders,
TotalCount = orders.Count,
PageNumber = request.PageNumber,
PageSize = request.PageSize
};
}
catch (Exception ie)
{
tc?.HandleError();
throw DBCustomError.GenerateCustomError(ie);
}
}
catch (Exception ex)
{
throw;
}
return response;
}
}

View File

@ -3,6 +3,7 @@ using Google.Api;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OnlineSalesAutoCrop.CoreAPI.Models;
@ -46,11 +47,11 @@ public class OrdersController(IOrderService service, IOptions<AppSettings> appSe
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
/// <response code="200">If login successful Return Order List</response>
[HttpPost("SaveOrder")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(SaveOrderResponse))]
public async Task<IActionResult> UpsertAttendance([FromBody] SaveOrderRequest request)
public async Task<IActionResult> SaveOrders([FromBody] SaveOrderRequest request)
{
SaveOrderResponse response = new();
try
@ -66,5 +67,32 @@ public class OrdersController(IOrderService service, IOptions<AppSettings> appSe
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
/// <summary>
/// Login using your credential data retrieve from SqlServer
/// </summary>
/// <remarks>
/// </remarks>
/// <param name="request"></param>
/// <response code="200">If login successful Return Attendance List</response>
[HttpGet("OrderSummary")]
[IgnoreAntiforgeryToken]
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(GetSalesOrderResponse))]
public async Task<IActionResult> GetOrderSummaries([FromQuery] GetOrderSummaryRequest request)
{
PagedResult<GetSalesOrderResponse> response = new();
try
{
int userId = HttpContext.User.GetClaimValue<int>(Constants.UserId);
response = await _service.GetSalesOrdersSummary(request, userId);
return Ok(MobileResponseBase<PagedResult<GetSalesOrderResponse>>.Success(response));
}
catch (Exception ex)
{
string msg = $"Exception occur on Save Orders endpoint with Order UUID request - {request?.UUID}";
_logger.LogError(exception: ex, message: msg);
return StatusCode(StatusCodes.Status500InternalServerError, MobileResponseBase<AppAuthUserResponse>.Failure(ex.InnerException != null ? ex.InnerException.Message : ex.Message, StatusCodes.Status500InternalServerError));
}
}
}

File diff suppressed because one or more lines are too long