using System;
using System.Linq;
using System.Web.Mvc;
using System.Data.Entity.Validation;
using System.Collections.Generic;
using Neo.Afx.Services.Workflows;
using Neo.LegitimateLicences.Data.Models;
using Neo.Afx.Services.Audits;
using Neo.LegitimateLicences.ApplicationRequest.Models.Database;
using Neo.Afx.Common;
using Neo.LegitimateLicences.Common;
namespace Neo.LegitimateLicences.ApplicationRequest
{
public partial class ApplicationRequestController
{
#region Save
///
/// Save application form data
///
///
///
[HttpPost]
public JsonNetResult Save(ApplicationDetail value)
{
var changes = new List();
var auditDb = new AuditsDatabase();
try
{
if (value.ApplicationDetailID <= 0)
{
changes.Add("New application created");
value.CreatedDate = DateTime.Now;
value.CreatedByID = Profile.UserID;
value.UpdatedDate = DateTime.Now;
value.UpdatedByID = Profile.UserID;
#region Applicant
var appDb = new ApplicationDatabase(); //don't use database context as we need the values refreshed every time
var existingModel = appDb.GetApplicationForm(value.ApplicationDetailID, Profile.UserID);
changes.AddRange(auditDb.GetEntityDifferences(existingModel.Applicant, value.Applicant, "ApplicationDetailID"));
#endregion
Database.Insert(value);
}
else
{
#region Check if can save
var model = GetModel();
if (!model.Ui.canSubmit)
{
throw new Exception("Security error");
}
#endregion
var appDb = new ApplicationDatabase(); //don't use database context as we need the values refreshed every time
var existingModel = appDb.GetApplicationForm(value.ApplicationDetailID, Profile.UserID);
value.UpdatedDate = DateTime.Now;
value.UpdatedByID = Profile.UserID;
#region Preserve provider Payment requirement
// Ensure provider registrations (60/61/62) always require payment.
// Use the persisted ApplicationRequestTypeID (existingModel) in case the posted payload omits it.
if (existingModel != null &&
(existingModel.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistration
|| existingModel.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistrationRenewal
|| existingModel.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistrationAmendConditions))
{
value.IsReceiptRequired = true;
}
#endregion
#region Update ApplicationDetail, ApplicationApplicantDetail, ApplicationPreviousLicenceHolder, ApplicationContractDetail, ApplicationNPTRDetail, ApplicationProxyDetail Details
Database.Update(value);
changes.AddRange(auditDb.GetEntityDifferences(existingModel, value, "ApplicationDetailID"));
Database.Update(value.Applicant);
changes.AddRange(auditDb.GetEntityDifferences(existingModel.Applicant, value.Applicant, "ApplicationDetailID"));
Database.Update(value.PreviousLicenceHolder);
changes.AddRange(auditDb.GetEntityDifferences(existingModel.PreviousLicenceHolder, value.PreviousLicenceHolder, "ApplicationDetailID"));
Database.Update(value.Contract);
changes.AddRange(auditDb.GetEntityDifferences(existingModel.Contract, value.Contract, "ApplicationDetailID"));
// // Compute NPTR totals before save
// if (value != null && value.NPTR != null)
// {
int existingTotal = (value.NPTR.TotalMotorcar ?? 0)
+ (value.NPTR.TotalMinibus ?? 0)
+ (value.NPTR.TotalMidibus ?? 0)
+ (value.NPTR.TotalBus ?? 0)
+ (value.NPTR.TotalOther ?? 0);
int newTotal = (value.NPTR.NewTotalMotorcar ?? 0)
+ (value.NPTR.NewTotalMinibus ?? 0)
+ (value.NPTR.NewTotalMidibus ?? 0)
+ (value.NPTR.NewTotalBus ?? 0)
+ (value.NPTR.NewTotalOther ?? 0);
// Persist computed totals
value.NPTR.TotalVehicles = existingTotal;
value.NPTR.TotalVehiclesToBePurchased = newTotal;
// // Server-side guard: require at least 1 vehicle across Existing or New
// if ((existingTotal + newTotal) <= 0)
// {
// throw new Exception("Validation error: At least one vehicle is required in Existing or New.");
// }
// }
Database.Update(value.NPTR);
changes.AddRange(auditDb.GetEntityDifferences(existingModel.NPTR, value.NPTR, "ApplicationDetailID"));
Database.Update(value.Proxy);
changes.AddRange(auditDb.GetEntityDifferences(existingModel.Proxy, value.Proxy, "ApplicationDetailID"));
#endregion
}
}
catch (Exception ex)
{
#region Error Handling
#region Error Additional Data
Dictionary additionalData = new Dictionary();
additionalData.Add("ApplicationDetailID", value.ApplicationDetailID);
#endregion
string error = ErrorHelper.ProcessError(ex, "ApplicationRequest", "Save", additionalData);
#endregion
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = false,
ErrorCode = "ERROR",
Error =string.Format("Error: {0}", error)
}
};
}
try
{
// Final enforcement: ensure provider apps always require receipt before commit
try
{
var appDbFinal = new ApplicationDatabase();
var persisted = appDbFinal.GetApplicationForm(value.ApplicationDetailID, Profile.UserID);
if (persisted != null &&
(persisted.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistration
|| persisted.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistrationRenewal
|| persisted.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistrationAmendConditions)
&& persisted.IsReceiptRequired == false)
{
persisted.IsReceiptRequired = true;
Database.Update(persisted);
}
}
catch {}
Database.Save();
WorkflowsDatabase workflowsDatabase = new WorkflowsDatabase();
workflowsDatabase.ExecutePostFormSave(value.WorkflowInstanceID.Value, Profile.UserID);
// Post-hook: some workflow post-save logic recalculates rules. Re-enforce for provider types.
try
{
var appDbPost = new ApplicationDatabase();
var persistedPost = appDbPost.GetApplicationForm(value.ApplicationDetailID, Profile.UserID);
if (persistedPost != null &&
(persistedPost.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistration
|| persistedPost.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistrationRenewal
|| persistedPost.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.NPTR_EhailingProviderRegistrationAmendConditions)
&& persistedPost.IsReceiptRequired == false)
{
// Use direct SQL to avoid any EF tracking or concurrency issues
var dbRaw = new LegitimateDatabase();
dbRaw.Context.Database.ExecuteSqlCommand(
"UPDATE App.ApplicationDetails SET IsReceiptRequired = 1 WHERE ApplicationDetailID = @p0 AND ApplicationRequestTypeID IN (60,61,62)",
new System.Data.SqlClient.SqlParameter("@p0", value.ApplicationDetailID));
}
}
catch {}
if (changes.Count > 0)
{
auditDb.WriteEntries((short)AuditSourceEnum.Application, (short)AuditActionEnum.Updated, changes, (short)EntityEnum.ApplicationtDetails, value.ApplicationDetailID, Profile.UserID);
}
}
catch (DbEntityValidationException dbEx)
{
foreach (var validationError in dbEx.EntityValidationErrors.SelectMany(validationErrors => validationErrors.ValidationErrors))
{
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = false,
ErrorCode = "ERROR",
Error =string.Format("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage)
}
};
}
}
catch (Exception ex)
{
#region Error Handling
#region Error Additional Data
Dictionary additionalData = new Dictionary();
additionalData.Add("ApplicationDetailID", value.ApplicationDetailID);
#endregion
string error = ErrorHelper.ProcessError(ex, "ApplicationRequest", "Save", additionalData);
#endregion
if (ex.InnerException != null)
{
if (ex.InnerException.Message.Contains("IX_PrecheckDetailID"))
{
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = false,
ErrorCode = "ERROR",
Error = "The application has already been saved against this pre-check. Please submit the original application instead."
}
};
}
else
{
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = false,
ErrorCode = "ERROR",
Error = string.Format("Error: {0}", error)
}
};
}
}
else {
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = false,
ErrorCode = "ERROR",
Error = string.Format("Error: {0}", error)
}
};
}
}
var formDb = new ApplicationDatabase();
var formData = formDb.GetApplicationForm(value.ApplicationDetailID, Profile.UserID);
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Result = formData,
Success = true
}
};
}
#endregion
#region IssueProviderCertificate
[HttpPost]
public JsonNetResult IssueProviderCertificate(long applicationDetailID)
{
try
{
if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.ApplicationsModule_Adjudication_Console_ApproveDecisions))
{
throw new Exception("#EXPOSE_ERROR#Security error");
}
var appDb = new ApplicationDatabase();
var info = appDb.IssueProviderCertificate(applicationDetailID, Profile.UserID);
// Notification: certificate issued
try
{
var db = new LegitimateDatabase();
var templateId = db.Context.Database.SqlQuery(
"SELECT TOP 1 MessageTemplateID FROM Crm.MessageTemplates WHERE MessageTemplateKey = @p0",
new object[] { "APP_PROVIDER_CERT_ISSUED" }
).FirstOrDefault();
if (templateId > 0)
{
db.Context.Database.ExecuteSqlCommand(
"EXEC Crm.Pr_MessageCreateTemplatedEmails @MessageTemplateID",
new System.Data.SqlClient.SqlParameter("@MessageTemplateID", templateId)
);
}
}
catch { }
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = true,
Result = info
}
};
}
catch (Exception ex)
{
string error = ErrorHelper.ProcessError(ex, "ApplicationRequest", "IssueProviderCertificate");
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = false,
ErrorCode = "ERROR",
Error = error
}
};
}
}
#endregion
#region ReissueProviderCertificate
[HttpPost]
public JsonNetResult ReissueProviderCertificate(long applicationDetailID, string reason)
{
try
{
if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.ApplicationsModule_Adjudication_Console_ApproveDecisions))
{
throw new Exception("#EXPOSE_ERROR#Security error");
}
var appDb = new ApplicationDatabase();
var info = appDb.ReissueProviderCertificate(applicationDetailID, reason, Profile.UserID);
// Notification: certificate reissued
try
{
var db = new LegitimateDatabase();
var templateId = db.Context.Database.SqlQuery(
"SELECT TOP 1 MessageTemplateID FROM Crm.MessageTemplates WHERE MessageTemplateKey = @p0",
new object[] { "APP_PROVIDER_CERT_REISSUED" }
).FirstOrDefault();
if (templateId > 0)
{
db.Context.Database.ExecuteSqlCommand(
"EXEC Crm.Pr_MessageCreateTemplatedEmails @MessageTemplateID",
new System.Data.SqlClient.SqlParameter("@MessageTemplateID", templateId)
);
}
}
catch { }
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = true,
Result = info
}
};
}
catch (Exception ex)
{
string error = ErrorHelper.ProcessError(ex, "ApplicationRequest", "ReissueProviderCertificate");
return new JsonNetResult()
{
Data = new JsonBaseResult()
{
Success = false,
ErrorCode = "ERROR",
Error = error
}
};
}
}
#endregion
}
}