diff --git a/.vs/OSS/v16/.suo b/.vs/OSS/v16/.suo index 0e76559..03478f0 100644 Binary files a/.vs/OSS/v16/.suo and b/.vs/OSS/v16/.suo differ diff --git a/Controllers/CompanyProfileExternalApiController.cs b/Controllers/CompanyProfileExternalApiController.cs index 6bdd0f9..69e2c1a 100644 --- a/Controllers/CompanyProfileExternalApiController.cs +++ b/Controllers/CompanyProfileExternalApiController.cs @@ -116,6 +116,45 @@ namespace OSS.Controllers { return Request.CreateResponse(DataSourceLoader.Load(myContext.ApplicationManagers.Where(t => t.CompanyEmail == Username && t.EvaluationStatus=="Approved").OrderByDescending(t => t.CreatedDate), loadOptions)); } + [HttpGet] + public HttpResponseMessage GetInvoicesByApplicationCode(DataSourceLoadOptions loadOptions, string ProjectCode) + { + try + { + if (string.IsNullOrEmpty(ProjectCode)) + { + return Request.CreateResponse(DataSourceLoader.Load(new List(), loadOptions)); + } + + // Query invoices directly from tblInvoice using ApplicationCode (ProjectCode) + var invoices = myContext.Database.SqlQuery( + "SELECT InvoiceID, SubServiceName, Amount, Currency, StartDate, Expiredate, BillItemRefNo, ControlNo, PaymentStatus, ApplicationCode FROM tblInvoice WHERE ApplicationCode = @p0 ORDER BY InvoiceID DESC", + new System.Data.SqlClient.SqlParameter("@p0", ProjectCode)).ToList(); + + // Convert to anonymous objects for DevExtreme (with null-safe defaults) + var invoiceList = invoices.Select(i => new + { + InvoiceID = i.InvoiceID, + SubServiceName = i.SubServiceName ?? "", + Amount = i.Amount ?? 0m, + Currency = i.Currency ?? "", + StartDate = i.StartDate, + Expiredate = i.Expiredate, + BillItemRefNo = i.BillItemRefNo ?? "", + ControlNo = i.ControlNo ?? "", + PaymentStatus = i.PaymentStatus ?? false, + ApplicationCode = i.ApplicationCode ?? "" + }).ToList(); + + return Request.CreateResponse(DataSourceLoader.Load(invoiceList, loadOptions)); + } + catch (Exception ex) + { + // Log error and return empty list to prevent 500 error + System.Diagnostics.Debug.WriteLine("Error loading invoices: " + ex.Message); + return Request.CreateResponse(DataSourceLoader.Load(new List(), loadOptions)); + } + } [HttpPost] diff --git a/Controllers/NewCOIController.cs b/Controllers/NewCOIController.cs index 0ed4e2e..6125dd0 100644 --- a/Controllers/NewCOIController.cs +++ b/Controllers/NewCOIController.cs @@ -4076,6 +4076,37 @@ namespace OSS.Controllers Session["ProjectCode"] = Id; return RedirectToAction("DisplayPDF"); } + public ActionResult DownloadInvoice(long? invoiceId) + { + if (!invoiceId.HasValue) + { + TempData["PaymentError"] = "Invoice ID is required."; + return RedirectToAction("ApplicationStatus"); + } + + try + { + // Get invoice from tblInvoice to get ApplicationCode + var invoice = myContext.Database.SqlQuery( + "SELECT InvoiceID, ApplicationCode, ApplicationID FROM tblInvoice WHERE InvoiceID = @p0", + invoiceId.Value).FirstOrDefault(); + + if (invoice == null) + { + TempData["PaymentError"] = "Invoice not found."; + return RedirectToAction("ApplicationStatus"); + } + + // Set ProjectCode in session and redirect to DisplayPDF + Session["ProjectCode"] = invoice.ApplicationCode; + return RedirectToAction("DisplayPDF"); + } + catch (Exception ex) + { + TempData["PaymentError"] = "Error loading invoice: " + ex.Message; + return RedirectToAction("ApplicationStatus"); + } + } public ActionResult RegenerateTransfer(string Id) { Session["ProjectCode"] = Id; diff --git a/Models/InvoiceDisplay.cs b/Models/InvoiceDisplay.cs new file mode 100644 index 0000000..3388a4c --- /dev/null +++ b/Models/InvoiceDisplay.cs @@ -0,0 +1,18 @@ +using System; +namespace OSS.Models +{ + public class InvoiceDisplay + { + public long? InvoiceID { get; set; } + public string SubServiceName { get; set; } + public decimal? Amount { get; set; } + public string Currency { get; set; } + public DateTime? StartDate { get; set; } + public DateTime? Expiredate { get; set; } + public string BillItemRefNo { get; set; } + public string ControlNo { get; set; } + public bool? PaymentStatus { get; set; } + public string ApplicationCode { get; set; } + } +} + diff --git a/OSS.csproj b/OSS.csproj index 2683fb8..b7da65e 100644 --- a/OSS.csproj +++ b/OSS.csproj @@ -1127,6 +1127,7 @@ + diff --git a/Views/NewCOI/ApplicationStatus.cshtml b/Views/NewCOI/ApplicationStatus.cshtml index add31c2..a3ada98 100644 --- a/Views/NewCOI/ApplicationStatus.cshtml +++ b/Views/NewCOI/ApplicationStatus.cshtml @@ -57,7 +57,7 @@  Go back @if (!string.IsNullOrEmpty(projCode)) { - Pay Additional Amount + Pay Additional Amount } @@ -171,6 +171,65 @@ + +
+
+
+  Invoice List +
+
+ @(Html.DevExtreme().DataGrid() + .ID("invoiceListGrid") + .DataSource(ds => ds.WebApi() + .RouteName("CompanyProfile") + .LoadAction("GetInvoicesByApplicationCode") + .Key("InvoiceID") + .LoadParams(new { ProjectCode = (Session["ProjectCode"] as string ?? string.Empty) }) + ) + .RemoteOperations(true) + .AllowColumnResizing(true) + .ShowRowLines(true) + .Columns(columns => + { + columns.Add().DataField("InvoiceID").Caption("Invoice ID").Visible(true); + columns.Add().DataField("SubServiceName").Caption("Service Name").Visible(true); + columns.Add().DataField("Amount").Caption("Amount").Visible(true).Format(Format.Currency); + columns.Add().DataField("Currency").Caption("Currency").Visible(true); + columns.Add().DataField("StartDate").Caption("Start Date").Visible(true).DataType(GridColumnDataType.Date).Format(Format.ShortDate); + columns.Add().DataField("Expiredate").Caption("Expiry Date").Visible(true).DataType(GridColumnDataType.Date).Format(Format.ShortDate); + columns.Add().DataField("BillItemRefNo").Caption("Bill Ref No").Visible(true); + columns.Add().DataField("ControlNo").Caption("Control No").Visible(true); + columns.Add().DataField("PaymentStatus").Caption("Payment Status").Visible(true).CellTemplate(@ + <% if(data.PaymentStatus == true) + {%> + Paid + <% } + else + {%> + Pending + <% } + %> + ); + columns.Add().Caption("Download").Width(150).CellTemplate(@ + <% if(data.InvoiceID != null) + {%> + " target="_blank" class="btn btn-outline-primary btn-sm"> + Download + + <% } + %> + ); + }) + .SearchPanel(f => f.Visible(true) + .SearchVisibleColumnsOnly(true) + .HighlightSearchText(true) + ) + .Paging(p => p.PageSize(10)) + .HeaderFilter(f => f.Visible(true)) + ) +
+
+ diff --git a/bin/OSS.dll b/bin/OSS.dll index 003e637..d7de638 100644 Binary files a/bin/OSS.dll and b/bin/OSS.dll differ diff --git a/bin/OSS.pdb b/bin/OSS.pdb index 99205a4..2d37334 100644 Binary files a/bin/OSS.pdb and b/bin/OSS.pdb differ diff --git a/obj/Debug/DesignTimeResolveAssemblyReferences.cache b/obj/Debug/DesignTimeResolveAssemblyReferences.cache index c40433e..f5e894a 100644 Binary files a/obj/Debug/DesignTimeResolveAssemblyReferences.cache and b/obj/Debug/DesignTimeResolveAssemblyReferences.cache differ diff --git a/obj/Debug/OSS.csproj.CoreCompileInputs.cache b/obj/Debug/OSS.csproj.CoreCompileInputs.cache index 12613af..b5993dc 100644 --- a/obj/Debug/OSS.csproj.CoreCompileInputs.cache +++ b/obj/Debug/OSS.csproj.CoreCompileInputs.cache @@ -1 +1 @@ -4e75d7d6e094f6c475400ea8de131765d1699b19 +c5563d2d9f3011f09d695d963bd339d6e2693d8d diff --git a/obj/Debug/OSS.dll b/obj/Debug/OSS.dll index 003e637..d7de638 100644 Binary files a/obj/Debug/OSS.dll and b/obj/Debug/OSS.dll differ diff --git a/obj/Debug/OSS.pdb b/obj/Debug/OSS.pdb index 99205a4..2d37334 100644 Binary files a/obj/Debug/OSS.pdb and b/obj/Debug/OSS.pdb differ