Partial for custom PO

This commit is contained in:
rowell_m_soriano 2026-02-19 17:23:28 +08:00
parent 11646fec68
commit da0af6a64e
44 changed files with 1411 additions and 606 deletions

View File

@ -8,6 +8,7 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="CaptchaGen.NetCore" Version="1.1.2" /> <PackageReference Include="CaptchaGen.NetCore" Version="1.1.2" />
<PackageReference Include="Dapper" Version="2.1.66" />
<PackageReference Include="Google.Apis.Drive.v3" Version="1.67.0.3373" /> <PackageReference Include="Google.Apis.Drive.v3" Version="1.67.0.3373" />
<PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.4" /> <PackageReference Include="Microsoft.AspNet.Identity.Core" Version="2.2.4" />
<PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.2.0" /> <PackageReference Include="Microsoft.AspNetCore.SignalR.Core" Version="1.2.0" />

View File

@ -15,6 +15,8 @@ namespace CPRNIMS.Domain.Contracts.PO
public interface IPurchaseOrder public interface IPurchaseOrder
{ {
#region Get #region Get
Task<POFormData> GetPOFormDataAsync(long? poId);
Task<List<Infrastructure.Entities.PO.PO>> GetPOListByTerm(PODto itemDto);
Task<List<IncomingShipmentDto>> GetIncomingShipment(PODto itemDto); Task<List<IncomingShipmentDto>> GetIncomingShipment(PODto itemDto);
Task<List<IndexCard>> GetIndexCard(PODto poDto); Task<List<IndexCard>> GetIndexCard(PODto poDto);
Task<List<PurchaseOrder>> GetForPOApprovalByPRNo(PODto PODto); Task<List<PurchaseOrder>> GetForPOApprovalByPRNo(PODto PODto);

View File

@ -1,8 +1,6 @@
using CPRNIMS.Domain.Contracts.PO; using CPRNIMS.Domain.Contracts.PO;
using CPRNIMS.Infrastructure.Database; using CPRNIMS.Infrastructure.Database;
using CPRNIMS.Infrastructure.Dto.Items;
using CPRNIMS.Infrastructure.Dto.PO; using CPRNIMS.Infrastructure.Dto.PO;
using CPRNIMS.Infrastructure.Dto.PR;
using CPRNIMS.Infrastructure.Entities.Canvass; using CPRNIMS.Infrastructure.Entities.Canvass;
using CPRNIMS.Infrastructure.Entities.Common; using CPRNIMS.Infrastructure.Entities.Common;
using CPRNIMS.Infrastructure.Entities.LocalDb.NonInvent; using CPRNIMS.Infrastructure.Entities.LocalDb.NonInvent;
@ -10,6 +8,7 @@ using CPRNIMS.Infrastructure.Entities.PO;
using CPRNIMS.Infrastructure.Helper; using CPRNIMS.Infrastructure.Helper;
using CPRNIMS.Infrastructure.ViewModel.Common; using CPRNIMS.Infrastructure.ViewModel.Common;
using CPRNIMS.Infrastructure.ViewModel.PO; using CPRNIMS.Infrastructure.ViewModel.PO;
using Dapper;
using Microsoft.Data.SqlClient; using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using System.Data; using System.Data;
@ -30,6 +29,32 @@ namespace CPRNIMS.Domain.Services.PO
_smptHelper = smptHelper; _smptHelper = smptHelper;
} }
#region Get #region Get
public async Task<POFormData> GetPOFormDataAsync(long? poId)
{
// Reuse the connection from your existing DbContext
var conn = _dbContext.Database.GetDbConnection();
var param = new DynamicParameters();
param.Add("@POId", poId, DbType.Int64);
// Open only if not already open (EF Core may have it open already)
if (conn.State != ConnectionState.Open)
await conn.OpenAsync();
using var multi = await conn.QueryMultipleAsync(
"GetExistingPOFormData",
param,
commandType: CommandType.StoredProcedure
);
return new POFormData
{
Header = await multi.ReadFirstOrDefaultAsync<POHeader>(),
LineItems = (await multi.ReadAsync<POLineItem>()).ToList(),
Charges = (await multi.ReadAsync<POCharges>()).ToList(),
DocsRequired = (await multi.ReadAsync<DocRequired>()).ToList()
};
}
public async Task<List<Incoterm>> GetIncoterms(PODto itemDto) public async Task<List<Incoterm>> GetIncoterms(PODto itemDto)
{ {
return await _dbContext.Incoterms.ToListAsync(); return await _dbContext.Incoterms.ToListAsync();
@ -41,21 +66,13 @@ namespace CPRNIMS.Domain.Services.PO
} }
public async Task<List<Suppliers>> GetSuppliers(PODto itemDto) public async Task<List<Suppliers>> GetSuppliers(PODto itemDto)
{ {
try var allItems = await _dbContext.Suppliers
{ .FromSqlRaw($"EXEC GetSuppliers @UserId,@SupplierName",
var allItems = await _dbContext.Suppliers new SqlParameter("@UserId", itemDto.UserId),
.FromSqlRaw($"EXEC GetSuppliers @UserId,@SupplierName", new SqlParameter("@SupplierName", itemDto.SupplierName))
new SqlParameter("@UserId", itemDto.UserId), .ToListAsync();
new SqlParameter("@SupplierName", itemDto.SupplierName))
.ToListAsync();
return allItems ?? new List<Suppliers>(); return allItems ?? new List<Suppliers>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<PRWOCanvass>> GetPRWOCanvass(PODto itemDto) public async Task<List<PRWOCanvass>> GetPRWOCanvass(PODto itemDto)
{ {
@ -69,55 +86,31 @@ namespace CPRNIMS.Domain.Services.PO
} }
public async Task<List<CreatedPO>> GetCreatedPO(PODto pODto) public async Task<List<CreatedPO>> GetCreatedPO(PODto pODto)
{ {
try var createdPOs = await _dbContext.CreatedPOs
{ .FromSqlRaw($"EXEC GetCreatedPO @UserId",
var createdPOs = await _dbContext.CreatedPOs new SqlParameter("@UserId", pODto.UserId))
.FromSqlRaw($"EXEC GetCreatedPO @UserId", .ToListAsync();
new SqlParameter("@UserId", pODto.UserId))
.ToListAsync();
return createdPOs ?? new List<CreatedPO>(); return createdPOs ?? new List<CreatedPO>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<CreatedPO>> GetMyCreatedPO(PODto pODto) public async Task<List<CreatedPO>> GetMyCreatedPO(PODto pODto)
{ {
try var createdPOs = await _dbContext.CreatedPOs
{ .FromSqlRaw($"EXEC GetMyCreatedPO @UserId",
var createdPOs = await _dbContext.CreatedPOs new SqlParameter("@UserId", pODto.UserId))
.FromSqlRaw($"EXEC GetMyCreatedPO @UserId", .ToListAsync();
new SqlParameter("@UserId", pODto.UserId))
.ToListAsync();
return createdPOs ?? new List<CreatedPO>(); return createdPOs ?? new List<CreatedPO>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<ApprovedPO>> GetApprovedPO(PODto PODto) public async Task<List<ApprovedPO>> GetApprovedPO(PODto PODto)
{ {
try var allItems = await _dbContext.ApprovedPOs
{ .FromSqlRaw($"EXEC GetApprovedPO @UserId ,@IsArchived",
var allItems = await _dbContext.ApprovedPOs new SqlParameter("@UserId", PODto.UserId),
.FromSqlRaw($"EXEC GetApprovedPO @UserId ,@IsArchived", new SqlParameter("@IsArchived", PODto.IsArchived))
new SqlParameter("@UserId", PODto.UserId), .ToListAsync();
new SqlParameter("@IsArchived", PODto.IsArchived))
.ToListAsync();
return allItems ?? new List<ApprovedPO>(); return allItems ?? new List<ApprovedPO>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<ItemListForPO>> GetApprovedPOPerEmail(PODto PODto) public async Task<List<ItemListForPO>> GetApprovedPOPerEmail(PODto PODto)
{ {
@ -134,24 +127,16 @@ namespace CPRNIMS.Domain.Services.PO
} }
public async Task<List<CreatedPOPerSupId>> GetCreatedPOPerSupId(PODto pODto) public async Task<List<CreatedPOPerSupId>> GetCreatedPOPerSupId(PODto pODto)
{ {
try var allItems = await _dbContext.CreatedPOPerSupIds
{ .FromSqlRaw("EXEC GetCreatedPOPerSupId @UserId,@SupplierId,@POTypeId,@PONo,@IsManual",
var allItems = await _dbContext.CreatedPOPerSupIds new SqlParameter("@UserId", pODto.UserId),
.FromSqlRaw("EXEC GetCreatedPOPerSupId @UserId,@SupplierId,@POTypeId,@PONo,@IsManual", new SqlParameter("@SupplierId", pODto.SupplierId),
new SqlParameter("@UserId", pODto.UserId), new SqlParameter("@POTypeId", pODto.POTypeId),
new SqlParameter("@SupplierId", pODto.SupplierId), new SqlParameter("@PONo", pODto.PONo),
new SqlParameter("@POTypeId", pODto.POTypeId), new SqlParameter("@IsManual", pODto.IsManual))
new SqlParameter("@PONo", pODto.PONo), .ToListAsync();
new SqlParameter("@IsManual", pODto.IsManual))
.ToListAsync();
return allItems ?? new List<CreatedPOPerSupId>(); return allItems ?? new List<CreatedPOPerSupId>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<DocRequired>> GetDocRequired(PODto pODto) public async Task<List<DocRequired>> GetDocRequired(PODto pODto)
{ {
@ -160,103 +145,54 @@ namespace CPRNIMS.Domain.Services.PO
} }
public async Task<List<BiddingApproval>> GetForBiddingApproval(PODto PODto) public async Task<List<BiddingApproval>> GetForBiddingApproval(PODto PODto)
{ {
try var allItems = await _dbContext.BiddingApprovals
{
var allItems = await _dbContext.BiddingApprovals
.FromSqlRaw($"EXEC GetForBiddingApproval @UserId", .FromSqlRaw($"EXEC GetForBiddingApproval @UserId",
new SqlParameter("@UserId", PODto.UserId)) new SqlParameter("@UserId", PODto.UserId))
.ToListAsync(); .ToListAsync();
return allItems ?? new List<BiddingApproval>(); return allItems ?? new List<BiddingApproval>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<ForPO>> GetForPO(PODto PODto) public async Task<List<ForPO>> GetForPO(PODto PODto)
{ {
try var allItems = await _dbContext.ForPOs
{
var allItems = await _dbContext.ForPOs
.FromSqlRaw($"EXEC GetForPO @UserId", .FromSqlRaw($"EXEC GetForPO @UserId",
new SqlParameter("@UserId", PODto.UserId)) new SqlParameter("@UserId", PODto.UserId))
.ToListAsync(); .ToListAsync();
return allItems ?? new List<ForPO>(); return allItems ?? new List<ForPO>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<ForPOApproval>> GetForPOApproval(PODto PODto) public async Task<List<ForPOApproval>> GetForPOApproval(PODto PODto)
{ {
try var allItems = await _dbContext.ForPOApprovals
{
var allItems = await _dbContext.ForPOApprovals
.FromSqlRaw($"EXEC GetForPOApproval @UserId = '{PODto.UserId}'") .FromSqlRaw($"EXEC GetForPOApproval @UserId = '{PODto.UserId}'")
.ToListAsync(); .ToListAsync();
return allItems ?? new List<ForPOApproval>(); return allItems ?? new List<ForPOApproval>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<Infrastructure.Entities.PO.PurchaseOrder>> public async Task<List<Infrastructure.Entities.PO.PurchaseOrder>>
GetForPOApprovalByPRNo(PODto PODto) GetForPOApprovalByPRNo(PODto PODto)
{ {
try var allItems = await _dbContext.PurchaseOrders
{ .FromSqlRaw($"EXEC GetForPOApprovalByPRNo @UserId = '{PODto.UserId}',@PRNo = '{PODto.PRNo}'")
var allItems = await _dbContext.PurchaseOrders .ToListAsync();
.FromSqlRaw($"EXEC GetForPOApprovalByPRNo @UserId = '{PODto.UserId}',@PRNo = '{PODto.PRNo}'")
.ToListAsync();
return allItems ?? new List<Infrastructure.Entities.PO.PurchaseOrder>(); return allItems ?? new List<Infrastructure.Entities.PO.PurchaseOrder>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<ItemListForPO>> GetForPOPerSuppEmail(PODto PODto) public async Task<List<ItemListForPO>> GetForPOPerSuppEmail(PODto PODto)
{ {
try var allItems = await _dbContext.ItemListForPOs
{
var allItems = await _dbContext.ItemListForPOs
.FromSqlRaw($"EXEC GetForPOPerSuppEmail @UserId = '{PODto.UserId}',@EmailAddress = '{PODto.EmailAddress}',@POTypeId = '{PODto.POTypeId}',@PONo = '{PODto.PONo}',@IsArchived = '{PODto.IsArchived}'") .FromSqlRaw($"EXEC GetForPOPerSuppEmail @UserId = '{PODto.UserId}',@EmailAddress = '{PODto.EmailAddress}',@POTypeId = '{PODto.POTypeId}',@PONo = '{PODto.PONo}',@IsArchived = '{PODto.IsArchived}'")
.ToListAsync(); .ToListAsync();
return allItems ?? new List<ItemListForPO>(); return allItems ?? new List<ItemListForPO>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<CentralPONo>> GetLatestPO(PODto pODto) public async Task<List<CentralPONo>> GetLatestPO(PODto pODto)
{ {
try var allItems = await _dbContext.CentralPONos
{
var allItems = await _dbContext.CentralPONos
.FromSqlRaw($"EXEC GetLatestPO") .FromSqlRaw($"EXEC GetLatestPO")
.ToListAsync(); .ToListAsync();
return allItems ?? new List<CentralPONo>(); return allItems ?? new List<CentralPONo>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<SystemSettings>> GetLatestPO2(PODto pODto) public async Task<List<SystemSettings>> GetLatestPO2(PODto pODto)
{ {
@ -345,25 +281,15 @@ namespace CPRNIMS.Domain.Services.PO
} }
public async Task<List<RFQPerSupplier>> GetSupplierBidById(PODto itemDto) public async Task<List<RFQPerSupplier>> GetSupplierBidById(PODto itemDto)
{ {
try var allItems = await _dbContext.RFQPerSuppliers
{ .FromSqlRaw($"EXEC GetSupplierBidById @CanvassDetailId = '{itemDto.CanvassDetailId}'")
var allItems = await _dbContext.RFQPerSuppliers .ToListAsync();
.FromSqlRaw($"EXEC GetSupplierBidById @CanvassDetailId = '{itemDto.CanvassDetailId}'")
.ToListAsync();
return allItems ?? new List<RFQPerSupplier>(); return allItems ?? new List<RFQPerSupplier>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<RFQPerSupplier>> GetSupplierBidByItem(PODto itemDto) public async Task<List<RFQPerSupplier>> GetSupplierBidByItem(PODto itemDto)
{ {
try var allItems = await _dbContext.RFQPerSuppliers
{
var allItems = await _dbContext.RFQPerSuppliers
.FromSqlRaw($"EXEC GetSupplierBidByItem @UserId,@Status,@ItemNo,@CanvassId,@IsHistory,@PRDetailsId", .FromSqlRaw($"EXEC GetSupplierBidByItem @UserId,@Status,@ItemNo,@CanvassId,@IsHistory,@PRDetailsId",
new SqlParameter("@UserId", itemDto.UserId), new SqlParameter("@UserId", itemDto.UserId),
new SqlParameter("@Status", itemDto.Status), new SqlParameter("@Status", itemDto.Status),
@ -373,13 +299,7 @@ namespace CPRNIMS.Domain.Services.PO
new SqlParameter("@PRDetailsId", itemDto.PRDetailsId)) new SqlParameter("@PRDetailsId", itemDto.PRDetailsId))
.ToListAsync(); .ToListAsync();
return allItems ?? new List<RFQPerSupplier>(); return allItems ?? new List<RFQPerSupplier>();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<List<PRPOSummaryCount>> GetPRPOSummaryReport(PODto itemDto) public async Task<List<PRPOSummaryCount>> GetPRPOSummaryReport(PODto itemDto)
{ {
@ -420,170 +340,130 @@ namespace CPRNIMS.Domain.Services.PO
return allItems ?? new List<IncomingShipmentDto>(); return allItems ?? new List<IncomingShipmentDto>();
} }
public async Task<List<Infrastructure.Entities.PO.PO>> GetPOListByTerm(PODto itemDto)
{
return await _dbContext.POs
.Where(p => !p.IsCancel && !p.IsPOClosed &&
p.IsActive && p.PONo.StartsWith(itemDto.PONo ?? "N/A"))
.Take(50)
.AsNoTracking()
.ToListAsync();
}
#endregion #endregion
#region PostPut #region PostPut
public async Task<Infrastructure.Entities.PO.PurchaseOrder> PostApprovedPO(PODto PODto) public async Task<Infrastructure.Entities.PO.PurchaseOrder> PostApprovedPO(PODto PODto)
{ {
try await _dbContext.Database
{ .ExecuteSqlRawAsync("EXEC PostApprovedPO @UserId, @PONo",
await _dbContext.Database new SqlParameter("@PONo", PODto.PONo != null ? PODto.PONo : 0L),
.ExecuteSqlRawAsync("EXEC PostApprovedPO @UserId, @PONo", new SqlParameter("@UserId", PODto.UserId));
new SqlParameter("@PONo", PODto.PONo != null ? PODto.PONo : 0L), return new Infrastructure.Entities.PO.PurchaseOrder();
new SqlParameter("@UserId", PODto.UserId));
return new Infrastructure.Entities.PO.PurchaseOrder();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<Infrastructure.Entities.PO.PurchaseOrder> PostApprovedSuggested(PODto PODto) public async Task<Infrastructure.Entities.PO.PurchaseOrder> PostApprovedSuggested(PODto PODto)
{ {
try await _dbContext.Database
{
await _dbContext.Database
.ExecuteSqlRawAsync("EXEC PostSuggestedSupp @UserId, @CanvassDetailId, @ItemNo, @SupplierId,@CanvassId", .ExecuteSqlRawAsync("EXEC PostSuggestedSupp @UserId, @CanvassDetailId, @ItemNo, @SupplierId,@CanvassId",
new SqlParameter("@CanvassDetailId", PODto.CanvassDetailId != null ? PODto.CanvassDetailId : 0L), new SqlParameter("@CanvassDetailId", PODto.CanvassDetailId != null ? PODto.CanvassDetailId : 0L),
new SqlParameter("@UserId", PODto.UserId), new SqlParameter("@UserId", PODto.UserId),
new SqlParameter("@ItemNo", PODto.ItemNo != null ? PODto.ItemNo : 0L), new SqlParameter("@ItemNo", PODto.ItemNo != null ? PODto.ItemNo : 0L),
new SqlParameter("@SupplierId", PODto.SupplierId), new SqlParameter("@SupplierId", PODto.SupplierId),
new SqlParameter("@CanvassId", PODto.CanvassId)); new SqlParameter("@CanvassId", PODto.CanvassId));
return new Infrastructure.Entities.PO.PurchaseOrder(); return new Infrastructure.Entities.PO.PurchaseOrder();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<Suppliers> PostApprovedSupplier(PODto PODto) public async Task<Suppliers> PostApprovedSupplier(PODto PODto)
{ { await _dbContext.Database
try .ExecuteSqlRawAsync("EXEC PostApprovedSupplier @UserId, @CanvassDetailId, @ItemNo",
{
await _dbContext.Database
.ExecuteSqlRawAsync("EXEC PostApprovedSupplier @UserId, @CanvassDetailId, @ItemNo",
new SqlParameter("@CanvassDetailId", PODto.CanvassDetailId != null ? PODto.CanvassDetailId : 0L), new SqlParameter("@CanvassDetailId", PODto.CanvassDetailId != null ? PODto.CanvassDetailId : 0L),
new SqlParameter("@UserId", PODto.UserId), new SqlParameter("@UserId", PODto.UserId),
new SqlParameter("@ItemNo", PODto.ItemNo)); new SqlParameter("@ItemNo", PODto.ItemNo));
return new Suppliers(); return new Suppliers();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<Infrastructure.Entities.PO.PurchaseOrder> PostPOToSupplier(PODto PODto) public async Task<Infrastructure.Entities.PO.PurchaseOrder> PostPOToSupplier(PODto PODto)
{ {
try await _dbContext.Database
{ .ExecuteSqlRawAsync("EXEC PostPOToSupplier @UserId, @POTypeId, @EmailAddress,@PONumber",
await _dbContext.Database new SqlParameter("@POTypeId", PODto.POTypeId),
.ExecuteSqlRawAsync("EXEC PostPOToSupplier @UserId, @POTypeId, @EmailAddress,@PONumber", new SqlParameter("@UserId", PODto.UserId),
new SqlParameter("@POTypeId", PODto.POTypeId), new SqlParameter("@EmailAddress", PODto.EmailAddress),
new SqlParameter("@UserId", PODto.UserId), new SqlParameter("@PONumber", PODto.PONo));
new SqlParameter("@EmailAddress", PODto.EmailAddress), return new Infrastructure.Entities.PO.PurchaseOrder();
new SqlParameter("@PONumber", PODto.PONo));
return new Infrastructure.Entities.PO.PurchaseOrder();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<Infrastructure.Entities.PO.PurchaseOrder> PostPutPO(PODto PODto) public async Task<Infrastructure.Entities.PO.PurchaseOrder> PostPutPO(PODto PODto)
{ {
try if (PODto.UserId == "89da2977-c70f-4df9-94d4-9a610aa999ea" ||
PODto.UserId == "ac95500c-4b73-4df8-bdcb-965f9fafec30")
{ {
if (PODto.UserId == "89da2977-c70f-4df9-94d4-9a610aa999ea" || await _dbContext.Database
PODto.UserId == "ac95500c-4b73-4df8-bdcb-965f9fafec30") .ExecuteSqlRawAsync($"EXEC PostPutPO @UserId,@POTypeId,@SupplierId,@PONumber,@PORemarks,@IncoTermsId,@PODId,@ProfInvoiceNo,@ProfInvoiceDate,@PaymentTermsId,@ShippingInstructionId,@DeliverTo",
new SqlParameter("@UserId", PODto.UserId),
new SqlParameter("@POTypeId", PODto.POTypeId),
new SqlParameter("@SupplierId", PODto.SupplierId),
new SqlParameter("@PONumber", PODto.PONo),
new SqlParameter("@PORemarks", PODto.PORemarks ?? "N/A"),
new SqlParameter("@IncoTermsId", 1),
new SqlParameter("@PODId", 1),
new SqlParameter("@ProfInvoiceNo", PODto.ProfInvoiceNo ?? "N/A"),
new SqlParameter("@ProfInvoiceDate", DateTime.Now),
new SqlParameter("@PaymentTermsId", 1),
new SqlParameter("@ShippingInstructionId", 1),
new SqlParameter("@DeliverTo", PODto.DeliverTo));
}
else
{
if (!isUpdated)
{ {
await _dbContext.Database PODto.PONo = await GetLatestPOById(PODto);//Retrieve and Update SystemSettings
.ExecuteSqlRawAsync($"EXEC PostPutPO @UserId,@POTypeId,@SupplierId,@PONumber,@PORemarks,@IncoTermsId,@PODId,@ProfInvoiceNo,@ProfInvoiceDate,@PaymentTermsId,@ShippingInstructionId,@DeliverTo",
new SqlParameter("@UserId", PODto.UserId),
new SqlParameter("@POTypeId", PODto.POTypeId),
new SqlParameter("@SupplierId", PODto.SupplierId),
new SqlParameter("@PONumber", PODto.PONo),
new SqlParameter("@PORemarks", PODto.PORemarks ?? "N/A"),
new SqlParameter("@IncoTermsId", 1),
new SqlParameter("@PODId", 1),
new SqlParameter("@ProfInvoiceNo", PODto.ProfInvoiceNo ?? "N/A"),
new SqlParameter("@ProfInvoiceDate", DateTime.Now),
new SqlParameter("@PaymentTermsId", 1),
new SqlParameter("@ShippingInstructionId", 1),
new SqlParameter("@DeliverTo", PODto.DeliverTo));
} }
else
{
if (!isUpdated)
{
PODto.PONo = await GetLatestPOById(PODto);//Retrieve and Update SystemSettings
}
await _dbContext.Database await _dbContext.Database
.ExecuteSqlRawAsync($"EXEC PostPutPO @UserId,@POTypeId,@SupplierId,@PONumber,@PORemarks,@IncoTermsId,@PODId,@ProfInvoiceNo,@ProfInvoiceDate,@PaymentTermsId,@ShippingInstructionId,@DeliverTo", .ExecuteSqlRawAsync($"EXEC PostPutPO @UserId,@POTypeId,@SupplierId,@PONumber,@PORemarks,@IncoTermsId,@PODId,@ProfInvoiceNo,@ProfInvoiceDate,@PaymentTermsId,@ShippingInstructionId,@DeliverTo",
new SqlParameter("@UserId", PODto.UserId), new SqlParameter("@UserId", PODto.UserId),
new SqlParameter("@POTypeId", PODto.POTypeId), new SqlParameter("@POTypeId", PODto.POTypeId),
new SqlParameter("@SupplierId", PODto.SupplierId), new SqlParameter("@SupplierId", PODto.SupplierId),
new SqlParameter("@PONumber", formattedPONumber), new SqlParameter("@PONumber", formattedPONumber),
new SqlParameter("@PORemarks", PODto.PORemarks ?? "N/A"), new SqlParameter("@PORemarks", PODto.PORemarks ?? "N/A"),
new SqlParameter("@IncoTermsId", 1), new SqlParameter("@IncoTermsId", 1),
new SqlParameter("@PODId", 1), new SqlParameter("@PODId", 1),
new SqlParameter("@ProfInvoiceNo", PODto.ProfInvoiceNo ?? "N/A"), new SqlParameter("@ProfInvoiceNo", PODto.ProfInvoiceNo ?? "N/A"),
new SqlParameter("@ProfInvoiceDate", DateTime.Now), new SqlParameter("@ProfInvoiceDate", DateTime.Now),
new SqlParameter("@PaymentTermsId", 1), new SqlParameter("@PaymentTermsId", 1),
new SqlParameter("@ShippingInstructionId", 1), new SqlParameter("@ShippingInstructionId", 1),
new SqlParameter("@DeliverTo", PODto.DeliverTo)); new SqlParameter("@DeliverTo", PODto.DeliverTo));
}
return new Infrastructure.Entities.PO.PurchaseOrder();
}
catch (SqlException ex)
{
ex.ToString();
throw;
} }
return new Infrastructure.Entities.PO.PurchaseOrder();
} }
private void PutLocalCentralPo(PODto PODto) private void PutLocalCentralPo(PODto PODto)
{ {
try string columnName;
string updatedPONo = "";
// Determine the column to update based on POTypeId
switch (PODto.POTypeId)
{ {
string columnName; case 1: // SI
string updatedPONo = ""; // Remove the first two characters from PONo
// Determine the column to update based on POTypeId updatedPONo = PODto.PONo;
switch (PODto.POTypeId) columnName = "PONoVatInc";
{ break;
case 1: // SI case 2: // DR
// Remove the first two characters from PONo updatedPONo = PODto.PONo;
updatedPONo = PODto.PONo; columnName = "PONoVatEx";
columnName = "PONoVatInc"; break;
break; case 3: // IMPORT
case 2: // DR updatedPONo = PODto.PONo;
updatedPONo = PODto.PONo; columnName = "IPONoVatInc";
columnName = "PONoVatEx"; break;
break; default:
case 3: // IMPORT throw new ArgumentException("Invalid POTypeId.");
updatedPONo = PODto.PONo; }
columnName = "IPONoVatInc";
break;
default:
throw new ArgumentException("Invalid POTypeId.");
}
// Build the SQL query // Build the SQL query
string query = $@" string query = $@"
UPDATE [dbo].[SystemSettings] UPDATE [dbo].[SystemSettings]
SET {columnName} = @UpdatedPONo SET {columnName} = @UpdatedPONo
WHERE {columnName} IS NOT NULL"; WHERE {columnName} IS NOT NULL";
// Execute the raw SQL query // Execute the raw SQL query
_dbLocalContext.Database.ExecuteSqlRaw(query, new SqlParameter("@UpdatedPONo", updatedPONo)); _dbLocalContext.Database.ExecuteSqlRaw(query, new SqlParameter("@UpdatedPONo", updatedPONo));
}
catch (Exception ex)
{
ex.ToString();
throw;
}
} }
public async Task<CustomPO> PostPutCustomPO(PODto pODto) public async Task<CustomPO> PostPutCustomPO(PODto pODto)
{ {
@ -693,107 +573,68 @@ namespace CPRNIMS.Domain.Services.PO
} }
public async Task<DocRequired> PostSuppDocRequirements(PODto poDto) public async Task<DocRequired> PostSuppDocRequirements(PODto poDto)
{ {
try await _dbContext.Database
{ .ExecuteSqlRawAsync("EXEC PostSuppDocRequirements @UserId,@DocRequirementId,@PONumber",
await _dbContext.Database new SqlParameter("@DocRequirementId", poDto.DocRequirementId),
.ExecuteSqlRawAsync("EXEC PostSuppDocRequirements @UserId,@DocRequirementId,@PONumber", new SqlParameter("@UserId", poDto.UserId),
new SqlParameter("@DocRequirementId", poDto.DocRequirementId), new SqlParameter("@PONumber", formattedPONumber));
new SqlParameter("@UserId", poDto.UserId), return new DocRequired();
new SqlParameter("@PONumber", formattedPONumber));
return new DocRequired();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<OtherCharges> PostSuppCharges(PODto poDto) public async Task<OtherCharges> PostSuppCharges(PODto poDto)
{ {
try await _dbContext.Database
{
await _dbContext.Database
.ExecuteSqlRawAsync("EXEC PostSuppCharges @UserId,@PONo,@OtherChargesId,@POTypeId,@Amount", .ExecuteSqlRawAsync("EXEC PostSuppCharges @UserId,@PONo,@OtherChargesId,@POTypeId,@Amount",
new SqlParameter("@UserId", poDto.UserId), new SqlParameter("@UserId", poDto.UserId),
new SqlParameter("@PONo", formattedPONumber), new SqlParameter("@PONo", formattedPONumber),
new SqlParameter("@OtherChargesId", poDto.OtherChargesId), new SqlParameter("@OtherChargesId", poDto.OtherChargesId),
new SqlParameter("@POTypeId", poDto.POTypeId), new SqlParameter("@POTypeId", poDto.POTypeId),
new SqlParameter("@Amount", poDto.Amount)); new SqlParameter("@Amount", poDto.Amount));
return new OtherCharges(); return new OtherCharges();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<Infrastructure.Entities.PO.PurchaseOrder> PutPRItemDetails(PODto pODto) public async Task<Infrastructure.Entities.PO.PurchaseOrder> PutPRItemDetails(PODto pODto)
{ {
try await _dbContext.Database
{ .ExecuteSqlRawAsync($"EXEC PutPRItemDetails @UserId,@ItemName,@Specification,@Qty,@UOMId,@PRDetailsId",
await _dbContext.Database new SqlParameter("@UserId", pODto.UserId),
.ExecuteSqlRawAsync($"EXEC PutPRItemDetails @UserId,@ItemName,@Specification,@Qty,@UOMId,@PRDetailsId", new SqlParameter("@ItemName", pODto.ItemName),
new SqlParameter("@UserId", pODto.UserId), new SqlParameter("@Specification", pODto.Specification),
new SqlParameter("@ItemName", pODto.ItemName), new SqlParameter("@Qty", pODto.Qty),
new SqlParameter("@Specification", pODto.Specification), new SqlParameter("@UOMId", pODto.UOMId),
new SqlParameter("@Qty", pODto.Qty), new SqlParameter("@PRDetailsId", pODto.PRDetailsId));
new SqlParameter("@UOMId", pODto.UOMId), return new Infrastructure.Entities.PO.PurchaseOrder();
new SqlParameter("@PRDetailsId", pODto.PRDetailsId));
return new Infrastructure.Entities.PO.PurchaseOrder();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<Infrastructure.Entities.PO.PurchaseOrder> PutPOItemDetail(PODto pODto) public async Task<Infrastructure.Entities.PO.PurchaseOrder> PutPOItemDetail(PODto pODto)
{ {
try await _dbContext.Database
{ .ExecuteSqlRawAsync($"EXEC PutPOItemDetail @UserId,@UOMId,@Qty,@PRDetailsId,@Remarks,@ItemDescription,@Specification,@PONo,@UnitPrice,@PaymentTermsId,@PODId",
await _dbContext.Database new SqlParameter("@UserId", pODto.UserId),
.ExecuteSqlRawAsync($"EXEC PutPOItemDetail @UserId,@UOMId,@Qty,@PRDetailsId,@Remarks,@ItemDescription,@Specification,@PONo,@UnitPrice,@PaymentTermsId,@PODId", new SqlParameter("@UOMId", pODto.UOMId),
new SqlParameter("@UserId", pODto.UserId), new SqlParameter("@Qty", pODto.Qty),
new SqlParameter("@UOMId", pODto.UOMId), new SqlParameter("@PRDetailsId", pODto.PRDetailsId),
new SqlParameter("@Qty", pODto.Qty), new SqlParameter("@Remarks", pODto.PORemarks),
new SqlParameter("@PRDetailsId", pODto.PRDetailsId), new SqlParameter("@ItemDescription", pODto.ItemDescription),
new SqlParameter("@Remarks", pODto.PORemarks), new SqlParameter("@Specification", pODto.Specification),
new SqlParameter("@ItemDescription", pODto.ItemDescription), new SqlParameter("@PONo", pODto.PONo),
new SqlParameter("@Specification", pODto.Specification), new SqlParameter("@UnitPrice", pODto.UnitPrice),
new SqlParameter("@PONo", pODto.PONo), new SqlParameter("@PaymentTermsId", pODto.PaymentTermsId),
new SqlParameter("@UnitPrice", pODto.UnitPrice), new SqlParameter("@PODId", pODto.PODId));
new SqlParameter("@PaymentTermsId", pODto.PaymentTermsId), return new Infrastructure.Entities.PO.PurchaseOrder();
new SqlParameter("@PODId", pODto.PODId));
return new Infrastructure.Entities.PO.PurchaseOrder();
}
catch (SqlException ex)
{
ex.ToString();
throw;
}
} }
public async Task<Infrastructure.Entities.PO.PurchaseOrder> PutMyPONo(PODto pODto) public async Task<Infrastructure.Entities.PO.PurchaseOrder> PutMyPONo(PODto pODto)
{ {
try string oldPONo = pODto.PONo;
if (!isUpdated)
{ {
string oldPONo = pODto.PONo; await GetLatestPOById(pODto);
if (!isUpdated) }
{
await GetLatestPOById(pODto);
}
await _dbContext.Database await _dbContext.Database
.ExecuteSqlRawAsync($"EXEC PutMyPONo @UserId,@OldPONo,@NewPONo,@PORemarks", .ExecuteSqlRawAsync($"EXEC PutMyPONo @UserId,@OldPONo,@NewPONo,@PORemarks",
new SqlParameter("@UserId", pODto.UserId), new SqlParameter("@UserId", pODto.UserId),
new SqlParameter("@OldPONo", oldPONo), new SqlParameter("@OldPONo", oldPONo),
new SqlParameter("@NewPONo", formattedPONumber), new SqlParameter("@NewPONo", formattedPONumber),
new SqlParameter("@PORemarks", pODto.PORemarks)); new SqlParameter("@PORemarks", pODto.PORemarks));
return new Infrastructure.Entities.PO.PurchaseOrder(); return new Infrastructure.Entities.PO.PurchaseOrder();
}
catch (SqlException)
{
throw;
}
} }
public async Task<List<POItemDetail>> GetPOItemDetail(PODto pODto) public async Task<List<POItemDetail>> GetPOItemDetail(PODto pODto)
{ {
@ -909,103 +750,71 @@ namespace CPRNIMS.Domain.Services.PO
} }
public async Task<bool> DeleteIncShip(PODto poDto) public async Task<bool> DeleteIncShip(PODto poDto)
{ {
try var inc = await _dbContext.IncomingShipments
{ .FirstOrDefaultAsync(i => i.POId == poDto.POId);
var inc = await _dbContext.IncomingShipments
.FirstOrDefaultAsync(i => i.POId == poDto.POId);
if (inc != null) if (inc != null)
{
inc.IsActive = false;
_dbContext.SaveChanges();
}
return true;
}
catch (Exception ex)
{ {
return false; inc.IsActive = false;
_dbContext.SaveChanges();
} }
return true;
} }
public string EMailTemplate(string relativePath, string emailTemplate) public string EMailTemplate(string relativePath, string emailTemplate)
{ {
try string basePath = AppContext.BaseDirectory;
{ string templateFolderPath = Path.Combine(basePath, relativePath);
string basePath = AppContext.BaseDirectory; string templateFilePath = Path.Combine(templateFolderPath, emailTemplate);
string templateFolderPath = Path.Combine(basePath, relativePath);
string templateFilePath = Path.Combine(templateFolderPath, emailTemplate);
if (System.IO.File.Exists(templateFilePath)) if (System.IO.File.Exists(templateFilePath))
{
return System.IO.File.ReadAllText(templateFilePath);
}
else
{
Console.WriteLine($"File not found: {templateFilePath}");
return "Template file not found";
}
}
catch (Exception ex)
{ {
var errorMessage = ex.ToString(); return System.IO.File.ReadAllText(templateFilePath);
throw new Exception($"Error loading email template: {errorMessage}", ex); }
else
{
Console.WriteLine($"File not found: {templateFilePath}");
return "Template file not found";
} }
} }
public async Task PostIncShipFollowUp(PODto itemDto, List<IncomingShipmentDto> shipFollowUp) public async Task PostIncShipFollowUp(PODto itemDto, List<IncomingShipmentDto> shipFollowUp)
{ {
try var baseTemplate = EMailTemplate("Content\\SMTPEmailContent", "IncShipFollowUp.cshtml");
{
var baseTemplate = EMailTemplate("Content\\SMTPEmailContent", "IncShipFollowUp.cshtml");
// Use the passed data instead of re-querying // Use the passed data instead of re-querying
foreach (var incShip in shipFollowUp) foreach (var incShip in shipFollowUp)
{
var message = new StringBuilder(baseTemplate);
message.Replace("@ViewBag.PONo", Convert.ToString(incShip.PONo));
message.Replace("@ViewBag.ProfInvoiceNo", Convert.ToString(incShip.ProfInvoiceNo));
message.Replace("@ViewBag.DeliveryDate", Convert.ToString(incShip.DeliveryDate));
message.Replace("@ViewBag.Supplier", Convert.ToString(incShip.SupplierName));
message.Replace("@ViewBag.Signature", Convert.ToString(incShip.Signature));
var messageDetails = new EmailMessageDetailsVM
{ {
var message = new StringBuilder(baseTemplate); Recipient = incShip.EmailAddress,
message.Replace("@ViewBag.PONo", Convert.ToString(incShip.PONo)); Message = message.ToString(),
message.Replace("@ViewBag.ProfInvoiceNo", Convert.ToString(incShip.ProfInvoiceNo)); Subject = incShip.Subject,
message.Replace("@ViewBag.DeliveryDate", Convert.ToString(incShip.DeliveryDate)); CC = incShip.CC,
message.Replace("@ViewBag.Supplier", Convert.ToString(incShip.SupplierName)); IsSuccess = false,
message.Replace("@ViewBag.Signature", Convert.ToString(incShip.Signature)); SenderEmail = incShip.UserName,
DisplayName = "llipurchasing.com",
NewPassword = incShip.Password,
OutGoingPort = 587,
Server = incShip.Server,
UserName = incShip.UserName
};
var messageDetails = new EmailMessageDetailsVM await _smptHelper.SendEmailAsync(messageDetails);
{
Recipient = incShip.EmailAddress,
Message = message.ToString(),
Subject = incShip.Subject,
CC = incShip.CC,
IsSuccess = false,
SenderEmail = incShip.UserName,
DisplayName = "llipurchasing.com",
NewPassword = incShip.Password,
OutGoingPort = 587,
Server = incShip.Server,
UserName = incShip.UserName
};
await _smptHelper.SendEmailAsync(messageDetails);
}
}
catch (Exception ex)
{
var errorMessage = ex.InnerException?.ToString() ?? ex.Message.ToString();
// Log the error properly
throw;
} }
} }
public async Task<bool> PostIncShipFollowUp(PODto itemDto) public async Task<bool> PostIncShipFollowUp(PODto itemDto)
{ {
try var shipFollowUp = await GetIncomingShipment(itemDto);
{ await PostIncShipFollowUp(itemDto, shipFollowUp);
var shipFollowUp = await GetIncomingShipment(itemDto); return true;
await PostIncShipFollowUp(itemDto, shipFollowUp);
return true;
}
catch (Exception ex)
{
ex.ToString();
return false;
}
} }
#endregion #endregion
} }
} }

View File

@ -0,0 +1,14 @@
using CPRNIMS.Infrastructure.Entities.PO;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CPRNIMS.Domain.UIContracts.PO
{
public interface ICustomPOService
{
Task<POFormData> GetPOFormDataAsync(long? poId = null);
}
}

View File

@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace CPRNIMS.Domain.UIContracts.PO namespace CPRNIMS.Domain.UIContracts.PO
{ {
public interface IPurchaseOrder public interface IPurchaseOrder
{ {
#region Get #region Get
Task<List<POVM>> GetSupplierBidById(User user, POVM viewModel); Task<List<POVM>> GetSupplierBidById(User user, POVM viewModel);
@ -40,6 +40,7 @@ namespace CPRNIMS.Domain.UIContracts.PO
Task<List<POVM>?> GetIndexCard(User user, POVM viewModel); Task<List<POVM>?> GetIndexCard(User user, POVM viewModel);
Task<List<POVM>?> GetPortOfDischarge(User user, POVM viewModels); Task<List<POVM>?> GetPortOfDischarge(User user, POVM viewModels);
Task<List<POVM>?> GetIncomingShipment(User user, POVM viewModels); Task<List<POVM>?> GetIncomingShipment(User user, POVM viewModels);
Task<List<POVM>?> GetPOListByTerm(User user, POVM viewModels);
#endregion #endregion
#region Post Put #region Post Put
Task<POVM> PostApprovedSupplier(User user, POVM viewModel); Task<POVM> PostApprovedSupplier(User user, POVM viewModel);

View File

@ -0,0 +1,76 @@
using CPRNIMS.Domain.UIContracts.PO;
using CPRNIMS.Infrastructure.Entities.PO;
using CPRNIMS.Infrastructure.Helper;
using Google.Apis.Services;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http.Headers;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace CPRNIMS.Domain.UIServices.PO
{
public class CustomPOService : ICustomPOService
{
private readonly IHttpClientFactory _httpClientFactory;
private readonly TokenHelper _tokenHelper;
private readonly IConfiguration _configuration;
private readonly ILogger<CustomPOService> _logger;
public CustomPOService(
IHttpClientFactory httpClientFactory,
TokenHelper tokenHelper,
IConfiguration configuration,
ILogger<CustomPOService> logger)
{
_httpClientFactory = httpClientFactory;
_tokenHelper = tokenHelper;
_configuration = configuration;
_logger = logger;
}
public async Task<POFormData> GetPOFormDataAsync(long? poId = null)
{
try
{
var token = await _tokenHelper.GetValidTokenAsync();
if (string.IsNullOrEmpty(token))
throw new UnauthorizedAccessException("No valid token available.");
var httpClient = _httpClientFactory.CreateClient("AuthApi");
httpClient.DefaultRequestHeaders.Authorization =
new AuthenticationHeaderValue("Bearer", token);
var url = _configuration["LLI:NonInvent:POMgmt:GetPOFormData"];
if (poId.HasValue)
url += $"?poId={poId}";
var response = await httpClient.GetAsync(url);
if (!response.IsSuccessStatusCode)
{
_logger.LogError("GetPOFormData failed: {StatusCode}", response.StatusCode);
return new POFormData(); // return empty rather than throw
}
var json = await response.Content.ReadAsStringAsync();
var result = JsonSerializer.Deserialize<POFormData>(json, new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
});
return result ?? new POFormData();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error in GetPOFormDataAsync");
return new POFormData();
}
}
}
}

View File

@ -126,6 +126,12 @@ namespace CPRNIMS.Domain.UIServices.PO
#endregion #endregion
#region Get #region Get
public async Task<List<POVM>?> GetPOListByTerm(User user, POVM viewModel)
{
return await SendGetApiRequest(user, viewModel,
_configuration["LLI:NonInvent:POMgmt:GetPOListByTerm"]);
}
public async Task<List<POVM>?> GetIncomingShipment(User user, POVM viewModel) public async Task<List<POVM>?> GetIncomingShipment(User user, POVM viewModel)
{ {
return await SendGetApiRequest(user, viewModel, return await SendGetApiRequest(user, viewModel,

View File

@ -13,12 +13,15 @@ namespace CPRNIMS.Infrastructure.Entities.PO
{ {
[Key] [Key]
public long POId { get; set; } public long POId { get; set; }
public long PONo { get; set; } public string PONo { get; set; }
public bool Submit { get; set; }
public bool IsActive { get; set; } public bool IsActive { get; set; }
public bool IsPOClosed { get; set; } public bool IsPOClosed { get; set; }
public bool IsCancel { get; set; }
public string? UserId { get; set; } public string? UserId { get; set; }
public DateTime CreatedDate { get; set; } public byte Status { get; set; }
public DateTime UpdatedDate { get; set; } public byte PaymentTermsId { get; set; }
public byte PODId { get; set; }
public byte POTypeId { get; set; }
public DateTime? UpdatedDate { get; set; }
} }
} }

View File

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CPRNIMS.Infrastructure.Entities.PO
{
public class POCharges
{
[Key]
public int OtherChargesId { get; set; }
public string? OtherChargesName { get; set; }
public decimal Amount { get; set; }
}
}

View File

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CPRNIMS.Infrastructure.Entities.PO
{
public class POFormData
{
public POHeader? Header { get; set; }
public List<POLineItem>? LineItems { get; set; }
public List<POCharges>? Charges { get; set; }
public List<DocRequired>? DocsRequired { get; set; }
}
}

View File

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CPRNIMS.Infrastructure.Entities.PO
{
public class POHeader
{
[Key]
public long POId { get; set; }
public string? PONo { get; set; }
public int SupplierId { get; set; }
public string? SupplierName { get; set; }
public DateTime DeliveryDate { get; set; }
public DateTime? ProfInvoiceDate { get; set; }
public string? ProfInvoiceNo { get; set; }
public string? CurrencyName { get; set; }
public string? PaymentTerms { get; set; }
public string? Remarks { get; set; }
public decimal Discount { get; set; }
public decimal GrossAmountUSD { get; set; }
public decimal FinalAmountUSD { get; set; }
public decimal GrossAmountPHP { get; set; }
public decimal FinalAmountPHP { get; set; }
public string? POTypeName { get; set; }
public string? UserId { get; set; }
public byte Status { get; set; }
public byte PaymentTermsId { get; set; }
public byte PODId { get; set; }
public byte POTypeId { get; set; }
public byte IncoTermsId { get; set; }
}
}

View File

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CPRNIMS.Infrastructure.Entities.PO
{
public class POLineItem
{
[Key]
public long PODetailId { get; set; }
public long PRNo { get; set; }
public decimal Qty { get; set; }
public decimal UnitPrice { get; set; }
public decimal TotalAmount { get; set; }
public string? UOMName { get; set; }
public long ItemNo { get; set; }
public string? ItemName { get; set; }
public string? Specification { get; set; }
}
}

View File

@ -256,7 +256,6 @@ namespace CPRNIMS.Infrastructure.Helper
return ExtractClaimsFromToken(tokenClaim.Value); return ExtractClaimsFromToken(tokenClaim.Value);
} }
// Rest of your existing methods...
public HttpClient CreateHttpClientWithDefaultHeaders(string token) public HttpClient CreateHttpClientWithDefaultHeaders(string token)
{ {
string BaseUrl = _configuration["CommonEndpoints:ApiDefaultHeaders:BaseUrl"]; string BaseUrl = _configuration["CommonEndpoints:ApiDefaultHeaders:BaseUrl"];
@ -281,24 +280,6 @@ namespace CPRNIMS.Infrastructure.Helper
return httpClient; return httpClient;
} }
public Dictionary<string, string> DefaultHeaders
{
get
{
var headersSection = _configuration.GetSection(
"CommonEndpoints:ApiDefaultHeaders");
var headers = new Dictionary<string, string>();
foreach (var childSection in headersSection.GetChildren())
{
headers[childSection.Key] = childSection.Value;
}
return headers;
}
}
public Dictionary<string, string> CustomHeaders public Dictionary<string, string> CustomHeaders
{ {
get get

View File

@ -147,7 +147,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="Helper\" />
<Folder Include="wwwroot\Content\Uploads\PRAttachment\" /> <Folder Include="wwwroot\Content\Uploads\PRAttachment\" />
</ItemGroup> </ItemGroup>

View File

@ -9,6 +9,7 @@ using CPRNIMS.Infrastructure.Helper;
using CPRNIMS.Infrastructure.Entities.Common; using CPRNIMS.Infrastructure.Entities.Common;
using CPRNIMS.Infrastructure.ViewModel.Common; using CPRNIMS.Infrastructure.ViewModel.Common;
using CPRNIMS.Infrastructure.Dto.Account; using CPRNIMS.Infrastructure.Dto.Account;
using System.Threading.Tasks;
namespace CPRNIMS.WebApi.Controllers.Account namespace CPRNIMS.WebApi.Controllers.Account
{ {
@ -36,7 +37,6 @@ namespace CPRNIMS.WebApi.Controllers.Account
_userManager = userManager; _userManager = userManager;
_signInManager = signInManager; _signInManager = signInManager;
} }
[AllowAnonymous] [AllowAnonymous]
[HttpPost("Login")] [HttpPost("Login")]
public async Task<IActionResult> Login([FromBody] LoginRequest model, public async Task<IActionResult> Login([FromBody] LoginRequest model,

View File

@ -279,6 +279,20 @@ namespace CPRNIMS.WebApi.Controllers.PO
} }
#endregion #endregion
#region Get #region Get
[HttpGet("GetPOFormData")]
public async Task<IActionResult> GetPOFormData(int? poId = null)
{
var data = await _purchaseOrder.GetPOFormDataAsync(poId);
return Ok(data);
}
[HttpPost("GetPOListByTerm")]
public async Task<IActionResult> GetPOListByTerm(PODto itemDto)
{
return await ExecuteWithErrorHandling(
() => _purchaseOrder.GetPOListByTerm(itemDto),
nameof(GetPOListByTerm), false
);
}
[HttpPost("GetIncomingShipment")] [HttpPost("GetIncomingShipment")]
public async Task<IActionResult> GetIncomingShipment(PODto itemDto) public async Task<IActionResult> GetIncomingShipment(PODto itemDto)
{ {

View File

@ -81,7 +81,8 @@ namespace CPRNIMS.WebApps.Common
builder.Services.AddTransient<IReceiving, Receiving>(); builder.Services.AddTransient<IReceiving, Receiving>();
builder.Services.AddTransient<ISMTP, SMTP>(); builder.Services.AddTransient<ISMTP, SMTP>();
builder.Services.AddTransient<IInventory, Inventory>(); builder.Services.AddTransient<IInventory, Inventory>();
builder.Services.AddTransient<IPurchaseOrder, PurchaseOrder>(); builder.Services.AddTransient<IPurchaseOrder, PurchaseOrder>();
builder.Services.AddTransient<ICustomPOService, CustomPOService>();
builder.Services.AddTransient<Domain.UIContracts.Attachment.IAttachment, Domain.UIServices.Attachment.Attachment>(); builder.Services.AddTransient<Domain.UIContracts.Attachment.IAttachment, Domain.UIServices.Attachment.Attachment>();
builder.Services.AddTransient<IAccount, Account>(); builder.Services.AddTransient<IAccount, Account>();
builder.Services.AddTransient<ICaptchaService, CaptchaService>(); builder.Services.AddTransient<ICaptchaService, CaptchaService>();

View File

@ -1,6 +1,5 @@
using CPRNIMS.Domain.UIContracts.Account; using CPRNIMS.Domain.UIContracts.Account;
using CPRNIMS.Domain.UIContracts.PO; using CPRNIMS.Domain.UIContracts.PO;
using CPRNIMS.Infrastructure.Entities.PO;
using CPRNIMS.Infrastructure.Helper; using CPRNIMS.Infrastructure.Helper;
using CPRNIMS.Infrastructure.ViewModel.PO; using CPRNIMS.Infrastructure.ViewModel.PO;
using CPRNIMS.WebApps.Controllers.Base; using CPRNIMS.WebApps.Controllers.Base;
@ -15,12 +14,14 @@ namespace CPRNIMS.WebApps.Controllers.PO
POVM postPutItem; POVM postPutItem;
private readonly IPurchaseOrder _purchaseOrder; private readonly IPurchaseOrder _purchaseOrder;
private readonly ICustomPOService _customPOService;
public POMgmtController( public POMgmtController(
ErrorLogHelper errorMessageService, IWebHostEnvironment webHostEnvironment ErrorLogHelper errorMessageService, IWebHostEnvironment webHostEnvironment
, IPurchaseOrder purchaseOrder, TokenHelper tokenHelper,IAccount account , IPurchaseOrder purchaseOrder, TokenHelper tokenHelper,IAccount account, ICustomPOService customPOService
) : base(errorMessageService, webHostEnvironment, tokenHelper, account) ) : base(errorMessageService, webHostEnvironment, tokenHelper, account)
{ {
_purchaseOrder = purchaseOrder; _purchaseOrder = purchaseOrder;
_customPOService = customPOService;
} }
#endregion #endregion
#region POST PUT #region POST PUT
@ -207,7 +208,7 @@ namespace CPRNIMS.WebApps.Controllers.PO
return Json(new { success = false, Response = postPutItem.Message }); return Json(new { success = false, Response = postPutItem.Message });
} }
#endregion #endregion
#region Get #region Mapper
private POList MapToPONoList(IEnumerable<POList> poList) private POList MapToPONoList(IEnumerable<POList> poList)
{ {
if (poList == null || !poList.Any()) if (poList == null || !poList.Any())
@ -267,6 +268,15 @@ namespace CPRNIMS.WebApps.Controllers.PO
Specification = itemList.SelectMany(ic => ic.Specification).ToList() Specification = itemList.SelectMany(ic => ic.Specification).ToList()
}; };
} }
#endregion
#region Get
[HttpGet]
public async Task<IActionResult> GetPOFormData(long? poId = null)
{
var data = await _customPOService.GetPOFormDataAsync(poId);
return Ok(data);
}
public async Task<IActionResult> GetIncomingShipment(POVM viewModels) public async Task<IActionResult> GetIncomingShipment(POVM viewModels)
{ {
response = await _purchaseOrder.GetIncomingShipment(GetUser(), viewModels); response = await _purchaseOrder.GetIncomingShipment(GetUser(), viewModels);
@ -304,7 +314,7 @@ namespace CPRNIMS.WebApps.Controllers.PO
var viewModels = new POVM(); var viewModels = new POVM();
response = await _purchaseOrder.GetForPO(GetUser(), viewModels); response = await _purchaseOrder.GetForPO(GetUser(), viewModels);
return GetResponse(response); return GetResponse(response);
} }
public async Task<IActionResult> GetForPOPerSuppEmail(POVM viewModels) public async Task<IActionResult> GetForPOPerSuppEmail(POVM viewModels)
{ {
response = await _purchaseOrder.GetForPOPerSuppEmail(GetUser(), viewModels); response = await _purchaseOrder.GetForPOPerSuppEmail(GetUser(), viewModels);
@ -352,6 +362,24 @@ namespace CPRNIMS.WebApps.Controllers.PO
return Json(new { success = true, data = formattedData }); return Json(new { success = true, data = formattedData });
} }
public async Task<IActionResult> GetPOListByTerm(string query)
{
var viewModels = new POVM();
viewModels.PONo = query;
response = await _purchaseOrder.GetPOListByTerm(GetUser(), viewModels);
if (response == null)
{
response = new List<POVM>();
}
var formattedData = response.Select(item => new
{
label = item.PONo,
value = item.POId,
value2 = item.POTypeId
});
return Json(new { success = true, data = formattedData });
}
public async Task<IActionResult> GetPaymentTerms(string query) public async Task<IActionResult> GetPaymentTerms(string query)
{ {
var viewModels = new POVM(); var viewModels = new POVM();

View File

@ -12,7 +12,8 @@ namespace CPRNIMS.WebApps.ViewComponents.POMgmt
{ {
1 => "~/Views/Components/POMgmt/CustomPO/SIElem.cshtml", 1 => "~/Views/Components/POMgmt/CustomPO/SIElem.cshtml",
2 => "~/Views/Components/POMgmt/CustomPO/DRElem.cshtml", 2 => "~/Views/Components/POMgmt/CustomPO/DRElem.cshtml",
_ => "~/Views/Components/POMgmt/CustomPO/ImportElem.cshtml" 3 => "~/Views/Components/POMgmt/CustomPO/ImportElem.cshtml",
_ => "~/Views/Components/POMgmt/CustomPO/PODetailModification.cshtml"
}; };
return View(viewName); return View(viewName);

View File

@ -216,5 +216,3 @@
@await Html.PartialAsync("PagesView/PO/_DocRequired") @await Html.PartialAsync("PagesView/PO/_DocRequired")
<input hidden id="dr-ImportPoNo" /> <input hidden id="dr-ImportPoNo" />
<input hidden id="si-ImportPoNo" /> <input hidden id="si-ImportPoNo" />

View File

@ -0,0 +1,28 @@
<div class="container mt-4 mb-4">
<!-- WARNING BANNER -->
<div class="alert alert-danger shadow-sm border-3 border-danger">
<div class="d-flex align-items-center">
<div class="me-3 fs-1">
</div>
<div>
<h4 class="mb-1 fw-bold text-danger">
You Are Modifying an Existing Purchase Order
</h4>
<p class="mb-0">
Any changes made here will directly affect supplier commitments, and financial reports.
Please review all details carefully before saving.
</p>
</div>
</div>
</div>
<!-- SECONDARY NOTICE -->
<div class="alert alert-warning shadow-sm">
<strong>Important:</strong>
Ensure that all quantities, prices, delivery dates, and supplier details are accurate.
Any incorrect modifications may result in discrepancies and processing issues.
</div>
</div>

View File

@ -24,6 +24,7 @@
UserRights = document.getElementById("roleRights").value; UserRights = document.getElementById("roleRights").value;
const reportTitle = `All Purchase Request - as of ${getFormattedDateTime()}`;
prTable = $('#PRTable').DataTable({ prTable = $('#PRTable').DataTable({
ajax: { ajax: {
url: '/PRMgmt/GetAllPR', url: '/PRMgmt/GetAllPR',
@ -42,7 +43,59 @@
} }
} }
}, },
initComplete: initCompleteCallback, dom: 'lBfrtip',
buttons: [
{
extend: 'csv',
title: reportTitle
},
{
extend: 'excel',
title: reportTitle
},
{
extend: 'pdf',
title: reportTitle
}
],
initComplete: function () {
initializeColumnSearch({
tableId: '#PRTable',
dataTable: prTable,
searchableColumns: [
{
columnIndex: 0,
columnName: 'PR No',
placeholder: 'Enter PR Number...',
searchType: 'text',
searchMode: 'exact',
width: '150px'
},
{
columnIndex: 2,
columnName: 'Item Name',
placeholder: 'Enter Item Name...',
searchType: 'text',
searchMode: 'contains',
width: '200px'
},
{
columnIndex: 6,
columnName: 'Department',
placeholder: 'Select Department...',
searchType: 'select',
searchMode: 'exact',
width: '150px'
}
]
});
const uniqueSearchClass = 'column-search-input-PRTable';
populateSelectOptions(prTable, 6, '.' + uniqueSearchClass + '[data-column="6"]');
restoreSearchFromURL(uniqueSearchClass, '#PRTable');
},
columns: colOnPRTable, columns: colOnPRTable,
order: [[3, 'asc']], order: [[3, 'asc']],
rowCallback: rowStatusColorCallback, rowCallback: rowStatusColorCallback,

View File

@ -24,8 +24,8 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// Initialize DataTable for Approved PR
const reportTitle = `Approved Purchase Request (No PO) - as of ${getFormattedDateTime()}`;
var approvedPRTable = $('#ApprovedPRTable').DataTable({ var approvedPRTable = $('#ApprovedPRTable').DataTable({
ajax: { ajax: {
url: '/PRMgmt/GetApprovedPR', url: '/PRMgmt/GetApprovedPR',
@ -44,11 +44,26 @@
} }
} }
}, },
dom: 'lBfrtip',
buttons: [
{
extend: 'csv',
title: reportTitle
},
{
extend: 'excel',
title: reportTitle
},
{
extend: 'pdf',
title: reportTitle
}
],
initComplete: function () { initComplete: function () {
initializeColumnSearch({ initializeColumnSearch({
tableId: '#ApprovedPRTable', tableId: '#ApprovedPRTable',
dataTable: approvedPRTable, dataTable: approvedPRTable,
searchableColumns: [ searchableColumns: [
{ {
columnIndex: 0, columnIndex: 0,
columnName: 'Status', columnName: 'Status',
@ -92,12 +107,12 @@
] ]
}); });
const uniqueSearchClass = 'column-search-input-ApprovedPRTable'; const uniqueSearchClass = 'column-search-input-ApprovedPRTable';
populateSelectOptions(approvedPRTable, 0, '.' + uniqueSearchClass + '[data-column="0"]'); populateSelectOptions(approvedPRTable, 0, '.' + uniqueSearchClass + '[data-column="0"]');
populateSelectOptions(approvedPRTable, 12, '.' + uniqueSearchClass + '[data-column="12"]'); populateSelectOptions(approvedPRTable, 12, '.' + uniqueSearchClass + '[data-column="12"]');
restoreSearchFromURL(uniqueSearchClass, '#ApprovedPRTable'); restoreSearchFromURL(uniqueSearchClass, '#ApprovedPRTable');
}, },
columns: [ columns: [
{ data: 'statusName' }, { data: 'statusName' },

View File

@ -23,8 +23,8 @@
<script> <script>
$(document).ready(function() { $(document).ready(function() {
// Initialize DataTable for Approved PR
const reportTitle = `Deleted Purchase Request - as of ${getFormattedDateTime()}`;
var removedPRTable = $('#RemovedPRTable').DataTable({ var removedPRTable = $('#RemovedPRTable').DataTable({
ajax: { ajax: {
url: '/PRMgmt/GetApprovedPR', url: '/PRMgmt/GetApprovedPR',
@ -43,8 +43,23 @@
} }
} }
}, },
dom: 'lBfrtip',
buttons: [
{
extend: 'csv',
title: reportTitle
},
{
extend: 'excel',
title: reportTitle
},
{
extend: 'pdf',
title: reportTitle
}
],
initComplete: function () { initComplete: function () {
initializeColumnSearch({ initializeColumnSearch({
tableId: '#RemovedPRTable', tableId: '#RemovedPRTable',
dataTable: removedPRTable, dataTable: removedPRTable,
searchableColumns: [ searchableColumns: [
@ -83,12 +98,12 @@
] ]
}); });
const uniqueSearchClass = 'column-search-input-RemovedPRTable'; const uniqueSearchClass = 'column-search-input-RemovedPRTable';
populateSelectOptions(removedPRTable, 10, '.' + uniqueSearchClass + '[data-column="10"]'); populateSelectOptions(removedPRTable, 10, '.' + uniqueSearchClass + '[data-column="10"]');
restoreSearchFromURL(uniqueSearchClass, '#RemovedPRTable'); restoreSearchFromURL(uniqueSearchClass, '#RemovedPRTable');
}, },
columns: [ columns: [
{ data: 'prNo' }, { data: 'prNo' },
{ data: 'itemNo' }, { data: 'itemNo' },

View File

@ -17,7 +17,7 @@
<div class="toast-container" id="toast-container"></div> <div class="toast-container" id="toast-container"></div>
</main> </main>
</div> </div>
<script src="~/JsFunctions/Account/loginV3.js"></script> <script src="~/JsFunctions/Account/loginV4.js"></script>
<script src="~/jsfunctions/utilities/utilsV3.js"></script> <script src="~/jsfunctions/utilities/utilsV3.js"></script>
<script src="~/js/toast-notifications.js"></script> <script src="~/js/toast-notifications.js"></script>
<script src="~/jsfunctions/account/accountvar.js"></script> <script src="~/jsfunctions/account/accountvar.js"></script>

View File

@ -2,21 +2,25 @@
<div class="container-fluid"> <div class="container-fluid">
<div class="row table-container shadow-lg p-2 mb-3 bg-white rounded"> <div class="row table-container shadow-lg p-2 mb-3 bg-white rounded">
<div class="header-container"> <div class="header-container">
<h2>Custom P.O. Creation</h2> <h2 id="customPOHeading">Custom P.O. Creation</h2>
</div> </div>
<div class="row"> <div class="row">
<!-- Left side (half of the row) --> <!-- Left side (half of the row) -->
<div class="col-6"> <div class="col-6">
<div class="row"> <div class="row">
<div class="col-4"> <div class="col-4">
<div class="form-group"> <div class="form-group">
<label for="poNo">PO No#</label> <label for="poNo">PO No.</label>
<input readonly id="poNo" class="form-control"> <i class="bx bx-pencil"
</div> style="color: orange; font-size: 1.2rem; cursor: pointer;"
onclick="enablePONoAutocomplete()"> </i>
<input type="search" readonly id="poNo" class="form-control">
<input type="hidden" id="poId" class="form-control" name="poId" />
</div>
</div> </div>
<div class="col-4"> <div class="col-4">
<div class="form-group"> <div class="form-group">
<label for="poNoFinal">Final PO No#</label> <label for="poNoFinal">Final PO No.</label>
<input readonly id="poNoFinal" class="form-control"> <input readonly id="poNoFinal" class="form-control">
</div> </div>
</div> </div>

View File

@ -159,7 +159,7 @@
<div class="modal-dialog modal-xl"> <div class="modal-dialog modal-xl">
<div class="modal-content"> <div class="modal-content">
<div class="modal-header"> <div class="modal-header">
<h5 class="modal-title" id="ModalLabel">PR Item Details</h5> <h5 class="modal-title" id="ModalLabel">PO Item Details</h5>
</div> </div>
<div class="modal-body"> <div class="modal-body">
<div class="row"> <div class="row">

View File

@ -11,7 +11,7 @@
Approved PR Approved PR
</button> </button>
<button class="pr-tab-btn" data-tab="pr-removed" data-endpoint="/PRMgmt/GetRemovedPR"> <button class="pr-tab-btn" data-tab="pr-removed" data-endpoint="/PRMgmt/GetRemovedPR">
Removed PR Deleted PR
</button> </button>
</div> </div>
</div> </div>
@ -76,7 +76,7 @@
<link href="~/css/pr/ButtonStyleV2.css" rel="stylesheet" /> <link href="~/css/pr/ButtonStyleV2.css" rel="stylesheet" />
<link href="~/css/pr/PRTabs.css" rel="stylesheet" /> <link href="~/css/pr/PRTabs.css" rel="stylesheet" />
@await Html.PartialAsync("PagesView/PR/_PRTracking") @await Html.PartialAsync("PagesView/PR/_PRTracking")
<script src="~/JsFunctions/PR/PRV7.js"></script> <script src="~/JsFunctions/PR/PRV8.js"></script>
<script src="~/JsFunctions/PR/PRTabs.js"></script> <script src="~/JsFunctions/PR/PRTabs.js"></script>
@await Html.PartialAsync("PagesView/PR/_PRScripts") @await Html.PartialAsync("PagesView/PR/_PRScripts")
</body> </body>

View File

@ -45,6 +45,6 @@
</div> </div>
</div> </div>
<link href="~/css/pr/trackingdetail.css" rel="stylesheet" /> <link href="~/css/pr/trackingdetail.css" rel="stylesheet" />
<script src="~/jsfunctions/pr/DetailedPRTrackingV6.js"></script> <script src="~/jsfunctions/pr/DetailedPRTrackingV7.js"></script>
@await Html.PartialAsync("PagesView/PR/_PRScripts") @await Html.PartialAsync("PagesView/PR/_PRScripts")
</body> </body>

View File

@ -22,4 +22,4 @@
style="color: green; font-size: 1.5rem; cursor: pointer;" onclick="viewCharges()"></i> style="color: green; font-size: 1.5rem; cursor: pointer;" onclick="viewCharges()"></i>
</div> </div>
</div> </div>
</div> </div>

View File

@ -3,7 +3,7 @@
</div> </div>
<link href="~/css/common/rowhighlighter.css" rel="stylesheet" /> <link href="~/css/common/rowhighlighter.css" rel="stylesheet" />
<script src="~/jsfunctions/pr/PRColumnV7.js"></script> <script src="~/jsfunctions/pr/PRColumnV8.js"></script>
<script src="~/jsfunctions/pr/PRViewV7.js"></script> <script src="~/jsfunctions/pr/PRViewV7.js"></script>
<script src="~/jsfunctions/pr/PRPutPost.js"></script> <script src="~/jsfunctions/pr/PRPutPost.js"></script>
<script src="~/jsfunctions/pr/PRButtonv3.js"></script> <script src="~/jsfunctions/pr/PRButtonv3.js"></script>

View File

@ -138,10 +138,6 @@ function validateOTP() {
} }
}); });
} }
function enableHideShowButton() {
//Enable the 'btnSendOTP' if success
//Read only input element id="email"
}
function refreshCaptcha() { function refreshCaptcha() {
const captchaImage = document.getElementById('captchaImage'); const captchaImage = document.getElementById('captchaImage');
captchaImage.src = `/Home/GetCaptcha?ts=${new Date().getTime()}`; // Cache-busting query captchaImage.src = `/Home/GetCaptcha?ts=${new Date().getTime()}`; // Cache-busting query
@ -302,14 +298,30 @@ function login() {
loader.hide(); loader.hide();
}, },
success: function (response) { success: function (response) {
let parsedMessage = null;
if (response && response.responseMessage) {
try {
parsedMessage = JSON.parse(response.responseMessage);
} catch (e) {
console.error("Failed to parse responseMessage", e);
}
}
if (response && response.success === true) { if (response && response.success === true) {
window.location.href = '/' + response.responseController + '/' + response.responseAction; window.location.href = '/' + response.responseController + '/' + response.responseAction;
} else if (response && response.success === false) { }
showToast('error', response.responseMessage, 'Login failed!', 4000); else if (response && response.success === false) {
const errorMessage = parsedMessage?.message || "Login failed.";
showToast('error', errorMessage, 'Login failed!', 4000);
// Highlight inputs if credential-related error
if (errorMessage.toLowerCase().includes('username') ||
errorMessage.toLowerCase().includes('credential')) {
// If login failed due to invalid credentials, highlight username and password
if (response.responseMessage.toLowerCase().includes('username') ||
response.responseMessage.toLowerCase().includes('credential')) {
addErrorClass(userNameInput); addErrorClass(userNameInput);
addErrorClass(passwordInput); addErrorClass(passwordInput);
} }

View File

@ -36,7 +36,7 @@
return; return;
} }
} }
console.log('ProjectCodeId', ProjectCodeId);
showConfirmation({ showConfirmation({
title: 'Purchasing Requisition', title: 'Purchasing Requisition',
message: 'Are you sure you want to proceed? This action cannot be undone.', message: 'Are you sure you want to proceed? This action cannot be undone.',

View File

@ -15,6 +15,7 @@
GetForBiddingApproval: "/POMgmt/GetForBiddingApproval", GetForBiddingApproval: "/POMgmt/GetForBiddingApproval",
GetSupplierBidById: "/POMgmt/GetSupplierBidById", GetSupplierBidById: "/POMgmt/GetSupplierBidById",
GetPortOfDischarge: "/POMgmt/GetPortOfDischarge", GetPortOfDischarge: "/POMgmt/GetPortOfDischarge",
GetPOListByTerm: "/POMgmt/GetPOListByTerm",
PutPOCancel: "/POMgmt/PutPOCancel", PutPOCancel: "/POMgmt/PutPOCancel",
PutPOItemDetail: "/POMgmt/PutPOItemDetail", PutPOItemDetail: "/POMgmt/PutPOItemDetail",

View File

@ -25,36 +25,52 @@ function poTableComponent(id, loader) {
} }
}); });
} }
function customFormPOElemComponent(id) { async function customFormPOElemComponent(id) {
document.getElementById("poNo").readOnly = true;
document.getElementById('customPOHeading').innerHTML = 'Custom P.O. Creation';
populateIncoterms(); populateIncoterms();
populatePOElem(id);
$('#poTypeId').val(id); $('#poTypeId').val(id);
$("#supplierName").on('keyup', function () {
$("#supplierName").off('keyup').on('keyup', function () {
populateSupplier(); populateSupplier();
}); });
if (!id) { if (!id) {
console.warn("No PO Type selected."); console.warn("No PO Type selected.");
return; return;
} }
$.ajax({
url: '/POMgmt/GetCustomFormPOElem', // 1. Load the custom form container FIRST
type: 'GET', await new Promise(function (resolve, reject) {
data: { id: id }, $.ajax({
success: function (response) { url: '/POMgmt/GetCustomFormPOElem',
$('#CustomFormPOElemContainer').html(response); type: 'GET',
$("#C-paymentTerms").on('keyup', function () { data: { id: id },
populateTerms(); success: function (response) {
}); $('#CustomFormPOElemContainer').html(response);
}, $("#C-paymentTerms").off('keyup').on('keyup', function () {
error: function (xhr, status, error) { populateTerms();
console.error("Error loading component:", error); });
} resolve();
},
error: function (xhr, status, error) {
console.error("Error loading component:", error);
reject(error);
}
});
}); });
// 2. NOW the hidden inputs exist in DOM — safe to populate
await populatePOElem(id);
// 3. NOW read from those inputs
getPONoType(id);
getPOType(id);
} }
function poNoComponent(id) { /*function poNoComponent(id) {
populatePONoElem(id); populatePONoElem(id);
$('#poTypeId').val(id); $('#poTypeId').val(id);
} }*/
function poReportComponent(id) { function poReportComponent(id) {
return $.ajax({ return $.ajax({
url: '/POMgmt/GetPOReportTable', url: '/POMgmt/GetPOReportTable',

View File

@ -21,6 +21,109 @@
} }
}); });
}); });
async function fetchAndPopulatePOFormData(poType, poId = null) {
loader = $('#overlay, #loader').css('z-index', 1060);
return new Promise((resolve, reject) => {
$.ajax({
url: '/POMgmt/GetPOFormData',
type: 'GET',
data: { poId: poId },
beforeSend: function () {
loader.show();
},
complete: function () {
loader.hide();
},
success: function (response) {
const d = response;
document.getElementById("poType").value = poType;
$('#poNoFinal').val($('#poNo').val());
// --- Header Fields ---
if (d.header) {
document.getElementById("supplierName").value = d.header.supplierName || '';
$('#supplierId').val(d.header.supplierId || 0);
console.log(d.header.supplierId);
console.log(d.header.supplierName);
$('#deliveryDate').val(d.header.deliveryDate || '');
$('#piDate').val(d.header.profInvoiceDate || '');
$('#piNo').val(d.header.profInvoiceNo || '');
$('#currencyCER').val(d.header.currencyCER || '59.00');
$('#podId').val(d.header.podId || 0);
$('#shippingInstructionId').val(1 || 0);
$('#incotermsName').val(d.header.incoTermsId || 0);
$('#incoTermsId').val(d.header.incoTermsId || 0);
$('#C-paymentTerms').val(d.header.paymentTerms || '');
$('#C-paymentTermsId').val(d.header.paymentTermsId || 0);
$('#remarks').val(d.header.remarks || '');
$('#grossAmountUSD').val(d.header.grossAmountUSD || 0);
$('#finalAmountUSD').val(d.header.finalAmountUSD || 0);
$('#grossAmountPHP').val(d.header.grossAmountPHP || 0);
$('#finalAmountPHP').val(d.header.finalAmountPHP || 0);
}
// --- DataTable: Line Items ---
if (poDataTable) {
poDataTable.clear();
if (d.lineItems && d.lineItems.length > 0) {
poDataTable.rows.add(d.lineItems).draw();
}
}
// --- DataTable: Charges ---
if (d.charges && d.charges.length > 0) {
const $tbody = $('#DestChargesTable tbody');
$tbody.empty(); // clear existing rows first
d.charges.forEach(function (charge) {
var newRow = '<tr>' +
'<td style="display: none;">' + charge.otherChargesId + '</td>' +
'<td>' + charge.otherChargesName + '</td>' +
'<td>' + charge.amount + '</td>' +
'<td><button class="btn btn-default" onclick="removeRow(this)" data-otherChargesId="' + charge.otherChargesId + '">' +
'<i class="fa-solid fa-trash fa-xl" style="color: #ff0000;" aria-hidden="true"></i>' +
'</button></td>' +
'</tr>';
$tbody.append(newRow);
});
// Recalculate after populating charges
calculateFinalPesoAmount($('#poTypeId').val());
calculateFinalUsdAmount();
lessDiscount();
}
// --- Docs Required ---
if (d.docsRequired && d.docsRequired.length > 0) {
$('#docRequiredId').val(
d.docsRequired.map(x => x.docName).join('\n')
);
}
resolve();
},
error: function (xhr, status, error) {
console.error("Error loading PO form data:", error);
reject(error);
}
});
});
}
function enablePONoAutocomplete() {
document.getElementById('customPOHeading').innerHTML = 'Custom P.O. Modification';
customFormPOElemComponent(4);
document.getElementById("poNo").removeAttribute("readonly");
document.getElementById("poNo").value ='';
document.getElementById("poNo").focus();
document.getElementById("poType").value = "0";
popPONo();
}
function lessDiscount() { function lessDiscount() {
let amount = parseFloat($('#finalAmount').val()) || 0; let amount = parseFloat($('#finalAmount').val()) || 0;
let discount = parseFloat($('#discount').val()) || 0; let discount = parseFloat($('#discount').val()) || 0;

View File

@ -641,18 +641,19 @@ function toggleShippingInstructions() {
} }
} }
function getPONoType(poType) { function getPONoType(poType) {
var poNo = ''; let poTypeNo = '';
if (poType == 1) { if (poType == 1)
poNo = $('#si-poNo').val(); poTypeNo = $('#si-poNo').val();
} else if (poType == 2) { else if (poType == 2)
poNo = $('#dr-poNo').val(); poTypeNo = $('#dr-poNo').val();
} else { else
poNo = $('#si-ImportPoNo').val(); poTypeNo = $('#si-ImportPoNo').val();
}
$('#c-poNo').val(poNo); $('#c-poNo').val(poTypeNo);
} }
function getPOType(poType) { function getPOType(poType) {
var poNo = ''; var poNo = '';
if (poType == 1) { if (poType == 1) {
poNo = $('#si-poNo').val(); poNo = $('#si-poNo').val();
calculateTotalPesoAmount(1); calculateTotalPesoAmount(1);
@ -665,6 +666,7 @@ function getPOType(poType) {
poNo = $('#si-ImportPoNo').val(); poNo = $('#si-ImportPoNo').val();
calculateTotalUsdAmount(); calculateTotalUsdAmount();
} }
$('#remarks').val(''); $('#remarks').val('');
$('#deliveryDate').val(''); $('#deliveryDate').val('');
$('#poNo').val(poNo); $('#poNo').val(poNo);

View File

@ -1,42 +1,123 @@
function populatePONoElem(id) { function popPONo() {
loader = $('#overlay, #loader').css('z-index', 1060); $("#poNo").autocomplete({
$.ajax($.extend({ source: function (request, response) {
url: endpoint.GetLatestPO2, $.ajax({
type: 'POST', url: endpoint.GetPOListByTerm,
success: function (data) { data: { query: request.term },
if (data && data.data && data.data.length > 0) { success: function (result) {
var item = data.data[0]; if (result && result.success && Array.isArray(result.data)) {
$('#si-poNo').val('00' + (parseFloat(item.poNoVatInc) + 1));
$('#dr-poNo').val(parseFloat(item.poNoVatEx) + 1); var formattedData = result.data.map(item => ({
$('#si-ImportPoNo').val('10-' + (parseFloat(item.ipoNoVatInc) + 1)); label: item.label || '',
$('#dr-ImportPoNo').val(item.ipoNoVatEx); value: item.value !== undefined && item.value !== null ? item.value : 0,
getPONoType(id); value2: item.value2 !== undefined && item.value2 !== null ? item.value2 : 0
} else { }));
console.log('Data is null or undefined');
} response(formattedData);
} else {
console.error('Invalid data format received:', result);
response([]);
}
}
});
}, },
error: errorHandler minLength: 2,
}, beforeComplete(loader))); select: function (event, ui) {
if (!ui.item || !ui.item.value) {
return false;
}
$('#poNo').val(ui.item.label);
$('#poId').val(ui.item.value);
$('#poTypeId').val(ui.item.value2);
console.log("Selected PO ID:", ui.item.value);
//#1
populatePOModificationForm(ui.item.value2);
fetchAndPopulatePOFormData(ui.item.value2,ui.item.value);
return false;
},
focus: function (event, ui) {
event.preventDefault();
},
open: function () {
var dropdown = $(".ui-autocomplete");
dropdown.css({
"max-height": "200px",
"overflow-y": "auto"
});
},
messages: {
noResults: '',
results: function (count) {
return count + (count > 1 ? ' results' : ' result');
}
}
});
}
async function populatePOModificationForm(id) {
populateIncoterms();
$("#supplierName").off('keyup').on('keyup', function () {
populateSupplier();
});
if (!id) {
console.warn("No PO Type selected.");
return;
}
// 1. Load the custom form container FIRST
await new Promise(function (resolve, reject) {
$.ajax({
url: '/POMgmt/GetCustomFormPOElem',
type: 'GET',
data: { id: id },
success: function (response) {
$('#CustomFormPOElemContainer').html(response);
$("#C-paymentTerms").off('keyup').on('keyup', function () {
populateTerms();
});
resolve();
},
error: function (xhr, status, error) {
console.error("Error loading component:", error);
reject(error);
}
});
});
} }
function populatePOElem(id) { function populatePOElem(id) {
loader = $('#overlay, #loader').css('z-index', 1060); loader = $('#overlay, #loader').css('z-index', 1060);
$.ajax($.extend({ return new Promise(function (resolve, reject) {
url: endpoint.GetLatestPO2, $.ajax($.extend(
type: 'POST', beforeComplete(loader),
success: function (data) { {
if (data && data.data && data.data.length > 0) { url: endpoint.GetLatestPO2,
var item = data.data[0]; type: 'POST',
$('#si-poNo').val('00' + (parseFloat(item.poNoVatInc) + 1)); success: function (data) {
$('#dr-poNo').val(parseFloat(item.poNoVatEx) + 1); if (data && data.data && data.data.length > 0) {
$('#si-ImportPoNo').val('10-' + (parseFloat(item.ipoNoVatInc) + 1)); var item = data.data[0];
$('#dr-ImportPoNo').val(item.ipoNoVatEx); $('#si-poNo').val('00' + (parseFloat(item.poNoVatInc) + 1));
getPOType(id); $('#dr-poNo').val(parseFloat(item.poNoVatEx) + 1);
} else { $('#si-ImportPoNo').val('10-' + (parseFloat(item.ipoNoVatInc) + 1));
console.log('Data is null or undefined'); $('#dr-ImportPoNo').val(item.ipoNoVatEx);
resolve(id);
} else {
console.log('Data is null or undefined');
resolve(id);
}
},
error: function (xhr, status, error) {
errorHandler(xhr, status, error);
reject(error);
}
} }
}, ));
error: errorHandler });
}, beforeComplete(loader)));
} }
function populateIncoterms() { function populateIncoterms() {
$.ajax({ $.ajax({

View File

@ -17,6 +17,14 @@
tableId: '#PRTable', tableId: '#PRTable',
dataTable: prTable, dataTable: prTable,
searchableColumns: [ searchableColumns: [
{
columnIndex: 0,
columnName: 'Status',
placeholder: 'Select Status...',
searchType: 'select',
searchMode: 'exact',
width: '150px'
},
{ {
columnIndex: 1, columnIndex: 1,
columnName: 'PR No', columnName: 'PR No',
@ -52,6 +60,7 @@
] ]
}); });
const uniqueSearchClass = 'column-search-input-PRTable'; const uniqueSearchClass = 'column-search-input-PRTable';
populateSelectOptions(prTable, 0, '.' + uniqueSearchClass + '[data-column="0"]');
populateSelectOptions(prTable, 13, '.' + uniqueSearchClass + '[data-column="13"]'); populateSelectOptions(prTable, 13, '.' + uniqueSearchClass + '[data-column="13"]');
restoreSearchFromURL(uniqueSearchClass, '#PRTable'); restoreSearchFromURL(uniqueSearchClass, '#PRTable');
}, },

View File

@ -96,10 +96,7 @@ var colOnPRTable = [
render: function (data, type, row) { render: function (data, type, row) {
return renderPRbtns(data, row); return renderPRbtns(data, row);
} }
}, }
{ data: 'status', visible: false },
{ data: 'itemCodeId', visible: false },
{ data: 'createdDate', visible: false },
]; ];
var colOnAlterOfferTable = [ var colOnAlterOfferTable = [
{ data: 'prNo' }, { data: 'prNo' },

View File

@ -0,0 +1,176 @@
(function () {
'use strict';
// Tab configuration with table IDs for view components
const tabConfig = {
'pr-list': {
title: 'All Purchase Requests',
tableId: 1,
endpoint: '/PRMgmt/GetTabbedById'
},
'pr-approved': {
title: 'Approved Purchase Requests (No PO)',
tableId: 2,
endpoint: '/PRMgmt/GetTabbedById'
},
'pr-removed': {
title: 'Deleted Purchase Requests',
tableId: 3,
endpoint: '/PRMgmt/GetTabbedById'
}
};
let currentTab = 'pr-list';
let isSwitching = false;
function init() {
const tabs = document.querySelectorAll('.pr-tab-btn');
tabs.forEach(tab => {
tab.addEventListener('click', handleTabClick);
});
// Load initial tab content
loadTabContent('pr-list');
}
function handleTabClick(e) {
if (isSwitching) return;
const btn = e.currentTarget;
const tabId = btn.getAttribute('data-tab');
if (tabId === currentTab) return;
switchTab(tabId, btn);
}
function switchTab(tabId, btn) {
if (!tabConfig[tabId]) {
console.error('Invalid tab ID:', tabId);
return;
}
isSwitching = true;
// Update active states
document.querySelectorAll('.pr-tab-btn').forEach(b => {
b.classList.remove('active');
});
btn.classList.add('active');
// Update title
updateTitle(tabConfig[tabId].title);
// Load view component
loadTabContent(tabId, btn);
currentTab = tabId;
}
function updateTitle(title) {
const titleEl = document.getElementById('pageTitle');
if (!titleEl) return;
// Fade out with slide
titleEl.classList.add('updating');
setTimeout(() => {
titleEl.textContent = title;
// Trigger reflow
void titleEl.offsetWidth;
// Fade in
titleEl.classList.remove('updating');
}, 250);
}
function loadTabContent(tabId, btn = null) {
const config = tabConfig[tabId];
if (!config) {
console.error('Tab config not found:', tabId);
isSwitching = false;
return;
}
// Show loading state
if (btn) {
btn.classList.add('loading');
}
showContainerLoading(true);
// Call your existing function
prTabbedComponent(config.tableId, config.endpoint, function (success) {
// Hide loading state
if (btn) {
btn.classList.remove('loading');
}
showContainerLoading(false);
isSwitching = false;
if (!success) {
console.error('Failed to load tab content');
}
});
}
function showContainerLoading(isLoading) {
const container = document.getElementById('TabbedContainer');
if (!container) return;
if (isLoading) {
container.style.opacity = '0.5';
container.style.pointerEvents = 'none';
} else {
container.style.opacity = '1';
container.style.pointerEvents = 'auto';
}
}
// Initialize on DOM ready
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
// Public API
window.PRTabs = {
switchTo: function (tabId) {
const btn = document.querySelector(`.pr-tab-btn[data-tab="${tabId}"]`);
if (btn && !isSwitching) {
switchTab(tabId, btn);
}
},
reload: function () {
loadTabContent(currentTab);
},
getCurrent: function () {
return currentTab;
},
addTab: function (tabId, config) {
// Dynamically add new tab configuration
tabConfig[tabId] = config;
}
};
})();
// Updated prTabbedComponent to work with callback
function prTabbedComponent(id, endpoint, callback) {
$.ajax({
url: endpoint,
type: 'GET',
data: { TableId: id }, // Note: capital T to match your controller parameter
success: function (response) {
$('#TabbedContainer').html(response);
if (callback) callback(true);
},
error: function (xhr, status, error) {
console.error("Error loading component:", error);
$('#TabbedContainer').html('<div class="alert alert-danger">Failed to load content. Please try again.</div>');
if (callback) callback(false);
}
});
}

View File

@ -18,7 +18,7 @@
data: { ItemNo: ItemNo, Status: Status, PRDetailsId: PRDetailsId, Remarks: Remarks }, data: { ItemNo: ItemNo, Status: Status, PRDetailsId: PRDetailsId, Remarks: Remarks },
success: function (response) { success: function (response) {
if (response.success) { if (response.success) {
getApproverName(PRDetailsId); getApproverName(PRDetailsId,0);
prDataTable.ajax.reload(null, false); prDataTable.ajax.reload(null, false);
isApproval = true; isApproval = true;
@ -46,14 +46,14 @@
}); });
} }
$(document).ready(function () { /*$(document).ready(function () {
loader = $('#overlay, #loader'); loader = $('#overlay, #loader');
UserRights = document.getElementById("roleRights").value; UserRights = document.getElementById("roleRights").value;
prTable = $('#PRTable').DataTable({ prTable = $('#PRTable').DataTable({
ajax: { ajax: {
url: '/PRMgmt/GetAllPR', url: '/PRMgmt/GetAllPR', // Initial endpoint
type: 'GET', type: 'GET',
beforeSend: function () { beforeSend: function () {
// Show the loader before making the AJAX request // Show the loader before making the AJAX request
@ -61,19 +61,49 @@ $(document).ready(function () {
}, },
complete: function () { complete: function () {
loader.hide(); loader.hide();
},
error: function (xhr, error, thrown) {
loader.hide();
console.error('Error loading data:', error);
// Optional: Show error notification
if (typeof toastr !== 'undefined') {
toastr.error('Failed to load data. Please try again.');
}
} }
}, },
initComplete: initCompleteCallback, initComplete: initCompleteCallback,
columns: colOnPRTable, columns: colOnPRTable,
order: [10, 'asc'], order: [[10, 'asc']],
rowCallback: rowStatusColorCallback, rowCallback: rowStatusColorCallback,
responsive: true, responsive: true,
language: { language: {
emptyTable: "No record available" emptyTable: "No record available",
loadingRecords: "Loading data...",
processing: "Processing..."
}, },
error: errorHandler error: errorHandler
}); });
})
// Initialize tabs after DataTable is ready
// The PRTabs.js script will handle tab switching and DataTable reloading
});*/
// Optional: Add helper function to refresh current tab
function refreshCurrentTab() {
if (typeof PRTabs !== 'undefined') {
PRTabs.reload();
} else if (prTable) {
prTable.ajax.reload();
}
}
// Optional: Add helper to switch tabs programmatically
function switchToPRTab(tabName) {
if (typeof PRTabs !== 'undefined') {
PRTabs.switchToTab(tabName);
}
}
function submitItem() { function submitItem() {
loader = $('#overlay, #loader'); loader = $('#overlay, #loader');
@ -269,4 +299,14 @@ function checkExistingAttachment() {
} else { } else {
existingAttachment = false; existingAttachment = false;
} }
}
function getFormattedDateTime() {
const now = new Date();
const yyyy = now.getFullYear();
const mm = String(now.getMonth() + 1).padStart(2, '0');
const dd = String(now.getDate()).padStart(2, '0');
const hh = String(now.getHours()).padStart(2, '0');
const min = String(now.getMinutes()).padStart(2, '0');
const ss = String(now.getSeconds()).padStart(2, '0');
return `${yyyy}-${mm}-${dd}_${hh}${min}${ss}`;
} }

View File

@ -55,29 +55,30 @@
modal.modal('show'); modal.modal('show');
} }
function getApproverName(prDetailsId) { function getApproverName(prDetailsId, prNo) {
PRDetailsId = prDetailsId;
const endPoint = (prNo === 0 || prNo === undefined) ? '/PRMgmt/GetApproverName'
: '/PRMgmt/GetApproverNameByPRNo';
$.ajax({ $.ajax({
url: '/PRMgmt/GetApproverName', url: endPoint,
type: 'POST', type: 'POST',
data: { PRDetailsId }, data: { prDetailsId, prNo },
success: function (data) { success: function (response) {
if (data && data.data && data.data.length > 0) { if (response && response.data && response.data.length > 0) {
var item = data.data[0]; const item = response.data[0];
const attestedBy = document.getElementById('label-pr-attestedBy'); const attestedBy = document.getElementById('label-pr-attestedBy');
const approveBy = document.getElementById('label-pr-approvedBy'); const approveBy = document.getElementById('label-pr-approvedBy');
if (attestedBy) {
attestedBy.innerHTML = item.attestedBy; // Security: Use textContent to prevent XSS
} if (attestedBy) attestedBy.textContent = item.attestedBy || '';
if (approveBy) { if (approveBy) approveBy.textContent = item.approvedBy || '';
approveBy.innerHTML = item.approvedBy;
}
} }
}, },
error: errorHandler error: errorHandler
}); });
} }
function printPRItem() { function printPRItem() {
const iframe = document.createElement('iframe'); const iframe = document.createElement('iframe');
iframe.style.position = 'fixed'; iframe.style.position = 'fixed';
@ -506,7 +507,7 @@ function viewPRStatusById(data) {
} else { } else {
var imageUrl = item.url + itemPicturePath; var imageUrl = item.url + itemPicturePath;
//console.log('imageUrl', imageUrl);
$('#t-itemPictureImage').attr('src', imageUrl); $('#t-itemPictureImage').attr('src', imageUrl);
} }
@ -684,8 +685,8 @@ function enableDisableInput(isDenied, dynamicBtn) {
document.getElementById('itemLocalName'), document.getElementById('itemLocalName'),
document.getElementById('itemClassId'), document.getElementById('itemClassId'),
document.getElementById('prTypeId'), document.getElementById('prTypeId'),
document.getElementById('itemQty'),//btnUpdateItem document.getElementById('itemQty'),
/* document.getElementById('btnUpdateItem'),*/
]; ];
inputs.forEach(function (input) { inputs.forEach(function (input) {
if (input) { if (input) {
@ -711,9 +712,19 @@ function viewPRDetails(data) {
tableDestroy(tableElement); tableDestroy(tableElement);
var PRNo = data.prNo; var PRNo = data.prNo;
getApproverName(0, PRNo);
$('#prId').val(data.prId); $('#prId').val(data.prId);
// Populate PR header details const allowedRoles = ['Approver1', 'Approver2', 'POApprover'];
if (allowedRoles.includes(UserRights)) {
document.getElementById('btnSubmitItem').style.display = 'block';
} else {
document.getElementById('btnSubmitItem').style.display = 'none';
}
populatePRHeader(data); populatePRHeader(data);
prDataTable = tableElement.DataTable({ prDataTable = tableElement.DataTable({
@ -789,14 +800,12 @@ function toggleAttachment(rowWithFile) {
function downloadPRAttachment() { function downloadPRAttachment() {
let fileName = $('#fileName').val(); let fileName = $('#fileName').val();
// Append parameters to URL for GET requests
const params = new URLSearchParams({ fileName: fileName }); const params = new URLSearchParams({ fileName: fileName });
const url = `/PRMgmt/GetPRAttachment?${params.toString()}`; const url = `/PRMgmt/GetPRAttachment?${params.toString()}`;
fetch(url, { method: 'GET' }) fetch(url, { method: 'GET' })
.then(response => { .then(response => {
if (!response.ok) { if (!response.ok) {
// If backend returns 500 or 400, it won't be a blob
throw new Error("Failed to download file"); throw new Error("Failed to download file");
} }
return response.blob(); return response.blob();

View File

@ -0,0 +1,217 @@
/* Tab Header Container */
.pr-tabs-header {
background: teal;
border-bottom: 1px solid #00695c;
margin: -1rem -1rem 0 -1rem;
padding: 0;
border-radius: 15px 10px 0 0;
}
/* Tab Navigation */
.pr-tabs-nav {
display: flex;
gap: 0;
align-items: stretch;
padding: 0;
}
/* Individual Tab Button */
.pr-tab-btn {
flex: 0 0 auto;
padding: 14px 32px;
background: transparent;
border: none;
border-bottom: 3px solid transparent;
color: white;
font-size: 15px;
font-weight: 500;
border-radius: 15px 0px 0 0;
cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
position: relative;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
letter-spacing: 0.3px;
}
/* Tab Hover State */
.pr-tab-btn:hover {
background: rgba(255, 255, 255, 0.15);
color: white;
}
/* Active Tab */
.pr-tab-btn.active {
background: white;
color: teal;
font-weight: 600;
border-bottom-color: white;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
}
/* Active Tab Accent Line */
.pr-tab-btn.active::before {
content: '';
position: absolute;
bottom: -3px;
left: 0;
right: 0;
height: 3px;
background: white;
}
/* Loading State */
.pr-tab-btn.loading {
pointer-events: none;
opacity: 0.6;
}
.pr-tab-btn.loading::after {
content: '';
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
width: 12px;
height: 12px;
border: 2px solid currentColor;
border-top-color: transparent;
border-radius: 50%;
animation: spin 0.7s linear infinite;
}
@keyframes spin {
to {
transform: translateY(-50%) rotate(360deg);
}
}
.page-header-section {
padding: 24px 0 16px 0;
}
.page-heading {
margin: 0;
font-size: 28px;
font-weight: 600;
color: teal;
text-align: left;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
letter-spacing: -0.5px;
position: relative;
padding-bottom: 12px;
}
/* Subtle Accent Line Under Heading */
.page-heading::after {
content: '';
position: absolute;
bottom: 0;
left: 0;
width: 60px;
height: 3px;
background: teal;
border-radius: 2px;
}
/* Title Transition Animation */
.page-heading {
transition: opacity 0.25s ease, transform 0.25s ease;
}
.page-heading.updating {
opacity: 0;
transform: translateX(-10px);
}
/* Table Container Adjustments */
.table-container {
margin-top: -15px !important;
overflow: hidden;
}
/* Ensure table container has proper border radius */
.table-container.rounded {
border-radius: 5px !important;
}
/* Responsive Design */
@media (max-width: 768px) {
.pr-tabs-nav {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
}
.pr-tab-btn {
padding: 12px 24px;
font-size: 14px;
white-space: nowrap;
}
.page-heading {
font-size: 24px;
}
.page-header-section {
padding: 20px 0 12px 0;
}
}
@media (max-width: 576px) {
.pr-tab-btn {
padding: 10px 20px;
font-size: 13px;
}
.page-heading {
font-size: 22px;
}
.page-header-section {
padding: 16px 0 10px 0;
}
}
/* Smooth scrollbar for mobile tabs */
.pr-tabs-nav::-webkit-scrollbar {
height: 3px;
}
.pr-tabs-nav::-webkit-scrollbar-track {
background: #e0f2f1;
}
.pr-tabs-nav::-webkit-scrollbar-thumb {
background: #80cbc4;
border-radius: 10px;
}
.pr-tabs-nav::-webkit-scrollbar-thumb:hover {
background: #4db6ac;
}
/* Enhanced Table Styling */
#PRTable {
margin-top: 0 !important;
}
/* Focus States for Accessibility */
.pr-tab-btn:focus {
outline: 2px solid white;
outline-offset: -2px;
}
.pr-tab-btn:focus:not(:focus-visible) {
outline: none;
}
/* Print Styles */
@media print {
.pr-tabs-header {
display: none;
}
.page-heading::after {
display: none;
}
}