using Neo.Afx.Security; using Neo.LegitimateLicences.LicenceIssueRequest.Models.Database; using Neo.LegitimateLicences.Common; using Neo.LegitimateLicences.Common.Helpers; using Neo.LegitimateLicences.Data.Models; using System; using System.Collections.Generic; using System.Linq; using System.Web.Mvc; using Xceed.Words.NET; using System.Drawing; using Neo.Afx.Services.Documents; using System.IO; using Neo.Afx.Common; using System.Reflection; using System.Xml.Linq; using Neo.LegitimateLicences.ApplicationRequest.Models.Database; using LicenceIssueDetail = Neo.LegitimateLicences.LicenceIssueRequest.Models.Database.LicenceIssueDetail; namespace Neo.LegitimateLicences.LicenceIssueRequest { public partial class LicenceIssueRequestController { #region Printing /// /// Return printing view /// /// public ActionResult Printing() { var itemId = WebHelper.ItemID; var model = new LicenceIssueRequestPrintingModel { UserSecurables = (Profile.Securables != null) ? Profile.Securables.ToList() : new List() }; var db = new LicenceIssueDatabase(); var licenceIssue = db.GetLicenceIssueForm(itemId, Profile.UserID); model.Data = licenceIssue; model.WorkflowInstance = WorkflowHelper.GetWorkflowInstanceView(WebHelper.EntityID, WebHelper.ItemID, Profile.UserID); model.ExceptionCount = db.GetLicenceExceptions(licenceIssue.VerifiedLicenceID, Profile.UserID).Count; return View("Printing", model); } #endregion #region StartPrintout /// /// StartPrintout /// /// /// /// /// /// /// /// /// [HttpPost] public JsonNetResult StartPrintout(int entityID, long itemID, short printoutTypeID, string certificateNumber, bool isReprint, string reprintReason, bool isTestPrint ) { try { var database = new LegitimateDatabase(); if (isTestPrint) { database.WriteAuditEntry((int)Profile.UserID, "Application", "LIR Test Print", "", false, false, "licence", itemID); } else { if (!isReprint) { if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_PrintLicence_Actual) && !SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_PrintLicence_Test)) { throw new Exception("#EXPOSE_ERROR#Security error"); } // Stamp DateOfIssue NOW so the printed paper shows the correct issue date. // The desktop client fetches the printout payload (GetPrintoutData) AFTER this // call returns, so the stamp has to happen here — stamping later in MarkAsPrinted // would leave Valid From blank on the paper. Idempotent: no-op when already set // (failed prior attempt) and blocks when DateOfExpiry hasn't been captured. // // For licence printouts (entityID 1011 = OperatingLicences) the itemID IS the // LicenceID — same convention MarkAsPrinted uses when calling UpdateOperatingLicence. // Skip for other entity types (accreditations etc.) which have their own date flow. if (entityID == (int)EntityEnum.OperatingLicences) { string stampErrorMessage; database.StampDateOfIssueForFirstPrint(itemID, out stampErrorMessage); if (!string.IsNullOrEmpty(stampErrorMessage)) { throw new Exception("#EXPOSE_ERROR#" + stampErrorMessage); } } } else { if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_RePrintLicence)) { throw new Exception("#EXPOSE_ERROR#Security error"); } } } var verificationToken = database.CreateVerifiedPrintout(entityID, itemID, printoutTypeID, Profile.UserID, isReprint, reprintReason, isTestPrint, certificateNumber); return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "", Result = new { PrintoutToken = verificationToken } } }; } catch(Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary(); additionalData.Add("entityID", entityID); additionalData.Add("itemID", itemID); additionalData.Add("printoutTypeID", printoutTypeID); additionalData.Add("certificateNumber", certificateNumber); additionalData.Add("isReprint", isReprint); additionalData.Add("reprintReason", reprintReason); additionalData.Add("isTestPrint", isTestPrint); #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "StartPrintout", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; } } #endregion #region StartPrintout /// /// StartPrintout /// /// /// /// /// /// /// /// /// [HttpPost] public JsonNetResult StartAnnexurePrintout(int entityID, long itemID, short printoutTypeID) { try { var database = new LegitimateDatabase(); if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_RePrintLicence)) { throw new Exception("#EXPOSE_ERROR#Security error"); } var verificationToken = database.CreateVerifiedPrintout(entityID, itemID, printoutTypeID, Profile.UserID, false, null, false, null); return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "", Result = new { PrintoutToken = verificationToken } } }; } catch (Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary { { "entityID", entityID }, { "itemID", itemID }, { "printoutTypeID", printoutTypeID } }; #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "StartPrintout", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; } } #endregion #region StartDecalPrintout /// /// Print licence record /// /// /// /// /// /// /// /// /// [HttpPost] public JsonNetResult StartDecalPrintout(int entityID, long itemID, short printoutTypeID, string certificateNumber, bool isReprint, string reprintReason, bool isTestPrint ) { try { var database = new LegitimateDatabase(); if (!isReprint) { if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_PrintLicence_Actual) && !SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_PrintLicence_Test)) { throw new Exception("#EXPOSE_ERROR#Security error"); } } else { if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_RePrintLicence)) { throw new Exception("#EXPOSE_ERROR#Security error"); } } var verificationToken = database.CreateVerifiedPrintout(entityID, itemID, printoutTypeID, Profile.UserID, isReprint, reprintReason, isTestPrint, certificateNumber); return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "", Result = new { PrintoutToken = verificationToken } } }; } catch (Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary(); additionalData.Add("entityID", entityID); additionalData.Add("itemID", itemID); additionalData.Add("printoutTypeID", printoutTypeID); additionalData.Add("certificateNumber", certificateNumber); additionalData.Add("isReprint", isReprint); additionalData.Add("reprintReason", reprintReason); additionalData.Add("isTestPrint", isTestPrint); #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "StartDecalPrintout", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; } } #endregion #region IssueWithoutPrint //[HttpPost] //public JsonResult IssueWithoutPrint(long licenceID, string reason) //{ // var database = new LegitimateDatabase(); // var errorMessage = ""; // if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_IssueWithoutPrint)) // { // throw new Exception("Security error"); // } // try // { // database.IssueLicenceWithoutPrint(licenceID, reason, Profile.UserID); // } // catch (Exception ex) // { // errorMessage = database.GetInnermostMessage(ex); // } // var result = new // { // ErrorMessage = errorMessage // }; // return Json(result, JsonSerializerOptions.None); //} #endregion #region PrintAnnexure [HttpGet] public FileResult PrintAnnexure(long licenceIssueDetailID, long licenceId) { if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), Common.SecurableEnum.OperatingLicencesModule_Issuing_LicencesAwaitingVerificationandPrinting)) { throw new Exception("Security error"); } var db = new LegitimateDatabase(); var licDb = new LicenceIssueDatabase(); var docDb = new DocumentsDatabase(); try { var officeLocationDocuments = db.GetOfficeLocationSetupDocumentTemplate(Profile.OfficeLocationID.Value); var licenceIssueDetail = db.GetLicenceIssueDetailsReport(licenceIssueDetailID, Profile.UserID); var applicationDetail = db.GetApplicationDetail_ViewOnly(licenceIssueDetail.ApplicationDetailID); var lirRoutes = db.GetVerifiedLicenceRoutes(licenceId, Profile.UserID); var licenceServices = db.GetVerifiedLicenceServiceDetails(licenceId); var licenceVehicle = licDb.GetLicenceIssueForm(licenceIssueDetailID, Profile.UserID); // Determine if this is a Temporary (Special) licence so that we can // prefer the route details captured on the Temporary Licence form // instead of the generic verified route data when building Annexure 1. var isTemporarySpecial = applicationDetail != null && applicationDetail.ApplicationRequestTypeID == (short)ApplicationRequestTypeEnum.TemporarySpecialLicence; // For Temporary Special licences, load the application-side route // details for the application so that Annexure 1 can use the captured // RouteOrigin, RouteDestination and RouteDescription values. List temporaryLicenceRoutes = null; if (isTemporarySpecial) { var appDb = new ApplicationDatabase(); // This call is already used by the Application Request module to // populate the Temporary Special Licence UI and returns the same // RouteOrigin/RouteDestination/RouteDescription values the user // sees when capturing the Temporary Licence. temporaryLicenceRoutes = appDb.GetApplicationLicencesRouteDetails(licenceIssueDetail.ApplicationDetailID, Profile.UserID); } #region Create Blank Document With Footer var verificationToken = db.CreateVerifiedPrintout((short)EntityEnum.LicenceIssueDetails, licenceIssueDetailID, (short)PrintoutTypeEnum.OperatingLicenceAnnexure, Profile.UserID, false, "", false, ""); var verificationSiteUrl = db.GetSettingValue("VerificationSiteUrl"); string footerUrl = "To verify document browse to " + verificationSiteUrl + " , Verification Token: " + verificationToken; string footerOlNumber = licenceIssueDetail.OperatingLicenceNumber; if (licenceIssueDetail.CertificateNumber != null) { footerOlNumber = footerOlNumber + " " + licenceIssueDetail.CertificateNumber; } var doc = DocX.Create(""); doc.AddFooters(); #region Footer Footer footer = doc.Footers.Odd; Paragraph pOl = footer.InsertParagraph(); pOl.Append(footerOlNumber) .Font("Arial") .FontSize(9) .Color(Color.Black) .Bold(); pOl.Alignment = Alignment.center; // Verification URL footer line hidden from the printout per business request. // The verification token is still generated above (CreateVerifiedPrintout) so // the licence remains verifiable via the verification site; only its display // in the footer is suppressed. //Paragraph pUrl = footer.InsertParagraph(); //pUrl.Append(footerUrl) //.Font("Arial") //.FontSize(9) //.Color(Color.Black) //.Bold(); //pUrl.Alignment = Alignment.center; footer.PageNumbers = true; #endregion #endregion #region Annexure 1 Paragraph pAnnexure1 = doc.InsertParagraph(); // Append some text and add formatting. pAnnexure1.Append("Annexure 1 \n") .Font("Arial") .FontSize(12) .Color(Color.Black) .UnderlineStyle(UnderlineStyle.singleLine) .Bold(); // For Temporary (Special) licences, prefer the route details captured // on the application (RouteOrigin, RouteDestination, RouteDescription). if (isTemporarySpecial && temporaryLicenceRoutes != null && temporaryLicenceRoutes.Any()) { foreach (var route in temporaryLicenceRoutes) { // get the linked service type var serviceType = db.GetServiceTypes() .Where(x => x.ServiceTypeID == route.ServiceTypeID) .Select(x => x.Description) .FirstOrDefault(); var table = doc.AddTable(7, 2); table.Alignment = Alignment.left; table.SetColumnWidth(0, 2500); table.SetColumnWidth(1, 6500); // Added below Service Type [DS20241203] table.Rows[0].Cells[0].Paragraphs.First().Append("Service Type:").Font("Arial").FontSize(11).Bold(); table.Rows[0].Cells[1].Paragraphs.First().Append(serviceType).Font("Arial").FontSize(10); table.Rows[1].Cells[0].Paragraphs.First().Append("Operating Licence Number:").Font("Arial").FontSize(11).Bold(); table.Rows[1].Cells[1].Paragraphs.First().Append(footerOlNumber).Font("Arial").FontSize(10); table.Rows[2].Cells[0].Paragraphs.First().Append("National Route Code:").Font("Arial").FontSize(11).Bold(); table.Rows[2].Cells[1].Paragraphs.First().Append(route.NationalRouteNumber).Font("Arial").FontSize(10); table.Rows[3].Cells[0].Paragraphs.First().Append("Board Route Number:").Font("Arial").FontSize(11).Bold(); table.Rows[3].Cells[1].Paragraphs.First().Append(route.BoardRouteNumber).Font("Arial").FontSize(10); table.Rows[4].Cells[0].Paragraphs.First().Append("Origin:").Font("Arial").FontSize(11).Bold(); table.Rows[4].Cells[1].Paragraphs.First().Append(route.RouteOrigin).Font("Arial").FontSize(10); table.Rows[5].Cells[0].Paragraphs.First().Append("Destination:").Font("Arial").FontSize(11).Bold(); table.Rows[5].Cells[1].Paragraphs.First().Append(route.RouteDestination).Font("Arial").FontSize(10); table.Rows[6].Cells[0].Paragraphs.First().Append("Description:").Font("Arial").FontSize(11).Bold(); table.Rows[6].Cells[1].Paragraphs.First().Append(route.RouteDescription).Font("Arial").FontSize(10); var blankBorder = new Border(BorderStyle.Tcbs_none, 0, 0, Color.White); table.SetBorder(TableBorderType.Bottom, blankBorder); table.SetBorder(TableBorderType.Top, blankBorder); table.SetBorder(TableBorderType.Left, blankBorder); table.SetBorder(TableBorderType.Right, blankBorder); table.SetBorder(TableBorderType.InsideV, blankBorder); table.SetBorder(TableBorderType.InsideH, blankBorder); doc.InsertTable(table); if (route.TimeTableDocumentID.HasValue) { try { doc.InsertSectionPageBreak(); var docDatabase = new DocumentsDatabase(); var timeTableDocument = docDatabase.GetDocumentObject(route.TimeTableDocumentID.Value); Stream timeTableStream = new MemoryStream(timeTableDocument.Content); var templateTimeTableDoc = DocX.Load(timeTableStream); this.NormaliseAnnexureFont(templateTimeTableDoc); this.ReplaceText(templateTimeTableDoc, licenceIssueDetail, applicationDetail, licenceVehicle); doc.InsertDocument(templateTimeTableDoc, true); } catch { throw new Exception("Error loading timetable annexure for route " + route.NationalRouteNumber + ". Please ensure that the file is uploaded as a .docx file"); } } if (route.FareScheduleDocumentID.HasValue) { try { doc.InsertSectionPageBreak(); var docDatabase = new DocumentsDatabase(); var fareScheduleDocument = docDatabase.GetDocumentObject(route.FareScheduleDocumentID.Value); Stream fareScheduleStream = new MemoryStream(fareScheduleDocument.Content); var fareScheduleDoc = DocX.Load(fareScheduleStream); this.NormaliseAnnexureFont(fareScheduleDoc); doc.InsertDocument(fareScheduleDoc, true); } catch { throw new Exception("Error loading fare schedule annexure for route " + route.NationalRouteNumber + ". Please ensure that the file is uploaded as a .docx file"); } } } } else { // Fallback (all non-temporary licences, or if no application-side // routes can be resolved): use the existing verified licence routes. foreach (var route in lirRoutes) { // get the linked service type var serviceType = db.GetServiceTypes().Where(x => x.ServiceTypeID == route.ServiceTypeID).Select(x => x.Description).FirstOrDefault(); var table = doc.AddTable(7, 2); table.Alignment = Alignment.left; table.SetColumnWidth(0, 2500); table.SetColumnWidth(1, 6500); // Added below Service Type [DS20241203] table.Rows[0].Cells[0].Paragraphs.First().Append("Service Type:").Font("Arial").FontSize(11).Bold(); table.Rows[0].Cells[1].Paragraphs.First().Append(serviceType).Font("Arial").FontSize(10); table.Rows[1].Cells[0].Paragraphs.First().Append("Operating Licence Number:").Font("Arial").FontSize(11).Bold(); table.Rows[1].Cells[1].Paragraphs.First().Append(footerOlNumber).Font("Arial").FontSize(10); table.Rows[2].Cells[0].Paragraphs.First().Append("National Route Code:").Font("Arial").FontSize(11).Bold(); table.Rows[2].Cells[1].Paragraphs.First().Append(route.NationalRouteNumber).Font("Arial").FontSize(10); table.Rows[3].Cells[0].Paragraphs.First().Append("Board Route Number:").Font("Arial").FontSize(11).Bold(); table.Rows[3].Cells[1].Paragraphs.First().Append(route.BoardRouteNumber).Font("Arial").FontSize(10); table.Rows[4].Cells[0].Paragraphs.First().Append("Origin:").Font("Arial").FontSize(11).Bold(); table.Rows[4].Cells[1].Paragraphs.First().Append(route.OriginDescription).Font("Arial").FontSize(10); table.Rows[5].Cells[0].Paragraphs.First().Append("Destination:").Font("Arial").FontSize(11).Bold(); table.Rows[5].Cells[1].Paragraphs.First().Append(route.DestinationDescription).Font("Arial").FontSize(10); table.Rows[6].Cells[0].Paragraphs.First().Append("Description:").Font("Arial").FontSize(11).Bold(); table.Rows[6].Cells[1].Paragraphs.First().Append(route.Description).Font("Arial").FontSize(10); var blankBorder = new Border(BorderStyle.Tcbs_none, 0, 0, Color.White); table.SetBorder(TableBorderType.Bottom, blankBorder); table.SetBorder(TableBorderType.Top, blankBorder); table.SetBorder(TableBorderType.Left, blankBorder); table.SetBorder(TableBorderType.Right, blankBorder); table.SetBorder(TableBorderType.InsideV, blankBorder); table.SetBorder(TableBorderType.InsideH, blankBorder); doc.InsertTable(table); if (route.TimeTableDocumentID.HasValue) { try { doc.InsertSectionPageBreak(); var docDatabase = new DocumentsDatabase(); var timeTableDocument = docDatabase.GetDocumentObject(route.TimeTableDocumentID.Value); Stream timeTableStream = new MemoryStream(timeTableDocument.Content); var templateTimeTableDoc = DocX.Load(timeTableStream); this.NormaliseAnnexureFont(templateTimeTableDoc); this.ReplaceText(templateTimeTableDoc, licenceIssueDetail, applicationDetail, licenceVehicle); doc.InsertDocument(templateTimeTableDoc, true); } catch { throw new Exception("Error loading timetable annexure for route " + route.NationalRouteNumber + ". Please ensure that the file is uploaded as a .docx file"); } } if (route.FareScheduleDocumentID.HasValue) { try { doc.InsertSectionPageBreak(); var docDatabase = new DocumentsDatabase(); var fareScheduleDocument = docDatabase.GetDocumentObject(route.FareScheduleDocumentID.Value); Stream fareScheduleStream = new MemoryStream(fareScheduleDocument.Content); var fareScheduleDoc = DocX.Load(fareScheduleStream); this.NormaliseAnnexureFont(fareScheduleDoc); doc.InsertDocument(fareScheduleDoc, true); } catch { throw new Exception("Error loading fare schedule annexure for route " + route.NationalRouteNumber + ". Please ensure that the file is uploaded as a .docx file"); } } } } doc.InsertSectionPageBreak(); #endregion #region Annexure 2 // Insert a Paragraph into this document. Paragraph p = doc.InsertParagraph(); // Append some text and add formatting. p.Append("Annexure 2 \n") .Font("Arial") .FontSize(12) .Color(Color.Black) .UnderlineStyle(UnderlineStyle.singleLine) .Bold(); bool isFirstAnnexure2 = true; foreach (var service in licenceServices) { var mapping = db.SearchDivisionTypeAnnexureMapping(service.ServiceTypeID, licenceVehicle.Vehicle.VehicleTypeID, Profile.UserID); if (mapping != null && mapping.AnnexureDocumentID != null) { if (!isFirstAnnexure2) doc.InsertSectionPageBreak(); var templateFile = docDb.GetDocumentObject(mapping.AnnexureDocumentID.Value); using (var stream = new MemoryStream(templateFile.Content)) { var TemplateAnnexure2 = DocX.Load(stream); this.NormaliseAnnexureFont(TemplateAnnexure2); this.ReplaceText(TemplateAnnexure2, licenceIssueDetail, applicationDetail, licenceVehicle); doc.InsertDocument(TemplateAnnexure2, true); } isFirstAnnexure2 = false; } } //if (licenceIssueDetail.ShowTouristAnnexure == 1) //{ // string fileLicenceConditionsTourist = Server.MapPath(@"~\Content\Annexure Documents\" + templateFolder + @"\LicenceConditionsTouristService.docx"); // var TemplateLicenceConditionsTourist = DocX.Load(fileLicenceConditionsTourist); // doc.InsertDocument(TemplateLicenceConditionsTourist, true); // //doc.InsertSectionPageBreak(); //} //if (licenceIssueDetail.ShowBusAnnexure == 1) //{ // string fileLicenceConditionsBuses = Server.MapPath(@"~\Content\Annexure Documents\" + templateFolder + @"\LicenceConditionsBuses.docx"); // var TemplateLicenceConditionsBuses = DocX.Load(fileLicenceConditionsBuses); // doc.InsertDocument(TemplateLicenceConditionsBuses, true); // doc.InsertSectionPageBreak(); //} //if (licenceIssueDetail.ShowMidiBusAnnexure == 1) //{ // string fileLicenceConditionsMidiBus = Server.MapPath(@"~\Content\Annexure Documents\" + templateFolder + @"\LicenceConditionsMidiBus.docx"); // var TemplateLicenceConditionsMidiBus = DocX.Load(fileLicenceConditionsMidiBus); // doc.InsertDocument(TemplateLicenceConditionsMidiBus, true); // doc.InsertSectionPageBreak(); //} //if (licenceIssueDetail.ShowMinibusAnnexure == 1) //{ // string fileLicenceConditionsMinibu = Server.MapPath(@"~\Content\Annexure Documents\" + templateFolder + @"\LicenceConditionsMinibus.docx"); // var TemplateLicenceConditionsMinibu = DocX.Load(fileLicenceConditionsMinibu); // doc.InsertDocument(TemplateLicenceConditionsMinibu, true); // doc.InsertSectionPageBreak(); //} //if (licenceIssueDetail.ShowMeteredTaxiAnnexure == 1) //{ // string fileLicenceConditionsMeteredTaxi = Server.MapPath(@"~\Content\Annexure Documents\" + templateFolder + @"\LicenceConditionsMeteredTaxi.docx"); // var TemplateLicenceConditionsMeteredTaxi = DocX.Load(fileLicenceConditionsMeteredTaxi); // doc.InsertDocument(TemplateLicenceConditionsMeteredTaxi, true); // doc.InsertSectionPageBreak(); //} //if (licenceIssueDetail.ShowScholarAnnexure == 1) //{ // string fileLicenceConditionsScholarTransport = Server.MapPath(@"~\Content\Annexure Documents\" + templateFolder + @"\LicenceConditionsScholarTransport.docx"); // var TemplateLicenceConditionsScholarTransport = DocX.Load(fileLicenceConditionsScholarTransport); // doc.InsertDocument(TemplateLicenceConditionsScholarTransport, true); // doc.InsertSectionPageBreak(); //} //if (licenceIssueDetail.ShowStaffServiceAnnexure == 1) //{ // string fileLicenceConditionsStaffService = Server.MapPath(@"~\Content\Annexure Documents\" + templateFolder + @"\LicenceConditionsStaffService.docx"); // var TemplateLicenceConditionsStaffServices = DocX.Load(fileLicenceConditionsStaffService); // doc.InsertDocument(TemplateLicenceConditionsStaffServices, true); // doc.InsertSectionPageBreak(); //} #endregion #region Annexure 3 if (applicationDetail.AdjudicationDetailID != null) { if (officeLocationDocuments.LicenceAnnexure_AdjudicationPanelDocumentID != null) { doc.InsertSectionPageBreak(); Paragraph p3 = doc.InsertParagraph(); // Append some text and add formatting. p3.Append("Annexure 3 \n") .Font("Arial") .FontSize(12) .Color(Color.Black) .UnderlineStyle(UnderlineStyle.singleLine) .Bold(); var templateFile = docDb.GetDocumentObject(officeLocationDocuments.LicenceAnnexure_AdjudicationPanelDocumentID.Value); using (var stream = new MemoryStream(templateFile.Content)) { var TemplateAnnexure3 = DocX.Load(stream); this.ReplaceText(TemplateAnnexure3, licenceIssueDetail, applicationDetail, licenceVehicle); doc.InsertDocument(TemplateAnnexure3, true); } } } #endregion var populatedFileStream = new MemoryStream(); doc.SaveAs(populatedFileStream); var generatedDocumentBytes = new byte[0]; using (var srv = new DevExpress.XtraRichEdit.RichEditDocumentServer()) { DevExpress.XtraRichEdit.API.Native.Document document = srv.Document; document.LoadDocument(populatedFileStream); using (var generatedocumentStream = new MemoryStream()) { var pdfOptions = new DevExpress.XtraPrinting.PdfExportOptions(); pdfOptions.DocumentOptions.Author = Profile.FullName; pdfOptions.Compressed = false; pdfOptions.ImageQuality = DevExpress.XtraPrinting.PdfJpegImageQuality.Highest; srv.ExportToPdf(generatedocumentStream, pdfOptions); generatedDocumentBytes = new byte[generatedocumentStream.Length]; generatedDocumentBytes = generatedocumentStream.ToArray(); } } return File(generatedDocumentBytes, "application/pdf", "APP" + licenceIssueDetail.ApplicationDetailID + "_" + licenceIssueDetail.CertificateNumber + ".pdf"); } catch (Exception ex) { ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "PrintAnnexure", null); return null; } } #endregion #region GetStationeryNumber /// /// Get Next Available Stationery Number /// /// [HttpPost] public JsonNetResult GetStationeryNumber() { try { if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), Common.SecurableEnum.OperatingLicencesModule_Issuing_LicencesAwaitingVerificationandPrinting)) { throw new Exception("#EXPOSE_ERROR#Security error"); } var db = new LegitimateDatabase(); Stationery stationery = new Stationery(); stationery = db.GetIssuedToStationery(Profile.UserID); if (stationery == null) { throw new Exception("#EXPOSE_ERROR#No issued stationary found for " + Profile.FullName); } return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "", Result = new { stationery = stationery } } }; } catch (Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary(); #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "GetStationeryNumber", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; } } #endregion #region MarkAsPrinted /// /// Mark licence as print /// /// /// /// /// /// /// /// /// /// /// [HttpPost] public JsonNetResult MarkAsPrinted(int entityID, long itemID, short printoutTypeID, string certificateNumber, bool isReprint, string reprintReason, bool isTestPrint, string verificationToken, long stationeryID) { #region not working /*try { var database = new LegitimateDatabase(); if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_RePrintLicence)) throw new Exception("#EXPOSE_ERROR#Security error"); #region Flag Printing Request is Successful database.UpdateVerifiedPrintout(entityID, itemID, verificationToken, certificateNumber, true, Profile.UserID); #endregion #region Update Licence with Certificate Number if (!string.IsNullOrEmpty(certificateNumber)) { // Get the licence ID from the licence issue detail var licenceIssueDetail = database.GetLicenceIssueDetailsReport(itemID, Profile.UserID); if (licenceIssueDetail != null) { string errorMessage; database.UpdateOperatingLicence(licenceIssueDetail.LicenceID, certificateNumber, isReprint, reprintReason, Profile.UserID, out errorMessage); if (!string.IsNullOrEmpty(errorMessage)) { throw new Exception("#EXPOSE_ERROR#" + errorMessage); } } } #endregion #region Update Stationery Status database.UpdateStationeryStatus(stationeryID, (short)StationeryStatusEnum.Used, "Licence printed", Profile.UserID); #endregion var result = new { Success = true, PrintoutToken = verificationToken, ErrorMessage = "" }; return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "", Result = new { PrintoutToken = verificationToken } } }; } catch(Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary(); additionalData.Add("entityID", entityID); additionalData.Add("itemID", itemID); additionalData.Add("certificateNumber", certificateNumber); additionalData.Add("isReprint", isReprint); additionalData.Add("reprintReason", reprintReason); additionalData.Add("isTestPrint", isTestPrint); additionalData.Add("verificationToken", verificationToken); additionalData.Add("stationeryID", stationeryID); #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "MarkAsPrinted", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; }*/ #endregion try { var database = new LegitimateDatabase(); if (isTestPrint) { database.WriteAuditEntry((int)Profile.UserID, "Application", "LIR Test Print", "", false, false, "licence", itemID); } else { if (!isReprint) { if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_PrintLicence_Actual) && !SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_PrintLicence_Test)) { throw new Exception("#EXPOSE_ERROR#Security error"); } } else { if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_RePrintLicence)) { throw new Exception("#EXPOSE_ERROR#Security error"); } } var errorMessage = ""; var ol = database.UpdateOperatingLicence(itemID, certificateNumber, isReprint, reprintReason, Profile.UserID, out errorMessage); if (string.IsNullOrEmpty(errorMessage) && string.IsNullOrEmpty(ol.LicenceExceptions)) { if (isReprint) { database.WriteAuditEntry((int)Profile.UserID, "Application", "LIR Reprint", reprintReason, false, false, "licence", itemID); } else { database.WriteAuditEntry((int)Profile.UserID, "Application", "LIR Print", reprintReason, false, false, "licence", itemID); } } else { var errorResult = new { Success = false, ErrorMessage = errorMessage }; return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, Error = errorMessage, ErrorCode = "Error" } }; } } #region Flag Printing Request is Successful database.UpdateVerifiedPrintout(entityID, itemID, verificationToken, certificateNumber, true, Profile.UserID); database.UpdateStationeryStatus(stationeryID, (short)StationeryStatusEnum.Used, "", Profile.UserID); #endregion var result = new { Success = true, PrintoutToken = verificationToken, ErrorMessage = "" }; return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "", Result = new { PrintoutToken = verificationToken } } }; } catch (Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary(); additionalData.Add("entityID", entityID); additionalData.Add("itemID", itemID); additionalData.Add("certificateNumber", certificateNumber); additionalData.Add("isReprint", isReprint); additionalData.Add("reprintReason", reprintReason); additionalData.Add("isTestPrint", isTestPrint); additionalData.Add("verificationToken", verificationToken); additionalData.Add("stationeryID", stationeryID); #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "MarkAsPrinted", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; } } /// /// Mark licence as print /// /// /// /// /// /// [HttpPost] public JsonNetResult MarkAnnexureAsPrinted(int entityID, long itemID, string verificationToken) { try { var database = new LegitimateDatabase(); if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_RePrintLicence)) throw new Exception("#EXPOSE_ERROR#Security error"); #region Flag Printing Request is Successful database.UpdateVerifiedPrintout(entityID, itemID, verificationToken, null, true, Profile.UserID); #endregion var result = new { Success = true, PrintoutToken = verificationToken, ErrorMessage = "" }; return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "", Result = new { PrintoutToken = verificationToken } } }; } catch (Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary { { "entityID", entityID }, { "itemID", itemID }, { "verificationToken", verificationToken } }; #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "MarkAnnexureAsPrinted", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; } } #endregion #region MarkDecalAsPrinted /// /// Mark decal as printed /// /// /// /// /// [HttpPost] public JsonNetResult MarkDecalAsPrinted(int entityID, long itemID, string verificationToken) { try { var database = new LegitimateDatabase(); if (!SecurityHelper.UserHasAccessToSecurable(Profile.Securables.ToList(), SecurableEnum.OperatingLicencesModule_LicenceIssueRequest_PrintLicence_Actual)) throw new Exception("#EXPOSE_ERROR#Security error"); // Validate printout exists var printout = database.GetVerifiedPrintoutByToken(verificationToken, Profile.UserID); if (printout == null) { throw new Exception("#EXPOSE_ERROR#Invalid or expired printout token"); } #region Flag Printing Request is Successful database.UpdateVerifiedPrintout(entityID, itemID, verificationToken, null, true, Profile.UserID); #endregion var result = new { Success = true, PrintoutToken = verificationToken, ErrorMessage = "" }; return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "", Result = new { PrintoutToken = verificationToken } } }; } catch (Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary { { "entityID", entityID }, { "itemID", itemID }, { "verificationToken", verificationToken } }; #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "MarkDecalAsPrinted", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; } } #endregion #region UpdateStationeryStatus /// /// Update Stationery Status to used/lost/ruined /// /// /// /// /// [HttpPost] public JsonNetResult UpdateStationeryStatus(long stationeryID, short stationeryStatusID, string comments) { try { var database = new LegitimateDatabase(); #region Flag Printing Request is Successful database.UpdateStationeryStatus(stationeryID, stationeryStatusID, comments, Profile.UserID); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = true, Error = "", ErrorCode = "" } }; } catch (Exception ex) { #region Error Handling #region Error Additional Data Dictionary additionalData = new Dictionary(); additionalData.Add("stationeryID", stationeryID); additionalData.Add("stationeryStatusID", stationeryStatusID); additionalData.Add("comments", comments); #endregion var errorMessage = ErrorHelper.ProcessError(ex, "LicenceIssueRequest", "UpdateStationeryStatus", additionalData); #endregion return new JsonNetResult() { Data = new JsonBaseResult() { Success = false, ErrorCode = "ERROR", Error = errorMessage } }; } } #endregion #region Private Methods private void ReplaceText(DocX documentTemplate, Pr_LicenceIssueDetaisReport_Result licenceIssueDetail = null, Vw_ApplicationDetails applicationDetail = null, LicenceIssueDetail licenceVehicle = null) { PropertyInfo[] rootProperties = typeof(Pr_LicenceIssueDetaisReport_Result).GetProperties(); foreach (PropertyInfo property in rootProperties) { var value = property.GetValue(licenceIssueDetail); documentTemplate.ReplaceText("{" + property.Name + "}", value == null ? string.Empty : value.ToString(), false); } rootProperties = typeof(Vw_ApplicationDetails).GetProperties(); foreach (PropertyInfo property in rootProperties) { var value = property.GetValue(applicationDetail); documentTemplate.ReplaceText("{" + property.Name + "}", value == null ? string.Empty : value.ToString(), false); } rootProperties = typeof(LicenceIssueDetail).GetProperties(); foreach (PropertyInfo property in rootProperties) { var value = property.GetValue(licenceVehicle); documentTemplate.ReplaceText("{" + property.Name + "}", value == null ? string.Empty : value.ToString(), false); } // Add Issuing Authority replacement if (licenceIssueDetail != null && licenceIssueDetail.ProvinceID.HasValue) { var database = new LegitimateDatabase(); var provinces = database.GetProvinces(); var province = provinces.FirstOrDefault(p => p.ProvinceID == licenceIssueDetail.ProvinceID.Value); if (province != null) { string issuingAuthority = province.Description + " Provincial Regulatory Entity"; documentTemplate.ReplaceText("{IssuingAuthority}", issuingAuthority, false); } else { documentTemplate.ReplaceText("{IssuingAuthority}", "", false); } } else { documentTemplate.ReplaceText("{IssuingAuthority}", "", false); } documentTemplate.ReplaceText("{Date_Now}", DateTime.Now.ToString("dd MM yyyy"), false); } // Forces every run inside an operator-uploaded annexure template to Arial at a // fixed size so the printed licence renders with the same font as Annexure 1. // Xceed's InsertDocument does not import styles.xml from the inserted document, // so any run whose font is inherited from a paragraph style (e.g. Word's Normal) // would otherwise fall back to the master document's default font on insert. // Paragraphs whose trimmed text ends with ":" are treated as labels and emitted // bold, mirroring the label / value styling used in Annexure 1. private void NormaliseAnnexureFont(Xceed.Words.NET.DocX documentTemplate, string fontFamily = "Arial", int halfPointSize = 22) { if (documentTemplate == null) return; XNamespace w = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"; foreach (var paragraph in documentTemplate.Paragraphs) { var text = paragraph.Text == null ? string.Empty : paragraph.Text.TrimEnd(); ApplyFontToRuns(paragraph.Xml, w, fontFamily, halfPointSize, text.EndsWith(":")); } foreach (var table in documentTemplate.Tables) { foreach (var row in table.Rows) { foreach (var cell in row.Cells) { foreach (var paragraph in cell.Paragraphs) { var text = paragraph.Text == null ? string.Empty : paragraph.Text.TrimEnd(); ApplyFontToRuns(paragraph.Xml, w, fontFamily, halfPointSize, text.EndsWith(":")); } } } } } private static void ApplyFontToRuns(XElement paragraphXml, XNamespace w, string fontFamily, int halfPointSize, bool isBold) { if (paragraphXml == null) return; foreach (var run in paragraphXml.Descendants(w + "r").ToList()) { var rPr = run.Element(w + "rPr"); if (rPr == null) { rPr = new XElement(w + "rPr"); run.AddFirst(rPr); } rPr.Elements(w + "rFonts").Remove(); rPr.AddFirst(new XElement(w + "rFonts", new XAttribute(w + "ascii", fontFamily), new XAttribute(w + "hAnsi", fontFamily), new XAttribute(w + "cs", fontFamily), new XAttribute(w + "eastAsia", fontFamily))); rPr.Elements(w + "sz").Remove(); rPr.Elements(w + "szCs").Remove(); var size = halfPointSize.ToString(System.Globalization.CultureInfo.InvariantCulture); rPr.Add(new XElement(w + "sz", new XAttribute(w + "val", size))); rPr.Add(new XElement(w + "szCs", new XAttribute(w + "val", size))); rPr.Elements(w + "b").Remove(); rPr.Elements(w + "bCs").Remove(); if (isBold) { rPr.Add(new XElement(w + "b")); rPr.Add(new XElement(w + "bCs")); } } } #endregion } }