feedback of UAT
This commit is contained in:
parent
68cf33d5a6
commit
0529139358
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -21,3 +21,4 @@ obj
|
|||
/App/ClientApp/node_modules
|
||||
/Api/OnlineSalesAutoCrop.CoreAPI/.config/dotnet-tools.json
|
||||
/App/ClientApp/.angular/cache/21.2.13/OnlineSalesAutoCropApp
|
||||
/Deployment/App/browser
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.Common;
|
|||
|
||||
public class AuthLoginRequest
|
||||
{
|
||||
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "Login Id must be between 3 and 10 characters.")]
|
||||
[Required, NotNull, StringLength(maximumLength: 15, MinimumLength = 3, ErrorMessage = "Login Id must be between 3 and 15 characters.")]
|
||||
public string LoginId { get; set; }
|
||||
|
||||
[Required, NotNull, StringLength(maximumLength: 20, MinimumLength = 5, ErrorMessage = "Password must be between 5 and 20 characters.")]
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ public class IntegrationEmployeeRequest
|
|||
[Phone(ErrorMessage = "Mobile number is not a valid phone number.")]
|
||||
public string MobileNo { get; set; }
|
||||
|
||||
[Required(ErrorMessage = "Email address is required.")]
|
||||
[StringLength(241, ErrorMessage = "Email address cannot exceed 241 characters.")]
|
||||
[EmailAddress(ErrorMessage = "Email address is not valid.")]
|
||||
public string Mail { get; set; }
|
||||
|
|
|
|||
|
|
@ -8,85 +8,85 @@ namespace OnlineSalesAutoCrop.CoreAPI.Models.Requests.MobileApp;
|
|||
|
||||
public class GetMarketHeirarchyByEmpRequest
|
||||
{
|
||||
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 10 characters.")]
|
||||
[Required, NotNull, StringLength(maximumLength: 12, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 12 characters.")]
|
||||
public string EmployeeNumber { get; set; }
|
||||
}
|
||||
|
||||
public class GetBrandsRequest : PagedRequest
|
||||
{
|
||||
[StringLength(6, MinimumLength = 1, ErrorMessage = "Brand code must be between 1 and 6 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Brand code must be between 1 and 15 characters.")]
|
||||
public string? BrandCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string? SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 15 characters.")]
|
||||
public string? EmployeeNumber { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetMaterialsRequest : PagedRequest
|
||||
{
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(6, MinimumLength = 1, ErrorMessage = "Brand code must be between 1 and 6 characters.")]
|
||||
public string? BrandCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Material Code must be between 1 and 15 characters.")]
|
||||
public string? MaterialCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 15 characters.")]
|
||||
public string? EmployeeNumber { get; set; }
|
||||
}
|
||||
|
||||
public class GetMaterialStockRequest : PagedRequest
|
||||
{
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Plant Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Plant Code must be between 1 and 15 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.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(6, MinimumLength = 1, ErrorMessage = "Brand code must be between 1 and 6 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Brand code must be between 1 and 15 characters.")]
|
||||
public string? BrandCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Material Code must be between 1 and 15 characters.")]
|
||||
public string? MaterialCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Employee number must be between 1 and 15 characters.")]
|
||||
public string? EmployeeNumber { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class GetCustomersRequest : PagedRequest
|
||||
{
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(5, MinimumLength = 3, ErrorMessage = "Teritory Code must be between 1 and 5 characters.")]
|
||||
public string? TeritoryCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 15 characters.")]
|
||||
public string? CustomerCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 15 characters.")]
|
||||
public string? EmployeeNumber { get; set; }
|
||||
}
|
||||
|
||||
public class GetAttendanceByEmpRequest
|
||||
{
|
||||
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 10 characters.")]
|
||||
[Required, NotNull, StringLength(maximumLength: 15, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 15 characters.")]
|
||||
public string EmployeeNumber { get; set; }
|
||||
public DateTime? AttendanceDate { get; set; }
|
||||
}
|
||||
|
||||
public class UpsertAttendanceByEmpRequest
|
||||
{
|
||||
[Required, NotNull, StringLength(maximumLength: 10, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 10 characters.")]
|
||||
[Required, NotNull, StringLength(maximumLength: 15, MinimumLength = 3, ErrorMessage = "EmployeeNumber must be between 3 and 15 characters.")]
|
||||
public string EmployeeNumber { get; set; }
|
||||
public TimeSpan? CheckInTime { get; set; }
|
||||
public string? CheckInLatitude { get; set; }
|
||||
|
|
@ -102,37 +102,37 @@ public class UpsertAttendanceByEmpRequest
|
|||
|
||||
public class GetDiscountRequest : PagedRequest
|
||||
{
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 15 characters.")]
|
||||
public string? CustomerCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 15 characters.")]
|
||||
public string? EmployeeNumber { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 15 characters.")]
|
||||
public string? MaterialCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 15 characters.")]
|
||||
public string? DiscountCode { get; set; }
|
||||
}
|
||||
|
||||
public class GetDiscountMaterialRequest : PagedRequest
|
||||
{
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 15 characters.")]
|
||||
public string? CustomerCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 15 characters.")]
|
||||
public string? EmployeeNumber { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 15 characters.")]
|
||||
public string? MaterialCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 15 characters.")]
|
||||
public string? DiscountCode { get; set; }
|
||||
}
|
||||
|
||||
|
|
@ -140,46 +140,46 @@ public class GetDiscountMaterialRequest : PagedRequest
|
|||
|
||||
public class GetFOCRequest : PagedRequest
|
||||
{
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 15 characters.")]
|
||||
public string? CustomerCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 15 characters.")]
|
||||
public string? EmployeeNumber { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 15 characters.")]
|
||||
public string? MaterialCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 15 characters.")]
|
||||
public string? FOCCode { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class GetFOCMaterialRequest : PagedRequest
|
||||
{
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Customer Code must be between 1 and 15 characters.")]
|
||||
public string? CustomerCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 5, ErrorMessage = "Employee number must be between 1 and 15 characters.")]
|
||||
public string? EmployeeNumber { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Material Code must be between 1 and 15 characters.")]
|
||||
public string? MaterialCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 1, ErrorMessage = "Discount Code must be between 1 and 15 characters.")]
|
||||
public string? FOCCode { get; set; }
|
||||
}
|
||||
|
||||
public class GetPaymentTermRequest : PagedRequest
|
||||
{
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "Sales organization code must be between 1 and 15 characters.")]
|
||||
public string SalesOrgCode { get; set; }
|
||||
|
||||
[StringLength(10, MinimumLength = 3, ErrorMessage = "PayementTerm Code must be between 3 and 10 characters.")]
|
||||
[StringLength(15, MinimumLength = 3, ErrorMessage = "PayementTerm Code must be between 3 and 15 characters.")]
|
||||
public string? PaymentTermCode { get; set; }
|
||||
}
|
||||
|
|
@ -41,6 +41,8 @@ public class GetSalesOrderResponse
|
|||
public decimal? TotalVatValue { get; set; }
|
||||
public decimal NetValue { get; set; }
|
||||
public int OrderStatus { get; set; }
|
||||
public string BillingNumber { get; set; }
|
||||
public DateTime? BillingDate { get; set; }
|
||||
|
||||
public List<GetSalesOrderItemResponse> Items { get; set; } = new();
|
||||
}
|
||||
|
|
@ -91,6 +93,9 @@ public sealed class CustomerLookupDto
|
|||
public int CustomerId { get; set; }
|
||||
public string CustomerCode { get; set; } = string.Empty;
|
||||
public string CustomerName { get; set; } = string.Empty;
|
||||
public bool IsCreditCustomer { get; set; } = false;
|
||||
public string CompanyCode { get; set; }
|
||||
public decimal CreditLimit { get; set; }
|
||||
}
|
||||
|
||||
public sealed class PaymentTermLookupDto
|
||||
|
|
|
|||
|
|
@ -171,7 +171,18 @@ public class IntegrationService : IIntegrationService
|
|||
|
||||
await AddUserAsync(tc, appUser);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppUserCreateRequest appUser = new()
|
||||
{
|
||||
MobileNo = request.MobileNo,
|
||||
EmailAddress = request.Mail,
|
||||
UserRoleType = roleTypeId,
|
||||
EmployeeNumber = request.EmployeeVendorCode
|
||||
};
|
||||
|
||||
await UpdateUserRoleAsync(tc, appUser);
|
||||
}
|
||||
response.EmployeeVendorCode = request.EmployeeVendorCode;
|
||||
response.CompanyCode = request.CompanyCode;
|
||||
tc.End();
|
||||
|
|
@ -820,6 +831,39 @@ public class IntegrationService : IIntegrationService
|
|||
}
|
||||
|
||||
|
||||
public async Task<bool> UpdateUserRoleAsync(TransactionContext tc, AppUserCreateRequest user)
|
||||
{
|
||||
bool returnValue;
|
||||
try
|
||||
{
|
||||
int userId = 0;
|
||||
user.Password = EncryptPassword(password: user.Password);
|
||||
|
||||
if (!string.IsNullOrEmpty(user.EmailAddress))
|
||||
user.EmailAddress = user.EmailAddress.Replace(" ", "");
|
||||
|
||||
|
||||
SqlParameter[] p =
|
||||
[
|
||||
SqlHelperExtension.CreateInParam(pName: "@MobileNo", pType: SqlDbType.VarChar, pValue: DataReader.GetNullValue(user.MobileNo), size: 20),
|
||||
SqlHelperExtension.CreateInParam(pName: "@EmailAddress", pType: SqlDbType.VarChar, pValue: user.EmailAddress, size: 200),
|
||||
SqlHelperExtension.CreateInParam(pName: "@UserRoleType", pType: SqlDbType.Int, pValue: DataReader.GetNullValue(user.UserRoleType)),
|
||||
SqlHelperExtension.CreateInParam(pName: "@EmployeeNumber", pType: SqlDbType.VarChar, pValue: DataReader.GetNullValue(user.EmployeeNumber), size: 10),
|
||||
SqlHelperExtension.CreateOutParam(pName:"@NewUserId", pType: SqlDbType.Int)
|
||||
];
|
||||
|
||||
_ = tc.ExecuteNonQuerySp(spName: "dbo.UpdateUserRole", parameterValues: p);
|
||||
|
||||
returnValue = true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new InvalidOperationException(e.Message, e);
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
private string EncryptPassword(string password)
|
||||
{
|
||||
try
|
||||
|
|
|
|||
|
|
@ -275,6 +275,7 @@ public class MobileMasterDataService : IMobileMasterDataService
|
|||
public async Task<PagedResult<GetCustomerResponse>> GetCustomersAsync(GetCustomersRequest request)
|
||||
{
|
||||
string companyCode = string.Empty;
|
||||
string salesOrgCode = string.Empty;
|
||||
decimal usedCreditBalance = 0;
|
||||
PagedResult<GetCustomerResponse> response = new();
|
||||
try
|
||||
|
|
@ -307,7 +308,7 @@ public class MobileMasterDataService : IMobileMasterDataService
|
|||
DivisionCode = dr.GetString(6),
|
||||
DivisionName = dr.GetString(7),
|
||||
MobileNumber = dr.GetString(8),
|
||||
EmailAddress = dr.GetString(9),
|
||||
EmailAddress = dr.IsDBNull(9) ? null : dr.GetString(9),
|
||||
TaxNumber = dr.GetString(10),
|
||||
SalesGroupCode = dr.IsDBNull(11)? null : dr.GetString(11),
|
||||
SalesGroupName = dr.IsDBNull(12) ? null : dr.GetString(12),
|
||||
|
|
@ -325,6 +326,7 @@ public class MobileMasterDataService : IMobileMasterDataService
|
|||
CreditOverdue = dr.GetDecimal(24),
|
||||
});
|
||||
companyCode = dr.GetString(25);
|
||||
salesOrgCode = dr.GetString(19);
|
||||
}
|
||||
dr.Close();
|
||||
|
||||
|
|
@ -335,7 +337,7 @@ public class MobileMasterDataService : IMobileMasterDataService
|
|||
|
||||
if (!string.IsNullOrWhiteSpace(request.CustomerCode))
|
||||
{
|
||||
usedCreditBalance = await GetCurrentApprovedOrderAmountByCustomerAsync(tc, request.CustomerCode, request.SalesOrgCode);
|
||||
usedCreditBalance = await GetCurrentApprovedOrderAmountByCustomerAsync(tc, request.CustomerCode, salesOrgCode);
|
||||
}
|
||||
|
||||
tc.End();
|
||||
|
|
@ -349,7 +351,7 @@ public class MobileMasterDataService : IMobileMasterDataService
|
|||
{
|
||||
response.Items = response.Items.Select(x =>
|
||||
{
|
||||
x.CreditBalance = (customerLedger.CurrentBalance - usedCreditBalance);
|
||||
x.CreditBalance = (customerLedger.CurrentBalance + usedCreditBalance);
|
||||
x.CreditOverdue = customerLedger.OverdueAmount;
|
||||
return x;
|
||||
}).ToList();
|
||||
|
|
@ -481,9 +483,9 @@ public class MobileMasterDataService : IMobileMasterDataService
|
|||
response.Add(new DistibutionChannleResponse
|
||||
{
|
||||
CompanyCode = dr.GetString(0),
|
||||
SalesOrgCode = dr.GetString(1),
|
||||
DistributorChannelCode = dr.GetString(2),
|
||||
DistributorChannelName = dr.GetString(3)
|
||||
SalesOrgCode = dr.IsDBNull(1) ? null: dr.GetString(1),
|
||||
DistributorChannelCode = dr.IsDBNull(2) ? null : dr.GetString(2),
|
||||
DistributorChannelName = dr.IsDBNull(3) ? null : dr.GetString(3)
|
||||
});
|
||||
}
|
||||
dr.Close();
|
||||
|
|
|
|||
|
|
@ -175,6 +175,21 @@ public class OrderService : IOrderService
|
|||
});
|
||||
}
|
||||
|
||||
decimal usedCreditBalance = await GetCurrentApprovedOrderAmountByCustomerAsync(tc, request.CustomerCode, request.SalesOrgCode);
|
||||
|
||||
|
||||
if (request.OrderStatus == OrderStatusEnum.Approved && customer.IsCreditCustomer && request.PaymentTermCode != "0001")
|
||||
{
|
||||
var customerLedger = await _httpService.GetCustomerLedgerAsync(request.CustomerCode, customer.CompanyCode);
|
||||
|
||||
var creditBalance = customer.CreditLimit- (customerLedger.CurrentBalance + usedCreditBalance);
|
||||
|
||||
if(creditBalance < request.NetValue)
|
||||
{
|
||||
throw new Exception("Credit Limit is extend for this customer");
|
||||
}
|
||||
}
|
||||
|
||||
// 5. Insert or update
|
||||
int orderId;
|
||||
if (isUpdate)
|
||||
|
|
@ -208,6 +223,33 @@ public class OrderService : IOrderService
|
|||
return response;
|
||||
}
|
||||
|
||||
private async Task<decimal> GetCurrentApprovedOrderAmountByCustomerAsync(TransactionContext tc, string customerCode, string salesOrgCode)
|
||||
{
|
||||
decimal totalApprovedAmount = 0;
|
||||
try
|
||||
{
|
||||
SqlParameter[] p =
|
||||
[
|
||||
SqlHelperExtension.CreateInParam(pName: "@CustomerCode", pType: SqlDbType.NVarChar, pValue: customerCode),
|
||||
SqlHelperExtension.CreateInParam(pName: "@SalesOrgCode", pType: SqlDbType.NVarChar, pValue: salesOrgCode),
|
||||
];
|
||||
using (IDataReader dr = await tc.ExecuteReaderSpAsync("dbo.GetCustomerApprovedAmount", p))
|
||||
{
|
||||
if (dr.Read())
|
||||
{
|
||||
totalApprovedAmount = dr.GetDecimal(0);
|
||||
}
|
||||
dr.Close();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw;
|
||||
}
|
||||
|
||||
return totalApprovedAmount;
|
||||
}
|
||||
|
||||
private bool IsPermissiontoModify(OrderStatusEnum orderStatus, UserRoleTypeEnum roleId)
|
||||
{
|
||||
if( UserRoleTypeEnum.OrderCollector == roleId && ( OrderStatusEnum.Draft == orderStatus || OrderStatusEnum.InOrderValidation == orderStatus))
|
||||
|
|
@ -308,7 +350,10 @@ public class OrderService : IOrderService
|
|||
{
|
||||
CustomerId = dr.GetInt32(0),
|
||||
CustomerCode = dr.GetString(1),
|
||||
CustomerName = dr.GetString(2)
|
||||
CustomerName = dr.GetString(2),
|
||||
IsCreditCustomer = dr.GetInt32(3) > 0,
|
||||
CompanyCode = dr.GetString(4),
|
||||
CreditLimit = dr.IsDBNull(5)? 0 : dr.GetDecimal(5)
|
||||
};
|
||||
}
|
||||
|
||||
|
|
@ -777,7 +822,9 @@ public class OrderService : IOrderService
|
|||
GrossValue = dr.GetDecimal(13),
|
||||
NetValue = dr.GetDecimal(14),
|
||||
OrderStatus = dr.GetInt32(15),
|
||||
TotalVatValue = dr.IsDBNull(17)? null: dr.GetDecimal(17)
|
||||
TotalVatValue = dr.IsDBNull(17) ? null: dr.GetDecimal(17),
|
||||
BillingNumber =dr.IsDBNull(18) ? null : dr.GetString(18),
|
||||
BillingDate =dr.IsDBNull(19) ? null : dr.GetDateTime(19)
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
using System;
|
||||
using System.DirectoryServices;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using System.IO;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
|
|
@ -309,6 +310,25 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers
|
|||
return Ok();
|
||||
}
|
||||
|
||||
|
||||
[AllowAnonymous]
|
||||
[HttpGet("download")]
|
||||
public IActionResult Download()
|
||||
{
|
||||
string fileName = "AutoCropCare.apk";
|
||||
var filePath = Path.Combine(@"D:\Local", fileName);
|
||||
|
||||
if (!System.IO.File.Exists(filePath))
|
||||
return NotFound();
|
||||
|
||||
return PhysicalFile(
|
||||
filePath,
|
||||
"application/octet-stream",
|
||||
fileName,
|
||||
enableRangeProcessing: true
|
||||
);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -611,6 +611,7 @@ namespace OnlineSalesAutoCrop.CoreAPI.Controllers.Web
|
|||
/// <returns></returns>
|
||||
[ValidateSession]
|
||||
[HttpPost("uploadPasswords")]
|
||||
[AllowAnonymous]
|
||||
[ProducesResponseType(StatusCodes.Status200OK, Type = typeof(BulkPasswordUploadResponse))]
|
||||
public async Task<IActionResult> UploadPasswords([FromForm] BulkPasswordUploadRequest request)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ public class NullableDecimalConverter : JsonConverter<decimal?>
|
|||
|
||||
if (reader.TokenType == JsonTokenType.Number)
|
||||
{
|
||||
var value = reader.GetInt32();
|
||||
var value = reader.GetDecimal();
|
||||
return value == 0 ? null : value;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ using Microsoft.AspNetCore.HttpOverrides;
|
|||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.FileProviders;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@ const routes: Routes = [
|
|||
{ path: 'newuser', loadComponent: () => import('./users/newuser.component').then(m => m.NewUserComponent), canActivate: [AuthGuard], data: { permissionKey: 'ELIT.1.2.2_1' } },
|
||||
{ path: 'edituser', loadComponent: () => import('./users/edituser.component').then(m => m.EditUserComponent), canActivate: [AuthGuard], data: { permissionKey: 'ELIT.1.2.2_2' } },
|
||||
{ path: 'resetPwd', loadComponent: () => import('./users/resetpwd.component').then(m => m.ResetPwdComponent), canActivate: [AuthGuard], data: { permissionKey: 'ELIT.1.2.3,ELIT.1.2.3_1,ELIT.1.2.3_2' } },
|
||||
{ path: 'uploadPwd', loadComponent: () => import('./users/uploadpwd.component').then(m => m.UploadPwdComponent), canActivate: [AuthGuard], data: { permissionKey: 'ELIT.1.2.3,ELIT.1.2.3_2' } },
|
||||
{ path: 'forcelogout', loadComponent: () => import('./forcelogout/forcelogout.component').then(m => m.ForceLogoutComponent), canActivate: [AuthGuard], data: { permissionKey: 'ELIT.1.2.4,ELIT.1.2.4_1,ELIT.1.2.4_2,ELIT.1.2.4_3' } },
|
||||
|
||||
//Landing Page
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ export const MENU_DEFINITION: MenuNode[] =
|
|||
[
|
||||
{ moduleId: 'ELIT.1.2.1', label: 'Groups', icon: 'fa fa-address-book-o', routerLink: 'groups' },
|
||||
{ moduleId: 'ELIT.1.2.2', label: 'Users', icon: 'fa fa-address-card-o', routerLink: 'users' },
|
||||
{ moduleId: 'ELIT.1.2.3', label: 'Upload Passwords', icon: 'fa fa-upload', routerLink: 'uploadPwd' },
|
||||
{ moduleId: 'ELIT.1.2.4', label: 'Force Logout', icon: 'fa fa-address-card-o', routerLink: 'forcelogout' }
|
||||
]
|
||||
},
|
||||
|
|
|
|||
58
App/ClientApp/src/app/users/uploadpwd.component.html
Normal file
58
App/ClientApp/src/app/users/uploadpwd.component.html
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
<form [formGroup]="uploadPwdForm" (ngSubmit)="onSubmit()">
|
||||
<div class="mb-2">
|
||||
<span>Excel file must have <b>EmployeeCode</b> and <b>Password</b> columns in the first row.</span>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 row g-0">
|
||||
<span class="required">Excel File:</span>
|
||||
<br />
|
||||
<div class="col-lg-4 col-md-8 col-sm-12">
|
||||
<div class="custom-file">
|
||||
<input type="file" class="custom-file-input" accept="{{acceptFileType}}" formControlName="uploadFile" name="uploadFile" id="uploadFile" (change)="onFileSelected($event)" [ngClass]="{ 'is-invalid': submitted && f.fileName.errors }">
|
||||
<label class="custom-file-label" #uploadFileLabel for="uploadFile" data-browse="Browse"><i class="fa fa-search button-search"></i> Choose file</label>
|
||||
</div>
|
||||
@if (submitted && f.fileName.errors)
|
||||
{
|
||||
<div class="invalid-feedback d-block">
|
||||
<span>Please select an excel file to upload.</span>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mb-2 col-lg-4 col-md-8 col-sm-12">
|
||||
<div class="form-check">
|
||||
<input type="checkbox" class="form-check-input" id="forcePasswordChange" formControlName="forcePasswordChange">
|
||||
<label class="form-check-label" for="forcePasswordChange">Force user to change password at next login</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if (canSave)
|
||||
{
|
||||
<div class="mb-2">
|
||||
<hr class="osds" />
|
||||
<button class="ui-button ui-widget ui-state-default ui-corner-all ui-button-raised ui-button-text-only" [disabled]="loading">
|
||||
<span class="ui-button-text-only ui-c"><i class="fa fa-upload button-edit" aria-hidden="true"></i> Upload & Update</span>
|
||||
</button>
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (totalRows > 0)
|
||||
{
|
||||
<div class="mb-2">
|
||||
<span>Total Row(s): <b>{{totalRows}}</b> | Updated: <b>{{successCount}}</b> | Failed: <b>{{failedCount}}</b></span>
|
||||
<br />
|
||||
<kendo-grid id="grdUploadPwd"
|
||||
[data]="items"
|
||||
[resizable]="true"
|
||||
[loading]="loading"
|
||||
[rowClass]="rowCallback"
|
||||
class="grid-font-900">
|
||||
<kendo-grid-column field="rowNo" title="Row" [width]="70" class="cell-padding" [headerStyle]="{'font-weight':'bold'}" [style]="{'text-align':'center'}"></kendo-grid-column>
|
||||
<kendo-grid-column field="employeeCode" title="Employee Code" [width]="150" class="cell-padding" [headerStyle]="{'font-weight':'bold'}"></kendo-grid-column>
|
||||
<kendo-grid-column field="loginId" title="Login Id" [width]="150" class="cell-padding" [headerStyle]="{'font-weight':'bold'}"></kendo-grid-column>
|
||||
<kendo-grid-column field="message" title="Remarks" class="cell-padding" [headerStyle]="{'font-weight':'bold'}"></kendo-grid-column>
|
||||
</kendo-grid>
|
||||
</div>
|
||||
}
|
||||
</form>
|
||||
143
App/ClientApp/src/app/users/uploadpwd.component.ts
Normal file
143
App/ClientApp/src/app/users/uploadpwd.component.ts
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
import { Router } from '@angular/router';
|
||||
import { NgClass } from '@angular/common';
|
||||
import { KENDO_GRID } from '@progress/kendo-angular-grid';
|
||||
import { Component, ElementRef, OnInit, ViewChild, inject } from '@angular/core';
|
||||
import { FormBuilder, FormGroup, FormsModule, ReactiveFormsModule, Validators } from '@angular/forms';
|
||||
|
||||
import { AlertService } from '../components/alert';
|
||||
import { BreadcrumbService } from '../breadcrumb.service';
|
||||
import { UserService } from '../../providers/user/user.service.';
|
||||
|
||||
@Component({
|
||||
standalone: true,
|
||||
selector: 'user-upload-pwd',
|
||||
templateUrl: './uploadpwd.component.html',
|
||||
styles: ['#grdUploadPwd tr.failed{color:#f00;}'],
|
||||
imports: [FormsModule, ReactiveFormsModule, NgClass, KENDO_GRID]
|
||||
})
|
||||
export class UploadPwdComponent implements OnInit
|
||||
{
|
||||
private readonly router = inject(Router);
|
||||
private readonly service = inject(UserService);
|
||||
private readonly formBuilder = inject(FormBuilder);
|
||||
private readonly alertService = inject(AlertService);
|
||||
|
||||
@ViewChild('uploadFileLabel') private uploadFileLabel: ElementRef;
|
||||
|
||||
public uploadPwdForm: FormGroup;
|
||||
public loading: boolean = false;
|
||||
public canSave: boolean = false;
|
||||
public submitted: boolean = false;
|
||||
public items: any[] = [];
|
||||
public totalRows: number = 0;
|
||||
public successCount: number = 0;
|
||||
public failedCount: number = 0;
|
||||
public readonly acceptFileType: string = '.xls,.xlsx';
|
||||
|
||||
private formData: FormData;
|
||||
|
||||
constructor()
|
||||
{
|
||||
const bcService = inject(BreadcrumbService);
|
||||
|
||||
this.alertService.clear();
|
||||
bcService.setItems([{ label: 'System Setup' }, { label: 'User Management' }, { label: 'Upload Passwords', routerLink: ['/uploadPwd'] }]);
|
||||
if (!this.service.currentUserValue)
|
||||
{
|
||||
this.router.navigate(['/login']);
|
||||
return;
|
||||
}
|
||||
|
||||
this.canSave = this.service.currentUserValue?.moduleIds?.includes('ELIT.1.2.3_2');
|
||||
}
|
||||
|
||||
ngOnInit()
|
||||
{
|
||||
this.uploadPwdForm = this.formBuilder.group(
|
||||
{
|
||||
uploadFile: '',
|
||||
fileName: ['', Validators.required],
|
||||
forcePasswordChange: false
|
||||
});
|
||||
}
|
||||
|
||||
get f() { return this.uploadPwdForm.controls; }
|
||||
|
||||
public rowCallback = (context: any) => { return { failed: !context.dataItem.updated }; };
|
||||
|
||||
public onFileSelected(event: any): void
|
||||
{
|
||||
this.clearData();
|
||||
|
||||
const selectedFile = event.target.files[0];
|
||||
if (!selectedFile)
|
||||
{
|
||||
this.uploadPwdForm.patchValue({ fileName: '' });
|
||||
return;
|
||||
}
|
||||
|
||||
const fileName = selectedFile.name;
|
||||
const extension = fileName.substring(fileName.lastIndexOf('.')).toLowerCase();
|
||||
if (extension !== '.xls' && extension !== '.xlsx')
|
||||
{
|
||||
this.uploadPwdForm.patchValue({ fileName: '' });
|
||||
this.alertService.error('Only excel (.xls/.xlsx) file is allowed to process.');
|
||||
return;
|
||||
}
|
||||
|
||||
this.uploadFileLabel.nativeElement.innerText = fileName;
|
||||
this.uploadPwdForm.patchValue({ fileName: fileName });
|
||||
|
||||
this.formData = new FormData();
|
||||
this.formData.append('fileName', fileName);
|
||||
this.formData.append('fileData', selectedFile);
|
||||
}
|
||||
|
||||
public clearData(): void
|
||||
{
|
||||
this.items = [];
|
||||
this.totalRows = this.successCount = this.failedCount = 0;
|
||||
}
|
||||
|
||||
public onSubmit(): void
|
||||
{
|
||||
this.submitted = true;
|
||||
this.alertService.clear();
|
||||
if (this.uploadPwdForm.invalid || !this.formData)
|
||||
return;
|
||||
|
||||
this.clearData();
|
||||
this.loading = true;
|
||||
this.formData.set('forcePasswordChange', `${this.f.forcePasswordChange.value === true}`);
|
||||
this.service.uploadPasswords(this.formData).subscribe(
|
||||
{
|
||||
next: (resp: any) =>
|
||||
{
|
||||
this.loading = false;
|
||||
this.items = resp.items ?? [];
|
||||
this.totalRows = resp.totalRows ?? 0;
|
||||
this.failedCount = resp.failedCount ?? 0;
|
||||
this.successCount = resp.successCount ?? 0;
|
||||
|
||||
if (resp.returnStatus === 200)
|
||||
{
|
||||
if (this.failedCount > 0)
|
||||
this.alertService.info(resp.returnMessage);
|
||||
else
|
||||
this.alertService.success(resp.returnMessage);
|
||||
|
||||
this.submitted = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.alertService.error(resp.returnMessage);
|
||||
}
|
||||
},
|
||||
error: (errorMessage: string) =>
|
||||
{
|
||||
this.loading = false;
|
||||
this.alertService.error(errorMessage);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -114,6 +114,11 @@ export class UserService extends Base
|
|||
return this.api.post('v1/users/resetPassword', params);
|
||||
}
|
||||
|
||||
public uploadPasswords(formdata: FormData)
|
||||
{
|
||||
return this.api.uplaodFormData('v1/users/uploadPasswords', formdata);
|
||||
}
|
||||
|
||||
public findAccount(accountId: string)
|
||||
{
|
||||
const params: any = { accountId: accountId };
|
||||
|
|
|
|||
3
Deployment/App/prerendered-routes.json
Normal file
3
Deployment/App/prerendered-routes.json
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"routes": {}
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user