This commit is contained in:
mustafa.juma 2025-11-16 12:56:51 +03:00
parent 19868f4954
commit 85bcc58499
9 changed files with 126 additions and 106 deletions

Binary file not shown.

View File

@ -1900,6 +1900,41 @@ namespace OSS.Controllers
}
private void EnsurePaymentSessionDefaults(string currencyIfUnset = "")
{
if (Session["Currency"] == null) Session["Currency"] = currencyIfUnset;
if (Session["Amount"] == null) Session["Amount"] = "";
if (Session["AmountinWords"] == null) Session["AmountinWords"] = "";
}
private bool TrySaveInvoice(OSSDBContext ctx, ApplicationManager inv, CompanyProfileExternal company, out string error)
{
error = null;
try
{
ctx.ApplicationManagers.Add(inv);
if (company != null)
{
company.CleaningStatus = "Submitted";
}
ctx.SaveChanges();
return true;
}
catch (System.Data.Entity.Validation.DbEntityValidationException ex)
{
var msgs = ex.EntityValidationErrors
.SelectMany(e => e.ValidationErrors)
.Select(e => e.PropertyName + ": " + e.ErrorMessage);
error = "Validation failed: " + string.Join("; ", msgs);
return false;
}
catch (Exception ex)
{
error = ex.Message;
return false;
}
}
public ActionResult Payment(ApplicationManager model)
{
try
@ -1912,12 +1947,56 @@ namespace OSS.Controllers
if (string.IsNullOrWhiteSpace(model?.Currency))
{
ViewBag.Error = "Currency is required.";
EnsurePaymentSessionDefaults();
return View("Payment");
}
var Username = Session["CompanyEmail"].ToString();
var ProjectCode = Session["ProjectCode"].ToString();
var serviceName = (Session["ServiceName"] as string) ?? string.Empty;
var serviceName = ((Session["ServiceName"] as string) ?? string.Empty).Trim();
// Normalize service name to match tblService keys (e.g., "Application for New Certificate" -> "New")
var rawService = serviceName;
if (rawService.IndexOf("new", StringComparison.OrdinalIgnoreCase) >= 0)
{
serviceName = "New";
}
else if (rawService.IndexOf("expansion", StringComparison.OrdinalIgnoreCase) >= 0)
{
serviceName = "Expansion";
}
// Enforce TZS only as requested
model.Currency = "TZS";
// Pre-compute amount from tblService (before early returns), single-row fetch (no iteration)
var getPDetailsEarly = myContext.ProjectProfilesExternal.SingleOrDefault(t => t.ProjectCode == ProjectCode);
if (getPDetailsEarly != null)
{
var ownershipRawEarly = (getPDetailsEarly.TypeofOwnership ?? "").Trim();
var isLocalEarly = ownershipRawEarly.Equals("Local", StringComparison.OrdinalIgnoreCase);
var isForeignOrMixedEarly =
ownershipRawEarly.Equals("Foreign", StringComparison.OrdinalIgnoreCase) ||
ownershipRawEarly.Equals("JV", StringComparison.OrdinalIgnoreCase) ||
ownershipRawEarly.Equals("Mixed", StringComparison.OrdinalIgnoreCase) ||
ownershipRawEarly.Equals("Mixed (Foreigners & Tanzanians)", StringComparison.OrdinalIgnoreCase);
var serviceKeyEarly = serviceName;
if (!isLocalEarly && isForeignOrMixedEarly) serviceKeyEarly = serviceName + "_Foreign";
var feeRow = myContext.ServiceFees.FirstOrDefault(s =>
s.ServiceName == serviceKeyEarly);
if (feeRow != null && feeRow.Fee.HasValue && feeRow.Fee.Value > 0)
{
TempData["PreAmountTZS"] = feeRow.Fee.Value.ToString("0");
}
else
{
TempData["PreAmountTZS"] = null; // force UI error downstream if not configured
}
}
var checkIfExist = myContext.ApplicationManagers.SingleOrDefault(t => t.ProjectCode == ProjectCode);
var checkIfCompany = myContext.CompanyProfileExternal.SingleOrDefault(t => t.AddedBy == Username);
@ -1928,6 +2007,16 @@ namespace OSS.Controllers
if (getPDetails == null)
{
ViewBag.Error = "Project details not found.";
EnsurePaymentSessionDefaults();
return View("Payment");
}
// Only New/Expansion supported in this TZS ownership block
if (!(serviceName.Equals("New", StringComparison.OrdinalIgnoreCase) ||
serviceName.Equals("Expansion", StringComparison.OrdinalIgnoreCase)))
{
ViewBag.Error = $"Unsupported ServiceName '{serviceName}'. Expected New/Expansion.";
EnsurePaymentSessionDefaults();
return View("Payment");
}
@ -1951,116 +2040,46 @@ namespace OSS.Controllers
inv.Station = model.Station;
inv.CompanyTIN = Session["CompanyTIN"] != null ? Session["CompanyTIN"].ToString() : null;
// Determine service name and try dynamic fee from tblService (case-insensitive)
var svcFee = myContext.ServiceFees
.AsEnumerable()
.FirstOrDefault(s =>
s.Status == 1 &&
string.Equals(s.ServiceName, serviceName, StringComparison.OrdinalIgnoreCase) &&
string.Equals(s.Currency, model.Currency, StringComparison.OrdinalIgnoreCase));
// Ownership-based TZS pricing for New and Expansion only (drive from tblService)
if (string.Equals(model.Currency, "TZS", StringComparison.OrdinalIgnoreCase)
&& (serviceName.Equals("New", StringComparison.OrdinalIgnoreCase) || serviceName.Equals("Expansion", StringComparison.OrdinalIgnoreCase)))
// Use precomputed amount from tblService or fallback (saved in TempData earlier)
decimal amountToUse;
if (TempData["PreAmountTZS"] != null && decimal.TryParse(TempData["PreAmountTZS"].ToString(), out amountToUse))
{
var ownership = (getPDetails.TypeofOwnership ?? "").Trim();
// Pick service key based on ownership
var serviceKey = serviceName;
if (!ownership.Equals("Local", StringComparison.OrdinalIgnoreCase))
{
serviceKey = serviceName + "_Foreign";
}
// Try to fetch fee from tblService, case-insensitive
var ownershipFee = myContext.ServiceFees
.AsEnumerable()
.FirstOrDefault(s =>
s.Status == 1 &&
string.Equals(s.ServiceName, serviceKey, StringComparison.OrdinalIgnoreCase) &&
s.Currency.Equals("TZS", StringComparison.OrdinalIgnoreCase));
if (ownershipFee?.Fee == null)
{
ViewBag.Error = $"Configured fee not found for '{serviceKey}' in TZS.";
return View("Payment");
}
var amountTzs = ownershipFee.Fee.Value;
inv.Amount = amountTzs;
Session["Amount"] = amountTzs.ToString("0");
Session["AmountinWords"] = CurrencyUtils.ToWords(amountTzs) + " Tanzanian Shillings";
inv.Amount = amountToUse;
Session["Amount"] = amountToUse.ToString("0");
Session["AmountinWords"] = CurrencyUtils.ToWords(amountToUse) + " Tanzanian Shillings";
Session["Currency"] = model.Currency;
myContext.ApplicationManagers.Add(inv);
if (checkIfCompany != null)
{
checkIfCompany.CleaningStatus = "Submitted";
}
myContext.SaveChanges();
if (serviceName.Equals("Expansion", StringComparison.OrdinalIgnoreCase))
{
return View("PaymentExpansion");
}
return View("Payment");
}
// If not TZS New/Expansion, use tblService if available
if (svcFee?.Fee != null)
{
var fee = svcFee.Fee.Value;
inv.Amount = fee;
Session["Amount"] = fee.ToString("0.##");
Session["AmountinWords"] = CurrencyUtils.ToWords(fee) + " " + model.Currency;
Session["Currency"] = model.Currency;
myContext.ApplicationManagers.Add(inv);
if (checkIfCompany != null)
{
checkIfCompany.CleaningStatus = "Submitted";
}
myContext.SaveChanges();
if (serviceName.Equals("Expansion", StringComparison.OrdinalIgnoreCase))
{
return View("PaymentExpansion");
}
return View("Payment");
}
// Fallback: existing COIPrice + ExchangeRate for New
ExchangeRate exchangeRate = myContext.ExchangeRates.SingleOrDefault(t => t.Currency == model.Currency);
COIPrice coiPrice = myContext.COIPrices.SingleOrDefault(t => t.ApplicationType == "New");
if (exchangeRate != null && coiPrice != null)
{
decimal Price = coiPrice.Price * exchangeRate.Rate;
string priceStr = Price.ToString();
priceStr = priceStr.Contains(".") ? priceStr.TrimEnd('0').TrimEnd('.') : priceStr;
inv.Amount = Price;
Session["Amount"] = priceStr;
Session["AmountinWords"] = CurrencyUtils.ToWords(Price) + " " + exchangeRate.CurrencyDesc;
Session["Currency"] = model.Currency;
myContext.ApplicationManagers.Add(inv);
if (checkIfCompany != null)
{
checkIfCompany.CleaningStatus = "Submitted";
}
myContext.SaveChanges();
if (serviceName.Equals("Expansion", StringComparison.OrdinalIgnoreCase))
{
return View("PaymentExpansion");
}
return View("Payment");
}
else
{
ViewBag.Error = "Unable to determine fee for the selected currency.";
var ownershipForKey = getPDetails.TypeofOwnership != null && getPDetails.TypeofOwnership.Equals("Local", StringComparison.OrdinalIgnoreCase)
? serviceName
: serviceName + "_Foreign";
var errMsg = $"Fee not configured in tblService for ServiceName='{ownershipForKey}', Currency='TZS'.";
TempData["PaymentError"] = errMsg;
ViewBag.Error = errMsg;
EnsurePaymentSessionDefaults("TZS");
// Show the appropriate payment page based on service
if (serviceName.Equals("Expansion", StringComparison.OrdinalIgnoreCase))
{
return View("PaymentExpansion");
}
return View("Payment");
}
string saveErrX;
if (!TrySaveInvoice(myContext, inv, checkIfCompany, out saveErrX))
{
ViewBag.Error = "Could not save invoice. " + saveErrX;
EnsurePaymentSessionDefaults(model.Currency);
return View("Payment");
}
if (serviceName.Equals("Expansion", StringComparison.OrdinalIgnoreCase))
{
return View("PaymentExpansion");
}
return View("Payment");
}
else
{
@ -2074,6 +2093,7 @@ namespace OSS.Controllers
catch (Exception ex)
{
ViewBag.Error = "Error processing payment. " + ex.Message;
EnsurePaymentSessionDefaults();
return View("Payment");
}
}

View File

@ -10,9 +10,9 @@ namespace OSS.Models
public class ServiceFee
{
[Key]
public int ServiID { get; set; }
public long ServiID { get; set; }
public string ServiceName { get; set; }
public int Status { get; set; }
public string Status { get; set; }
public decimal? Fee { get; set; }
public string GFSCode { get; set; }
public string Currency { get; set; }

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.