diff --git a/.vs/OSS/v16/.suo b/.vs/OSS/v16/.suo index f3eac74..f0837e9 100644 Binary files a/.vs/OSS/v16/.suo and b/.vs/OSS/v16/.suo differ diff --git a/Controllers/NewCOIController.cs b/Controllers/NewCOIController.cs index cc13943..0fb0499 100644 --- a/Controllers/NewCOIController.cs +++ b/Controllers/NewCOIController.cs @@ -2199,6 +2199,124 @@ namespace OSS.Controllers return View("PaymentExpansion"); } + // Create an additional payment invoice (e.g., surcharge when ownership underpayment occurs) + [Authorize] + public ActionResult AdditionalPayment(string projectCode = null) + { + try + { + var username = Session["CompanyEmail"] as string; + if (string.IsNullOrWhiteSpace(username)) + { + return RedirectToAction("Index", "Home"); + } + + // Prefer explicit project code if provided, otherwise fall back to session + var code = !string.IsNullOrWhiteSpace(projectCode) ? projectCode : (Session["ProjectCode"] as string); + if (string.IsNullOrWhiteSpace(code)) + { + TempData["PaymentError"] = "No project selected. Open a project first or pass ?projectCode=..."; + EnsurePaymentSessionDefaults("TZS"); + return RedirectToAction("Payment"); + } + + var project = myContext.ProjectProfilesExternal.FirstOrDefault(t => t.ProjectCode == code); + if (project == null) + { + TempData["PaymentError"] = "Project details not found."; + EnsurePaymentSessionDefaults("TZS"); + return RedirectToAction("Payment"); + } + + // Resolve additional amount from tblService (ServiceName='Additional_Amount', Currency='TZS', Status='1') + decimal addAmount = 0m; + try + { + var feeRow = myContext.ServiceFees + .AsNoTracking() + .FirstOrDefault(s => + (s.Status ?? "").Trim() == "1" && + (s.Currency ?? "").Trim().ToUpper() == "TZS" && + (s.ServiceName ?? "").Trim() == "Additional_Amount"); + + if (feeRow != null && feeRow.Fee.HasValue && feeRow.Fee.Value > 0m) + addAmount = feeRow.Fee.Value; + } + catch + { + // handled below + } + + if (addAmount <= 0m) + { + var err = "Fee not configured in tblService for ServiceName='Additional_Amount', Currency='TZS'."; + TempData["PaymentError"] = err; + EnsurePaymentSessionDefaults("TZS"); + return RedirectToAction("Payment"); + } + + // If an additional invoice already exists, reuse it + var existingInv = myContext.ApplicationManagers + .OrderByDescending(a => a.CreatedDate) + .FirstOrDefault(a => a.ProjectCode == code && a.ServiceName == "Additional_Amount"); + + if (existingInv != null) + { + Session["Amount"] = existingInv.Amount.ToString("0"); + var currency = string.IsNullOrWhiteSpace(existingInv.Currency) ? "TZS" : existingInv.Currency; + Session["Currency"] = currency; + Session["AmountinWords"] = CurrencyUtils.ToWords(existingInv.Amount) + " " + currency; + // In Additional Payment context: hide the button and paid invoices, and mark additional context + ViewBag.HideAdditionalButton = true; + TempData["HidePaidInvoices"] = true; + TempData["AdditionalContext"] = true; + return View("Payment"); + } + + var applicant = myContext.InvestorExternl.FirstOrDefault(x => x.CompanyEmail == username); + + var inv = new ApplicationManager + { + ProjectCode = code, + ProjectName = project.ProjectName ?? string.Empty, + CompanyName = project.CompanyName ?? string.Empty, + ServiceName = "Additional_Amount", + MobileNo = applicant?.Mobile ?? string.Empty, + CreatedDate = DateTime.Now, + CompanyTIN = (Session["CompanyTIN"] as string) ?? string.Empty, + CompanyEmail = username, + Currency = "TZS", + Station = "HQ", + Amount = addAmount + }; + + Session["Amount"] = addAmount.ToString("0"); + Session["Currency"] = "TZS"; + Session["AmountinWords"] = CurrencyUtils.ToWords(addAmount) + " Tanzanian Shillings"; + + string saveErr; + var company = myContext.CompanyProfileExternal.FirstOrDefault(c => c.AddedBy == username); + if (!TrySaveInvoice(myContext, inv, company, out saveErr)) + { + TempData["PaymentError"] = "Could not save additional payment invoice. " + saveErr; + EnsurePaymentSessionDefaults("TZS"); + return RedirectToAction("Payment"); + } + + // In Additional Payment context: hide the "Pay Additional Amount" button and hide previous paid invoices + ViewBag.HideAdditionalButton = true; + TempData["HidePaidInvoices"] = true; + TempData["AdditionalContext"] = true; + return View("Payment"); + } + catch (Exception ex) + { + TempData["PaymentError"] = "Error creating additional payment invoice. " + ex.Message; + EnsurePaymentSessionDefaults("TZS"); + return RedirectToAction("Payment"); + } + } + public async Task GenerateControlNo() { await Task.Delay(4000); @@ -2208,12 +2326,29 @@ namespace OSS.Controllers [HttpPost] public async Task ProceControlNumber() { - var Username = Session["CompanyEmail"].ToString(); - var ProjectCode = Session["ProjectCode"].ToString(); - var Currency = Session["Currency"].ToString(); + var Username = Session["CompanyEmail"] as string; + var ProjectCode = Session["ProjectCode"] as string; + var Currency = Session["Currency"] as string; - var getPDetails = myContext.ApplicationManagers.SingleOrDefault(t => t.ProjectCode == ProjectCode); - ExchangeRate exchangeRate = myContext.ExchangeRates.SingleOrDefault(t => t.Currency == getPDetails.Currency); + if (string.IsNullOrWhiteSpace(Username) || string.IsNullOrWhiteSpace(ProjectCode)) + { + TempData["PaymentError"] = "Your session expired or project is missing. Please login and open the project again."; + return RedirectToAction("Payment", "NewCOI"); + } + + var getPDetails = myContext.ApplicationManagers + .Where(t => t.ProjectCode == ProjectCode) + .OrderByDescending(t => t.CreatedDate) + .FirstOrDefault(); + + if (getPDetails == null) + { + TempData["PaymentError"] = "No invoice found for this project. Create an invoice first."; + return RedirectToAction("Payment", "NewCOI"); + } + + ExchangeRate exchangeRate = myContext.ExchangeRates + .FirstOrDefault(t => t.Currency == getPDetails.Currency); if(exchangeRate != null){ Session["EqAmount"] = exchangeRate.Rate * getPDetails.Amount; @@ -2269,7 +2404,10 @@ namespace OSS.Controllers } catch (Exception ex) { - var getGepgResponse = myContext.ApplicationManagers.SingleOrDefault(t => t.ProjectCode == ProjectCode); + var getGepgResponse = myContext.ApplicationManagers + .Where(t => t.ProjectCode == ProjectCode) + .OrderByDescending(t => t.CreatedDate) + .FirstOrDefault(); TempData["error"] = "Network timeout..please try again"; return RedirectToAction("GenerateControlNo", "NewCOI"); } diff --git a/Views/NewCOI/ApplicationStatus.cshtml b/Views/NewCOI/ApplicationStatus.cshtml index e0b33fd..2f19ac0 100644 --- a/Views/NewCOI/ApplicationStatus.cshtml +++ b/Views/NewCOI/ApplicationStatus.cshtml @@ -47,11 +47,19 @@ + @{ + var projCode = Session["ProjectCode"] as string; + } @if (Session["EvaluationStatus"].ToString()=="Deffered") { - Click here to rectify corrections and re-submit} + Click here to rectify corrections and re-submit + }  Go back - + @if (!string.IsNullOrEmpty(projCode)) + { + Go to Payment + Pay Additional Amount + } diff --git a/Views/NewCOI/LoadgeNewCOI.cshtml b/Views/NewCOI/LoadgeNewCOI.cshtml index ded6ba4..152474a 100644 --- a/Views/NewCOI/LoadgeNewCOI.cshtml +++ b/Views/NewCOI/LoadgeNewCOI.cshtml @@ -95,6 +95,21 @@ Invalid Input +
+ + @Html.DropDownList( + "TypeofOwnership", + new List { + new SelectListItem { Text = "Tanzanians Only", Value = "Local" }, + new SelectListItem { Text = "Foreigners Only", Value = "Foreign" }, + new SelectListItem { Text = "Mixed (Foreigners & Tanzanians)", Value = "JV" } + }, + new { @class = "selectpicker form-control", @id = "TypeofOwnership", @name = "TypeofOwnership", @required = "required" } + ) +
+ Select ownership type +
+
@Html.TextBoxFor(m => m.IncorpCertNo, new { @name = "IncorpCertNo", @class = "form-control mb-4", @id = "IncorpCertNo", @type = "text", @pattern = "^[0-9]+$" ,@maxlength="10" }) diff --git a/Views/NewCOI/LoadgeNewExpansion.cshtml b/Views/NewCOI/LoadgeNewExpansion.cshtml index 5265a06..7257f20 100644 --- a/Views/NewCOI/LoadgeNewExpansion.cshtml +++ b/Views/NewCOI/LoadgeNewExpansion.cshtml @@ -92,6 +92,21 @@ Invalid Input
+
+ + @Html.DropDownList( + "TypeofOwnership", + new List { + new SelectListItem { Text = "Tanzanians Only", Value = "Local" }, + new SelectListItem { Text = "Foreigners Only", Value = "Foreign" }, + new SelectListItem { Text = "Mixed (Foreigners & Tanzanians)", Value = "JV" } + }, + new { @class = "selectpicker form-control", @id = "TypeofOwnership", @name = "TypeofOwnership", @required = "required" } + ) +
+ Select ownership type +
+
@Html.TextBoxFor(m => m.IncorpCertNo, new { @name = "LastName", @class = "form-control mb-4", @id = "LastName", @type = "text", @required = "true" }) diff --git a/Views/NewCOI/Payment.cshtml b/Views/NewCOI/Payment.cshtml index 48dd512..ffbfbc2 100644 --- a/Views/NewCOI/Payment.cshtml +++ b/Views/NewCOI/Payment.cshtml @@ -57,7 +57,7 @@
- @Session["ProjectCode"].ToString() + @(Session["ProjectCode"] as string ?? "")
@@ -68,12 +68,12 @@
- - @Session["Amount"].ToString() + + @(Session["Amount"] as string ?? "")
- @Session["AmountinWords"].ToString() + @(Session["AmountinWords"] as string ?? "")
@@ -83,8 +83,8 @@

Invoice Details
- @(Html.DevExtreme().DataGrid -() + @(Html.DevExtreme().DataGrid() +.ID("invoiceGrid") .DataSource(ds => ds.WebApi() .RouteName("CompanyProfile") .LoadAction("GetInvoiceByUser") @@ -92,7 +92,7 @@ .Key("ApplicationID") //.InsertAction("Post") -.LoadParams(new { ProjectCode = Session["ProjectCode"].ToString() }) +.LoadParams(new { ProjectCode = (Session["ProjectCode"] as string ?? string.Empty) }) ) .RemoteOperations(true) .AllowColumnResizing(true) @@ -166,6 +166,63 @@ columns.AddFor(m => m.CompanyEmail).Caption("Company Email").Visible(true).Allow
+ @{ + var additionalProjectCode = Session["ProjectCode"] as string; + } + @{ + bool hideAdditionalBtn = false; + if (ViewBag.HideAdditionalButton != null) + { + bool.TryParse(ViewBag.HideAdditionalButton.ToString(), out hideAdditionalBtn); + } + } + @if (!string.IsNullOrEmpty(additionalProjectCode) && !hideAdditionalBtn) + { + + } + + @if (TempData["HidePaidInvoices"] != null) + { + + } + + @if (TempData["AdditionalContext"] != null) + { + + } +
diff --git a/bin/OSS.dll b/bin/OSS.dll index ec2deda..dbb276c 100644 Binary files a/bin/OSS.dll and b/bin/OSS.dll differ diff --git a/bin/OSS.pdb b/bin/OSS.pdb index 4b99dac..fb518ed 100644 Binary files a/bin/OSS.pdb and b/bin/OSS.pdb differ diff --git a/obj/Debug/OSS.csproj.AssemblyReference.cache b/obj/Debug/OSS.csproj.AssemblyReference.cache index f5e894a..33280fc 100644 Binary files a/obj/Debug/OSS.csproj.AssemblyReference.cache and b/obj/Debug/OSS.csproj.AssemblyReference.cache differ diff --git a/obj/Debug/OSS.dll b/obj/Debug/OSS.dll index ec2deda..dbb276c 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 4b99dac..fb518ed 100644 Binary files a/obj/Debug/OSS.pdb and b/obj/Debug/OSS.pdb differ