This commit is contained in:
2024-03-26 15:56:31 +08:00
parent 634e8b71ab
commit 0855ae42cd
547 changed files with 94818 additions and 60463 deletions

View File

@ -1,6 +1,8 @@
using Foresight.Fleet.Services.AssetHealth;
using Foresight.Standard;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@ -9,8 +11,11 @@ namespace IronIntel.Contractor.Maintenance
{
public class AlertInfo
{
private const char SPLITCHAR = (char)175;
private const char SPLITCHAR1 = (char)181;
public long AlertID { get; set; }
public long WorkOrderID { get; set; }
public string WorkOrderNumber { get; set; }
public string WorkOrderStatus { get; set; }
public string AlertType { get; set; }
public DateTime AlertTime_UTC { get; set; }
@ -82,10 +87,64 @@ namespace IronIntel.Contractor.Maintenance
public string AcknowledgedTime_LocalStr { get { return AcknowledgedTime_Local == DateTime.MinValue ? "" : AcknowledgedTime_Local.ToString(); } }
public string AcknowledgedComment { get; set; }
public string Comment { get; set; }
public override string ToString()
{
StringBuilder sb = new StringBuilder();
TextableDTO.Append(sb, AlertID);
TextableDTO.Append(sb, SPLITCHAR, WorkOrderID);
TextableDTO.Append(sb, SPLITCHAR, WorkOrderStatus);
TextableDTO.Append(sb, SPLITCHAR, AlertType);
TextableDTO.Append(sb, SPLITCHAR, AlertTime_UTC);
TextableDTO.Append(sb, SPLITCHAR, AlertTime_UTCStr);
TextableDTO.Append(sb, SPLITCHAR, AlertLocalTime);
TextableDTO.Append(sb, SPLITCHAR, AlertLocalTimeStr);
TextableDTO.Append(sb, SPLITCHAR, Completed ? "1" : "0");
TextableDTO.Append(sb, SPLITCHAR, MachineID);
TextableDTO.Append(sb, SPLITCHAR, ModelID);
TextableDTO.Append(sb, SPLITCHAR, Model);
TextableDTO.Append(sb, SPLITCHAR, MakeID);
TextableDTO.Append(sb, SPLITCHAR, Make);
TextableDTO.Append(sb, SPLITCHAR, VIN);
TextableDTO.Append(sb, SPLITCHAR, MachineName);
TextableDTO.Append(sb, SPLITCHAR, EngineHours);
TextableDTO.Append(sb, SPLITCHAR, CurrentHours);
TextableDTO.Append(sb, SPLITCHAR, Description);
TextableDTO.Append(sb, SPLITCHAR, ServiceDescription);
TextableDTO.Append(sb, SPLITCHAR, ScheduleID);
TextableDTO.Append(sb, SPLITCHAR, IntervalID);
TextableDTO.Append(sb, SPLITCHAR, Recurring ? "1" : "0");
TextableDTO.Append(sb, SPLITCHAR, Priority);
TextableDTO.Append(sb, SPLITCHAR, ExpectedCost);
TextableDTO.Append(sb, SPLITCHAR, AlertCount);
if (RepeatedAlerts != null && RepeatedAlerts.Count > 0)
{
string repeatedalertsstr = string.Join(SPLITCHAR1.ToString(), RepeatedAlerts);
TextableDTO.Append(sb, SPLITCHAR, repeatedalertsstr);
}
else
TextableDTO.Append(sb, SPLITCHAR, "");
TextableDTO.Append(sb, SPLITCHAR, OpenWorkOrderCount);
TextableDTO.Append(sb, SPLITCHAR, PMType);
TextableDTO.Append(sb, SPLITCHAR, AcknowledgedBy);
TextableDTO.Append(sb, SPLITCHAR, AcknowledgedByName);
TextableDTO.Append(sb, SPLITCHAR, AcknowledgedTime_UTC);
TextableDTO.Append(sb, SPLITCHAR, AcknowledgedTime_UTCStr);
TextableDTO.Append(sb, SPLITCHAR, AcknowledgedTime_Local);
TextableDTO.Append(sb, SPLITCHAR, AcknowledgedTime_LocalStr);
TextableDTO.Append(sb, SPLITCHAR, AcknowledgedComment);
TextableDTO.Append(sb, SPLITCHAR, WorkOrderNumber);
TextableDTO.Append(sb, SPLITCHAR, Comment);
return sb.ToString();
}
}
public class MachineInfoForAlert
{
private const char SPLITCHAR = (char)182;
private const char SPLITCHAR1 = (char)180;
public long MachineID { get; set; }
public string VIN { get; set; }
public string MachineName { get; set; }
@ -113,6 +172,39 @@ namespace IronIntel.Contractor.Maintenance
public string LatestAlertDateTimeStr { get { return LatestAlertDateTime == DateTime.MinValue ? "" : LatestAlertDateTime.ToString(); } }
public List<AlertInfo> Alerts { get; } = new List<AlertInfo>();
public override string ToString()
{
StringBuilder sb = new StringBuilder();
TextableDTO.Append(sb, MachineID);
TextableDTO.Append(sb, SPLITCHAR, VIN);
TextableDTO.Append(sb, SPLITCHAR, MachineName);
TextableDTO.Append(sb, SPLITCHAR, Make);
TextableDTO.Append(sb, SPLITCHAR, Model);
TextableDTO.Append(sb, SPLITCHAR, EngineHours);
TextableDTO.Append(sb, SPLITCHAR, DTCAlertCount);
TextableDTO.Append(sb, SPLITCHAR, PMAlertCount);
TextableDTO.Append(sb, SPLITCHAR, InspectAlertCount);
TextableDTO.Append(sb, SPLITCHAR, OpenWorkOrders);
TextableDTO.Append(sb, SPLITCHAR, LatestAlertDateTime);
TextableDTO.Append(sb, SPLITCHAR, LatestAlertDateTimeStr);
if (Alerts != null && Alerts.Count > 0)
{
StringBuilder sb1 = new StringBuilder();
foreach (AlertInfo ai in Alerts)
{
if (sb1.Length > 0)
sb1.Append(SPLITCHAR1 + ai.ToString());
else
sb1.Append(ai.ToString());
}
TextableDTO.Append(sb, SPLITCHAR, sb1.ToString());
}
else
TextableDTO.Append(sb, SPLITCHAR, "");
return sb.ToString();
}
}
public class AssetAlertInfo

View File

@ -17,26 +17,10 @@ namespace IronIntel.Contractor.Maintenance
{
}
public StringKeyValue[] GetAlertTypes()
{
const string SQL = "select distinct ltrim(rtrim(ALERTTYPE)) as ALERTTYPE from ALERTS with(nolock) where ISNULL(ALERTTYPE,'')<>''";
DataTable tb = GetDataTableBySQL(SQL);
if (tb.Rows.Count == 0)
{
return new StringKeyValue[0];
}
List<StringKeyValue> list = new List<StringKeyValue>();
foreach (DataRow dr in tb.Rows)
{
string type = FIDbAccess.GetFieldString(dr["ALERTTYPE"], string.Empty);
StringKeyValue kv = new StringKeyValue();
kv.Key = type;
kv.Value = type;
list.Add(kv);
}
return list.OrderBy(t => t.Key).ToArray();
}
/// <summary>
/// 根据WorkorderId获取Alert列表
/// </summary>
/// <returns></returns>
public AlertInfo[] GetAlertsByWorkOrder(long workorderid, Foresight.Fleet.Services.User.UserInfo user)
{
const string SQL = @"select a.ALERTID,ALERTTYPE,a.ALERTTIME_UTC,COMPLETED,a.MACHINEID,a.VIN,a.MACHINENAME,a.ENGINGHOURS,a.ALERTDESC,pit.SERVICEDESCRIPTION,a.PMTYPE from ALERTS a
@ -60,7 +44,7 @@ namespace IronIntel.Contractor.Maintenance
public void AcknowledgeAlert(string useriid, long[] alertids, string acknowledgmentcomment)
{
const string SQL = "update ALERTS set ACKNOWLEDGED=1,ACKNOWLEDGEDBY={1},ACKNOWLEDGMENTCOMMENT={2},ACKNOWLEDGEDDATE_UTC=GETUTCDATE() where ALERTID={0}";
const string SQL_S = "select ALERTID from ALERTS where ISNULL(ACKNOWLEDGED,0)<>1 and ISNULL(COMPLETED,0)<>1 and MACHINEID=(select MACHINEID from ALERTS where ALERTID={0}) and ALERTDESC=(select ALERTDESC from ALERTS where ALERTID={0}) ";
const string SQL_S = "select ALERTID from ALERTS a where ISNULL(ACKNOWLEDGED,0)<>1 and ISNULL(COMPLETED,0)<>1 and MACHINEID=(select MACHINEID from ALERTS where ALERTID={0}) and ALERTDESC=(select ALERTDESC from ALERTS where ALERTID={0}) and not exists(select 1 from WORKORDER_ALERTS woa where woa.ALERTID=a.ALERTID) ";
if (alertids != null && alertids.Length > 0)
{

View File

@ -18,6 +18,7 @@ namespace IronIntel.Contractor.Maintenance
public string BeginDate { get; set; }
public string EndDate { get; set; }
public bool IncludeunCompleted { get; set; }
public string[] Category { get; set; }
}
public class AutoAcknowledgeInfo : AutoAcknowledgeItem

View File

@ -9,6 +9,9 @@ using IronIntel.Contractor.Machines;
namespace IronIntel.Contractor.Maintenance
{
/// <summary>
/// 已移到CurfewWinService服务中执行
/// </summary>
public class IATCAlertsSyncService
{
private static bool isrunning = false;

View File

@ -36,6 +36,7 @@ namespace IronIntel.Contractor.Maintenance
public PmIntervalItem[] Intervals { get; set; }
public int[] AllIntervals { get; set; }
public bool Enabled { get; set; }
}
public class PmIntervalItem

View File

@ -1,4 +1,5 @@
using Foresight.Data;
using DocumentFormat.OpenXml.Office2010.CustomUI;
using Foresight.Data;
using Foresight.Fleet.Services.Asset;
using Foresight.Fleet.Services.AssetHealth;
using Foresight.Fleet.Services.User;
@ -18,6 +19,10 @@ namespace IronIntel.Contractor.Maintenance
#region PM SCHEDULES
/// <summary>
/// 根据PM类型、PMId获取PM计划列表
/// </summary>
/// <returns></returns>
public static PmScheduleInfo[] GetPmSchedule(string sessionid, string pmtype, string pmid, string filter)
{
var items = FleetServiceClientHelper.CreateClient<PMClient>(sessionid).GetPMScheduleItems(SystemParams.CompanyID, pmtype, filter, true);
@ -34,6 +39,7 @@ namespace IronIntel.Contractor.Maintenance
pm.PmScheduleUom = item.UOM;
pm.PmScheduleType = item.ScheduleType;
pm.Notes = item.Notes;
pm.Enabled = item.Enabled;
if (item.Intervals != null || item.Intervals.Count > 0)
{
List<PmIntervalItem> lsinterval = new List<PmIntervalItem>();
@ -56,6 +62,10 @@ namespace IronIntel.Contractor.Maintenance
return list.ToArray();
}
/// <summary>
/// 根据PM计划ID获取计划信息
/// </summary>
/// <returns></returns>
public static PmScheduleInfo GetPMScheduleByID(string sessionid, string scheduleid)
{
var item = FleetServiceClientHelper.CreateClient<PMClient>(sessionid).GetPMScheduleItem(SystemParams.CompanyID, scheduleid, true);
@ -65,6 +75,7 @@ namespace IronIntel.Contractor.Maintenance
pm.PmScheduleUom = item.UOM;
pm.PmScheduleType = item.ScheduleType;
pm.Notes = item.Notes;
pm.Enabled = item.Enabled;
if (item.Intervals != null || item.Intervals.Count > 0)
{
List<PmIntervalItem> lsinterval = new List<PmIntervalItem>();
@ -159,6 +170,10 @@ namespace IronIntel.Contractor.Maintenance
return list.ToArray();
}
/// <summary>
/// 根据机器id获取PM计划列表
/// </summary>
/// <returns></returns>
public static PMAssetAlertInfo[] GetPmScheduleByAsset(string sessionid, long assetid, bool includeinterval)
{
List<PMAssetAlertInfo> result = new List<PMAssetAlertInfo>();
@ -225,6 +240,7 @@ namespace IronIntel.Contractor.Maintenance
pm.UOM = si.PmScheduleUom;
pm.ScheduleType = si.PmScheduleType;
pm.Notes = si.Notes;
pm.Enabled = si.Enabled;
if (si.Intervals != null && si.Intervals.Length > 0)
{
List<PMIntervalItem> list = new List<PMIntervalItem>();
@ -485,8 +501,8 @@ namespace IronIntel.Contractor.Maintenance
public static WorkOrderListItemClient[] GetMaintenanceWorkOrders(string sessionid, string custid, string[] assignedusers, string[] asseitgroups, string filter, string useriid)
{
const string SQL = @"select m.MAINTENANCEID,m.COMPLETEDBY,(select USERNAME from USERS with(nolock) where USERS.USERIID=m.COMPLETEDBY) as ASSIGNEDTONAME,m.NOTES,m.MAINTENANCEDATE
,b.MACHINEID,b.VIN,b.MACHINENAME,b.MACHINENAME2 from MAINTENANCELOG m with(nolock) left join MACHINES b with(nolock) on b.MACHINEID=m.MACHINEID
where m.ALERTID not in (select ALERTID from WORKORDER_ALERTS with(nolock)) and m.MACHINEID = b.MACHINEID and ISNULL(b.HIDE,0)<>1 ";
,b.MACHINEID,b.VIN,b.MACHINENAME,b.MACHINENAME2,b.MAKENAME,b.MODELNAME,b.JOBSITES,m.COMPLETED from MAINTENANCELOG m with(nolock) left join V_WORKORDER_MACHINES b with(nolock) on b.MACHINEID=m.MACHINEID left join WORKORDER_ALERTS woa on woa.ALERTID=m.ALERTID
where woa.ALERTID is null and m.MACHINEID = b.MACHINEID";
const string SQL_FILTER = " and (m.NOTES like {0} or b.MACHINEID like {0} or b.VIN like {0} or b.MACHINENAME like {0} or b.MACHINENAME2 like {0}) ";
const string SQL_ORDERBY = " order by m.MAINTENANCEID";
@ -547,11 +563,26 @@ namespace IronIntel.Contractor.Maintenance
wo.MaintenanceID = FIDbAccess.GetFieldString(dr["MAINTENANCEID"], string.Empty);
wo.Description = FIDbAccess.GetFieldString(dr["NOTES"], string.Empty);
wo.CompleteDate = FIDbAccess.GetFieldDateTime(dr["MAINTENANCEDATE"], DateTime.MinValue);
wo.AssetName = FIDbAccess.GetFieldString(dr["MACHINENAME"], string.Empty);
wo.Make = FIDbAccess.GetFieldString(dr["MAKENAME"], string.Empty);
wo.Model = FIDbAccess.GetFieldString(dr["MODELNAME"], string.Empty);
wo.CurrentJobsites = FIDbAccess.GetFieldString(dr["JOBSITES"], string.Empty);
wo.VIN = FIDbAccess.GetFieldString(dr["VIN"], string.Empty);
wo.AssetName = FIDbAccess.GetFieldString(dr["MACHINENAME2"], string.Empty);
if (string.IsNullOrWhiteSpace(wo.AssetName))
{
wo.AssetName = FIDbAccess.GetFieldString(dr["MACHINENAME"], string.Empty);
if (string.IsNullOrWhiteSpace(wo.AssetName))
{
wo.AssetName = wo.VIN;
}
}
//var assignedTo = FIDbAccess.GetFieldString(dr["COMPLETEDBY"], string.Empty);
//wo.AssignedToName = FIDbAccess.GetFieldString(dr["ASSIGNEDTONAME"], assignedTo);
wo.WorkOrderNumber = "";
wo.Status = FIDbAccess.GetFieldInt(dr["COMPLETED"], 0) == 1 ? 100 : -1;
if (!wo.Completed)
wo.CompleteDate = null;
list.Add(wo);
}

View File

@ -1,6 +1,7 @@
using Foresight.Fleet.Services.AssetHealth.WorkOrder;
using Foresight.Fleet.Services.Customer;
using Foresight.ServiceModel;
using IronIntel.Contractor.Machines;
using IronIntel.Contractor.Users;
using System;
using System.Collections.Generic;
@ -34,6 +35,9 @@ namespace IronIntel.Contractor.Maintenance
public class WorkOrderListItemClient : WorkOrderListItem
{
const char SPLITCHAR = (char)170;
const char SPLIT_CHAR182 = (char)182;
const char SPLIT_CHAR183 = (char)183;
public string DueDateStr { get { return DueDate == null ? "" : DueDate.Value.ToShortDateString(); } }
public string CompleteDateStr { get { return CompleteDate == null ? "" : CompleteDate.Value.ToShortDateString(); } }
public string NextFollowUpDateStr { get { return NextFollowUpDate == null ? "" : NextFollowUpDate.Value.ToShortDateString(); } }
@ -88,6 +92,98 @@ namespace IronIntel.Contractor.Maintenance
return rst;
}
}
public override string ToString()
{
StringBuilder sb = new StringBuilder();
sb.Append(base.ToString());
sb.Append(SPLITCHAR + DueDateStr);
sb.Append(SPLITCHAR + CompleteDateStr);
sb.Append(SPLITCHAR + NextFollowUpDateStr);
sb.Append(SPLITCHAR + CreateDateStr);
sb.Append(SPLITCHAR + CreationDateStr);
sb.Append(SPLITCHAR + LastCommunicationDateStr);
sb.Append(SPLITCHAR + LastInternalCommunicationDateStr);
sb.Append(SPLITCHAR + PartsExpectedDateStr);
sb.Append(SPLITCHAR + LastLaborDateStr);
sb.Append(SPLITCHAR + MaintenanceID);
sb.Append(SPLITCHAR + ((WorkOrderStatus != null && WorkOrderStatus.Length > 0) ? WorkOrderStatus[0].ToString() : ""));
if (AssignedToUsers != null && AssignedToUsers.Length > 0)
{
StringBuilder sb1 = new StringBuilder();
foreach (UserInfo user in AssignedToUsers)
{
string str = user.IID + SPLIT_CHAR183 + user.DisplayName;
if (sb1.Length == 0)
sb1.Append(str);
else
sb1.Append(SPLIT_CHAR182 + str);
}
sb.Append(SPLITCHAR + sb1.ToString());
}
else
{
sb.Append(SPLITCHAR + "");
}
if (Departments != null && Departments.Length > 0)
{
StringBuilder sb1 = new StringBuilder();
foreach (DepartmentInfo dept in Departments)
{
string str = dept.Id.ToString() + SPLIT_CHAR183 + dept.Name;
if (sb1.Length == 0)
sb1.Append(str);
else
sb1.Append(SPLIT_CHAR182 + str);
}
sb.Append(SPLITCHAR + sb1.ToString());
}
else
{
sb.Append(SPLITCHAR + "");
}
if (Locations != null && Locations.Length > 0)
{
StringBuilder sb1 = new StringBuilder();
foreach (CustomerLocation loc in Locations)
{
string str = loc.ID.ToString() + SPLIT_CHAR183 + loc.Name;
if (sb1.Length == 0)
sb1.Append(str);
else
sb1.Append(SPLIT_CHAR182 + str);
}
sb.Append(SPLITCHAR + sb1.ToString());
}
else
{
sb.Append(SPLITCHAR + "");
}
if (Salespersons != null && Salespersons.Length > 0)
{
StringBuilder sb1 = new StringBuilder();
foreach (StringKeyValue sale in Salespersons)
{
string str = sale.Key + SPLIT_CHAR183 + sale.Value;
if (sb1.Length == 0)
sb1.Append(str);
else
sb1.Append(SPLIT_CHAR182 + str);
}
sb.Append(SPLITCHAR + sb1.ToString());
}
else
{
sb.Append(SPLITCHAR + "");
}
sb.Append(SPLITCHAR + ContactsStr);
sb.Append(SPLITCHAR + (Completed ? "1" : "0"));
return sb.ToString();
}
}
public class TextMessageClient : TextMessage

View File

@ -248,7 +248,7 @@ namespace IronIntel.Contractor.Maintenance
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_HOURLYRATE", "Hourly Rate") + "</td><td>{0}</td></tr>", wo.HourlyRate);
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_TIMETOCOMPLATEHOURS", "Time To Complete(Hrs)") + "</td><td>{0}</td></tr>", wo.HoursToComplete);
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_TIMETOCOMPLATEHOURS", "Labor Hours") + "</td><td>{0}</td></tr>", wo.HoursToComplete);
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPLETEDDATE", "Completed Date") + "</td><td>{0}</td></tr>", wo.CompleteDate == null ? "" : wo.CompleteDate.Value.ToShortDateString());
str.AppendLine("");
@ -256,7 +256,7 @@ namespace IronIntel.Contractor.Maintenance
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_INVOICENUMBER", "Invoice Number") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(wo.InvoiceNumber));
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + "Billable" + "</td><td>{0}</td></tr>", wo.Billable ? "Yes" : "No");
str.AppendFormat("<tr><td class='label'>" + "Billable" + "</td><td>{0}</td></tr>", wo.Billable ? SystemParams.GetTextByKey(lang, "P_UTILITY_YES", "Yes") : SystemParams.GetTextByKey(lang, "P_UTILITY_NO", "No"));
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + "Bill To Job" + "</td><td>{0}</td></tr>", wo.BillToJobName);
str.AppendLine("");
@ -287,11 +287,11 @@ namespace IronIntel.Contractor.Maintenance
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPONENT", "Component") + "</td><td>{0}</td></tr>", se.Component);
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPLETED", "Completed") + "</td><td>{0}</td></tr>", se.Completed ? "Yes" : "No");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPLETED", "Completed") + "</td><td>{0}</td></tr>", se.Completed ? SystemParams.GetTextByKey(lang, "P_UTILITY_YES", "Yes") : SystemParams.GetTextByKey(lang, "P_UTILITY_NO", "No"));
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPLETEDDATE", "Completed Date") + "</td><td>{0}</td></tr>", se.CompletedDate == null ? "" : se.CompletedDate.Value.ToShortDateString());
str.AppendFormat("<tr><td class='label'>" + "Segment Type" + "</td><td>{0}</td></tr>", se.SegmentType);
str.AppendFormat("<tr><td class='label'>" + "Billable" + "</td><td>{0}</td></tr>", se.Billable ? "Yes" : "No");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_SEGMENTTYPE", "Segment Type") + "</td><td>{0}</td></tr>", se.SegmentType);
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_BILLABLE", "Billable") + "</td><td>{0}</td></tr>", se.Billable ? SystemParams.GetTextByKey(lang, "P_UTILITY_YES", "Yes") : SystemParams.GetTextByKey(lang, "P_UTILITY_NO", "No"));
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_DESCRIPTION", "Description") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(se.Description));
str.AppendLine("");
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_NOTES", "Notes") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(se.Notes).Replace("\n", "<br>"));
@ -646,6 +646,7 @@ namespace IronIntel.Contractor.Maintenance
ai.Recurring = alertitem.Recurring;
ai.Priority = alertitem.Priority;
ai.ExpectedCost = alertitem.ExpectedCost;
ai.Comment = alertitem.Comment;
return ai;
}