From 44862d01b5b539f2d8b1a193613b0b64573101b7 Mon Sep 17 00:00:00 2001 From: rowell_m_soriano Date: Mon, 15 Jun 2026 16:41:50 +0800 Subject: [PATCH] RIS creation, approval and Cancel working well --- .../Contracts/Inventory/IInventory.cs | 8 +- CPRNIMS.Domain/Contracts/Inventory/IMRS.cs | 19 + CPRNIMS.Domain/Contracts/Inventory/IRIS.cs | 22 + .../Services/Inventory/Inventory.cs | 372 +++-- CPRNIMS.Domain/Services/Inventory/MRS.cs | 155 ++ CPRNIMS.Domain/Services/Inventory/RIS.cs | 307 ++++ .../UIContracts/Inventory/IInventory.cs | 5 + CPRNIMS.Domain/UIContracts/Inventory/IRIS.cs | 20 + .../UIServices/Inventory/Inventory.cs | 89 +- CPRNIMS.Domain/UIServices/Inventory/RIS.cs | 170 ++ .../Database/NonInventoryDbContext.cs | 144 +- .../Dto/Common/ApiResponse.cs | 15 + .../Dto/Inventory/DisciplineDto.cs | 14 + .../Dto/Inventory/MRSFilterDto.cs | 20 + .../Dto/Inventory/MRSPagedResult.cs | 17 + .../Dto/Inventory/PagedResult.cs | 20 + .../Dto/Inventory/RISFilterDto.cs | 21 + .../Dto/Inventory/RISPagedResult.cs | 17 + .../Dto/Inventory/RISReferenceDto.cs | 19 + .../Inventory/Request/ApproveRISRequest.cs | 13 + .../Dto/Inventory/Request/CancelRISRequest.cs | 14 + .../Dto/Inventory/Request/CreateMRSRequest.cs | 17 + .../Dto/Inventory/Request/CreateRISRequest.cs | 18 + .../Dto/Inventory/Request/InventoryRequest.cs | 23 + .../Dto/Inventory/Request/RISPagedRequest.cs | 19 + .../Response/InventoryByIdResponse.cs | 28 + .../Inventory/Response/InventoryResponse.cs | 28 + .../Dto/Inventory/Response/MRSResponse.cs | 28 + .../Inventory/Response/RISPagedResponse.cs | 56 + .../Dto/Inventory/Response/RISResponse.cs | 32 + .../Dto/Inventory/TransactContextDto.cs | 23 + .../Entities/Inventory/Discipline.cs | 18 + .../Entities/Inventory/InventTrans.cs | 22 + .../Entities/Inventory/InventTransDetail.cs | 28 + .../Entities/Inventory/Inventory.cs | 16 +- .../Entities/Inventory/Lot.cs | 2 +- .../Entities/Inventory/LotType.cs | 18 + .../Entities/Inventory/MRS.cs | 46 + .../Entities/Inventory/RIS.cs | 48 + .../Entities/Purchasing/PRDetails.cs | 2 + .../Models/RegisterModel.cs | 6 +- .../ViewModel/Account/LoginVM.cs | 2 - .../ViewModel/Inventory/InventoryVM.cs | 7 + CPRNIMS.WebApi/CPRNIMS.WebApi.csproj | 1 + CPRNIMS.WebApi/Common/ServiceExtensions.cs | 2 + .../Inventory/InventoryMgmtController.cs | 149 +- .../Inventory/MRSMgmtController.cs | 12 + .../Inventory/RISMgmtController.cs | 76 + CPRNIMS.WebApi/Sql/Phase 5/StoredProc.sql | 117 ++ CPRNIMS.WebApi/Sql/Phase 5/Table.sql | 61 + CPRNIMS.WebApps/Common/ServiceExtensions.cs | 1 + .../Inventory/InventoryMgmtController.cs | 179 +-- .../Controllers/Inventory/MRSController.cs | 12 + .../Inventory/RISMgmtController.cs | 101 ++ .../InventoryTabPageViewComponent.cs | 19 + .../Views/CanvassMgmt/Suppliers.cshtml | 2 +- .../Inventory/TabPage/Inventory.cshtml | 299 ++++ .../Inventory/TabPage/RISForApproval.cshtml | 936 +++++++++++ .../Views/InventoryMgmt/Inventory.cshtml | 284 ++-- CPRNIMS.WebApps/Views/RISMgmt/Index.cshtml | 5 + .../PagesView/Canvass/_CanvassScript.cshtml | 2 +- .../Inventory/_InventoryHelpers.cshtml | 314 ++++ .../Inventory/_InventoryStyles.cshtml | 1404 +++++++++++++++++ .../Inventory/_InventoryTransactModal.cshtml | 738 +++++++++ .../Views/Shared/PartialView/_Head.cshtml | 4 +- .../Shared/PartialView/_PartialScripts.cshtml | 2 +- CPRNIMS.WebApps/appsettings.json | 10 +- .../JsFunctions/Inventory/InventoryTabs.js | 161 ++ ...ion-modal.css => confirmation-modalV2.css} | 2 +- ...ications.css => toast-notificationsV2.css} | 2 +- ...ation-modal.js => confirmation-modalV2.js} | 21 +- 71 files changed, 6275 insertions(+), 609 deletions(-) create mode 100644 CPRNIMS.Domain/Contracts/Inventory/IMRS.cs create mode 100644 CPRNIMS.Domain/Contracts/Inventory/IRIS.cs create mode 100644 CPRNIMS.Domain/Services/Inventory/MRS.cs create mode 100644 CPRNIMS.Domain/Services/Inventory/RIS.cs create mode 100644 CPRNIMS.Domain/UIContracts/Inventory/IRIS.cs create mode 100644 CPRNIMS.Domain/UIServices/Inventory/RIS.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Common/ApiResponse.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/DisciplineDto.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/MRSFilterDto.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/MRSPagedResult.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/PagedResult.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/RISFilterDto.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/RISPagedResult.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/RISReferenceDto.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Request/ApproveRISRequest.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Request/CancelRISRequest.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateMRSRequest.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateRISRequest.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Request/InventoryRequest.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Request/RISPagedRequest.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Response/InventoryByIdResponse.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Response/InventoryResponse.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Response/MRSResponse.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Response/RISPagedResponse.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/Response/RISResponse.cs create mode 100644 CPRNIMS.Infrastructure/Dto/Inventory/TransactContextDto.cs create mode 100644 CPRNIMS.Infrastructure/Entities/Inventory/Discipline.cs create mode 100644 CPRNIMS.Infrastructure/Entities/Inventory/InventTrans.cs create mode 100644 CPRNIMS.Infrastructure/Entities/Inventory/InventTransDetail.cs create mode 100644 CPRNIMS.Infrastructure/Entities/Inventory/LotType.cs create mode 100644 CPRNIMS.Infrastructure/Entities/Inventory/MRS.cs create mode 100644 CPRNIMS.Infrastructure/Entities/Inventory/RIS.cs create mode 100644 CPRNIMS.WebApi/Controllers/Inventory/MRSMgmtController.cs create mode 100644 CPRNIMS.WebApi/Controllers/Inventory/RISMgmtController.cs create mode 100644 CPRNIMS.WebApi/Sql/Phase 5/StoredProc.sql create mode 100644 CPRNIMS.WebApi/Sql/Phase 5/Table.sql create mode 100644 CPRNIMS.WebApps/Controllers/Inventory/MRSController.cs create mode 100644 CPRNIMS.WebApps/Controllers/Inventory/RISMgmtController.cs create mode 100644 CPRNIMS.WebApps/ViewComponents/Inventory/InventoryTabPageViewComponent.cs create mode 100644 CPRNIMS.WebApps/Views/Components/Inventory/TabPage/Inventory.cshtml create mode 100644 CPRNIMS.WebApps/Views/Components/Inventory/TabPage/RISForApproval.cshtml create mode 100644 CPRNIMS.WebApps/Views/RISMgmt/Index.cshtml create mode 100644 CPRNIMS.WebApps/Views/Shared/PagesView/Inventory/_InventoryHelpers.cshtml create mode 100644 CPRNIMS.WebApps/Views/Shared/PagesView/Inventory/_InventoryStyles.cshtml create mode 100644 CPRNIMS.WebApps/Views/Shared/PagesView/Inventory/_InventoryTransactModal.cshtml create mode 100644 CPRNIMS.WebApps/wwwroot/JsFunctions/Inventory/InventoryTabs.js rename CPRNIMS.WebApps/wwwroot/css/{confirmation-modal.css => confirmation-modalV2.css} (98%) rename CPRNIMS.WebApps/wwwroot/css/{toast-notifications.css => toast-notificationsV2.css} (98%) rename CPRNIMS.WebApps/wwwroot/js/{confirmation-modal.js => confirmation-modalV2.js} (89%) diff --git a/CPRNIMS.Domain/Contracts/Inventory/IInventory.cs b/CPRNIMS.Domain/Contracts/Inventory/IInventory.cs index fd8d7f1..3b31a70 100644 --- a/CPRNIMS.Domain/Contracts/Inventory/IInventory.cs +++ b/CPRNIMS.Domain/Contracts/Inventory/IInventory.cs @@ -1,4 +1,6 @@ using CPRNIMS.Infrastructure.Dto.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Dto.Inventory.Response; using CPRNIMS.Infrastructure.Entities.Inventory; using System; using System.Collections.Generic; @@ -11,11 +13,15 @@ namespace CPRNIMS.Domain.Contracts.Inventory public interface IInventory { Task> GetLotNo(InventoryDto itemDto); - Task> GetLotNoById(InventoryDto itemDto);// + Task> GetLotNoById(InventoryDto itemDto); Task> GetLotQtyByItem(InventoryDto itemDto); Task> GetInventoryByUserId(InventoryDto itemDto); Task> GetRequestedItemByUserId(InventoryDto itemDto); Task> GetInventoryById(InventoryDto itemDto); + Task> GetInventory(InventoryRequest request, CancellationToken ct); + Task> GetInventoryById(InventoryRequest itemDto, CancellationToken ct); + Task GetTransactContextAsync(int inventoryId, 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 new file mode 100644 index 0000000..e42df8e --- /dev/null +++ b/CPRNIMS.Domain/Contracts/Inventory/IMRS.cs @@ -0,0 +1,19 @@ +using CPRNIMS.Infrastructure.Dto.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Entities.Inventory; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Domain.Contracts.Inventory +{ + public interface IMRS + { + Task GetPagedAsync(MRSFilterDto filter); + Task GetByIdAsync(long mrsId); + Task CreateAsync(CreateMRSRequest dto, string createdBy); + Task ApproveAsync(long mrsId, string approvedBy); + } +} diff --git a/CPRNIMS.Domain/Contracts/Inventory/IRIS.cs b/CPRNIMS.Domain/Contracts/Inventory/IRIS.cs new file mode 100644 index 0000000..9e2d2ca --- /dev/null +++ b/CPRNIMS.Domain/Contracts/Inventory/IRIS.cs @@ -0,0 +1,22 @@ +using CPRNIMS.Infrastructure.Dto.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Dto.Inventory.Response; +using CPRNIMS.Infrastructure.Entities.Inventory; +using CPRNIMS.Infrastructure.Entities.Purchasing; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Domain.Contracts.Inventory +{ + public interface IRIS + { + Task GetPagedAsync(RISFilterDto filter, CancellationToken ct); + Task GetByIdAsync(long risId, CancellationToken ct); + Task CreateAsync(CreateRISRequest dto, string createdBy, CancellationToken ct); + Task ApproveAsync(ApproveRISRequest request, string approvedBy, CancellationToken ct); + Task CancelAsync(CancelRISRequest request, CancellationToken ct); + } +} diff --git a/CPRNIMS.Domain/Services/Inventory/Inventory.cs b/CPRNIMS.Domain/Services/Inventory/Inventory.cs index f008a86..1cda8e5 100644 --- a/CPRNIMS.Domain/Services/Inventory/Inventory.cs +++ b/CPRNIMS.Domain/Services/Inventory/Inventory.cs @@ -1,8 +1,8 @@ using CPRNIMS.Domain.Contracts.Inventory; using CPRNIMS.Infrastructure.Database; using CPRNIMS.Infrastructure.Dto.Inventory; -using CPRNIMS.Infrastructure.Dto.Items; -using CPRNIMS.Infrastructure.Entities.Finance; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Dto.Inventory.Response; using CPRNIMS.Infrastructure.Entities.Inventory; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; @@ -21,65 +21,203 @@ namespace CPRNIMS.Domain.Services.Inventory { _dbContext = dbContext; } - public async Task> GetInventoryById(InventoryDto itemDto) + public async Task GetTransactContextAsync(int inventoryId, CancellationToken ct) { - try - { - var allItems = await _dbContext.ItemDetails - .FromSqlRaw($"EXEC GetInventoryById @UserId = '{itemDto.UserId}',@InventoryId = '{itemDto.InventoryId}'") - .ToListAsync(); - - return allItems ?? new List(); - } - catch (SqlException ex) - { - ex.ToString(); - throw; - } - } - - public async Task> - GetInventoryByUserId(InventoryDto itemDto) - { - try - { - if(itemDto.IsSorting == false) + var inv = await _dbContext.Inventories + .Where(i => i.InventoryId == inventoryId && i.IsActive) + .Select(i => new { - itemDto.DateFrom=DateTime.Now; - itemDto.DateTo = DateTime.Now; - } - var allItems = await _dbContext.Inventories - .FromSqlRaw($"EXEC GetInventoryByUserId @UserId,@DateFrom,@DateTo,@IsSorting", - new SqlParameter("@UserId", itemDto.UserId), - new SqlParameter("@DateFrom", itemDto.DateFrom), - new SqlParameter("@DateTo", itemDto.DateTo), - new SqlParameter("@IsSorting", itemDto.IsSorting)) - .ToListAsync(); + i.InventoryId, + i.QtyOnHand, + i.QtyIn, + i.QtyOut, - return allItems ?? new List(); - } - catch (SqlException ex) + LotNo = i.Lot != null ? i.Lot.LotName : null, + + Department = i.User != null && i.User.Department != null + ? i.User.Department.Department + : null, + i.ItemNo, + FirstDetail = i.InventTrans + .Where(t => t.IsActive) + .SelectMany(t => t.InventTransDetails) + .Where(d => d.PRDetails != null + && d.PRDetails.PRs != null + && d.IsActive) + .Select(d => new + { + d.PRDetails!.ItemName, + PRNo = d.PRDetails.PRs!.PRNo + }) + .FirstOrDefault() + }) + .FirstOrDefaultAsync(ct); + + if (inv == null) return null; + + // Computed property QtyAvailableToReturn can't be used in EF Where, + // so filter after projection using a raw expression in the query. + var openRIS = await _dbContext.RIS + .Where(r => r.InventoryId == inventoryId + && r.Status == 1) + .Select(r => new RISReferenceDto + { + RISId = r.RISId, + RISNo = r.RISNo, + QtyIssued = r.QtyIssued, + TotalReturned = r.MaterialReturns + .Where(m => m.Status != 2) + .Sum(m => (int?)m.QtyReturned) ?? 0, + DisciplineName = r.Discipline.DisciplineName, + CreatedDate = r.CreatedDate + }) + + // Can't use the computed property here — EF won't translate it + // so we repeat the expression inline + .Where(r => r.QtyIssued - r.TotalReturned > 0) + .OrderByDescending(r => r.CreatedDate) + .ToListAsync(ct); + + var disciplines = await GetDisciplinesAsync(ct); + + return new TransactContextDto { - ex.ToString(); - throw; + InventoryId = inv.InventoryId, + ItemName = inv.FirstDetail?.ItemName ?? "—", + PRNo = inv.FirstDetail.PRNo, + ItemNo = inv.ItemNo, + LotNo = inv.LotNo, + Department = inv.Department, + QtyOnHand = inv.QtyOnHand, + QtyIn = inv.QtyIn, + QtyOut = inv.QtyOut, + Disciplines = disciplines, + OpenRISList = openRIS + }; + } + public async Task> GetDisciplinesAsync(CancellationToken ct) + { + return await _dbContext.Disciplines + .OrderBy(d => d.DisciplineName) + .Select(d => new DisciplineDto + { + DisciplineId = d.DisciplineId, + DisciplineName = d.DisciplineName + }) + .ToListAsync(ct); + } + public async Task> GetInventoryById(InventoryDto itemDto) + { + var allItems = await _dbContext.ItemDetails + .FromSqlRaw($"EXEC GetInventoryById @UserId = '{itemDto.UserId}',@InventoryId = '{itemDto.InventoryId}'") + .ToListAsync(); + + return allItems ?? new List(); + } + public async Task> GetInventory(InventoryRequest request, CancellationToken ct) + { + var parameters = new[] + { + new SqlParameter("@UserId", request.UserId), + new SqlParameter("@SearchPRNo", request.SearchPRNo ?? ""), + new SqlParameter("@SearchItemNo", request.SearchItemNo ?? ""), + new SqlParameter("@SearchItemName", request.SearchItemName ?? ""), + new SqlParameter("@SearchDept", request.SearchDept ?? ""), + new SqlParameter("@SearchProjectCode",request.SearchProjectCode ?? ""), + new SqlParameter("@PageNumber", request.PageNumber), + new SqlParameter("@PageSize", request.PageSize) + }; + + var departmentList = new List(); + int totalCount = 0; + var items = new List(); + + await using var conn = _dbContext.Database.GetDbConnection(); + await conn.OpenAsync(ct); + + using var cmd = conn.CreateCommand(); + cmd.CommandText = @"EXEC GetInventory @UserId, @SearchPRNo, @SearchItemNo, @SearchItemName, @SearchDept,@SearchProjectCode, @PageNumber, @PageSize"; + foreach (var p in parameters) cmd.Parameters.Add(p); + cmd.CommandTimeout = 60; + + using var reader = await cmd.ExecuteReaderAsync(ct); + + while (await reader.ReadAsync(ct)) + departmentList.Add(reader.GetString(0)); + + await reader.NextResultAsync(ct); + if (await reader.ReadAsync(ct)) + totalCount = reader.GetInt32(0); + + await reader.NextResultAsync(ct); + while (await reader.ReadAsync(ct)) + { + items.Add(new InventoryResponse + { + InventoryId = reader.GetInt32(reader.GetOrdinal("InventoryId")), + QtyIn = reader["QtyIn"] as decimal? ?? 0, + QtyOut = reader["QtyOut"] as decimal? ?? 0, + QtyOnHand = reader["QtyOnHand"] as decimal? ?? 0, + LotNo = reader["LotNo"]?.ToString(), + PRNo = Convert.ToInt64(reader["PRNo"]), + UserId = reader["UserId"]?.ToString(), + ItemName = reader["ItemName"]?.ToString(), + ItemNo = Convert.ToInt64(reader["ItemNo"]), + ItemDescription = reader["ItemDescription"]?.ToString(), + ItemCategoryName = reader["ItemCategoryName"]?.ToString(), + Department = reader["Department"]?.ToString(), + ProjectCode = reader["ProjectCode"]?.ToString(), + CreatedDate = reader["CreatedDate"] == DBNull.Value + ? DateTime.MinValue + : Convert.ToDateTime(reader["CreatedDate"]) + }); } + + await conn.CloseAsync(); + + return new PagedResult + { + Data = items, + TotalCount = totalCount, + PageNumber = request.PageNumber, + PageSize = request.PageSize, + DepartmentList = departmentList + }; + } + public async Task> GetInventoryById(InventoryRequest itemDto,CancellationToken ct) + { + var allItems = await _dbContext.InventoryByIdResponses + .FromSqlRaw($"EXEC GetInventoryById @InventoryId", + new SqlParameter("@InventoryId", itemDto.InventoryId)) + .ToListAsync(ct); + + return allItems ?? new List(); + } + public async Task>GetInventoryByUserId(InventoryDto itemDto) + { + if (itemDto.IsSorting == false) + { + itemDto.DateFrom = DateTime.Now; + itemDto.DateTo = DateTime.Now; + } + var allItems = await _dbContext.Inventories + .FromSqlRaw($"EXEC GetInventoryByUserId @UserId,@DateFrom,@DateTo,@IsSorting", + new SqlParameter("@UserId", itemDto.UserId), + new SqlParameter("@DateFrom", itemDto.DateFrom), + new SqlParameter("@DateTo", itemDto.DateTo), + new SqlParameter("@IsSorting", itemDto.IsSorting)) + .ToListAsync(); + + return allItems ?? new List(); } public async Task> GetLotNoById(InventoryDto itemDto) { - try - { - var allItems = await _dbContext.Lots - .FromSqlRaw($"EXEC GetLotById @UserId = '{itemDto.UserId}'") - .ToListAsync(); + var allItems = await _dbContext.Lots + .FromSqlRaw($"EXEC GetLotById @UserId = '{itemDto.UserId}'") + .ToListAsync(); - return allItems ?? new List(); - } - catch (SqlException ex) - { - ex.ToString(); - throw; - } + return allItems ?? new List(); } public async Task> GetLotNo(InventoryDto itemDto) @@ -94,125 +232,77 @@ namespace CPRNIMS.Domain.Services.Inventory public async Task PostPutLotNo(InventoryDto itemDto) { - try - { - await _dbContext.Database - .ExecuteSqlRawAsync("EXEC PostPutLotNo @UserId, @LotId, @LotTypeId,@LotName", - new SqlParameter("@LotId", itemDto.LotId != null ? itemDto.LotId : 0L), - new SqlParameter("@UserId", itemDto.UserId), - new SqlParameter("@LotTypeId", itemDto.LotTypeId), - new SqlParameter("@LotName", itemDto.LotName)); - return new Lot(); - } - catch (SqlException ex) - { - ex.ToString(); - throw; - } + await _dbContext.Database + .ExecuteSqlRawAsync("EXEC PostPutLotNo @UserId, @LotId, @LotTypeId,@LotName", + new SqlParameter("@LotId", itemDto.LotId != null ? itemDto.LotId : 0L), + new SqlParameter("@UserId", itemDto.UserId), + new SqlParameter("@LotTypeId", itemDto.LotTypeId), + new SqlParameter("@LotName", itemDto.LotName)); + return new Lot(); } public async Task PostPutReqApproval(InventoryDto itemDto) { - try - { - await _dbContext.Database - .ExecuteSqlRawAsync("EXEC PostPutReqApproval @UserId, @ItemNo, @Status, @Remarks", - new SqlParameter("@ItemNo", itemDto.InventoryId != null ? itemDto.InventoryId : 0L), - new SqlParameter("@UserId", itemDto.UserId), - new SqlParameter("@Status", itemDto.Status), - new SqlParameter("@Remarks", itemDto.Remarks ?? "N/A")); - return new Infrastructure.Entities.Inventory.Inventory(); - } - catch (SqlException ex) - { - ex.ToString(); - throw; - } + await _dbContext.Database + .ExecuteSqlRawAsync("EXEC PostPutReqApproval @UserId, @ItemNo, @Status, @Remarks", + new SqlParameter("@ItemNo", itemDto.InventoryId != null ? itemDto.InventoryId : 0L), + new SqlParameter("@UserId", itemDto.UserId), + new SqlParameter("@Status", itemDto.Status), + new SqlParameter("@Remarks", itemDto.Remarks ?? "N/A")); + return new Infrastructure.Entities.Inventory.Inventory(); } public async Task PostPutLotBin(InventoryDto itemDto) { - try - { - await _dbContext.Database - .ExecuteSqlRawAsync("EXEC PostPutLotBin @UserId, @LotId, @InventoryId", - new SqlParameter("@InventoryId", itemDto.InventoryId), - new SqlParameter("@UserId", itemDto.UserId), - new SqlParameter("@LotId", itemDto.LotId)); - return new ItemDetail(); - } - catch (SqlException ex) - { - ex.ToString(); - throw; - } + await _dbContext.Database + .ExecuteSqlRawAsync("EXEC PostPutLotBin @UserId, @LotId, @InventoryId", + new SqlParameter("@InventoryId", itemDto.InventoryId), + new SqlParameter("@UserId", itemDto.UserId), + new SqlParameter("@LotId", itemDto.LotId)); + return new ItemDetail(); } public async Task PostPutReqItems(InventoryDto itemDto) { - try + if (itemDto.QtyReceived == null || itemDto.QtyReceived == 0) { - if(itemDto.QtyReceived == null || itemDto.QtyReceived == 0) - { - itemDto.QtyReceived = 0; - } - if(itemDto.LotId == null || itemDto.LotId == 0) - { - itemDto.LotId = 0; - } - await _dbContext.Database - .ExecuteSqlRawAsync("EXEC PostPutReqItems @UserId, @RequestItemId, @ItemNo, @QtyRequest,@Status,@IsApproved,@QtyReceived,@LotId", - new SqlParameter("@UserId", itemDto.UserId), - new SqlParameter("@ItemNo", itemDto.ItemNo), - new SqlParameter("@RequestItemId", itemDto.RequestItemId != null ? itemDto.RequestItemId : 0L), - new SqlParameter("@QtyRequest", itemDto.QtyRequest), - new SqlParameter("@Status", itemDto.Status), - new SqlParameter("@IsApproved", itemDto.IsApproved), - new SqlParameter("@QtyReceived", itemDto.QtyReceived), - new SqlParameter("@LotId", itemDto.LotId)); - return new RequestItem(); + itemDto.QtyReceived = 0; } - catch (SqlException ex) + if (itemDto.LotId == null || itemDto.LotId == 0) { - ex.ToString(); - throw; + itemDto.LotId = 0; } + await _dbContext.Database + .ExecuteSqlRawAsync("EXEC PostPutReqItems @UserId, @RequestItemId, @ItemNo, @QtyRequest,@Status,@IsApproved,@QtyReceived,@LotId", + new SqlParameter("@UserId", itemDto.UserId), + new SqlParameter("@ItemNo", itemDto.ItemNo), + new SqlParameter("@RequestItemId", itemDto.RequestItemId != null ? itemDto.RequestItemId : 0L), + new SqlParameter("@QtyRequest", itemDto.QtyRequest), + new SqlParameter("@Status", itemDto.Status), + new SqlParameter("@IsApproved", itemDto.IsApproved), + new SqlParameter("@QtyReceived", itemDto.QtyReceived), + new SqlParameter("@LotId", itemDto.LotId)); + return new RequestItem(); } public async Task> GetRequestedItemByUserId(InventoryDto itemDto) { - try - { - var allItems = await _dbContext.RequestItemDetails + var allItems = await _dbContext.RequestItemDetails .FromSqlRaw($"EXEC GetRequestedItemByUserId @UserId = '{itemDto.UserId}', " + $"@RequestItemId = '{itemDto.RequestItemId}',@WithoutStocks = '{itemDto.WithoutStocks}'") .ToListAsync(); - return allItems ?? new List(); - } - catch (SqlException ex) - { - ex.ToString(); - throw; - } + return allItems ?? new List(); } public async Task> GetLotQtyByItem(InventoryDto itemDto) { - try - { - var allItems = await _dbContext.LotQtyByItems - .FromSqlRaw($"EXEC GetLotQtyByItem @UserId = '{itemDto.UserId}', " + - $"@ItemNo = '{itemDto.ItemNo}',@LotId = '{itemDto.LotId}'") - .ToListAsync(); + var allItems = await _dbContext.LotQtyByItems + .FromSqlRaw($"EXEC GetLotQtyByItem @UserId = '{itemDto.UserId}', " + + $"@ItemNo = '{itemDto.ItemNo}',@LotId = '{itemDto.LotId}'") + .ToListAsync(); - return allItems ?? new List(); - } - catch (SqlException ex) - { - ex.ToString(); - throw; - } + return allItems ?? new List(); } } } diff --git a/CPRNIMS.Domain/Services/Inventory/MRS.cs b/CPRNIMS.Domain/Services/Inventory/MRS.cs new file mode 100644 index 0000000..1180fb8 --- /dev/null +++ b/CPRNIMS.Domain/Services/Inventory/MRS.cs @@ -0,0 +1,155 @@ +using CPRNIMS.Domain.Contracts.Inventory; +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.Inventory; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Domain.Services.Inventory +{ + public class MRS : IMRS + { + private readonly NonInventoryDbContext _db; + public MRS(NonInventoryDbContext db) => _db = db; + + public async Task ApproveAsync(long mrsId, string approvedBy) + { + var rms = await _db.MRS.FindAsync(mrsId) + ?? throw new InvalidOperationException("MRS not found."); + + if (rms.Status != 0) + throw new InvalidOperationException("Only Draft MRS records can be approved."); + + rms.Status = 1; // Approved + rms.ApprovedBy = approvedBy; + rms.ApprovedDate = DateTime.Now; + + await _db.SaveChangesAsync(); + } + + public async Task CreateAsync(CreateMRSRequest dto, string createdBy) + { + var ris = await _db.RIS + .Include(r => r.Inventory) + .FirstOrDefaultAsync(r => r.RISId == dto.RISId) + ?? throw new InvalidOperationException("Referenced RIS not found."); + + if (dto.QtyReturned > ris.QtyIssued) + throw new InvalidOperationException( + $"Cannot return more than issued. Issued: {ris.QtyIssued}."); + + var mrsNo = await GenerateMRSNoAsync(); + + var mrs = new Infrastructure.Entities.Inventory.MRS + { + MRSNo = mrsNo, + RISId = dto.RISId, + InventoryId = ris.InventoryId, + ReturnedBy = dto.ReturnedBy, + QtyReturned = dto.QtyReturned, + Condition = dto.Condition, + Remarks = dto.Remarks, + Status = 0, + CreatedBy = createdBy, + CreatedDate = DateTime.Now + }; + _db.MRS.Add(mrs); + + var inventory = ris.Inventory; + inventory.QtyOut = Math.Max(0m, inventory.QtyOut - dto.QtyReturned); + + inventory.QtyOnHand = inventory.QtyIn - inventory.QtyOut; + + var trans = await _db.InventTrans + .FirstOrDefaultAsync(t => t.InventoryId == ris.InventoryId && t.IsActive == true)!; + + _db.InventTransDetails.Add(new InventTransDetail + { + InventTransId = trans.InventTransId, + TransTypeId = 6, + QtyIn = dto.QtyReturned, + CreatedDate = DateTime.Now, + Remarks = $"MRS: {mrsNo} — return from MRS: {ris.RISNo}", + IsActive = true + }); + + await _db.SaveChangesAsync(); + return mrs; + } + + public async Task GetByIdAsync(long mrsId) + + => await _db.MRS + .Include(r => r.Inventory) + .Include(r => r.RIS) + .FirstOrDefaultAsync(r => r.RISId == mrsId); + + public async Task GetPagedAsync(MRSFilterDto filter) + { + var q = _db.MRS + .Include(m => m.RIS) + .Include(m => m.Inventory) + .AsQueryable(); + + if (!string.IsNullOrWhiteSpace(filter.SearchMRSNo)) + q = q.Where(m => m.MRSNo.Contains(filter.SearchMRSNo)); + + if (filter.RISId.HasValue) + q = q.Where(m => m.RISId == filter.RISId.Value); + + if (filter.Status.HasValue) + q = q.Where(m => m.Status == filter.Status.Value); + + if (filter.DateFrom.HasValue) + q = q.Where(m => m.CreatedDate >= filter.DateFrom.Value); + + if (filter.DateTo.HasValue) + q = q.Where(m => m.CreatedDate <= filter.DateTo.Value.AddDays(1)); + + var total = await q.CountAsync(); + + var data = await q + .OrderByDescending(m => m.CreatedDate) + .Skip((filter.Page - 1) * filter.PageSize) + .Take(filter.PageSize) + .Select(m => new MRSResponse + { + MRSId = m.MRSId, + MRSNo = m.MRSNo, + RISId = m.RISId, + RISNo = m.RIS.RISNo, + InventoryId = m.InventoryId, + ItemName = m.Inventory.InventTrans + .SelectMany(t => t.InventTransDetails) + .Select(d => d.PRDetails != null ? d.PRDetails.ItemName : "—") + .FirstOrDefault() ?? "—", + ReturnedBy = m.ReturnedBy, + QtyReturned = m.QtyReturned, + Condition = m.Condition, + Remarks = m.Remarks, + Status = m.Status, + CreatedBy = m.CreatedBy, + CreatedDate = m.CreatedDate, + ApprovedBy = m.ApprovedBy, + ApprovedDate = m.ApprovedDate + }) + .ToListAsync(); + + return new MRSPagedResult { Data = data, RecordsTotal = total }; + } + + private async Task GenerateMRSNoAsync() + { + var year = DateTime.Now.Year; + var month = DateTime.Now.Month.ToString("D2"); + var count = await _db.MRS.CountAsync(m => m.CreatedDate.Year == year) + 1; + return $"MRS-{year}{month}-{count:D4}"; + } + } +} diff --git a/CPRNIMS.Domain/Services/Inventory/RIS.cs b/CPRNIMS.Domain/Services/Inventory/RIS.cs new file mode 100644 index 0000000..649645b --- /dev/null +++ b/CPRNIMS.Domain/Services/Inventory/RIS.cs @@ -0,0 +1,307 @@ +using CPRNIMS.Domain.Contracts.Inventory; +using CPRNIMS.Domain.UIServices.Inventory; +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.Inventory; +using Microsoft.EntityFrameworkCore; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Domain.Services.Inventory +{ + public class RIS : IRIS + { + private readonly NonInventoryDbContext _db; + + public RIS(NonInventoryDbContext db) => _db = db; + + public async Task CreateAsync(CreateRISRequest dto, string createdBy, CancellationToken ct) + { + var strategy = _db.Database.CreateExecutionStrategy(); + + return await strategy.ExecuteAsync(async () => + { + await using var tx = await _db.Database.BeginTransactionAsync(ct); + try + { + var inventory = await _db.Inventories + .FirstOrDefaultAsync(i => i.InventoryId == dto.InventoryId, ct) + ?? throw new InvalidOperationException("Inventory record not found."); + + if (inventory.QtyOnHand < dto.QtyIssued) + throw new InvalidOperationException( + $"Insufficient stock. On hand: {inventory.QtyOnHand}, requested: {dto.QtyIssued}."); + + var risNo = await GenerateRISNoAsync(ct); + + var ris = new Infrastructure.Entities.Inventory.RIS + { + RISNo = risNo, + InventoryId = dto.InventoryId, + PRDetailId = dto.PRDetailId, + IssuedTo = dto.IssuedTo, + DisciplineId = dto.DisciplineId, + QtyIssued = dto.QtyIssued, + Remarks = dto.Remarks, + Status = 0, + CreatedBy = createdBy, + CreatedDate = DateTime.Now + }; + _db.RIS.Add(ris); + await _db.SaveChangesAsync(ct); + + var trans = await _db.InventTrans + .Where(t => t.InventoryId == dto.InventoryId && t.IsActive == true) + .FirstOrDefaultAsync(ct) + ?? throw new InvalidOperationException( + "No active InventTrans found for this inventory record."); + + _db.InventTransDetails.Add(new InventTransDetail + { + InventTransId = trans.InventTransId, + TransTypeId = 5, + PRDetailId = dto.PRDetailId, + QtyOut = dto.QtyIssued, + CreatedDate = DateTime.Now, + Remarks = $"RIS: {risNo}", + IsActive = true + }); + + inventory.QtyOut = Math.Max(0m, inventory.QtyOut) + dto.QtyIssued; + inventory.QtyOnHand = Math.Max(0m, inventory.QtyIn) - (decimal)inventory.QtyOut; + + await _db.SaveChangesAsync(ct); + await tx.CommitAsync(ct); + + return ris; + } + catch + { + await tx.RollbackAsync(ct); + throw; + } + }); + } + + public async Task ApproveAsync(ApproveRISRequest request, string approvedBy, CancellationToken ct) + { + var ris = await _db.RIS.FindAsync(request.RISId, ct) + ?? throw new InvalidOperationException("RIS not found."); + + if (ris.Status != 0) + throw new InvalidOperationException("Only Draft RIS records can be approved."); + + ris.Status = 1; // Approved + ris.ApprovedBy = approvedBy; + ris.ApprovedDate = DateTime.Now; + + await _db.SaveChangesAsync(ct); + } + + public async Task CancelAsync(CancelRISRequest request, CancellationToken ct) + { + var strategy = _db.Database.CreateExecutionStrategy(); + + await strategy.ExecuteAsync(async () => + { + await using var tx = await _db.Database.BeginTransactionAsync(ct); + try + { + var ris = await _db.RIS + .Include(r => r.Inventory) + .FirstOrDefaultAsync(r => r.RISId == request.RISId, ct) + ?? throw new InvalidOperationException("RIS not found."); + + if (ris.Status == 2) + throw new InvalidOperationException("RIS is already cancelled."); + + ris.Inventory.QtyOut = Math.Max(0m, ris.Inventory.QtyOut - ris.QtyIssued); + ris.Inventory.QtyOnHand = ris.Inventory.QtyIn - ris.Inventory.QtyOut; + ris.Reason = request.Reason; + ris.Status = 2; // Cancelled + + var trans = await _db.InventTrans + .Where(t => t.InventoryId == ris.InventoryId && t.IsActive == true) + .FirstOrDefaultAsync(ct) + ?? throw new InvalidOperationException( + "No active InventTrans found for this inventory record."); + + _db.InventTransDetails.Add(new InventTransDetail + { + InventTransId = trans.InventTransId, + TransTypeId = 5, + PRDetailId = ris.PRDetailId, + QtyIn = ris.QtyIssued,//Return the issued Qty + CreatedDate = DateTime.Now, + Remarks = request.Reason, + IsActive = true + }); + + //var inventory = await _db.Inventories + // .FirstOrDefaultAsync(i => i.InventoryId == ris.InventoryId, ct) + // ?? throw new InvalidOperationException("Inventory record not found."); + + //if (inventory.QtyOnHand < ris.QtyIssued) + // throw new InvalidOperationException( + // $"Insufficient stock. On hand: {inventory.QtyOnHand}, requested: {ris.QtyIssued}."); + + ////restore the QtyOnHand using ris.QtyIssued + //inventory.QtyOnHand = Math.Max(0m, inventory.QtyOnHand) + ris.QtyIssued; + ////reduce the QtyOut using ris.QtyIssued as we cancel the return isuance slip + //inventory.QtyOut = Math.Max(0m, inventory.QtyOut) - ris.QtyIssued; + + await _db.SaveChangesAsync(ct); + await tx.CommitAsync(ct); + + return ris; + } + catch + { + await tx.RollbackAsync(ct); + throw; + } + }); + } + + private async Task GenerateRISNoAsync(CancellationToken ct) + { + var year = DateTime.Now.Year; + var month = DateTime.Now.Month.ToString("D2"); + var count = await _db.RIS + .CountAsync(r => r.CreatedDate.Year == year,ct) + 1; + return $"RIS-{year}{month}-{count:D4}"; // e.g. RIS-202606-0001 + } + + public async Task GetPagedAsync(RISFilterDto filter, CancellationToken ct) + { + var q = _db.RIS + .Include(r => r.Discipline) + .Include(r => r.Inventory) + .Include(r => r.MaterialReturns) + .AsQueryable(); + + // Status filter (default to Draft=0 if null) + if (filter.Status.HasValue) + q = q.Where(r => r.Status == filter.Status.Value); + else + q = q.Where(r => r.Status == 0); + + // RIS No + if (!string.IsNullOrWhiteSpace(filter.SearchRISNo)) + q = q.Where(r => r.RISNo.Contains(filter.SearchRISNo)); + + // Item Name + if (!string.IsNullOrWhiteSpace(filter.SearchItemName)) + q = q.Where(r => r.Inventory.InventTrans + .SelectMany(t => t.InventTransDetails) + .Any(d => d.PRDetails != null && + d.PRDetails.ItemName.Contains(filter.SearchItemName))); + + // Issued To + if (!string.IsNullOrWhiteSpace(filter.SearchIssuedTo)) + q = q.Where(r => r.IssuedTo.Contains(filter.SearchIssuedTo)); + + // Discipline + if (!string.IsNullOrWhiteSpace(filter.Discipline)) + q = q.Where(r => r.Discipline.DisciplineName == filter.Discipline); + + // Date range (if you ever add date filters) + if (filter.DateFrom.HasValue) + q = q.Where(r => r.CreatedDate >= filter.DateFrom.Value); + if (filter.DateTo.HasValue) + q = q.Where(r => r.CreatedDate <= filter.DateTo.Value.AddDays(1)); + + var total = await q.CountAsync(ct); + + var data = await q + .OrderByDescending(r => r.CreatedDate) + .Skip((filter.PageNumber - 1) * filter.PageSize) + .Take(filter.PageSize) + .Select(r => new RISResponse + { + RISId = r.RISId, + RISNo = r.RISNo, + InventoryId = r.InventoryId, + ItemName = r.Inventory.InventTrans + .SelectMany(t => t.InventTransDetails) + .Select(d => d.PRDetails != null ? d.PRDetails.ItemName : "—") + .FirstOrDefault() ?? "—", + ItemNo = r.Inventory.ItemNo, + LotNo = r.Inventory.Lot != null ? r.Inventory.Lot.LotName : null, + IssuedTo = r.IssuedTo, + DisciplineName = r.Discipline.DisciplineName, + DisciplineId = r.DisciplineId, + QtyIssued = r.QtyIssued, + Remarks = r.Remarks, + Status = r.Status, + CreatedBy = r.CreatedBy, + CreatedDate = r.CreatedDate, + ApprovedBy = r.ApprovedBy, + ApprovedDate = r.ApprovedDate, + MRSCount = r.MaterialReturns.Count(m => m.Status != 2), + TotalReturned = r.MaterialReturns + .Where(m => m.Status != 2) + .Sum(m => m.QtyReturned) + }) + .ToListAsync(ct); + + // Full department list (never filtered) + var departments = await _db.Departments + .Select(d => d.Department) + .OrderBy(d => d) + .ToListAsync(ct); + + var disciplines = await GetDisciplinesAsync(ct); + + return new RISPagedResult + { + Data = data, + RecordsTotal = total, + DepartmentList = departments, + DisciplineList = disciplines + }; + } + public async Task> GetDisciplinesAsync(CancellationToken ct) + { + return await _db.Disciplines + .OrderBy(d => d.DisciplineName) + .Select(d => new DisciplineDto + { + DisciplineId = d.DisciplineId, + DisciplineName = d.DisciplineName + }) + .ToListAsync(ct); + } + public async Task GetByIdAsync(long risId, CancellationToken ct) + { + return await _db.RIS + .Where(r => r.RISId == risId) + .Select(r => new RISResponse + { + RISId = r.RISId, + RISNo = r.RISNo, + InventoryId = r.InventoryId, + IssuedTo = r.IssuedTo, + DisciplineName = r.Discipline.DisciplineName, + DisciplineId = r.DisciplineId, + QtyIssued = r.QtyIssued, + Remarks = r.Remarks, + Status = r.Status, + CreatedBy = r.CreatedBy, + CreatedDate = r.CreatedDate, + ApprovedBy = r.ApprovedBy, + ApprovedDate = r.ApprovedDate, + MRSCount = r.MaterialReturns.Count(m => m.Status != 2), + TotalReturned = r.MaterialReturns + .Where(m => m.Status != 2) + .Sum(m => m.QtyReturned) + }) + .FirstOrDefaultAsync(ct); + } + } +} diff --git a/CPRNIMS.Domain/UIContracts/Inventory/IInventory.cs b/CPRNIMS.Domain/UIContracts/Inventory/IInventory.cs index 5383bb7..9c7ada8 100644 --- a/CPRNIMS.Domain/UIContracts/Inventory/IInventory.cs +++ b/CPRNIMS.Domain/UIContracts/Inventory/IInventory.cs @@ -1,4 +1,6 @@ using CPRNIMS.Infrastructure.Dto.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Dto.Inventory.Response; using CPRNIMS.Infrastructure.Models.Account; using CPRNIMS.Infrastructure.ViewModel.Inventory; using System; @@ -11,12 +13,15 @@ namespace CPRNIMS.Domain.UIContracts.Inventory { public interface IInventory { + Task GetTransactContextAsync(int inventoryId); Task> GetInventoryByUserId(User user, InventoryVM viewModel); Task> GetRequestedItemByUserId(User user, InventoryVM viewModel); Task> GetInventoryById(User user, InventoryVM viewModel); Task> GetLotNo(User user, InventoryVM viewModel); Task> GetLotQtyByItem(User user, InventoryVM viewModel); Task> GetLotNoById(User user, InventoryVM viewModel); + Task> GetInventory(User user, InventoryRequest request); + Task PostPutLotNo(User user, InventoryVM viewModel); Task PostPutLotBin(User user, InventoryVM viewModel); Task PostPutReqApproval(User user, InventoryVM viewModel); diff --git a/CPRNIMS.Domain/UIContracts/Inventory/IRIS.cs b/CPRNIMS.Domain/UIContracts/Inventory/IRIS.cs new file mode 100644 index 0000000..8df4e60 --- /dev/null +++ b/CPRNIMS.Domain/UIContracts/Inventory/IRIS.cs @@ -0,0 +1,20 @@ +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Dto.Inventory.Response; +using CPRNIMS.Infrastructure.ViewModel.Inventory; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Domain.UIContracts.Inventory +{ + public interface IRIS + { + Task ApproveRIS(ApproveRISRequest request, CancellationToken ct); + Task CancelRIS(CancelRISRequest request, CancellationToken ct); + Task CreateRIS(CreateRISRequest request, CancellationToken ct); + Task GetRISById(int risId, CancellationToken ct); + Task GetRISPaged(RISPagedRequest request, CancellationToken ct); + } +} diff --git a/CPRNIMS.Domain/UIServices/Inventory/Inventory.cs b/CPRNIMS.Domain/UIServices/Inventory/Inventory.cs index 8d26333..eaa0c06 100644 --- a/CPRNIMS.Domain/UIServices/Inventory/Inventory.cs +++ b/CPRNIMS.Domain/UIServices/Inventory/Inventory.cs @@ -1,9 +1,11 @@ using CPRNIMS.Domain.UIContracts.Common; using CPRNIMS.Domain.UIContracts.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Dto.Inventory.Response; using CPRNIMS.Infrastructure.Helper; using CPRNIMS.Infrastructure.Models.Account; using CPRNIMS.Infrastructure.Models.Common; -using CPRNIMS.Infrastructure.ViewModel.Finance; using CPRNIMS.Infrastructure.ViewModel.Inventory; using Microsoft.Extensions.Configuration; using System; @@ -123,6 +125,73 @@ namespace CPRNIMS.Domain.UIServices.Inventory throw; } } + public async Task GetTransactContextAsync(int inventoryId) + { + var token = await _tokenHelper.GetValidTokenAsync(); + + if (string.IsNullOrEmpty(token)) + return null; + + var apiEndpoint = + _configuration["LLI:NonInvent:InventoryMgmt:GetTransactContext"] ?? "api/InventoryMgmt/GetTransactContext"; + + using var httpClient = _apiConfigurationService.CreateHttpClientWithDefaultHeaders(token); + + var response = await httpClient.GetAsync( $"{apiEndpoint}?inventoryId={inventoryId}"); + + if (!response.IsSuccessStatusCode) + return null; + + var jsonResponse = await response.Content.ReadAsStringAsync(); + + return JsonSerializer.Deserialize(jsonResponse, + new JsonSerializerOptions{PropertyNameCaseInsensitive = true}); + } + + public async Task> SendGetPageListApiRequest + (User user, InventoryRequest request, string apiEndpoint) + { + var token = await _tokenHelper.GetValidTokenAsync(); + + try + { + if (string.IsNullOrEmpty(token)) + { + return null; + } + + request.UserId = user.UserId; + var jsonContent = JsonSerializer.Serialize(request); + var content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); + + using (var httpClient = _apiConfigurationService.CreateHttpClientWithDefaultHeaders(token)) + { + HttpResponseMessage response; + + response = await httpClient.PostAsync(apiEndpoint, content); + var jsonResponse = await response.Content.ReadAsStringAsync(); + + if (response.IsSuccessStatusCode) + { + var options = new JsonSerializerOptions { PropertyNameCaseInsensitive = true }; + var result = JsonSerializer.Deserialize>(jsonResponse, options); + return result ?? new PagedResult(); + } + else + { + return new PagedResult + { + IsSuccess = false, + ErrorMessage = $"API returned {response.StatusCode}" + }; + } + } + } + catch (Exception ex) + { + throw; + } + } #endregion #region Get public async Task> GetInventoryById(User user, InventoryVM viewModel) @@ -141,7 +210,11 @@ namespace CPRNIMS.Domain.UIServices.Inventory return await SendGetApiRequest(user, viewModel, _configuration["LLI:NonInvent:InventoryMgmt:GetLotNoById"]); } - + public async Task> GetInventory(User user, InventoryRequest reqquest) + { + return await SendGetPageListApiRequest(user, reqquest, + _configuration["LLI:NonInvent:InventoryMgmt:GetInventory"]); + } public async Task> GetInventoryByUserId(User user, InventoryVM viewModel) { return await SendGetApiRequest(user, viewModel, @@ -153,7 +226,11 @@ namespace CPRNIMS.Domain.UIServices.Inventory return await SendGetApiRequest(user, viewModel, _configuration["LLI:NonInvent:InventoryMgmt:GetRequestedItemByUserId"]); } - + public async Task> GetLotQtyByItem(User user, InventoryVM viewModel) + { + return await SendGetApiRequest(user, viewModel, + _configuration["LLI:NonInvent:InventoryMgmt:GetLotQtyByItem"]); + } #endregion #region Post Put public async Task PostPutReqApproval(User user, InventoryVM viewModel) @@ -177,12 +254,6 @@ namespace CPRNIMS.Domain.UIServices.Inventory return await SendPostApiRequest(user, viewModel, _configuration["LLI:NonInvent:InventoryMgmt:PostPutReqItems"]); } - - public async Task> GetLotQtyByItem(User user, InventoryVM viewModel) - { - return await SendGetApiRequest(user, viewModel, - _configuration["LLI:NonInvent:InventoryMgmt:GetLotQtyByItem"]); - } #endregion } } diff --git a/CPRNIMS.Domain/UIServices/Inventory/RIS.cs b/CPRNIMS.Domain/UIServices/Inventory/RIS.cs new file mode 100644 index 0000000..19c1069 --- /dev/null +++ b/CPRNIMS.Domain/UIServices/Inventory/RIS.cs @@ -0,0 +1,170 @@ +using CPRNIMS.Domain.UIContracts.Common; +using CPRNIMS.Domain.UIContracts.Inventory; +using CPRNIMS.Infrastructure.Dto.Common; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Dto.Inventory.Response; +using CPRNIMS.Infrastructure.Helper; +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; + +namespace CPRNIMS.Domain.UIServices.Inventory +{ + public class RIS : IRIS + { + private readonly IConfiguration _configuration; + private readonly TokenHelper _tokenHelper; + private readonly IApiConfigurationService _apiConfigurationService; + public RIS(IConfiguration configuration, TokenHelper tokenHelper, + IApiConfigurationService apiConfigurationService) + { + _configuration = configuration; + _tokenHelper = tokenHelper; + _apiConfigurationService = apiConfigurationService; + } + #region Get + public async Task GetRISPaged(RISPagedRequest request, CancellationToken ct) + { + try + { + var token = await _tokenHelper.GetValidTokenAsync(); + if (string.IsNullOrEmpty(token)) + throw new InvalidOperationException("Token has been expired."); + + var baseEndpoint = _configuration["LLI:NonInvent:InventoryMgmt:GetRIS"] + ?? throw new InvalidOperationException("GetRIS endpoint is not configured."); + + // ── Build query string — GET request, no body ── + var qs = new StringBuilder(baseEndpoint).Append('?'); + qs.Append($"pageNumber={request.PageNumber}"); + qs.Append($"&pageSize={request.PageSize}"); + + if (!string.IsNullOrWhiteSpace(request.SearchRISNo)) + qs.Append($"&searchRISNo={Uri.EscapeDataString(request.SearchRISNo)}"); + + if (!string.IsNullOrWhiteSpace(request.SearchItemName)) + qs.Append($"&searchItemName={Uri.EscapeDataString(request.SearchItemName)}"); + + if (!string.IsNullOrWhiteSpace(request.SearchIssuedTo)) + qs.Append($"&searchIssuedTo={Uri.EscapeDataString(request.SearchIssuedTo)}"); + + if (!string.IsNullOrWhiteSpace(request.Discipline)) + qs.Append($"&discipline={Uri.EscapeDataString(request.Discipline)}"); + + if (request.Status.HasValue) + qs.Append($"&status={request.Status.Value}"); + + using var httpClient = _apiConfigurationService.CreateHttpClientWithDefaultHeaders(token); + + // ── GET, no content body ── + var response = await httpClient.GetAsync(qs.ToString(), ct); + var json = await response.Content.ReadAsStringAsync(ct); + + if (!response.IsSuccessStatusCode) + { + Console.WriteLine($"[GetRISPaged] Error {(int)response.StatusCode}: {json}"); + return new RISPagedResponse { Data = [], RecordsTotal = 0 }; + } + + var result = JsonSerializer.Deserialize(json, _jsonOptions); + return result ?? new RISPagedResponse(); + } + catch (Exception ex) + { + ex.ToString(); + throw; + } + + } + #endregion + #region Post Put + public async Task ApproveRIS(ApproveRISRequest request, CancellationToken ct) + { + var token = await _tokenHelper.GetValidTokenAsync(); + if (string.IsNullOrEmpty(token)) + throw new InvalidOperationException("Token has been expired."); + + var endpoint = _configuration["LLI:NonInvent:InventoryMgmt:ApproveRIS"] + ?? throw new InvalidOperationException("ApproveRIS endpoint is not configured."); + + using var httpClient = _apiConfigurationService.CreateHttpClientWithDefaultHeaders(token); + using var content = new StringContent(JsonSerializer.Serialize(request),Encoding.UTF8,"application/json"); + + var response = await httpClient.PutAsync(endpoint, content, ct); + var json = await response.Content.ReadAsStringAsync(ct); + + if (!response.IsSuccessStatusCode) + { + return false; + } + return true; + } + + public async Task CancelRIS(CancelRISRequest request, CancellationToken ct) + { + var token = await _tokenHelper.GetValidTokenAsync(); + if (string.IsNullOrEmpty(token)) + throw new InvalidOperationException("Token has been expired."); + + var endpoint = _configuration["LLI:NonInvent:InventoryMgmt:CancelRIS"] + ?? throw new InvalidOperationException("CancelRIS endpoint is not configured."); + + using var httpClient = _apiConfigurationService.CreateHttpClientWithDefaultHeaders(token); + using var content = new StringContent( + JsonSerializer.Serialize(request),Encoding.UTF8,"application/json"); + + var response = await httpClient.PutAsync(endpoint, content, ct); + var json = await response.Content.ReadAsStringAsync(ct); + + if (!response.IsSuccessStatusCode) + { + return false; + } + return true; + } + public async Task CreateRIS(CreateRISRequest request, CancellationToken ct) + { + var token = await _tokenHelper.GetValidTokenAsync(); + if (string.IsNullOrEmpty(token)) + throw new InvalidOperationException("Token has been expired."); + + + var endpoint = _configuration["LLI:NonInvent:InventoryMgmt:CreateRIS"] ?? + throw new InvalidOperationException("CreateRIS endpoint is not configured."); + + using var httpClient = _apiConfigurationService.CreateHttpClientWithDefaultHeaders(token); + using var content = new StringContent( + JsonSerializer.Serialize(request), + Encoding.UTF8, + "application/json"); + + var response = await httpClient.PostAsync(endpoint, content,ct); + + if (!response.IsSuccessStatusCode) + { + return new RISResponse(); + } + + var json = await response.Content.ReadAsStringAsync(); + + var result = JsonSerializer.Deserialize>(json, _jsonOptions); + return result?.data ?? new RISResponse(); + } + + public Task GetRISById(int risId, CancellationToken ct) + { + throw new NotImplementedException(); + } + + private static readonly JsonSerializerOptions _jsonOptions = new() + { + PropertyNameCaseInsensitive = true + }; + #endregion + } +} diff --git a/CPRNIMS.Infrastructure/Database/NonInventoryDbContext.cs b/CPRNIMS.Infrastructure/Database/NonInventoryDbContext.cs index cb34a23..0cd59cf 100644 --- a/CPRNIMS.Infrastructure/Database/NonInventoryDbContext.cs +++ b/CPRNIMS.Infrastructure/Database/NonInventoryDbContext.cs @@ -1,4 +1,5 @@ using CPRNIMS.Infrastructure.Dto.Canvass.Response; +using CPRNIMS.Infrastructure.Dto.Inventory.Response; using CPRNIMS.Infrastructure.Entities.Account; using CPRNIMS.Infrastructure.Entities.Canvass; using CPRNIMS.Infrastructure.Entities.Common; @@ -22,9 +23,7 @@ namespace CPRNIMS.Infrastructure.Database public class NonInventoryDbContext : IdentityDbContext { public NonInventoryDbContext(DbContextOptions options) : base(options) { } - public virtual DbSet ItemCodes { get; set; } - public virtual DbSet ItemList { get; set; } - public virtual DbSet Items { get; set; } + #region Common public DbSet Departments { get; set; } public DbSet IdentityRoles { get; set; } public DbSet AuthorizeRoles { get; set; } @@ -32,39 +31,51 @@ namespace CPRNIMS.Infrastructure.Database public DbSet> IdentityUserRoles { get; set; } public DbSet ForgotPasswords { get; set; } public virtual DbSet Otps { get; set; } + public virtual DbSet ErrorMessages { get; set; } + public virtual DbSet ControllerAccess { get; set; } + public virtual DbSet SMTPCredentials { get; set; } + #endregion + + #region Item + public virtual DbSet ItemCodes { get; set; } + public virtual DbSet ItemList { get; set; } + public virtual DbSet Items { get; set; } public DbSet Attachments { get; set; } public virtual DbSet AttachmentExtensions { get; set; } public virtual DbSet AttachmentFileTypes { get; set; } public virtual DbSet ItemAttachements { get; set; } - public virtual DbSet ErrorMessages { get; set; } - public virtual DbSet ControllerAccess { get; set; } public virtual DbSet ItemCategories { get; set; } public virtual DbSet UnitOfMessures { get; set; } public virtual DbSet ItemColors { get; set; } public virtual DbSet ItemLocalizations { get; set; } public virtual DbSet ItemCarts { get; set; } + public virtual DbSet ItemApprovals { get; set; } + public virtual DbSet ItemDetails { get; set; } + #endregion + + #region PR public virtual DbSet PRs { get; set; } public virtual DbSet Approved { get; set; } public virtual DbSet ApprovedPrs { get; set; } public virtual DbSet DeletedPRs { get; set; } - public virtual DbSet SMTPCredentials { get; set; } public virtual DbSet PRDetails { get; set; } public virtual DbSet PRItemLists { get; set; } public DbSet PRAttachments { get; set; } public DbSet ProjectCodes { get; set; } + public virtual DbSet PRLists { get; set; } + public virtual DbSet PRItemList { get; set; } + public virtual DbSet PRWOCanvasses { get; set; } + public virtual DbSet PRItemDetails { get; set; } + public virtual DbSet DetailedPRTrackings { get; set; } + public virtual DbSet PRTrackings { get; set; } + public virtual DbSet Dashboards { get; set; } + #endregion + + #region Canvassing public virtual DbSet NotificationByIds { get; set; } public virtual DbSet AlternativeOffers { get; set; } public virtual DbSet AlternativeOfferDetails { get; set; } - public virtual DbSet MyPRWOCanvass { get; set; } - public virtual DbSet PRLists { get; set; } - public virtual DbSet PRItemList { get; set; } - public virtual DbSet ItemApprovals { get; set; } - 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 ForRRs { get; set; } - public virtual DbSet RRs { get; set; } + public virtual DbSet MyPRWOCanvass { get; set; } public virtual DbSet Canvasses { get; set; } public DbSet SupplierForCanvass { get; set; } public DbSet SupplierResponses { get; set; } @@ -87,13 +98,17 @@ namespace CPRNIMS.Infrastructure.Database public DbSet ForAISearchingTaggings { get; set; } public virtual DbSet CanvassGroupByPRNos { get; set; } public virtual DbSet ForCanvasses { get; set; } + #endregion + + #region PO public virtual DbSet ForPOs { get; set; } public virtual DbSet CreatedPOs { get; set; } public virtual DbSet CustomPOs { get; set; } - public virtual DbSet IndexCards { get; set; } + public virtual DbSet IndexCards { get; set; } public virtual DbSet ForPOApprovals { get; set; } - public virtual DbSet ApprovedPOs { get; set; } + public virtual DbSet ApprovedPOs { get; set; } public virtual DbSet PurchaseOrders { get; set; } + public virtual DbSet ForPayments { get; set; } public virtual DbSet POs { get; set; } public DbSet PODetails { get; set; } public virtual DbSet PRPOSummaryCounts { get; set; } @@ -103,29 +118,42 @@ namespace CPRNIMS.Infrastructure.Database public virtual DbSet PortOfDischarges { get; set; } public virtual DbSet DocRequireds { get; set; } public virtual DbSet BiddingApprovals { get; set; } - public virtual DbSet RRDetailss { get; set; } - public virtual DbSet RRSeries { get; set; } - public virtual DbSet PRWOCanvasses { get; set; } - public virtual DbSet ForPayments { get; set; } - public virtual DbSet Inventories { get; set; } - public virtual DbSet ItemDetails { get; set; } - public virtual DbSet PRItemDetails { get; set; } - public virtual DbSet Lots { get; set; } - public virtual DbSet LotQtyByItems { get; set; } - public virtual DbSet RequestItems { get; set; } - public virtual DbSet RequestItemDetails { get; set; } + public virtual DbSet NotifUserKeys { get; set; } public virtual DbSet ItemListForPOs { get; set; } public virtual DbSet CreatedPOPerSupIds { get; set; } - public virtual DbSet PRTrackings { get; set; } - public virtual DbSet Dashboards { get; set; } + public DbSet IncomingShipments { get; set; } + public virtual DbSet IncomingShipmentDtos { get; set; } public virtual DbSet PaymentTerms { get; set; } public virtual DbSet Incoterms { get; set; } public virtual DbSet CentralPONos { get; set; } - public virtual DbSet DetailedPRTrackings { get; set; } - public DbSet IncomingShipments { get; set; } - public virtual DbSet IncomingShipmentDtos { get; set; } - + #endregion + + #region Inventory + public virtual DbSet Inventories { get; set; } + public virtual DbSet Lots { get; set; } + public virtual DbSet LotTypes { get; set; } + public virtual DbSet LotQtyByItems { get; set; } + public virtual DbSet RequestItems { get; set; } + public virtual DbSet RequestItemDetails { get; set; } + public virtual DbSet RIS { get; set; } + public virtual DbSet MRS { get; set; } + public virtual DbSet Disciplines { get; set; } + public virtual DbSet InventTrans { get; set; } + public virtual DbSet InventTransDetails { get; set; } + public DbSet InventoryByIdResponses { get; set; } + #endregion + + #region RR + 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 ForRRs { get; set; } + public virtual DbSet RRs { get; set; } + public virtual DbSet RRDetailss { get; set; } + public virtual DbSet RRSeries { get; set; } + #endregion #region Automation Part public virtual DbSet AllForCanvasses { get; set; } @@ -236,6 +264,52 @@ namespace CPRNIMS.Infrastructure.Database { b.ToTable("UserRoles"); }); + modelBuilder.Entity() + .HasOne(i => i.Lot) + .WithMany() + .HasForeignKey(i => i.LotId) + .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity(e => + { + e.HasMany(r => r.InventTransDetails) + .WithOne() + .HasForeignKey(t => t.InventTransId) + .OnDelete(DeleteBehavior.Restrict); + }); + + modelBuilder.Entity(e => + { + e.HasOne(i => i.PRDetails) + .WithMany() + .HasForeignKey(t => t.PRDetailId) + .OnDelete(DeleteBehavior.Restrict); + }); + modelBuilder.Entity(e => + { + e.HasOne(i => i.PRs) + .WithMany() + .HasForeignKey(t => t.PRId) + .OnDelete(DeleteBehavior.Restrict); + }); + + modelBuilder.Entity(e => { + e.HasOne(r => r.Inventory) + .WithMany() + .HasForeignKey(r => r.InventoryId) + .OnDelete(DeleteBehavior.Restrict); + + e.HasOne(r => r.Discipline) + .WithMany() + .HasForeignKey(r => r.DisciplineId); + }); + + modelBuilder.Entity(e => { + e.HasOne(m => m.RIS) + .WithMany(r => r.MaterialReturns) + .HasForeignKey(m => m.RISId) + .OnDelete(DeleteBehavior.Restrict); + }); } } } diff --git a/CPRNIMS.Infrastructure/Dto/Common/ApiResponse.cs b/CPRNIMS.Infrastructure/Dto/Common/ApiResponse.cs new file mode 100644 index 0000000..547ab21 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Common/ApiResponse.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.Common +{ + public class ApiResponse + { + public bool success { get; set; } + public string? message { get; set; } + public T? data { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/DisciplineDto.cs b/CPRNIMS.Infrastructure/Dto/Inventory/DisciplineDto.cs new file mode 100644 index 0000000..442ba21 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/DisciplineDto.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class DisciplineDto + { + public byte DisciplineId { get; set; } + public string DisciplineName { get; set; } = string.Empty; + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/MRSFilterDto.cs b/CPRNIMS.Infrastructure/Dto/Inventory/MRSFilterDto.cs new file mode 100644 index 0000000..0ef727e --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/MRSFilterDto.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class MRSFilterDto + { + public int Page { get; set; } = 1; + public int PageSize { get; set; } = 12; + public string? SearchMRSNo { get; set; } + public long? RISId { get; set; } + public short? Status { get; set; } + public DateTime? DateFrom { get; set; } + public DateTime? DateTo { get; set; } + } + +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/MRSPagedResult.cs b/CPRNIMS.Infrastructure/Dto/Inventory/MRSPagedResult.cs new file mode 100644 index 0000000..2f7e0cc --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/MRSPagedResult.cs @@ -0,0 +1,17 @@ +using CPRNIMS.Infrastructure.Dto.Inventory.Response; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class MRSPagedResult + { + public IEnumerable Data { get; set; } = []; + public int RecordsTotal { get; set; } + public List DepartmentList { get; set; } = new List(); + public List DisciplineList { get; set; } = new List(); + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/PagedResult.cs b/CPRNIMS.Infrastructure/Dto/Inventory/PagedResult.cs new file mode 100644 index 0000000..2c7c075 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/PagedResult.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class PagedResult + { + public List Data { get; set; } = new List(); + public int TotalCount { get; set; } + public int PageNumber { get; set; } + public int PageSize { get; set; } + public List DepartmentList { get; set; } = new List(); + public List CategoryList { get; set; } = new List(); + public bool IsSuccess { get; set; } = true; + public string? ErrorMessage { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/RISFilterDto.cs b/CPRNIMS.Infrastructure/Dto/Inventory/RISFilterDto.cs new file mode 100644 index 0000000..08286ce --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/RISFilterDto.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class RISFilterDto + { + public string? SearchRISNo { get; set; } + public string? SearchItemName { get; set; } + public string? SearchIssuedTo { get; set; } + public string? Discipline { get; set; } + public short? Status { get; set; } + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 12; + public DateTime? DateFrom { get; set; } + public DateTime? DateTo { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/RISPagedResult.cs b/CPRNIMS.Infrastructure/Dto/Inventory/RISPagedResult.cs new file mode 100644 index 0000000..57cd44d --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/RISPagedResult.cs @@ -0,0 +1,17 @@ +using CPRNIMS.Infrastructure.Dto.Inventory.Response; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class RISPagedResult + { + public IEnumerable Data { get; set; } = []; + public int RecordsTotal { get; set; } + public IEnumerable DepartmentList { get; set; } = []; + public IEnumerable DisciplineList { get; set; } = []; + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/RISReferenceDto.cs b/CPRNIMS.Infrastructure/Dto/Inventory/RISReferenceDto.cs new file mode 100644 index 0000000..82579f1 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/RISReferenceDto.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class RISReferenceDto + { + public long RISId { get; set; } + public string RISNo { get; set; } = string.Empty; + public decimal QtyIssued { get; set; } + public decimal TotalReturned { get; set; } + public decimal QtyAvailableToReturn => QtyIssued - TotalReturned; + public string DisciplineName { get; set; } = string.Empty; + public DateTime CreatedDate { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Request/ApproveRISRequest.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Request/ApproveRISRequest.cs new file mode 100644 index 0000000..aba124c --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Request/ApproveRISRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Request +{ + public class ApproveRISRequest + { + public long RISId { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Request/CancelRISRequest.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Request/CancelRISRequest.cs new file mode 100644 index 0000000..a3aa46a --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Request/CancelRISRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Request +{ + public class CancelRISRequest + { + public long RISId { get; set; } + public string Reason { get; set; } = string.Empty; + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateMRSRequest.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateMRSRequest.cs new file mode 100644 index 0000000..0686e4f --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateMRSRequest.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Request +{ + public class CreateMRSRequest + { + public long RISId { get; set; } + public decimal QtyReturned { get; set; } + public string ReturnedBy { get; set; } = string.Empty; + public string? Condition { get; set; } + public string? Remarks { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateRISRequest.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateRISRequest.cs new file mode 100644 index 0000000..6f56b43 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Request/CreateRISRequest.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Request +{ + public class CreateRISRequest + { + public int InventoryId { get; set; } + public long PRDetailId { get; set; } + public string IssuedTo { get; set; } = string.Empty; + public byte DisciplineId { get; set; } + public decimal QtyIssued { get; set; } + public string? Remarks { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Request/InventoryRequest.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Request/InventoryRequest.cs new file mode 100644 index 0000000..039e49d --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Request/InventoryRequest.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Request +{ + public class InventoryRequest + { + public string? SearchPRNo { get; set; } + public string? SearchItemName { get; set; } + public string? SearchDept { get; set; } + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 10; + public byte MessCode { get; set; } + public string? SearchProjectCode { get; set; } + public string? SearchItemNo { get; set; } + public string? UserId { get; set; } + public int InventoryId { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Request/RISPagedRequest.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Request/RISPagedRequest.cs new file mode 100644 index 0000000..24d59dc --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Request/RISPagedRequest.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Request +{ + public class RISPagedRequest + { + public string? SearchRISNo { get; set; } + public string? SearchItemName { get; set; } + public string? SearchIssuedTo { get; set; } + public string? Discipline { get; set; } + public short? Status { get; set; } + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 12; + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/InventoryByIdResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/InventoryByIdResponse.cs new file mode 100644 index 0000000..7d41e3e --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/InventoryByIdResponse.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Response +{ + public class InventoryByIdResponse + { + [Key] + public int InventoryId { get; set; } + public decimal QtyIn { get; set; } + public decimal QtyOut { get; set; } + public decimal QtyOnHand { get; set; } + public string? LotNo { get; set; } + public string? ProjectCode { get; set; } + public string? UserId { get; set; } + public string? ItemName { get; set; } + public string? ItemDescription { get; set; } + public string? ItemCategoryName { get; set; } + public string? Department { get; set; } + public DateTime CreatedDate { get; set; } + public long ItemNo { get; set; } + public long PRNo { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/InventoryResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/InventoryResponse.cs new file mode 100644 index 0000000..5c35a09 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/InventoryResponse.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Response +{ + public class InventoryResponse + { + [Key] + public int InventoryId { get; set; } + public decimal QtyIn { get; set; } + public decimal QtyOut { get; set; } + public decimal QtyOnHand { get; set; } + public string? LotNo { get; set; } + public string? ProjectCode { get; set; } + public string? UserId { get; set; } + public string? ItemName { get; set; } + public string? ItemDescription { get; set; } + public string? ItemCategoryName { get; set; } + public string? Department { get; set; } + public DateTime CreatedDate { get; set; } + public long ItemNo { get; set; } + public long PRNo { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/MRSResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/MRSResponse.cs new file mode 100644 index 0000000..aa5ee86 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/MRSResponse.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Response +{ + public class MRSResponse + { + public long MRSId { get; set; } + public string MRSNo { get; set; } = string.Empty; + public long RISId { get; set; } + public string RISNo { get; set; } = string.Empty; + public int InventoryId { get; set; } + public string ItemName { get; set; } = string.Empty; + public string ReturnedBy { get; set; } = string.Empty; + public decimal QtyReturned { get; set; } + public string? Condition { get; set; } + public string? Remarks { get; set; } + public short Status { get; set; } + public string StatusLabel => Status switch { 0 => "Draft", 1 => "Approved", 2 => "Cancelled", _ => "Unknown" }; + public string CreatedBy { get; set; } = string.Empty; + public DateTime CreatedDate { get; set; } + public string? ApprovedBy { get; set; } + public DateTime? ApprovedDate { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISPagedResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISPagedResponse.cs new file mode 100644 index 0000000..410715d --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISPagedResponse.cs @@ -0,0 +1,56 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Response +{ + public class RISPagedResponse + { + public List Data { get; set; } = []; + + public int RecordsTotal { get; set; } + + public List DepartmentList { get; set; } = []; + + public List DisciplineList { get; set; } = []; + } + public class RISListItem + { + public long RISId { get; set; } + + public string RISNo { get; set; } = string.Empty; + + public int InventoryId { get; set; } + public string? ItemName { get; set; } + + public long ItemNo { get; set; } + + public string? IssuedTo { get; set; } + + public string? DisciplineName { get; set; } + + public decimal QtyIssued { get; set; } + + public decimal TotalReturned { get; set; } + public string? Remarks { get; set; } + + public short Status { get; set; } + + public string? StatusLabel { get; set; } + + public string? CreatedBy { get; set; } + + public DateTime CreatedDate { get; set; } + + public string? ApprovedBy { get; set; } + public DateTime? ApprovedDate { get; set; } + public decimal MRSCount { get; set; } + } + public class DisciplineItem + { + public byte DisciplineId { get; set; } + public string DisciplineName { get; set; } = string.Empty; + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISResponse.cs b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISResponse.cs new file mode 100644 index 0000000..d2fd405 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/Response/RISResponse.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory.Response +{ + public class RISResponse + { + public long RISId { get; set; } + public string RISNo { get; set; } = string.Empty; + public int InventoryId { get; set; } + 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 string DisciplineName { get; set; } = string.Empty; + public string? Message { get; set; } + public byte DisciplineId { get; set; } + public decimal QtyIssued { get; set; } + public string? Remarks { get; set; } + public short Status { get; set; } + public string StatusLabel => Status switch { 0 => "Draft", 1 => "Approved", 2 => "Cancelled", _ => "Unknown" }; + public string CreatedBy { get; set; } = string.Empty; + public DateTime CreatedDate { get; set; } + public string? ApprovedBy { get; set; } + public DateTime? ApprovedDate { get; set; } + public decimal MRSCount { get; set; } + public decimal TotalReturned { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Dto/Inventory/TransactContextDto.cs b/CPRNIMS.Infrastructure/Dto/Inventory/TransactContextDto.cs new file mode 100644 index 0000000..f2d0f95 --- /dev/null +++ b/CPRNIMS.Infrastructure/Dto/Inventory/TransactContextDto.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Dto.Inventory +{ + public class TransactContextDto + { + public int InventoryId { get; set; } + public string ItemName { get; set; } = string.Empty; + public long ItemNo { get; set; } + public long PRNo { get; set; } + public string? LotNo { get; set; } + public string? Department { get; set; } + public decimal QtyOnHand { get; set; } + public decimal QtyIn { get; set; } + public decimal QtyOut { get; set; } + public IEnumerable Disciplines { get; set; } = []; + public IEnumerable OpenRISList { get; set; } = []; + } +} diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/Discipline.cs b/CPRNIMS.Infrastructure/Entities/Inventory/Discipline.cs new file mode 100644 index 0000000..a079dee --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/Inventory/Discipline.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CPRNIMS.Infrastructure.Entities.Inventory +{ + public class Discipline + { + [Key] + public byte DisciplineId { get; set; } + + [Required, MaxLength(100)] + public string DisciplineName { get; set; } = string.Empty; + } +} diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/InventTrans.cs b/CPRNIMS.Infrastructure/Entities/Inventory/InventTrans.cs new file mode 100644 index 0000000..637ba82 --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/Inventory/InventTrans.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.Inventory +{ + [Table("InventTrans")] + public class InventTrans + { + [Key] + public int InventTransId { get; set; } + public int InventoryId { get; set; } + public long RRNo { get; set; } + public string CreatedBy { get; set; }=string.Empty; + public bool IsActive { get; set; } + public ICollection InventTransDetails { get; set; } = []; + } +} diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/InventTransDetail.cs b/CPRNIMS.Infrastructure/Entities/Inventory/InventTransDetail.cs new file mode 100644 index 0000000..3ad7002 --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/Inventory/InventTransDetail.cs @@ -0,0 +1,28 @@ +using CPRNIMS.Infrastructure.Entities.Purchasing; +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.Inventory +{ + [Table("InventTransDetail")] + public class InventTransDetail + { + [Key] + 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 PRDetails? PRDetails { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/Inventory.cs b/CPRNIMS.Infrastructure/Entities/Inventory/Inventory.cs index 1706872..6254c2d 100644 --- a/CPRNIMS.Infrastructure/Entities/Inventory/Inventory.cs +++ b/CPRNIMS.Infrastructure/Entities/Inventory/Inventory.cs @@ -1,12 +1,15 @@ -using System; +using CPRNIMS.Infrastructure.Entities.Account; +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.Inventory { + [Table("Inventory")] public class Inventory { [Key] @@ -14,15 +17,12 @@ namespace CPRNIMS.Infrastructure.Entities.Inventory public decimal QtyIn { get; set; } public decimal QtyOut { get; set; } public decimal QtyOnHand { get; set; } - public decimal RemainingQty { get; set; } - public string? LotNo { get; set; } public string? UserId { get; set; } - public string? ItemName { get; set; } - public string? ItemDescription { get; set; } - public string? ItemCategoryName { get; set; } - public string? Department { get; set; } - public DateTime CreatedDate { get; set; } public bool IsActive { get; set; } public long ItemNo { get; set; } + public int LotId { get; set; } + public Lot? Lot { get; set; } + public ICollection InventTrans { get; set; } = []; + public ApplicationUser? User { get; set; } } } diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/Lot.cs b/CPRNIMS.Infrastructure/Entities/Inventory/Lot.cs index e788cec..a21e394 100644 --- a/CPRNIMS.Infrastructure/Entities/Inventory/Lot.cs +++ b/CPRNIMS.Infrastructure/Entities/Inventory/Lot.cs @@ -17,8 +17,8 @@ namespace CPRNIMS.Infrastructure.Entities.Inventory public int LotId { get; set; } public int InventoryId { get; set; } public string? LotName { get; set; } - public string? LotTypeName { get; set; } public byte LotTypeId { get; set; } public string? UserId { get; set; } + public LotType? LotType { get; set; } } } diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/LotType.cs b/CPRNIMS.Infrastructure/Entities/Inventory/LotType.cs new file mode 100644 index 0000000..e711f65 --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/Inventory/LotType.cs @@ -0,0 +1,18 @@ +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.Inventory +{ + [Table("LotType")] + public class LotType + { + [Key] + public int LotTypeId { get; set; } + public string? LotTypeName { get; set; } + } +} diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/MRS.cs b/CPRNIMS.Infrastructure/Entities/Inventory/MRS.cs new file mode 100644 index 0000000..352038d --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/Inventory/MRS.cs @@ -0,0 +1,46 @@ +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.Inventory +{ + [Table("MRS")] + public class MRS + { + [Key] + public long MRSId { get; set; } + + [Required, MaxLength(50)] + public string MRSNo { get; set; } = string.Empty; + public long RISId { get; set; } + public int InventoryId { get; set; } + [Required, MaxLength(450)] + public string ReturnedBy { get; set; } = string.Empty; + public decimal QtyReturned { get; set; } + + [MaxLength(100)] + public string? Condition { get; set; } + + [MaxLength(500)] + public string? Remarks { get; set; } + + public short Status { get; set; } = 0; + + [Required, MaxLength(450)] + public string CreatedBy { get; set; } = string.Empty; + + public DateTime CreatedDate { get; set; } = DateTime.Now; + public string? ApprovedBy { get; set; } + public DateTime? ApprovedDate { get; set; } + public string? CanceledBy { get; set; } + public DateTime? CanceledDate { get; set; } + public string? Reason { get; set; } + public RIS RIS { get; set; } = null!; + public Inventory Inventory { get; set; } = null!; + } + +} diff --git a/CPRNIMS.Infrastructure/Entities/Inventory/RIS.cs b/CPRNIMS.Infrastructure/Entities/Inventory/RIS.cs new file mode 100644 index 0000000..3f95684 --- /dev/null +++ b/CPRNIMS.Infrastructure/Entities/Inventory/RIS.cs @@ -0,0 +1,48 @@ +using CPRNIMS.Infrastructure.Entities.Purchasing; +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.Inventory +{ + [Table("RIS")] + public class RIS + { + [Key] + public long RISId { get; set; } + + [Required, MaxLength(50)] + public string RISNo { get; set; } = string.Empty; + + 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; } + + [MaxLength(500)] + public string? Remarks { get; set; } + + public short Status { get; set; } = 0; + + [Required, MaxLength(450)] + public string CreatedBy { get; set; } = string.Empty; + public DateTime CreatedDate { get; set; } = DateTime.Now; + public string? ApprovedBy { get; set; } + public DateTime? ApprovedDate { get; set; } + public string? CanceledBy { get; set; } + public DateTime? CanceledDate { get; set; } + public string? Reason { get; set; } + public Inventory Inventory { get; set; } = null!; + public PRDetails PRDetail { get; set; } = null!; + public Discipline Discipline { get; set; } = null!; + public ICollection MaterialReturns { get; set; } = []; + } + } diff --git a/CPRNIMS.Infrastructure/Entities/Purchasing/PRDetails.cs b/CPRNIMS.Infrastructure/Entities/Purchasing/PRDetails.cs index ba03ae7..b3d2c0c 100644 --- a/CPRNIMS.Infrastructure/Entities/Purchasing/PRDetails.cs +++ b/CPRNIMS.Infrastructure/Entities/Purchasing/PRDetails.cs @@ -15,6 +15,7 @@ namespace CPRNIMS.Infrastructure.Entities.Purchasing { [Key] public long PRDetailsId { get; set; } + public long PRId { get; set; } public string ItemName { get; set; }=string.Empty; public string ItemDescription { get; set; } = string.Empty; public short Status { get; set; } @@ -22,5 +23,6 @@ namespace CPRNIMS.Infrastructure.Entities.Purchasing public long ItemNo { get; set; } public decimal Qty { get; set; } public bool IsSearched { get; set; } + public PR? PRs { get; set; } } } diff --git a/CPRNIMS.Infrastructure/Models/RegisterModel.cs b/CPRNIMS.Infrastructure/Models/RegisterModel.cs index 01eafdd..c6f01de 100644 --- a/CPRNIMS.Infrastructure/Models/RegisterModel.cs +++ b/CPRNIMS.Infrastructure/Models/RegisterModel.cs @@ -10,15 +10,11 @@ namespace CPRNIMS.Infrastructure.Models { public class RegisterModel : ApplicationUser { - [EmailAddress] - [Required(ErrorMessage = "Email is required")] - public string Email { get; set; } - public string Role { get; set; } + public string? Role { get; set; } [Required(ErrorMessage = "Password is required")] public string? Password { get; set; } - //public string? UserId { get; set; } [Required(ErrorMessage = "ClaimType is required")] public string? ClaimType { get; set; } [Required(ErrorMessage = "ClaimValue is required")] diff --git a/CPRNIMS.Infrastructure/ViewModel/Account/LoginVM.cs b/CPRNIMS.Infrastructure/ViewModel/Account/LoginVM.cs index ade4e3c..2605c10 100644 --- a/CPRNIMS.Infrastructure/ViewModel/Account/LoginVM.cs +++ b/CPRNIMS.Infrastructure/ViewModel/Account/LoginVM.cs @@ -13,7 +13,5 @@ namespace CPRNIMS.Infrastructure.ViewModel.Account public int Id { get; set; } public string? Message { get; set; } public string? Status { get; set; } - public string? Token { get; internal set; } - } } diff --git a/CPRNIMS.Infrastructure/ViewModel/Inventory/InventoryVM.cs b/CPRNIMS.Infrastructure/ViewModel/Inventory/InventoryVM.cs index 47cbc4b..5a354d4 100644 --- a/CPRNIMS.Infrastructure/ViewModel/Inventory/InventoryVM.cs +++ b/CPRNIMS.Infrastructure/ViewModel/Inventory/InventoryVM.cs @@ -70,5 +70,12 @@ namespace CPRNIMS.Infrastructure.ViewModel.Inventory public DateTime DateTo { get; set; } public bool IsSorting { get; set; } public string? URL { get; set; } + public string SearchPRNo { get; set; } = ""; + public string SearchItemName { get; set; } = ""; + public string SearchDept { get; set; } = ""; + public int PageNumber { get; set; } = 1; + public int PageSize { get; set; } = 10; + public byte MessCode { get; set; } + public string? SearchProjectCode { get; set; } } } diff --git a/CPRNIMS.WebApi/CPRNIMS.WebApi.csproj b/CPRNIMS.WebApi/CPRNIMS.WebApi.csproj index 753cb2d..e381846 100644 --- a/CPRNIMS.WebApi/CPRNIMS.WebApi.csproj +++ b/CPRNIMS.WebApi/CPRNIMS.WebApi.csproj @@ -147,6 +147,7 @@ + diff --git a/CPRNIMS.WebApi/Common/ServiceExtensions.cs b/CPRNIMS.WebApi/Common/ServiceExtensions.cs index f3e9468..56889d1 100644 --- a/CPRNIMS.WebApi/Common/ServiceExtensions.cs +++ b/CPRNIMS.WebApi/Common/ServiceExtensions.cs @@ -152,6 +152,8 @@ namespace CPRNIMS.WebApi.Common services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); + services.AddScoped(); #region Automation using LLM services.AddHttpClient(); diff --git a/CPRNIMS.WebApi/Controllers/Inventory/InventoryMgmtController.cs b/CPRNIMS.WebApi/Controllers/Inventory/InventoryMgmtController.cs index 3e56055..dcf6f2e 100644 --- a/CPRNIMS.WebApi/Controllers/Inventory/InventoryMgmtController.cs +++ b/CPRNIMS.WebApi/Controllers/Inventory/InventoryMgmtController.cs @@ -1,6 +1,8 @@ using CPRNIMS.Domain.Contracts.Inventory; using CPRNIMS.Domain.Services; using CPRNIMS.Infrastructure.Dto.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Dto.PR; using CPRNIMS.WebApi.Controllers.Base; using Microsoft.AspNetCore.Mvc; @@ -10,16 +12,23 @@ namespace CPRNIMS.WebApi.Controllers.Inventory public class InventoryMgmtController : BaseController { private readonly IInventory _inventory; - public InventoryMgmtController(ErrorMessageService errorMessageService, IWebHostEnvironment webHostEnvironment, IConfiguration configuration, IInventory inventory) : base(errorMessageService, webHostEnvironment,configuration) + => _inventory = inventory; + + #region Get + [HttpGet("GetTransactContext")] + public async Task GetTransactContext([FromQuery] int inventoryId, CancellationToken ct) { - _inventory = inventory; + var ctx = await _inventory.GetTransactContextAsync(inventoryId, ct); + if (ctx == null) + return NotFound(new { success = false, message = "Inventory record not found." }); + + return Ok(ctx); } - #region Get [HttpPost("GetInventoryByUserId")] public async Task GetInventoryByUserId(InventoryDto itemCodeDto) { @@ -28,83 +37,45 @@ namespace CPRNIMS.WebApi.Controllers.Inventory [HttpPost("GetRequestedItemByUserId")] public async Task GetRequestedItemByUserId(InventoryDto itemCodeDto) { - try - { - var allPR = await _inventory.GetRequestedItemByUserId(itemCodeDto); + var allPR = await _inventory.GetRequestedItemByUserId(itemCodeDto); - return Ok(allPR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "GetRequestedItemByUserId", "WebApi"); - throw; - } + return Ok(allPR); } - //GetRequestedItemByUserId - [HttpPost("GetInventoryById")] - public async Task GetInventoryById(InventoryDto itemCodeDto) + + [HttpPost("GetInventory")] + public async Task GetInventory(InventoryRequest request, CancellationToken ct) { - try - { - var allPR = await _inventory.GetInventoryById(itemCodeDto); - - return Ok(allPR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "GetInventoryById", "WebApi"); - throw; - } + var result = await _inventory.GetInventory(request, ct); + return Ok(result); } + + [HttpPost("GetInventoryById")] + public async Task GetInventoryById(InventoryRequest request, CancellationToken ct) + { + var result = await _inventory.GetInventoryById(request, ct); + return Ok(result); + } + [HttpPost("GetLotNo")] public async Task GetLotNo(InventoryDto itemCodeDto) { - try - { - var allPR = await _inventory.GetLotNo(itemCodeDto); + var allPR = await _inventory.GetLotNo(itemCodeDto); - return Ok(allPR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "GetInventoryById", "WebApi"); - throw; - } + return Ok(allPR); } [HttpPost("GetLotNoById")] public async Task GetLotNoById(InventoryDto itemCodeDto) { - try - { - var allPR = await _inventory.GetLotNoById(itemCodeDto); + var allPR = await _inventory.GetLotNoById(itemCodeDto); - return Ok(allPR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "GetInventoryById", "WebApi"); - throw; - } + return Ok(allPR); } [HttpPost("GetLotQtyByItem")] public async Task GetLotQtyByItem(InventoryDto itemCodeDto) { - try - { - var allPR = await _inventory.GetLotQtyByItem(itemCodeDto); + var allPR = await _inventory.GetLotQtyByItem(itemCodeDto); - return Ok(allPR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "GetLotQtyByItem", "WebApi"); - throw; - } + return Ok(allPR); } #endregion @@ -112,66 +83,28 @@ namespace CPRNIMS.WebApi.Controllers.Inventory [HttpPost("PostPutReqItems")] public async Task PostPutReqItems(InventoryDto InventoryDto) { - try - { - var pR = await _inventory.PostPutReqItems(InventoryDto); + var pR = await _inventory.PostPutReqItems(InventoryDto); - return Ok(pR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "PostPutReqItems", "WebApi"); - throw; - } + return Ok(pR); } [HttpPost("PostPutReqApproval")] public async Task PostPutReqApproval(InventoryDto InventoryDto) { - try - { - var pR = await _inventory.PostPutReqApproval(InventoryDto); + var pR = await _inventory.PostPutReqApproval(InventoryDto); - return Ok(pR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "PostPutReqApproval", "WebApi"); - throw; - } + return Ok(pR); } [HttpPost("PostPutLotNo")] public async Task PostPutLotNo(InventoryDto InventoryDto) { - try - { - var pR = await _inventory.PostPutLotNo(InventoryDto); - - return Ok(pR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "PostPutReqApproval", "WebApi"); - throw; - } + var pR = await _inventory.PostPutLotNo(InventoryDto); + return Ok(pR); } [HttpPost("PostPutLotBin")] public async Task PostPutLotBin(InventoryDto InventoryDto) { - try - { - var pR = await _inventory.PostPutLotBin(InventoryDto); - - return Ok(pR); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - await PostErrorMessage(message + "PostPutLotBin", "WebApi"); - throw; - } + var pR = await _inventory.PostPutLotBin(InventoryDto); + return Ok(pR); } #endregion } diff --git a/CPRNIMS.WebApi/Controllers/Inventory/MRSMgmtController.cs b/CPRNIMS.WebApi/Controllers/Inventory/MRSMgmtController.cs new file mode 100644 index 0000000..9fe8990 --- /dev/null +++ b/CPRNIMS.WebApi/Controllers/Inventory/MRSMgmtController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CPRNIMS.WebApi.Controllers.Inventory +{ + public class MRSMgmtController : Controller + { + public IActionResult Index() + { + return View(); + } + } +} diff --git a/CPRNIMS.WebApi/Controllers/Inventory/RISMgmtController.cs b/CPRNIMS.WebApi/Controllers/Inventory/RISMgmtController.cs new file mode 100644 index 0000000..dea47b2 --- /dev/null +++ b/CPRNIMS.WebApi/Controllers/Inventory/RISMgmtController.cs @@ -0,0 +1,76 @@ +using Azure.Core; +using CPRNIMS.Domain.Contracts.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.WebApi.Security; +using Microsoft.AspNetCore.Mvc; +using System.Security.Claims; + +namespace CPRNIMS.WebApi.Controllers.Inventory +{ + [Route("api/[controller]")] + [ApiController] + public class RISMgmtController : ControllerBase + { + private readonly IRIS _risRepo; + public RISMgmtController(IRIS risRepo) { + _risRepo = risRepo; + } + + [HttpGet("GetRIS")] + public async Task GetRIS([FromQuery] RISFilterDto filter, CancellationToken ct) + { + var result = await _risRepo.GetPagedAsync(filter,ct); + + return Ok(result); + } + [HttpGet("{id}")] + public async Task GetRISById(long id, CancellationToken ct) + { + return Ok(await _risRepo.GetByIdAsync(id, ct)); + } + + [HttpPost] + public async Task CreateRIS([FromBody] CreateRISRequest request,CancellationToken ct) + { + var currentUser = User.ToUserClaims(); + if (currentUser == null) + return BadRequest(); + + if (!ModelState.IsValid) + return BadRequest(new + { + success = false, + message = "Validation failed.", + errors = ModelState.Values + .SelectMany(v => v.Errors) + .Select(e => e.ErrorMessage) + }); + + var ris = await _risRepo.CreateAsync(request, currentUser.UserName,ct); + return Ok(new + { + success = true, + message = $"RIS {ris.RISNo} created successfully.", + data= ris + }); + } + + [HttpPut("ApproveRIS")] + public async Task ApproveRIS([FromBody] ApproveRISRequest request, CancellationToken ct) + { + var currentUser = User.ToUserClaims(); + if(currentUser == null) + return BadRequest(); + + await _risRepo.ApproveAsync(request, currentUser.UserName, ct); + return Ok(new { success = true, message = "RIS approved." }); + } + [HttpPut("CancelRIS")] + public async Task CancelRIS([FromBody] CancelRISRequest request, CancellationToken ct) + { + await _risRepo.CancelAsync(request, ct); + return Ok(new { success = true, message = "RIS cancelled and inventory restored." }); + } + } +} diff --git a/CPRNIMS.WebApi/Sql/Phase 5/StoredProc.sql b/CPRNIMS.WebApi/Sql/Phase 5/StoredProc.sql new file mode 100644 index 0000000..1ed4e0f --- /dev/null +++ b/CPRNIMS.WebApi/Sql/Phase 5/StoredProc.sql @@ -0,0 +1,117 @@ +USE [CPRNIMS] +GO +/****** Object: StoredProcedure [dbo].[GetInventory] Script Date: 6/11/2026 9:29:29 AM ******/ +SET ANSI_NULLS ON +GO +SET QUOTED_IDENTIFIER ON +GO +ALTER PROCEDURE [dbo].[GetInventory] +( + @UserId VARCHAR(450)='89da2977-c70f-4df9-94d4-9a610aa999ea', + @SearchPRNo VARCHAR(50) = '', + @SearchItemNo VARCHAR(50) = '', + @SearchItemName VARCHAR(100) = '', + @SearchDept VARCHAR(200) = '', + @SearchProjectCode VARCHAR(200) = '', + @PageNumber INT = 1, + @PageSize INT = 10 +) +AS +BEGIN + SET NOCOUNT ON; + DECLARE @Offset INT = (@PageNumber - 1) * @PageSize; + + -- ── 1. Full department list — unaffected by any filter ────────────── + SELECT DISTINCT D.Department + FROM dbo.Departments D + INNER JOIN dbo.Users U + ON U.DepartmentId = D.DepartmentId + INNER JOIN dbo.Inventory IV + ON IV.UserId = U.Id + ORDER BY D.Department; + + -- ── 2. Filtered temp table ─────────────────────────────────────────── + IF OBJECT_ID('tempdb..#Inventory') IS NOT NULL + DROP TABLE #Inventory; + + SELECT + IV.InventoryId + , IV.ItemNo + , IV.QtyOnHand + , IV.QtyIn + , IV.QtyOut + , L.LotName AS LotNo + , IV.UserId + , PR.PRNo + , PRD.ItemName + , D.Department + , PRD.ItemDescription + , ICAT.ItemCategoryName + , RRD.RemainingQty + , ITD.CreatedDate + ,COALESCE(PCD.ProjectCode,'N/A') ProjectCode + INTO #Inventory + FROM dbo.Inventory IV + INNER JOIN dbo.InventTrans IT + ON IV.InventoryId = IT.InventoryId + INNER JOIN dbo.InventTransDetail ITD + ON IT.InventTransId = ITD.InventTransId + INNER JOIN dbo.PRDetails PRD + ON ITD.PRDetailId = PRD.PRDetailsId + AND PRD.IsActive = 1 + INNER JOIN dbo.RRDetails RRD + ON PRD.PRDetailsId = RRD.PRDetailId + AND RRD.IsActive = 1 + INNER JOIN dbo.ItemCategories ICAT + ON PRD.ItemCategoryId = ICAT.ItemCategoryId + INNER JOIN dbo.Lot L + ON IV.LotId = L.LotId + INNER JOIN dbo.LotType LT + ON L.LotTypeId = LT.LotTypeId + INNER JOIN dbo.PR PR + ON PR.UserId = IV.UserId + AND PR.IsActive = 1 + INNER JOIN dbo.ProjectCodes PC + ON PR.ProjectCodeId = PC.ProjectCodeId + INNER JOIN dbo.Users U + ON IV.UserId = U.Id + INNER JOIN dbo.Departments D + ON U.DepartmentId = D.DepartmentId + INNER JOIN dbo.ProjectCodes PCD + ON PR.ProjectCodeId = PCD.ProjectCodeId + WHERE ITD.TransTypeId=2 AND IV.IsActive=1 AND ITD.IsActive=1 AND + (@SearchPRNo = '' OR PR.PRNo = @SearchPRNo) + AND (@SearchItemNo = '' OR PRD.ItemNo = @SearchItemNo) + AND (@SearchItemName = '' OR PRD.ItemName LIKE '%' + @SearchItemName + '%') + AND (@SearchDept = '' OR D.Department LIKE '%' + @SearchDept + '%') + AND (@SearchProjectCode = '' OR PC.ProjectCode LIKE '%' + @SearchProjectCode + '%') + GROUP BY + IV.InventoryId + , IV.ItemNo + , IV.QtyOnHand + , IV.QtyIn + , IV.QtyOut + , L.LotName + , IV.UserId + , PR.PRNo + , PRD.ItemName + , D.Department + , PRD.ItemDescription + , ICAT.ItemCategoryName + , RRD.RemainingQty + , ITD.CreatedDate + ,PCD.ProjectCode; + + -- ── 3. Total count of filtered results ────────────────────────────── + SELECT COUNT(*) AS TotalCount + FROM #Inventory; + + -- ── 4. Paged filtered results ──────────────────────────────────────── + SELECT * + FROM #Inventory + ORDER BY CreatedDate DESC + OFFSET @Offset ROWS + FETCH NEXT @PageSize ROWS ONLY; + + DROP TABLE #Inventory; +END \ No newline at end of file diff --git a/CPRNIMS.WebApi/Sql/Phase 5/Table.sql b/CPRNIMS.WebApi/Sql/Phase 5/Table.sql new file mode 100644 index 0000000..afa20a8 --- /dev/null +++ b/CPRNIMS.WebApi/Sql/Phase 5/Table.sql @@ -0,0 +1,61 @@ +-- ── Disciplines lookup (Trade / Matrix / Structural / Architectural) ── +CREATE TABLE [dbo].[Disciplines] ( + [DisciplineId] TINYINT IDENTITY(1,1) PRIMARY KEY NOT NULL, + [DisciplineName] VARCHAR(100) NOT NULL +); + +INSERT INTO [dbo].[Disciplines] ([DisciplineName]) VALUES + ('Trade'), + ('Matrix'), + ('Structural'), + ('Architectural'); + +-- ── RIS: Return Issuance Slip ───────────────────────────────────── +CREATE TABLE [dbo].[RIS] ( + [RISId] BIGINT IDENTITY(1,1) PRIMARY KEY NOT NULL, + [RISNo] VARCHAR(50) NOT NULL, -- generated slip number + [InventoryId] INT NOT NULL, + [PRDetailId] BIGINT NOT NULL, + [IssuedTo] VARCHAR(450) NOT NULL, -- UserId receiving items + [DisciplineId] TINYINT NOT NULL, -- Trade/Matrix/Structural/Architectural + [QtyIssued] DECIMAL(14,2) NOT NULL, + [Remarks] VARCHAR(500) NULL, + [Status] SMALLINT NOT NULL DEFAULT 0, -- 0=Draft,1=Approved,2=Cancelled + [CreatedBy] VARCHAR(450) NOT NULL, + [CreatedDate] DATETIME NOT NULL DEFAULT GETDATE(), + [ApprovedBy] VARCHAR(450) NULL, + [ApprovedDate] DATETIME NULL, + CanceledBy VARCHAR(50) NULL, + CanceledDate DATETIME NULL, + Reason VARCHAR(150) NULL, + FOREIGN KEY ([InventoryId]) REFERENCES [Inventory]([InventoryId]), + FOREIGN KEY ([PRDetailId]) REFERENCES [PRDetails]([PRDetailsId]), + FOREIGN KEY ([DisciplineId]) REFERENCES [Disciplines]([DisciplineId]) +); + +-- ── MRS: Material Return Slip ───────────────────────────────────── +CREATE TABLE [dbo].[MRS] ( + [MRSId] BIGINT IDENTITY(1,1) PRIMARY KEY NOT NULL, + [MRSNo] VARCHAR(50) NOT NULL, + [RISId] BIGINT NOT NULL, -- must reference an original issuance + [InventoryId] INT NOT NULL, + [ReturnedBy] VARCHAR(450) NOT NULL, + [QtyReturned] DECIMAL(14,2) NOT NULL, + [Condition] VARCHAR(100) NULL, -- Good / Damaged / Partial + [Remarks] VARCHAR(500) NULL, + [Status] SMALLINT NOT NULL DEFAULT 0, + [CreatedBy] VARCHAR(450) NOT NULL, + [CreatedDate] DATETIME NOT NULL DEFAULT GETDATE(), + [ApprovedBy] VARCHAR(450) NULL, + [ApprovedDate] DATETIME NULL, + CanceledBy VARCHAR(50) NULL, + CanceledDate DATETIME NULL, + Reason VARCHAR(150) NULL, + FOREIGN KEY ([RISId]) REFERENCES [RIS]([RISId]), + FOREIGN KEY ([InventoryId]) REFERENCES [Inventory]([InventoryId]) +); + +INSERT INTO [dbo].[TransTypes] +(TransTypeName) +VALUES +('RIS'),('MRS') \ No newline at end of file diff --git a/CPRNIMS.WebApps/Common/ServiceExtensions.cs b/CPRNIMS.WebApps/Common/ServiceExtensions.cs index 3d5257f..0b5b8f8 100644 --- a/CPRNIMS.WebApps/Common/ServiceExtensions.cs +++ b/CPRNIMS.WebApps/Common/ServiceExtensions.cs @@ -87,6 +87,7 @@ namespace CPRNIMS.WebApps.Common builder.Services.AddTransient(); builder.Services.AddTransient(); builder.Services.AddScoped(); + builder.Services.AddScoped(); } private static void AddSessionAndAuthentication(WebApplicationBuilder builder) diff --git a/CPRNIMS.WebApps/Controllers/Inventory/InventoryMgmtController.cs b/CPRNIMS.WebApps/Controllers/Inventory/InventoryMgmtController.cs index 82c53a8..cc22a7e 100644 --- a/CPRNIMS.WebApps/Controllers/Inventory/InventoryMgmtController.cs +++ b/CPRNIMS.WebApps/Controllers/Inventory/InventoryMgmtController.cs @@ -1,13 +1,12 @@ -using CPRNIMS.Domain.UIContracts.Account; +using Azure.Core; +using CPRNIMS.Domain.UIContracts.Account; using CPRNIMS.Domain.UIContracts.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; using CPRNIMS.Infrastructure.Helper; -using CPRNIMS.Infrastructure.ViewModel.Account; -using CPRNIMS.Infrastructure.ViewModel.Finance; using CPRNIMS.Infrastructure.ViewModel.Inventory; using CPRNIMS.WebApps.Controllers.Base; using Microsoft.AspNetCore.Mvc; -using Microsoft.IdentityModel.Tokens; -using static System.Runtime.InteropServices.JavaScript.JSType; + namespace CPRNIMS.WebApps.Controllers.Inventory { @@ -23,61 +22,30 @@ namespace CPRNIMS.WebApps.Controllers.Inventory _inventory = inventory; } #region Get + public async Task GetTransactContext(int inventoryId) + { + var response = await _inventory.GetTransactContextAsync(inventoryId); + return GetResponse(response); + } public async Task GetLotQtyByItem(InventoryVM viewModels) { - try - { - response = await _inventory.GetLotQtyByItem(GetUser(), viewModels); - return GetResponse(response); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - - throw; - } + response = await _inventory.GetLotQtyByItem(GetUser(), viewModels); + return GetResponse(response); } public async Task GetLotNo(InventoryVM viewModels) { - try - { - response = await _inventory.GetLotNo(GetUser(), viewModels); - return GetResponse(response); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - - throw; - } + response = await _inventory.GetLotNo(GetUser(), viewModels); + return GetResponse(response); } public async Task GetLotNoById(InventoryVM viewModels) { - try - { - response = await _inventory.GetLotNoById(GetUser(), viewModels); - return GetResponse(response); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - - throw; - } + response = await _inventory.GetLotNoById(GetUser(), viewModels); + return GetResponse(response); } public async Task GetInventoryById(InventoryVM viewModels) { - try - { - response = await _inventory.GetInventoryById(GetUser(), viewModels); - return GetResponse(response); - } - catch (Exception ex) - { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - - throw; - } + response = await _inventory.GetInventoryById(GetUser(), viewModels); + return GetResponse(response); } public async Task GetInventoryByUserId(InventoryVM viewModels) { @@ -86,99 +54,88 @@ namespace CPRNIMS.WebApps.Controllers.Inventory } public async Task GetRequestedItemByUserId(InventoryVM viewModels) { - try + response = await _inventory.GetRequestedItemByUserId(GetUser(), viewModels); + return GetResponse(response); + } + [HttpGet] + public async Task GetInventory(string searchPRNo = "", string searchItemNo = "",string searchItemName = "", + string searchDept = "",string searchProjectCode="", int pageNumber = 1, int pageSize = 10) + { + var request = new InventoryRequest { - response = await _inventory.GetRequestedItemByUserId(GetUser(), viewModels); - return GetResponse(response); - } - catch (Exception ex) + SearchPRNo = searchPRNo, + SearchItemNo = searchItemNo, + SearchItemName = searchItemName, + SearchDept = searchDept, + SearchProjectCode = searchProjectCode, + PageNumber = pageNumber, + PageSize = pageSize + }; + + var result = await _inventory.GetInventory(GetUser(), request); + int draw = int.TryParse(Request.Query["draw"], out int d) ? d : 1; + + return Json(new { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - - throw; - } + draw = draw, + recordsTotal = result.TotalCount, + recordsFiltered = result.TotalCount, + data = result.Data, + departmentList=result.DepartmentList, + }); } #endregion #region POST PUT public async Task PostPutLotNo(InventoryVM viewModel) { - try - { - var postPutItem = await _inventory.PostPutLotNo(GetUser(), viewModel); + var postPutItem = await _inventory.PostPutLotNo(GetUser(), viewModel); - if (postPutItem.StatusResponse != "Error") - { - return Json(new { success = true }); - } - - return Json(new { success = false, Response = postPutItem.Message }); - } - catch (Exception ex) + if (postPutItem.StatusResponse != "Error") { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - throw; + return Json(new { success = true }); } + + return Json(new { success = false, Response = postPutItem.Message }); } public async Task PostPutLotBin(InventoryVM viewModel) { - try - { - var postPutItem = await _inventory.PostPutLotBin(GetUser(), viewModel); + var postPutItem = await _inventory.PostPutLotBin(GetUser(), viewModel); - if (postPutItem.StatusResponse != "Error") - { - return Json(new { success = true }); - } - - return Json(new { success = false, Response = postPutItem.Message }); - } - catch (Exception ex) + if (postPutItem.StatusResponse != "Error") { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - - throw; + return Json(new { success = true }); } + + return Json(new { success = false, Response = postPutItem.Message }); } public async Task PostPutReqApproval(InventoryVM viewModel) { - try - { - var postPutItem = await _inventory.PostPutReqApproval(GetUser(), viewModel); + var postPutItem = await _inventory.PostPutReqApproval(GetUser(), viewModel); - if (postPutItem.StatusResponse != "Error") - { - return Json(new { success = true }); - } - - return Json(new { success = false, Response = postPutItem.Message }); - } - catch (Exception ex) + if (postPutItem.StatusResponse != "Error") { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - throw; + return Json(new { success = true }); } + + return Json(new { success = false, Response = postPutItem.Message }); } public async Task PostPutReqItems(InventoryVM viewModel) { - try - { - var postPutItem = await _inventory.PostPutReqItems(GetUser(), viewModel); + var postPutItem = await _inventory.PostPutReqItems(GetUser(), viewModel); - if (postPutItem.StatusResponse != "Error") - { - return Json(new { success = true }); - } - - return Json(new { success = false, Response = postPutItem.Message }); - } - catch (Exception ex) + if (postPutItem.StatusResponse != "Error") { - var message = ex.InnerException?.ToString() ?? ex.Message.ToString(); - throw; + return Json(new { success = true }); } + + return Json(new { success = false, Response = postPutItem.Message }); } #endregion #region Views + public IActionResult GetInventoryTabPage(int id) + { + return ViewComponent("InventoryTabPage", new { inventoryTabPageId = id }); + } public async Task Inventory() { return await IsAuthenTicated(); diff --git a/CPRNIMS.WebApps/Controllers/Inventory/MRSController.cs b/CPRNIMS.WebApps/Controllers/Inventory/MRSController.cs new file mode 100644 index 0000000..e5cc590 --- /dev/null +++ b/CPRNIMS.WebApps/Controllers/Inventory/MRSController.cs @@ -0,0 +1,12 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CPRNIMS.WebApps.Controllers.Inventory +{ + public class MRSController : Controller + { + public IActionResult Index() + { + return View(); + } + } +} diff --git a/CPRNIMS.WebApps/Controllers/Inventory/RISMgmtController.cs b/CPRNIMS.WebApps/Controllers/Inventory/RISMgmtController.cs new file mode 100644 index 0000000..25f285e --- /dev/null +++ b/CPRNIMS.WebApps/Controllers/Inventory/RISMgmtController.cs @@ -0,0 +1,101 @@ +using CPRNIMS.Domain.UIContracts.Account; +using CPRNIMS.Domain.UIContracts.Inventory; +using CPRNIMS.Infrastructure.Dto.Inventory.Request; +using CPRNIMS.Infrastructure.Helper; +using CPRNIMS.WebApps.Controllers.Base; +using Microsoft.AspNetCore.Mvc; + +namespace CPRNIMS.WebApps.Controllers.Inventory +{ + public class RISMgmtController : BaseMethod + { + private readonly IRIS _ris; + public RISMgmtController(ErrorLogHelper errorMessageService, + IWebHostEnvironment webHostEnvironment, TokenHelper tokenHelper + , IRIS ris, IAccount account) + : base(errorMessageService, webHostEnvironment, tokenHelper, account) + { + _ris = ris; + } + [HttpPost] + public async Task CreateRIS([FromBody] CreateRISRequest request,CancellationToken ct) + { + var result = await _ris.CreateRIS(request,ct); + + return Json(new { success = true, message= $"RIS {result.RISNo} created successfully.", data = result }); + } + [HttpPost] + public async Task ApproveRIS([FromBody] ApproveRISRequest request,CancellationToken ct) + { + bool isSuccess = await _ris.ApproveRIS(request, ct); + + if (!isSuccess) + return BadRequest(new { success = false, message = "RIS cancelled failed" }); + + return Ok(new + { + success = true, + message = $"RIS approved successfully." + }); + } + + [HttpPost] + public async Task CancelRIS([FromBody] CancelRISRequest request,CancellationToken ct) + { + if (string.IsNullOrWhiteSpace(request.Reason)) + return BadRequest(new + { + success = false, + message = "A reason for cancellation is required." + }); + bool isSuccess = await _ris.CancelRIS(request,ct); + + if (!isSuccess) + return BadRequest(new { success = false, message = "RIS cancelled failed" }); + + return Ok(new + { + success = true, + message = "RIS cancelled and inventory restored." + }); + } + + [HttpGet] + public async Task GetRIS( + [FromQuery] string? searchRISNo,string? searchItemName,string? searchIssuedTo,string? discipline,string? status, + int pageNumber = 1,int pageSize = 12,CancellationToken ct = default) + { + short? statusCode = status switch + { + "0" => 0, + "1" => 1, + "2" => 2, + _ => null + }; + + var result = await _ris.GetRISPaged(new RISPagedRequest + { + SearchRISNo = searchRISNo, + SearchItemName = searchItemName, + SearchIssuedTo = searchIssuedTo, + Discipline = discipline, + Status = statusCode, + PageNumber = pageNumber, + PageSize = pageSize + }, ct); + + return Json(new + { + data = result.Data, + recordsTotal = result.RecordsTotal, + departmentList = result.DepartmentList, + disciplineList = result.DisciplineList + }); + } + public async Task GetRISById(int risId, CancellationToken ct) + { + var response = await _ris.GetRISById(risId,ct); + return GetResponse(response); + } + } +} diff --git a/CPRNIMS.WebApps/ViewComponents/Inventory/InventoryTabPageViewComponent.cs b/CPRNIMS.WebApps/ViewComponents/Inventory/InventoryTabPageViewComponent.cs new file mode 100644 index 0000000..beadb64 --- /dev/null +++ b/CPRNIMS.WebApps/ViewComponents/Inventory/InventoryTabPageViewComponent.cs @@ -0,0 +1,19 @@ +using Microsoft.AspNetCore.Mvc; + +namespace CPRNIMS.WebApps.ViewComponents.Inventory +{ + public class InventoryTabPageViewComponent : ViewComponent + { + public IViewComponentResult Invoke(int InventoryTabPageId) + { + string viewName = InventoryTabPageId switch + { + 1 => "~/Views/Components/Inventory/TabPage/Inventory.cshtml", + 2 => "~/Views/Components/Inventory/TabPage/RISForApproval.cshtml", + 3 => "~/Views/Components/Inventory/TabPage/MRS.cshtml", + _ => "~/Views/Components/Inventory/TabPage/InventoryTransaction.cshtml" + }; + return View(viewName); + } + } +} diff --git a/CPRNIMS.WebApps/Views/CanvassMgmt/Suppliers.cshtml b/CPRNIMS.WebApps/Views/CanvassMgmt/Suppliers.cshtml index f057b42..e6356df 100644 --- a/CPRNIMS.WebApps/Views/CanvassMgmt/Suppliers.cshtml +++ b/CPRNIMS.WebApps/Views/CanvassMgmt/Suppliers.cshtml @@ -70,5 +70,5 @@ @await Html.PartialAsync("PagesView/Canvass/_Suppliers") @await Html.PartialAsync("PagesView/PR/_PRWOCanvass") @await Html.PartialAsync("PagesView/Canvass/_CanvassSCript") - + diff --git a/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/Inventory.cshtml b/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/Inventory.cshtml new file mode 100644 index 0000000..ff384fa --- /dev/null +++ b/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/Inventory.cshtml @@ -0,0 +1,299 @@ +
+ + + + + +
+
+ + + All Department + + +
+
+ +
+
+ All Department +
+
+
+
+ +
+ Show + + 0 results +
+
+ +@* {{-- CARD GRID --}} *@ +
+
+

Loading…

+
+
+ +@* {{-- PAGINATION --}} *@ +
+ +
+
+ + \ No newline at end of file diff --git a/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/RISForApproval.cshtml b/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/RISForApproval.cshtml new file mode 100644 index 0000000..ce1a2f0 --- /dev/null +++ b/CPRNIMS.WebApps/Views/Components/Inventory/TabPage/RISForApproval.cshtml @@ -0,0 +1,936 @@ +@* ── 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 ── *@ +
+ + + + + @* ── Discipline dropdown ── *@ +
+
+ + + All Disciplines + + +
+
+ +
+
+ All Disciplines +
+
+
+
+ + @* ── Status filter ── *@ +
+
+ + + All Status + + +
+
+ +
+
+ All Status +
+
+
+
+ +
+ Show + + 0 results +
+
+ +@* ── CARD GRID ── *@ +
+
+
+

Loading…

+
+
+ +@* ── PAGINATION ── *@ +
+ +
+
+ +@* ── APPROVE CONFIRMATION MODAL ── *@ + + +@* ── CANCEL CONFIRMATION MODAL ── *@ + + + + + diff --git a/CPRNIMS.WebApps/Views/InventoryMgmt/Inventory.cshtml b/CPRNIMS.WebApps/Views/InventoryMgmt/Inventory.cshtml index 843967a..e1b0e00 100644 --- a/CPRNIMS.WebApps/Views/InventoryMgmt/Inventory.cshtml +++ b/CPRNIMS.WebApps/Views/InventoryMgmt/Inventory.cshtml @@ -1,176 +1,114 @@ - -
-
-
-

Inventory List

-
-
-
- - -
-
- - -
-
- -
-
-
- - - - - - - - - - - - - - - - - - - - -
Txn.Id.ItemNoItemNameSpecificationCategoryNameDepartmentInOutOnHandOusts.QtyLocationTrans.DateAction
-
- - - - - - - -