complete save order endpoint
This commit is contained in:
parent
7acf518892
commit
97a07bd216
|
|
@ -14,8 +14,9 @@ public class SaveOrderRequest
|
||||||
public string? OrderNo { get; set; }
|
public string? OrderNo { get; set; }
|
||||||
public DateTime? OrderDate { get; set; }
|
public DateTime? OrderDate { get; set; }
|
||||||
public DateTime? ExpectedDeliveryDate { get; set; }
|
public DateTime? ExpectedDeliveryDate { get; set; }
|
||||||
public string UUID { get; set; }
|
public Guid UUID { get; set; }
|
||||||
public string SalesOrgCode { get; set; }
|
public string SalesOrgCode { get; set; }
|
||||||
|
public int? CustomerId { get; set; }
|
||||||
public string CustomerCode { get; set; }
|
public string CustomerCode { get; set; }
|
||||||
public string CustomerName { get; set; }
|
public string CustomerName { get; set; }
|
||||||
public int? EmployeeId { get; set; }
|
public int? EmployeeId { get; set; }
|
||||||
|
|
@ -24,6 +25,7 @@ public class SaveOrderRequest
|
||||||
public string PaymentTermCode { get; set; }
|
public string PaymentTermCode { get; set; }
|
||||||
public string DiscountCode { get; set; }
|
public string DiscountCode { get; set; }
|
||||||
public string FocCode { get; set; }
|
public string FocCode { get; set; }
|
||||||
|
public decimal FocValue { get; set; }
|
||||||
public decimal DiscountValue { get; set; }
|
public decimal DiscountValue { get; set; }
|
||||||
public decimal GrossValue { get; set; }
|
public decimal GrossValue { get; set; }
|
||||||
public decimal NetValue { get; set; }
|
public decimal NetValue { get; set; }
|
||||||
|
|
@ -33,10 +35,14 @@ public class SaveOrderRequest
|
||||||
|
|
||||||
public class SaveOrderItemRequest
|
public class SaveOrderItemRequest
|
||||||
{
|
{
|
||||||
|
public int? OrderId { get; set; }
|
||||||
|
public int? ItemId { get; set; }
|
||||||
|
public int? MaterialId { get; set; }
|
||||||
public string MaterialCode { get; set; }
|
public string MaterialCode { get; set; }
|
||||||
public string MaterialName { get; set; }
|
public string MaterialName { get; set; }
|
||||||
public decimal UnitPrice { get; set; }
|
public decimal UnitPrice { get; set; }
|
||||||
public string SalesUnit { get; set; }
|
public string SalesUnit { get; set; }
|
||||||
|
public decimal PromoQuantity { get; set; }
|
||||||
public decimal OrderQuantity { get; set; }
|
public decimal OrderQuantity { get; set; }
|
||||||
public decimal ValidatedQuantity { get; set; }
|
public decimal ValidatedQuantity { get; set; }
|
||||||
public decimal ApprovedQuantity { get; set; }
|
public decimal ApprovedQuantity { get; set; }
|
||||||
|
|
@ -48,6 +54,7 @@ public class SaveOrderItemRequest
|
||||||
|
|
||||||
public class SaveOrderPromotionRequest
|
public class SaveOrderPromotionRequest
|
||||||
{
|
{
|
||||||
|
public int ItemId { get; set; }
|
||||||
public int OrderId { get; set; }
|
public int OrderId { get; set; }
|
||||||
public int MaterialId { get; set; }
|
public int MaterialId { get; set; }
|
||||||
public string PromotionCode { get; set; }
|
public string PromotionCode { get; set; }
|
||||||
|
|
|
||||||
|
|
@ -7,11 +7,20 @@ public class SaveOrderResponse
|
||||||
{
|
{
|
||||||
public int OrderId { get; set; }
|
public int OrderId { get; set; }
|
||||||
public string OrderNo { get; set; }
|
public string OrderNo { get; set; }
|
||||||
public string UUID { get; set; }
|
|
||||||
public DateTime OrderDate { get; set; }
|
public DateTime OrderDate { get; set; }
|
||||||
|
public Guid UUID { get; set; }
|
||||||
public bool IsNewOrder { get; set; }
|
public bool IsNewOrder { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class OrderBasicResponse
|
||||||
|
{
|
||||||
|
public int OrderId { get; set; }
|
||||||
|
public string OrderNo { get; set; }
|
||||||
|
public DateTime OrderDate { get; set; }
|
||||||
|
public Guid UUID { get; set; }
|
||||||
|
public OrderStatusEnum OrderStatus { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class GetOrderByUUIDResponse
|
public class GetOrderByUUIDResponse
|
||||||
{
|
{
|
||||||
public int OrderId { get; set; }
|
public int OrderId { get; set; }
|
||||||
|
|
@ -74,3 +83,47 @@ public class GetOrderPromotionResponse
|
||||||
public decimal ApprovedFocQuantity { get; set; }
|
public decimal ApprovedFocQuantity { get; set; }
|
||||||
public int PromotionType { get; set; }
|
public int PromotionType { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public sealed class UserRoleDto
|
||||||
|
{
|
||||||
|
public int UserId { get; set; }
|
||||||
|
public UserRoleTypeEnum RoleId { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class CustomerLookupDto
|
||||||
|
{
|
||||||
|
public int CustomerId { get; set; }
|
||||||
|
public string CustomerCode { get; set; } = string.Empty;
|
||||||
|
public string CustomerName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class PaymentTermLookupDto
|
||||||
|
{
|
||||||
|
public int PaymentTermId { get; set; }
|
||||||
|
public string PaymentTermCode { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class DiscountLookupDto
|
||||||
|
{
|
||||||
|
public int DiscountId { get; set; }
|
||||||
|
public string DiscountCode { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class MaterialLookupDto
|
||||||
|
{
|
||||||
|
public int MaterialId { get; set; }
|
||||||
|
public string MaterialCode { get; set; } = string.Empty;
|
||||||
|
public string MaterialName { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
public sealed class FreeGoodsRuleDto
|
||||||
|
{
|
||||||
|
public int FreeGoodsId { get; set; }
|
||||||
|
public int MaterialId { get; set; }
|
||||||
|
public decimal MinOrderQuantity { get; set; }
|
||||||
|
public decimal ForQuantity { get; set; }
|
||||||
|
public decimal FreeQuantity { get; set; }
|
||||||
|
public string UnitOfMeasure { get; set; } = string.Empty;
|
||||||
|
public string FocUnitOfMeasure { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
|
@ -7,5 +7,5 @@ namespace OnlineSalesAutoCrop.CoreAPI.Services.Contracts.MobileApp;
|
||||||
|
|
||||||
public interface IOrderService
|
public interface IOrderService
|
||||||
{
|
{
|
||||||
Task<SaveOrderResponse> SaveOrderAsync(SaveOrderRequest request);
|
Task<SaveOrderResponse> SaveOrderAsync(SaveOrderRequest request, int userId);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
using Ease.NetCore.DataAccess;
|
using Ease.NetCore.DataAccess;
|
||||||
using Ease.NetCore.DataAccess.SQL;
|
using Ease.NetCore.DataAccess.SQL;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Data.SqlClient;
|
using Microsoft.Data.SqlClient;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models;
|
||||||
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.MobileApp;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
||||||
|
|
@ -11,6 +13,7 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Data;
|
using System.Data;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Security.Claims;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.MobileApp;
|
namespace OnlineSalesAutoCrop.CoreAPI.Services.Services.MobileApp;
|
||||||
|
|
@ -28,36 +31,196 @@ public class OrderService : IOrderService
|
||||||
_masterService = masterService;
|
_masterService = masterService;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<SaveOrderResponse> SaveOrderAsync(SaveOrderRequest request)
|
//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();
|
SaveOrderResponse response = new();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode,true);
|
using TransactionContext tc = await TransactionContext.BeginAsync(_settings.DefaultConnection.ConnectionNode, true);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 1. Role - fetched using the claims-resolved UserId
|
||||||
|
UserRoleDto? userRole = await GetUserRoleAsync(tc, userId);
|
||||||
|
if (userRole is null)
|
||||||
|
throw new Exception($"User id '{userId}' was not found.");
|
||||||
|
|
||||||
|
if (!IsPermissiontoModify(request.OrderStatus ,userRole.RoleId ))
|
||||||
|
{
|
||||||
|
throw new Exception("You are not permitted to submit of modify this order");
|
||||||
|
}
|
||||||
|
|
||||||
|
var existingOrder = await GetExistingOrderIdAsync(tc, request.UUID);
|
||||||
|
request.OrderId = (existingOrder != null && existingOrder.OrderId > 0)? existingOrder.OrderId : 0;
|
||||||
|
|
||||||
|
foreach (var item in request.Items)
|
||||||
|
{
|
||||||
|
item.ItemId = 0;
|
||||||
|
item.OrderId = request.OrderId;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GetOrderByUUIDResponse order= await GetOrderByUUIDAsync(tc, request.UUID);
|
// 2. Insert vs update decision
|
||||||
|
bool isUpdate = existingOrder != null && existingOrder.OrderId > 0 ;
|
||||||
|
|
||||||
|
// 3. Reference data - SPs only fetch, every pass/fail call happens here
|
||||||
|
CustomerLookupDto? customer = await GetCustomerAsync(tc, request.CustomerCode);
|
||||||
|
if (customer is null)
|
||||||
|
throw new Exception($"Customer code '{request.CustomerCode}' does not exist.");
|
||||||
|
|
||||||
|
request.CustomerId = customer.CustomerId;
|
||||||
|
|
||||||
|
PaymentTermLookupDto? paymentTerm = await GetPaymentTermAsync(tc, request.PaymentTermCode, request.SalesOrgCode);
|
||||||
|
if (paymentTerm is null)
|
||||||
|
throw new Exception($"Payment term code '{request.PaymentTermCode}' does not exist for sales org '{request.SalesOrgCode}'.");
|
||||||
|
|
||||||
|
|
||||||
tc.End();
|
DiscountLookupDto? discount = await GetDiscountAsync(tc, request.DiscountCode, request.SalesOrgCode);
|
||||||
|
if (discount is null)
|
||||||
|
throw new Exception($"Discount code '{request.DiscountCode}' does not exist.");
|
||||||
|
|
||||||
|
bool focCodeExists = await CheckFocCodeExistsAsync(tc, request.FocCode, request.SalesOrgCode);
|
||||||
|
if (!focCodeExists)
|
||||||
|
throw new Exception($"FOC code '{request.FocCode}' does not exist.");
|
||||||
|
|
||||||
|
if (request.Items is null || request.Items.Count == 0)
|
||||||
|
throw new Exception("Order must contain at least one item.");
|
||||||
|
|
||||||
|
Dictionary<string, MaterialLookupDto> materialsByCode = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
if (request.Items is { Count: > 0 })
|
||||||
|
{
|
||||||
|
List<string> distinctCodes = request.Items
|
||||||
|
.Select(i => i.MaterialCode)
|
||||||
|
.Distinct(StringComparer.OrdinalIgnoreCase)
|
||||||
|
.ToList();
|
||||||
|
|
||||||
|
materialsByCode = await GetMaterialsAsync(tc, distinctCodes);
|
||||||
|
|
||||||
|
foreach (string code in distinctCodes)
|
||||||
|
{
|
||||||
|
if (!materialsByCode.ContainsKey(code))
|
||||||
|
throw new Exception($"Material code '{code}' does not exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var focItem = request.Items.FirstOrDefault(x => x.IsFocItem == true);
|
||||||
|
var dicountItem = request.Items.FirstOrDefault(x => x.DiscountAmount > 0);
|
||||||
|
List<SaveOrderPromotionRequest> promotions = new List<SaveOrderPromotionRequest>();
|
||||||
|
|
||||||
|
request.FocValue = 0;
|
||||||
|
|
||||||
|
promotions.Add(new SaveOrderPromotionRequest()
|
||||||
|
{
|
||||||
|
OrderId = isUpdate ? existingOrder.OrderId : 0,
|
||||||
|
MaterialId = materialsByCode[dicountItem.MaterialCode].MaterialId,
|
||||||
|
PromotionCode =request.DiscountCode ,
|
||||||
|
DiscountPercentage = dicountItem.DiscountPercentage,
|
||||||
|
DiscountValue = dicountItem.DiscountAmount,
|
||||||
|
ForQuantity = dicountItem.PromoQuantity,
|
||||||
|
OrderFocQty = 0,
|
||||||
|
ValidatedFocQty = 0,
|
||||||
|
ApprovedFocQty = 0,
|
||||||
|
PromotionType = 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
promotions.Add(new SaveOrderPromotionRequest()
|
||||||
|
{
|
||||||
|
OrderId = isUpdate ? existingOrder.OrderId : 0,
|
||||||
|
MaterialId = materialsByCode[focItem.MaterialCode].MaterialId,
|
||||||
|
PromotionCode = request.FocCode,
|
||||||
|
DiscountPercentage = 0,
|
||||||
|
DiscountValue = 0,
|
||||||
|
ForQuantity = focItem.PromoQuantity,
|
||||||
|
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,
|
||||||
|
});
|
||||||
|
|
||||||
|
// 5. Insert or update
|
||||||
|
int orderId;
|
||||||
|
if (isUpdate)
|
||||||
|
{
|
||||||
|
orderId = existingOrder.OrderId;
|
||||||
|
await UpdateOrderAsync(tc, orderId, request, customer!, paymentTerm!, discount!, materialsByCode, promotions, userId,(int) userRole!.RoleId);
|
||||||
|
response.IsNewOrder = !isUpdate;
|
||||||
|
response.UUID = request.UUID;
|
||||||
|
response.OrderId = orderId;
|
||||||
|
response.OrderDate = existingOrder.OrderDate;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
response = await InsertOrderAsync(tc, request, customer!, paymentTerm!, discount!, materialsByCode, promotions, userId,(int) userRole!.RoleId);
|
||||||
|
}
|
||||||
|
|
||||||
|
tc.End();
|
||||||
|
}
|
||||||
|
catch (Exception ie)
|
||||||
|
{
|
||||||
|
tc?.HandleError();
|
||||||
|
throw DBCustomError.GenerateCustomError(ie);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch(Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new SaveOrderResponse()
|
return response;
|
||||||
{
|
|
||||||
OrderId = 12345,
|
|
||||||
OrderDate = DateTime.Now,
|
|
||||||
OrderNo = "Ord-000001-" + DateTime.Now.ToString("HH-mm-ss"),
|
|
||||||
UUID = request.UUID,
|
|
||||||
IsNewOrder =true
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<GetOrderByUUIDResponse> GetOrderByUUIDAsync(TransactionContext tc, string uuid)
|
private bool IsPermissiontoModify(OrderStatusEnum orderStatus, UserRoleTypeEnum roleId)
|
||||||
|
{
|
||||||
|
if( UserRoleTypeEnum.OrderCollector == roleId && ( OrderStatusEnum.Draft == orderStatus || OrderStatusEnum.InOrderValidation == orderStatus))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserRoleTypeEnum.OrderValidator == roleId && (OrderStatusEnum.CancelledByValidator == orderStatus || OrderStatusEnum.InOrderApproval == orderStatus))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (UserRoleTypeEnum.OrderApprover == roleId && (OrderStatusEnum.CancelledByApprover == orderStatus || OrderStatusEnum.Approved == orderStatus))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private async Task<GetOrderByUUIDResponse> GetOrderByUUIDAsync(TransactionContext tc, Guid uuid)
|
||||||
{
|
{
|
||||||
GetOrderByUUIDResponse response = null;
|
GetOrderByUUIDResponse response = null;
|
||||||
|
|
||||||
|
|
@ -70,7 +233,6 @@ public class OrderService : IOrderService
|
||||||
|
|
||||||
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetOrderDetailsByUUID", parameterValues: p))
|
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetOrderDetailsByUUID", parameterValues: p))
|
||||||
{
|
{
|
||||||
// Result Set 1: Order Header
|
|
||||||
if (dr.Read())
|
if (dr.Read())
|
||||||
{
|
{
|
||||||
response = new GetOrderByUUIDResponse
|
response = new GetOrderByUUIDResponse
|
||||||
|
|
@ -127,7 +289,7 @@ public class OrderService : IOrderService
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Result Set 3: Promotions (attach to matching item)
|
|
||||||
if (response != null && dr.NextResult())
|
if (response != null && dr.NextResult())
|
||||||
{
|
{
|
||||||
while (dr.Read())
|
while (dr.Read())
|
||||||
|
|
@ -154,7 +316,6 @@ public class OrderService : IOrderService
|
||||||
dr.Close();
|
dr.Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
tc.End();
|
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|
@ -164,4 +325,487 @@ public class OrderService : IOrderService
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<UserRoleDto?> GetUserRoleAsync(TransactionContext tc, int userId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UserId", pType: SqlDbType.Int, pValue: userId)
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetUserRoleByUserId", parameterValues: p);
|
||||||
|
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
return new UserRoleDto { UserId = dr.GetInt32(0), RoleId =(UserRoleTypeEnum) dr.GetInt32(1) };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<OrderBasicResponse?> GetExistingOrderIdAsync(TransactionContext tc, Guid uuid)
|
||||||
|
{
|
||||||
|
OrderBasicResponse response = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UUID", pType: SqlDbType.UniqueIdentifier, pValue: uuid)
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetOrderHeaderByUUID", parameterValues: p);
|
||||||
|
|
||||||
|
if( dr.Read())
|
||||||
|
{
|
||||||
|
response = new OrderBasicResponse()
|
||||||
|
{
|
||||||
|
OrderId = dr.GetInt32(0),
|
||||||
|
OrderNo = dr.GetString(1),
|
||||||
|
OrderDate = dr.GetDateTime(2),
|
||||||
|
UUID = uuid,
|
||||||
|
OrderStatus = (OrderStatusEnum)dr.GetInt32(3)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
dr.Close();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<CustomerLookupDto?> GetCustomerAsync(TransactionContext tc, string customerCode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.VarChar, pValue: customerCode)
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetCustomerByCode", parameterValues: p);
|
||||||
|
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
return new CustomerLookupDto
|
||||||
|
{
|
||||||
|
CustomerId = dr.GetInt32(0),
|
||||||
|
CustomerCode = dr.GetString(1),
|
||||||
|
CustomerName = dr.GetString(2)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<PaymentTermLookupDto?> GetPaymentTermAsync(TransactionContext tc, string paymentTermCode, string salesOrgCode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@PaymentTermCode", pType: SqlDbType.VarChar, pValue: paymentTermCode),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: salesOrgCode)
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetPaymentTermByCode", parameterValues: p);
|
||||||
|
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
return new PaymentTermLookupDto { PaymentTermId = dr.GetInt32(0), PaymentTermCode = dr.GetString(1) };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<DiscountLookupDto?> GetDiscountAsync(TransactionContext tc, string discountCode, string salesOrgCode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@DiscountCode", pType: SqlDbType.VarChar, pValue: discountCode),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: salesOrgCode)
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetDiscountByCode", parameterValues: p);
|
||||||
|
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
return new DiscountLookupDto { DiscountId = dr.GetInt32(0), DiscountCode = dr.GetString(1) };
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<bool> CheckFocCodeExistsAsync(TransactionContext tc, string focCode, string salesOrgCode)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: salesOrgCode),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@FocCode", pType: SqlDbType.VarChar, pValue: focCode)
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.CheckFocCodeExists", parameterValues: p);
|
||||||
|
|
||||||
|
return dr.Read();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<Dictionary<string, MaterialLookupDto>> GetMaterialsAsync(TransactionContext tc, IEnumerable<string> materialCodes)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Dictionary<string, MaterialLookupDto> result = new(StringComparer.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
DataTable codesTable = new();
|
||||||
|
codesTable.Columns.Add("Code", typeof(string));
|
||||||
|
foreach (string code in materialCodes)
|
||||||
|
codesTable.Rows.Add(code);
|
||||||
|
|
||||||
|
SqlParameter codesParam = SqlHelperExtension.CreateInParam(pName: "@Codes", pType: SqlDbType.Structured, pValue: codesTable);
|
||||||
|
codesParam.TypeName = "dbo.CodeListTableType"; // CreateInParam has no TypeName slot, so it's set separately
|
||||||
|
|
||||||
|
SqlParameter[] p = [codesParam];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetMaterialsByCodes", parameterValues: p);
|
||||||
|
|
||||||
|
while (dr.Read())
|
||||||
|
{
|
||||||
|
MaterialLookupDto dto = new()
|
||||||
|
{
|
||||||
|
MaterialId = dr.GetInt32(0),
|
||||||
|
MaterialCode = dr.GetString(1),
|
||||||
|
MaterialName = dr.GetString(2)
|
||||||
|
};
|
||||||
|
|
||||||
|
result[dto.MaterialCode] = dto;
|
||||||
|
}
|
||||||
|
|
||||||
|
dr.Close();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<List<FreeGoodsRuleDto>> GetFreeGoodsRulesAsync(TransactionContext tc, string salesOrgCode, string focCode, IEnumerable<int> materialIds, DateTime? asOfDate, int customerId)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<FreeGoodsRuleDto> rules = new();
|
||||||
|
|
||||||
|
DataTable idsTable = new();
|
||||||
|
idsTable.Columns.Add("Id", typeof(int));
|
||||||
|
foreach (int id in materialIds)
|
||||||
|
idsTable.Rows.Add(id);
|
||||||
|
|
||||||
|
SqlParameter idsParam = SqlHelperExtension.CreateInParam(pName: "@MaterialIds", pType: SqlDbType.Structured, pValue: idsTable);
|
||||||
|
idsParam.TypeName = "dbo.IntListTableType";
|
||||||
|
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: salesOrgCode),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@CustomerId", pType: SqlDbType.VarChar, pValue: customerId),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@FocCode", pType: SqlDbType.VarChar, pValue: focCode),idsParam,
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@AsOfDate", pType: SqlDbType.DateTime, pValue: DateTime.Now)
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetFreeGoodsRules", parameterValues: p);
|
||||||
|
|
||||||
|
while (dr.Read())
|
||||||
|
{
|
||||||
|
rules.Add(new FreeGoodsRuleDto
|
||||||
|
{
|
||||||
|
FreeGoodsId = dr.GetInt32(0),
|
||||||
|
MaterialId = dr.GetInt32(1),
|
||||||
|
MinOrderQuantity = dr.GetDecimal(2),
|
||||||
|
ForQuantity = dr.GetDecimal(3),
|
||||||
|
FreeQuantity = dr.GetDecimal(4),
|
||||||
|
UnitOfMeasure = dr.IsDBNull(5) ? string.Empty : dr.GetString(5),
|
||||||
|
FocUnitOfMeasure = dr.IsDBNull(6) ? string.Empty : dr.GetString(6)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
dr.Close();
|
||||||
|
return rules;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once OrderQuantity >= MinOrderQuantity, the material earns FreeQuantity for every
|
||||||
|
// ForQuantity units ordered (e.g. Min 10 / For 10 / Free 1 -> ordering 25 = floor(25/10)*1 = 2 free).
|
||||||
|
// This is my read of "calculate based on order quantity" - swap the formula below if yours differs.
|
||||||
|
private static List<SaveOrderPromotionRequest> BuildFocPromotions(SaveOrderRequest request,
|
||||||
|
Dictionary<string, MaterialLookupDto> materialsByCode,List<FreeGoodsRuleDto> focRules)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
List<SaveOrderPromotionRequest> promotions = new();
|
||||||
|
|
||||||
|
Dictionary<int, FreeGoodsRuleDto> rulesByMaterialId = focRules
|
||||||
|
.GroupBy(r => r.MaterialId)
|
||||||
|
.ToDictionary(g => g.Key, g => g.First()); // first active rule wins if more than one overlaps
|
||||||
|
|
||||||
|
foreach (SaveOrderItemRequest item in request.Items)
|
||||||
|
{
|
||||||
|
if (item.IsFocItem)
|
||||||
|
continue; // a free item doesn't itself trigger more free goods
|
||||||
|
|
||||||
|
if (!materialsByCode.TryGetValue(item.MaterialCode, out MaterialLookupDto? material))
|
||||||
|
continue; // already caught by validation - guarded here defensively
|
||||||
|
|
||||||
|
if (!rulesByMaterialId.TryGetValue(material.MaterialId, out FreeGoodsRuleDto? rule))
|
||||||
|
continue; // no free-goods rule configured for this material under this FOC code
|
||||||
|
|
||||||
|
if (rule.ForQuantity <= 0 || item.OrderQuantity < rule.MinOrderQuantity)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
decimal eligibleSets = Math.Floor(item.OrderQuantity / rule.ForQuantity);
|
||||||
|
decimal focQuantity = eligibleSets * rule.FreeQuantity;
|
||||||
|
|
||||||
|
if (focQuantity <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
promotions.Add(new SaveOrderPromotionRequest
|
||||||
|
{
|
||||||
|
MaterialId = material.MaterialId,
|
||||||
|
PromotionCode = request.FocCode,
|
||||||
|
DiscountPercentage = 0,
|
||||||
|
DiscountValue = 0,
|
||||||
|
ForQuantity = rule.ForQuantity,
|
||||||
|
OrderFocQty = focQuantity,
|
||||||
|
ValidatedFocQty = 0,
|
||||||
|
ApprovedFocQty = 0,
|
||||||
|
PromotionType = 1 // TODO: swap for your real "free goods" PromotionType constant
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return promotions;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DataTable ToOrderItemTable(IEnumerable<SaveOrderItemRequest> items, Dictionary<string, MaterialLookupDto> materialsByCode, int orderStatus )
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DataTable table = new();
|
||||||
|
table.Columns.Add("OrderId", typeof(int));
|
||||||
|
table.Columns.Add("ItemId", typeof(int));
|
||||||
|
table.Columns.Add("MaterialId", typeof(int));
|
||||||
|
table.Columns.Add("MaterialCode", typeof(string));
|
||||||
|
table.Columns.Add("MaterialName", typeof(string));
|
||||||
|
table.Columns.Add("UnitPrice", typeof(decimal));
|
||||||
|
table.Columns.Add("SalesUnit", typeof(string));
|
||||||
|
table.Columns.Add("PromoQty", typeof(decimal));
|
||||||
|
table.Columns.Add("OrderQuantity", typeof(decimal));
|
||||||
|
table.Columns.Add("ValidatedQuantity", typeof(decimal));
|
||||||
|
table.Columns.Add("ApprovedQuantity", typeof(decimal));
|
||||||
|
table.Columns.Add("DiscountPercentage", typeof(decimal));
|
||||||
|
table.Columns.Add("DiscountAmount", typeof(decimal));
|
||||||
|
table.Columns.Add("IsFocItem", typeof(bool));
|
||||||
|
table.Columns.Add("LineTotalValue", typeof(decimal));
|
||||||
|
table.Columns.Add("OrderStatus", typeof(int));
|
||||||
|
|
||||||
|
foreach (SaveOrderItemRequest item in items)
|
||||||
|
{
|
||||||
|
MaterialLookupDto material = materialsByCode[item.MaterialCode];
|
||||||
|
|
||||||
|
table.Rows.Add(
|
||||||
|
item.ItemId,
|
||||||
|
item.OrderId,
|
||||||
|
material.MaterialId,
|
||||||
|
item.MaterialCode,
|
||||||
|
item.MaterialName ?? material.MaterialName,
|
||||||
|
item.UnitPrice,
|
||||||
|
item.SalesUnit,
|
||||||
|
item.PromoQuantity,
|
||||||
|
item.OrderQuantity,
|
||||||
|
item.ValidatedQuantity,
|
||||||
|
item.ApprovedQuantity,
|
||||||
|
item.DiscountPercentage,
|
||||||
|
item.DiscountAmount,
|
||||||
|
item.IsFocItem,
|
||||||
|
item.LineTotalValue,
|
||||||
|
orderStatus);
|
||||||
|
}
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DataTable ToOrderPromotionTable(IEnumerable<SaveOrderPromotionRequest> promotions)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
DataTable table = new();
|
||||||
|
table.Columns.Add("ItemId", typeof(int));
|
||||||
|
table.Columns.Add("OrderId", typeof(int));
|
||||||
|
table.Columns.Add("MaterialId", typeof(int));
|
||||||
|
table.Columns.Add("PromotionCode", typeof(string));
|
||||||
|
table.Columns.Add("DiscountPercentage", typeof(decimal));
|
||||||
|
table.Columns.Add("DiscountValue", typeof(decimal));
|
||||||
|
table.Columns.Add("ForQuantity", typeof(decimal));
|
||||||
|
table.Columns.Add("OrderFocQty", typeof(decimal));
|
||||||
|
table.Columns.Add("ValidatedFocQty", typeof(decimal));
|
||||||
|
table.Columns.Add("ApprovedFocQty", typeof(decimal));
|
||||||
|
table.Columns.Add("PromotionType", typeof(int));
|
||||||
|
|
||||||
|
foreach (SaveOrderPromotionRequest promo in promotions)
|
||||||
|
{
|
||||||
|
table.Rows.Add(
|
||||||
|
promo.ItemId,
|
||||||
|
promo.OrderId,
|
||||||
|
promo.MaterialId,
|
||||||
|
promo.PromotionCode ,
|
||||||
|
promo.DiscountPercentage,
|
||||||
|
promo.DiscountValue,
|
||||||
|
promo.ForQuantity,
|
||||||
|
promo.OrderFocQty,
|
||||||
|
promo.ValidatedFocQty,
|
||||||
|
promo.ApprovedFocQty,
|
||||||
|
promo.PromotionType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return table;
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task<SaveOrderResponse> InsertOrderAsync(TransactionContext tc, SaveOrderRequest request, CustomerLookupDto customer, PaymentTermLookupDto paymentTerm,
|
||||||
|
DiscountLookupDto discount, Dictionary<string, MaterialLookupDto> materialsByCode,
|
||||||
|
List<SaveOrderPromotionRequest> promotions, int userId, int role)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter itemsParam = SqlHelperExtension.CreateInParam(pName: "@Items", pType: SqlDbType.Structured, pValue: ToOrderItemTable(request.Items, materialsByCode, (int)request.OrderStatus));
|
||||||
|
itemsParam.TypeName = "dbo.OrderItemTableType";
|
||||||
|
|
||||||
|
SqlParameter promotionsParam = SqlHelperExtension.CreateInParam(pName: "@Promotions", pType: SqlDbType.Structured, pValue: ToOrderPromotionTable(promotions));
|
||||||
|
promotionsParam.TypeName = "dbo.OrderPromotionTableType";
|
||||||
|
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@UUID", pType: SqlDbType.UniqueIdentifier, pValue: request.UUID),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@OrderNo", pType: SqlDbType.VarChar, pValue: request.OrderNo),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@OrderDate", pType: SqlDbType.DateTime, pValue: request.OrderDate ?? DateTime.Now ),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@ExpectedDeliveryDate", pType: SqlDbType.DateTime, pValue: request.ExpectedDeliveryDate ),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.VarChar, pValue: request.SalesOrgCode),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@CustomerId", pType: SqlDbType.Int, pValue: customer.CustomerId),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.VarChar, pValue: request.CustomerCode),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@CustomerName", pType: SqlDbType.VarChar, pValue: request.CustomerName),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@EmployeeId", pType: SqlDbType.Int, pValue: request.EmployeeId ),
|
||||||
|
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: "@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),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@FOCValue", pType: SqlDbType.Decimal, pValue: request.FocCode),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@NetValue", pType: SqlDbType.Decimal, pValue: request.NetValue),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@OrderStatus", pType: SqlDbType.Int, pValue: (int)request.OrderStatus),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@SapRefferenceOrderNo", pType: SqlDbType.NVarChar, pValue: null),
|
||||||
|
itemsParam,
|
||||||
|
promotionsParam
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.InsertOrder", parameterValues: p);
|
||||||
|
|
||||||
|
int newOrderId = 0;
|
||||||
|
string orderNo = string.Empty;
|
||||||
|
if (dr.Read())
|
||||||
|
{
|
||||||
|
newOrderId = dr.GetInt32(0);
|
||||||
|
orderNo = dr.GetString(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
dr.Close();
|
||||||
|
return new SaveOrderResponse() { IsNewOrder=true, OrderDate= DateTime.Now, OrderId= newOrderId,OrderNo =orderNo,UUID = request.UUID};
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task UpdateOrderAsync(TransactionContext tc, int orderId, SaveOrderRequest request, CustomerLookupDto customer, PaymentTermLookupDto paymentTerm,
|
||||||
|
DiscountLookupDto discount, Dictionary<string, MaterialLookupDto> materialsByCode,
|
||||||
|
List<SaveOrderPromotionRequest> promotions, int userId, int role)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
SqlParameter itemsParam = SqlHelperExtension.CreateInParam(pName: "@Items", pType: SqlDbType.Structured, pValue: ToOrderItemTable(request.Items, materialsByCode, (int)request.OrderStatus));
|
||||||
|
itemsParam.TypeName = "dbo.OrderItemTableType";
|
||||||
|
|
||||||
|
SqlParameter promotionsParam = SqlHelperExtension.CreateInParam(pName: "@Promotions", pType: SqlDbType.Structured, pValue: ToOrderPromotionTable(promotions));
|
||||||
|
promotionsParam.TypeName = "dbo.OrderPromotionTableType";
|
||||||
|
|
||||||
|
SqlParameter[] p =
|
||||||
|
[
|
||||||
|
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: "@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),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@FOCValue", pType: SqlDbType.Decimal, pValue: request.FocCode),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@NetValue", pType: SqlDbType.Decimal, pValue: request.NetValue),
|
||||||
|
SqlHelperExtension.CreateInParam(pName: "@OrderStatus", pType: SqlDbType.Int, pValue: (int)request.OrderStatus),
|
||||||
|
itemsParam,
|
||||||
|
promotionsParam
|
||||||
|
];
|
||||||
|
|
||||||
|
using IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.UpdateOrder", parameterValues: p);
|
||||||
|
dr.Close();
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Configuration.DI
|
||||||
{
|
{
|
||||||
if (services == null)
|
if (services == null)
|
||||||
return;
|
return;
|
||||||
|
services.AddSingleton<IEaseCache, EaseCache>();
|
||||||
services.AddSingleton<IEaseCache, EaseCache>();
|
|
||||||
services.AddTransient<IUserService, UserService>();
|
services.AddTransient<IUserService, UserService>();
|
||||||
services.AddTransient<IParamTypeService, ParamTypeService>();
|
services.AddTransient<IParamTypeService, ParamTypeService>();
|
||||||
services.AddTransient<IThisSystemService, ThisSystemService>();
|
services.AddTransient<IThisSystemService, ThisSystemService>();
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ 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.Integrations;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.MobileApp;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models.Responses.Systems;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Auth;
|
||||||
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
|
using OnlineSalesAutoCrop.CoreAPI.Services.Contracts.Systems;
|
||||||
using System;
|
using System;
|
||||||
|
|
@ -130,7 +131,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers
|
||||||
[
|
[
|
||||||
Helper.CreateClaim("LoginId", loginReponse.LoginId),
|
Helper.CreateClaim("LoginId", loginReponse.LoginId),
|
||||||
Helper.CreateClaim("Email", loginReponse.Email),
|
Helper.CreateClaim("Email", loginReponse.Email),
|
||||||
Helper.CreateClaim("Mobile", $"{loginReponse.MobileNumber}"),
|
Helper.CreateClaim("UserId", $"{loginReponse.UserId}"),
|
||||||
Helper.CreateClaim("HashKey", Guid.NewGuid().ToString())
|
Helper.CreateClaim("HashKey", Guid.NewGuid().ToString())
|
||||||
]),
|
]),
|
||||||
Expires = DateTime.UtcNow.AddMinutes(_appSettings.AccessTokenDuration),
|
Expires = DateTime.UtcNow.AddMinutes(_appSettings.AccessTokenDuration),
|
||||||
|
|
@ -208,7 +209,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers
|
||||||
[
|
[
|
||||||
Helper.CreateClaim("LoginId", userRefreshToken.LoginId),
|
Helper.CreateClaim("LoginId", userRefreshToken.LoginId),
|
||||||
Helper.CreateClaim("Email", userRefreshToken.EmailAddress),
|
Helper.CreateClaim("Email", userRefreshToken.EmailAddress),
|
||||||
Helper.CreateClaim("AuthKey", $"{userRefreshToken.AuthKey}"),
|
Helper.CreateClaim("UserId", $"{userRefreshToken.UserId}"),
|
||||||
Helper.CreateClaim("HashKey", Guid.NewGuid().ToString())
|
Helper.CreateClaim("HashKey", Guid.NewGuid().ToString())
|
||||||
]),
|
]),
|
||||||
Expires = DateTime.UtcNow.AddHours(12),
|
Expires = DateTime.UtcNow.AddHours(12),
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using OnlineSalesAutoCrop.CoreAPI.Models;
|
||||||
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;
|
||||||
|
|
@ -54,7 +55,8 @@ public class OrdersController(IOrderService service, IOptions<AppSettings> appSe
|
||||||
SaveOrderResponse response = new();
|
SaveOrderResponse response = new();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
response = await _service.SaveOrderAsync(request);
|
int userId = HttpContext.User.GetClaimValue<int>(Constants.UserId);
|
||||||
|
response = await _service.SaveOrderAsync(request, userId);
|
||||||
return Ok(MobileResponseBase<SaveOrderResponse>.Success(response));
|
return Ok(MobileResponseBase<SaveOrderResponse>.Success(response));
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user