This commit is contained in:
mustafa.juma 2025-11-16 16:09:03 +03:00
parent 85bcc58499
commit ef35d12e21
11 changed files with 248 additions and 15 deletions

Binary file not shown.

View File

@ -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<ActionResult> GenerateControlNo()
{
await Task.Delay(4000);
@ -2208,12 +2326,29 @@ namespace OSS.Controllers
[HttpPost]
public async Task<ActionResult> 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");
}

View File

@ -47,11 +47,19 @@
<td>
</td>
<td>
@{
var projCode = Session["ProjectCode"] as string;
}
@if (Session["EvaluationStatus"].ToString()=="Deffered")
{
<a class="btn btn-danger btn-lg mt-2 " href="/NewCOI/AttachmentsNewDeffered"><blink>Click here to rectify corrections and re-submit<blink></a>}
<a class="btn btn-danger btn-lg mt-2 " href="/NewCOI/AttachmentsNewDeffered"><blink>Click here to rectify corrections and re-submit<blink></a>
}
&nbsp;<a class="btn btn-primary btn-lg mt-2 " href="/NewCOI/">Go back</a>
@if (!string.IsNullOrEmpty(projCode))
{
<a class="btn btn-success btn-lg mt-2" href="@Url.Action("Payment","NewCOI")">Go to Payment</a>
<a class="btn btn-warning btn-lg mt-2" href="@Url.Action("AdditionalPayment","NewCOI", new { projectCode = projCode })">Pay Additional Amount</a>
}
</td>
</tr>

View File

@ -95,6 +95,21 @@
Invalid Input
</div>
</div>
<div class="col-md-3">
<label for="TypeofOwnership" class="text-black">Type of Ownership</label>
@Html.DropDownList(
"TypeofOwnership",
new List<SelectListItem> {
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" }
)
<div class="invalid-feedback">
Select ownership type
</div>
</div>
<div class="col-md-3" id="incopl">
<label for="validationCustom05" class="text-black">Registration Number</label>
@Html.TextBoxFor(m => m.IncorpCertNo, new { @name = "IncorpCertNo", @class = "form-control mb-4", @id = "IncorpCertNo", @type = "text", @pattern = "^[0-9]+$" ,@maxlength="10" })

View File

@ -92,6 +92,21 @@
Invalid Input
</div>
</div>
<div class="col-md-3">
<label for="TypeofOwnership" class="text-black">Type of Ownership</label>
@Html.DropDownList(
"TypeofOwnership",
new List<SelectListItem> {
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" }
)
<div class="invalid-feedback">
Select ownership type
</div>
</div>
<div class="col-md-3" id="incopl">
<label for="validationCustom05" class="text-black">Registration Number</label>
@Html.TextBoxFor(m => m.IncorpCertNo, new { @name = "LastName", @class = "form-control mb-4", @id = "LastName", @type = "text", @required = "true" })

View File

@ -57,7 +57,7 @@
<div class="row">
<div class="col-md-3">
<label for="validationCustom05" class="text-black">Application No</label>
<font class="form-control"> @Session["ProjectCode"].ToString()</font>
<font class="form-control"> @(Session["ProjectCode"] as string ?? "")</font>
</div>
<div class="col-md-6">
@ -68,12 +68,12 @@
</div>
<div class="col-md-3">
<label for="validationCustom05" class="text-black">Total Amount in @Session["Currency"].ToString()</label>
<font class="form-control"> @Session["Amount"].ToString()</font>
<label for="validationCustom05" class="text-black">Total Amount in @(Session["Currency"] as string ?? "")</label>
<font class="form-control"> @(Session["Amount"] as string ?? "")</font>
</div>
<div class="col-md-12 ">
<label for="validationCustom05" class="text-black">Amount in words</label>
<font class="form-control"> @Session["AmountinWords"].ToString()</font>
<font class="form-control"> @(Session["AmountinWords"] as string ?? "")</font>
</div>
<div class="col-md-4 ">
@ -83,8 +83,8 @@
<br /><br />
<h6 class="text-primary"> Invoice Details</h6>
@(Html.DevExtreme().DataGrid<OSS.Models.ApplicationManager>
()
@(Html.DevExtreme().DataGrid<OSS.Models.ApplicationManager>()
.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
</div>
@{
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)
{
<div class="mt-3">
<a class="btn btn-warning" href="@Url.Action("AdditionalPayment","NewCOI", new { projectCode = additionalProjectCode })">
Pay Additional Amount
</a>
</div>
}
@if (TempData["HidePaidInvoices"] != null)
{
<script type="text/javascript">
$(function () {
var grid = $("#invoiceGrid").dxDataGrid("instance");
if (grid) {
grid.filter(["PaymentStatus", "<>", "Paid"]);
}
});
</script>
}
@if (TempData["AdditionalContext"] != null)
{
<script type="text/javascript">
$(function () {
var grid = $("#invoiceGrid").dxDataGrid("instance");
if (grid) {
// Sort newest first
grid.clearSorting();
grid.columnOption("CreatedDate", "sortOrder", "desc");
// Filter to latest Additional_Amount for current project
var proj = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Session["ProjectCode"] as string ?? ""));
grid.filter([
["ServiceName", "=", "Additional_Amount"],
"and",
["ProjectCode", "=", proj]
]);
// Only one (latest) row
grid.option("paging.pageSize", 1);
grid.refresh();
}
});
</script>
}
</div>
<div class="tab-content">
<div class="statbox widget box box-shadow">

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.