using FI.FIC;
using Foresight.Fleet.Services;
using Foresight.Fleet.Services.Asset;
using Foresight.Fleet.Services.AssetHealth;
using Foresight.Fleet.Services.AssetHealth.WorkOrder;
using Foresight.Fleet.Services.Attachment;
using Foresight.Fleet.Services.Customer;
using Foresight.Fleet.Services.Inspection;
using Foresight.Fleet.Services.JobSite;
using Foresight.Fleet.Services.Partner;
using Foresight.ServiceModel;
using IronIntel.Contractor.Machines;
using IronIntel.Contractor.Maintenance;
using IronIntel.Contractor.MapView;
using IronIntel.Contractor.Users;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;
using System.Web;

namespace IronIntel.Contractor.Site.Maintenance
{
    public class WorkOrderBasePage : ContractorBasePage
    {
        const int MaxAttachmentSize = 1258291; //1.2M//1024 * 1024 * 2;
        const string OkResult = "OK";
        const string FailedResult = "Failed";

        protected void ProcessRequest(string methodName)
        {
            object result = null;

            if (methodName != null)
            {
                switch (methodName.ToUpper())
                {
                    case "GETWORKORDERS":
                        result = GetWorkOrders();
                        break;
                    case "GETWORKORDERLISTITEM":
                        result = GetWorkOrderListItem();
                        break;
                    case "SAVEWORKORDER":
                        result = SaveWorkOrder();
                        break;
                    case "DELETEWORKORDER":
                        result = DeleteWorkOrder();
                        break;
                    case "RESTOREDELETEWORKORDER":
                        result = RestoreDeleteWorkOrder();
                        break;
                    case "GETASSETCONTACTS":
                        result = GetAssetContacts();
                        break;
                    case "GETMACHINES":
                        result = GetMachines();
                        break;
                    case "GETWORKORDERINFO":
                        result = GetWorkOrderInfo();
                        break;
                    case "GETOPENWORKORDERID":
                        result = GetOpenWorkOrderID();
                        break;
                    case "GETSEGMENTS":
                        result = GetSegments();
                        break;
                    case "SAVESEGMENT":
                        result = SaveSegment();
                        break;
                    case "DELETESEGMENT":
                        result = DeleteSegment();
                        break;
                    case "GETSEGMENTDATASOURCE":
                        result = GetSegmentDataSource();
                        break;
                    case "GETSEGMENTDATASOURCE1":
                        result = GetSegmentDataSource1();
                        break;
                    case "GETCOMPONENTS":
                        result = GetComponents();
                        break;
                    case "GETJOBSITES":
                        result = GetJobsites();
                        break;
                    case "GETNONEASSIGNEDALERTS":
                        result = GetNoneAssignedAlerts();
                        break;
                    case "ADDORREMOVEALERTSFROMWORKORDER":
                        result = AddOrRemoveAlertsFromWorkOrder();
                        break;
                    case "GETATTACHMENTS":
                        result = GetAttachments();
                        break;
                    case "GETWORKORDERATTACHMENTS":
                        result = GetWorkOrderAttachments();
                        break;
                    case "ADDATTACHMENT":
                        result = AddAttachment();
                        break;
                    case "DELETEATTACHMENT":
                        result = DeleteAttachment();
                        break;
                    case "GETMACHINECONTACTS":
                        result = GetMachineContacts();
                        break;
                    case "SENDWORKORDER":
                        result = SendWorkOrder();
                        break;
                    case "GETINVOICENUMBER":
                        result = GetInvoiceNumber();
                        break;
                    case "GETALERTSFORWORKORDER":
                        result = GetAlertsForWorkOrder();
                        break;
                    case "GETASSETDETAILINFO":
                        result = GetAssetDetailInfo();
                        break;
                    case "GETPMSCHEDULESBYASSET":
                        result = GetPMSchedulesByAsset();
                        break;
                    case "GENERATEMANUALPMALERTS":
                        result = GenerateManualPMAlerts();
                        break;
                    case "GETWORKORDERSTATUSES":
                        result = GetWorkOrderStatuses();
                        break;
                    case "GETCOMMENTS":
                        result = GetComments();
                        break;
                    case "GETCOMMUNICATIONS":
                        result = GetCommunications();
                        break;
                    case "ADDWORKORDERCOMMUNICATION":
                        result = AddWorkOrderCommunication();
                        break;
                    case "GETCUSTOMERCONTACTS":
                        result = GetCustomerContacts();
                        break;
                    case "SAVEWORKORDERSTATUS":
                        result = SaveWorkOrderStatus();
                        break;
                    case "DELETEWORKORDERSTATUS":
                        result = DeleteWorkOrderStatus();
                        break;
                    case "UPDATEWOSTATUSTECHNICIANSAVAILABLE":
                        result = UpdateWOStatusTechniciansAvailable();
                        break;
                    case "UPDATEWOSTATUSAUTOTEXT":
                        result = UpdateWOStatusAutoText();
                        break;
                    case "GETFILTERDATASOURCE":
                        result = GetFilterDataSource();
                        break;
                    case "SETWORKORDERDEFAULT":
                        result = SetWorkOrderDefault();
                        break;
                    case "GETWORKORDERDEFAULT":
                        result = GetWorkOrderDefault();
                        break;
                    case "SETWORKORDERCOLLAPSED":
                        result = SetWorkOrderCollapsed();
                        break;
                    case "GETWORKORDERCOLLAPSED":
                        result = GetWorkOrderCollapsed();
                        break;
                    case "GETWOINSPECTITEMS":
                        result = GetWOInspectItems();
                        break;
                    case "SENDINTERNALCOMMENTS":
                        result = SendInternalComments();
                        break;
                    case "UPDATEWORKORDER":
                        result = UpdateWorkOrder();
                        break;
                    case "UPDATEWOATTACHMENTEXTENSION":
                        result = UpdateWOAttachmentExtension();
                        break;
                    case "UPDATEWOSTATUSTYPE":
                        result = UpdateWOStatusType();
                        break;
                    case "UPDATEWODEFAULTONOPEN":
                        result = UpdateWODefaultOnOpen();
                        break;
                    case "GETLOCATIONSANDDEPARTMENTS":
                        result = GetLocationsAndDepartments();
                        break;
                    case "GETDEPARTMENTS":
                        result = GetDepartments();
                        break;
                    case "GETWORKORDERTYPES":
                        result = GetWorkOrderTypes();
                        break;
                    case "GETPARTSSTATUSES":
                        result = GetPartsStatuses();
                        break;
                    case "GETLOCATIONS":
                        result = GetLocations();
                        break;
                    case "GETWORKORDERESTIMATES":
                        result = GetWorkOrderEstimates();
                        break;
                    case "SAVEWORKORDERESTIMATE":
                        result = SaveWorkOrderEstimate();
                        break;
                    case "PUBLISHESTIMATETOCUSTOMER":
                        result = PublishEstimateToCustomer();
                        break;
                    case "UPDATEWOESTIMATEVISIBLETOCUSTOMER":
                        result = UpdateWOEstimateVisibleToCustomer();
                        break;
                    case "DELETEWORKORDERESTIMATE":
                        result = DeleteWorkOrderEstimate();
                        break;
                    case "REVOKEWORKORDERESTIMATE":
                        result = RevokeWorkOrderEstimate();
                        break;
                    case "ADDESTIMATEATTACHMENT":
                        result = AddEstimateAttachment();
                        break;
                    case "DELETEESTIMATEATTACHMENT":
                        result = DeleteEstimateAttachment();
                        break;
                    case "UPDATEINSPECTIONVISIBLETOCUSTOMER":
                        result = UpdateInspectionVisibleToCustomer();
                        break;
                    case "GETESTIMATEATTACHMENT":
                        result = GetEstimateAttachment();
                        break;
                    case "GETSURVEYTEMPLATEITEMS":
                        result = GetSurveyTemplateItems();
                        break;
                    case "GETSURVEYTEMPLATEINFO":
                        result = GetSurveyTemplateInfo();
                        break;
                    case "SAVESURVEYTEMPLATE":
                        result = SaveSurveyTemplate();
                        break;
                    case "DELETESURVEYTEMPLATE":
                        result = DeleteSurveyTemplate();
                        break;
                    case "SENDWORKORDERSURVEYS":
                        result = SendWorkOrderSurveys();
                        break;
                    case "CREATEWORKORDERSURVEYSBYCONTACTS":
                        result = CreateWorkOrderSurveysByContacts();
                        break;
                    case "GETWORKORDERSURVEYS":
                        result = GetWorkOrderSurveys();
                        break;
                    case "GETWORKORDERSURVEYSBYIDS":
                        result = GetWorkOrderSurveysByIDs();
                        break;
                    case "GETWORKORDERSURVEYRESULT":
                        result = GetWorkOrderSurveyResult();
                        break;
                    case "UPDATEINSPECTIONWORKORDER":
                        result = UpdateInspectionWorkOrder();
                        break;
                    case "GETSURVEYTEMPLATEREPORT":
                        result = GetSurveyTemplateReport();
                        break;
                    case "GETSURVEYTEMPLATEEMAIL":
                        result = GetSurveyTemplateEmail();
                        break;
                    case "UPDATECOMMUNICATIONACKNOWLEDGED":
                        result = UpdateCommunicationAcknowledged();
                        break;
                    case "UPDATEESTIMATEACKNOWLEDGED":
                        result = UpdateEstimateAcknowledged();
                        break;
                    case "GETWORKORDERINVOICES":
                        result = GetWorkOrderInvoices();
                        break;
                    case "SAVEWORKORDERINVOICE":
                        result = SaveWorkOrderInvoice();
                        break;
                    case "PUBLISHINVOICETOCUSTOMER":
                        result = PublishInvoiceToCustomer();
                        break;
                    case "DELETEWORKORDERINVOICE":
                        result = DeleteWorkOrderInvoice();
                        break;
                    case "REVOKEWORKORDERINVOICE":
                        result = RevokeWorkOrderInvoice();
                        break;
                    case "MARKASPAID":
                        result = MarkAsPaid();
                        break;
                    case "CANCELPAYMENT":
                        result = CancelPayment();
                        break;
                    case "CHANGEWOINVOICECUSTOMERVISIBLE":
                        result = ChangeWOInvoiceCustomerVisible();
                        break;
                    case "GETWORKORDERINVOICEATTACHMENTS":
                        result = GetWorkOrderInvoiceAttachments();
                        break;
                    case "ADDINVOICEATTACHMENT":
                        result = AddInvoiceAttachment();
                        break;
                    case "DELETEINVOICEATTACHMENT":
                        result = DeleteInvoiceAttachment();
                        break;
                    case "GETWORKORDERINVOICEPAYMENT":
                        result = GetWorkOrderInvoicePayment();
                        break;
                    case "UPDATEWORKORDERATTACHMENTCAPTION":
                        result = UpdateWorkOrderAttachmentCaption();
                        break;
                    case "RECORDDOWNLOADLOG":
                        result = RecordDownloadLog();
                        break;
                    case "GETWOSERVICETIMESETTING":
                        result = GetWOServiceTimeSetting();
                        break;
                    case "SETWOSERVICETIMESETTING":
                        result = SetWOServiceTimeSetting();
                        break;
                    case "GETWORKORDERNUMBERS":
                        result = GetWorkOrderNumbers();
                        break;
                    case "GETWORKORDERHISTORYS":
                        result = GetWorkOrderHistorys();
                        break;
                    case "GETSMSFOOTNOTES":
                        result = GetSMSFootnotes();
                        break;
                    case "SETSMSFOOTNOTES":
                        result = SetSMSFootnotes();
                        break;
                    case "GETESTIMATESETTINGS":
                        result = GetEstimateSettings();
                        break;
                    case "SETESTIMATESETTINGS":
                        result = SetEstimateSettings();
                        break;
                    case "GETINVOICESETTINGS":
                        result = GetInvoiceSettings();
                        break;
                    case "SETINVOICESETTINGS":
                        result = SetInvoiceSettings();
                        break;
                    case "GETWORKORDERPARAMS":
                        result = GetWorkorderParams();
                        break;
                    case "GETWORKORDERFOLLOWERS":
                        result = GetWorkOrderFollowers();
                        break;
                    case "GETALLFOLLOWERS":
                        result = GetAllFollowers();
                        break;
                    case "GETCUSTOMERFOLLOWERS":
                        result = GetCustomerFollowers();
                        break;
                    case "GETSALESPERSONS":
                        result = GetSalespersons();
                        break;
                    case "GETALLWORKORDERTYPES":
                        result = GetAllWorkOrderTypes();
                        break;
                    case "GETSURVEYAUTOMATIONSETTING":
                        result = GetSurveyAutomationSetting();
                        break;
                    case "SETSURVEYAUTOMATIONSETTING":
                        result = SetSurveyAutomationSetting();
                        break;
                    case "SETDONOTSENDSURVEY":
                        result = SetDoNotSendSurvey();
                        break;
                    case "GETINSPECTIONTEMPLATEITEMS":
                        result = GetInspectionTemplateItems();
                        break;
                    case "GETWORKORDERCONTACTS":
                        result = GetWorkOrderContacts();
                        break;
                    case "SAVEWORKORDERCONTACT":
                        result = SaveWorkOrderContact();
                        break;
                    case "SAVEWORKORDERFOLLOWER":
                        result = SaveWorkOrderFollower();
                        break;
                    case "DELETEWORKORDERFOLLOWER":
                        result = DeleteWorkOrderFollower();
                        break;
                    case "GETSURVEYPREVIEWURL":
                        result = GetSurveyPreviewUrl();
                        break;
                    case "GETWORKORDERWIDGETS":
                        result = GetWorkOrderWidgets();
                        break;
                    case "SAVEWORKORDERWIDGETS":
                        result = SaveWorkOrderWidgets();
                        break;
                    case "SAVEWORKORDERWIDGETLAYOUT":
                        result = SaveWorkOrderWidgetLayout();
                        break;
                    case "ISATTACHMENTEXCEEDSLIMIT":
                        result = IsAttachmentExceedsLimit();
                        break;
                    case "VALIDATEPHONES":
                        result = WrapExceptionWithPermission(ValidatePhones, null);
                        break;
                    case "UPDATEMESSAGESTATUS":
                        result = WrapExceptionWithPermission(UpdateMessageStatus);
                        break;
                    case "GETMESSAGESTATUSHISTORY":
                        result = WrapExceptionWithPermission(GetMessageStatusHistory);
                        break;
                }
            }

            string json = JsonConvert.SerializeObject(result);
            Response.Write(json);
            Response.End();
        }

        protected void ProcessFileRequest()
        {
            bool download = false;
            string fileName = "";
            byte[] buffer = null;
            try
            {
                string type = Request.Params["t"];
                if (type != null)
                {
                    switch (type)
                    {
                        case "1"://download
                            buffer = GetWorkOrderSurveyPDF(out fileName, false);
                            download = true;
                            break;
                        case "2"://print
                            buffer = GetWorkOrderSurveyPDF(out fileName);
                            break;
                        case "3"://download work order report
                            buffer = GetWorkOrderReportPDF(out fileName);
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                SystemParams.WriteLog("error", "WorkOrderBasePage", ex.Message, ex.ToString());
                throw ex;
            }

            fileName = HttpUtility.UrlEncode(string.IsNullOrEmpty(fileName) ? "attachment" : fileName, System.Text.Encoding.UTF8) + ".pdf";

            Response.ContentType = "application/pdf";
            Response.BufferOutput = false;
            Response.ContentEncoding = System.Text.Encoding.UTF8;
            Response.AddHeader("Content-Disposition"
                , string.Format("{0}filename={1}", download ? "attachment;" : "", fileName));
            if (buffer != null)
            {
                Response.AddHeader("Content-Length", buffer.Length.ToString());
                Response.BinaryWrite(buffer);
            }
            Response.Flush();
            Response.End();
        }

        private object GetWorkOrders()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    StringBuilder log = new StringBuilder();
                    DateTime start = DateTime.Now;
                    DateTime last = DateTime.Now;

                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    WorkOrderQueryParams p = JsonConvert.DeserializeObject<WorkOrderQueryParams>(clientdata);

                    WorkOrderProvider wop = CreateClient<WorkOrderProvider>();

                    WorkOrderListItem[] workorders = null;
                    if (p.AssetID > 0)
                        workorders = wop.GetWorkOrderItemsByAsset(SystemParams.CompanyID, p.AssetID);
                    else
                        workorders = wop.GetWorkOrderItems(SystemParams.CompanyID, p.Contacts, p.Statuses, p.OrderTypes, p.AssetGroups, p.SearchText, p.Completed, p.Locations, p.Departments, p.Advisors);

                    log.AppendLine("GetWorkOrderItems: " + (DateTime.Now - last).ToString());
                    last = DateTime.Now;

                    WorkOrderListItemClient[] maintenanceworkorders = null;//
                    if (p.ShowMaintenance)
                    {
                        maintenanceworkorders = MaintenanceManagement.GetMaintenanceWorkOrders(session.SessionID, SystemParams.CompanyID, p.Contacts, p.AssetGroups, p.SearchText, session.User.UID);
                        log.AppendLine("GetMaintenanceWorkOrders: " + (DateTime.Now - last).ToString());
                        last = DateTime.Now;
                    }

                    WorkOrderStatus[] allwostatus = wop.GetWorkOrderStatuses(SystemParams.CompanyID);
                    WorkOrderStatus[] wostatus = allwostatus;
                    if (session.User.ContactType == Foresight.Fleet.Services.User.ContactTypes.Technician)
                    {
                        wostatus = allwostatus.Where(m => m.TechniciansAvailable).ToArray();
                    }
                    log.AppendLine("GetWorkOrderStatuses: " + (DateTime.Now - last).ToString());
                    last = DateTime.Now;

                    List<WorkOrderListItemClient> list = new List<WorkOrderListItemClient>();
                    if (maintenanceworkorders != null)
                    {
                        //普通用户机器权限过滤
                        var user = GetCurrentUser();
                        if (user.UserType < UserTypes.Admin)
                        {
                            long[] availableAssetsids = CreateClient<AssetQueryClient>().GetAvailableAssetsForUsers(SystemParams.CompanyID, session.User.UID);
                            foreach (WorkOrderListItemClient wi in maintenanceworkorders)
                            {
                                if (availableAssetsids != null && !availableAssetsids.Contains(wi.AssetId))
                                    continue;
                                list.Add(wi);
                            }
                        }
                        else
                            list.AddRange(maintenanceworkorders);

                        log.AppendLine("maintenanceworkorders: " + (DateTime.Now - last).ToString());
                        last = DateTime.Now;
                    }

                    foreach (WorkOrderListItem wo in workorders)
                    {
                        WorkOrderListItemClient wi = new WorkOrderListItemClient();
                        Helper.CloneProperty(wi, wo);
                        if (wi.CreateDate != null)
                            wi.CreateDate = wi.CreateDate.Value.Date;
                        if (wi.CreationDate != null)
                            wi.CreationDate = wi.CreationDate.Value.Date;
                        if (wi.LastCommunicationDate != null)
                            wi.LastCommunicationDate = wi.LastCommunicationDate.Value.Date;

                        var sel = allwostatus.FirstOrDefault(s => s.Id == wi.Status);
                        if (sel != null)
                            wi.WorkOrderStatus = new WorkOrderStatus[] { sel };

                        if (wi.AssignedTo == "-1")
                        {
                            wi.AssignedTo = "";
                            wi.AssignedToName = "";
                        }
                        if (!string.IsNullOrWhiteSpace(wi.AssignedTo))
                            wi.AssignedToUsers = new UserInfo[] { new UserInfo() { IID = wi.AssignedTo, DisplayName = wi.AssignedToName } };

                        if (wi.DepartmentId > 0)
                            wi.Departments = new DepartmentInfo[] { new DepartmentInfo() { Id = wi.DepartmentId, Name = wi.Department } };

                        if (wi.LocationId > 0)
                            wi.Locations = new CustomerLocation[] { new CustomerLocation() { ID = wi.LocationId, Name = wi.Location } };

                        if (!string.IsNullOrWhiteSpace(wi.SalespersonId))
                            wi.Salespersons = new StringKeyValue[] { new StringKeyValue() { Key = wi.SalespersonId, Value = wi.SalespersonName } };

                        if (wi.AdvisorId == "-1")
                        {
                            wi.AdvisorId = "";
                            wi.AdvisorName = "";
                        }

                        wi.Contacts = wi.Contacts.OrderBy(m => m.Name).ToList();
                        list.Add(wi);
                    }
                    log.AppendLine("Process WorkOrders: " + (DateTime.Now - last).ToString());
                    last = DateTime.Now;

                    string[] woTypes = wop.GetWorkOrderTypes(SystemParams.CompanyID);
                    if (woTypes != null)
                        woTypes = woTypes.OrderBy(m => m).ToArray();

                    log.AppendLine("GetWorkOrderTypes: " + (DateTime.Now - last).ToString());
                    last = DateTime.Now;

                    List<StringKeyValue> advs = new List<StringKeyValue>();
                    var users = UserManagement.GetUsers();
                    foreach (var u in users.Where(u => u.ContactType == ContactTypes.Advisor))
                    {
                        StringKeyValue kv = new StringKeyValue();
                        kv.Key = u.IID.ToLower();
                        kv.Value = u.DisplayName;
                        advs.Add(kv);
                    }
                    log.AppendLine("GetUsers: " + (DateTime.Now - last).ToString());
                    last = DateTime.Now;

                    list = list.OrderBy((m) =>
                    {
                        int v = 0;
                        if (int.TryParse(m.WorkOrderNumber, out v))
                            return m.WorkOrderNumber.PadLeft(50, '0');
                        else
                            return m.WorkOrderNumber;
                    }).ToList();

                    StringBuilder sb_wos = new StringBuilder();
                    foreach (WorkOrderListItemClient wo in list)
                    {
                        if (sb_wos.Length > 0)
                            sb_wos.Append(SPLIT_CHAR180 + wo.ToString());
                        else
                            sb_wos.Append(wo.ToString());
                    }

                    StringBuilder sb_ws = new StringBuilder();
                    var workorderstatus = wostatus.OrderBy(s => s.Name).ToArray();
                    foreach (WorkOrderStatus ws in workorderstatus)
                    {
                        if (sb_ws.Length > 0)
                            sb_ws.Append(SPLIT_CHAR180 + ws.ToString());
                        else
                            sb_ws.Append(ws.ToString());
                    }

                    string workordertypes = string.Join(SPLIT_CHAR180.ToString(), woTypes);

                    StringBuilder sb_advisor = new StringBuilder();
                    var advisors = advs.OrderBy((m) => m.Value).ToArray();
                    foreach (StringKeyValue kv in advisors)
                    {
                        string advisorstr = kv.Key + SPLIT_CHAR175 + kv.Value;
                        if (sb_advisor.Length > 0)
                            sb_advisor.Append(SPLIT_CHAR180 + advisorstr);
                        else
                            sb_advisor.Append(advisorstr);
                    }

                    var deleteandrestoreworkorder = wop.GetDeleteAndRestoreWorkOrder(SystemParams.CompanyID, p.SearchText);
                    string delrewostr = deleteandrestoreworkorder == null ? "" : deleteandrestoreworkorder.Key + SPLIT_CHAR175 + deleteandrestoreworkorder.Value;

                    StringBuilder sb = new StringBuilder();
                    sb.Append(sb_wos.ToString());
                    sb.Append(SPLIT_CHAR181 + sb_ws.ToString());
                    sb.Append(SPLIT_CHAR181 + workordertypes);
                    sb.Append(SPLIT_CHAR181 + sb_advisor.ToString());
                    sb.Append(SPLIT_CHAR181 + delrewostr);

                    log.AppendLine("Process List: " + (DateTime.Now - last).ToString());
                    log.Insert(0, "Total: " + list.Count() + "; Time: " + (DateTime.Now - start).ToString());

                    //AddLog("Info", "WorkOrderBasePage.GetWorkOrders", session.User.ID, log.ToString());
                    return sb.ToString();
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrders", ex.Message, ex.ToString());
                return ex.Message;
            }
        }
        private object GetWorkOrderListItem()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    WorkOrderQueryParams p = JsonConvert.DeserializeObject<WorkOrderQueryParams>(clientdata);

                    WorkOrderListItem wo = null;
                    wo = CreateClient<WorkOrderProvider>().GetWorkOrderListItemById(SystemParams.CompanyID, p.WorkOrderID, p.Contacts, p.Statuses, p.OrderTypes, p.AssetGroups, p.SearchText, p.Completed, p.Locations, p.Departments, p.Advisors);
                    if (wo == null)
                        return null;

                    WorkOrderStatus[] allwostatus = CreateClient<WorkOrderProvider>().GetWorkOrderStatuses(SystemParams.CompanyID);
                    WorkOrderStatus[] wostatus = allwostatus;
                    if (session.User.ContactType == Foresight.Fleet.Services.User.ContactTypes.Technician)
                    {
                        wostatus = allwostatus.Where(m => m.TechniciansAvailable).ToArray();
                    }

                    WorkOrderListItemClient wi = new WorkOrderListItemClient();
                    Helper.CloneProperty(wi, wo);
                    if (wi.CreateDate != null)
                        wi.CreateDate = wi.CreateDate.Value.Date;
                    if (wi.LastCommunicationDate != null)
                        wi.LastCommunicationDate = wi.LastCommunicationDate.Value.Date;

                    var sel = allwostatus.FirstOrDefault(s => s.Id == wi.Status);
                    if (sel != null)
                        wi.WorkOrderStatus = new WorkOrderStatus[] { sel };

                    if (wi.AssignedTo == "-1")
                    {
                        wi.AssignedTo = "";
                        wi.AssignedToName = "";
                    }
                    if (!string.IsNullOrWhiteSpace(wi.AssignedTo))
                        wi.AssignedToUsers = new UserInfo[] { new UserInfo() { IID = wi.AssignedTo, DisplayName = wi.AssignedToName } };

                    if (wi.DepartmentId > 0)
                        wi.Departments = new DepartmentInfo[] { new DepartmentInfo() { Id = wi.DepartmentId, Name = wi.Department } };

                    if (wi.LocationId > 0)
                        wi.Locations = new CustomerLocation[] { new CustomerLocation() { ID = wi.LocationId, Name = wi.Location } };

                    if (!string.IsNullOrWhiteSpace(wi.SalespersonId))
                        wi.Salespersons = new StringKeyValue[] { new StringKeyValue() { Key = wi.SalespersonId, Value = wi.SalespersonName } };

                    if (wi.AdvisorId == "-1")
                    {
                        wi.AdvisorId = "";
                        wi.AdvisorName = "";
                    }

                    return wi.ToString();
                }
                else
                    return null;

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrders", ex.Message, ex.ToString());
                return ex.Message;
            }
        }


        private object GetWorkOrderInfo()
        {
            try
            {
                if (GetCurrentLoginSession() != null)
                {
                    var woid = Request.Form["ClientData"];

                    WorkOrderInfoClient woi = new WorkOrderInfoClient();
                    WorkOrderInfo wo = CreateClient<WorkOrderProvider>().GetWorkOrderInfo(SystemParams.CompanyID, Convert.ToInt64(woid));
                    Helper.CloneProperty(woi, wo);
                    if (woi.AssignedTo == "-1")
                    {
                        woi.AssignedTo = "";
                        woi.AssignedToName = "";
                    }
                    if (woi.AdvisorId == "-1")
                    {
                        woi.AdvisorId = "";
                        woi.AdvisorName = "";
                    }

                    List<ContactInfoClient> lsct = new List<ContactInfoClient>();
                    if (wo.Contacts != null && wo.Contacts.Length > 0)
                    {
                        var lang = GetLanguageCookie();
                        foreach (var pa in wo.Contacts)
                        {
                            ContactInfoClient item = new ContactInfoClient();
                            Helper.CloneProperty(item, pa);
                            if ((int)item.ContactPreference == 0)
                                item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_TEXT", "Text");
                            else if ((int)item.ContactPreference == 1)
                                item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_EMAIL", "Email");
                            else if ((int)item.ContactPreference == 2)
                                item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_PHONE", "Phone");
                            lsct.Add(item);
                        }
                        woi.Contacts = lsct.ToArray();
                    }

                    var asset = CreateClient<AssetQueryClient>().GetAssetBasicInfoByID(SystemParams.CompanyID, wo.AssetID);
                    if (asset != null)
                    {
                        woi.VIN = asset.VIN;
                        woi.AssetName = asset.DisplayName;
                        woi.MakeName = asset.MakeName;
                        woi.ModelName = asset.ModelName;
                        woi.TypeName = asset.TypeName;
                    }

                    return woi;
                }
                else
                    return new WorkOrderInfo();
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderInfo", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetAlertsForWorkOrder()//获取当前WO已选和未选的的Alerts
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);

                    var woid = ps[0];
                    var aid = ps[1];
                    long workorderid = Convert.ToInt64(woid);
                    long assetid = Convert.ToInt64(aid);
                    AlertManager am = new AlertManager(SystemParams.DataDbConnectionString);
                    AlertInfo[] alerts = am.GetAlertsByWorkOrder(workorderid, session.User);

                    AssetAlertItem[] aAlerts = CreateClient<WorkOrderProvider>().GetNoneAssignedAlerts(SystemParams.CompanyID, assetid);
                    List<AlertInfo> assetAlerts = new List<AlertInfo>();
                    if (aAlerts != null)
                    {
                        foreach (var aa in aAlerts)
                        {
                            AlertInfo ai = new AlertInfo();
                            ai.AlertID = aa.ID;
                            ai.MachineID = aa.AssetID;
                            ai.AlertType = aa.AlertType;
                            ai.Description = aa.Description;
                            ai.Description = ai.FormatDescription(ai.Description);
                            ai.AlertTime_UTC = aa.AlertTime;
                            ai.AlertLocalTime = aa.AlertLocalTime;
                            ai.ServiceDescription = aa.ServiceDescription;
                            assetAlerts.Add(ai);
                        }
                    }

                    WorkorderAlerts wa = new WorkorderAlerts();
                    wa.Alerts = alerts;
                    wa.AssetAlerts = assetAlerts.ToArray();

                    return wa;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "AlertsBasePage.GetAlertsByWorkOrder", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetOpenWorkOrderID()
        {
            try
            {
                if (GetCurrentLoginSession() != null)
                {
                    var mid = Request.Form["ClientData"];
                    long aid = 0;
                    long.TryParse(mid, out aid);

                    var wos = CreateClient<WorkOrderProvider>().GetWorkOrderItemsByAsset(SystemParams.CompanyID, aid);
                    List<string> wonumbers = new List<string>();
                    foreach (var wo in wos)
                    {
                        if (!wo.Completed)
                            wonumbers.Add(wo.WorkOrderNumber);
                    }
                    //WorkOrderManager workordermanager = new WorkOrderManager(SystemParams.DataDbConnectionString);
                    //long[] workorderids = workordermanager.GetOpenWorkOrderID(mid);
                    string ids = string.Join(", ", wonumbers);
                    ids = mid + "|" + ids;
                    return ids;
                }
                else
                    return "";
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetOpenWorkOrderID", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SaveWorkOrder()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var workorderitem = HttpUtility.HtmlDecode(clientdata[0]);
                    var ids = HttpUtility.HtmlDecode(clientdata[1]);
                    long[] alertids = JsonConvert.DeserializeObject<long[]>(ids);

                    var woc = JsonConvert.DeserializeObject<WorkOrderInfoClient>(workorderitem);
                    if (woc.Completed)
                    {
                        if (woc.CompleteDate == null)
                            woc.CompleteDate = DateTime.Now;
                    }
                    else
                        woc.CompleteDate = null;

                    long workorderid = woc.Id;
                    string wonumber = woc.WorkOrderNumber;
                    var woclient = CreateClient<WorkOrderProvider>(SystemParams.CompanyID);
                    if (woc.Id == -1)
                    {
                        var CanOpenWO = CheckRight(SystemParams.CompanyID, Foresight.Fleet.Services.User.Feature.OPENWORKORDERS);
                        if (!CanOpenWO)
                            return -1;
                        //contacts
                        if (woc.CustomerId > 0 && woc.ContactsClient != null && woc.ContactsClient.Length > 0)
                        {
                            var client = CreateClient<BusinessPartnerProvider>();
                            for (int i = 0; i < woc.ContactsClient.Length; i++)
                            {
                                var contact = woc.ContactsClient[i];
                                if (contact.SaveToCustomer > 0)
                                {
                                    Foresight.Fleet.Services.Partner.ContactInfo pContact = new Foresight.Fleet.Services.Partner.ContactInfo();
                                    Helper.CloneProperty(pContact, contact);
                                    pContact.Active = true;
                                    if (contact.Id > 0)
                                        client.UpdateContact(SystemParams.CompanyID, woc.CustomerId, pContact);
                                    else
                                    {
                                        contact.Id = (int)client.AddContact(SystemParams.CompanyID, woc.CustomerId, pContact);
                                        woc.Contacts[i].Id = contact.Id;
                                    }
                                }
                            }
                        }

                        WorkOrderInfo wo = new WorkOrderInfo();
                        Helper.CloneProperty(wo, woc);

                        workorderid = woclient.AddNewWorkOrder(SystemParams.CompanyID, wo, alertids);
                        wonumber = workorderid.ToString();//2021-10-20 新增时wonumber默认为woid

                        //followers
                        if (woc.Followers != null)
                        {
                            woclient.AddWorkOrderFollower(SystemParams.CompanyID, workorderid, woc.Followers);
                        }
                    }
                    else
                    {
                        WorkOrderInfo wo = new WorkOrderInfo();
                        Helper.CloneProperty(wo, woc);

                        WorkOrderInfo oldwo = woclient.GetWorkOrderInfo(SystemParams.CompanyID, workorderid);
                        var user = UserManagement.GetUserByIID(session.User.UID);

                        bool reopenworkorders = CheckRight(SystemParams.CompanyID, Foresight.Fleet.Services.User.Feature.REOPENWORKORDERS);
                        if (oldwo.Completed && user.UserType < UserTypes.Admin && !reopenworkorders)
                        {
                            return "You cannot edit a Completed Work Order.";
                        }
                        wo.WorkOrderNumber = oldwo.WorkOrderNumber;
                        woclient.UpdateWorkOrder(SystemParams.CompanyID, wo);
                        wonumber = oldwo.WorkOrderNumber;
                    }

                    return new string[] { workorderid.ToString(), wonumber };
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object UpdateWorkOrder()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    clientdata = HttpUtility.HtmlDecode(clientdata);

                    var wo = JsonConvert.DeserializeObject<WorkOrderInfo>(clientdata);
                    if (wo.Completed)
                    {
                        if (wo.CompleteDate == null)
                            wo.CompleteDate = DateTime.Now;
                    }
                    else
                        wo.CompleteDate = null;

                    CreateClient<WorkOrderProvider>().UpdateWorkOrderList(SystemParams.CompanyID, wo);
                    WorkOrderInfoClient woc = new WorkOrderInfoClient();
                    Helper.CloneProperty(woc, wo);
                    return woc;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object GetWorkOrderContacts()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long woid = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    var client = CreateClient<WorkOrderProvider>();
                    Foresight.Fleet.Services.AssetHealth.WorkOrder.ContactInfo[] items = client.GetWorkOrderContacts(SystemParams.CompanyID, woid);
                    if (items == null || items.Length == 0)
                        return new ContactInfoClient[0];

                    List<ContactInfoClient> lsct = new List<ContactInfoClient>();
                    if (items != null && items.Length > 0)
                    {
                        var lang = GetLanguageCookie();
                        foreach (var pa in items)
                        {
                            ContactInfoClient item = new ContactInfoClient();
                            Helper.CloneProperty(item, pa);
                            if ((int)item.ContactPreference == 0)
                                item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_TEXT", "Text");
                            else if ((int)item.ContactPreference == 1)
                                item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_EMAIL", "Email");
                            else if ((int)item.ContactPreference == 2)
                                item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_PHONE", "Phone");
                            lsct.Add(item);
                        }
                    }

                    return lsct.ToArray();
                }
                else
                    return new ContactInfoClient[0];
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderContacts", ex.Message, ex.ToString());
                return ex.Message;
            }
        }
        private object SaveWorkOrderContact()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    var p = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = Convert.ToInt64(p[0]);
                    int customerid = Convert.ToInt32(p[1]);

                    Foresight.Fleet.Services.AssetHealth.WorkOrder.ContactInfo[] contacts = JsonConvert.DeserializeObject<Foresight.Fleet.Services.AssetHealth.WorkOrder.ContactInfo[]>(p[2]);
                    ContactInfoClient[] contactsclient = JsonConvert.DeserializeObject<ContactInfoClient[]>(p[2]);

                    //contacts
                    if (customerid > 0 && contactsclient != null && contactsclient.Length > 0)
                    {
                        var client = CreateClient<BusinessPartnerProvider>();
                        for (int i = 0; i < contactsclient.Length; i++)
                        {
                            var contact = contactsclient[i];
                            if (contact.SaveToCustomer > 0)
                            {
                                Foresight.Fleet.Services.Partner.ContactInfo pContact = new Foresight.Fleet.Services.Partner.ContactInfo();
                                Helper.CloneProperty(pContact, contact);
                                pContact.Active = true;
                                if (contact.Id > 0)
                                    client.UpdateContact(SystemParams.CompanyID, customerid, pContact);
                                else
                                {
                                    contact.Id = (int)client.AddContact(SystemParams.CompanyID, customerid, pContact);
                                    contacts[i].Id = contact.Id;
                                }
                            }
                        }
                    }

                    CreateClient<WorkOrderProvider>().SaveWorkOrderContact(SystemParams.CompanyID, woid, customerid, contacts);
                    return contacts;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object SaveWorkOrderFollower()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    var p = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = Convert.ToInt64(p[0]);
                    WorkOrderFollowerInfo[] followers = JsonConvert.DeserializeObject<WorkOrderFollowerInfo[]>(p[1]);

                    CreateClient<WorkOrderProvider>().AddWorkOrderFollower(SystemParams.CompanyID, woid, followers);
                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteWorkOrderFollower()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    int id = Convert.ToInt32(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().DeleteWorkOrderFollower(SystemParams.CompanyID, id);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }


        private object DeleteWorkOrder()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long id = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().DeleteWorkOrder(SystemParams.CompanyID, id, string.Empty);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object RestoreDeleteWorkOrder()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long id = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().RestoreDeleteWorkOrder(SystemParams.CompanyID, id);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object GetCustomerContacts()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string custid = Request.Form["ClientData"];
                    custid = HttpUtility.HtmlDecode(custid);

                    Foresight.Fleet.Services.Partner.ContactInfo[] contacts = CreateClient<BusinessPartnerProvider>().GetContacts(SystemParams.CompanyID, int.Parse(custid)).Where(m => m.Active).ToArray();
                    if (contacts == null || contacts.Length == 0)
                        return new Foresight.Fleet.Services.Partner.ContactInfo[0];

                    var lang = GetLanguageCookie();
                    List<ContactInfoClient> ls = new List<ContactInfoClient>();
                    foreach (var pa in contacts)
                    {
                        ContactInfoClient item = new ContactInfoClient();
                        Helper.CloneProperty(item, pa);
                        if ((int)item.ContactPreference == 0)
                            item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_TEXT", "Text");
                        else if ((int)item.ContactPreference == 1)
                            item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_EMAIL", "Email");
                        else if ((int)item.ContactPreference == 2)
                            item.ContactPreferenceStr = SystemParams.GetTextByKey(lang, "P_CR_PHONE", "Phone");
                        ls.Add(item);
                    }
                    return ls.ToArray();
                }
                else
                    return new ContactInfoClient[0];

            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private UserInfo[] GetAssetContacts()
        {
            var session = GetCurrentLoginSession();
            UserInfo[] users = null;
            if (GetCurrentLoginSession() != null)
            {
                var clientdata = Request.Form["ClientData"];
                string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                long assetid = 0; int locid = 0; int depid = 0;
                long.TryParse(ps[0], out assetid);
                int.TryParse(ps[1], out locid);
                int.TryParse(ps[2], out depid);
                users = UserManagement.GetWorkOrderAssignToUsers(session.SessionID, SystemParams.CompanyID, assetid, locid, depid);
                return users;
            }
            else
            {
                users = new UserInfo[0];
            }
            return users;
        }

        private object GetMachines()
        {
            var session = GetCurrentLoginSession();
            MachineItem[] machines = null;
            if (GetCurrentLoginSession() != null)
            {
                //machines = MachineManagement.GetMachines(session.SessionID, session.User.UID, "");

                var items = CreateClient<AssetQueryClient>(SystemParams.CompanyID).GetAssetListItemsByUser(SystemParams.CompanyID, session.User.UID, "", false, 0, true, null, null, null);
                return items.Select(i => new
                {
                    i.Id,
                    i.VIN,
                    i.MakeName,
                    i.ModelName,
                    i.TypeName,
                    i.OnRoad,
                    EngineHours = Math.Round(i.EngineHours ?? 0, 2),
                    Odometer = Math.Round(i.Odometer ?? 0, 2),
                    DisplayName = GetDisplayName(i)
                }).OrderBy(g => g.DisplayName).ToArray();
            }
            else
            {
                machines = new MachineItem[0];
            }
            return machines.Where(m => m.Hide == false).OrderBy(m => m.DisplayName).ToArray();
        }
        private string GetDisplayName(AssetListItemInfo a)
        {
            //Name取值顺序为Name2,Name,VIN,ID用于前端显示
            string name = a.Name2;
            if (string.IsNullOrWhiteSpace(name))
                name = a.Name;
            if (string.IsNullOrWhiteSpace(name))
                name = a.VIN;
            if (string.IsNullOrWhiteSpace(name))
                name = a.Id.ToString();
            return name;
        }

        private object GetAssetDetailInfo()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var custid = HttpUtility.HtmlDecode(clientdata[0]);
                    var assetidstr = HttpUtility.HtmlDecode(clientdata[1]);
                    long assetid = -1;
                    long.TryParse(assetidstr, out assetid);
                    if (string.IsNullOrWhiteSpace(custid))
                        custid = SystemParams.CompanyID;

                    AssetDetailInfo info = CreateClient<AssetQueryClient>(custid).GetAssetDetailInfo(custid, assetid);

                    return info;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetNoneAssignedAlerts()
        {
            try
            {
                if (GetCurrentLoginSession() != null)
                {
                    var id = Request.Form["ClientData"];
                    long assetid = Convert.ToInt64(id);

                    AssetAlertItem[] alerts = CreateClient<WorkOrderProvider>().GetNoneAssignedAlerts(SystemParams.CompanyID, assetid);
                    if (alerts == null || alerts.Length == 0)
                        return new AssetAlertInfo[0];

                    List<AssetAlertInfo> list = new List<AssetAlertInfo>();
                    foreach (AssetAlertItem alert in alerts)
                    {
                        AssetAlertInfo ai = new AssetAlertInfo();
                        Helper.CloneProperty(ai, alert);
                        ai.Description = ai.FormatDescription(ai.Description);
                        ai.AlertTime = ai.AlertTime.ToLocalTime();
                        ai.CompletedDate = ai.AlertTime.ToLocalTime();
                        list.Add(ai);
                    }
                    return list.ToArray();
                }
                else
                    return new AssetAlertInfo[0];
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "AlertsBasePage.GetNoneAssignedAlerts", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetPMSchedulesByAsset()
        {
            try
            {
                try
                {
                    var session = GetCurrentLoginSession();
                    if (session != null)
                    {
                        string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                        long assetid = 0;
                        long.TryParse(clientdata, out assetid);
                        var client = CreateClient<PMClient>(session.SessionID);
                        PMScheduleItem[] pms = client.GetPMScheduleItemsByAssetID(SystemParams.CompanyID, assetid, "", string.Empty, false);
                        if (pms == null)
                            return new PMScheduleItem[0];
                        return pms;
                    }

                    return new PMScheduleItem[0];
                }
                catch (Exception ex)
                {
                    AddLog("ERROR", "AssetBasePage.GetPmSchedules", ex.Message, ex.ToString());
                    return ex.Message;
                }
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetAssetSchedules", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GenerateManualPMAlerts()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);

                    long assetid = 0;
                    long.TryParse(ps[0], out assetid);
                    long woid = 0;
                    long.TryParse(ps[1], out woid);
                    string[] scheduleids = JsonConvert.DeserializeObject<string[]>(ps[2]);

                    var client = CreateClient<PMClient>();
                    PMAlertResult[] rs = client.GenerateManualPMAlerts(SystemParams.CompanyID, assetid, woid, scheduleids, session.User.UID);
                    return rs;
                }
                else
                    return new string[0];
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object AddOrRemoveAlertsFromWorkOrder()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var woid = HttpUtility.HtmlDecode(clientdata[0]);
                    var ids = HttpUtility.HtmlDecode(clientdata[1]);
                    var isaddstr = HttpUtility.HtmlDecode(clientdata[2]);
                    bool isadd = Helper.IsTrue(isaddstr);
                    long[] alertids = JsonConvert.DeserializeObject<long[]>(ids);


                    CreateClient<WorkOrderProvider>().AddOrRemoveAlertsFromWorkOrder(SystemParams.CompanyID, Convert.ToInt64(woid), alertids, isadd);

                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object UpdateCommunicationAcknowledged()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long id = Convert.ToInt64(ps[0]);
                    bool check = Helper.IsTrue(ps[1]);

                    CreateClient<WorkOrderProvider>().UpdateCommunicationAcknowledged(SystemParams.CompanyID, id, check);

                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object UpdateEstimateAcknowledged()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long id = Convert.ToInt64(ps[0]);
                    bool check = Helper.IsTrue(ps[1]);

                    CreateClient<WorkOrderProvider>().UpdateEstimateAcknowledged(SystemParams.CompanyID, id, check);

                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetComponents()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    int t = 0;
                    int.TryParse(clientdata, out t);

                    var woc = CreateClient<WorkOrderProvider>().GetComponents(SystemParams.CompanyID, t);

                    return woc;
                }
                else
                    return new SegmentClient();
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetComponents", ex.Message, ex.ToString());
                return ex.Message;
            }
        }
        private object GetJobsites()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var jss = CreateClient<JobSiteProvider>().GetJobSiteItems(SystemParams.CompanyID, "", false);
                    List<JobSiteViewItem> list = new List<JobSiteViewItem>();
                    foreach (var js in jss)
                    {
                        JobSiteViewItem item = new JobSiteViewItem();
                        item.ID = js.ID;
                        item.Name = js.Name;

                        list.Add(item);
                    }

                    return list;
                }
                else
                    return new SegmentClient();
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetJobsites", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetSalespersons()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var users = CreateClient<Foresight.Fleet.Services.User.UserQueryClient>().GetUsersByCustomerID(SystemParams.CompanyID, "");

                    List<StringKeyValue> list = new List<StringKeyValue>();
                    foreach (var user in users)
                    {
                        if (!user.Active)
                            continue;

                        StringKeyValue kv = new StringKeyValue();
                        kv.Key = user.UID;
                        kv.Value = user.Name;
                        list.Add(kv);
                    }

                    return list.ToArray();
                }
                else
                    return new StringKeyValue[0];
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetSalespersons", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetInspectionTemplateItems()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var templates = CreateClient<AssetInspectClient>().GetAssetTemplateItems(SystemParams.CompanyID, "", -1, -1, -1, session.User.UID, 1);

                    List<StringKeyValue> list = new List<StringKeyValue>();
                    foreach (var temp in templates)
                    {
                        StringKeyValue kv = new StringKeyValue();
                        kv.Key = temp.Id.ToString();
                        kv.Value = temp.Name;
                        list.Add(kv);
                    }

                    return list.ToArray();
                }
                else
                    return new StringKeyValue[0];
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetAssetTemplateItems", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        #region Segment

        private object GetSegmentDataSource()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    SegmentClient client = new SegmentClient();

                    client.Users = UserManagement.GetUsers();
                    if (client.Users == null)
                        client.Users = new UserInfo[0];

                    var jss = CreateClient<JobSiteProvider>().GetJobSiteItems(SystemParams.CompanyID, "", false);
                    List<JobSiteViewItem> list = new List<JobSiteViewItem>();
                    foreach (var js in jss)
                    {
                        JobSiteViewItem item = new JobSiteViewItem();
                        item.ID = js.ID;
                        item.Name = js.Name;

                        list.Add(item);
                    }

                    client.JobSites = list.ToArray();
                    if (client.JobSites == null)
                        client.JobSites = new JobSiteViewItem[0];

                    var wop = CreateClient<WorkOrderProvider>();
                    client.Components = wop.GetComponents(SystemParams.CompanyID, 0);
                    client.SegmentTypes = wop.GetSegmentTypes(SystemParams.CompanyID);

                    return client;
                }
                else
                    return new SegmentClient();
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetSegmentDataSource", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetSegmentDataSource1()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    SegmentClient client = new SegmentClient();
                    var wop = CreateClient<WorkOrderProvider>();
                    client.Components = wop.GetComponents(SystemParams.CompanyID, 0);
                    client.SegmentTypes = wop.GetSegmentTypes(SystemParams.CompanyID);

                    return client;
                }
                else
                    return new SegmentClient();
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetSegmentDataSource", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetSegments()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long woid = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    WorkOrderSegmentInfo[] segments = CreateClient<WorkOrderProvider>().GetSegments(SystemParams.CompanyID, woid);
                    if (segments == null || segments.Length == 0)
                        return new
                        {
                            WorkOrderID = woid,
                            Data = new SegmentInfo[0]
                        };

                    List<SegmentInfo> list = new List<SegmentInfo>();
                    foreach (WorkOrderSegmentInfo se in segments)
                    {
                        SegmentInfo si = new SegmentInfo();
                        Helper.CloneProperty(si, se);
                        si.SegmentID = se.Id;
                        list.Add(si);
                    }
                    return new
                    {
                        WorkOrderID = woid,
                        Data = list.ToArray()
                    };
                }
                else
                    return new
                    {
                        WorkOrderID = -1,
                        Data = new SegmentInfo[0]
                    };

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetSegments", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SaveSegment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    SegmentInfo si = JsonConvert.DeserializeObject<SegmentInfo>(clientdata);
                    WorkOrderSegmentInfo segment = new WorkOrderSegmentInfo();
                    Helper.CloneProperty(segment, si);
                    segment.Id = si.SegmentID;
                    if (segment.CompletedDate != null)
                        segment.Completed = true;
                    if (segment.Id == -1)
                    {
                        segment.Id = CreateClient<WorkOrderProvider>().AddNewSegment(SystemParams.CompanyID, segment);
                    }
                    else
                    {
                        CreateClient<WorkOrderProvider>().UpdateSegment(SystemParams.CompanyID, segment);
                    }

                    return segment.Id;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteSegment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    int id = Convert.ToInt32(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().DeleteSegment(SystemParams.CompanyID, id, string.Empty);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }


        #endregion

        #region Attachment

        private object GetAttachments()
        {
            try
            {
                if (GetCurrentLoginSession() != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = -1;
                    long.TryParse(ps[0], out woid);
                    long assetid = -1;
                    long.TryParse(ps[1], out assetid);

                    WOAttachments attas = new WOAttachments();
                    var wop = CreateClient<WorkOrderProvider>();
                    AssetDocumentInfo[] aatts = new AssetDocumentInfo[0];
                    if (assetid > 0)
                    {
                        aatts = CreateClient<AssetDocumentProvider>().GetAssetDocuments(SystemParams.CompanyID, assetid).Where(m => m.VisibleOnWorkOrder == true).ToArray();
                    }
                    //WorkOrderAttachmentInfo[] aatts = wop.GetAssetAttachementsAvailbleOnWorkOrder(SystemParams.CompanyID, assetid);
                    WorkOrderAttachmentInfo[] woatts = new WorkOrderAttachmentInfo[0];
                    MediaInfo[] iatts = new MediaInfo[0];
                    if (woid > 0)
                    {
                        woatts = wop.GetWorkOrderAttachments(SystemParams.CompanyID, woid, false);
                        iatts = wop.GetWOInspectMedias(SystemParams.CompanyID, woid);
                    }

                    List<WorkOrderAttachmentItem> list = new List<WorkOrderAttachmentItem>();
                    foreach (AssetDocumentInfo att in aatts)
                    {
                        WorkOrderAttachmentItem item = new WorkOrderAttachmentItem();
                        item.FileName = att.Name;
                        item.FileType = att.FileType;
                        item.AttachmentId = att.Id;
                        item.AttachmentIdStr = att.Id.ToString();
                        item.AttachmentType = 1;
                        item.Url = att.Url;
                        list.Add(item);
                    }
                    attas.AssetAttachments = list.OrderBy(m => m.AddedOnLocal).ToArray();

                    list.Clear();
                    foreach (WorkOrderAttachmentInfo att in woatts)
                    {
                        WorkOrderAttachmentItem item = new WorkOrderAttachmentItem();
                        Helper.CloneProperty(item, att);
                        item.AttachmentIdStr = att.AttachmentId.ToString();
                        item.AttachmentType = 2;
                        item.Extensions = new List<AttachmentExtensionInfo>();

                        item.AvailableToCustomer = false;
                        if (att.Extensions.Count > 0)
                        {
                            var ext = att.Extensions.First(m => m.Key == "1");
                            if (ext != null)
                                item.AvailableToCustomer = Helper.IsTrue(ext.Value);
                        }
                        list.Add(item);
                    }
                    attas.WorkOrderAttachments = list.OrderBy(m => m.AddedOnLocal).ToArray();

                    list.Clear();
                    foreach (MediaInfo att in iatts)
                    {
                        WorkOrderAttachmentItem item = new WorkOrderAttachmentItem();
                        item.FileName = att.FileName;
                        item.FileType = att.FileType;
                        item.AttachmentIdStr = att.Id;
                        item.AttachmentType = 3;
                        item.Url = att.Url;
                        item.ThumbnailUrl = att.ThumbnailUrl;
                        list.Add(item);
                    }
                    attas.InspectionAttachments = list.OrderBy(m => m.AddedOnLocal).ToArray();
                    return new
                    {
                        WorkOrderID = woid,
                        Data = attas
                    };
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetWorkOrderAttachments()
        {
            try
            {
                if (GetCurrentLoginSession() != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    long woid = Convert.ToInt64(clientdata);

                    WorkOrderAttachmentInfo[] woatts = CreateClient<WorkOrderProvider>().GetWorkOrderAttachments(SystemParams.CompanyID, woid, false);
                    if (woatts == null || woatts.Length == 0)
                        return new WorkOrderAttachmentItem[0];

                    List<WorkOrderAttachmentItem> list = new List<WorkOrderAttachmentItem>();
                    foreach (WorkOrderAttachmentInfo att in woatts)
                    {
                        WorkOrderAttachmentItem item = new WorkOrderAttachmentItem();
                        Helper.CloneProperty(item, att);
                        item.AttachmentIdStr = att.AttachmentId.ToString();
                        item.AttachmentType = 2;
                        item.Extensions = new List<AttachmentExtensionInfo>();

                        item.AvailableToCustomer = false;
                        if (att.Extensions.Count > 0)
                        {
                            var ext = att.Extensions.First(m => m.Key == "1");
                            if (ext != null)
                                item.AvailableToCustomer = Helper.IsTrue(ext.Value);
                        }
                        list.Add(item);
                    }
                    return list.OrderBy(m => m.AddedOnLocal).ToArray();
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object AddAttachment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = Convert.ToInt64(ps[0]);
                    string notes = HttpUtility.UrlDecode(ps[1]);

                    HttpPostedFile uploadFile = null;
                    byte[] iconfilebyte = null;
                    if (Request.Files.Count > 0)
                    {
                        uploadFile = Request.Files[0];
                        iconfilebyte = ConvertFile2bytes(uploadFile);
                    }

                    string filename = uploadFile == null ? "" : uploadFile.FileName;
                    long attid = CreateClient<WorkOrderProvider>().AddWorkOrderAttachment(SystemParams.CompanyID, Convert.ToInt64(woid), filename, notes, iconfilebyte);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteAttachment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string attachid = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    CreateClient<WorkOrderProvider>().DeleteWorkOrderAttachment(SystemParams.CompanyID, Convert.ToInt64(attachid));
                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }

        }

        private object UpdateWOAttachmentExtension()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long attid = Convert.ToInt64(ps[0]);
                    AttachmentExtensionInfo ext = JsonConvert.DeserializeObject<AttachmentExtensionInfo>(ps[1]);

                    CreateClient<WorkOrderProvider>().UpdateWOAttachmentExtension(SystemParams.CompanyID, attid, ext);

                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object RecordDownloadLog()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    string url = ps[0];

                    FICHostEnvironment.WriteExportAuditTrail(session.User.UID, "Download", "", "Download", url, "", null);

                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object UpdateWorkOrderAttachmentCaption()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long attid = Convert.ToInt64(ps[0]);
                    string caption = ps[1];

                    CreateClient<WorkOrderProvider>().UpdateWorkOrderAttachmentCaption(SystemParams.CompanyID, attid, caption);

                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object UpdateInspectionVisibleToCustomer()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    string id = ps[0];
                    bool check = Helper.IsTrue(ps[1]);

                    CreateClient<WorkOrderProvider>().UpdateInspectionVisibleToCustomer(SystemParams.CompanyID, id, check);

                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object IsAttachmentExceedsLimit()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string attachid = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    bool rst = false;
                    var atta = CreateClient<WorkOrderProvider>().GetWorkOrderAttachmentData(SystemParams.CompanyID, Convert.ToInt64(attachid));
                    if (atta != null)
                    {
                        if (atta.Item2.Length > MaxAttachmentSize)
                            rst = true;
                    }

                    return rst;
                }
                return true;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }


        #endregion

        #region WorkOrder Status

        private object GetWorkOrderStatuses()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var items = CreateClient<WorkOrderProvider>().GetWorkOrderStatuses(SystemParams.CompanyID);
                    if (session.User.ContactType == Foresight.Fleet.Services.User.ContactTypes.Technician)
                    {
                        items = items.Where(m => m.TechniciansAvailable).ToArray();
                    }
                    return items;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object SaveWorkOrderStatus()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    WorkOrderStatus status = JsonConvert.DeserializeObject<WorkOrderStatus>(clientdata);
                    if (status.Id == -1)
                    {
                        CreateClient<WorkOrderProvider>().AddWorkOrderStatus(SystemParams.CompanyID, status);
                    }
                    else
                    {
                        if (status.Id == 100 && status.StatusType != 100)
                            return FailedResult;

                        CreateClient<WorkOrderProvider>().UpdateWorkOrderStatus(SystemParams.CompanyID, status);
                    }

                    return new string[0];
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteWorkOrderStatus()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    int id = Convert.ToInt32(HttpUtility.HtmlDecode(clientdata));
                    if (id != 100)
                        CreateClient<WorkOrderProvider>().DeleteWorkOrderStatus(SystemParams.CompanyID, id);

                    return new string[0];
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private string UpdateWOStatusTechniciansAvailable()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    StringKeyValue kv = JsonConvert.DeserializeObject<StringKeyValue>(clientdata);
                    int id = Convert.ToInt32(kv.Key);
                    bool techniciansavailable = Helper.IsTrue(kv.Value);

                    CreateClient<WorkOrderProvider>().UpdateWOStatusTechniciansAvailable(SystemParams.CompanyID, id, techniciansavailable);
                    return OkResult;
                }
                else
                {
                    return FailedResult;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private string UpdateWOStatusAutoText()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    StringKeyValue kv = JsonConvert.DeserializeObject<StringKeyValue>(clientdata);
                    int id = Convert.ToInt32(kv.Key);
                    bool autotext = Helper.IsTrue(kv.Value);

                    CreateClient<WorkOrderProvider>().UpdateWOStatusAutoText(SystemParams.CompanyID, id, autotext);
                    return OkResult;
                }
                else
                {
                    return FailedResult;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private string UpdateWOStatusType()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    StringKeyValue kv = JsonConvert.DeserializeObject<StringKeyValue>(clientdata);
                    int id = Convert.ToInt32(kv.Key);
                    int statustype = Convert.ToInt32(kv.Value);
                    if (id == 100 && statustype != 100)
                        return FailedResult;

                    CreateClient<WorkOrderProvider>().UpdateWOStatusType(SystemParams.CompanyID, id, statustype);
                    return OkResult;
                }
                else
                {
                    return FailedResult;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private string UpdateWODefaultOnOpen()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    StringKeyValue kv = JsonConvert.DeserializeObject<StringKeyValue>(clientdata);
                    int id = Convert.ToInt32(kv.Key);
                    int statustype = Convert.ToInt32(kv.Value);

                    CreateClient<WorkOrderProvider>().UpdateWODefaultOnOpen(SystemParams.CompanyID, id, statustype);
                    return OkResult;
                }
                else
                {
                    return FailedResult;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        #endregion

        #region Send Email
        private object GetMachineContacts()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var assetid = Request.Form["ClientData"];
                    var users = UserManagement.GetUsersByAssetID(session.SessionID, Convert.ToInt64(assetid), SystemParams.CompanyID);
                    foreach (var u in users)
                    {
                        u.Mobile = Foresight.Standard.PhoneNumber.PreparePhonenumber(u.Mobile);
                    }
                    return UserManagement.GetUsersByAssetID(session.SessionID, Convert.ToInt64(assetid), SystemParams.CompanyID);
                }
                else
                    return new UserInfo[0];
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object SendWorkOrder()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"].Split((char)170);
                    var woidstr = HttpUtility.HtmlDecode(clientdata[0]);
                    var address = HttpUtility.HtmlDecode(clientdata[1]);
                    var desc = HttpUtility.HtmlDecode(clientdata[2]);
                    Foresight.Standard.StringKeyValue[] emailaddress = JsonConvert.DeserializeObject<Foresight.Standard.StringKeyValue[]>(address);

                    if (emailaddress == null || emailaddress.Length == 0)
                        return FailedResult;
                    long woid = Convert.ToInt64(woidstr);
                    string absuri = Context.Request.Url.AbsoluteUri;
                    string wourl = absuri.Substring(0, absuri.LastIndexOf("/Maintenance", StringComparison.OrdinalIgnoreCase));
                    wourl = wourl + "/jump.aspx?p=" + Convert.ToBase64String(Encoding.UTF8.GetBytes("jt=woe;woid=" + woid));

                    CreateClient<WorkOrderProvider>().SendWorkOrderEmail(SystemParams.CompanyID, woid, desc, wourl, emailaddress);
                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        #endregion

        private object GetFilterDataSource()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    FilterDataSourceItem item = new FilterDataSourceItem();

                    var groups = MachineManagement.GetMachineGroupsByUser(session.User.UID, null);
                    List<StringKeyValue> list = new List<StringKeyValue>();
                    foreach (var gp in groups)
                    {
                        StringKeyValue kv = new StringKeyValue();
                        kv.Key = gp.GroupID;
                        kv.Value = gp.GroupName;
                        list.Add(kv);
                    }
                    item.AssetGroups = list.OrderBy((m) => m.Value).ToArray();

                    var client = CreateClient<CustomerProvider>();
                    CustomerLocation[] alllocs = client.GetLocations(SystemParams.CompanyID);
                    var plocs = alllocs.Where(d => d.PId <= 0).OrderBy(d => d.Name);
                    List<CustomerLocation> resultlocs = new List<CustomerLocation>();
                    foreach (var ploc in plocs)
                    {
                        resultlocs.Add(ploc);
                        resultlocs.AddRange(alllocs.Where(d => d.PId == ploc.ID).OrderBy(d => d.Name));
                    }
                    item.Locations = resultlocs.ToArray();

                    DepartmentInfo[] alldeps = client.GetAllDepartments(SystemParams.CompanyID);
                    var pdeps = alldeps.Where(d => d.PId <= 0).OrderBy(d => d.Name);
                    List<DepartmentInfo> result = new List<DepartmentInfo>();
                    foreach (var pdep in pdeps)
                    {
                        result.Add(pdep);
                        result.AddRange(alldeps.Where(d => d.PId == pdep.Id).OrderBy(d => d.Name));
                    }
                    item.Departments = result.ToArray();

                    List<StringKeyValue> adep = new List<StringKeyValue>();
                    var users = UserManagement.GetUsers();
                    foreach (var u in users.Where(u => u.ContactType == ContactTypes.Advisor))
                    {
                        StringKeyValue kv = new StringKeyValue();
                        kv.Key = u.IID.ToLower();
                        kv.Value = u.DisplayName;
                        adep.Add(kv);
                    }
                    item.Advisors = adep.OrderBy((m) => m.Value).ToArray();

                    List<StringKeyValue> otypes = new List<StringKeyValue>();
                    var wop = CreateClient<WorkOrderProvider>();
                    string[] woTypes = wop.GetWorkOrderTypes(SystemParams.CompanyID);
                    foreach (var t in woTypes)
                    {
                        StringKeyValue kv = new StringKeyValue();
                        kv.Key = t;
                        kv.Value = t;
                        otypes.Add(kv);
                    }
                    item.OrderTypes = otypes.OrderBy((m) => m.Value).ToArray();

                    List<StringKeyValue> statuses = new List<StringKeyValue>();
                    var wostatuses = wop.GetWorkOrderStatuses(SystemParams.CompanyID);
                    foreach (var s in wostatuses)
                    {
                        StringKeyValue kv = new StringKeyValue();
                        kv.Key = s.Id.ToString();
                        kv.Value = s.Name;
                        statuses.Add(kv);
                    }
                    item.Statuses = statuses.OrderBy((m) => m.Value).ToArray();

                    return item;
                }
                else
                    return new FilterDataSourceItem();
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetLocationsAndDepartments()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    FilterDataSourceItem item = new FilterDataSourceItem();
                    var client = CreateClient<CustomerProvider>();
                    CustomerLocation[] alllocs = client.GetLocations(SystemParams.CompanyID);
                    var plocs = alllocs.Where(d => d.PId <= 0).OrderBy(d => d.Name);
                    List<CustomerLocation> resultlocs = new List<CustomerLocation>();
                    foreach (var ploc in plocs)
                    {
                        resultlocs.Add(ploc);
                        resultlocs.AddRange(alllocs.Where(d => d.PId == ploc.ID).OrderBy(d => d.Name));
                    }
                    item.Locations = resultlocs.ToArray();

                    DepartmentInfo[] alldeps = client.GetAllDepartments(SystemParams.CompanyID);
                    var pdeps = alldeps.Where(d => d.PId <= 0).OrderBy(d => d.Name);
                    List<DepartmentInfo> result = new List<DepartmentInfo>();
                    foreach (var pdep in pdeps)
                    {
                        result.Add(pdep);
                        result.AddRange(alldeps.Where(d => d.PId == pdep.Id).OrderBy(d => d.Name));
                    }
                    item.Departments = result.ToArray();

                    return item;
                }
                else
                    return new FilterDataSourceItem();
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetDepartments()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var client = CreateClient<CustomerProvider>();
                    DepartmentInfo[] alldeps = client.GetAllDepartments(SystemParams.CompanyID);
                    var pdeps = alldeps.Where(d => d.PId <= 0).OrderBy(d => d.Name);
                    List<DepartmentInfo> result = new List<DepartmentInfo>();
                    foreach (var pdep in pdeps)
                    {
                        result.Add(pdep);
                        result.AddRange(alldeps.Where(d => d.PId == pdep.Id).OrderBy(d => d.Name));
                    }
                    return result.ToArray();
                }
                else
                    return new DepartmentInfo[0];
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object GetLocations()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var client = CreateClient<CustomerProvider>();
                    CustomerLocation[] alllocs = client.GetLocations(SystemParams.CompanyID);
                    var plocs = alllocs.Where(d => d.PId <= 0).OrderBy(d => d.Name);
                    List<CustomerLocation> result = new List<CustomerLocation>();
                    foreach (var ploc in plocs)
                    {
                        result.Add(ploc);
                        result.AddRange(alllocs.Where(d => d.PId == ploc.ID).OrderBy(d => d.Name));
                    }
                    return result.ToArray();
                }
                else
                    return new CustomerLocation[0];
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private string SetWorkOrderDefault()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    UserParams.SetStringParameter(session.User.UID, "WorkOrderDefault", clientdata);
                    return OkResult;
                }
                else
                {
                    return FailedResult;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetWorkOrderDefault()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);

                    string value = UserParams.GetStringParameter(session.User.UID, "WorkOrderDefault");

                    WorkOrderDefaultItem item = null;
                    try
                    {
                        if (!string.IsNullOrEmpty(value))
                            item = JsonConvert.DeserializeObject<WorkOrderDefaultItem>(value);
                    }
                    catch { }

                    return item;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private string SetWorkOrderCollapsed()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    UserParams.SetStringParameter(session.User.UID, "WorkOrderCollapsed", clientdata);
                    return OkResult;
                }
                else
                {
                    return FailedResult;
                }
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetWorkOrderCollapsed()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);

                    string value = UserParams.GetStringParameter(session.User.UID, "WorkOrderCollapsed");

                    StringKeyValue[] data = null;
                    if (!string.IsNullOrEmpty(value))
                        data = JsonConvert.DeserializeObject<StringKeyValue[]>(value);

                    return data;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetInvoiceNumber()
        {
            try
            {
                if (GetCurrentLoginSession() != null)
                {
                    var woid = Request.Form["ClientData"];
                    return new WorkOrderManager(SystemParams.DataDbConnectionString).GetInvoiceNumber(woid);
                }
                else
                    return new string[0];
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetComments()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var woid = Request.Form["ClientData"];

                    var msgs = CreateClient<WorkOrderProvider>().GetInternalTextMessages(SystemParams.CompanyID, Convert.ToInt64(woid));
                    List<TextMessageClient> list = new List<TextMessageClient>();
                    foreach (var c in msgs)
                    {
                        TextMessageClient citem = new TextMessageClient();
                        Helper.CloneProperty(citem, c);
                        citem.Participator.AddRange(c.Participator);
                        list.Add(citem);
                    }

                    return list.ToArray();
                }
                else
                    return new TextMessageClient[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetComments", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SendInternalComments()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    //string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    //string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = Convert.ToInt64(Request.Form["WorkorderId"]);
                    string comment = HttpUtility.UrlDecode(Request.Form["Comment"]);
                    StringKeyValue[] emailaddress = null;
                    StringKeyValue[] phonenumbers = null;
                    var emailstr = Request.Form["Emails"];
                    if (!string.IsNullOrEmpty(emailstr))
                    {
                        emailaddress = JsonConvert.DeserializeObject<StringKeyValue[]>(emailstr);
                    }
                    var phonestr = Request.Form["Phones"];
                    if (!string.IsNullOrEmpty(phonestr))
                    {
                        phonenumbers = JsonConvert.DeserializeObject<StringKeyValue[]>(phonestr);
                    }

                    string filename = null;
                    byte[] atta = null;
                    if (Request.Files.Count > 0)
                    {
                        for (int i = 0; i < Request.Files.Count; i++)
                        {
                            HttpPostedFile uploadFile = Request.Files[i];
                            filename = uploadFile.FileName;
                            atta = ConvertFile2bytes(uploadFile);
                            break;
                        }
                    }
                    string[] pnvalues = null;
                    string pnStr = null;

                    if (emailaddress != null && phonenumbers != null)
                    {
                        var wo = CreateClient<WorkOrderProvider>().GetWorkOrderInfo(SystemParams.CompanyID, woid);

                        var lang = GetLanguageCookie();
                        string title = SystemParams.GetTextByKey(lang, "P_WO_INTERNALCOMMUNICATIONADDED", "Internal communication added");
                        string won = wo.WorkOrderNumber;
                        if (string.IsNullOrWhiteSpace(won))
                            won = string.Format("WO {0}", woid);
                        title = string.Format("{0}: {1}", won, title);

                        List<StringKeyValue> phs = new List<StringKeyValue>();
                        phs.AddRange(emailaddress);
                        phs.AddRange(phonenumbers);

                        //string[] pns = phs.Select(m => m.Key).ToArray();
                        string[] pns = phs.Select(m => m.Value).ToArray();
                        pnvalues = phs.Select(m => m.Tag1).ToArray();
                        pnStr = string.Join(";", pns);
                    }

                    try
                    {
                        var client = CreateClient<WorkOrderProvider>();
                        client.SendInternalTextMessage(SystemParams.CompanyID, woid, pnStr, pnvalues, comment, false, filename, atta);
                    }
                    catch (Exception ex)
                    {
                        AddLog("ERROR", "WorkOrderBasePage.SendInternalComments.SendTextMessage", ex.Message, ex.ToString());
                    }
                }
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object GetCommunications()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var woid = Request.Form["ClientData"];

                    var msgs = CreateClient<WorkOrderProvider>().GetTextMessages(SystemParams.CompanyID, Convert.ToInt64(woid));
                    List<TextMessageClient> list = new List<TextMessageClient>();
                    foreach (var c in msgs)
                    {
                        TextMessageClient citem = new TextMessageClient();
                        Helper.CloneProperty(citem, c);
                        citem.Participator.AddRange(c.Participator);
                        list.Add(citem);
                    }

                    return list.ToArray();
                }
                else
                    return new TextMessageClient[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetCommunications", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object AddWorkOrderCommunication()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    bool license = SystemParams.HasLicense("CustomerRecord");
                    bool crpermission = CheckRight(SystemParams.CompanyID, Foresight.Fleet.Services.User.Feature.CUSTOMER_RECORD);
                    bool AllowCustomer = license && crpermission;
                    bool AllowCommunicate = license && CheckRight(SystemParams.CompanyID, Foresight.Fleet.Services.User.Feature.COMMUNICATEWITHCUSTOMER);
                    if (!AllowCommunicate) return "";

                    //string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    //string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = Convert.ToInt64(Request.Form["WorkorderId"]);
                    StringKeyValue[] phs = JsonConvert.DeserializeObject<StringKeyValue[]>(Request.Form["PMEmails"]);
                    string msg = HttpUtility.UrlDecode(Request.Form["Comment"]);
                    bool includeStatusLink = Request.Form["IncludeStatusLink"] == "1";
                    bool IsAttachment = Request.Form["IsAttachment"] == "1";
                    AttaDataInfo attaData = null;
                    string attaDataStr = HttpUtility.UrlDecode(Request.Params["AttaData"]);
                    if (!string.IsNullOrWhiteSpace(attaDataStr))
                        attaData = JsonConvert.DeserializeObject<AttaDataInfo>(attaDataStr);

                    string filename = null;
                    byte[] atta = null;
                    bool exceedsMax = false;
                    if (Request.Files.Count > 0)
                    {
                        for (int i = 0; i < Request.Files.Count; i++)
                        {
                            HttpPostedFile uploadFile = Request.Files[i];
                            filename = uploadFile.FileName;
                            atta = ConvertFile2bytes(uploadFile);
                            //if (uploadFile.ContentType?.StartsWith("image/") != true && atta.Length > MaxAttachmentSize)
                            //{
                            //    exceedsMax = true;
                            //}
                            break;//只支持一个附件
                        }
                    }
                    else if (attaData != null)
                    {
                        filename = string.IsNullOrWhiteSpace(attaData.Caption) ? attaData.FileName : attaData.Caption;
                        var attainfo = GetAttachmentContent(attaData.AttaType, attaData.Id);//只支持一个附件
                        if (attainfo != null)
                        {
                            if (!filename.EndsWith(attainfo.Item1))
                                filename = filename + attainfo.Item1;
                            atta = attainfo.Item2;
                        }
                        if (IsAttachment)
                        {
                            if (atta?.Length > MaxAttachmentSize)
                            {
                                exceedsMax = true;
                            }
                        }
                    }
                    var lang = GetLanguageCookie();
                    if (exceedsMax)
                    {
                        return SystemParams.GetTextByKey(lang, "P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS", "Attachment size exceeds the maximum allowed to be sent (1.2MB).");
                    }

                    var client = CreateClient<WorkOrderProvider>();
                    if (phs != null && phs.Length > 0)
                    {
                        string[] pns = phs.Select(m => m.Key).ToArray();
                        string[] pnvlues = phs.Select(m => m.Value).ToArray();
                        string pnStr = string.Join(";", pns);

                        try
                        {
                            client.SendTextMessage(SystemParams.CompanyID, woid, pnStr, pnvlues, msg, includeStatusLink, filename, atta);
                        }
                        catch (Foresight.Standard.BusinessException ex)
                        {
                            AddLog("ERROR", "WorkOrderBasePage.AddWorkOrderCommunication.SendTextMessage", ex.Message, ex.ToString());
                            if (ex.ErrorCode == 101)
                                return SystemParams.GetTextByKey(lang, "P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS", "Attachment size exceeds the maximum allowed to be sent (1.2MB).");
                        }
                        catch (Exception ex)
                        {
                            AddLog("ERROR", "WorkOrderBasePage.AddWorkOrderCommunication.SendTextMessage", ex.Message, ex.ToString());
                        }
                    }
                    //foreach (var pm in phonenumbers)
                    //{
                    //    client.SendTextMessage(SystemParams.CompanyID, woid, pm, msg);
                    //}
                }
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        //at: 1:Asset, 2: WorkOrder, 3: Inspection
        private Tuple<string, byte[]> GetAttachmentContent(string at, string attaid)
        {
            byte[] content = null;
            string ext = null;
            if (at == "1" || at == "2")
            {
                long aid = 0;
                if (!long.TryParse(attaid, out aid))
                    return new Tuple<string, byte[]>(null, null);
                var client = FleetServiceClientHelper.CreateClient<WorkOrderProvider>(SystemParams.CompanyID, GetCurrentLoginSession().SessionID);
                Tuple<string, byte[]> atta = null;
                if (at == "1")
                {
                    atta = client.GetAssetAttachmentData(SystemParams.CompanyID, aid);
                }
                else
                {
                    atta = client.GetWorkOrderAttachmentData(SystemParams.CompanyID, aid);
                }

                if (atta != null)
                {
                    content = atta.Item2;
                    ext = atta.Item1;
                }
            }
            else if (at == "3")
            {
                var client = FleetServiceClientHelper.CreateClient<AssetInspectClient>(SystemParams.CompanyID, GetCurrentLoginSession().SessionID);
                var atta = client.DownloadMediaContent(SystemParams.CompanyID, attaid);
                if (atta != null)
                {
                    content = atta.Content;
                    ext = atta.FileType;
                }
            }
            return new Tuple<string, byte[]>(ext, content);
        }
        private object GetWOInspectItems()
        {
            try
            {
                var sesstion = GetCurrentLoginSession();
                if (sesstion != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = 0;
                    long assetid = 0;
                    long.TryParse(ps[0], out woid);
                    long.TryParse(ps[1], out assetid);

                    var client = CreateClient<WorkOrderProvider>();
                    AssetInspectItem[] insplectitems = client.GetWOInspectItems(SystemParams.CompanyID, woid);
                    if (insplectitems == null || insplectitems.Length == 0)
                        return new
                        {
                            WorkOrderID = woid,
                            Data = new AssetInspectItem[0]
                        };

                    List<AssetInspectInfo> list = new List<AssetInspectInfo>();
                    foreach (AssetInspectItem item in insplectitems)
                    {
                        AssetInspectInfo inspect = new AssetInspectInfo();
                        Helper.CloneProperty(inspect, item);
                        list.Add(inspect);
                    }

                    if (list.Count > 0)
                    {
                        WorkOrderListItem[] wos = client.GetWorkOrderItemsByAsset(SystemParams.CompanyID, assetid);
                        wos = wos.OrderByDescending(w => !w.Completed).ThenBy(w => w.WorkOrderNumber).ToArray();
                        list[0].WorkOrders = wos;
                    }

                    return new
                    {
                        WorkOrderID = woid,
                        Data = list.ToArray()
                    };
                }
                else
                    return new
                    {
                        WorkOrderID = -1,
                        Data = new AssetInspectItem[0]
                    };
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object UpdateInspectionWorkOrder()
        {
            try
            {
                var sesstion = GetCurrentLoginSession();
                if (sesstion != null)
                {
                    string clientdata = Request.Params["ClientData"];
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    string ispid = ps[0];
                    long woid = 0;
                    long oldwoid = 0;
                    long.TryParse(ps[1], out woid);
                    long.TryParse(ps[2], out oldwoid);

                    CreateClient<AssetInspectClient>().UpdateInspectionWorkOrder(SystemParams.CompanyID, ispid, woid, oldwoid);
                    return new string[0];
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetWorkOrderTypes()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var items = CreateClient<WorkOrderProvider>().GetWorkOrderTypes(SystemParams.CompanyID);
                    return items;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetPartsStatuses()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var items = CreateClient<WorkOrderProvider>().GetPartsStatuses(SystemParams.CompanyID);
                    return items;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object GetWorkOrderNumbers()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var items = CreateClient<WorkOrderProvider>().GetWorkOrderNumbers(SystemParams.CompanyID);
                    return items;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object GetWorkOrderHistorys()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Params["ClientData"];
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = Convert.ToInt64(ps[0]);

                    DateTime beginDate = Helper.DBMinDateTime;
                    DateTime endDate = DateTime.MaxValue;
                    if (!DateTime.TryParse(ps[1], out beginDate))
                        beginDate = Helper.DBMinDateTime;
                    if (!DateTime.TryParse(ps[2], out endDate))
                        endDate = DateTime.MaxValue;

                    WorkOrderHistoryInfo[] items = CreateClient<WorkOrderProvider>().GetWorkOrderHistorys(SystemParams.CompanyID, woid, beginDate, endDate, "");
                    if (items == null || items.Length == 0)
                        return new WorkOrderHistoryItem[0];

                    List<WorkOrderHistoryItem> ls = new List<WorkOrderHistoryItem>();
                    foreach (WorkOrderHistoryInfo item in items)
                    {
                        WorkOrderHistoryItem his = new WorkOrderHistoryItem();
                        Helper.CloneProperty(his, item);
                        ls.Add(his);
                    }
                    return ls.ToArray();
                }
                else
                    return new WorkOrderHistoryItem[0];
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }


        #region Estimate

        private object GetWorkOrderEstimates()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long woid = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    var client = CreateClient<WorkOrderProvider>();
                    WorkOrderEstimateInfo[] estimates = client.GetWorkOrderEstimates(SystemParams.CompanyID, woid);
                    if (estimates == null || estimates.Length == 0)
                        return new
                        {
                            WorkOrderID = woid,
                            Data = new WorkOrderEstimateItem[0]
                        };

                    List<WorkOrderEstimateItem> list = new List<WorkOrderEstimateItem>();
                    foreach (WorkOrderEstimateInfo es in estimates)
                    {
                        WorkOrderEstimateItem item = new WorkOrderEstimateItem();
                        Helper.CloneProperty(item, es);
                        WorkOrderAttachmentInfo[] atts = client.GetWorkOrderEstimateAttachments(SystemParams.CompanyID, item.Id);
                        if (atts != null && atts.Length > 0)
                        {
                            List<WorkOrderAttachmentItem> lsatt = new List<WorkOrderAttachmentItem>();
                            foreach (var att in atts)
                            {
                                WorkOrderAttachmentItem attitem = new WorkOrderAttachmentItem();
                                Helper.CloneProperty(attitem, att);
                                lsatt.Add(attitem);
                            }
                            item.Attachments = lsatt.ToArray();
                        }

                        list.Add(item);
                    }

                    return new
                    {
                        WorkOrderID = woid,
                        Data = list.ToArray()
                    };
                }
                else
                    return new
                    {
                        WorkOrderID = -1,
                        Data = new WorkOrderEstimateItem[0]
                    };
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderEstimates", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SaveWorkOrderEstimate()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    WorkOrderEstimateInfo est = JsonConvert.DeserializeObject<WorkOrderEstimateInfo>(clientdata);

                    if (est.Id == -1)
                    {
                        est.Id = CreateClient<WorkOrderProvider>().AddNewWorkOrderEstimate(SystemParams.CompanyID, est);
                    }
                    else
                    {
                        CreateClient<WorkOrderProvider>().UpdateWorkOrderEstimate(SystemParams.CompanyID, est);
                    }

                    return est.Id;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object PublishEstimateToCustomer()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long id = Convert.ToInt64(ps[0]);
                    long woid = Convert.ToInt64(ps[1]);
                    StringKeyValue[] phs = JsonConvert.DeserializeObject<StringKeyValue[]>(ps[2]);
                    string msg = ps[3];
                    bool includeStatusLink = ps[4] == "1";

                    AttaDataInfo attaData = null;
                    string attaDataStr = HttpUtility.HtmlDecode(Request.Params["AttaData"]);
                    if (!string.IsNullOrWhiteSpace(attaDataStr))
                        attaData = JsonConvert.DeserializeObject<AttaDataInfo>(attaDataStr);

                    var client = CreateClient<WorkOrderProvider>();

                    string filename = null;
                    byte[] atta = null;
                    bool exceedsMax = false;
                    if (Request.Files.Count > 0)
                    {
                        for (int i = 0; i < Request.Files.Count; i++)
                        {
                            HttpPostedFile uploadFile = Request.Files[i];
                            filename = uploadFile.FileName;
                            atta = ConvertFile2bytes(uploadFile);
                            if (uploadFile.ContentType?.StartsWith("image/") != true && atta.Length > MaxAttachmentSize)
                            {
                                exceedsMax = true;
                            }
                            break;//只支持一个附件
                        }
                    }
                    else if (attaData != null)
                    {
                        filename = string.IsNullOrWhiteSpace(attaData.Caption) ? attaData.FileName : attaData.Caption;
                        var attainfo = client.GetWorkOrderEstimateAttachmentData(SystemParams.CompanyID, attaData.Id);
                        if (attainfo != null)
                        {
                            if (!filename.EndsWith(attainfo.Item1))
                                filename += attainfo.Item1;
                            atta = attainfo.Item2;
                            if (atta?.Length > MaxAttachmentSize)
                            {
                                exceedsMax = true;
                            }
                        }
                    }

                    var lang = GetLanguageCookie();
                    if (exceedsMax)
                    {
                        return SystemParams.GetTextByKey(lang, "P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS", "Attachment size exceeds the maximum allowed to be sent (1.2MB).");
                    }
                    client.PublishEstimateToCustomer(SystemParams.CompanyID, id);
                    if (phs != null && phs.Length > 0)
                    {
                        string[] pns = phs.Select(m => m.Key).ToArray();
                        string[] pnvalues = phs.Select(m => m.Value).ToArray();
                        string pnStr = string.Join(";", pns);

                        try
                        {
                            client.SendTextMessage(SystemParams.CompanyID, woid, pnStr, pnvalues, msg, includeStatusLink, filename, atta);
                        }
                        catch (Foresight.Standard.BusinessException ex)
                        {
                            AddLog("ERROR", "WorkOrderBasePage.PublishEstimateToCustomer.SendTextMessage", ex.Message, ex.ToString());
                            if (ex.ErrorCode == 101)
                                return SystemParams.GetTextByKey(lang, "P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS", "Attachment size exceeds the maximum allowed to be sent (1.2MB).");
                        }
                        catch (Exception ex)
                        {
                            AddLog("ERROR", "WorkOrderBasePage.PublishEstimateToCustomer.SendTextMessage", ex.Message, ex.ToString());
                        }
                    }
                }

                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object UpdateWOEstimateVisibleToCustomer()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long id = Convert.ToInt64(ps[0]);
                    bool visibleToCustomer = Helper.IsTrue(ps[1]);

                    var client = CreateClient<WorkOrderProvider>();
                    client.UpdateWOEstimateVisibleToCustomer(SystemParams.CompanyID, id, visibleToCustomer);
                }

                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteWorkOrderEstimate()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long id = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().DeleteWorkOrderEstimate(SystemParams.CompanyID, id);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object RevokeWorkOrderEstimate()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long id = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().RevokeWorkOrderEstimate(SystemParams.CompanyID, id);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetEstimateAttachment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long estid = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    WorkOrderAttachmentInfo[] atts = CreateClient<WorkOrderProvider>().GetWorkOrderEstimateAttachments(SystemParams.CompanyID, estid);
                    if (atts == null || atts.Length == 0)
                        return new WorkOrderAttachmentItem[0];

                    List<WorkOrderAttachmentItem> ls = new List<WorkOrderAttachmentItem>();
                    foreach (var att in atts)
                    {
                        WorkOrderAttachmentItem attitem = new WorkOrderAttachmentItem();
                        Helper.CloneProperty(attitem, att);
                        ls.Add(attitem);
                    }

                    return ls.ToArray();
                }
                else
                    return new WorkOrderAttachmentItem[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetEstimateAttachment", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object AddEstimateAttachment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    string estid = ps[0];
                    string[] notesdata = JsonConvert.DeserializeObject<string[]>(ps[1]);

                    if (Request.Files.Count > 0)
                    {
                        for (int i = 0; i < Request.Files.Count; i++)
                        {
                            HttpPostedFile uploadFile = null;
                            byte[] iconfilebyte = null;
                            uploadFile = Request.Files[i];
                            iconfilebyte = ConvertFile2bytes(uploadFile);

                            string filename = uploadFile == null ? "" : uploadFile.FileName;
                            string notes = HttpUtility.UrlDecode(notesdata[i]);
                            long attid = CreateClient<WorkOrderProvider>().AddWorkOrderEstimateAttachment(SystemParams.CompanyID, Convert.ToInt64(estid), filename, notes, iconfilebyte);
                        }
                    }

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteEstimateAttachment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string estid = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    CreateClient<WorkOrderProvider>().DeleteWorkOrderEstimateAttachment(SystemParams.CompanyID, Convert.ToInt64(estid));
                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }

        }

        #endregion

        #region Survey

        private object GetSurveyTemplateItems()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    var client = CreateClient<WorkOrderSurveyProvider>();
                    SurveyTemplateItem[] temps = client.GetSurveyTemplateItems(SystemParams.CompanyID, clientdata);
                    if (temps == null || temps.Length == 0)
                        return new SurveyTemplateItem[0];

                    int[] tempids = client.GetWorkOrderSurveyTemplates(SystemParams.CompanyID);
                    List<SurveyTemplateClient> ls = new List<SurveyTemplateClient>();
                    foreach (SurveyTemplateItem item in temps)
                    {
                        SurveyTemplateClient temp = new SurveyTemplateClient();
                        Helper.CloneProperty(temp, item);
                        if (tempids != null && tempids.Length > 0 && tempids.Contains(temp.Id))
                            temp.InUse = true;
                        ls.Add(temp);
                    }

                    return ls.ToArray();
                }
                else
                    return new SurveyTemplateClient[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetSurveyTemplateItems", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetSurveyTemplateInfo()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    int id = Convert.ToInt32(HttpUtility.HtmlDecode(clientdata));

                    var client = CreateClient<WorkOrderSurveyProvider>();
                    SurveyTemplateInfo temp = client.GetSurveyTemplateInfo(SystemParams.CompanyID, id);
                    if (temp == null)
                        return new SurveyTemplateInfo();

                    return temp;
                }
                else
                    return new SurveyTemplateInfo();

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetSurveyTemplateItems", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SaveSurveyTemplate()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    SurveyTemplateInfo temp = JsonConvert.DeserializeObject<SurveyTemplateInfo>(clientdata);

                    if (temp.Questions != null && temp.Questions.Count > 0)
                    {
                        foreach (SurveyTemplateQuestion qus in temp.Questions)
                        {
                            if (string.IsNullOrWhiteSpace(qus.Id))
                                qus.Id = Guid.NewGuid().ToString();
                        }
                    }

                    if (temp.Id == -1)
                    {
                        temp.Id = CreateClient<WorkOrderSurveyProvider>().AddNewSurveyTemplate(SystemParams.CompanyID, temp);
                    }
                    else
                    {
                        CreateClient<WorkOrderSurveyProvider>().UpdateSurveyTemplate(SystemParams.CompanyID, temp);
                    }

                    return temp.Id;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteSurveyTemplate()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    int id = Convert.ToInt32(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderSurveyProvider>().DeleteSurveyTemplate(SystemParams.CompanyID, id);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object SendWorkOrderSurveys()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long[] woids = JsonConvert.DeserializeObject<long[]>(ps[0]);
                    int templateid = Convert.ToInt32(ps[1]);
                    CreateClient<WorkOrderSurveyProvider>().CreateWorkOrderSurveys(SystemParams.CompanyID, woids, templateid);
                }
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object CreateWorkOrderSurveysByContacts()
        {
            try
            {
                var user = GetCurrentUser();
                if (user != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long woid = Convert.ToInt64(ps[0]);
                    int templateid = Convert.ToInt32(ps[1]);
                    Foresight.Fleet.Services.AssetHealth.WorkOrder.ContactInfo[] contacts = JsonConvert.DeserializeObject<Foresight.Fleet.Services.AssetHealth.WorkOrder.ContactInfo[]>(ps[2]);

                    CreateClient<WorkOrderSurveyProvider>().CreateWorkOrderSurveysByContacts(SystemParams.CompanyID, woid, templateid, contacts);
                }
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetWorkOrderSurveysByIDs()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string ps = clientdata;
                    string[] p = ps.Split(',');
                    List<long> list = new List<long>();
                    foreach (string s in p)
                    {
                        list.Add(Convert.ToInt64(s));
                    }
                    var client = CreateClient<WorkOrderSurveyProvider>();
                    WorkOrderSurveyItem[] items = client.GetWorkOrderSurveyItemsBySurveyIds(SystemParams.CompanyID, list.ToArray());
                    if (items == null || items.Length == 0)
                        return new WorkOrderSurveyInfo[0];

                    List<WorkOrderSurveyInfo> ls = new List<WorkOrderSurveyInfo>();
                    foreach (WorkOrderSurveyItem item in items)
                    {
                        WorkOrderSurveyInfo si = new WorkOrderSurveyInfo();
                        Helper.CloneProperty(si, item);
                        ls.Add(si);
                    }
                    return ls.ToArray();
                }
                else
                    return new WorkOrderSurveyInfo[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderSurveys", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetWorkOrderSurveys()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    int status = Convert.ToInt32(ps[0]);
                    DateTime beginDate = Helper.DBMinDateTime;
                    DateTime endDate = DateTime.MaxValue;
                    if (!DateTime.TryParse(ps[1], out beginDate))
                        beginDate = Helper.DBMinDateTime;
                    if (!DateTime.TryParse(ps[2], out endDate))
                        endDate = DateTime.MaxValue;
                    int[] locations = JsonConvert.DeserializeObject<int[]>(ps[4]);
                    string[] advisors = JsonConvert.DeserializeObject<string[]>(ps[5]);
                    int tempid = Convert.ToInt32(ps[6]);

                    DateTime wobeginDate = Helper.DBMinDateTime;
                    DateTime woendDate = DateTime.MaxValue;
                    if (!DateTime.TryParse(ps[7], out wobeginDate))
                        wobeginDate = Helper.DBMinDateTime;
                    if (!DateTime.TryParse(ps[8], out woendDate))
                        woendDate = DateTime.MaxValue;

                    var client = CreateClient<WorkOrderSurveyProvider>();
                    WorkOrderSurveyItem[] items = client.GetWorkOrderSurveyItems(SystemParams.CompanyID, status, beginDate, endDate == DateTime.MaxValue ? (DateTime?)null : endDate, HttpUtility.HtmlDecode(ps[3]), locations, advisors, tempid, wobeginDate, woendDate == DateTime.MaxValue ? (DateTime?)null : woendDate);
                    if (items == null || items.Length == 0)
                        return new WorkOrderSurveyInfo[0];

                    List<WorkOrderSurveyInfo> ls = new List<WorkOrderSurveyInfo>();
                    foreach (WorkOrderSurveyItem item in items)
                    {
                        WorkOrderSurveyInfo si = new WorkOrderSurveyInfo();
                        Helper.CloneProperty(si, item);
                        if (si.Contacts.Count > 0)
                            si.Contacts = si.Contacts.OrderBy(m => m.SurveyOptOut_BC).ToList();
                        ls.Add(si);
                    }
                    return ls.ToArray();
                }
                else
                    return new WorkOrderSurveyInfo[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderSurveys", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SetDoNotSendSurvey()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long id = Convert.ToInt64(ps[0]);
                    bool check = Helper.IsTrue(ps[1]);
                    CreateClient<WorkOrderSurveyProvider>().SetDoNotSendSurvey(SystemParams.CompanyID, id, check);

                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetWorkOrderSurveyResult()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    int id = Convert.ToInt32(HttpUtility.HtmlDecode(clientdata));

                    var client = CreateClient<WorkOrderSurveyProvider>();
                    WorkOrderSurveyResult result = client.GetWorkOrderSurveyResult(SystemParams.CompanyID, id);
                    WorkOrderSurveyResultItem item = new WorkOrderSurveyResultItem();
                    item.SurveyData = result;

                    return item;
                }
                else
                    return new WorkOrderSurveyResult();

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderSurveyResult", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private byte[] GetWorkOrderSurveyPDF(out string fileName, bool print = true)
        {
            fileName = "";
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string id = Request.Params["id"];
                    byte[] bytes = null;

                    var client = CreateClient<WorkOrderSurveyProvider>();
                    bytes = client.GetWorkOrderSurveyPDF(SystemParams.CompanyID, Convert.ToInt64(id));
                    fileName = "Work Order Survey";
                    FICHostEnvironment.WriteExportAuditTrail(session.User.UID, "WorkOrderSurvey", "", print ? "Print" : "DownLoad", fileName + ".pdf", print ? "" : ".pdf", bytes);
                    return bytes;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private byte[] GetWorkOrderReportPDF(out string fileName)
        {
            fileName = "";
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string id = Request.Params["id"];
                    string type = Request.Params["tt"];
                    byte[] bytes = null;

                    var client = CreateClient<WorkOrderProvider>();
                    bytes = client.GetWorkOrderPDF(SystemParams.CompanyID, Convert.ToInt64(id), Convert.ToInt32(type));
                    fileName = "Work Order Report";
                    FICHostEnvironment.WriteExportAuditTrail(session.User.UID, "WorkOrderReport", "", "", fileName + ".pdf", ".pdf", bytes);
                    return bytes;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private object GetSurveyTemplateReport()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);

                    var id = HttpUtility.HtmlDecode(ps[0]);
                    var sdatestr = HttpUtility.HtmlDecode(ps[1]);
                    var edatestr = HttpUtility.HtmlDecode(ps[2]);

                    int[] locations = JsonConvert.DeserializeObject<int[]>(ps[3]);
                    string[] advisors = JsonConvert.DeserializeObject<string[]>(ps[4]);

                    DateTime? beginDate = null;
                    DateTime? endDate = null;
                    DateTime bDate = DateTime.Now;
                    DateTime eDate = DateTime.Now;
                    if (DateTime.TryParse(sdatestr, out bDate))
                    {
                        beginDate = bDate;
                    }
                    if (DateTime.TryParse(edatestr, out eDate))
                    {
                        endDate = eDate;
                    }
                    var client = CreateClient<WorkOrderSurveyProvider>();
                    SurveyReportInfo report = client.GetWorkOrderSurveyReport(SystemParams.CompanyID, Convert.ToInt32(id), beginDate, endDate, locations, advisors);

                    return report;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                return null;
            }
        }

        private object GetSurveyTemplateEmail()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = HttpUtility.UrlDecode(Request.Params["ClientData"]);
                    string[] pars = clientdata.Split((char)170);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(pars[0]);

                    var id = HttpUtility.HtmlDecode(ps[0]);
                    var sdatestr = HttpUtility.HtmlDecode(ps[1]);
                    var edatestr = HttpUtility.HtmlDecode(ps[2]);

                    int[] locations = JsonConvert.DeserializeObject<int[]>(ps[3]);
                    string[] advisors = JsonConvert.DeserializeObject<string[]>(ps[4]);

                    DateTime? beginDate = null;
                    DateTime? endDate = null;
                    DateTime bDate = DateTime.Now;
                    DateTime eDate = DateTime.Now;
                    if (DateTime.TryParse(sdatestr, out bDate))
                    {
                        beginDate = bDate;
                    }
                    if (DateTime.TryParse(edatestr, out eDate))
                    {
                        endDate = eDate;
                    }
                    var client = CreateClient<WorkOrderSurveyProvider>();
                    SurveyReportInfo report = client.GetWorkOrderSurveyReport(SystemParams.CompanyID, Convert.ToInt32(id), beginDate, endDate, locations, advisors);

                    StringKeyValue[] emails = JsonConvert.DeserializeObject<StringKeyValue[]>(pars[1]);

                    var (body, images) = WorkOrderManager.GetSurveyReportEmail(report);

                    var subject = "Survey Report - Template: " + report.TemplateName;

                    foreach (var email in emails)
                    {
                        var view = AlternateView.CreateAlternateViewFromString(body, Encoding.Default, "text/html");
                        foreach (var image in images)
                        {
                            view.LinkedResources.Add(new LinkedResource(new System.IO.MemoryStream(image.Value), "image/jpeg") { ContentId = image.Key });
                        }
                        var message = new MailMessage
                        {
                            Subject = subject,
                            To = { new MailAddress(email.Value, email.Key) },
                            Body = body,
                            IsBodyHtml = true,
                            AlternateViews = { view }
                        };
                        SystemParams.SendMail(message);
                    }
                    return null;
                }
                return "Unknown error occurs.";
            }
            catch (Exception ex)
            {
                AddLog("Error", "GetSurveyTemplateEmail", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object GetSurveyPreviewUrl()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string id = HttpUtility.UrlDecode(Request.Params["ClientData"]);
                    var client = CreateClient<CustomerProvider>();
                    var custid = SystemParams.CompanyID;
                    var detail = client.GetCustomerDetail(custid);
                    return new[]
                    {
                         detail.CustomerSiteAddress + "/wosurvey?sid=" + id + "&cid=" + custid + "&preview=1"
                    };
                }
                return "Id is required.";
            }
            catch (Exception ex)
            {
                AddLog("Error", "GetSurveyTemplateEmail", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        #endregion


        #region Invoice

        private object GetWorkOrderInvoices()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long woid = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    var client = CreateClient<WorkOrderProvider>();
                    WorkOrderInvoiceInfo[] invoices = client.GetWorkOrderInvoices(SystemParams.CompanyID, woid);
                    if (invoices == null || invoices.Length == 0)
                        return new
                        {
                            WorkOrderID = woid,
                            Data = new WorkOrderInvoiceInfoItem[0]
                        };

                    List<WorkOrderInvoiceInfoItem> list = new List<WorkOrderInvoiceInfoItem>();
                    foreach (WorkOrderInvoiceInfo es in invoices)
                    {
                        WorkOrderInvoiceInfoItem item = new WorkOrderInvoiceInfoItem();
                        Helper.CloneProperty(item, es);
                        WorkOrderAttachmentInfo[] atts = client.GetWorkOrderInvoiceAttachments(SystemParams.CompanyID, item.Id);
                        if (atts != null && atts.Length > 0)
                        {
                            List<WorkOrderAttachmentItem> lsatt = new List<WorkOrderAttachmentItem>();
                            foreach (var att in atts)
                            {
                                WorkOrderAttachmentItem attitem = new WorkOrderAttachmentItem();
                                Helper.CloneProperty(attitem, att);
                                lsatt.Add(attitem);
                            }
                            item.Attachments = lsatt.ToArray();
                        }

                        if (item.Status == WorkOrderInvoiceStatus.Paid)
                        {
                            try
                            {
                                PaymentInfo payment = client.GetWorkOrderInvoicePayment(SystemParams.CompanyID, item.Id);
                                if (payment != null)
                                {
                                    PaymentItem pitem = new PaymentItem();
                                    Helper.CloneProperty(pitem, payment);
                                    item.PaymentItem = pitem;
                                }
                            }
                            catch (Exception ex1)
                            {
                                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderInvoices.GetWorkOrderInvoicePayment", ex1.Message, ex1.ToString());
                            }
                        }
                        else if (item.Status == WorkOrderInvoiceStatus.ManualPaid)
                        {
                            try
                            {
                                item.PaymentItem = new PaymentItem()
                                {
                                    CheckNumber = item.CheckNumber,
                                    PaymentEnteredByName = item.PaymentEnteredByName,
                                    PaymentType = item.PaymentMethod,
                                    CreatedLocal = item.PaymentEnteredOnLocal
                                };
                            }
                            catch (Exception ex1)
                            {
                                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderInvoices.GetWorkOrderInvoicePayment", ex1.Message, ex1.ToString());
                            }
                        }

                        list.Add(item);
                    }

                    return new
                    {
                        WorkOrderID = woid,
                        Data = list.ToArray()
                    };
                }
                else
                    return new
                    {
                        WorkOrderID = -1,
                        Data = new WorkOrderInvoiceInfoItem[0]
                    };
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderInvoices", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SaveWorkOrderInvoice()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    WorkOrderInvoiceInfo invoice = JsonConvert.DeserializeObject<WorkOrderInvoiceInfo>(clientdata);

                    if (invoice.Id == -1)
                    {
                        invoice.Id = CreateClient<WorkOrderProvider>().AddNewWorkOrderInvoice(SystemParams.CompanyID, invoice);
                    }
                    else
                    {
                        CreateClient<WorkOrderProvider>().UpdateWorkOrderInvoice(SystemParams.CompanyID, invoice);
                    }

                    return invoice.Id;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object PublishInvoiceToCustomer()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = HttpUtility.HtmlDecode(Request.Params["ClientData"]);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    long id = Convert.ToInt64(ps[0]);
                    long woid = Convert.ToInt64(ps[1]);
                    StringKeyValue[] phs = JsonConvert.DeserializeObject<StringKeyValue[]>(ps[2]);
                    string msg = ps[3];
                    bool includeStatusLink = ps[4] == "1";

                    AttaDataInfo attaData = null;
                    string attaDataStr = HttpUtility.HtmlDecode(Request.Params["AttaData"]);
                    if (!string.IsNullOrWhiteSpace(attaDataStr))
                        attaData = JsonConvert.DeserializeObject<AttaDataInfo>(attaDataStr);

                    var client = CreateClient<WorkOrderProvider>();

                    string filename = null;
                    byte[] atta = null;
                    bool exceedsMax = false;
                    if (Request.Files.Count > 0)
                    {
                        for (int i = 0; i < Request.Files.Count; i++)
                        {
                            HttpPostedFile uploadFile = Request.Files[i];
                            filename = uploadFile.FileName;
                            atta = ConvertFile2bytes(uploadFile);
                            if (uploadFile.ContentType?.StartsWith("image/") != true && atta.Length > MaxAttachmentSize)
                            {
                                exceedsMax = true;
                            }
                            break;//只支持一个附件
                        }
                    }
                    else if (attaData != null)
                    {
                        filename = string.IsNullOrWhiteSpace(attaData.Caption) ? attaData.FileName : attaData.Caption;
                        var attainfo = client.GetWorkOrderEstimateAttachmentData(SystemParams.CompanyID, attaData.Id);
                        if (attainfo != null)
                        {
                            if (!filename.EndsWith(attainfo.Item1))
                                filename += attainfo.Item1;
                            atta = attainfo.Item2;
                            if (atta?.Length > MaxAttachmentSize)
                            {
                                exceedsMax = true;
                            }
                        }
                    }
                    var lang = GetLanguageCookie();
                    if (exceedsMax)
                    {
                        return SystemParams.GetTextByKey(lang, "P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS", "Attachment size exceeds the maximum allowed to be sent (1.2MB).");
                    }

                    client.PublishInvoiceToCustomer(SystemParams.CompanyID, id);
                    if (phs != null && phs.Length > 0)
                    {
                        string[] pns = phs.Select(m => m.Key).ToArray();
                        string[] pnvalues = phs.Select(m => m.Value).ToArray();
                        string pnStr = string.Join(";", pns);

                        try
                        {
                            client.SendTextMessage(SystemParams.CompanyID, woid, pnStr, pnvalues, msg, includeStatusLink, filename, atta);
                        }
                        catch (Foresight.Standard.BusinessException ex)
                        {
                            AddLog("ERROR", "WorkOrderBasePage.PublishInvoiceToCustomer.SendTextMessage", ex.Message, ex.ToString());
                            if (ex.ErrorCode == 101)
                                return SystemParams.GetTextByKey(lang, "P_WO_ATTACHMENTSIZEEXCEEDSTHEMAXIMUMTIPS", "Attachment size exceeds the maximum allowed to be sent (1.2MB).");
                        }
                        catch (Exception ex)
                        {
                            AddLog("ERROR", "WorkOrderBasePage.PublishInvoiceToCustomer.SendTextMessage", ex.Message, ex.ToString());
                        }
                    }
                }

                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteWorkOrderInvoice()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long id = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().DeleteWorkOrderInvoice(SystemParams.CompanyID, id);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object RevokeWorkOrderInvoice()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long id = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().RevokeWorkOrderInvoice(SystemParams.CompanyID, id);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object MarkAsPaid()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    string[] ps = JsonConvert.DeserializeObject<string[]>(HttpUtility.HtmlDecode(clientdata));
                    long id = Convert.ToInt64(ps[0]);
                    WorkOrderInvoiceInfo i = new WorkOrderInvoiceInfo()
                    {
                        Id = id,
                        Status = WorkOrderInvoiceStatus.ManualPaid,
                        PaymentMethod = ps[1],
                        CheckNumber = ps[2]
                    };

                    CreateClient<WorkOrderProvider>().MarkAsPaid(SystemParams.CompanyID, i);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object CancelPayment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long id = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    CreateClient<WorkOrderProvider>().CancelPayment(SystemParams.CompanyID, id);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object ChangeWOInvoiceCustomerVisible()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    string[] ps = JsonConvert.DeserializeObject<string[]>(HttpUtility.HtmlDecode(clientdata));
                    long id = Convert.ToInt64(ps[0]);

                    CreateClient<WorkOrderProvider>().ChangeWOInvoiceCustomerVisible(SystemParams.CompanyID, id, Convert.ToInt32(ps[1]) == 1);

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetWorkOrderInvoicePayment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long invoiceid = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    var client = CreateClient<WorkOrderProvider>();
                    PaymentInfo payment = client.GetWorkOrderInvoicePayment(SystemParams.CompanyID, invoiceid);
                    if (payment == null)
                        return null;

                    PaymentItem pitem = new PaymentItem();
                    Helper.CloneProperty(pitem, payment);
                    if (payment.Card != null)
                    {
                        pitem.Card = new CardItem();
                        Helper.CloneProperty(pitem.Card, payment.Card);
                    }

                    return pitem;
                }
                else
                    return null;
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderInvoicePayment", ex.Message, ex.ToString());
                return ex.Message;
            }
        }
        private object GetWorkOrderInvoiceAttachments()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long estid = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    WorkOrderAttachmentInfo[] atts = CreateClient<WorkOrderProvider>().GetWorkOrderInvoiceAttachments(SystemParams.CompanyID, estid);
                    if (atts == null || atts.Length == 0)
                        return new WorkOrderAttachmentItem[0];

                    List<WorkOrderAttachmentItem> ls = new List<WorkOrderAttachmentItem>();
                    foreach (var att in atts)
                    {
                        WorkOrderAttachmentItem attitem = new WorkOrderAttachmentItem();
                        Helper.CloneProperty(attitem, att);
                        ls.Add(attitem);
                    }

                    return ls.ToArray();
                }
                else
                    return new WorkOrderAttachmentItem[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderInvoiceAttachments", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object AddInvoiceAttachment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);
                    string estid = ps[0];
                    string[] notesdata = JsonConvert.DeserializeObject<string[]>(ps[1]);

                    if (Request.Files.Count > 0)
                    {
                        for (int i = 0; i < Request.Files.Count; i++)
                        {
                            HttpPostedFile uploadFile = null;
                            byte[] iconfilebyte = null;
                            uploadFile = Request.Files[i];
                            iconfilebyte = ConvertFile2bytes(uploadFile);

                            string filename = uploadFile == null ? "" : uploadFile.FileName;
                            string notes = HttpUtility.UrlDecode(notesdata[i]);
                            long attid = CreateClient<WorkOrderProvider>().AddWorkOrderInvoiceAttachment(SystemParams.CompanyID, Convert.ToInt64(estid), filename, notes, iconfilebyte);
                        }
                    }

                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object DeleteInvoiceAttachment()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string estid = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    CreateClient<WorkOrderProvider>().DeleteWorkOrderInvoiceAttachment(SystemParams.CompanyID, Convert.ToInt64(estid));
                    return OkResult;
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }

        }

        #endregion

        #region WO Service Working Time Setting


        private object GetWOServiceTimeSetting()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string setting = SystemParams.GetStringParam("WorkOrderServiceWorkingTime");

                    return new
                    {
                        Setting = setting
                    };
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object SetWOServiceTimeSetting()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null && session.User.UserType >= Foresight.Fleet.Services.User.UserTypes.Admin)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    SystemParams.SetStringParam("WorkOrderServiceWorkingTime", clientdata);

                    return 0;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        #endregion

        #region SMS Footnotes

        private object GetSMSFootnotes()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    return SystemParams.GetStringParam(SystemParams.WOSMSFootnotes);
                }
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object SetSMSFootnotes()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);

                    SystemParams.SetStringParam(SystemParams.WOSMSFootnotes, clientdata);

                    return "";
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        #endregion

        #region Estimate Settings

        private object GetEstimateSettings()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    List<string> r = new List<string>();
                    r.Add(SystemParams.GetStringParam(SystemParams.EstimateMessage));
                    r.Add(Helper.IsTrue(SystemParams.GetStringParam(SystemParams.DefaultPORequired)) ? "1" : "0");

                    return r.ToArray();
                }
                return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object SetEstimateSettings()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);
                    string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);

                    SystemParams.SetStringParam(SystemParams.EstimateMessage, ps[0]);
                    SystemParams.SetStringParam(SystemParams.DefaultPORequired, ps[1] == "1" ? "Yes" : "No");

                    return "";
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        #endregion

        #region Invoice Settings

        private object GetInvoiceSettings()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    return SystemParams.GetStringParam(SystemParams.InvoiceMessage);
                }
                return "";
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object SetInvoiceSettings()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    clientdata = HttpUtility.HtmlDecode(clientdata);

                    SystemParams.SetStringParam(SystemParams.InvoiceMessage, clientdata);

                    return "";
                }
                return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        #endregion

        private object GetWorkorderParams()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    return new
                    {
                        EstimateMessage = SystemParams.GetStringParam(SystemParams.EstimateMessage),
                        DefaultPORequired = Helper.IsTrue(SystemParams.GetStringParam(SystemParams.DefaultPORequired)),
                        InvoiceMessage = SystemParams.GetStringParam(SystemParams.InvoiceMessage),
                    };
                }
                return null;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        #region Follower
        private object GetWorkOrderFollowers()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string clientdata = Request.Form["ClientData"];
                    long woid = Convert.ToInt64(HttpUtility.HtmlDecode(clientdata));

                    var client = CreateClient<WorkOrderProvider>();
                    WorkOrderFollowerInfo[] items = client.GetWorkOrderFollowers(SystemParams.CompanyID, woid);
                    if (items == null || items.Length == 0)
                        return new WorkOrderFollowerInfo[0];

                    return items;
                }
                else
                    return new WorkOrderFollowerInfo[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderFollowers", ex.Message, ex.ToString());
                return ex.Message;
            }
        }
        private object GetCustomerFollowers()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string custid = Request.Form["ClientData"];
                    custid = HttpUtility.HtmlDecode(custid);

                    FollowerInfo[] followers = CreateClient<BusinessPartnerProvider>().GetFollowers(SystemParams.CompanyID, int.Parse(custid));
                    if (followers == null || followers.Length == 0)
                        return new FollowerInfo[0];
                    return followers;
                }
                else
                    return new FollowerInfo[0];

            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        private object GetAllFollowers()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var users = UserManagement.GetAllFollowers(session.SessionID);
                    return users;
                }
                else
                    return new UserInfo[0];

            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetAllFollowers", ex.Message, ex.ToString());
                return ex.Message;
            }
        }
        #endregion


        #region Survey Automaction

        private object GetAllWorkOrderTypes()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string[] items = CreateClient<WorkOrderProvider>().GetWorkOrderTypes(SystemParams.CompanyID);

                    if (items == null || items.Length == 0)
                        return new StringKeyValue[0];

                    List<StringKeyValue> ls = new List<StringKeyValue>();
                    foreach (string item in items)
                    {
                        StringKeyValue kv = new StringKeyValue();
                        kv.Key = item;
                        kv.Value = item;
                        ls.Add(kv);
                    }
                    return ls.ToArray();
                }
                else
                    return new StringKeyValue[0];
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object GetSurveyAutomationSetting()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    string setting = SystemParams.GetStringParam("SurveyAutomation");
                    SurveyAutomationItem item = JsonConvert.DeserializeObject<SurveyAutomationItem>(setting);

                    return item;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object SetSurveyAutomationSetting()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null && session.User.UserType >= Foresight.Fleet.Services.User.UserTypes.Admin)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);
                    SurveyAutomationInfo info = JsonConvert.DeserializeObject<SurveyAutomationInfo>(clientdata);

                    SystemParams.SetStringParam("SurveyAutomation", JsonConvert.SerializeObject(info));

                    return 0;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        #endregion

        #region Widgets

        private object GetWorkOrderWidgets()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var client = CreateClient<Foresight.Fleet.Services.User.UserProfileProvider>();
                    Foresight.Fleet.Services.User.UserWidgetInfo[] items = client.GetWidgets(SystemParams.CompanyID, session.User.UID, "WorkOrder");
                    if (items == null || items.Length == 0)
                        return new Foresight.Fleet.Services.User.UserWidgetInfo[0];

                    bool license = SystemParams.HasLicense("CustomerRecord");
                    bool crpermission = CheckRight(SystemParams.CompanyID, Foresight.Fleet.Services.User.Feature.CUSTOMER_RECORD);
                    bool AllowCustomer = license && crpermission;
                    bool AllowCommunicate = license && CheckRight(SystemParams.CompanyID, Foresight.Fleet.Services.User.Feature.COMMUNICATEWITHCUSTOMER);
                    if (!AllowCustomer)
                    {
                        items = items.Where(i => !i.WidgetId.Equals("Estimates", StringComparison.OrdinalIgnoreCase)
                        && !i.WidgetId.Equals("Invoices", StringComparison.OrdinalIgnoreCase)
                        && !i.WidgetId.Equals("CustomerRecordComments", StringComparison.OrdinalIgnoreCase)).ToArray();
                    }
                    if (!AllowCommunicate)
                    {
                        items = items.Where(i => !i.WidgetId.Equals("CustomerCommunication", StringComparison.OrdinalIgnoreCase)).ToArray();
                    }

                    license = SystemParams.HasLicense("Inspection");
                    bool AllowInspection = license && CheckRight(SystemParams.CompanyID, Foresight.Fleet.Services.User.Feature.INSPECTION_REPORTS);
                    if (!AllowInspection)
                    {
                        items = items.Where(i => !i.WidgetId.Equals("Inspections", StringComparison.OrdinalIgnoreCase)).ToArray();
                    }

                    return items;
                }
                else
                    return new Foresight.Fleet.Services.User.UserWidgetInfo[0];
            }
            catch (Exception ex)
            {
                AddLog("ERROR", "WorkOrderBasePage.GetWorkOrderWidgets", ex.Message, ex.ToString());
                return ex.Message;
            }
        }

        private object SaveWorkOrderWidgets()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    var widgets = JsonConvert.DeserializeObject<Foresight.Fleet.Services.User.UserWidgetInfo[]>(clientdata);
                    CreateClient<Foresight.Fleet.Services.User.UserProfileProvider>().SaveWidgets(SystemParams.CompanyID, widgets);
                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object SaveWorkOrderWidgetLayout()
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session != null)
                {
                    var clientdata = HttpUtility.HtmlDecode(Request.Form["ClientData"]);

                    var widget = JsonConvert.DeserializeObject<Foresight.Fleet.Services.User.UserWidgetInfo>(clientdata);
                    widget.UserIID = session.User.UID;
                    widget.Category = "WorkOrder";
                    CreateClient<Foresight.Fleet.Services.User.UserProfileProvider>().SaveWidgetLayout(SystemParams.CompanyID, widget);
                    return OkResult;
                }
                else
                    return FailedResult;
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }
        #endregion

        #region Communications

        private object WrapExceptionWithPermission(Func<object> action, string nullResult = FailedResult)
        {
            try
            {
                var session = GetCurrentLoginSession();
                if (session == null)
                {
                    return nullResult;
                }

                return action();
            }
            catch (Exception ex)
            {
                return ex.Message;
            }
        }

        private object ValidatePhones()
        {
            string clientdata = Request.Params["ClientData"];
            string[] ps = JsonConvert.DeserializeObject<string[]>(clientdata);

            var client = CreateClient<BusinessPartnerProvider>();
            return client.ValidateNumbers(ps);
        }

        private object UpdateMessageStatus()
        {
            string clientdata = Request.Params["ClientData"];
            var ps = JsonConvert.DeserializeObject<TextMessageParticipator[]>(clientdata);

            var client = CreateClient<WorkOrderProvider>();
            client.UpdateTextMessageStatus(SystemParams.CompanyID, ps);

            return OkResult;
        }

        private object GetMessageStatusHistory()
        {
            string clientdata = Request.Params["ClientData"];
            long id = Convert.ToInt64(clientdata);

            var client = CreateClient<WorkOrderProvider>();
            return client.GetTextMessageStatusHistory(SystemParams.CompanyID, id)
                .OrderByDescending(h => h.UpdatedOn)
                //.Take(1)
                .Select(h => new TextMessageParticipatorHistoryClient(h))
                .ToArray();
        }

        #endregion
    }

    #region - Structs -

    public class SurveyAutomationInfo
    {
        public int TemplateId { get; set; }
        public int DaysFromCompletedDate { get; set; }
        public int DaysSinceLastReceivedSurvey { get; set; }
        public int Resend { get; set; }
        public int ResendAfterDays { get; set; }
        public int Randomization { get; set; }
        public string[] ExcludeWorkOrderTypes { get; set; }
        public string SurveySendTimes { get; set; }
    }

    public class SegmentClient
    {
        public UserInfo[] Users { get; set; }
        public JobSiteViewItem[] JobSites { get; set; }
        public string[] Components { get; set; }
        public string[] SegmentTypes { get; set; }
    }

    class WorkorderAlerts
    {
        public AlertInfo[] Alerts { get; set; }
        public AlertInfo[] AssetAlerts { get; set; }
    }

    public class WorkOrderAttachmentItem : WorkOrderAttachmentInfo
    {
        public string AddedOnLocalStr { get { return AddedOnLocal == null ? "" : AddedOnLocal.ToString(); } }

        public bool AvailableToCustomer { get; set; }
        public string AttachmentIdStr { get; set; }//兼容Inspect的guid
        public int AttachmentType { get; set; }//Asset: 1;WO: 2;Inspert: 3
    }

    class WOAttachments
    {
        public WorkOrderAttachmentItem[] AssetAttachments { get; set; }
        public WorkOrderAttachmentItem[] WorkOrderAttachments { get; set; }
        public WorkOrderAttachmentItem[] InspectionAttachments { get; set; }
    }

    public class FilterDataSourceItem
    {
        public StringKeyValue[] AssetGroups { get; set; }
        public CustomerLocation[] Locations { get; set; }
        public DepartmentInfo[] Departments { get; set; }
        public StringKeyValue[] Advisors { get; set; }
        public StringKeyValue[] Statuses { get; set; }
        public StringKeyValue[] OrderTypes { get; set; }
    }


    public class WorkOrderDefaultItem
    {
        public int[] Locations { get; set; }
        public int[] Departments { get; set; }
        public string[] Advisors { get; set; }
        public string[] OrderTypes { get; set; }
    }

    public class WorkOrderEstimateItem : WorkOrderEstimateInfo
    {
        public WorkOrderAttachmentItem[] Attachments { get; set; }
        public string PublishTimeStr { get { return PublishTime == null ? "" : PublishTime.Value.ToString(); } }
        public string CustomerResponseTimeStr { get { return CustomerResponseTime == null ? "" : CustomerResponseTime.Value.ToString(); } }
        public string ResponsePhoneStr
        {
            get
            {
                string rst = "";
                if (Helper.IsEmail(ResponsePhone))
                    rst = ResponsePhone;
                else
                    rst = Foresight.Standard.PhoneNumber.FormatPhoneNumber(ResponsePhone);
                return rst;
            }
        }
    }

    public class WorkOrderSurveyInfo : WorkOrderSurveyItem
    {
        public string SubmitTimeStr { get { return SubmitTime == null ? "" : SubmitTime.Value.ToShortDateString(); } }
        public string SentTimeStr { get { return SentTime == null ? "" : SentTime.Value.ToShortDateString(); } }
        public string ContactNumberStr
        {
            get
            {
                string rst = "";
                if (Helper.IsEmail(ContactNumber))
                    rst = ContactNumber;
                else
                    rst = Foresight.Standard.PhoneNumber.FormatPhoneNumber(ContactNumber);
                return rst;
            }
        }
    }

    public class WorkOrderSurveyResultItem
    {
        public WorkOrderSurveyResult SurveyData { get; set; }
        public string SubmitTimeStr { get { return (SurveyData.Question != null && SurveyData.Question.SubmitTime != null) ? SurveyData.Question.SubmitTime.Value.ToString() : ""; } }
    }
    public class SurveyTemplateClient : SurveyTemplateItem
    {
        public bool InUse { get; set; }
    }
    public class WorkOrderInvoiceInfoItem : WorkOrderInvoiceInfo
    {
        public WorkOrderAttachmentItem[] Attachments { get; set; }
        public PaymentItem PaymentItem { get; set; }
        public string LastUpdatedOnStr { get { return LastUpdatedOn == null ? "" : LastUpdatedOn.Value.ToString(); } }
    }

    public class PaymentItem : PaymentInfo
    {
        public string CreatedLocalStr { get { return CreatedLocal == null ? "" : CreatedLocal.Value.ToString(); } }
        public string CardNumber => Card == null ? string.Empty : "**** " + Card.Last4Number;
        public string CardExpiration => Card == null ? string.Empty : Card.ExpMonth.ToString("00") + " / " + Card.ExpYear.ToString("0000");
        public string CardType => Card == null ? string.Empty : Card.Brand + " " + Card.Funding;
        public string CardIssuer => Card?.Issuer ?? string.Empty;

        //Macnul Paid
        public string CheckNumber { get; set; }
        public string PaymentEnteredByName { get; set; }
    }

    class WorkOrderHistoryItem : WorkOrderHistoryInfo
    {
        public string DateTimeStr { get { return DateTime == null ? "" : DateTime.Value.ToString(); } }
    }

    class SurveyAutomationItem
    {
        public int TemplateId { get; set; }
        public int DaysFromCompletedDate { get; set; }
        public int DaysSinceLastReceivedSurvey { get; set; }
        public int Resend { get; set; }
        public int ResendAfterDays { get; set; }
        public int Randomization { get; set; }
        public string[] ExcludeWorkOrderTypes { get; set; }
        public string SurveySendTimes { get; set; }
    }

    class AttaDataInfo
    {
        public string Id { get; set; }
        public string AttaType { get; set; }
        public string FileName { get; set; }
        public string Caption { get; set; }

    }

    class TextMessageParticipatorHistoryClient
    {
        public TextMessageParticipatorHistory History { get; }

        public string UpdatedOnStr => History?.UpdatedOn.ToString("M/d/yyyy h:mm tt") ?? string.Empty;

        public string CustomerNumberFormatted => Foresight.Standard.PhoneNumber.FormatPhoneNumber(History?.CustomerNumber);

        public TextMessageParticipatorHistoryClient(TextMessageParticipatorHistory history)
        {
            History = history;
        }
    }

    #endregion
}
