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

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 LotTravelerController : PdfViewController {

    LotTravelerDMO LotTravDMO = new LotTravelerDMO();
    string docTypeString = "LotTraveler";
    WorkflowDMO wfDMO = new WorkflowDMO();
    private readonly AppSettings _AppSettings = GlobalVars.AppSettings;

    public ActionResult CreateWorkRequest() {
        LTWorkRequest workRequest = new LTWorkRequest();
        try {
            workRequest.OriginatorID = (int)Session[GlobalVars.SESSION_USERID];
            LotTravDMO.InsertWorkRequest(workRequest);
            return RedirectToAction("Edit", new { issueID = workRequest.ID });
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + workRequest.SWRNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n CreateWorkRequest - LotTraveler\r\n" + e.InnerException == null ? e.Message : e.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = workRequest.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Error", Comments = "CreateWorkRequest - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult Edit(int issueID) {
        int isITARCompliant = 1;
        Session["CreateNewRevision"] = "false";
        ViewBag.NewRevision = "false";

        LTWorkRequest workRequest = new LTWorkRequest();
        try {
            workRequest = LotTravDMO.GetLTWorkRequestItemForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return View("UnAuthorizedAccess");
            }
            if ((int)Session[GlobalVars.SESSION_USERID] == workRequest.OriginatorID)
                ViewBag.IsOriginator = "true";
            else
                ViewBag.IsOriginator = "false";

            List<ApproversListViewModel> userList = MiscDMO.GetPendingApproversListByDocument(issueID, workRequest.CurrentStep, (int)GlobalVars.DocumentType.LotTraveler);
            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 (workRequest.CloseDate != null) {
                // LATER ON SHOULD CALL THE LOT TRAVLELER VIEW
                return RedirectToAction("WorkRequestReadOnly", new { issueID = issueID });
            }

            // open the view based on the Workflow step
            if (workRequest.CurrentStep == 0) {
                if ((workRequest.RecordLockIndicator && workRequest.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID])) {
                    return RedirectToAction("WorkRequestReadOnly", new { issueID = issueID });
                }

            } else if (workRequest.CurrentStep >= 1 && workRequest.CurrentStep < 3 && workRequest.CloseDate == null) // Before
              {
                if ((ViewBag.IsApprover == "true") || ((bool)Session[GlobalVars.IS_ADMIN]))
                    return RedirectToAction("WorkRequestApproval", new { issueID = issueID });
                else
                    return RedirectToAction("WorkRequestReadOnly", new { issueID = issueID });
            } else if (workRequest.CurrentStep == 3) {
                if ((workRequest.RecordLockIndicator && workRequest.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID]) || (ViewBag.IsApprover == "false")) {
                    return RedirectToAction("WorkRequestReadOnly", new { issueID = issueID });
                } else {
                    Session["CreateNewRevision"] = "true";
                    ViewBag.NewRevision = "true";
                    workRequest = LotTravDMO.GetLTWorkRequestItem(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
                    return RedirectToAction("WorkRequestRevision", new { workRequestID = issueID });
                }

                // Start the versioning of the documents with the Edit Feature
                // Call the Edit Form

            }
            workRequest = LotTravDMO.GetLTWorkRequestItem(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
            // else do this part
            ViewBag.Departments = MiscDMO.GetDepartments();
            ViewBag.AffectedModules = MiscDMO.GetModules();
            ViewBag.WorkReqRevisionList = LotTravDMO.GetWorkReqRevisions(workRequest.SWRNumber);
            return View(workRequest);
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + workRequest.SWRNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n Edit WorkRequest - LotTraveler\r\n" + e.InnerException == null ? e.Message : e.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = workRequest.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Error", Comments = "Edit WorkRequest - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult SaveRevision(LTWorkRequest model) {
        try {
            var data = model;
            if (Session["CreateNewRevision"].ToString() == "true") {
                ViewBag.NewRevision = "false";
                Session["CreateNewRevision"] = "false";
                model.OriginatorID = (int)Session[GlobalVars.SESSION_USERID];
                int newRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
                // TODO
                // Send email to the Originator and Group of People
                NotifyfWorkRequestRevisionChange(newRequestID);

                return Content(newRequestID.ToString());
            } else {
                LotTravDMO.UpdateWorkRequest(model, (int)Session[GlobalVars.SESSION_USERID]);
                return Content("");
            }
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + model.SWRNumber.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n SaveRevision - LotTraveler\r\n" + e.InnerException == null ? e.Message : e.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = model.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Error", Comments = "SaveRevision - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult WorkRequestReadOnly(int issueID) {
        int isITARCompliant = 1;
        LTWorkRequest workRequest = new LTWorkRequest();
        try {
            workRequest = LotTravDMO.GetLTWorkRequestItemForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

            ViewBag.Departments = MiscDMO.GetDepartments();
            ViewBag.AffectedModules = MiscDMO.GetModules();
            ViewBag.WorkReqRevisionList = LotTravDMO.GetWorkReqRevisions(workRequest.SWRNumber);

            return View(workRequest);
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + issueID.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n WorkRequestReadOnly - LotTraveler\r\n" + e.InnerException == null ? e.Message : e.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Error", Comments = "WorkRequestReadOnly - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult WorkRequestApproval(int issueID) {
        int isITARCompliant = 1;
        LTWorkRequest workRequest = new LTWorkRequest();
        try {
            workRequest = LotTravDMO.GetLTWorkRequestItemForRead(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

            List<ApproversListViewModel> userList = MiscDMO.GetPendingApproversListByDocument(issueID, workRequest.CurrentStep, (int)GlobalVars.DocumentType.LotTraveler);

            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 (workRequest.RecordLockIndicator && workRequest.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID]) {
                return RedirectToAction("WorkRequestReadOnly", new { issueID = issueID });
            }

            workRequest = LotTravDMO.GetLTWorkRequestItem(issueID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
            ViewBag.Departments = MiscDMO.GetDepartments();
            ViewBag.AffectedModules = MiscDMO.GetModules();
            ViewBag.WorkReqRevisionList = LotTravDMO.GetWorkReqRevisions(workRequest.SWRNumber);

            return View(workRequest);
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + issueID.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n WorkRequestApproval - LotTraveler\r\n" + e.InnerException == null ? e.Message : e.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = issueID, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Error", Comments = "WorkRequestApproval - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public ActionResult GetWorkRequestRevision(int workRequestID) {
        int isITARCompliant = 1;
        LTWorkRequest workRequest = new LTWorkRequest();
        workRequest = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

        return Content("");
    }

    public ActionResult DisplayWorkRequestPDF(int workRequestID) {
        WorkRequestPdf workRequest = new WorkRequestPdf();
        try {
            workRequest = LotTravDMO.GetLTWorkRequestItemPDF(workRequestID);

            // 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("", "WorkRequestPDF", workRequest);
        } catch (Exception ex) {
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n DisplayWorkRequestPDF - LotTraveler\r\n" + ex.InnerException.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = workRequest.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTravler", OperationType = "Generate PDF", Comments = ex.Message });
            workRequest = null;
            return Content("");
        }
    }

    public ActionResult WorkRequestRevision(int workRequestID) {
        int isITARCompliant = 1;
        LTWorkRequest workRequest = new LTWorkRequest();
        workRequest = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
        List<ApproversListViewModel> userList = MiscDMO.GetPendingApproversListByDocument(workRequestID, workRequest.CurrentStep, (int)GlobalVars.DocumentType.LotTraveler);
        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 (
            (workRequest.RecordLockIndicator && workRequest.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID]
            || (ViewBag.IsApprover == "false"))
            || (!workRequest.IsCurrentRevision)
            || (workRequest.CloseDate != null)
            ) {
            return RedirectToAction("WorkRequestReadOnly", new { issueID = workRequestID });
        }

        workRequest = LotTravDMO.GetLTWorkRequestItem(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

        ViewBag.Departments = MiscDMO.GetDepartments();
        ViewBag.AffectedModules = MiscDMO.GetModules();
        ViewBag.WorkReqRevisionList = LotTravDMO.GetWorkReqRevisions(workRequest.SWRNumber);

        return View(workRequest);
    }

    [HttpPost]
    public ActionResult Edit(LTWorkRequest model) {
        try {
            Session["CreateNewRevision"] = "false";
            var data = model;
            LotTravDMO.UpdateWorkRequest(model, (int)Session[GlobalVars.SESSION_USERID]);
        } catch (Exception ex) {
            return Content(ex.Message);
        }

        return Content("Successfully Saved");
    }
    /// <summary>
    /// 
    /// </summary>
    public JsonResult GetBaseFlowLocations(string baseFlow) {
        List<BaseFlowLocation> loclist = LotTravDMO.GetBaseFlowLocations(baseFlow);
        return Json(loclist, JsonRequestBehavior.AllowGet);
    }

    public JsonResult GetMaterialRecord(int materialID) {
        LTMaterial ltMaterial = LotTravDMO.GetMaterialRecord(materialID);
        return Json(ltMaterial, JsonRequestBehavior.AllowGet);
    }

    public JsonResult GetBaseFlowOperations(string baseFlow, string location) {
        List<BaseFlowOperations> operationslist = LotTravDMO.GetBaseFlowOperations(baseFlow, location);
        return Json(operationslist, JsonRequestBehavior.AllowGet);
    }

    public ActionResult GetMaterialDetails([DataSourceRequest] DataSourceRequest request, int workRequestID) {
        return Json(LotTravDMO.GetMaterialDetails(workRequestID).ToDataSourceResult(request));
    }

    public JsonResult GetPartNumbers() {
        List<PartNumberAttrib> operationslist = LotTravDMO.GetPartNumbers();
        return Json(operationslist, JsonRequestBehavior.AllowGet);
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult InsertMaterialDetail([DataSourceRequest] DataSourceRequest request, LTMaterialViewModel model) {
        try {
            string s = Session["CreateNewRevision"].ToString();
            if (model != null && ModelState.IsValid) {
                LotTravDMO.InsertMaterialDetail(model, (int)Session[GlobalVars.SESSION_USERID]);
            }

            return Json(new[] { model }.ToDataSourceResult(request, ModelState));
        } catch (Exception ex) {
            return this.Json(new DataSourceResult {
                Errors = ex.Message
            });
        }
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult UpdateMaterialDetail([DataSourceRequest] DataSourceRequest request, LTMaterialViewModel model) {
        try {
            if (model != null && ModelState.IsValid) {
                LotTravDMO.UpdateMaterialDetail(model, (int)Session[GlobalVars.SESSION_USERID]);
            }

            return Json(new[] { model }.ToDataSourceResult(request, ModelState));
        } catch (Exception ex) {
            return this.Json(new DataSourceResult {
                Errors = ex.Message
            });
        }
    }

    public ActionResult AddMaterialDetailRevision(LTWorkRequest model) {
        var modelMaterialDetail = model.LTMaterial;
        int previousMaterialID = model.LTMaterial.ID;
        int newWorkRequestID = model.ID;
        if (Session["CreateNewRevision"].ToString() == "true") {
            Session["CreateNewRevision"] = "false";

            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            modelMaterialDetail.LTWorkRequestID = newWorkRequestID;

            // Any update will be a new entry
            LotTravDMO.InsertMaterialDetail(modelMaterialDetail, (int)Session[GlobalVars.SESSION_USERID]);
            // TODO
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        } else {
            if (modelMaterialDetail != null && ModelState.IsValid) {
                LotTravDMO.InsertMaterialDetail(modelMaterialDetail, (int)Session[GlobalVars.SESSION_USERID]);
            }
        }

        return Content(newWorkRequestID.ToString());
    }

    /// <summary>
    /// For the Revison
    /// </summary>
    public ActionResult UpdateMaterialDetailRevision(LTWorkRequest model) {
        var modelMaterialDetail = model.LTMaterial;
        int previousMaterialID = model.LTMaterial.ID;
        int newWorkRequestID = model.ID;

        if (Session["CreateNewRevision"].ToString() == "true") {
            Session["CreateNewRevision"] = "false";

            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            modelMaterialDetail.LTWorkRequestID = newWorkRequestID;

            // Any update will be a new entry
            LotTravDMO.UpdateMaterialDetailRevision(modelMaterialDetail, previousMaterialID);
            // TODO
            // Send email to the Originator and Group of People
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        } else {
            if (modelMaterialDetail != null && ModelState.IsValid) {
                LotTravDMO.UpdateMaterialDetail(modelMaterialDetail, (int)Session[GlobalVars.SESSION_USERID]);
            }
        }

        return Content(newWorkRequestID.ToString());
    }

    public ActionResult DeleteMaterialDetail([DataSourceRequest] DataSourceRequest request, LTMaterialViewModel model) {
        try {
            if (model != null && ModelState.IsValid) {
                LotTravDMO.DeleteMaterialDetail(model.ID);

            }
        } catch (Exception e) {
        }

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

    public ActionResult DeleteMaterialDetailRevision(LTWorkRequest model) {
        var modelMaterialDetail = model.LTMaterial;
        int newWorkRequestID = model.ID;

        if (Session["CreateNewRevision"].ToString() == "true") {
            Session["CreateNewRevision"] = "false";

            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            modelMaterialDetail.LTWorkRequestID = newWorkRequestID;

            // Any update will be a new entry
            LotTravDMO.DeleteMaterialDetailRevision(modelMaterialDetail.ID);
            // TODO
            // Send email to the Originator and Group of People
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        } else {
            if (modelMaterialDetail != null && ModelState.IsValid) {
                LotTravDMO.DeleteMaterialDetail(modelMaterialDetail.ID);
            }
        }

        return Content(newWorkRequestID.ToString());
    }

    public ActionResult GetHoldSteps([DataSourceRequest] DataSourceRequest request, int workRequestID) {
        return Json(LotTravDMO.GetHoldSteps(workRequestID).ToDataSourceResult(request));
    }

    public ActionResult InsertHoldStep([DataSourceRequest] DataSourceRequest request, LTHoldStep model) {
        if (model != null && ModelState.IsValid) {
            model.UpdatedBy = (int)Session[GlobalVars.SESSION_USERID];
            LotTravDMO.InsertHoldStep(model);
        }

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

    public ActionResult UpdateHoldStepRevision(LTWorkRequest model) {
        var holdStepModel = model.LTHoldStep;
        int newWorkRequestID = model.ID;

        if (Session["CreateNewRevision"].ToString() == "true") {
            Session["CreateNewRevision"] = "false";

            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            holdStepModel.LTWorkRequestID = newWorkRequestID;

            // Any update will be a new entry
            LotTravDMO.UpdateHoldStepRevision(holdStepModel);
            // TODO
            // Send email to the Originator and Group of People
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        } else {
            if (holdStepModel != null && ModelState.IsValid) {
                holdStepModel.UpdatedBy = (int)Session[GlobalVars.SESSION_USERID];
                LotTravDMO.UpdateHoldStep(holdStepModel);
            }
        }

        return Content(newWorkRequestID.ToString());
    }

    public ActionResult InsertHoldStepRevision(LTWorkRequest model) {
        var holdStepModel = model.LTHoldStep;
        int newWorkRequestID = model.ID;

        if (Session["CreateNewRevision"].ToString() == "true") {
            Session["CreateNewRevision"] = "false";

            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            holdStepModel.LTWorkRequestID = newWorkRequestID;

            // Any update will be a new entry
            LotTravDMO.InsertHoldStepRevision(holdStepModel);
            // TODO
            // Send email to the Originator and Group of People
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        } else {
            if (holdStepModel != null && ModelState.IsValid) {
                holdStepModel.UpdatedBy = (int)Session[GlobalVars.SESSION_USERID];
                LotTravDMO.InsertHoldStep(holdStepModel);
            }
        }

        return Content(newWorkRequestID.ToString());
    }

    public ActionResult DeleteHoldStepRevision(LTWorkRequest model) {
        var holdStepModel = model.LTHoldStep;
        int newWorkRequestID = model.ID;

        if (Session["CreateNewRevision"].ToString() == "true") {
            Session["CreateNewRevision"] = "false";

            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            holdStepModel.LTWorkRequestID = newWorkRequestID;

            // Any update will be a new entry
            LotTravDMO.DeleteHoldStepRevision(holdStepModel.ID);
            // TODO
            // Send email to the Originator and Group of People
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        } else {
            if (holdStepModel != null && ModelState.IsValid) {

                LotTravDMO.DeleteHoldStep(holdStepModel.ID, (int)Session[GlobalVars.SESSION_USERID]);
            }
        }

        return Content(newWorkRequestID.ToString());
    }

    public void UpdateHoldStep(LTHoldStep model) {
        if (model != null && ModelState.IsValid) {
            LotTravDMO.UpdateHoldStep(model);
        }
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteHoldStep([DataSourceRequest] DataSourceRequest request, LTHoldStep model) {
        try {
            if (model != null && ModelState.IsValid) {
                LotTravDMO.DeleteHoldStep(model.ID, (int)Session[GlobalVars.SESSION_USERID]);

            }
        } catch (Exception ex) {
            return this.Json(new DataSourceResult {
                Errors = ex.Message
            });
        }

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

    public ActionResult GetHoldStep(int holdStepID) {
        var model = new LTHoldStep();
        model = LotTravDMO.GetHoldStep(holdStepID);

        return PartialView("_HoldStepAttachments", model);
    }

    public ActionResult GetHoldStepRevision(int holdStepID) {
        var model = new LTHoldStep();
        model = LotTravDMO.GetHoldStep(holdStepID);

        return PartialView("_HoldStepAttachmentsRevision", model);
    }

    public ActionResult GetLotTravHoldStepRevision(int ltHoldStepID) {
        var model = new LTLotTravelerHoldSteps();
        model = LotTravDMO.GetLotTravHoldStep(ltHoldStepID);
        return PartialView("_LotTravHoldStepAttachRev", model);
    }

    public ActionResult GetHoldStepAttachments([DataSourceRequest] DataSourceRequest request, int holdStepID) {
        return Json(LotTravDMO.GetHoldStepAttachemnts(holdStepID).ToDataSourceResult(request));
    }

    public ActionResult GetLTHoldStepAttachments([DataSourceRequest] DataSourceRequest request, int ltHoldStepID) {
        return Json(LotTravDMO.GetLotTravHoldStepAttachemnts(ltHoldStepID).ToDataSourceResult(request));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteHoldStepAttachment([DataSourceRequest] DataSourceRequest request, LTWorkRequestAttachment model) {
        try {
            if (model != null && ModelState.IsValid) {
                LotTravDMO.DeleteWorkRequestAttachment(model.ID);

            }
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Delete =" + model.ID.ToString() + "  " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n AttachmentID Work Request\r\n" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { UserID = @User.Identity.Name, OperationType = "Error", Comments = exceptionString });
            throw new Exception(e.Message);
        }

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

    public ActionResult GetWorkRequestAttachments([DataSourceRequest] DataSourceRequest request, int workRequestID) {
        return Json(LotTravDMO.GetWorkRequestAttachments(workRequestID).ToDataSourceResult(request));
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult UpdateWorkRequestAttachment([DataSourceRequest] DataSourceRequest request, LTWorkRequestAttachment model) {
        if (model != null && ModelState.IsValid) {
            LotTravDMO.UpdateWorkRequestAttachment(model);
        }

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

    public ActionResult UpdateWorkRequestAttachmentRevision(LTWorkRequest model) {
        var wrAttachmentDetail = model.WorkRequestAttachment;
        int previousWorkRequestAttachmentID = model.WorkRequestAttachment.ID;
        int newWorkRequestID = model.ID;

        if (Session["CreateNewRevision"].ToString() == "true") {
            Session["CreateNewRevision"] = "false";

            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            wrAttachmentDetail.WorkRequestID = newWorkRequestID;

            // Any update will be a new entry
            LotTravDMO.UpdateWorkRequestAttachmentRevision(wrAttachmentDetail, previousWorkRequestAttachmentID);
            // TODO
            // Send email to the Originator and Group of People
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        } else {
            if (wrAttachmentDetail != null && ModelState.IsValid) {
                LotTravDMO.UpdateWorkRequestAttachment(wrAttachmentDetail);
            }
        }

        return Content(newWorkRequestID.ToString());
    }

    [AcceptVerbs(HttpVerbs.Post)]
    public ActionResult DeleteWorkRequestAttachment([DataSourceRequest] DataSourceRequest request, LTWorkRequestAttachment model) {
        try {
            if (model != null && ModelState.IsValid) {
                LotTravDMO.DeleteWorkRequestAttachment(model.ID);

            }
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Delete =" + model.ID.ToString() + "  " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n AttachmentID WorkRequiest\r\n" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { UserID = @User.Identity.Name, OperationType = "Error", Comments = exceptionString });
            throw new Exception(e.Message);
        }

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

    public ActionResult DeleteWorkRequestAttachmentRevision(LTWorkRequest model) {
        var wrAttachmentDetail = model.WorkRequestAttachment;
        int previousWorkRequestAttachmentID = model.WorkRequestAttachment.ID;
        int newWorkRequestID = model.ID;

        if (Session["CreateNewRevision"].ToString() == "true") {
            Session["CreateNewRevision"] = "false";

            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            wrAttachmentDetail.WorkRequestID = newWorkRequestID;

            // Any update will be a new entry
            LotTravDMO.DeleteWorkRequestAttachmentRevision(wrAttachmentDetail.ID);
            // TODO
            // Send email to the Originator and Group of People
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        } else {
            if (wrAttachmentDetail != null && ModelState.IsValid) {
                LotTravDMO.DeleteWorkRequestAttachment(wrAttachmentDetail.ID);
            }
        }

        return Content(newWorkRequestID.ToString());
    }

    public ActionResult AttachSaveWorkRequest(IEnumerable<HttpPostedFileBase> files, int workRequestID, int currentRevision, int swrNo, string comments, string docType) {
        // The Name of the Upload component is "files"
        if (files != null) {
            int userId = (int)Session[GlobalVars.SESSION_USERID];
            foreach (var file in files) {
                LotTravelerHelper.AttachSaveWorkRequest(_AppSettings, LotTravDMO, workRequestID, swrNo, comments, docType, userId, file.FileName, file.InputStream);
            }
        }
        return Content("");
    }

    public ActionResult AttachSaveWorkRequestRevision(IEnumerable<HttpPostedFileBase> files, int workRequestID, int currentRevision, int swrNo, string revComments, string docType, string attachComments) {
        bool newRevision = false;
        int newWorkRequestID = -1;
        int isITARCompliant = 1;
        LTWorkRequest model = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
        model.RevisionComments = revComments;

        if (Session["CreateNewRevision"].ToString() == "true") {
            newRevision = true;
            Session["CreateNewRevision"] = "false";
            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);

            // Send email to the Originator and Group of People
            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        }

        // The Name of the Upload component is "files"
        if (files != null) {
            int userId = (int)Session[GlobalVars.SESSION_USERID];
            foreach (var file in files) {
                LotTravelerHelper.AttachSaveWorkRequestRevision(_AppSettings, LotTravDMO, workRequestID, swrNo, docType, attachComments, newRevision, userId, file.FileName, file.InputStream);
            }
        }
        return Content("");
    }

    public ActionResult HoldStepAttachSave(IEnumerable<HttpPostedFileBase> HoldStepAttachment, int holdStepID, int currentRevision, int swrNo, string docType, string comments) {
        // The Name of the Upload component is "files"
        try {
            if (HoldStepAttachment != null) {
                int userId = (int)Session[GlobalVars.SESSION_USERID];
                foreach (var file in HoldStepAttachment) {
                    LotTravelerHelper.HoldStepAttachSave(_AppSettings, LotTravDMO, holdStepID, swrNo, docType, comments, userId, file.FileName, file.InputStream);
                }
            }
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "HoldStep=" + holdStepID.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n Approve\r\n" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = holdStepID, UserID = @User.Identity.Name, DocumentType = docTypeString, OperationType = "Error", Comments = "HoldStep Attachment - " + exceptionString });
            throw new Exception(e.Message);
        }
        return Content("");
    }

    public ActionResult HoldStepAttachSaveRev(IEnumerable<HttpPostedFileBase> HoldStepAttachment, int workRequestID, int holdStepID, int currentRevision, int swrNo, string docType, string comments, string revComments) {
        // The Name of the Upload component is "files"
        bool newRevision = false;
        int newWorkRequestID = -1;
        int isITARCompliant = 1;
        LTWorkRequest model = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
        model.RevisionComments = revComments;

        if (Session["CreateNewRevision"].ToString() == "true") {
            newRevision = true;
            Session["CreateNewRevision"] = "false";
            newWorkRequestID = LotTravDMO.CreateWorkRequestRevision(model, (int)Session[GlobalVars.SESSION_USERID]);

            NotifyfWorkRequestRevisionChange(newWorkRequestID);
        }

        try {
            if (HoldStepAttachment != null) {
                int userId = (int)Session[GlobalVars.SESSION_USERID];
                foreach (var file in HoldStepAttachment) {
                    LotTravelerHelper.HoldStepAttachSaveRev(_AppSettings, LotTravDMO, holdStepID, swrNo, docType, comments, newRevision, userId, file.FileName, file.InputStream);
                }
            }
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "HoldStep=" + holdStepID.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n Approve\r\n" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = holdStepID, UserID = @User.Identity.Name, DocumentType = docTypeString, OperationType = "Error", Comments = "HoldStep Attachment - " + exceptionString });
            throw new Exception(e.Message);
        }
        return Content("");
    }

    public int GetRevisedWrkReqIDFromHoldStepID(int prevHoldStepID) {
        return LotTravDMO.GetRevisedWrkReqIDFromHoldStepID(prevHoldStepID);
    }

    public int GetRevisedWrkReqIDFromPreviousWrkReqID(int prevWorkRequestID) {
        return LotTravDMO.GetRevisedWrkReqIDFromPreviousWrkReqID(prevWorkRequestID);
    }

    public JsonResult GetWorkRequestAttachDetail(int wrAttachmentID) {
        LTWorkRequestAttachment data = LotTravDMO.GetWorkRequestAttachDetail(wrAttachmentID);
        return Json(data, JsonRequestBehavior.AllowGet);
    }

    public ActionResult SubmitDocument(int workRequestID, int documentType) {
        int isITARCompliant = 1;
        LTWorkRequest ltWR = new LTWorkRequest();
        try {
            int appoverCount = LotTravDMO.SubmitDocument(workRequestID, (int)Session[GlobalVars.SESSION_USERID], documentType, out isITARCompliant);
            if (isITARCompliant == 0) // not ITAR Compliant
            {
                return View("UnAuthorizedAccess");
            } else {
                if (appoverCount > 0) {
                    NotifyApprovers(workRequestID, (byte)GlobalVars.WorkFLowStepNumber.Step1, documentType);
                } else {
                    // automaically approve current step (Step 1) beacuase there are no approvers in step 1 and move to the next step of approval
                    Approve(workRequestID, (byte)GlobalVars.WorkFLowStepNumber.Step1, "", documentType); // this is the Submit Level Approval

                }

                ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

                List<ApproversListViewModel> userList = MiscDMO.GetPendingApproversListByDocument(workRequestID, ltWR.CurrentStep, (int)documentType);
                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] == ltWR.OriginatorID)
                    ViewBag.IsOriginator = "true";
                else
                    ViewBag.IsOriginator = "false";

                if (Request.IsAjaxRequest()) {
                    // the content gets evaluated on the client side
                    return Content("Redirect");
                } else
                    return Content("Invalid");

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

    public void Approve(int workRequestID, byte currentStep, string comments, int documentType) {
        LTWorkRequest ltWR = new LTWorkRequest();
        int isITAR = 1;
        ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITAR, (int)Session[GlobalVars.SESSION_USERID]);
        try {
            bool lastStep = false;
            bool lastApprover = wfDMO.Approve(_AppSettings, workRequestID, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType, ltWR.WorkFlowNumber);

            while (lastApprover && !lastStep) {
                currentStep++;
                lastApprover = wfDMO.Approve(_AppSettings, workRequestID, currentStep, comments, out lastStep, (int)Session[GlobalVars.SESSION_USERID], documentType, ltWR.WorkFlowNumber);
                NotifyApprovers(workRequestID, currentStep, documentType);
            }

            if (lastApprover && lastStep) {
                // Send email to the Originator and different groups
                NotifyApprovalOfWorkRequest(workRequestID);
            }

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

    public void Reject(int workRequestID, byte currentStep, string comments, int docType) {
        LTWorkRequest ltWR = new LTWorkRequest();
        int isITARCompliant = 1;
        ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
        try {
            if (Session[GlobalVars.SESSION_USERID] != null) {
                wfDMO.Reject(workRequestID, currentStep, comments, (int)Session[GlobalVars.SESSION_USERID], docType);
                NotifyRejectionToOrginator(workRequestID);
            } else {
                Response.Redirect("~/Account/Login");
            }
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + workRequestID.ToString() + " Step:" + currentStep + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n Reject\r\n" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Error", Comments = "Reject - " + exceptionString });
            throw new Exception(e.Message);
        }
    }

    public void NotifyRejectionToOrginator(int workRequestID) {
        int isITARCompliant = 0;
        string username = Session[GlobalVars.SESSION_USERNAME].ToString();
        List<string> emailIst = LotTravDMO.GetRejectionOrginatorEmailList(workRequestID).Distinct().ToList();
        LTWorkRequest ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
        string userEmail = LotTravelerHelper.NotifyRejectionToOrginator(_AppSettings, @User.Identity.Name, workRequestID, username, emailIst, ltWR);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Email", Comments = "Rejection: " + userEmail });
        } catch { }
    }

    public void NotifyApprovers(int workRequestID, byte currentStep, int documentType) {
        string emailSentList = "";
        int isITARCompliant = 0;
        LTWorkRequest ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

        List<string> emailIst = MiscDMO.GetApproverEmailListByDocument(workRequestID, currentStep, documentType).Distinct().ToList();
        emailSentList = LotTravelerHelper.NotifyApprovers(_AppSettings, @User.Identity.Name, workRequestID, emailSentList, ltWR, emailIst);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Email", Comments = "Approvers for Step " + currentStep.ToString() + ":" + emailSentList });
        } catch { }
    }

    public void NotifyApprovalOfWorkRequest(int workRequestID) {
        string emailSentList = "";
        int isITARCompliant = 0;
        LTWorkRequest ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);

        List<string> emailIst = MiscDMO.GetWorkRequestApprovedNotifyList((int)GlobalVars.NotificationType.WorkRequest, workRequestID, (int)Session[GlobalVars.SESSION_USERID]).Distinct().ToList();
        emailSentList = LotTravelerHelper.NotifyApprovalOfWorkRequest(_AppSettings, @User.Identity.Name, workRequestID, emailSentList, ltWR, emailIst);

        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Email", Comments = "Approvers for WorkRequest: " + emailSentList });
        } catch { }
    }

    public void NotifyfWorkRequestRevisionChange(int workRequestID) {
        string emailSentList = "";
        int isITARCompliant = 0;
        int currentUserID = (int)Session[GlobalVars.SESSION_USERID];
        LTWorkRequest ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, currentUserID);

        List<string> emailIst = MiscDMO.GetWorkRequestRevisionNotifyList((int)GlobalVars.NotificationType.WorkRequest, workRequestID, currentUserID).Distinct().ToList();
        emailSentList = LotTravelerHelper.NotifyfWorkRequestRevisionChange(_AppSettings, @User.Identity.Name, workRequestID, emailSentList, ltWR, emailIst);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Email", Comments = "Work Request Revision Change for  :" + emailSentList });
        } catch { }
    }

    public void NotifyLotTravelerRevisionChange(int ltLotID, int revisionNumber) {
        string emailSentList = "";
        LTLotTravelerHeaderViewModel data = LotTravDMO.GetLotTravelerHeaderForReadOnly(ltLotID, revisionNumber);
        int currentUserID = (int)Session[GlobalVars.SESSION_USERID];
        List<string> emailIst = MiscDMO.GetLotTravelerCreationAndRevisionNotifyList(ltLotID, data.LTWorkRequestID, currentUserID).Distinct().ToList();
        emailSentList = LotTravelerHelper.NotifyLotTravelerRevisionChange(_AppSettings, @User.Identity.Name, emailSentList, data, emailIst);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = data.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Email", Comments = "Lot Traveler Revision Change Notification:" + emailSentList });
        } catch { }
    }

    public void NotifyLotTravelerCreation(int ltLotID, int revisionNumber) {
        string emailSentList = "";
        LTLotTravelerHeaderViewModel data = LotTravDMO.GetLotTravelerHeaderForReadOnly(ltLotID, revisionNumber);
        int currentUserID = (int)Session[GlobalVars.SESSION_USERID];
        List<string> emailIst = MiscDMO.GetLotTravelerCreationAndRevisionNotifyList(ltLotID, data.LTWorkRequestID, currentUserID).Distinct().ToList();
        emailSentList = LotTravelerHelper.NotifyLotTravelerCreation(_AppSettings, @User.Identity.Name, emailSentList, data, emailIst);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = data.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Email", Comments = "Lot Traveler Revision Change Notification:" + emailSentList });
        } catch { }
    }

    public ActionResult GetApproversList([DataSourceRequest] DataSourceRequest request, int workRequestID, byte step) {
        return Json(MiscDMO.GetApproversListByDocument(workRequestID, step, (int)GlobalVars.DocumentType.LotTraveler).ToDataSourceResult(request));
    }

    public void ReleaseLockOnDocument(int workRequestID) {
        LotTravDMO.ReleaseLockOnDocument((int)Session[GlobalVars.SESSION_USERID], workRequestID);
    }

    public void ReleaseLockOnLotTravelerUpdateDoc(int lotID) {
        try {
            LotTravDMO.ReleaseLockOnLotTravelerUpdateDoc((int)Session[GlobalVars.SESSION_USERID], lotID);
        } catch {
            // TODO
            // unlock the current revision of the Lot traveler
            LotTravDMO.ReleaseLockOnLotTravelerUpdateDoc(-1, lotID);
        }
    }

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

    public void ReAssignApproverByAdmin(int workRequestID, int reAssignApproverFrom, int reAssignApproverTo, byte step, int docType) {
        var email = "";
        int isITARCompliant = 0;
        LTWorkRequest ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
        try {
            email = wfDMO.ReAssignApproval(workRequestID, reAssignApproverFrom, reAssignApproverTo, step, docType);
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + workRequestID.ToString() + " Step:" + step + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReAssignApproval\r\n" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Error", Comments = "ReAssignApproval - " + exceptionString });
            throw new Exception(e.Message);
        }
        LotTravelerHelper.ReAssignApproverByAdmin(_AppSettings, @User.Identity.Name, workRequestID, email, ltWR);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Email", Comments = "ReAssign Approver: " + email });
        } catch { }
    }

    public void ReAssignApproval(int workRequestID, int userIDs, byte step, int docType) {
        var email = "";
        int isITARCompliant = 0;
        LTWorkRequest ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
        try {
            email = wfDMO.ReAssignApproval(workRequestID, (int)Session[GlobalVars.SESSION_USERID], userIDs, step, docType);
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + workRequestID.ToString() + " Step:" + step + " " + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n ReAssignApproval\r\n" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Error", Comments = "ReAssignApproval - " + exceptionString });
            throw new Exception(e.Message);
        }
        LotTravelerHelper.ReAssignApproval(_AppSettings, @User.Identity.Name, workRequestID, email, ltWR);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Email", Comments = "ReAssign Approver: " + email });
        } catch { }
    }

    public void AddAdditionalApproval(int workRequestID, byte step, string userIDs, int docType) {
        string emailSentList = "";
        var emailArray = "";
        int isITARCompliant = 0;
        LTWorkRequest ltWR = LotTravDMO.GetLTWorkRequestItemForRead(workRequestID, out isITARCompliant, (int)Session[GlobalVars.SESSION_USERID]);
        try {
            emailArray = wfDMO.AddAdditionalApproval(workRequestID, userIDs, step, docType);
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "Issue=" + workRequestID.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" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Error", Comments = "AddAdditionalApproval - " + exceptionString });
            throw new Exception(e.Message);
        }
        emailSentList = LotTravelerHelper.AddAdditionalApproval(_AppSettings, @User.Identity.Name, workRequestID, emailSentList, emailArray, ltWR);
        try {
            EventLogDMO.Add(new WinEventLog() { IssueID = ltWR.SWRNumber, UserID = @User.Identity.Name, DocumentType = "Work Request", OperationType = "Email", Comments = "Additonal Approver: " + emailSentList });
        } catch { }
    }

    public JsonResult AddLots(string lotNumbers, int workRequestID) {
        IssueWithExistingLotsViewModel issueWEL = new IssueWithExistingLotsViewModel();
        try {
            if (lotNumbers.Length > 0) {
                string[] tempLots = lotNumbers.Split(new char[] { '~' });
                foreach (string lotNumber in tempLots) {
                    LTLot l = new LTLot();
                    l.LotNumber = lotNumber;
                    l.WorkRequestID = workRequestID;
                    l.LotUploadedBy = (int)Session[GlobalVars.SESSION_USERID];
                    LotTravDMO.InsertLot(l);
                    if (l.WRWithExistingLot != 0) {
                        issueWEL.LotList += l.LotNumber + "~";
                        issueWEL.IssuesList += l.WRWithExistingLot.ToString() + "~";
                    }
                }
            }

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

        return Json(issueWEL, JsonRequestBehavior.AllowGet);
    }

    public JsonResult SearchLots(string searchText, string searchBy) {
        List<String> lotlist = MiscDMO.SearchLTLots(searchText, searchBy).Select(x => x.LotNumber).ToList<String>();
        return Json(lotlist, JsonRequestBehavior.AllowGet);
    }

    public JsonResult SearchParts(string searchText) {
        List<String> partList = MiscDMO.SearchLTParts(searchText.Trim()).Select(x => x.WIPPartData).ToList<String>();
        return Json(partList, JsonRequestBehavior.AllowGet);
    }

    public ActionResult GetLotList([DataSourceRequest] DataSourceRequest request, int workRequestID) {
        return Json(LotTravDMO.GetLotList(workRequestID).ToDataSourceResult(request));
    }

    public void CreateTaveler(int ltLotID, int workRequestID) {
        try {
            LotTravDMO.CreateTraveler(ltLotID, workRequestID, (int)Session[GlobalVars.SESSION_USERID]);

            // Thread.Sleep(10000);
            NotifyLotTravelerCreation(ltLotID, -1);
        } catch (Exception ex) {
            EventLogDMO.Add(new WinEventLog() { IssueID = workRequestID, UserID = @User.Identity.Name, DocumentType = "LotTraveler", OperationType = "CreateTaveler", Comments = ex.Message });
            throw new Exception(ex.Message);
        }
    }

    public JsonResult GetLotTravelerHeader(int ltLotID) {
        LTLotTravelerHeaderViewModel data = new LTLotTravelerHeaderViewModel();
        data = LotTravDMO.GetLotTravelerHeaderForUpdate(ltLotID, (int)Session[GlobalVars.SESSION_USERID]);
        return Json(data, JsonRequestBehavior.AllowGet);
    }

    public ActionResult GetLotTravRevisions(int ltLotID) {
        return Json(LotTravDMO.GetLotTravRevisions(ltLotID), JsonRequestBehavior.AllowGet);
    }

    public ActionResult DisplayLotTraveler(int ltLotID) {
        LTLotTravelerHeaderViewModel data = new LTLotTravelerHeaderViewModel();
        data = LotTravDMO.GetLotTravelerHeaderForUpdate(ltLotID, (int)Session[GlobalVars.SESSION_USERID]);

        ViewBag.LotTravRevisionList = LotTravDMO.GetLotTravRevisions(ltLotID);
        ViewBag.LotList = LotTravDMO.GetLotsWithTraveler(data.LTWorkRequestID);

        if (data.RecordLockIndicator && data.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID]) {
            // redirect to a readonly Lot Travler
            return Content("Readonly" + "~" + data.LotTravCurrentRevision.ToString());
        } else
            return Content("Update");
    }

    public ActionResult LotTravelerUpdate(int ltLotID) {

        LTLotTravelerHeaderViewModel data = new LTLotTravelerHeaderViewModel();
        data = LotTravDMO.GetLotTravelerHeaderForUpdate(ltLotID, (int)Session[GlobalVars.SESSION_USERID]);

        if (data.TravelerClosedDate != null) {
            return RedirectToAction("LotTravelerReadOnly", new { ltLotID = ltLotID, revisionNumber = -1 });
        }

        ViewBag.LotTravRevisionList = LotTravDMO.GetLotTravRevisions(ltLotID);
        ViewBag.LotList = LotTravDMO.GetLotsWithTraveler(data.LTWorkRequestID);

        Session["CreateLotTravNewRevision"] = "true";
        return View(data);
    }

    public ActionResult LotTravelerReadonly(int ltLotID, int revisionNumber) {
        LTLotTravelerHeaderViewModel data = new LTLotTravelerHeaderViewModel();
        data = LotTravDMO.GetLotTravelerHeaderForReadOnly(ltLotID, revisionNumber);

        if (data.IsCurrentRevision && (!data.RecordLockIndicator)) {
            return RedirectToAction("LotTravelerUpdate", new { ltLotID = ltLotID });
        }

        ViewBag.LotTravRevisionList = LotTravDMO.GetLotTravRevisions(ltLotID);
        ViewBag.LotList = LotTravDMO.GetLotsWithTraveler(data.LTWorkRequestID);
        return View(data);
    }

    public ActionResult DisplayLotTravelerForExecute(int ltLotID) {
        LTLotTravelerHeaderViewModel data = new LTLotTravelerHeaderViewModel();
        data = LotTravDMO.GetLotTravelerHeaderForUpdate(ltLotID, (int)Session[GlobalVars.SESSION_USERID]);
        ViewBag.LotTravRevisionList = LotTravDMO.GetLotTravRevisions(ltLotID);
        ViewBag.LotList = LotTravDMO.GetLotsWithTraveler(data.LTWorkRequestID);

        if (data.RecordLockIndicator && data.RecordLockedBy != (int)Session[GlobalVars.SESSION_USERID]) {
            // redirect to a readonly Lot Travler
            return Content("Readonly" + "~" + data.LotTravCurrentRevision.ToString());
        } else
            return Content("Execute");
    }

    public ActionResult LotTravelerExecute(int ltLotID) {
        LTLotTravelerHeaderViewModel data = new LTLotTravelerHeaderViewModel();
        data = LotTravDMO.GetLotTravelerHeaderForUpdate(ltLotID, (int)Session[GlobalVars.SESSION_USERID]);
        ViewBag.LotTravRevisionList = LotTravDMO.GetLotTravRevisions(ltLotID);
        ViewBag.LotList = LotTravDMO.GetLotsWithTraveler(data.LTWorkRequestID);

        return View(data);
    }

    public ActionResult GetLotTravHoldSteps([DataSourceRequest] DataSourceRequest request, int LotID) {
        return Json(LotTravDMO.GetLotTravHoldSteps(LotID).ToDataSourceResult(request));
    }

    public ActionResult GetLotTravHoldStepsPending([DataSourceRequest] DataSourceRequest request, int LotID) {
        return Json(LotTravDMO.GetLotTravHoldStepsPending(LotID).ToDataSourceResult(request));
    }

    public ActionResult GetLotTravHoldStepsCompleted([DataSourceRequest] DataSourceRequest request, int LotID) {
        return Json(LotTravDMO.GetLotTravHoldStepsCompleted(LotID).ToDataSourceResult(request));
    }

    public void UpdateLotTravlerExecution(int currentHoldStepID, string taskComments, bool taskcompleted) {
        LotTravDMO.UpdateLotTravlerExecution(currentHoldStepID, taskComments, taskcompleted, (int)Session[GlobalVars.SESSION_USERID]);
    }

    public ActionResult GetLotTravHoldStepsByRevision([DataSourceRequest] DataSourceRequest request, int LotID, int revisionNumber) {
        return Json(LotTravDMO.GetLotTravelerHolStepsByRevision(LotID, revisionNumber).ToDataSourceResult(request));
    }

    public ActionResult UpdateLotTravHoldStepRevision(LTLotTravelerHoldSteps ltHoldStepObj) {
        int prevLotTravRevID = ltHoldStepObj.LotTravelerRevisionID;
        int newLotTravRevID = 1;
        try {
            if (Session["CreateLotTravNewRevision"].ToString() == "true") {
                // Create a new Revision
                Session["CreateLotTravNewRevision"] = "false";
                newLotTravRevID = LotTravDMO.CreateLotTravelerRevision(ltHoldStepObj, (int)Session[GlobalVars.SESSION_USERID]);

                try {

                    LotTravDMO.UpdateRevisedLotTravelerHoldStep(ltHoldStepObj, (int)Session[GlobalVars.SESSION_USERID]);
                } catch {

                    LotTravDMO.RestoreLotTravToPrevRevision(prevLotTravRevID, newLotTravRevID);
                    throw new Exception("There was a problem while creating the revision, Please try againm,. \n If the problem persist please contact the Site Administrator");
                }

                // send a notification
                // - 1 indicates to return the current revision
                NotifyLotTravelerRevisionChange(ltHoldStepObj.LTLotID, -1);
            } else {
                int result = LotTravDMO.UpdateLotTravelerHoldStep(ltHoldStepObj, (int)Session[GlobalVars.SESSION_USERID]);
                if (result == -1) {
                    throw new Exception("Cannot add the Hold Step as the step has already been passed in the Mfg Process.");
                }
            }
        } catch (Exception ex) {
            return Content(ex.Message);
        }

        return Content(GlobalVars.SUCCESS);
    }

    public ActionResult InsertLotTravHoldStepRevision(LTLotTravelerHoldSteps ltHoldStepObj) {
        int prevLotTravRevID = ltHoldStepObj.LotTravelerRevisionID;
        int newLotTravRevID = -1;
        try {
            if (Session["CreateLotTravNewRevision"].ToString() == "true") {
                // Create a new Revision
                Session["CreateLotTravNewRevision"] = "false";

                int result = LotTravDMO.CanAddLocationOperation(ltHoldStepObj);
                if (result == -1) {
                    Session["CreateLotTravNewRevision"] = "true";
                    throw new Exception("Cannot add the Hold Step as the step has already been passed in the Mfg Process.");
                }
                newLotTravRevID = LotTravDMO.CreateLotTravelerRevision(ltHoldStepObj, (int)Session[GlobalVars.SESSION_USERID]);
                ltHoldStepObj.LotTravelerRevisionID = newLotTravRevID;

                try {

                    LotTravDMO.InsertLotTravelerHoldStep(ltHoldStepObj, (int)Session[GlobalVars.SESSION_USERID]);
                } catch {
                    // roll back the revision creation
                    LotTravDMO.RestoreLotTravToPrevRevision(prevLotTravRevID, newLotTravRevID);
                    throw new Exception("There was a problem while creating the revision, Please logout and log back and then retry. \n If the problem persist please contact the Site Administrator");
                }

                // send a notification
                // - 1 indicates to return the current revision
                NotifyLotTravelerRevisionChange(ltHoldStepObj.LTLotID, -1);

            } else {
                int result = LotTravDMO.InsertLotTravelerHoldStep(ltHoldStepObj, (int)Session[GlobalVars.SESSION_USERID]);
                if (result == -1) {
                    throw new Exception("Cannot add the Hold Step as the step has already been passed in the Mfg Process.");
                }
            }
        } catch (Exception ex) {
            return Content(ex.Message);
        }

        return Content(GlobalVars.SUCCESS);
    }

    public ActionResult DeleteLotTravHoldStepRevision(LTLotTravelerHoldSteps ltHoldStepObj) {
        int prevLotTravRevID = ltHoldStepObj.LotTravelerRevisionID;
        int newLotTravRevID = -1;
        try {
            if (Session["CreateLotTravNewRevision"].ToString() == "true") {
                // Create a new Revision
                Session["CreateLotTravNewRevision"] = "false";
                newLotTravRevID = LotTravDMO.CreateLotTravelerRevision(ltHoldStepObj, (int)Session[GlobalVars.SESSION_USERID]);

                try {
                    LotTravDMO.DeleteLotTravHoldStepRevision(ltHoldStepObj.ID);
                } catch {
                    // roll back the revision creation
                    LotTravDMO.RestoreLotTravToPrevRevision(prevLotTravRevID, newLotTravRevID);
                    throw new Exception("There was a problem while creating the revision, Please logout and log back and then retry. \n If the problem persist please contact the Site Administrator");
                }

                // send a notification
                // - 1 indicates to return the current revision
                NotifyLotTravelerRevisionChange(ltHoldStepObj.LTLotID, -1);
            } else {
                LotTravDMO.DeleteLotTravHoldStep(ltHoldStepObj.ID);
            }
        } catch (Exception ex) {
            return Content(ex.Message);
        }

        return Content(GlobalVars.SUCCESS);
    }

    public void DeleteLot(int ltLotID) {
        LotTravDMO.DeleteLot(ltLotID);
    }

    ///
    public ActionResult DisplayLotTravlerPdf(int ltLotID, int revisionNumber) {
        LotTravelerPdf traveler = new LotTravelerPdf();
        try {
            traveler = LotTravDMO.GetLotTravlerPdf(ltLotID, revisionNumber);

            // 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("", "LotTravelerPDF", traveler);
        } catch (Exception ex) {
            EventLogDMO.Add(new WinEventLog() { IssueID = traveler.SWRNumber, UserID = @User.Identity.Name, DocumentType = "LotTraveler", OperationType = "Generate PDF", Comments = ex.Message });
            traveler = null;
            return Content("");
        }
    }

    public ActionResult ApprovalLogHistory_Read([DataSourceRequest] DataSourceRequest request, int swrNumber) {
        return Json(LotTravDMO.GetWorkReqApprovalLogHistory(swrNumber).ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }

    public ActionResult GetWorkRequestRevisionHistory([DataSourceRequest] DataSourceRequest request, int swrNumber) {
        return Json(LotTravDMO.GetWorkReqRevisionHistory(swrNumber).ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }

    public ActionResult GetLotTravelerRevisionHistory([DataSourceRequest] DataSourceRequest request, int lotID) {
        return Json(LotTravDMO.GetLotTravelerRevisionHistory(lotID).ToDataSourceResult(request), JsonRequestBehavior.AllowGet);
    }

    public ActionResult LotTravHoldStepAttachSaveRev(IEnumerable<HttpPostedFileBase> LotTravHoldStepAttachment, int ltHoldStepID, int swrNo, string docType, string revComments) {
        // The Name of the Upload component is "files"

        int prevLotTravRevID = -1;
        int newLotTravRevID = -1;

        bool newRevision = false;
        LTLotTravelerHoldSteps model = LotTravDMO.GetLotTravHoldStep(ltHoldStepID);
        prevLotTravRevID = model.LotTravelerRevisionID;

        model.RevisionComments = revComments;

        if (Session["CreateLotTravNewRevision"].ToString() == "true") {
            // Create a new Revision
            newRevision = true;
            Session["CreateLotTravNewRevision"] = "false";
            newLotTravRevID = LotTravDMO.CreateLotTravelerRevision(model, (int)Session[GlobalVars.SESSION_USERID]);
            model.LotTravelerRevisionID = newLotTravRevID;
        }

        try {
            if (LotTravHoldStepAttachment != null) {
                int userId = (int)Session[GlobalVars.SESSION_USERID];
                foreach (var file in LotTravHoldStepAttachment) {
                    LotTravelerHelper.LotTravHoldStepAttachSaveRev(_AppSettings, LotTravDMO, ltHoldStepID, swrNo, docType, prevLotTravRevID, newLotTravRevID, newRevision, userId, file.FileName, file.InputStream);
                }

                // send a notification
                // - 1 indicates to return the current revision
                if (newRevision) {
                    NotifyLotTravelerRevisionChange(model.LTLotID, -1);
                }
            }
        } catch (Exception e) {
            string exceptionString = e.Message.ToString().Trim().Length > 500 ? "LotTravHoldStep=" + ltHoldStepID.ToString() + e.Message.ToString().Substring(0, 250) : e.Message.ToString();
            Functions.WriteEvent(_AppSettings, @User.Identity.Name + "\r\n Attachment \r\n" + e.Message.ToString(), System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = ltHoldStepID, UserID = @User.Identity.Name, DocumentType = docTypeString, OperationType = "Error", Comments = "Lot Traveler HoldStep Attachment - " + exceptionString });
            throw new Exception(e.Message);
        }
        return Content("");
    }

    public bool IsWorkRequestDocLockedByUser(int workRequestID) {
        int result = LotTravDMO.IsWorkRequestDocLockedByUser(workRequestID, (int)Session[GlobalVars.SESSION_USERID]);
        if (result == 0)
            return false;
        else
            return true;
    }

    public ActionResult CloseTraveler(int ltLotID, string reason) {
        int result = LotTravDMO.CloseTraveler(ltLotID, (int)Session[GlobalVars.SESSION_USERID], reason);

        if (result == 1)
            return Content("C");
        else
            return Content("O");
    }

    public FileResult DownloadFile(string fileGuid, string swrNumber, int typeOfDoc) {
        string fileName = LotTravDMO.GetFileName(fileGuid, typeOfDoc);

        string fileExtension = fileName.Substring(fileName.LastIndexOf("."), fileName.Length - fileName.LastIndexOf("."));

        string ecnFolderPath = _AppSettings.AttachmentFolder + "LotTraveler\\" + swrNumber.ToString();
        var sDocument = System.IO.Path.Combine(ecnFolderPath, fileGuid + fileExtension);

        var FDir_AppData = _AppSettings.AttachmentFolder;
        if (!sDocument.StartsWith(FDir_AppData)) {
            // Ensure that we are serving file only inside the Fab2ApprovalAttachments folder
            // and block requests outside like "../web.config"
            throw new HttpException(403, "Forbidden");
        }

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

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

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

        try {
            LotTravDMO.ReassignOriginator(workRequestID, 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" + workRequestID.ToString() + "\r\n" + detailedException, System.Diagnostics.EventLogEntryType.Error);
            EventLogDMO.Add(new WinEventLog() { IssueID = workRequestID, UserID = @User.Identity.Name, DocumentType = "Lot Traveler", OperationType = "Error", Comments = "ReAssignOriginatorByAdmin - " + exceptionString });
            throw new Exception(e.Message);
        }
    }
}