using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Web;
using System.Web.Mvc;

using Dapper;

using Fab2ApprovalSystem.DMO;
using Fab2ApprovalSystem.Misc;
using Fab2ApprovalSystem.Models;
using Fab2ApprovalSystem.PdfGenerator;
using Fab2ApprovalSystem.ViewModels;

using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;

namespace Fab2ApprovalSystem.Controllers;

[Authorize]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
[SessionExpireFilter]
public class ECNController : PdfViewController {

    private const string ECN_PREFIX = "ECN_";
    private const string TECN_PREFIX = "TECN_";
    private const string ETECN_PREFIX = "ETECN_";

    ECN_DMO ecnDMO = new ECN_DMO();
    WorkflowDMO wfDMO = new WorkflowDMO();
    TrainingDMO trainingDMO = new TrainingDMO();
    UserAccountDMO userDMO = new UserAccountDMO();
    private readonly AppSettings _AppSettings = GlobalVars.AppSettings;

    // GET: /ECN/
    public ActionResult Index() {
        return View();
    }

    // GET: /ECN/Details/5
    public ActionResult Details(int id) {
        return View();
    }

    // GET: /ECN/Create
    public ActionResult Create() {

        ECN ecn = new ECN();
        try {
            // TODO: Add insert logic here

            ecn.OriginatorID = (int)Session[GlobalVars.SESSION_USERID];
            ecnDMO.InsertECN(ecn);
            return RedirectToAction("Edit", new { issueID = ecn.ECNNumber });
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecn.ECNNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n SubmitDocument - ECN\r\n" + ecn.ECNNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecn.ECNNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "SubmitDocument - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    // GET: /ECN/Edit/5
    public ActionResult Edit(int issueID) {
        int isITARCompliant = 1;
        ECN ecn = new ECN();
        try {

            ecn = ecnDMO.GetECNForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return View("UnAuthorizedAccess");
            } else {

                if (ecn.Deleted) {
                    return RedirectToAction("ReadOnly", new { issueID = issueID });
                }
                if (ecn.CurrentStep >= 1) {
                    return RedirectToAction("EditApproval", new { issueID = issueID });
                } else {

                    if ((ecn.RecordLockIndicator && ecn.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID])) {
                        return RedirectToAction("ReadOnly", new { issueID = issueID });
                    } else {
                        ecn = ecnDMO.GetECN(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
                        ViewBag.Departments = ecnDMO.GetDepartments();
                        ViewBag.AffectedModules = ecnDMO.GetModules();
                        ViewBag.AffectedAreas = ecnDMO.GetECNAreas();
                        ViewBag.AffectedTechnologies = ecnDMO.GetECNTechnologies();
                        ViewBag.AcknowledgementTrainingByIDs = trainingDMO.GetTrainingGroups();
                        ViewBag.Categories = ecnDMO.GetCategories();
                        ViewBag.ProductFamilies = ecnDMO.GetProductFamilies();
                        return View(ecn);
                    }
                }
            }

        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(
                _AppSettings,
                String.Format("{0}\r\nEdit ECN\r\n{1}\r\n{2}", @User?.Identity?.Name, ecn?.ECNNumber, e.InnerException),
                System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = exceptionString });
            return View("Error");
        }
    }

    // POST: /ECN/Edit/5
    [HttpPost]
    public void Edit(ECN ecn) {
        try {
            // TODO: Add update logic here

            ecnDMO.UpdateECN(ecn);
            ;
        } catch {
        }
    }

    public ActionResult ReadOnly(int issueID) {
        int isITARCompliant = 1;
        ECN ecn = new ECN();
        try {

            ecn = ecnDMO.GetECNForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
            bool trainingRequired = ecn.TrainingRequired;
            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return View("UnAuthorizedAccess");
            } else {
                GlobalVars.DocumentType docType = (ecn.ExpirationInProgress || ecn.ExpirationProcessed || ecn.CancellationInProgress || ecn.CancellationApproved) ? GlobalVars.DocumentType.TECNCancelledExpired : GlobalVars.DocumentType.ECN;
                if (ecn.IsEmergencyTECN)
                    docType = GlobalVars.DocumentType.EECN;

                List<ApproversListViewModel> userList = MiscDMO.GetPendingApproversListByDocument(issueID, ecn.CurrentStep, (int)docType);
                ApproversListViewModel approver = userList.Find(delegate (ApproversListViewModel al) { return al.UserID == (int)Session[GlobalVars.SESSION_USERID]; });
                if (approver == null)
                    ViewBag.IsApprover = "false";
                else
                    ViewBag.IsApprover = "true";

                if ((int)Session[GlobalVars.SESSION_USERID] == ecn.OriginatorID)
                    ViewBag.IsOriginator = "true";
                else
                    ViewBag.IsOriginator = "false";
                int trainingId = trainingDMO.GetTrainingId(ecn.ECNNumber);
                if (trainingId > 0) {
                    bool? trainingStatus = (trainingDMO.GetTraining(trainingId)).Status;

                    ViewBag.TrainingID = trainingId;
                    ViewBag.TrainingStatus = trainingStatus;
                }

                ViewBag.Departments = ecnDMO.GetDepartments();
                ViewBag.AffectedModules = ecnDMO.GetModules();
                ViewBag.AffectedAreas = ecnDMO.GetECNAreas();
                ViewBag.AffectedTechnologies = ecnDMO.GetECNTechnologies();
                ViewBag.AcknowledgementTrainingByIDs = trainingDMO.GetTrainingGroups();
                ViewBag.Categories = ecnDMO.GetCategories();
                ViewBag.ProductFamilies = ecnDMO.GetProductFamilies();
                ViewBag.ECNNumber = ecn.ECNNumber;

                return View(ecn);
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "IssueID=" + issueID.ToString() + "  " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReadOnly ECN\r\n" + ecn.ECNNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = exceptionString });
            throw new Exception(e.Message);
        }
    }

    [OutputCache(Duration = 60, VaryByCustom = "host")]
    public ActionResult ECNTrainingView(int issueID) {
        int isITARCompliant = 1;
        ECN ecn = new ECN();
        try {
            ecn = ecnDMO.GetECNForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return PartialView("UnAuthorizedAccess");
            } else {
                ViewBag.Departments = ecnDMO.GetDepartments();
                ViewBag.AffectedModules = ecnDMO.GetModules();
                ViewBag.AffectedAreas = ecnDMO.GetECNAreas();
                ViewBag.AffectedTechnologies = ecnDMO.GetECNTechnologies();
                ViewBag.AcknowledgementTrainingByIDs = ecnDMO.GetECNAcknowledgementTrainingBy();
                ViewBag.Categories = ecnDMO.GetCategories();
                ViewBag.ProductFamilies = ecnDMO.GetProductFamilies();
                ViewBag.ECNNumber = ecn.ECNNumber;

                return PartialView(ecn);
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "IssueID=" + issueID.ToString() + "  " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReadOnly ECN\r\n" + ecn.ECNNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult Acknowledge(int issueID) {
        int isITARCompliant = 1;
        ECN ecn = new ECN();
        try {
            ecn = ecnDMO.GetECNForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return View("UnAuthorizedAccess");
            } else {
                GlobalVars.DocumentType docType = (ecn.ExpirationInProgress || ecn.ExpirationProcessed || ecn.CancellationInProgress || ecn.CancellationApproved) ? GlobalVars.DocumentType.TECNCancelledExpired : GlobalVars.DocumentType.ECN;
                if (ecn.IsEmergencyTECN)
                    docType = GlobalVars.DocumentType.EECN;

                List<ApproversListViewModel> userList = MiscDMO.GetPendingApproversListByDocument(issueID, ecn.CurrentStep, (int)docType);
                ApproversListViewModel approver = userList.Find(delegate (ApproversListViewModel al) { return al.UserID == (int)Session[GlobalVars.SESSION_USERID]; });
                if (approver == null)
                    ViewBag.IsApprover = "false";
                else
                    ViewBag.IsApprover = "true";

                if ((int)Session[GlobalVars.SESSION_USERID] == ecn.OriginatorID)
                    ViewBag.IsOriginator = "true";
                else
                    ViewBag.IsOriginator = "false";

                ViewBag.Departments = ecnDMO.GetDepartments();
                ViewBag.AffectedModules = ecnDMO.GetModules();
                ViewBag.AffectedAreas = ecnDMO.GetECNAreas();
                ViewBag.AffectedTechnologies = ecnDMO.GetECNTechnologies();
                ViewBag.AcknowledgementTrainingByIDs = ecnDMO.GetECNAcknowledgementTrainingBy();
                ViewBag.Categories = ecnDMO.GetCategories();
                ViewBag.ProductFamilies = ecnDMO.GetProductFamilies();

                return View(ecn);
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "IssueID=" + issueID.ToString() + "  " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReadOnly ECN\r\n" + ecn.ECNNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult EditApproval(int issueID) {
        int isITARCompliant = 1;
        ECN ecn = new ECN();
        try {
            ecn = ecnDMO.GetECNForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return View("UnAuthorizedAccess");
            } else {
                if (ecn.Deleted) {
                    return RedirectToAction("ReadOnly", new { issueID = issueID });
                }

                GlobalVars.DocumentType docType = GlobalVars.DocumentType.ECN;
                if (ecn.IsEmergencyTECN)
                    docType = GlobalVars.DocumentType.EECN;
                if (ecn.ExpirationInProgress || ecn.ExpirationProcessed || ecn.CancellationInProgress || ecn.CancellationApproved)
                    docType = GlobalVars.DocumentType.TECNCancelledExpired;

                List<ApproversListViewModel> userList = MiscDMO.GetPendingApproversListByDocument(issueID, ecn.CurrentStep, (int)docType);
                ApproversListViewModel approver = userList.Find(delegate (ApproversListViewModel al) { return al.UserID == (int)Session[GlobalVars.SESSION_USERID]; });
                if (approver == null)
                    ViewBag.IsApprover = "false";
                else
                    ViewBag.IsApprover = "true";

                if ((int)Session[GlobalVars.SESSION_USERID] == ecn.OriginatorID)
                    ViewBag.IsOriginator = "true";
                else
                    ViewBag.IsOriginator = "false";

                int trainingId = trainingDMO.GetTrainingId(ecn.ECNNumber);
                if (trainingId > 0) {
                    bool? trainingStatus = (trainingDMO.GetTraining(trainingId)).Status;

                    ViewBag.TrainingID = trainingId;
                    ViewBag.TrainingStatus = trainingStatus;
                }
                if (ViewBag.IsApprover == "true" || ViewBag.IsOriginator == "true") {
                    ecn = ecnDMO.GetECN(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
                    if (ecn.RecordLockIndicator && ecn.RecordLockedBy == (int)Session[GlobalVars.SESSION_USERID]) {

                        ViewBag.Departments = ecnDMO.GetDepartments();
                        ViewBag.AffectedModules = ecnDMO.GetModules();
                        ViewBag.AffectedAreas = ecnDMO.GetECNAreas();
                        ViewBag.AffectedTechnologies = ecnDMO.GetECNTechnologies();
                        ViewBag.AcknowledgementTrainingByIDs = trainingDMO.GetTrainingGroups();
                        ViewBag.Categories = ecnDMO.GetCategories();
                        ViewBag.ProductFamilies = ecnDMO.GetProductFamilies();

                        return View(ecn);
                    } else {
                        return RedirectToAction("ReadOnly", new { issueID = issueID });
                    }
                } else {
                    return RedirectToAction("ReadOnly", new { issueID = issueID });
                }
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }

            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "IssueID=" + issueID.ToString() + "  " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReadOnly ECN\r\n" + ecn.ECNNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult AttachSave(IEnumerable<HttpPostedFileBase> files, int ecnNumber) {
        string returnString = "";
        // The Name of the Upload component is "files"
        if (files != null) {
            int userId = (int)Session[GlobalVars.SESSION_USERID];
            foreach (var file in files) {
                returnString = ECNHelper.AttachSave(_AppSettings, ecnDMO, ecnNumber, returnString, userId, file.FileName, file.InputStream);
            }
        }
        return Content(returnString);
    }

    public ActionResult Attachment_Read([DataSourceRequest] DataSourceRequest request, int ecnNumber) {
        return Json(ecnDMO.GetECNAttachments(ecnNumber).ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }

    public ActionResult ApprovalLogHistory_Read([DataSourceRequest] DataSourceRequest request, int ecnNumber) {
        return Json(ecnDMO.GetECNApprovalLogHistory(ecnNumber).ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }

    [HttpPost]
    public void DeleteAttachment(int attachmentID, string fileName, int ecnNumber) {
        try {
            if (ModelState.IsValid) {
                ecnDMO.DeleteECNAttachment(attachmentID);
                var physicalPath = System.IO.Path.Combine(_AppSettings.AttachmentFolder + @"ECN\" + ecnNumber.ToString(), fileName);

                System.IO.FileInfo f = new System.IO.FileInfo(physicalPath);

                if (f.Exists)
                    f.Delete();

            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "AttachmentID=" + attachmentID.ToString() + "  " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n DeleteAttachment ECN\r\n" + ecnNumber.ToString() + detailedException.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = 999, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "Delete Attachment " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult Attachment_Destroy([DataSourceRequest] DataSourceRequest request, Attachment attachment) {
        try {
            if (attachment != null && ModelState.IsValid) {
                ecnDMO.DeleteECNAttachment(attachment.AttachmentID);

            }
        } catch (Exception e) {
        }

        return Json(new[] { attachment }.ToDataSourceResult(request, ModelState));
    }

    public ActionResult SubmitDocument(int ecnNumber, int documentType, string ecnTypeString) {
        int isITARCompliant = 1;
        try {
            int appoverCount = ecnDMO.SubmitDocument(ecnNumber, (int)Session[GlobalVars.SESSION_USERID], documentType, out isITARCompliant);
            if (isITARCompliant == 0) // not ITAR Compliant
            {
                // the content gets evaluated on the client side
                return Content("ITAR");
            } else {
                if (appoverCount > 0) {
                    NotifyApprovers(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, documentType, ecnTypeString);
                } else {
                    // automaically approve current step (Step 1) beacuase there are no approvers in step 1 and move to the next step of approval
                    Approve(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, "", documentType, ecnTypeString); // this is the Submit Level Approval

                }

                if (Request.IsAjaxRequest()) {
                    // the content gets evaluated on the client side
                    return Content("Redirect");
                } else
                    return Content("Invalid");
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n SubmitDocument\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "SubmitDocument - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult SubmitTECNExtension(int ecnNumber, int documentType, string ecnTypeString, DateTime extensionDate) {
        try {
            int appoverCount = ecnDMO.SubmitTECNExtensionDocument(ecnNumber, (int)Session[GlobalVars.SESSION_USERID], documentType, extensionDate);

            if (appoverCount > 0)
                NotifyApprovers(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, documentType, ecnTypeString);
            else {
                // automaically approve current step (Step 1) beacuase there are no approvers in step 1 and move to the next step of approval
                Approve(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, "", documentType, ecnTypeString); // this is the Submit Level Approval
            }

            if (Request.IsAjaxRequest()) {
                return Content("Redirect");
            } else
                return Content("Invalid");
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n SubmitDocument\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "SubmitDocument - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult SubmitDocument_EmergencyTECN(int ecnNumber, int documentType) {
        int isITARCompliant = 0;
        try {
            ecnDMO.SubmitDocument(ecnNumber, (int)Session[GlobalVars.SESSION_USERID], documentType, out isITARCompliant);

            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return View("ITAR");
            } else {
                if (Request.IsAjaxRequest()) {
                    return Content("Redirect");
                } else
                    return Content("Invalid");
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n SubmitDocument ETECN\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "SubmitDocument-ETECN - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public void Approve(int ecnNumber, byte currentStep, string comments, int documentType, string ecnTypeString) {
        try {
            bool lastStep = false;
            ECN ecn = ecnDMO.GetECN(ecnNumber);
            bool lastApprover = wfDMO.Approve(_AppSettings, ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType, ecn.WorkFlowNumber);

            while (lastApprover && !lastStep) {

                currentStep++;
                // Changed this next line of code to not pass the currently approving user. This prevents a user from approving multiple steps at once. An undesired function.
                lastApprover = wfDMO.Approve(_AppSettings, ecnNumber, currentStep, comments, out lastStep, 11111111, documentType, ecn.WorkFlowNumber);
                NotifyApprovers(ecnNumber, currentStep, documentType, ecnTypeString);

            }

            // only execute at the last step of the Approval loop
            if (lastApprover && lastStep) {
                NotifySubmitter(ecn.ECNNumber, ecnTypeString);
                NotifyAdmin(ecn.ECNNumber, ecnTypeString);
                if (ecn.TrainingRequired) {
                    TrainingController NewTraining = new TrainingController();
                    NewTraining.Create(ecnNumber);
                }

                if (ecn.IsECN && ecn.ConvertedFromNumber != null) {
                    // Set the cancellation date for the TECN
                    ecnDMO.CancelECN(ecn.ConvertedFromNumber);

                    // copy the TECN to the new ECN folder
                    GenerateECNPdfDifferentLocation((int)ecn.ConvertedFromNumber, ecnNumber);

                }
                // Combine the TECN and the ECN in a zipped file for DCC task creation
                PostApproval(ecnNumber, documentType);

                if (ecn.IsECN && ecn.ConvertedFromNumber != null) {
                    ApprovalLogDMO.Add(new ApprovalLog {
                        IssueID = (int)ecn.ConvertedFromNumber,
                        DocumentTypeID = documentType,
                        OperationType = "Change to " + ecnTypeString + ecnNumber.ToString() + " Approved",
                        UserID = (int)Session[GlobalVars.SESSION_USERID],
                        OperationLog = "Approval of the Document conversion"
                    });

                    List<string> attachments = new List<string>();
                    attachments.Add(_AppSettings.AttachmentFolder + "ECN\\" + ecnNumber + "\\ECNForm_" + ecnNumber + ".pdf");
                    attachments.Add(_AppSettings.AttachmentFolder + "ECN\\" + ecnNumber + "\\ECNForm_" + ecn.ConvertedFromNumber + ".pdf");

                    NotifyTECNAutoCancellation(ecnNumber, (int)ecn.ConvertedFromNumber, attachments);
                }

            }

        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " Step:" + currentStep + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n Approve\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "Approve - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    private void PostApproval(int ecnNumber, int documentType) {
        try {
            ECNPdf ecn = new ECNPdf();

            // Generate the PDF version of the ECN form and Approval log
            if (GenerateECNPdf(ecnNumber, out ecn)) {
                // Zip up all the attached files along with the Pdf version of the ECN form and the Approval Log
                if (ECNHelper.CreateZip(_AppSettings, ecn, @User.Identity.Name)) {
                } else {
                    // TODO How to recreate and send the files to documentum
                    throw new Exception("Problems while generating the ZIP file. Please contact the system Administrator");
                }
            } else {
                throw new Exception("Problems while generating the PDF file. Please contact the system Administrator");
            }

            // Notify a list of people when the E-TECN is approved
            if (documentType == (int)GlobalVars.DocumentType.EECN) {
                NotifyEmergencyTECNApproval(ecnNumber, ecn.ExpirationDate);
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ECN - PostApproval \r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "PostApprovalForECNsDerivedFromTECN - " + exceptionString });
            throw e;
        }
    }

    public void NotifySubmitter(int ecnNumber, string ecnTypeString) {
        try {
            string emailSentList = "";
            ECN ecn = ecnDMO.GetECN(ecnNumber);
                emailSentList = ECNHelper.NotifySubmitter(_AppSettings, ecnNumber, ecnTypeString, ecn);
            try {
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + ":" + emailSentList });
            } catch { }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ECN - Notify Approvers \r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "Approve - " + exceptionString });
            throw e;
        }
    }

    public void NotifyAdmin(int ecnNumber, string ecnTypeString) {
        try {
            string emailSentList = "";
            ECN ecn = ecnDMO.GetECN(ecnNumber);
            IEnumerable<int> ecnAdminIDs = MiscDMO.GetUserIDsBySubRoleID(383);
            foreach (int id in ecnAdminIDs) {
                        emailSentList = ECNHelper.NotifyAdmin(_AppSettings, ecnNumber, ecnTypeString, ecn, id);
                try {
                    EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + ":" + emailSentList });
                } catch { }
            }

        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ECN - Notify Approvers \r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "Approve - " + exceptionString });
            throw e;
        }
    }

    public void NotifyApprovers(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) {
        try {
            string emailSentList = "";
            ECN ecn = ecnDMO.GetECN(ecnNumber);
            List<string> emailIst = MiscDMO.GetApproverEmailListByDocument(@ecnNumber, currentStep, documentType).Distinct().ToList();
                emailSentList = ECNHelper.NotifyApprovers(_AppSettings, ecnNumber, ecnTypeString, emailSentList, ecn, emailIst);
            try {
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList });
            } catch { }

        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " Step:" + currentStep + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ECN - Notify Approvers \r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "Approve - " + exceptionString });
            throw e;
        }
    }

    /// <summary>
    /// Get a list of Approvers and the status
    /// </summary>
    public ActionResult GetApproversList([DataSourceRequest] DataSourceRequest request, int issueID, byte step, bool isTECN, bool isEmergrncyTECN) {
        int isITARCompliant = 0;
        ECN ecn = new ECN();
        ecn = ecnDMO.GetECNForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

        GlobalVars.DocumentType docType;
        // fix related to ticket #35336
        if (ecn.CancellationInProgress || ecn.CancellationApproved || ecn.ExpirationInProgress || ecn.ExpirationProcessed)
            docType = GlobalVars.DocumentType.TECNCancelledExpired;
        else
            docType = isEmergrncyTECN ? GlobalVars.DocumentType.EECN : GlobalVars.DocumentType.ECN;

        return Json(MiscDMO.GetApproversListByDocument(issueID, step, (int)docType).ToDataSourceResult(request));
    }

    public void NotifyRejectionToOrginator(int issueID, string ecnTypeString, string comments) {
        List<string> emailIst = ecnDMO.GetRejectionOrginatorEmailList(@issueID).Distinct().ToList();
        ECN ecn = ecnDMO.GetECN(issueID);
        string username = Session[GlobalVars.SESSION_USERNAME].ToString();
        string userEmail = ECNHelper.NotifyRejectionToOrginator(_AppSettings, issueID, ecnTypeString, comments, emailIst, ecn, username);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Rejection: " + userEmail });
        } catch { }
    }

    public void NotifyTECNExtensionRejectionToOrginator(int issueID, string ecnTypeString) {
        List<string> emailIst = ecnDMO.GetRejectionOrginatorEmailList(@issueID).Distinct().ToList();
        ECN ecn = ecnDMO.GetECN(issueID);
        string username = Session[GlobalVars.SESSION_USERNAME].ToString();
        string userEmail = ECNHelper.NotifyTECNExtensionRejectionToOrginator(_AppSettings, issueID, ecnTypeString, emailIst, ecn, username);

        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Rejection: " + userEmail });
        } catch { }
    }

    public void Reject(int ecnNumber, byte currentStep, string comments, int docType, string ecnTypeString) {
        try {
            // TODO 
            // Check Rejection is for the TECN Extension

            int isITARCompliant = 0;
            ECN ecn = new ECN();
            ecn = ecnDMO.GetECNForRead(ecnNumber, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

            if (Session[GlobalVars.SESSION_USERID] != null) {
                if (ecn.TECNExtensionState) {
                    wfDMO.RejectTECNExtension(ecnNumber, currentStep, comments, (int)Session[GlobalVars.SESSION_USERID], docType);
                    NotifyTECNExtensionRejectionToOrginator(ecnNumber, ecnTypeString);
                } else {
                    if (ecn.IsECN && ecn.ConvertedFromNumber != null) {
                        ecnDMO.ECNResetTECNAtRejection(ecnNumber, (int)Session[GlobalVars.SESSION_USERID], docType);
                    }

                    wfDMO.Reject(ecnNumber, currentStep, comments, (int)Session[GlobalVars.SESSION_USERID], docType);
                    NotifyRejectionToOrginator(ecnNumber, ecnTypeString, comments);
                }
            } else {
                Response.Redirect("~/Account/Login");
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }

            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " Step:" + currentStep + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n Reject\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "Reject - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public void RecallDocument(int ecnNumber, byte currentStep, string comments, int docType, string ecnTypeString) {
        try {
            // TODO 
            // Check Rejection is for the TECN Extension

            int isITARCompliant = 0;
            ECN ecn = new ECN();
            ecn = ecnDMO.GetECNForRead(ecnNumber, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

            if (Session[GlobalVars.SESSION_USERID] != null) {
                NotifyApproversForRecall(ecnNumber, currentStep, docType, ecnTypeString, comments);
                wfDMO.Recall(ecnNumber, currentStep, comments, (int)Session[GlobalVars.SESSION_USERID], docType);
            } else {
                Response.Redirect("~/Account/Login");
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }

            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " Step:" + currentStep + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n Reject\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "Reject - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public void ReAssignApproverByAdmin(int issueID, int reAssignApproverFrom, int reAssignApproverTo, byte step, int docType, string ecnTypeString) {
        var email = "";
        try {
            email = wfDMO.ReAssignApproval(issueID, reAssignApproverFrom, reAssignApproverTo, step, docType);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + issueID.ToString() + " Step:" + step + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReAssignApproval\r\n" + issueID.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "ReAssignApproval - " + exceptionString });
            throw new Exception(e.Message);
        }

        ECN ecn = ecnDMO.GetECN(issueID);
        ECNHelper.ReAssignApproverByAdmin(_AppSettings, issueID, ecnTypeString, email, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "ReAssign Approver: " + email });
        } catch { }
    }

    [HttpPost]
    public void ReAssignOriginatorByAdmin(int ecnNumber, string comments, int newOriginatorId) {
        if (Session[GlobalVars.IS_ADMIN] == null)
            throw new Exception("Permission denied");

        try {
            ecnDMO.ReassignOriginatorECN(ecnNumber, newOriginatorId, comments, (int)Session[GlobalVars.SESSION_USERID]);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim();
            if (exceptionString.Length > 450)
                exceptionString = exceptionString.Substring(0, 450);
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReAssignOriginatorByAdmin\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "ReAssignOriginatorByAdmin - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public void ReAssignApproval(int issueID, int userIDs, byte step, int docType, string ecnTypeString) {
        var email = "";
        try {
            email = wfDMO.ReAssignApproval(issueID, (int)Session[GlobalVars.SESSION_USERID], userIDs, step, docType);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + issueID.ToString() + " Step:" + step + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReAssignApproval\r\n" + issueID.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Error", Comments = "ReAssignApproval - " + exceptionString });
            throw new Exception(e.Message);
        }

        ECN ecn = ecnDMO.GetECN(issueID);
        ECNHelper.ReAssignApproval(_AppSettings, issueID, ecnTypeString, email, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "ReAssign Approver: " + email });
        } catch { }
    }

    public JsonResult GetAllUsersList() {
        UserAccountDMO userDMO = new UserAccountDMO();
        IEnumerable<LoginModel> userlist = userDMO.GetAllActiveUsers();
        return Json(userlist, JsonRequestBehavior.AllowGet);
    }

    public void AddAdditionalApproval(int issueID, byte step, string userIDs, int docType, string ecnTypeString) {
        string emailSentList = "";
        var emailArray = "";
        try {
            emailArray = wfDMO.AddAdditionalApproval(issueID, userIDs, step, docType);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + issueID.ToString() + " Step:" + step + " " + " Userid:" + userIDs + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n AddAdditionalApproval\r\n" + issueID.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "AddAdditionalApproval - " + exceptionString });
            throw new Exception(e.Message);
        }
        ECN ecn = ecnDMO.GetECN(issueID);
        emailSentList = ECNHelper.AddAdditionalApproval(_AppSettings, issueID, ecnTypeString, emailSentList, emailArray, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Additonal Approver: " + emailSentList });
        } catch { }
    }

    public bool GenerateECNPdf(int ecnNumber, out ECNPdf ecn) {
        try {

            string outputFileName = "";
            ecn = ecnDMO.GetECNPdf(ecnNumber);
            outputFileName = ecnNumber.ToString() + ".pdf";

            string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString();
            System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(ecnFolderPath);
            // create the folder for the ECN if it does not exist
            if (!di.Exists)
                di.Create();

            // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
            // requires the controller to be inherited from MyController instead of MVC's Controller.
            SavePdf(ecnFolderPath + "\\ECNForm_" + outputFileName, "ECNPdf", ecn);
            SavePdf(ecnFolderPath + "\\ECNApprovalLog_" + outputFileName, "ECNApprovalPdf", ecn);
        } catch (Exception ex) {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message });
            ecn = null;
            return false;
        }

        return true;
    }

    public bool GenerateECNPdfDifferentLocation(int ecnNumber, int folderName) {
        ECNPdf ecn = new ECNPdf();
        try {
            string outputFileName = "";

            ecn = ecnDMO.GetECNPdf(ecnNumber);
            outputFileName = ecnNumber.ToString() + ".pdf";

            string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + folderName.ToString();

            System.IO.DirectoryInfo di = new System.IO.DirectoryInfo(ecnFolderPath);
            // create the folder for the ECN if it does not exist
            if (!di.Exists)
                di.Create();

            // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
            // requires the controller to be inherited from MyController instead of MVC's Controller.
            SavePdf(ecnFolderPath + "\\ECNForm_" + outputFileName, "ECNPdf", ecn);
        } catch (Exception ex) {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Generate PDF", Comments = ex.Message });
            ecn = null;
            return false;
        }

        return true;
    }

    public ActionResult PrintECNPdf(int ecnNumber) {
        ECNPdf ecn;
        try {
            ecn = ecnDMO.GetECNPdf(ecnNumber);
            // To render a PDF instead of an HTML, all we need to do is call ViewPdf instead of View. This
            // requires the controller to be inherited from MyController instead of MVC's Controller.
            return this.ViewPdf("", "ECNPdf", ecn);
        } catch (Exception ex) {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Print PDF", Comments = ex.Message });
            ecn = null;
            return Content("");
        }
    }

    public void NotifyEmergencyTECNApproval(int ecnNumber, DateTime? expDate) {
        ECN ecn = ecnDMO.GetECN(ecnNumber);
        string emailSentList = ECNHelper.NotifyEmergencyTECNApproval(_AppSettings, ecnNumber, expDate, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN", OperationType = "Email", Comments = "Approvers for Step 1:" + emailSentList });
        } catch { }
    }

    public void NotifyApproversForCancellation(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) {
        ECN ecn = ecnDMO.GetECN(ecnNumber);
        string emailSentList = ECNHelper.NotifyApproversForCancellation(_AppSettings, ecnNumber, currentStep, documentType, ecnTypeString, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList });
        } catch { }
    }

    public void NotifyApproversForRecall(int ecnNumber, byte currentStep, int documentType, string ecnTypeString, string recallComments) {
        ECN ecn = ecnDMO.GetECN(ecnNumber);
        string emailSentList = ECNHelper.NotifyApproversForRecall(_AppSettings, ecnNumber, currentStep, documentType, ecnTypeString, recallComments, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList });
        } catch { }
    }

    public void NotifyApproversForExpiration(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) {
        ECN ecn = ecnDMO.GetECN(ecnNumber);
        string emailSentList = ECNHelper.NotifyApproversForExpiration(_AppSettings, ecnNumber, currentStep, documentType, ecnTypeString, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList });
        } catch { }
    }

    public void NotifyTECNCancellation(int ecnNumber, string ecnFolderPath) {
        ECN ecn = ecnDMO.GetECN(ecnNumber);
        List<int> notificationUserList = ecnDMO.GetTECNNotificationUsers().ToList();
        string emailSentList = ECNHelper.NotifyTECNCancellation(_AppSettings, userDMO, ecnNumber, ecnFolderPath, ecn, notificationUserList);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN", OperationType = "Email", Comments = "Approvers for Cancellation :" + emailSentList });
        } catch { }
    }

    public void NotifyTECNAutoCancellation(int ecnNumber, int tecnNumber, List<string> attachments) {
        ECN ecn = ecnDMO.GetECN(tecnNumber);
        string emailSentList = ECNHelper.NotifyTECNAutoCancellation(_AppSettings, ecnNumber, tecnNumber, attachments, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN", OperationType = "Email", Comments = "Approvers for Cancellation :" + emailSentList });
        } catch { }
    }

    public void NotifyTECNExpiration(int ecnNumber, string ecnFolderPath) {
        ECN ecn = ecnDMO.GetECN(ecnNumber);
        string emailSentList = ECNHelper.NotifyTECNExpiration(_AppSettings, ecnNumber, ecnFolderPath, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Email", Comments = "Approvers for Expiration:" + emailSentList });
        } catch { }
    }

    public void AddEECNApproval(int ecnNumber, byte step, string engUserIDs, string OpUserIDs) {
        ECN ecn = ecnDMO.GetECN(ecnNumber);
        string emailSentList = ECNHelper.AddEECNApproval(_AppSettings, @User.Identity.Name, wfDMO, ecnNumber, out step, engUserIDs, OpUserIDs, ecn);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN", OperationType = "Email", Comments = "Additonal Approver: " + emailSentList });
        } catch { }
    }

    public void SaveAfterSubmitByApprover(int ecnNumber, string implementationDetails) {
        try {
            ecnDMO.SaveAfterSubmitByApprover(ecnNumber, implementationDetails);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " - " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n SaveAfterSubmitByApprover\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "E-TECN ", OperationType = "Error", Comments = "SaveAfterSubmitByApprover - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public void DeleteDocument(int ecnNumber, string ecnTypeString) {
        try {
            ecnDMO.DeleteDocument(ecnNumber, (int)Session[GlobalVars.SESSION_USERID], ecnTypeString);
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " - " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n DeleteDocument\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "", OperationType = "Error", Comments = "DeleteDocument - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public void DeleteDocumentBySubmitter(int ecnNumber, string ecnTypeString) {
        ECN ecn = ecnDMO.GetECN(ecnNumber);
        int submitterId = ecn.OriginatorID;
        if (submitterId == (int)Session[GlobalVars.SESSION_USERID]) {
            try {
                ecnDMO.DeleteDocument(ecnNumber, (int)Session[GlobalVars.SESSION_USERID], ecnTypeString);
            } catch (Exception e) {
                string detailedException = "";
                try {
                    detailedException = e.InnerException.ToString();
                } catch {
                    detailedException = e.Message;
                }
                string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + " - " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
                Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n DeleteDocument\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "", OperationType = "Error", Comments = "DeleteDocument - " + exceptionString });
                throw new Exception(e.Message);
            }
        } else {
        }
    }

    public ActionResult ReSubmitDocument(int ecnNumber, int documentType, string ecnTypeString, string oldECNTypeString, string descriptionOfChange, string reasonForChange, string categoryId = "") {
        ECN ecn = new ECN();

        int isITARCompliant = 1;
        int newECNNumber = 0;
        int catId = 0;
        Int32.TryParse(categoryId, out catId);
        try {
            int appoverCount = ecnDMO.ReSubmitDocument(
                ecnNumber,
                (int)Session[GlobalVars.SESSION_USERID],
                documentType,
                out isITARCompliant,
                descriptionOfChange,
                reasonForChange,
                ecnTypeString,
                out newECNNumber,
                catId);

            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return Content("ITAR");
            } else {
                Functions.CopyAttachments(_AppSettings, ecnNumber, newECNNumber);

                try {
                    ecn = ecnDMO.GetECN(ecnNumber);

                    ApprovalLogDMO.Add(new ApprovalLog {
                        IssueID = ecnNumber,
                        DocumentTypeID = documentType,
                        OperationType = "Changed From " + oldECNTypeString + " To " + ecnTypeString,
                        UserID = (int)Session[GlobalVars.SESSION_USERID],
                        OperationLog = "Changed the Document Type"
                    });
                } catch (Exception e) {
                    string detailedException = "";
                    try {
                        detailedException = e.InnerException.ToString();
                    } catch {
                        detailedException = e.Message;
                    }
                    string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
                    Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReSubmitDocument (ApprovalLogDMO)\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
                    EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Error", Comments = "ReSubmitDocument (ApprovalLogDMO)" + exceptionString });

                }

                try {
                    ECNTypeChangeLogDMO.Add(new ECNTypeChangeLog {
                        ECNNumber = ecnNumber,
                        UserID = (int)Session[GlobalVars.SESSION_USERID],
                        ECNTypeFrom = oldECNTypeString,
                        ECNTypeTo = ecnTypeString
                    });
                } catch (Exception e) {
                    string detailedException = "";
                    try {
                        detailedException = e.InnerException.ToString();
                    } catch {
                        detailedException = e.Message;
                    }
                    string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
                    Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReSubmitDocument (ECNTypeChangeLogDMO)\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
                    EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = ecnTypeString, OperationType = "Error", Comments = "ReSubmitDocument (ECNTypeChangeLogDMO)" + exceptionString });
                }

                if (Request.IsAjaxRequest()) {
                    return Content("Redirect~" + newECNNumber);

                } else
                    return Content("Invalid");
            }
        } catch (Exception e) {
            string detailedException = "";
            try {
                detailedException = e.InnerException.ToString();
            } catch {
                detailedException = e.Message;
            }
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + ecnNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n SubmitDocument\r\n" + ecnNumber.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "ECN", OperationType = "Error", Comments = "Re-SubmitDocument - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult PCRBExists(int pcrb) {
        return Content(ecnDMO.PCRBExists(pcrb).ToString());
    }

    public ActionResult CancelDocument(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) {
        bool lastApproverAndLastStep = false;
        int appoverCount = ecnDMO.SubmitForCancellation(ecnNumber, (byte)GlobalVars.WorkFLowStepNumber.Step1, (int)Session[GlobalVars.SESSION_USERID], documentType, ecnTypeString, (int)GlobalVars.TECNExpirationCancellation.Cancellation);
        if (appoverCount > 0) {
            NotifyApproversForCancellation(ecnNumber, currentStep, documentType, ecnTypeString);
        } else // TODO Automatically close the
          {
            lastApproverAndLastStep = ApproveCancellation(ecnNumber, currentStep, "", documentType, ecnTypeString);
        }

        if (!lastApproverAndLastStep) {
            try {
                lastApproverAndLastStep = true;

                ECNPdf ecn = new ECNPdf();
                GenerateECNPdf(ecnNumber, out ecn);

                string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\";
                string outputFullFilePath = "";

                string outputFileName;
                outputFileName = TECN_PREFIX + ecnNumber.ToString() + ".zip";

                outputFullFilePath = _AppSettings.AttachmentFolder + "\\TECNCancelledZipped\\" + outputFileName;

                Zipper zip = new Zipper();
                zip.CreateZip(outputFullFilePath, sourceDirectory);
                NotifyTECNCancellation(ecnNumber, outputFullFilePath);

            } catch (Exception ex) {
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message });

            }

        }
        int trainingId = trainingDMO.GetTrainingId(ecnNumber);
        trainingDMO.DeleteTraining(trainingId);

        if (Request.IsAjaxRequest()) {
            return Content("Redirect");
        } else
            return Content("Invalid");
    }

    public ActionResult CancelDocumentBySubmitter(int ecnNumber, byte currentStep, int documentType, string ecnTypeString) {
        return Content("Redirect");
    }

    public bool ApproveCancellation(int ecnNumber, byte currentStep, string comments, int documentType, string ecnTypeString) {
        bool lastApproverAndLastStep = false;
        bool lastStep = false;
        bool lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType);
        while (lastApprover && !lastStep) {
            currentStep++;
            lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType);
            NotifyApproversForCancellation(ecnNumber, currentStep, documentType, ecnTypeString);
        }

        if (lastApprover && lastStep) {
            try {
                lastApproverAndLastStep = true;

                ECNPdf ecn = new ECNPdf();
                GenerateECNPdf(ecnNumber, out ecn);

                string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\";
                string outputFullFilePath = "";

                string outputFileName;
                outputFileName = TECN_PREFIX + ecnNumber.ToString() + ".zip";

                outputFullFilePath = _AppSettings.AttachmentFolder + "\\TECNCancelledZipped\\" + outputFileName;

                Zipper zip = new Zipper();
                zip.CreateZip(outputFullFilePath, sourceDirectory);
                NotifyTECNCancellation(ecnNumber, outputFullFilePath);

            } catch (Exception ex) {
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message });

            }
        }

        return lastApproverAndLastStep;
    }

    public void ApproveExpiration(int ecnNumber, byte currentStep, string comments, int documentType, string ecnTypeString) {
        bool lastStep = false;
        bool lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType);
        while (lastApprover && !lastStep) {
            currentStep++;
            lastApprover = lastApprover = ecnDMO.ECNApproveCancelled_ExpiredDocument(ecnNumber, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType);
            NotifyApproversForExpiration(ecnNumber, currentStep, documentType, ecnTypeString);
        }
        if (lastApprover && lastStep) {
            try {
                ECNPdf ecn = new ECNPdf();
                GenerateECNPdf(ecnNumber, out ecn);

                string sourceDirectory = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString() + "\\";
                string outputFullFilePath = "";

                string outputFileName;
                outputFileName = TECN_PREFIX + ecnNumber.ToString() + ".zip";

                outputFullFilePath = _AppSettings.AttachmentFolder + "\\TECNExpiredZipped\\" + outputFileName;

                Zipper zip = new Zipper();
                zip.CreateZip(outputFullFilePath, sourceDirectory);

                NotifyTECNExpiration(ecnNumber, outputFullFilePath);
            } catch (Exception ex) {
                EventLogDMO.Add(new WinEventLog() { IssueID = ecnNumber, UserID = @User.Identity.Name, DocumentType = "TECN", OperationType = "Error", Comments = ex.Message });

            }
        }
    }

    public void CheckCanSubmit(int ecnNumber) {
        bool result = ecnDMO.CanSubmitECN(ecnNumber);
        if (result) {
            throw new Exception("Cannot Submit");
        }
    }

    public void ReleaseLockOnDocument(int issueID) {
        try {
            ecnDMO.ReleaseLockOnDocument((int)Session[GlobalVars.SESSION_USERID], issueID);
        } catch (Exception e) {
            try {
                Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReleaseLockOnDocument ECN\r\n" + issueID.ToString() + "\r\n" + e.Message, System.Diagnostics.EventLogEntryType.Error);
            } catch { }
            ecnDMO.ReleaseLockOnDocument(-1, issueID);
        }
    }

    public void ReleaseLockOnDocumentAdmin(int issueID) {
        try {
            ecnDMO.ReleaseLockOnDocument(-1, issueID);
        } catch (Exception e) {
            try {
                Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReleaseLockOnDocument ECN\r\n" + issueID.ToString() + "\r\n" + e.Message, System.Diagnostics.EventLogEntryType.Error);
            } catch { }
            ecnDMO.ReleaseLockOnDocument(-1, issueID);
        }
    }

    public FileResult DownloadFile(string attachmentID, string ecnNumber) {
        string fileName = ecnDMO.GetFileName(attachmentID);

        string ecnFolderPath = _AppSettings.AttachmentFolder + "ECN\\" + ecnNumber.ToString();
        var sDocument = System.IO.Path.Combine(ecnFolderPath, fileName);

        var FDir_AppData = _AppSettings.AttachmentFolder;
        if (!sDocument.StartsWith(FDir_AppData)) {
            throw new HttpException(403, "Forbidden");
        }

        if (!System.IO.File.Exists(sDocument)) {
            return null;
        }

        return File(sDocument, System.Net.Mime.MediaTypeNames.Application.Octet, fileName);
    }

}