diff --git a/CPRNIMS.Domain/Contracts/Finance/IRR.cs b/CPRNIMS.Domain/Contracts/Finance/IRR.cs index bbb203f..27103d5 100644 --- a/CPRNIMS.Domain/Contracts/Finance/IRR.cs +++ b/CPRNIMS.Domain/Contracts/Finance/IRR.cs @@ -13,6 +13,6 @@ namespace CPRNIMS.Domain.Contracts.Finance { Task> GetAllClosedPO(RRDetailsDto itemDto); Task> GetRRDetailByPO(RRDetailsDto itemDto); - Task PostPutPayment(RRDetailsDto itemDto); + Task PostPutPayment(RRDetailsDto itemDto); } } diff --git a/CPRNIMS.Domain/Contracts/Inventory/IInventory.cs b/CPRNIMS.Domain/Contracts/Inventory/IInventory.cs index 3b31a70..55f9472 100644 --- a/CPRNIMS.Domain/Contracts/Inventory/IInventory.cs +++ b/CPRNIMS.Domain/Contracts/Inventory/IInventory.cs @@ -21,7 +21,7 @@ namespace CPRNIMS.Domain.Contracts.Inventory Task> GetInventory(InventoryRequest request, CancellationToken ct); Task> GetInventoryById(InventoryRequest itemDto, CancellationToken ct); Task GetTransactContextAsync(int inventoryId, CancellationToken ct); - Task> GetDisciplinesAsync(CancellationToken ct); + Task> GetDisciplinesAsync(CancellationToken ct); Task PostPutReqApproval(InventoryDto itemDto); Task PostPutReqItems(InventoryDto itemDto); Task PostPutLotNo(InventoryDto itemDto); diff --git a/CPRNIMS.Domain/Contracts/Inventory/IMRS.cs b/CPRNIMS.Domain/Contracts/Inventory/IMRS.cs index 9540c15..bfbfbda 100644 --- a/CPRNIMS.Domain/Contracts/Inventory/IMRS.cs +++ b/CPRNIMS.Domain/Contracts/Inventory/IMRS.cs @@ -12,6 +12,8 @@ namespace CPRNIMS.Domain.Contracts.Inventory public interface IMRS { Task GetPagedAsync(MRSFilterDto filter, CancellationToken ct,int? departmentId = null, string? userName = ""); + Task> SearchRISForReturnAsync(string? risNoQuery, int? projectCodeId, CancellationToken ct); + Task> GetProjectsWithOpenRISAsync(string? nameQuery, CancellationToken ct); Task GetByIdAsync(long mrsId, CancellationToken ct); Task CreateAsync(CreateMRSRequest dto, string createdBy, CancellationToken ct); Task ApproveAsync(long mrsId, string approvedBy, CancellationToken ct); diff --git a/CPRNIMS.Domain/Contracts/Items/IItem.cs b/CPRNIMS.Domain/Contracts/Items/IItem.cs index d7e0902..f5f33ed 100644 --- a/CPRNIMS.Domain/Contracts/Items/IItem.cs +++ b/CPRNIMS.Domain/Contracts/Items/IItem.cs @@ -16,14 +16,14 @@ namespace CPRNIMS.Domain.Contracts.Items Task> GetDepartment(ItemCodeDto itemCode); Task> GetItemList(ItemCodeDto itemCode); Task> GetItemCart(ItemDto itemDto); - Task> GetItemDetail(ItemDto itemDto); + Task> GetItemDetail(ItemDto itemDto); Task> GetItemLocalization(ItemDto itemDto); Task> GetItemCateg(ItemDto itemDto); Task> GetItemColor(ItemDto itemDto); Task> GetItemUOM(ItemDto itemDto); Task> GetNotifUserKey(ItemDto itemDto); - Task> GetProjectCode(); - Task> GetProjectCodeByTerm(string? fileName); + Task> GetProjectCode(); + Task> GetProjectCodeByTerm(string? fileName); Task<(long, long)> GetPRNo(); Task PostPurchRequest(ItemDto itemDto); Task PostPutItem(ItemCodeDto itemDto); diff --git a/CPRNIMS.Domain/Contracts/PO/IPurchaseOrder.cs b/CPRNIMS.Domain/Contracts/PO/IPurchaseOrder.cs index 3f770c5..513518d 100644 --- a/CPRNIMS.Domain/Contracts/PO/IPurchaseOrder.cs +++ b/CPRNIMS.Domain/Contracts/PO/IPurchaseOrder.cs @@ -70,6 +70,7 @@ namespace CPRNIMS.Domain.Contracts.PO Task PostPutIncoterms(PODto pODto); Task DeleteIncShip(PODto poDto); Task PostIncShipFollowUp(PODto pODto); + Task> GetCurrencies(string currencyName, CancellationToken ct); #endregion } } diff --git a/CPRNIMS.Domain/Contracts/Receiving/IReceiving.cs b/CPRNIMS.Domain/Contracts/Receiving/IReceiving.cs index 75bbc8c..c1f230b 100644 --- a/CPRNIMS.Domain/Contracts/Receiving/IReceiving.cs +++ b/CPRNIMS.Domain/Contracts/Receiving/IReceiving.cs @@ -12,7 +12,7 @@ namespace CPRNIMS.Domain.Contracts.Receiving public interface IReceiving { Task> GetRRDetailByPO(ItemDto itemDto); - Task> GetRRDetail(ItemDto itemDto); + Task> GetRRDetail(ItemDto itemDto); Task> GetForReceiving(ItemDto itemDto); Task> GetRR(ItemDto itemDto); Task> GetLatestRRNo(ItemDto itemDto); diff --git a/CPRNIMS.Domain/Services/Finance/RR.cs b/CPRNIMS.Domain/Services/Finance/RR.cs index 88e9e7b..a727cc8 100644 --- a/CPRNIMS.Domain/Services/Finance/RR.cs +++ b/CPRNIMS.Domain/Services/Finance/RR.cs @@ -40,7 +40,7 @@ namespace CPRNIMS.Domain.Services.Finance return allItems ?? new List(); } - public async Task PostPutPayment(RRDetailsDto itemDto) + public async Task PostPutPayment(RRDetailsDto itemDto) { await _dbContext.Database .ExecuteSqlRawAsync("EXEC PostPutPayment @UserId, @PONo, @POTypeId, @PRDetailsId", @@ -48,7 +48,7 @@ namespace CPRNIMS.Domain.Services.Finance new SqlParameter("@PONo", itemDto.PONo), new SqlParameter("@POTypeId", itemDto.POTypeId), new SqlParameter("@PRDetailsId", itemDto.PRDetailsId)); - return new RRDetail(); + return new RRDetailDto(); } } } diff --git a/CPRNIMS.Domain/Services/Inventory/Inventory.cs b/CPRNIMS.Domain/Services/Inventory/Inventory.cs index 1cda8e5..8df5d49 100644 --- a/CPRNIMS.Domain/Services/Inventory/Inventory.cs +++ b/CPRNIMS.Domain/Services/Inventory/Inventory.cs @@ -3,7 +3,9 @@ using CPRNIMS.Infrastructure.Database; using CPRNIMS.Infrastructure.Dto.Inventory; using CPRNIMS.Infrastructure.Dto.Inventory.Request; using CPRNIMS.Infrastructure.Dto.Inventory.Response; +using CPRNIMS.Infrastructure.Entities.Account; using CPRNIMS.Infrastructure.Entities.Inventory; +using Microsoft.AspNetCore.Identity; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using System; @@ -17,9 +19,11 @@ namespace CPRNIMS.Domain.Services.Inventory public class Inventory : IInventory { private readonly NonInventoryDbContext _dbContext; - public Inventory(NonInventoryDbContext dbContext) + private readonly UserManager _userManager; + public Inventory(NonInventoryDbContext dbContext, UserManager userManager) { _dbContext = dbContext; + _userManager = userManager; } public async Task GetTransactContextAsync(int inventoryId, CancellationToken ct) { @@ -79,7 +83,7 @@ namespace CPRNIMS.Domain.Services.Inventory .ToListAsync(ct); var disciplines = await GetDisciplinesAsync(ct); - + var projectCodes = await GetProjectCodesAsync(ct); return new TransactContextDto { InventoryId = inv.InventoryId, @@ -91,13 +95,15 @@ namespace CPRNIMS.Domain.Services.Inventory QtyOnHand = inv.QtyOnHand, QtyIn = inv.QtyIn, QtyOut = inv.QtyOut, + ProjectCodes = projectCodes, Disciplines = disciplines, OpenRISList = openRIS }; } - public async Task> GetDisciplinesAsync(CancellationToken ct) + public async Task> GetDisciplinesAsync(CancellationToken ct) { return await _dbContext.Disciplines + .AsNoTracking() .OrderBy(d => d.DisciplineName) .Select(d => new DisciplineDto { @@ -106,6 +112,19 @@ namespace CPRNIMS.Domain.Services.Inventory }) .ToListAsync(ct); } + public async Task> GetProjectCodesAsync(CancellationToken ct) + { + return await _dbContext.ProjectCodes + .Where(p => p.StatusName != "Completed" && p.IsActive) + .OrderBy(d => d.ProjectName) + .Select(d => new ProjectCodeDto + { + ProjectCodeId = d.ProjectCodeId, + ProjectCode = d.ProjectCode ?? "N/A", + ProjectName = d.ProjectName ?? "N/A" + }) + .ToListAsync(ct); + } public async Task> GetInventoryById(InventoryDto itemDto) { var allItems = await _dbContext.ItemDetails diff --git a/CPRNIMS.Domain/Services/Inventory/InventoryReports.cs b/CPRNIMS.Domain/Services/Inventory/InventoryReports.cs index 2dcd900..a00245d 100644 --- a/CPRNIMS.Domain/Services/Inventory/InventoryReports.cs +++ b/CPRNIMS.Domain/Services/Inventory/InventoryReports.cs @@ -1,6 +1,7 @@ using CPRNIMS.Domain.Contracts.Inventory; using CPRNIMS.Infrastructure.Database; using CPRNIMS.Infrastructure.Dto.Inventory.Reports; +using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; namespace CPRNIMS.Domain.Services.Inventory @@ -43,7 +44,7 @@ namespace CPRNIMS.Domain.Services.Inventory ItemName = r.PRDetail != null ? r.PRDetail.ItemName : "—", ItemNo = r.Inventory.ItemNo, DisciplineName = r.Discipline.DisciplineName, - IssuedTo = r.IssuedTo, + ProjectName = r.ProjectCodes.ProjectName, QtyIssued = r.QtyIssued, TotalReturned = r.MaterialReturns .Where(m => m.Status != 2) @@ -79,7 +80,7 @@ namespace CPRNIMS.Domain.Services.Inventory .ToList(); var topRecipients = rows - .GroupBy(r => r.IssuedTo) + .GroupBy(r => r.ProjectName) .Select(g => new TopRecipient { IssuedTo = g.Key, @@ -187,108 +188,104 @@ namespace CPRNIMS.Domain.Services.Inventory public async Task GetInventoryReportAsync(DateTime dateFrom, DateTime dateTo, CancellationToken ct, int? departmentId = null, string? userName = "") { - var endDate = dateTo.Date.AddDays(1); - - var allowedAllDeptUsers = new[] { "LSKRISUR24", "LSCYNDIZ25", "LSJONTAN25" , "LHRIOCAS24" }; + var allowedAllDeptUsers = new[] { "LSKRISUR24", "LSCYNDIZ25", "LSJONTAN25", "LHRIOCAS24" }; bool seeAllDepartments = !string.IsNullOrWhiteSpace(userName) && allowedAllDeptUsers.Contains(userName, StringComparer.OrdinalIgnoreCase); - var query = _db.InventTransDetails - .Where(itd => - itd.IsActive && - itd.InventTrans.IsActive && - itd.InventTrans.Inventory.IsActive && - itd.CreatedDate >= dateFrom && - itd.CreatedDate < endDate); - - if (departmentId.HasValue && !seeAllDepartments) - { - query = query.Where(itd => - itd.InventTrans.Inventory.User.DepartmentId == departmentId.Value); - } - - var rawRows = await query - .Select(itd => new - { - itd.InventTrans.Inventory.InventoryId, - itd.InventTrans.Inventory.ItemNo, - itd.InventTrans.Inventory.QtyIn, - itd.InventTrans.Inventory.QtyOut, - itd.InventTrans.Inventory.QtyOnHand, - LotNo = itd.InventTrans.Inventory.Lot != null - ? itd.InventTrans.Inventory.Lot.LotName - : null, - ItemName = itd.InventTrans.Inventory.Item.ItemCode.ItemName ?? "None", - ItemCategoryName = - itd.InventTrans.Inventory.Item.ItemCode.ItemCategory.ItemCategoryName ?? "None", - itd.CreatedDate - }) - .ToListAsync(ct); - - // De-duplicate: one row per Inventory (latest trans detail wins for the date shown) - var rows = rawRows - .GroupBy(r => r.InventoryId) - .Select(g => - { - var inv = g.OrderByDescending(x => x.CreatedDate).First(); - return new InventoryReportRow - { - ItemName = inv.ItemName, - ItemNo = inv.ItemNo, - ItemCategoryName = inv.ItemCategoryName, - LotNo = inv.LotNo, - QtyIn = inv.QtyIn, - QtyOut = inv.QtyOut, - QtyOnHand = inv.QtyOnHand, - StockPct = inv.QtyIn > 0 - ? (int)Math.Round(Math.Max(0, Math.Min(100, (inv.QtyOnHand / inv.QtyIn) * 100))) - : 0 - }; - }) - .OrderBy(r => r.ItemName) - .ToList(); - - var summary = new InventoryReportSummary - { - TotalSKUs = rows.Count, - TotalOnHand = rows.Sum(r => r.QtyOnHand), - TotalQtyIn = rows.Sum(r => r.QtyIn), - TotalQtyOut = rows.Sum(r => r.QtyOut), - LowStockCount = rows.Count(r => r.StockPct < 20 && r.QtyOnHand > 0), - OutOfStockCount = rows.Count(r => r.QtyOnHand <= 0) - }; - - var byCategory = rows - .GroupBy(r => r.ItemCategoryName) - .Select(g => new CategoryStockLevel - { - CategoryName = g.Key, - AvgStockPct = (int)Math.Round(g.Average(r => r.StockPct)) - }) - .OrderByDescending(c => c.AvgStockPct) - .ToList(); - - var alerts = rows - .Where(r => r.StockPct < 20) - .OrderBy(r => r.StockPct) - .Take(10) - .Select(r => new InventoryAlert - { - ItemName = r.ItemName, - QtyOnHand = r.QtyOnHand, - Severity = r.QtyOnHand <= 0 ? "Critical" : "Low" - }) - .ToList(); - - return new InventoryReportDto + var dto = new InventoryReportDto { ReportNo = $"RPT-INV-{DateTime.Now:yyyyMM}-{Random.Shared.Next(1, 999):D3}", - AsOf = dateTo.Date, // reflect the requested period end, not always today - Summary = summary, - Rows = rows, - ByCategory = byCategory, - Alerts = alerts + AsOf = dateTo.Date, + Rows = new List(), + ByCategory = new List(), + Alerts = new List(), + Summary = new InventoryReportSummary() }; + + var conn = _db.Database.GetDbConnection(); + await using var cmd = conn.CreateCommand(); + cmd.CommandText = "dbo.GetInventoryReport"; + cmd.CommandType = System.Data.CommandType.StoredProcedure; + + cmd.Parameters.Add(new SqlParameter("@DateFrom", dateFrom)); + cmd.Parameters.Add(new SqlParameter("@DateTo", dateTo)); + cmd.Parameters.Add(new SqlParameter("@DepartmentId", (object?)departmentId ?? DBNull.Value)); + cmd.Parameters.Add(new SqlParameter("@SeeAllDepartments", seeAllDepartments ? 1 : 0)); + + if (conn.State != System.Data.ConnectionState.Open) + await conn.OpenAsync(ct); + + try + { + await using var reader = await cmd.ExecuteReaderAsync(ct); + + // 1: detail rows + while (await reader.ReadAsync(ct)) + { + dto.Rows.Add(new InventoryReportRow + { + ItemName = reader.GetString(reader.GetOrdinal("ItemName")), + ItemNo = reader.GetInt64(reader.GetOrdinal("ItemNo")), + ItemCategoryName = reader.GetString(reader.GetOrdinal("ItemCategoryName")), + LotNo = reader.IsDBNull(reader.GetOrdinal("LotNo")) + ? null : reader.GetString(reader.GetOrdinal("LotNo")), + QtyIn = reader.GetDecimal(reader.GetOrdinal("QtyIn")), + QtyOut = reader.GetDecimal(reader.GetOrdinal("QtyOut")), + QtyOnHand = reader.GetDecimal(reader.GetOrdinal("QtyOnHand")), + UnitPrice = reader.GetDecimal(reader.GetOrdinal("UnitPrice")), + StockPct = reader.GetInt32(reader.GetOrdinal("StockPct")) + }); + } + + // 2: summary + if (await reader.NextResultAsync(ct) && await reader.ReadAsync(ct)) + { + dto.Summary = new InventoryReportSummary + { + TotalSKUs = reader.GetInt32(reader.GetOrdinal("TotalSKUs")), + TotalOnHand = reader.GetDecimal(reader.GetOrdinal("TotalOnHand")), + TotalQtyIn = reader.GetDecimal(reader.GetOrdinal("TotalQtyIn")), + TotalQtyOut = reader.GetDecimal(reader.GetOrdinal("TotalQtyOut")), + TotalValue = reader.GetDecimal(reader.GetOrdinal("TotalValue")), + LowStockCount = reader.GetInt32(reader.GetOrdinal("LowStockCount")), + OutOfStockCount = reader.GetInt32(reader.GetOrdinal("OutOfStockCount")) + }; + } + + // 3: by category + if (await reader.NextResultAsync(ct)) + { + while (await reader.ReadAsync(ct)) + { + dto.ByCategory.Add(new CategoryStockLevel + { + CategoryName = reader.GetString(reader.GetOrdinal("CategoryName")), + AvgStockPct = reader.GetInt32(reader.GetOrdinal("AvgStockPct")) + }); + } + } + + // 4: alerts + if (await reader.NextResultAsync(ct)) + { + while (await reader.ReadAsync(ct)) + { + dto.Alerts.Add(new InventoryAlert + { + ItemName = reader.GetString(reader.GetOrdinal("ItemName")), + QtyOnHand = reader.GetDecimal(reader.GetOrdinal("QtyOnHand")), + Severity = reader.GetString(reader.GetOrdinal("Severity")) + }); + } + } + } + finally + { + if (conn.State == System.Data.ConnectionState.Open) + await conn.CloseAsync(); + } + + return dto; } } } diff --git a/CPRNIMS.Domain/Services/Inventory/MRS.cs b/CPRNIMS.Domain/Services/Inventory/MRS.cs index 13801bb..750f781 100644 --- a/CPRNIMS.Domain/Services/Inventory/MRS.cs +++ b/CPRNIMS.Domain/Services/Inventory/MRS.cs @@ -19,6 +19,17 @@ namespace CPRNIMS.Domain.Services.Inventory } public async Task ApproveAsync(long mrsId, string approvedBy, CancellationToken ct) { + //var user = await _userManager.FindByNameAsync(approvedBy); + //if (user != null) + //{ + // bool isApprover2 = await _userManager.IsInRoleAsync(user, "APPROVER2"); + + // if (!isApprover2) + // { + // throw new Exception("You have no permission to approve this item."); + // } + //} + var rms = await _db.MRS.FindAsync(mrsId) ?? throw new InvalidOperationException("MRS not found."); @@ -34,6 +45,17 @@ namespace CPRNIMS.Domain.Services.Inventory public async Task CancelAsync(CancelMRSRequest request,string canceledBy, CancellationToken ct) { + //var user = await _userManager.FindByNameAsync(canceledBy); + //if (user != null) + //{ + // bool isApprover2 = await _userManager.IsInRoleAsync(user, "APPROVER2"); + + // if (!isApprover2) + // { + // throw new Exception("You have no permission to cancel this item."); + // } + //} + await _transactionFacade.ExecuteAsync(async () => { var mrs = await _db.MRS @@ -78,7 +100,7 @@ namespace CPRNIMS.Domain.Services.Inventory QtyReturned = dto.QtyReturned, Condition = dto.Condition, Remarks = dto.Remarks, - Status = 0, + Status = 1,//Matic Approve for now CreatedBy = createdBy, CreatedDate = DateTime.Now }; @@ -177,7 +199,6 @@ namespace CPRNIMS.Domain.Services.Inventory return new MRSPagedResult { Data = data, RecordsTotal = total }; } - private async Task GenerateMRSNoAsync() { var year = DateTime.Now.Year; @@ -185,5 +206,55 @@ namespace CPRNIMS.Domain.Services.Inventory var count = await _db.MRS.CountAsync(m => m.CreatedDate.Year == year) + 1; return $"MRS-{year}{month}-{count:D4}"; } + public async Task> SearchRISForReturnAsync(string? risNoQuery, int? projectCodeId, CancellationToken ct) + { + var query = _db.RIS + .Where(r => r.Status == 1); + + if (projectCodeId.HasValue) + query = query.Where(r => r.ProjectCodeId == projectCodeId.Value); + + if (!string.IsNullOrWhiteSpace(risNoQuery)) + query = query.Where(r => r.RISNo.Contains(risNoQuery)); + + return await query + .Select(r => new RISSearchResultDto + { + RISId = r.RISId, + RISNo = r.RISNo, + ProjectCodeId = r.ProjectCodeId, + ProjectCode = r.ProjectCodes.ProjectCode ?? "N/A", + ProjectName = r.ProjectCodes.ProjectName ?? "N/A", + DisciplineName = r.Discipline.DisciplineName, + QtyAvailableToReturn = r.QtyIssued - r.MaterialReturns.Sum(m => m.QtyReturned) + }) + .Where(r => r.QtyAvailableToReturn > 0) + .OrderByDescending(r => r.RISId) + .Take(20) + .ToListAsync(ct); + } + + public async Task> GetProjectsWithOpenRISAsync(string? nameQuery, CancellationToken ct) + { + var query = _db.RIS + .Where(r => r.Status == 1 && r.QtyIssued > r.MaterialReturns.Sum(m => m.QtyReturned)); + + if (!string.IsNullOrWhiteSpace(nameQuery)) + query = query.Where(r => + r.ProjectCodes.ProjectName.Contains(nameQuery) || + r.ProjectCodes.ProjectCode.Contains(nameQuery)); + + return await query + .Select(r => new ProjectCodeOptionDto + { + ProjectCodeId = r.ProjectCodeId, + ProjectCode = r.ProjectCodes.ProjectCode ?? "N/A", + ProjectName = r.ProjectCodes.ProjectName ?? "N/A" + }) + .Distinct() + .OrderBy(p => p.ProjectName) + .Take(20) + .ToListAsync(ct); + } } } diff --git a/CPRNIMS.Domain/Services/Inventory/RIS.cs b/CPRNIMS.Domain/Services/Inventory/RIS.cs index 5f32441..55e48ae 100644 --- a/CPRNIMS.Domain/Services/Inventory/RIS.cs +++ b/CPRNIMS.Domain/Services/Inventory/RIS.cs @@ -42,11 +42,11 @@ namespace CPRNIMS.Domain.Services.Inventory RISNo = risNo, InventoryId = dto.InventoryId, PRDetailId = dto.PRDetailId, - IssuedTo = dto.IssuedTo, + ProjectCodeId = dto.ProjectCodeId, DisciplineId = dto.DisciplineId, QtyIssued = dto.QtyIssued, Remarks = dto.Remarks, - Status = 0, + Status = 1,//Approved alredy 0 is Draft CreatedBy = createdBy, CreatedDate = DateTime.Now }; @@ -78,6 +78,17 @@ namespace CPRNIMS.Domain.Services.Inventory public async Task ApproveAsync(ApproveRISRequest request, string approvedBy, CancellationToken ct) { + //var user = await _userManager.FindByNameAsync(approvedBy); + //if (user != null) + //{ + // bool isApprover2 = await _userManager.IsInRoleAsync(user, "APPROVER2"); + + // if (!isApprover2) + // { + // throw new Exception("You have no permission to approved this item."); + // } + //} + var ris = await _db.RIS.FindAsync(request.RISId, ct) ?? throw new InvalidOperationException("RIS not found."); @@ -93,6 +104,17 @@ namespace CPRNIMS.Domain.Services.Inventory public async Task CancelAsync(CancelRISRequest request,string canceledBy, CancellationToken ct) { + //var user = await _userManager.FindByNameAsync(canceledBy); + //if (user != null) + //{ + // bool isApprover2 = await _userManager.IsInRoleAsync(user, "APPROVER2"); + + // if (!isApprover2) + // { + // throw new Exception("You have no permission to cancel this item."); + // } + //} + await _transactionFacade.ExecuteAsync(async () => { var ris = await _db.RIS @@ -189,9 +211,10 @@ namespace CPRNIMS.Domain.Services.Inventory .Any(d => d.PRDetails != null && d.PRDetails.ItemName.Contains(filter.SearchItemName))); - // Issued To + // Issued To is Project code/name if (!string.IsNullOrWhiteSpace(filter.SearchIssuedTo)) - q = q.Where(r => r.IssuedTo.Contains(filter.SearchIssuedTo)); + q = q.Where(r => r.ProjectCodes.ProjectCode.Contains(filter.SearchIssuedTo) + || r.ProjectCodes.ProjectName.Contains(filter.SearchIssuedTo)); // Discipline if (!string.IsNullOrWhiteSpace(filter.Discipline)) @@ -220,7 +243,8 @@ namespace CPRNIMS.Domain.Services.Inventory .FirstOrDefault() ?? "—", ItemNo = r.Inventory.ItemNo, LotNo = r.Inventory.Lot != null ? r.Inventory.Lot.LotName : null, - IssuedTo = r.IssuedTo, + ProjectName = r.ProjectCodes.ProjectName, + ProjectCode = r.ProjectCodes.ProjectCode, DisciplineName = r.Discipline.DisciplineName, DisciplineId = r.DisciplineId, QtyIssued = r.QtyIssued, @@ -253,7 +277,7 @@ namespace CPRNIMS.Domain.Services.Inventory DisciplineList = disciplines }; } - public async Task> GetDisciplinesAsync(CancellationToken ct) + public async Task> GetDisciplinesAsync(CancellationToken ct) { return await _db.Disciplines .OrderBy(d => d.DisciplineName) @@ -264,6 +288,19 @@ namespace CPRNIMS.Domain.Services.Inventory }) .ToListAsync(ct); } + public async Task> GetProjectCodesAsync(CancellationToken ct) + { + return await _db.ProjectCodes + .Where(p=>p.StatusName !="Completed") + .OrderBy(d => d.ProjectName) + .Select(d => new ProjectCodeDto + { + ProjectCodeId= d.ProjectCodeId, + ProjectCode = d.ProjectCode ?? "N/A", + ProjectName = d.ProjectName ?? "N/A" + }) + .ToListAsync(ct); + } public async Task GetByIdAsync(long risId, CancellationToken ct) { return await _db.RIS @@ -273,7 +310,7 @@ namespace CPRNIMS.Domain.Services.Inventory RISId = r.RISId, RISNo = r.RISNo, InventoryId = r.InventoryId, - IssuedTo = r.IssuedTo, + ProjectCodeId = r.ProjectCodeId, DisciplineName = r.Discipline.DisciplineName, DisciplineId = r.DisciplineId, QtyIssued = r.QtyIssued, diff --git a/CPRNIMS.Domain/Services/Items/Item.cs b/CPRNIMS.Domain/Services/Items/Item.cs index 98e90f5..20fd0e6 100644 --- a/CPRNIMS.Domain/Services/Items/Item.cs +++ b/CPRNIMS.Domain/Services/Items/Item.cs @@ -63,7 +63,6 @@ namespace CPRNIMS.Domain.Services.Items UserId = itemDto.UserId }; } - public async Task PutItemDetail(ItemDto itemDto) { await _dbContext.Database @@ -92,126 +91,6 @@ namespace CPRNIMS.Domain.Services.Items return new Infrastructure.Entities.Items.Item(); } - public async Task> GetItemLocalization(ItemDto itemDto) - { - var localizations = await _dbContext.ItemLocalizations - .Where(ic => ic.IsActive == true && - EF.Functions.Like(ic.ItemLocalName, $"%{itemDto.ItemLocalName}%")) - .Take(15) - .ToListAsync(); - - return localizations ?? new List(); - } - public async Task> GetItemCateg(ItemDto itemDto) - { - if (itemDto.ItemCategoryId == 0 || itemDto.ItemCategoryId == null) - { - var categories = await _dbContext.ItemCategories - .Where(ic => ic.IsActive == true) - .ToListAsync(); - return categories ?? new List(); - } - else - { - var categories = await _dbContext.ItemCategories - .Where(ic => ic.IsActive == true && ic.ItemCategoryId == itemDto.ItemCategoryId) - .ToListAsync(); - return categories ?? new List(); - } - } - - public async Task> GetItemDetail(ItemDto itemDto) - { - var allItems = await _dbContext.Items - .FromSqlRaw($"EXEC GetItemDetail @ItemCodeId,@UserId", - new SqlParameter("@ItemCodeId", itemDto.ItemCodeId), - new SqlParameter("@UserId", itemDto.UserId)) - .ToListAsync(); - - return allItems ?? new List(); - } - - public async Task> GetItemList(ItemCodeDto dto) - { - var parameters = new[] - { - new SqlParameter("@UserId", dto.UserId), - new SqlParameter("@SearchItemNo", dto.SearchItemNo ?? ""), - new SqlParameter("@SearchItemName", dto.SearchItemName ?? ""), - new SqlParameter("@SearchCategory", dto.SearchCategory ?? ""), - new SqlParameter("@PageNumber", dto.PageNumber), - new SqlParameter("@PageSize", dto.PageSize) - }; - - int totalCount = 0; - var items = new List(); - var categoryList = new List(); - - // Use ADO.NET to read two result sets - var conn = _dbContext.Database.GetDbConnection(); - await conn.OpenAsync(); - - using var cmd = conn.CreateCommand(); - cmd.CommandText = "EXEC GetItemList @UserId, @SearchItemNo,@SearchItemName,@SearchCategory, @PageNumber, @PageSize"; - foreach (var p in parameters) cmd.Parameters.Add(p); - cmd.CommandTimeout = 60; - - using var reader = await cmd.ExecuteReaderAsync(); - - while (await reader.ReadAsync()) - categoryList.Add(reader.GetString(0)); - - await reader.NextResultAsync(); - - if (await reader.ReadAsync()) - totalCount = reader.GetInt32(0); - - await reader.NextResultAsync(); - - while (await reader.ReadAsync()) - { - items.Add(new ItemList - { - ItemCodeId = Convert.ToInt64(reader["ItemCodeId"]), - ItemNo = Convert.ToInt64(reader["ItemNo"]), - ItemName = reader["ItemName"]?.ToString(), - ItemDescription = reader["ItemDescription"]?.ToString(), - ItemCategoryName = reader["ItemCategoryName"]?.ToString(), - CartItemCount = Convert.ToInt32(reader["CartItemCount"]) - }); - } - await conn.CloseAsync(); - - return new PagedResult - { - Data = items, - TotalCount = totalCount, - CategoryList= categoryList, - PageNumber = dto.PageNumber, - PageSize = dto.PageSize - }; - } - public async Task> GetItemColor(ItemDto itemDto) - { - var colors = await _dbContext.ItemColors - .Where(ic => EF.Functions.Like(ic.ItemColorName, $"%{itemDto.ItemColorName}%")) - .Take(5) - .ToListAsync(); - - return colors ?? new List(); - } - - public async Task> GetItemUOM(ItemDto itemDto) - { - var uoms = await _dbContext.UnitOfMessures - .Where(ic => ic.IsActive == true && - EF.Functions.Like(ic.UOMName, $"%{itemDto.UOMName}%")) - .Take(150) - .ToListAsync(); - - return uoms ?? new List(); - } - public async Task PostPutItemPath(ItemDto itemDto) { var isExist = await _dbContext.ItemAttachements @@ -243,19 +122,6 @@ namespace CPRNIMS.Domain.Services.Items new SqlParameter("@ItemLocalId", itemDto.ItemLocalId)); return new ItemCart(); } - - public async Task> GetItemCart(ItemDto itemDto) - { - var allItems = await _dbContext.ItemCarts - .FromSqlRaw($"EXEC GetItemCart @UserId,@RequestTypeId,@IsCount", - new SqlParameter("@UserId", itemDto.UserId), - new SqlParameter("@RequestTypeId", itemDto.RequestTypeId), - new SqlParameter("@IsCount", itemDto.IsCount)) - .ToListAsync(); - - return allItems ?? new List(); - } - public async Task PostPurchRequest(ItemDto itemDto) { var (messCode, message) = OutputParamMessage.CreateOutputParams(); @@ -321,8 +187,23 @@ namespace CPRNIMS.Domain.Services.Items existing.FileName = attach.FileName; } await _dbContext.SaveChangesAsync(); + } + Task IItem.PostPutItemPath(ItemDto itemDto) + { + throw new NotImplementedException(); } - public async Task<(long,long)> GetPRNo() + public async Task> GetItemCart(ItemDto itemDto) + { + var allItems = await _dbContext.ItemCarts + .FromSqlRaw($"EXEC GetItemCart @UserId,@RequestTypeId,@IsCount", + new SqlParameter("@UserId", itemDto.UserId), + new SqlParameter("@RequestTypeId", itemDto.RequestTypeId), + new SqlParameter("@IsCount", itemDto.IsCount)) + .ToListAsync(); + + return allItems ?? new List(); + } + public async Task<(long, long)> GetPRNo() { try { @@ -332,9 +213,9 @@ namespace CPRNIMS.Domain.Services.Items .FirstOrDefaultAsync(); if (latestPR != null) - return (latestPR.PRNo + 1,latestPR.PRId + 1); + return (latestPR.PRNo + 1, latestPR.PRId + 1); else - return (0,0); + return (0, 0); } catch (Exception ex) { @@ -343,11 +224,122 @@ namespace CPRNIMS.Domain.Services.Items } } - Task IItem.PostPutItemPath(ItemDto itemDto) + public async Task> GetItemLocalization(ItemDto itemDto) { - throw new NotImplementedException(); - } + var localizations = await _dbContext.ItemLocalizations + .Where(ic => ic.IsActive == true && + EF.Functions.Like(ic.ItemLocalName, $"%{itemDto.ItemLocalName}%")) + .Take(15) + .ToListAsync(); + return localizations ?? new List(); + } + public async Task> GetItemCateg(ItemDto itemDto) + { + if (itemDto.ItemCategoryId == 0 || itemDto.ItemCategoryId == null) + { + var categories = await _dbContext.ItemCategories + .Where(ic => ic.IsActive == true) + .ToListAsync(); + return categories ?? new List(); + } + else + { + var categories = await _dbContext.ItemCategories + .Where(ic => ic.IsActive == true && ic.ItemCategoryId == itemDto.ItemCategoryId) + .ToListAsync(); + return categories ?? new List(); + } + } + public async Task> GetItemDetail(ItemDto itemDto) + { + var allItems = await _dbContext.ItemDtos + .FromSqlRaw($"EXEC GetItemDetail @ItemCodeId,@UserId", + new SqlParameter("@ItemCodeId", itemDto.ItemCodeId), + new SqlParameter("@UserId", itemDto.UserId)) + .ToListAsync(); + + return allItems ?? new List(); + } + public async Task> GetItemList(ItemCodeDto dto) + { + var parameters = new[] + { + new SqlParameter("@UserId", dto.UserId), + new SqlParameter("@SearchItemNo", dto.SearchItemNo ?? ""), + new SqlParameter("@SearchItemName", dto.SearchItemName ?? ""), + new SqlParameter("@SearchCategory", dto.SearchCategory ?? ""), + new SqlParameter("@PageNumber", dto.PageNumber), + new SqlParameter("@PageSize", dto.PageSize) + }; + + int totalCount = 0; + var items = new List(); + var categoryList = new List(); + + // Use ADO.NET to read two result sets + var conn = _dbContext.Database.GetDbConnection(); + await conn.OpenAsync(); + + using var cmd = conn.CreateCommand(); + cmd.CommandText = "EXEC GetItemList @UserId, @SearchItemNo,@SearchItemName,@SearchCategory, @PageNumber, @PageSize"; + foreach (var p in parameters) cmd.Parameters.Add(p); + cmd.CommandTimeout = 60; + + using var reader = await cmd.ExecuteReaderAsync(); + + while (await reader.ReadAsync()) + categoryList.Add(reader.GetString(0)); + + await reader.NextResultAsync(); + + if (await reader.ReadAsync()) + totalCount = reader.GetInt32(0); + + await reader.NextResultAsync(); + + while (await reader.ReadAsync()) + { + items.Add(new ItemList + { + ItemCodeId = Convert.ToInt64(reader["ItemCodeId"]), + ItemNo = Convert.ToInt64(reader["ItemNo"]), + ItemName = reader["ItemName"]?.ToString(), + ItemDescription = reader["ItemDescription"]?.ToString(), + ItemCategoryName = reader["ItemCategoryName"]?.ToString(), + CartItemCount = Convert.ToInt32(reader["CartItemCount"]) + }); + } + await conn.CloseAsync(); + + return new PagedResult + { + Data = items, + TotalCount = totalCount, + CategoryList = categoryList, + PageNumber = dto.PageNumber, + PageSize = dto.PageSize + }; + } + public async Task> GetItemColor(ItemDto itemDto) + { + var colors = await _dbContext.ItemColors + .Where(ic => EF.Functions.Like(ic.ItemColorName, $"%{itemDto.ItemColorName}%")) + .Take(5) + .ToListAsync(); + + return colors ?? new List(); + } + public async Task> GetItemUOM(ItemDto itemDto) + { + var uoms = await _dbContext.UnitOfMessures + .Where(ic => ic.IsActive == true && + EF.Functions.Like(ic.UOMName, $"%{itemDto.UOMName}%")) + .Take(150) + .ToListAsync(); + + return uoms ?? new List(); + } public async Task > GetDepartment(ItemCodeDto itemCode) { return await _dbContext.Departments @@ -366,18 +358,18 @@ namespace CPRNIMS.Domain.Services.Items return allItems ?? new List(); } - - public async Task> GetProjectCode() + public async Task> GetProjectCode() { return await _dbContext.ProjectCodes .AsNoTracking() .ToListAsync(); } - public async Task> GetProjectCodeByTerm(string? term) + public async Task> GetProjectCodeByTerm(string? term) { return await _dbContext.ProjectCodes .AsNoTracking() - .Where(p => EF.Functions.Like(p.ProjectCode, $"%{term}%")) + .Where(p => p.StatusName != "Completed" && p.IsActive + && EF.Functions.Like(p.ProjectCode, $"%{term}%")) .ToListAsync(); } } diff --git a/CPRNIMS.Domain/Services/PO/PurchaseOrder.cs b/CPRNIMS.Domain/Services/PO/PurchaseOrder.cs index 0e0b9bb..d963df2 100644 --- a/CPRNIMS.Domain/Services/PO/PurchaseOrder.cs +++ b/CPRNIMS.Domain/Services/PO/PurchaseOrder.cs @@ -30,6 +30,14 @@ namespace CPRNIMS.Domain.Services.PO _smptHelper = smptHelper; } #region Get + + public async Task> GetCurrencies(string currencyName, CancellationToken ct) + { + return await _dbContext.Currencies.AsNoTracking() + .Where(c => c.IsActive==true && + (string.IsNullOrEmpty(currencyName) || c.CurrencyName.Contains(currencyName))) + .ToListAsync(ct); + } public async Task GetPOFormDataAsync(long? poId) { // Reuse the connection from your existing DbContext @@ -493,7 +501,7 @@ namespace CPRNIMS.Domain.Services.PO await _dbContext.Database .ExecuteSqlRawAsync("EXEC PostPutCustomPO @UserId,@POTypeId,@PONumber,@PRDetailsId,@Specification,@PRNo,@PORemarks,@IncoTermsId," + $"@PODId,@ProfInvoiceNo,@ProfInvoiceDate,@PaymentTermsId,@ShippingInstructionId,@SupplierId,@DeliveryDate,@Discount,@Amount," + - $"@UnitPrice,@Quantity,@DeliverTo,@CountryOrigin, @MessCode OUTPUT, @Message OUTPUT", + $"@UnitPrice,@Quantity,@DeliverTo,@CountryOrigin,@CurrencyId, @MessCode OUTPUT, @Message OUTPUT", new SqlParameter("@UserId", pODto.UserId), new SqlParameter("@POTypeId", pODto.POTypeId), new SqlParameter("@PONumber", formattedPONumber), @@ -516,6 +524,7 @@ namespace CPRNIMS.Domain.Services.PO new SqlParameter("@Quantity", pODto.Quantity), new SqlParameter("@DeliverTo", pODto.DeliverTo), new SqlParameter("@CountryOrigin", pODto.CountryOrigin ?? "N/A"), + new SqlParameter("@CurrencyId", pODto.CurrencyId), messCode, message); @@ -544,7 +553,7 @@ namespace CPRNIMS.Domain.Services.PO await _dbContext.Database .ExecuteSqlRawAsync("EXEC PutExistingPO @UserId,@POTypeId,@PONumber,@PRDetailsId,@Specification,@PRNo,@PORemarks,@IncoTermsId," + $"@PODId,@ProfInvoiceNo,@ProfInvoiceDate,@PaymentTermsId,@ShippingInstructionId,@SupplierId,@DeliveryDate,@Discount,@Amount," + - $"@UnitPrice,@Quantity,@DeliverTo,@IsRemoved,@CountryOrigin, @MessCode OUTPUT, @Message OUTPUT", + $"@UnitPrice,@Quantity,@DeliverTo,@IsRemoved,@CountryOrigin,@CurrencyId, @MessCode OUTPUT, @Message OUTPUT", new SqlParameter("@UserId", pODto.UserId), new SqlParameter("@POTypeId", pODto.POTypeId), new SqlParameter("@PONumber", pODto.PONo), @@ -568,6 +577,7 @@ namespace CPRNIMS.Domain.Services.PO new SqlParameter("@DeliverTo", pODto.DeliverTo), new SqlParameter("@IsRemoved", isRemoved), new SqlParameter("@CountryOrigin", pODto.CountryOrigin ?? "N/A"), + new SqlParameter("@CurrencyId", pODto.CurrencyId), messCode, message); @@ -635,7 +645,8 @@ namespace CPRNIMS.Domain.Services.PO DeliverTo = PODto.DeliverTo ?? "N/A", Specification = specification, IsUpdate = PODto.IsUpdate, - CountryOrigin=PODto.CountryOrigin + CountryOrigin=PODto.CountryOrigin, + CurrencyId=PODto.CurrencyId }; } public async Task PostSuppDocRequirements(PODto poDto) diff --git a/CPRNIMS.Domain/Services/PR/PRequest.cs b/CPRNIMS.Domain/Services/PR/PRequest.cs index 1278e83..ade0f03 100644 --- a/CPRNIMS.Domain/Services/PR/PRequest.cs +++ b/CPRNIMS.Domain/Services/PR/PRequest.cs @@ -633,6 +633,17 @@ namespace CPRNIMS.Domain.Services.PR && pr.IsActive select pr).AnyAsync(); } + private async Task ProjectStatusChanges(int projectCodeId,string? status) + { + var project = await _dbContext.ProjectCodes.FirstOrDefaultAsync(pc=>pc.ProjectCodeId==projectCodeId); + if (project == null) + return false; + + if (project.StatusName == status) + return false; + else + return true; + } public async Task PRItemRemoval(PRDto prDto) { var (messCode, message) = CreateOutputParams(); @@ -653,7 +664,6 @@ namespace CPRNIMS.Domain.Services.PR }; return response; } - public async Task PostPutProjectCode(PRDto prDto) { if (prDto == null) throw new ArgumentNullException(nameof(prDto)); @@ -669,13 +679,14 @@ namespace CPRNIMS.Domain.Services.PR ProjectName = prDto.ProjectName, DeliveryAddress = prDto.DeliveryAddress, MaxDays = prDto.MaxDays, + StatusName = prDto.StatusName, IsActive = prDto.IsActive }; await _dbContext.ProjectCodes.AddAsync(project); } else { - if (await IsUsingAsync(prDto.ProjectCodeId)) + if (await IsUsingAsync(prDto.ProjectCodeId) && await ProjectStatusChanges(prDto.ProjectCodeId,prDto.StatusName) == false) { return new ResponseObject() { @@ -684,12 +695,17 @@ namespace CPRNIMS.Domain.Services.PR success = false, }; } + if (await IsUsingAsync(prDto.ProjectCodeId)) + { + existing.StatusName = prDto.StatusName; + } else { existing.ProjectCode = prDto.ProjectCode; existing.ProjectName = prDto.ProjectName; existing.DeliveryAddress = prDto.DeliveryAddress; existing.MaxDays = prDto.MaxDays; + existing.StatusName = prDto.StatusName; existing.IsActive = prDto.IsActive; } } diff --git a/CPRNIMS.Domain/Services/Receiving/Receiving.cs b/CPRNIMS.Domain/Services/Receiving/Receiving.cs index 37ed0c8..4302291 100644 --- a/CPRNIMS.Domain/Services/Receiving/Receiving.cs +++ b/CPRNIMS.Domain/Services/Receiving/Receiving.cs @@ -73,7 +73,7 @@ namespace CPRNIMS.Domain.Services.Receiving return allItems ?? new List(); } - public async Task> GetRRDetail(ItemDto itemDto) + public async Task> GetRRDetail(ItemDto itemDto) { var allItems = await _dbContext.RRDetailss .FromSqlRaw("EXEC GetRRDetail @RRNo,@UserId", @@ -81,7 +81,7 @@ namespace CPRNIMS.Domain.Services.Receiving new SqlParameter("@UserId", itemDto.UserId)) .ToListAsync(); - return allItems ?? new List(); + return allItems ?? new List(); } #endregion #region Post Put diff --git a/CPRNIMS.Domain/UIContracts/Inventory/IMRS.cs b/CPRNIMS.Domain/UIContracts/Inventory/IMRS.cs index db894dd..c762070 100644 --- a/CPRNIMS.Domain/UIContracts/Inventory/IMRS.cs +++ b/CPRNIMS.Domain/UIContracts/Inventory/IMRS.cs @@ -16,5 +16,7 @@ namespace CPRNIMS.Domain.UIContracts.Inventory Task> CreateMRS(CreateMRSRequest request, CancellationToken ct); Task> ApproveMRS(ApproveMRSRequest request, CancellationToken ct); Task> CancelMRS(CancelMRSRequest request, CancellationToken ct); + Task>> SearchRIS(SearchRISProjectCodeRequest request, CancellationToken ct); + Task>> SearchProjects(SearchRISProjectCodeRequest request, CancellationToken ct); } } diff --git a/CPRNIMS.Domain/UIContracts/PO/IPurchaseOrder.cs b/CPRNIMS.Domain/UIContracts/PO/IPurchaseOrder.cs index 254db89..9b904dd 100644 --- a/CPRNIMS.Domain/UIContracts/PO/IPurchaseOrder.cs +++ b/CPRNIMS.Domain/UIContracts/PO/IPurchaseOrder.cs @@ -11,6 +11,7 @@ namespace CPRNIMS.Domain.UIContracts.PO public interface IPurchaseOrder { #region Get + Task> GetCurrencies(User user, POVM viewModels); Task> GetSupplierBidById(User user, POVM viewModel); Task> GetSupplierBidByItem(User user, POVM viewModel); Task> GetSupplierBid(User user, POVM viewModel); diff --git a/CPRNIMS.Domain/UIServices/Inventory/MRS.cs b/CPRNIMS.Domain/UIServices/Inventory/MRS.cs index 7ccc98d..bb3e148 100644 --- a/CPRNIMS.Domain/UIServices/Inventory/MRS.cs +++ b/CPRNIMS.Domain/UIServices/Inventory/MRS.cs @@ -1,4 +1,5 @@ -using CPRNIMS.Domain.Services; +using Azure.Core; +using CPRNIMS.Domain.Services; using CPRNIMS.Domain.UIContracts.Common; using CPRNIMS.Domain.UIContracts.Inventory; using CPRNIMS.Infrastructure.Dto.Common; @@ -141,5 +142,56 @@ namespace CPRNIMS.Domain.UIServices.Inventory return result; } + + public async Task>> SearchRIS(SearchRISProjectCodeRequest request, CancellationToken ct) + { + var token = await _tokenHelper.GetValidTokenAsync(); + if (string.IsNullOrEmpty(token)) + throw new InvalidOperationException("Token has been expired."); + + var baseEndpoint = _configuration["LLI:NonInvent:InventoryMgmt:SearchRIS"] + ?? throw new InvalidOperationException("GetMRS endpoint is not configured."); + + var qs = new StringBuilder(baseEndpoint).Append('?'); + + if (!string.IsNullOrWhiteSpace(request.SearchRISNo)) + qs.Append($"&searchRISNo={Uri.EscapeDataString(request.SearchRISNo)}"); + if (!string.IsNullOrWhiteSpace(request.SearchRISNo)) + qs.Append($"&projectCodeId= {request.SearchProjectCodeId}"); + + using var http = _apiConfigurationService.CreateHttpClientWithDefaultHeaders(token); + var response = await http.GetAsync(qs.ToString(), ct); + var json = await response.Content.ReadAsStringAsync(ct); + + if (!response.IsSuccessStatusCode) + return new ApiResponse>{ }; + + var result = JsonSerializer.Deserialize>>(json, _mrsJsonOpts); + return result ?? new ApiResponse>(); + } + + public async Task>> SearchProjects(SearchRISProjectCodeRequest request, CancellationToken ct) + { + var token = await _tokenHelper.GetValidTokenAsync(); + if (string.IsNullOrEmpty(token)) + throw new InvalidOperationException("Token has expired."); + + var baseEndpoint = _configuration["LLI:NonInvent:InventoryMgmt:SearchProjects"] + ?? throw new InvalidOperationException("SearchProjects endpoint is not configured."); + + var qs = new StringBuilder(baseEndpoint); + if (!string.IsNullOrWhiteSpace(request.SearchProjectCode)) + qs.Append('?').Append("searchProjectCode=").Append(Uri.EscapeDataString(request.SearchProjectCode)); + + using var http = _apiConfigurationService.CreateHttpClientWithDefaultHeaders(token); + var response = await http.GetAsync(qs.ToString(), ct); + var json = await response.Content.ReadAsStringAsync(ct); + + if (!response.IsSuccessStatusCode) + return new ApiResponse>(); + + var result = JsonSerializer.Deserialize>>(json, _mrsJsonOpts); + return result ?? new ApiResponse>(); + } } } diff --git a/CPRNIMS.Domain/UIServices/PO/PurchaseOrder.cs b/CPRNIMS.Domain/UIServices/PO/PurchaseOrder.cs index 022d028..7d6a92b 100644 --- a/CPRNIMS.Domain/UIServices/PO/PurchaseOrder.cs +++ b/CPRNIMS.Domain/UIServices/PO/PurchaseOrder.cs @@ -284,6 +284,11 @@ namespace CPRNIMS.Domain.UIServices.PO return await SendGetApiRequest(user, viewModel, _configuration["LLI:NonInvent:POMgmt:GetPortOfDischarge"]); } + public async Task> GetCurrencies(User user, POVM viewModel) + { + return await SendGetApiRequest(user, viewModel, + _configuration["LLI:NonInvent:POMgmt:GetCurrencies"]); + } #endregion #region Post Put public async Task PostApprovedSupplier(User user, POVM viewModel) diff --git a/CPRNIMS.Infrastructure/Database/NonInventoryDbContext.cs b/CPRNIMS.Infrastructure/Database/NonInventoryDbContext.cs index 82e7b57..c2e06c4 100644 --- a/CPRNIMS.Infrastructure/Database/NonInventoryDbContext.cs +++ b/CPRNIMS.Infrastructure/Database/NonInventoryDbContext.cs @@ -40,6 +40,7 @@ namespace CPRNIMS.Infrastructure.Database public virtual DbSet ItemCodes { get; set; } public virtual DbSet ItemList { get; set; } public virtual DbSet Items { get; set; } + public DbSet ItemDtos { get; set; } public DbSet Attachments { get; set; } public virtual DbSet AttachmentExtensions { get; set; } public virtual DbSet AttachmentFileTypes { get; set; } @@ -127,6 +128,7 @@ namespace CPRNIMS.Infrastructure.Database public virtual DbSet PaymentTerms { get; set; } public virtual DbSet Incoterms { get; set; } public virtual DbSet CentralPONos { get; set; } + public DbSet Currencies { get; set; } #endregion #region Inventory @@ -148,10 +150,11 @@ namespace CPRNIMS.Infrastructure.Database public virtual DbSet ForReceivings { get; set; } public virtual DbSet RRReports { get; set; } public virtual DbSet ReceivingDetails { get; set; } - public virtual DbSet RRDetails { get; set; } + public virtual DbSet RRDetailDtos { get; set; } public virtual DbSet ForRRs { get; set; } public virtual DbSet RRs { get; set; } - public virtual DbSet RRDetailss { get; set; } + public virtual DbSet RRDetailss { get; set; } + public virtual DbSet RRDetails { get; set; } public virtual DbSet RRSeries { get; set; } #endregion @@ -294,7 +297,15 @@ namespace CPRNIMS.Infrastructure.Database .WithMany() .HasForeignKey(t => t.PRDetailId) .OnDelete(DeleteBehavior.Restrict); + + e.HasOne(r => r.RRDetails) + .WithMany() + .HasForeignKey(r => r.RRDetailId) + .IsRequired(false) + .HasForeignKey(r => r.RRDetailId) + .OnDelete(DeleteBehavior.Restrict); }); + modelBuilder.Entity(e => { e.HasOne(i => i.PRs) @@ -312,6 +323,10 @@ namespace CPRNIMS.Infrastructure.Database e.HasOne(r => r.Discipline) .WithMany() .HasForeignKey(r => r.DisciplineId); + + e.HasOne(r => r.ProjectCodes) + .WithMany() + .HasForeignKey(r => r.ProjectCodeId); }); modelBuilder.Entity(e => { diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/DisciplineDto.cs b/CPRNIMS.Infrastructure/Dto/Inventory/DisciplineDto.cs index 442ba21..fc45cc1 100644 --- a/CPRNIMS.Infrastructure/Dto/Inventory/DisciplineDto.cs +++ b/CPRNIMS.Infrastructure/Dto/Inventory/DisciplineDto.cs @@ -11,4 +11,10 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory public byte DisciplineId { get; set; } public string DisciplineName { get; set; } = string.Empty; } + public class ProjectCodeDto + { + public string ProjectCode { get; set; } = string.Empty; + public string ProjectName { get; set; } = string.Empty; + public int ProjectCodeId { get; set; } + } } diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/RISSearchResultDto.cs b/CPRNIMS.Infrastructure/Dto/Inventory/RISSearchResultDto.cs new file mode 100644 index 0000000..cab1928 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/RISSearchResultDto.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class RISSearchResultDto + { + public long RISId { get; set; } + public string RISNo { get; set; } = string.Empty; + public int ProjectCodeId { get; set; } + public string ProjectCode { get; set; } = string.Empty; + public string ProjectName { get; set; } = string.Empty; + public string DisciplineName { get; set; } = string.Empty; + public decimal QtyAvailableToReturn { get; set; } + } + + public class ProjectCodeOptionDto + { + public int ProjectCodeId { get; set; } + public string ProjectCode { get; set; } = string.Empty; + public string ProjectName { get; set; } = string.Empty; + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Reports/ReportDtos.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Reports/ReportDtos.cs index 6b075ea..d756fac 100644 --- a/CPRNIMS.Infrastructure/Dto/Inventory/Reports/ReportDtos.cs +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Reports/ReportDtos.cs @@ -39,7 +39,7 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory.Reports public string ItemName { get; set; } = string.Empty; public long ItemNo { get; set; } public string DisciplineName { get; set; } = string.Empty; - public string IssuedTo { get; set; } = string.Empty; + public string ProjectName { get; set; } = string.Empty; public decimal QtyIssued { get; set; } public decimal TotalReturned { get; set; } public decimal NetIssued { get; set; } @@ -121,6 +121,7 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory.Reports public decimal TotalOnHand { get; set; } public decimal TotalQtyIn { get; set; } public decimal TotalQtyOut { get; set; } + public decimal TotalValue { get; set; } public int LowStockCount { get; set; } public int OutOfStockCount { get; set; } } @@ -134,6 +135,7 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory.Reports public decimal QtyIn { get; set; } public decimal QtyOut { get; set; } public decimal QtyOnHand { get; set; } + public decimal UnitPrice { get; set; } public int StockPct { get; set; } } diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateRISRequest.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateRISRequest.cs index 6f56b43..49173ee 100644 --- a/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateRISRequest.cs +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateRISRequest.cs @@ -10,7 +10,7 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory.Request { public int InventoryId { get; set; } public long PRDetailId { get; set; } - public string IssuedTo { get; set; } = string.Empty; + public int ProjectCodeId { get; set; } public byte DisciplineId { get; set; } public decimal QtyIssued { get; set; } public string? Remarks { get; set; } diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Request/SearchRISProjectCodeRequest.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Request/SearchRISProjectCodeRequest.cs new file mode 100644 index 0000000..a45108b --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Request/SearchRISProjectCodeRequest.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Request +{ + public class SearchRISProjectCodeRequest + { + public int? SearchProjectCodeId { get; set; } + public string? SearchRISNo { get; set; } + public string? SearchProjectCode { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISPagedResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISPagedResponse.cs index 410715d..a12ff2a 100644 --- a/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISPagedResponse.cs +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISPagedResponse.cs @@ -27,7 +27,9 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory.Response public long ItemNo { get; set; } - public string? IssuedTo { get; set; } + public string? ProjectCode { get; set; } + + public string? ProjectName { get; set; } public string? DisciplineName { get; set; } diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISProjectCodeResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISProjectCodeResponse.cs new file mode 100644 index 0000000..78e64da --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISProjectCodeResponse.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Response +{ + public class RISProjectCodeResponse + { + public string ProjectCode { get; set; }=string.Empty; + public string ProjectName { get; set; } = string.Empty; + + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISResponse.cs index d2fd405..f70fc35 100644 --- a/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISResponse.cs +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISResponse.cs @@ -14,7 +14,7 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory.Response public string ItemName { get; set; } = string.Empty; public long ItemNo { get; set; } public string? LotNo { get; set; } - public string IssuedTo { get; set; } = string.Empty; + public int ProjectCodeId { get; set; } public string DisciplineName { get; set; } = string.Empty; public string? Message { get; set; } public byte DisciplineId { get; set; } @@ -28,5 +28,7 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory.Response public DateTime? ApprovedDate { get; set; } public decimal MRSCount { get; set; } public decimal TotalReturned { get; set; } + public string? ProjectName { get; set; } + public string? ProjectCode { get; set; } } } diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/SearchRISProjectCodeResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/SearchRISProjectCodeResponse.cs new file mode 100644 index 0000000..7c9c185 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/SearchRISProjectCodeResponse.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Response +{ + public class SearchApiResponse + { + public bool Success { get; set; } + public List data { get; set; } = new List(); + } + public class SearchRISProjectCodeResponse + { + public long RISId { get; set; } + public string RISNo { get; set; } = string.Empty; + public int ProjectCodeId { get; set; } + public string ProjectCode { get; set; } = string.Empty; + public string ProjectName { get; set; } = string.Empty; + public string DisciplineName { get; set; } = string.Empty; + public decimal QtyAvailableToReturn { get; set; } + } + public class ProjectCodeOptionResponse + { + public int ProjectCodeId { get; set; } + public string ProjectCode { get; set; } = string.Empty; + public string ProjectName { get; set; } = string.Empty; + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/TransactContextDto.cs b/CPRNIMS.Infrastructure/Dto/Inventory/TransactContextDto.cs index f2d0f95..406cca6 100644 --- a/CPRNIMS.Infrastructure/Dto/Inventory/TransactContextDto.cs +++ b/CPRNIMS.Infrastructure/Dto/Inventory/TransactContextDto.cs @@ -17,6 +17,7 @@ namespace CPRNIMS.Infrastructure.Dto.Inventory public decimal QtyOnHand { get; set; } public decimal QtyIn { get; set; } public decimal QtyOut { get; set; } + public IEnumerable ProjectCodes { get; set; } = []; public IEnumerable Disciplines { get; set; } = []; public IEnumerable OpenRISList { get; set; } = []; } diff --git a/CPRNIMS.Infrastructure/Dto/PO/PODto.cs b/CPRNIMS.Infrastructure/Dto/PO/PODto.cs index 812f2ad..5119a95 100644 --- a/CPRNIMS.Infrastructure/Dto/PO/PODto.cs +++ b/CPRNIMS.Infrastructure/Dto/PO/PODto.cs @@ -23,7 +23,7 @@ namespace CPRNIMS.Infrastructure.Dto.PO public string? SupplierName { get; set; } public string? Manufacturer { get; set; } public int ItemCount { get; set; } - public short CurrencyId { get; set; } + public byte CurrencyId { get; set; } public string? Department { get; set; } public string? ItemCategoryName { get; set; } public DateTime CommitmentDate { get; set; } diff --git a/CPRNIMS.Infrastructure/Entities/Account/ApplicationUser.cs b/CPRNIMS.Infrastructure/Entities/Account/ApplicationUser.cs index 2787f66..bb4b0c7 100644 --- a/CPRNIMS.Infrastructure/Entities/Account/ApplicationUser.cs +++ b/CPRNIMS.Infrastructure/Entities/Account/ApplicationUser.cs @@ -23,6 +23,7 @@ namespace CPRNIMS.Infrastructure.Entities.Account public DateTime UpdatedDate { get; set; } public string? ProfilePicture { get; set; } public string? Address { get; set; } + public bool? IsActive { get; set; } public Attachment? Attachment { get; set; } } } diff --git a/CPRNIMS.Infrastructure/Entities/Finance/RRDetail.cs b/CPRNIMS.Infrastructure/Entities/Finance/RRDetailDto.cs similarity index 96% rename from CPRNIMS.Infrastructure/Entities/Finance/RRDetail.cs rename to CPRNIMS.Infrastructure/Entities/Finance/RRDetailDto.cs index 07f67a5..73cb990 100644 --- a/CPRNIMS.Infrastructure/Entities/Finance/RRDetail.cs +++ b/CPRNIMS.Infrastructure/Entities/Finance/RRDetailDto.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace CPRNIMS.Infrastructure.Entities.Finance { - public class RRDetail : CommonProperties + public class RRDetailDto : CommonProperties { [Key] public long RRDetailId { get; set; } diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/InventTrans.cs b/CPRNIMS.Infrastructure/Entities/Inventory/InventTrans.cs index 542d8bf..a129954 100644 --- a/CPRNIMS.Infrastructure/Entities/Inventory/InventTrans.cs +++ b/CPRNIMS.Infrastructure/Entities/Inventory/InventTrans.cs @@ -18,7 +18,6 @@ namespace CPRNIMS.Infrastructure.Entities.Inventory public string CreatedBy { get; set; }=string.Empty; public bool IsActive { get; set; } public Inventory? Inventory { get; set; } - // public InventTransDetail? InventTransDetail { get; set; } public ICollection InventTransDetails { get; set; } = []; } } diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/InventTransDetail.cs b/CPRNIMS.Infrastructure/Entities/Inventory/InventTransDetail.cs index 16e8762..db12408 100644 --- a/CPRNIMS.Infrastructure/Entities/Inventory/InventTransDetail.cs +++ b/CPRNIMS.Infrastructure/Entities/Inventory/InventTransDetail.cs @@ -1,5 +1,6 @@ using CPRNIMS.Infrastructure.Entities.Items; using CPRNIMS.Infrastructure.Entities.Purchasing; +using CPRNIMS.Infrastructure.Entities.Receiving; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; @@ -17,15 +18,15 @@ namespace CPRNIMS.Infrastructure.Entities.Inventory public long InventTransDetailId { get; set; } public int InventTransId { get; set; } public byte TransTypeId { get; set; } - public long RRDetailId { get; set; } public decimal QtyIn { get; set; } public decimal QtyOut { get; set; } public DateTime CreatedDate { get; set; } public string? Remarks { get; set; } public bool IsActive { get; set; } public long PRDetailId { get; set; } + public long? RRDetailId { get; set; } public PRDetails? PRDetails { get; set; } - public ItemCategory? ItemCategory { get; set; } + public RRDetails? RRDetails { get; set; } public InventTrans? InventTrans { get; set; } } } diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/RIS.cs b/CPRNIMS.Infrastructure/Entities/Inventory/RIS.cs index 3f95684..85809fa 100644 --- a/CPRNIMS.Infrastructure/Entities/Inventory/RIS.cs +++ b/CPRNIMS.Infrastructure/Entities/Inventory/RIS.cs @@ -20,10 +20,6 @@ namespace CPRNIMS.Infrastructure.Entities.Inventory public int InventoryId { get; set; } public long PRDetailId { get; set; } - - [Required, MaxLength(450)] - public string IssuedTo { get; set; } = string.Empty; - public byte DisciplineId { get; set; } public decimal QtyIssued { get; set; } @@ -40,6 +36,8 @@ namespace CPRNIMS.Infrastructure.Entities.Inventory public string? CanceledBy { get; set; } public DateTime? CanceledDate { get; set; } public string? Reason { get; set; } + public int ProjectCodeId { get; set; } + public ProjectCodes ProjectCodes { get; set; } = null!; public Inventory Inventory { get; set; } = null!; public PRDetails PRDetail { get; set; } = null!; public Discipline Discipline { get; set; } = null!; diff --git a/CPRNIMS.Infrastructure/Entities/Items/ItemDtos.cs b/CPRNIMS.Infrastructure/Entities/Items/ItemDtos.cs new file mode 100644 index 0000000..ccba894 --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/Items/ItemDtos.cs @@ -0,0 +1,41 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Entities.Items +{ + public class ItemDtos + { + [Key] + public long ItemNo { get; set; } + public long ItemCodeId { get; set; } + public string? Department { get; set; } + public string? ItemCategoryName { get; set; } + public string? UserId { get; set; } + public string? ItemName { get; set; } + public string? ItemDescription { get; set; } + public string? StatusName { get; set; } + public bool IsActive { get; set; } + public bool IsCommon { get; set; } + public byte RequestTypeId { get; set; } + public string? ItemLocalName { get; set; } + public string? ItemTypeName { get; set; } + public string? PRTypeName { get; set; } + public decimal Qty { get; set; } + public int ItemColorId { get; set; } + public short ItemLocalId { get; set; } + public int UOMId { get; set; } + public short ItemCategoryId { get; set; } + public string? PackagingTypeName { get; set; } + public short ItemClassId { get; set; } + public string? UOMName { get; set; } + public string? ItemColorName { get; set; } + public long ItemAttachId { get; set; } + public string? ItemAttachPath { get; set; } + public bool IsMDLD { get; set; } + public bool CheckBox { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Entities/PO/Currencies.cs b/CPRNIMS.Infrastructure/Entities/PO/Currencies.cs new file mode 100644 index 0000000..cc92620 --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/PO/Currencies.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Entities.PO +{ + [Table("Currencies")] + public class Currencies + { + [Key] + public byte CurrencyId { get; set; } + public string CurrencyName { get; set; }=string.Empty; + public decimal VatRate { get; set; } + public decimal CER { get; set; } + public string? AmountWords { get; set; } + public bool? IsActive { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Entities/PO/POHeader.cs b/CPRNIMS.Infrastructure/Entities/PO/POHeader.cs index 3d1be6c..100c1cf 100644 --- a/CPRNIMS.Infrastructure/Entities/PO/POHeader.cs +++ b/CPRNIMS.Infrastructure/Entities/PO/POHeader.cs @@ -34,6 +34,7 @@ namespace CPRNIMS.Infrastructure.Entities.PO public byte PODId { get; set; } public byte POTypeId { get; set; } public byte IncoTermsId { get; set; } + public byte CurrencyId { get; set; } public string? IncotermsName { get; set; } public string? CountryOrigin { get; set; } } diff --git a/CPRNIMS.Infrastructure/Entities/Purchasing/ProjectCodes.cs b/CPRNIMS.Infrastructure/Entities/Purchasing/ProjectCodes.cs index 7f90ed0..7726e43 100644 --- a/CPRNIMS.Infrastructure/Entities/Purchasing/ProjectCodes.cs +++ b/CPRNIMS.Infrastructure/Entities/Purchasing/ProjectCodes.cs @@ -17,6 +17,7 @@ namespace CPRNIMS.Infrastructure.Entities.Purchasing public string? ProjectName { get; set; } public int MaxDays { get; set; } public string? DeliveryAddress { get; set; } + public string? StatusName { get; set; } public bool IsActive { get; set; } } } diff --git a/CPRNIMS.Infrastructure/Entities/Receiving/RRDetail.cs b/CPRNIMS.Infrastructure/Entities/Receiving/RRDetailDto.cs similarity index 98% rename from CPRNIMS.Infrastructure/Entities/Receiving/RRDetail.cs rename to CPRNIMS.Infrastructure/Entities/Receiving/RRDetailDto.cs index ace4bac..f81c4fd 100644 --- a/CPRNIMS.Infrastructure/Entities/Receiving/RRDetail.cs +++ b/CPRNIMS.Infrastructure/Entities/Receiving/RRDetailDto.cs @@ -8,7 +8,7 @@ using System.Threading.Tasks; namespace CPRNIMS.Infrastructure.Entities.Receiving { - public class RRDetail + public class RRDetailDto { [Key] public long PRDetailsId { get; set; } diff --git a/CPRNIMS.Infrastructure/Entities/Receiving/RRDetails.cs b/CPRNIMS.Infrastructure/Entities/Receiving/RRDetails.cs new file mode 100644 index 0000000..5546022 --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/Receiving/RRDetails.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Entities.Receiving +{ + [Table("RRDetails")] + public class RRDetails + { + [Key] + public long RRDetailId { get; set; } + public long PRDetailId { get; set; } + public long RRId { get; set; } + public long PODetailId { get; set; } + public decimal Quantity { get; set; } + public decimal QuantityReceived { get; set; } + public decimal QtyRemaining { get; set; } + public decimal UnitPrice { get; set; } + public bool IsActive { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Models/Account/User.cs b/CPRNIMS.Infrastructure/Models/Account/User.cs index 2a96675..1ff6281 100644 --- a/CPRNIMS.Infrastructure/Models/Account/User.cs +++ b/CPRNIMS.Infrastructure/Models/Account/User.cs @@ -23,5 +23,6 @@ namespace CPRNIMS.Infrastructure.Models.Account public string? Token { get; set; } public string? Company { get; set; } public string? MyAccess { get; set; } + public int DepartmentId { get; set; } } } diff --git a/CPRNIMS.Infrastructure/ViewModel/PO/POVM.cs b/CPRNIMS.Infrastructure/ViewModel/PO/POVM.cs index 5489a00..45cb431 100644 --- a/CPRNIMS.Infrastructure/ViewModel/PO/POVM.cs +++ b/CPRNIMS.Infrastructure/ViewModel/PO/POVM.cs @@ -24,7 +24,7 @@ namespace CPRNIMS.Infrastructure.ViewModel.PO public string? ContactPerson { get; set; } public string? Manufacturer { get; set; } public int ItemCount { get; set; } - public short CurrencyId { get; set; } + public byte CurrencyId { get; set; } public string? Department { get; set; } public string? ItemCategoryName { get; set; } public DateTime CommitmentDate { get; set; } diff --git a/CPRNIMS.WebApi/CPRNIMS.WebApi.csproj b/CPRNIMS.WebApi/CPRNIMS.WebApi.csproj index d14d03a..e381846 100644 --- a/CPRNIMS.WebApi/CPRNIMS.WebApi.csproj +++ b/CPRNIMS.WebApi/CPRNIMS.WebApi.csproj @@ -29,9 +29,6 @@ - - - diff --git a/CPRNIMS.WebApi/Controllers/Inventory/MRSMgmtController.cs b/CPRNIMS.WebApi/Controllers/Inventory/MRSMgmtController.cs index 8f907f7..e452332 100644 --- a/CPRNIMS.WebApi/Controllers/Inventory/MRSMgmtController.cs +++ b/CPRNIMS.WebApi/Controllers/Inventory/MRSMgmtController.cs @@ -23,7 +23,20 @@ namespace CPRNIMS.WebApi.Controllers.Inventory var result = await _mrs.GetPagedAsync(filter, ct, currentUser.DepartmentId, currentUser.UserName); return Ok(result); } - [HttpPost()] + [HttpGet("SearchRIS")] + public async Task SearchRIS([FromQuery] string? searchRISNo, int? projectCodeId, CancellationToken ct) + { + var results = await _mrs.SearchRISForReturnAsync(searchRISNo, projectCodeId, ct); + return Ok(new { success = true, data = results }); + } + + [HttpGet("SearchProjects")] + public async Task SearchProjects([FromQuery] string? searchProjectCode, CancellationToken ct) + { + var results = await _mrs.GetProjectsWithOpenRISAsync(searchProjectCode, ct); + return Ok(new { success = true, data = results }); + } + [HttpPost] public async Task CreateMRS([FromBody] CreateMRSRequest request, CancellationToken ct) { var currentUser = User.ToUserClaims(); diff --git a/CPRNIMS.WebApi/Controllers/PO/POMgmtController.cs b/CPRNIMS.WebApi/Controllers/PO/POMgmtController.cs index 01b329c..ee15b00 100644 --- a/CPRNIMS.WebApi/Controllers/PO/POMgmtController.cs +++ b/CPRNIMS.WebApi/Controllers/PO/POMgmtController.cs @@ -284,6 +284,12 @@ namespace CPRNIMS.WebApi.Controllers.PO } #endregion #region Get + [HttpPost("GetCurrencies")] + public async Task GetCurrencies(Currencies request, CancellationToken ct) + { + var data = await _purchaseOrder.GetCurrencies(request.CurrencyName,ct); + return Ok(data); + } [HttpGet("GetPOFormData")] public async Task GetPOFormData(int? poId = null) { diff --git a/CPRNIMS.WebApi/Program.cs b/CPRNIMS.WebApi/Program.cs index 152a480..66e6090 100644 --- a/CPRNIMS.WebApi/Program.cs +++ b/CPRNIMS.WebApi/Program.cs @@ -17,14 +17,14 @@ if (app.Environment.IsDevelopment()) app.UseSwagger(); app.UseSwaggerUI(c => { - c.SwaggerEndpoint("./v2/swagger.json", "LLOYD API V2"); //originally "./swagger/v1/swagger.json" + c.SwaggerEndpoint("./v2/swagger.json", "LLOYD API V2"); }); } app.UseMiddleware(); app.UseSwagger(); app.UseSwaggerUI(c => { - c.SwaggerEndpoint("./v2/swagger.json", "LLOYD API V2"); //originally "./swagger/v1/swagger.json" + c.SwaggerEndpoint("./v2/swagger.json", "LLOYD API V2"); }); app.UseCors("AllowAnyOrigin"); diff --git a/CPRNIMS.WebApi/Sql/Phase 5/Table.sql b/CPRNIMS.WebApi/Sql/Phase 5/Table.sql index afa20a8..a7c898e 100644 --- a/CPRNIMS.WebApi/Sql/Phase 5/Table.sql +++ b/CPRNIMS.WebApi/Sql/Phase 5/Table.sql @@ -16,7 +16,7 @@ CREATE TABLE [dbo].[RIS] ( [RISNo] VARCHAR(50) NOT NULL, -- generated slip number [InventoryId] INT NOT NULL, [PRDetailId] BIGINT NOT NULL, - [IssuedTo] VARCHAR(450) NOT NULL, -- UserId receiving items + [ProjectCodeId] INT NOT NULL, -- UserId receiving items [DisciplineId] TINYINT NOT NULL, -- Trade/Matrix/Structural/Architectural [QtyIssued] DECIMAL(14,2) NOT NULL, [Remarks] VARCHAR(500) NULL, @@ -30,7 +30,8 @@ CREATE TABLE [dbo].[RIS] ( Reason VARCHAR(150) NULL, FOREIGN KEY ([InventoryId]) REFERENCES [Inventory]([InventoryId]), FOREIGN KEY ([PRDetailId]) REFERENCES [PRDetails]([PRDetailsId]), - FOREIGN KEY ([DisciplineId]) REFERENCES [Disciplines]([DisciplineId]) + FOREIGN KEY ([DisciplineId]) REFERENCES [Disciplines]([DisciplineId]), + FOREIGN KEY ([ProjectCodeId]) REFERENCES ProjectCodes([ProjectCodeId]) ); -- ── MRS: Material Return Slip ───────────────────────────────────── diff --git a/CPRNIMS.WebApps/Controllers/Base/BaseMethod.cs b/CPRNIMS.WebApps/Controllers/Base/BaseMethod.cs index 6d8eef9..e3b3b4a 100644 --- a/CPRNIMS.WebApps/Controllers/Base/BaseMethod.cs +++ b/CPRNIMS.WebApps/Controllers/Base/BaseMethod.cs @@ -43,6 +43,7 @@ namespace CPRNIMS.WebApps.Controllers.Base UserName = User.Identity?.Name, FullName = User.FindFirst("FullName")?.Value, Company = User.FindFirst("Company")?.Value, + DepartmentId = Convert.ToInt32(User.FindFirst("DepartmentId")?.Value), MyAccess = UserRoles, URLAttachment = User.FindFirst("URLAttachment")?.Value }; diff --git a/CPRNIMS.WebApps/Controllers/Inventory/InventoryMgmtController.cs b/CPRNIMS.WebApps/Controllers/Inventory/InventoryMgmtController.cs index b65d8ab..b9b59f5 100644 --- a/CPRNIMS.WebApps/Controllers/Inventory/InventoryMgmtController.cs +++ b/CPRNIMS.WebApps/Controllers/Inventory/InventoryMgmtController.cs @@ -5,6 +5,7 @@ using CPRNIMS.Infrastructure.Helper; using CPRNIMS.Infrastructure.ViewModel.Inventory; using CPRNIMS.WebApps.Controllers.Base; using Microsoft.AspNetCore.Mvc; +using System.Threading.Tasks; namespace CPRNIMS.WebApps.Controllers.Inventory @@ -133,7 +134,10 @@ namespace CPRNIMS.WebApps.Controllers.Inventory #region Views public IActionResult GetInventoryTabPage(int id) { - return ViewComponent("InventoryTabPage", new { inventoryTabPageId = id }); + var currentDepartment = GetUser(); + bool isFinance = currentDepartment.DepartmentId is 6 or 9; + + return ViewComponent("InventoryTabPage", new { inventoryTabPageId = id, isFinance }); } public async Task Inventory() { diff --git a/CPRNIMS.WebApps/Controllers/Inventory/MRSMgmtController.cs b/CPRNIMS.WebApps/Controllers/Inventory/MRSMgmtController.cs index 2eaa661..eadcdc5 100644 --- a/CPRNIMS.WebApps/Controllers/Inventory/MRSMgmtController.cs +++ b/CPRNIMS.WebApps/Controllers/Inventory/MRSMgmtController.cs @@ -40,7 +40,25 @@ namespace CPRNIMS.WebApps.Controllers.Inventory return Json(new { data = result.Data, recordsTotal = result.RecordsTotal}); } + [HttpGet] + public async Task SearchRIS([FromQuery] int? searchProjectCodeId, string? searchRISNo , CancellationToken ct = default) + { + var result = await _mrs.SearchRIS(new SearchRISProjectCodeRequest + { + SearchRISNo = searchRISNo, + SearchProjectCodeId = searchProjectCodeId, + }, ct); + return Json(new { data = result.data, success = result.success, message = result.message }); + } + [HttpGet] + public async Task SearchProjects([FromQuery] string? searchProjectCode, CancellationToken ct = default) + { + var result = await _mrs.SearchProjects(new SearchRISProjectCodeRequest + { SearchProjectCode = searchProjectCode,}, ct); + + return Json(new { data = result.data, success = result.success, message = result.message }); + } [HttpPost] public async Task CreateMRS([FromBody] CreateMRSRequest request,CancellationToken ct) { diff --git a/CPRNIMS.WebApps/Controllers/PO/POMgmtController.cs b/CPRNIMS.WebApps/Controllers/PO/POMgmtController.cs index 71803ed..1e039e6 100644 --- a/CPRNIMS.WebApps/Controllers/PO/POMgmtController.cs +++ b/CPRNIMS.WebApps/Controllers/PO/POMgmtController.cs @@ -418,6 +418,26 @@ namespace CPRNIMS.WebApps.Controllers.PO response = await _purchaseOrder.GetOtherCharges(GetUser(), viewModels); return GetResponse(response); } + [HttpGet] + public async Task GetCurrencies([FromQuery] string query) + { + var viewModels = new POVM(); + viewModels.CurrencyName = query; + var responseQuery = await _purchaseOrder.GetCurrencies(GetUser(), viewModels); + + if (responseQuery == null) + { + responseQuery = new List(); + } + var formattedData = responseQuery.Select(item => new + { + label = item.CurrencyName, + value = item.CurrencyId, + value2 = item.Currency + }); + + return Json(new { success = true, data = formattedData }); + } public async Task GetSuppliers(string query) { var viewModels = new POVM(); @@ -435,6 +455,7 @@ namespace CPRNIMS.WebApps.Controllers.PO value2 = item.Currency, value3 = item.PaymentTerms, value4 = item.PaymentTermsId, + value5 = item.CurrencyId }); return Json(new { success = true, data = formattedData }); diff --git a/CPRNIMS.WebApps/Program.cs b/CPRNIMS.WebApps/Program.cs index 0161dcc..a394bfa 100644 --- a/CPRNIMS.WebApps/Program.cs +++ b/CPRNIMS.WebApps/Program.cs @@ -17,10 +17,6 @@ if (!app.Environment.IsDevelopment()) app.UseHsts(); } -//var provider = new FileExtensionContentTypeProvider(); -//provider.Mappings[".js"] = "text/javascript"; -//provider.Mappings[".css"] = "text/css"; - app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); diff --git a/CPRNIMS.WebApps/ViewComponents/Inventory/InventoryTabPageViewComponent.cs b/CPRNIMS.WebApps/ViewComponents/Inventory/InventoryTabPageViewComponent.cs index 8f5dc3a..61bce53 100644 --- a/CPRNIMS.WebApps/ViewComponents/Inventory/InventoryTabPageViewComponent.cs +++ b/CPRNIMS.WebApps/ViewComponents/Inventory/InventoryTabPageViewComponent.cs @@ -4,14 +4,17 @@ namespace CPRNIMS.WebApps.ViewComponents.Inventory { public class InventoryTabPageViewComponent : ViewComponent { - public IViewComponentResult Invoke(int InventoryTabPageId) + public IViewComponentResult Invoke(int InventoryTabPageId,bool isFinance) { + var report = isFinance ? "~/Views/Components/Inventory/TabPage/Reports/InventorySummaryReportFinance.cshtml" + : "~/Views/Components/Inventory/TabPage/Reports/InventorySummaryReport.cshtml"; + string viewName = InventoryTabPageId switch { 1 => "~/Views/Components/Inventory/TabPage/Inventory.cshtml", 2 => "~/Views/Components/Inventory/TabPage/RIS.cshtml", 3 => "~/Views/Components/Inventory/TabPage/MRS.cshtml", - 4 => "~/Views/Components/Inventory/TabPage/Reports/InventorySummaryReport.cshtml", + 4 => report, 5 => "~/Views/Components/Inventory/TabPage/Reports/RISReport.cshtml", _ => "~/Views/Components/Inventory/TabPage/Reports/MRSReport.cshtml" }; diff --git a/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/InventoryTransaction.cshtml b/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/InventoryTransaction.cshtml index 4c90651..b29e632 100644 --- a/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/InventoryTransaction.cshtml +++ b/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/InventoryTransaction.cshtml @@ -1,8 +1,3 @@ -@* ── Tab: Return Issuance Slip — For Approval ─────────────────────────────── - Returned by GetInventoryTabPage?id=2 (or whichever tab id you assign) - Depends on: _InventoryStyles, _InventoryHelpers, window.InventoryHelpers -────────────────────────────────────────────────────────────────────────────── *@ - @* ── FILTER BAR ── *@