840 lines
48 KiB
C#
840 lines
48 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Data;
|
|
using Foresight.Data;
|
|
using System.Web;
|
|
using Foresight.Fleet.Services.AssetHealth;
|
|
using Foresight.Fleet.Services.Asset;
|
|
using Foresight.Fleet.Services.AssetHealth.WorkOrder;
|
|
using Foresight.Fleet.Services.Inspection;
|
|
using Foresight.Chart.Drawer;
|
|
using System.Drawing;
|
|
using System.IO;
|
|
using Foresight.Chart.Drawer.Contracts;
|
|
using System.Net.Mail;
|
|
|
|
namespace IronIntel.Contractor.Maintenance
|
|
{
|
|
public class WorkOrderManager : BusinessBase
|
|
{
|
|
public WorkOrderManager(string dbstr) : base(dbstr)
|
|
{
|
|
}
|
|
|
|
public long[] GetOpenWorkOrderID(string machineid)
|
|
{
|
|
const string SQL = "select WORKORDERID from WORKORDER where MACHINEID={0} and STATUS<>'Completed' and and isnull(DELETED,0)=0";
|
|
DataTable tb = GetDataTableBySQL(SQL, machineid);
|
|
|
|
List<long> result = new List<long>();
|
|
foreach (DataRow dr in tb.Rows)
|
|
{
|
|
result.Add(FIDbAccess.GetFieldInt(dr[0], 0));
|
|
}
|
|
|
|
return result.ToArray();
|
|
}
|
|
|
|
public bool CanAccessWorkOrder(string sessionid, string woid, string mid, string useriid)
|
|
{
|
|
const string SQL = "select count(1) from WORKORDER where WORKORDERID={0} and ASSIGNEDTO={1}";
|
|
|
|
bool result = true;
|
|
var user = FleetServiceClientHelper.CreateClient<Foresight.Fleet.Services.User.UserQueryClient>(sessionid).GetUserByIID(useriid);
|
|
if ((!user.IsForesightUser) && (user.ContactType == Foresight.Fleet.Services.User.ContactTypes.Technician))
|
|
{
|
|
result = FIDbAccess.GetFieldInt(GetRC1BySQL(SQL, woid, useriid), 0) > 0;
|
|
}
|
|
if (result && user.UserType < Foresight.Fleet.Services.User.UserTypes.Admin)
|
|
{
|
|
long assetid = -1;
|
|
if (!string.IsNullOrEmpty(mid))
|
|
Int64.TryParse(mid, out assetid);
|
|
else
|
|
{
|
|
var client = FleetServiceClientHelper.CreateClient<WorkOrderProvider>(sessionid);
|
|
var workorder = client.GetWorkOrderInfo(SystemParams.CompanyID, Convert.ToInt64(woid));
|
|
assetid = workorder.AssetID;
|
|
}
|
|
long[] availableAssetsids = FleetServiceClientHelper.CreateClient<AssetQueryClient>(sessionid).GetAvailableAssetsForUsers(SystemParams.CompanyID, useriid);
|
|
if (availableAssetsids != null && !availableAssetsids.Contains(assetid))
|
|
result = false;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
public string[] GetInvoiceNumber(string woid)
|
|
{
|
|
const string SQL = @"select a.INVOICENUMBER from WORKORDER_ALERTS t left join MAINTENANCELOG a on a.ALERTID=t.ALERTID,MACHINES b
|
|
where t.WORKORDERID={0} and a.MACHINEID = b.MACHINEID and ISNULL(b.HIDE,0)<>1 and ISNULL(a.INVOICENUMBER,'')<>'' ORDER BY a.ADDEDON DESC";
|
|
|
|
DataTable dt = GetDataTableBySQL(SQL, woid);
|
|
if (dt.Rows.Count == 0)
|
|
return new string[0];
|
|
|
|
List<string> list = new List<string>();
|
|
foreach (DataRow dr in dt.Rows)
|
|
{
|
|
string num = FIDbAccess.GetFieldString(dr["INVOICENUMBER"], string.Empty);
|
|
if (!string.IsNullOrEmpty(num))
|
|
list.Add(num);
|
|
}
|
|
return list.ToArray();
|
|
}
|
|
|
|
public string[] GetLocations()
|
|
{
|
|
const string SQL = @"select distinct LOCATION from WORKORDER where ISNULL(LOCATION,'')<>''";
|
|
|
|
DataTable dt = GetDataTableBySQL(SQL);
|
|
if (dt.Rows.Count == 0)
|
|
return new string[0];
|
|
|
|
List<string> list = new List<string>();
|
|
foreach (DataRow dr in dt.Rows)
|
|
{
|
|
string num = FIDbAccess.GetFieldString(dr["LOCATION"], string.Empty);
|
|
if (!string.IsNullOrEmpty(num))
|
|
list.Add(num);
|
|
}
|
|
return list.ToArray();
|
|
}
|
|
|
|
public string[] GetDepartments()
|
|
{
|
|
const string SQL = @"select distinct DEPARTMENT from WORKORDER where ISNULL(DEPARTMENT,'')<>''";
|
|
|
|
DataTable dt = GetDataTableBySQL(SQL);
|
|
if (dt.Rows.Count == 0)
|
|
return new string[0];
|
|
|
|
List<string> list = new List<string>();
|
|
foreach (DataRow dr in dt.Rows)
|
|
{
|
|
string num = FIDbAccess.GetFieldString(dr["DEPARTMENT"], string.Empty);
|
|
if (!string.IsNullOrEmpty(num))
|
|
list.Add(num);
|
|
}
|
|
return list.ToArray();
|
|
}
|
|
|
|
|
|
public string[] GetAdvisors()
|
|
{
|
|
const string SQL = @"select distinct ADVISOR from WORKORDER where ISNULL(ADVISOR,'')<>''";
|
|
|
|
DataTable dt = GetDataTableBySQL(SQL);
|
|
if (dt.Rows.Count == 0)
|
|
return new string[0];
|
|
|
|
List<string> list = new List<string>();
|
|
foreach (DataRow dr in dt.Rows)
|
|
{
|
|
string num = FIDbAccess.GetFieldString(dr["ADVISOR"], string.Empty);
|
|
if (!string.IsNullOrEmpty(num))
|
|
list.Add(num);
|
|
}
|
|
return list.ToArray();
|
|
}
|
|
public static string GenerateWorkOrderPrintHtml(string sessionid, string companyid, long woid, string lang)
|
|
{
|
|
var client = FleetServiceClientHelper.CreateClient<WorkOrderProvider>(companyid, sessionid);
|
|
WorkOrderInfo wo = client.GetWorkOrderInfo(companyid, woid);
|
|
|
|
StringBuilder str = new StringBuilder();
|
|
str.AppendLine("<H1 style='text-align:center;'>" + SystemParams.GetTextByKey(lang, "P_WORKORDER", "Work Order") + "</H1>");
|
|
string detailstr = SystemParams.GetTextByKey(lang, "P_WO_DETAILFORWORKORDERARELISTEDBELOW", "Details for work order <{0}> are listed below:").Replace("<", "<").Replace(">", ">");
|
|
str.AppendFormat("<div style='font-weight:bold;padding-bottom:5px;'>" + detailstr + "</div>", wo.WorkOrderNumber);
|
|
str.AppendLine("");
|
|
//str.AppendLine("<div class='label' style='text-align:left;'>Work Order Information:</div>");
|
|
str.AppendLine("<div style='padding-left:30px;margin-bottom:36px;'>");
|
|
|
|
var aclient = FleetServiceClientHelper.CreateClient<AssetQueryClient>(companyid, sessionid);
|
|
var asset = aclient.GetAssetDetailInfo(companyid, wo.AssetID);
|
|
str.Append(GenerateWorkOrderInfoHtml(asset, wo, lang));
|
|
str.AppendLine("</div>");
|
|
//str.AppendLine("<div class='label' style='text-align:left;'>Segments:</div>");
|
|
|
|
WorkOrderSegmentInfo[] segments = client.GetSegments(companyid, woid);
|
|
|
|
if (segments != null && segments.Length > 0)
|
|
{
|
|
for (int i = 0; i < segments.Length; i++)
|
|
{
|
|
var se = segments[i];
|
|
str.Append(GenerateSegmentHtml(se, i + 1, lang));
|
|
}
|
|
}
|
|
|
|
str.Append("<div style='margin-bottom:36px;margin-left:30px;'>");
|
|
str.Append(WorkorderAlertsFormart(woid, lang, sessionid));
|
|
|
|
AssetInspectItem[] insplectitems = client.GetWOInspectItems(SystemParams.CompanyID, woid);
|
|
if (insplectitems != null && insplectitems.Length > 0)
|
|
{
|
|
foreach (AssetInspectItem isp in insplectitems)
|
|
{
|
|
var report = FleetServiceClientHelper.CreateClient<AssetInspectClient>(sessionid).GetInspection(SystemParams.CompanyID, isp.Id);
|
|
str.Append(GenerateInspectionHtml(report, lang));
|
|
}
|
|
}
|
|
|
|
|
|
str.Append("</div>");
|
|
|
|
return str.ToString();
|
|
}
|
|
|
|
private static string GenerateWorkOrderInfoHtml(AssetDetailInfo asset, WorkOrderInfo wo, string lang)
|
|
{
|
|
StringBuilder str = new StringBuilder();
|
|
str.Append("<table>");
|
|
str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_ASSETNAME", "Asset Name") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.Name));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_ASSETNAMECUSTOM", "Asset Name (Custom)") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.Name2));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_VIN", "VIN/SN") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.VIN));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_MAKE", "Make") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.MakeName));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_MODEL", "Model") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.ModelName));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_ASSETTYPE", "Asset Type") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.TypeName));
|
|
str.AppendLine("");
|
|
if (asset.OnRoad)
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_CURRENTODOMETER", "Current Odometer") + "</td><td>{0}</td></tr>", asset.CurrentOdometer == null ? "" : asset.CurrentOdometer.Corrected.ToString("#,##0"));
|
|
else
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_CURRENTHOURS", "Current Hours") + "</td><td>{0}</td></tr>", asset.CurrentHours == null ? "" : asset.CurrentHours.Corrected.ToString("#,##0"));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_CURRJOBSITE", "Current Jobsite") + " </td><td>{0}</td></tr>", HttpUtility.HtmlEncode(asset.CurrentJobSiteNames));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_CURRLOCATION", "Current Location") + " </td><td>{0}</td></tr>", asset.CurrentLocation == null ? "" : HttpUtility.HtmlEncode(asset.CurrentLocation.Address));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_WORKORDERTYPE", "Work Order Type") + "</td><td>{0}</td></tr>", wo.WorkOrderType);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_COMPONENT", "Work Order Type") + "</td><td>{0}</td></tr>", wo.Completed);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_ASSIGNEDTO", "Assigned To") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(wo.AssignedToName));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_STATUS", "Status") + "</td><td>{0}</td></tr>", wo.StatusName);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_DUEDATE", "Due Date") + "</td><td>{0}</td></tr>", wo.DueDate == null ? "" : wo.DueDate.Value.ToShortDateString());
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_NEXTFOLLOWUPDATE", "Next Follow Up Date") + "</td><td>{0}</td></tr>", wo.NextFollowUpDate == null ? "" : wo.NextFollowUpDate.Value.ToShortDateString());
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_DESCRIPTION", "Description") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(wo.Description).Replace("\n", "<br>"));
|
|
str.AppendLine("");
|
|
if (wo.Completed)
|
|
{
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_METERTYPE", "Meter Type") + "</td><td>{0}</td></tr>", wo.MeterType);
|
|
str.AppendLine("");
|
|
if (string.Compare(wo.MeterType, "HourMeter", true) == 0
|
|
|| string.Compare(wo.MeterType, "Both", true) == 0)
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_HOURMETER", "Hour Meter") + "</td><td>{0}</td></tr>", wo.HourMeter);
|
|
if (string.Compare(wo.MeterType, "Odometer", true) == 0
|
|
|| string.Compare(wo.MeterType, "Both", true) == 0)
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_ODOMETER", "Odometer") + "</td><td>{0} {1}</td></tr>", wo.Odometer, wo.OdometerUnits);
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_WORKORDERTOTALCOST", "Work Order Total Costs ($)") + "</td><td>{0}</td></tr>", wo.WorkOrderTotalCost);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_OTHERCOST", "Other Cost ($)") + "</td><td>{0}</td></tr>", wo.OtherCost);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_PARTSCOST", "Parts Cost ($)") + "</td><td>{0}</td></tr>", wo.PartsCost);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_TRAVELTIMECOST", "Travel Time Cost ($)") + "</td><td>{0}</td></tr>", wo.TravelTimeCost);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_LABORCOST", "Labor Cost ($)") + "</td><td>{0}</td></tr>", wo.LaborCost);
|
|
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.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("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_INTERNALID", "Internal ID") + "</td><td>{0}</td></tr>", wo.InternalID);
|
|
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.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + "Bill To Job" + "</td><td>{0}</td></tr>", wo.BillToJobName);
|
|
str.AppendLine("");
|
|
}
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_NOTES", "Notes") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(wo.Notes).Replace("\n", "<br>"));
|
|
str.AppendLine("");
|
|
str.AppendFormat("</table>");
|
|
|
|
return str.ToString();
|
|
}
|
|
|
|
private static string GenerateSegmentHtml(WorkOrderSegmentInfo se, int index, string lang)
|
|
{
|
|
StringBuilder str = new StringBuilder();
|
|
//str.AppendFormat("<div style='margin-bottom:36px;margin-left:30px;{0}'>", (index - 2) % 4 == 0 ? "page-break-after: always;" : "");
|
|
//str.AppendLine("");
|
|
str.AppendLine("<div style='margin-bottom:36px;margin-left:30px;'>");
|
|
str.AppendLine("<table>");
|
|
str.AppendFormat("<tr><td class='label' colspan='2' style='text-align:left;'>" + SystemParams.GetTextByKey(lang, "P_WO_SEGMENT", "Segment") + " {0}</td></tr>", index);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label' style='width:170px;'>" + SystemParams.GetTextByKey(lang, "P_WO_USER", "User") + "</td><td>{0}</td></tr>", HttpUtility.HtmlEncode(se.UserName));
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_HOURS", "Hours") + "</td><td>{0}</td></tr>", se.Hours);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_JOBSITE", "Jobsite") + "</td><td>{0}</td></tr>", se.JobsiteName);
|
|
str.AppendLine("");
|
|
str.AppendFormat("<tr><td class='label'>" + SystemParams.GetTextByKey(lang, "P_WO_COST", "Cost") + "</td><td>{0}</td></tr>", se.Cost);
|
|
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.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_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>"));
|
|
str.AppendLine("");
|
|
str.AppendLine("</table>");
|
|
str.AppendLine("</div>");
|
|
return str.ToString();
|
|
}
|
|
|
|
private static string GenerateInspectionHtml(InspectReportInfo report, string lang)
|
|
{
|
|
StringBuilder str = new StringBuilder();
|
|
str.AppendLine("<div style='margin-bottom:36px;'>");
|
|
str.AppendLine("<table>");
|
|
str.AppendFormat("<tr><td class='label' colspan='2' style='text-align:left;'>" + report.Template.Name + " <span style='margin-left:30px;'>" + (report.CommitTimeLocal == DateTime.MinValue ? "" : report.CommitTimeLocal.ToString("M/d/yyyy h:mm tt")) + "</span></td></tr>");
|
|
str.AppendLine("");
|
|
foreach (var page in report.Template.Pages)
|
|
{
|
|
foreach (var section in page.Sections)
|
|
{
|
|
foreach (var q in section.Questions)
|
|
{
|
|
//if (q.VisibleToCustomer)
|
|
//{
|
|
str.AppendLine("<tr><td class='label' style='width:170px;'>" + q.DisplayText + "</td>");
|
|
var span_level = "<span style='float:right;padding-right:3px;'>" + ShowSeverityLevel(lang, (int)q.SeverityLevel) + "</span>";
|
|
InspectResultItem[] anwers = report.Answers.Where(m => m.QuestionId.ToLower() == q.Id.ToLower()).ToArray();
|
|
if (anwers != null && anwers.Length > 0)
|
|
{
|
|
foreach (var a in anwers)
|
|
{
|
|
int[] ids = new int[] { 5, 8, 9, 10, 14, 15 };
|
|
if (!ids.Contains((int)q.QuestionType) || ((int)q.QuestionType == 15 && q.SubType != 15))
|
|
{
|
|
var result = a.Result;
|
|
if (result == null)
|
|
result = "";
|
|
|
|
if ((int)q.QuestionType == 6 && result.IndexOf(' ') >= 0)//Date do not show time
|
|
result = result.Split(' ')[0];
|
|
if ((int)q.QuestionType == 11//Odometer
|
|
|| (int)q.QuestionType == 18 //FuelUsed
|
|
|| ((int)q.QuestionType == 15 && q.SubType == 8)//FuelRecords Odometer
|
|
|| ((int)q.QuestionType == 15 && q.SubType == 10))//FuelRecords Quantity
|
|
result += " " + ConvertUnits(a.Units);
|
|
|
|
if ((int)q.QuestionType == 17 && q.TextToCompare != null && result.ToLower() != q.TextToCompare.ToLower()) // BarCodeValidate
|
|
str.AppendLine("<td><span style='color:red'>" + result + "<span><span style='margin-left:6px'>(" + q.TextToCompare + ")<span>");
|
|
else
|
|
str.AppendLine("<td>" + result);
|
|
|
|
str.AppendLine(span_level + "</td>");
|
|
break;
|
|
}
|
|
else if ((int)q.QuestionType == 5)//YesOrNo
|
|
{
|
|
if (a.SelectedItems != null && a.SelectedItems.Count > 0)
|
|
{
|
|
span_level = "<span style='float:right;padding-right:3px;'>" + ShowSeverityLevel(lang, (int)a.SelectedItems[0].SeverityLevel) + "</span>";
|
|
var label = "<label style='margin-left:5px; '>" + a.SelectedItems[0].Text + "</lable>";
|
|
var div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;'></div>";
|
|
if (!string.IsNullOrEmpty(a.SelectedItems[0].BackgroundColor))
|
|
{
|
|
div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;background-color:" + a.SelectedItems[0].BackgroundColor + "'></div>";
|
|
}
|
|
|
|
str.AppendLine("<td>" + div_circle + label + span_level + "</td>");
|
|
}
|
|
}
|
|
else if ((int)q.QuestionType == 8 || (int)q.QuestionType == 9 || ((int)q.QuestionType == 15 && q.SubType == 6) || ((int)q.QuestionType == 15 && q.SubType == 9))//DropDown、List
|
|
{
|
|
if (q.MultipleSelect)
|
|
{
|
|
if (a.SelectedItems != null && a.SelectedItems.Count > 0)
|
|
{
|
|
StringBuilder str1 = new StringBuilder();
|
|
str1.AppendLine("<table class='inptable'>");
|
|
for (var j = 0; j < a.SelectedItems.Count; j++)
|
|
{
|
|
str1.AppendLine("<tr>");
|
|
span_level = "<span style='float:right;padding-right:3px;'>" + ShowSeverityLevel(lang, (int)a.SelectedItems[j].SeverityLevel) + "</span>";
|
|
var label = "<label style='margin-left:5px; '>" + (j + 1) + ". " + a.SelectedItems[j].Text + "</lable>";
|
|
|
|
var div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;'></div>";
|
|
if (!string.IsNullOrEmpty(a.SelectedItems[j].BackgroundColor))
|
|
{
|
|
div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;background-color:" + a.SelectedItems[j].BackgroundColor + "'></div>";
|
|
}
|
|
str1.AppendLine("<td>" + div_circle + label + span_level + "</td>");
|
|
str1.AppendLine("</tr>");
|
|
}
|
|
|
|
str1.AppendLine("</table>");
|
|
str.AppendLine("<td>" + str1.ToString() + "</td>");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (a.SelectedItems != null && a.SelectedItems.Count > 0)
|
|
{
|
|
span_level = "<span style='float:right;padding-right:3px;'>" + ShowSeverityLevel(lang, (int)a.SelectedItems[0].SeverityLevel) + "</span>";
|
|
var label = "<label style='margin-left:5px; '>" + a.SelectedItems[0].Text + "</lable>";
|
|
|
|
var div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;'></div>";
|
|
if (!string.IsNullOrEmpty(a.SelectedItems[0].BackgroundColor))
|
|
{
|
|
div_circle = "<div style=' width: 12px; height: 12px; border-radius: 6px; display: inline-block;background-color:" + a.SelectedItems[0].BackgroundColor + "'></div>";
|
|
}
|
|
|
|
str.AppendLine("<td>" + div_circle + label + span_level + "</td>");
|
|
}
|
|
}
|
|
}
|
|
else if ((int)q.QuestionType == 14)//Email (Drop Down)
|
|
{
|
|
if (a.SelectedItems != null && a.SelectedItems.Count > 0)
|
|
{
|
|
StringBuilder str1 = new StringBuilder();
|
|
str1.AppendLine("<table class='inptable'>");
|
|
for (var j = 0; j < a.SelectedItems.Count; j++)
|
|
{
|
|
str1.AppendLine("<tr>");
|
|
var label = "<label>" + (j + 1) + ". " + a.SelectedItems[j].Text + "<" + a.SelectedItems[j].Value + "</lable>"; ;
|
|
str1.AppendLine("<td>" + label + "</td>");
|
|
str1.AppendLine("</tr>");
|
|
}
|
|
str1.AppendLine("</table>");
|
|
str.AppendLine("<td>" + str1.ToString() + "</td>");
|
|
}
|
|
}
|
|
else if ((int)q.QuestionType == 10 || ((int)q.QuestionType == 15 && q.SubType == 15))//Picture
|
|
{
|
|
StringBuilder str1 = new StringBuilder();
|
|
str1.AppendLine("<div style='min-height:80px;overflow:auto;'>");
|
|
if (report.Medias != null && report.Medias.Count > 0)
|
|
{
|
|
for (var j = 0; j < report.Medias.Count; j++)
|
|
{
|
|
var m = report.Medias[j];
|
|
if (m.AnswerId.ToLower() == a.Id.ToLower())
|
|
{
|
|
string[] pictypes = new string[] { ".mp4", ".mov" };
|
|
if (pictypes.Contains(m.FileType.ToLower()))
|
|
{
|
|
str1.AppendLine("<div class='media'><span class='video'></span></div>");
|
|
}
|
|
else
|
|
{
|
|
str1.AppendLine("<img class='media' src='" + m.ThumbnailUrl + "'></img>");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
str1.AppendLine("</div>");
|
|
|
|
str.AppendLine("<td>" + str1.ToString() + "</td>");
|
|
}
|
|
else
|
|
str.AppendLine("<td></td>");
|
|
}
|
|
str.AppendLine("</tr>");
|
|
str.AppendLine("");
|
|
}
|
|
else
|
|
{
|
|
str.AppendLine("<td></td>");
|
|
str.AppendLine("</tr>");
|
|
str.AppendLine("");
|
|
}
|
|
//}
|
|
}
|
|
}
|
|
}
|
|
|
|
str.AppendLine("</table>");
|
|
str.AppendLine("</div>");
|
|
return str.ToString();
|
|
}
|
|
|
|
private static string ConvertUnits(string u)
|
|
{
|
|
switch (u.ToLower())
|
|
{
|
|
case "mile":
|
|
return "Mile(s)";
|
|
case "kilometre":
|
|
case "kilometer":
|
|
return "Kilometer";
|
|
case "percent":
|
|
return "Percent";
|
|
case "gallon":
|
|
case "gal":
|
|
return "Gallon";
|
|
case "litre":
|
|
return "Litre";
|
|
default:
|
|
break;
|
|
}
|
|
return u;
|
|
}
|
|
|
|
private static string ShowSeverityLevel(string lang, int level)
|
|
{
|
|
var levertext = SystemParams.GetTextByKey(lang, "P_IPT_SEVERITYLEVEL_COLON", "Severity Level: ");
|
|
if (level == 0)
|
|
levertext = "";
|
|
if (level == 1)
|
|
levertext += SystemParams.GetTextByKey(lang, "P_IPT_SL_LOW", "Low");
|
|
else if (level == 2)
|
|
levertext += SystemParams.GetTextByKey(lang, "P_IPT_SL_MEDIUM", "Medium");
|
|
else if (level == 3)
|
|
levertext += SystemParams.GetTextByKey(lang, "P_IPT_SL_HIGH", "High");
|
|
return levertext;
|
|
}
|
|
|
|
public static string WorkorderAlertsFormart(long woid, string lang, string sessionid)
|
|
{
|
|
AlertItems items = GetWorkOrderAlerts(woid, sessionid);
|
|
string EmailFormat = string.Empty;
|
|
if (items != null)
|
|
{
|
|
if (items.DTCAlerts != null && items.DTCAlerts.Length > 0)
|
|
EmailFormat += AlertsFormat(items.DTCAlerts, SystemParams.GetTextByKey(lang, "P_WO_DTCALERTS", "DTC Alerts"), lang);
|
|
if (items.PMAlerts != null && items.PMAlerts.Length > 0)
|
|
EmailFormat += AlertsFormat(items.PMAlerts, SystemParams.GetTextByKey(lang, "P_WO_PMALERTS", "PM Alerts"), lang);
|
|
if (items.InspectAlerts != null && items.InspectAlerts.Length > 0)
|
|
EmailFormat += AlertsFormat(items.InspectAlerts, SystemParams.GetTextByKey(lang, "P_WO_INSPECTALERTS", "Inspect Alerts"), lang);
|
|
if (items.OilAlerts != null && items.OilAlerts.Length > 0)
|
|
EmailFormat += AlertsFormat(items.OilAlerts, SystemParams.GetTextByKey(lang, "P_WO_OILALERTS", "Oil Alerts"), lang);
|
|
}
|
|
return EmailFormat;
|
|
}
|
|
|
|
public static string AlertsFormat(AlertInfo[] alerts, string type, string lang)
|
|
{
|
|
string AlertsFormat = "<table style=\"border:solid 1px #e1dbdb;border-collapse: collapse;margin-bottom:36px;\"><tr>";
|
|
AlertsFormat += "<td colspan=\"6\"><span style=\"font-weight:700;\">{0}</span></td></tr>";
|
|
|
|
AlertsFormat += "<tr style=\"height:30px; background-color:#f1f1f1;\">";
|
|
AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_HOURS", "Hours") + "</td>";
|
|
AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_ALERTTYPE", "Alert Type") + "</td>";
|
|
AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_DESCRIPTION", "Description") + "</td>";
|
|
if (string.Compare(type, "PM Alerts", true) == 0)
|
|
AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_SERVICEDESCRIPTION", "Service Description") + "</td>";
|
|
AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_COUNT", "Count") + "</td>";
|
|
AlertsFormat += "<td style=\"border:1px solid #e1dbdb;\">" + SystemParams.GetTextByKey(lang, "P_WO_LATESTDATETIME", "Latest DateTime") + "</td>";
|
|
AlertsFormat += "</tr>";
|
|
AlertsFormat += "{1}";//Alert Information
|
|
AlertsFormat += "</table>";
|
|
|
|
if (alerts != null)
|
|
{
|
|
string tr_data = string.Empty;
|
|
foreach (AlertInfo item in alerts)
|
|
{
|
|
tr_data += "<tr>";
|
|
tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.EngineHours + "</td>";
|
|
tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.AlertType + "</td>";
|
|
tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.Description + "</td>";
|
|
if (string.Compare(type, "PM Alerts", true) == 0)
|
|
tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.ServiceDescription + "</td>";
|
|
tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.AlertCount + "</td>";
|
|
tr_data += "<td style=\"border:1px solid #e1dbdb;\">" + item.AlertLocalTimeStr + "</td>";
|
|
tr_data += "</tr>";
|
|
}
|
|
|
|
return string.Format(AlertsFormat, type, tr_data);
|
|
}
|
|
return string.Empty;
|
|
}
|
|
|
|
public static AlertItems GetWorkOrderAlerts(long workorderid, string sessionid)
|
|
{
|
|
AssetAlertItem[] alerts = FleetServiceClientHelper.CreateClient<WorkOrderProvider>(sessionid).GetWorkOrderAlerts(SystemParams.CompanyID, workorderid);
|
|
|
|
if (alerts != null)
|
|
{
|
|
AlertItems items = new AlertItems();
|
|
var dtcalerts = new List<AlertInfo>();
|
|
var pmaalerts = new List<AlertInfo>();
|
|
var inspectalerts = new List<AlertInfo>();
|
|
var oilalerts = new List<AlertInfo>();
|
|
Dictionary<string, List<AlertInfo>> pmalertdic = new Dictionary<string, List<AlertInfo>>();
|
|
foreach (AssetAlertItem alertitem in alerts.OrderByDescending(ai => ai.AlertTime))
|
|
{
|
|
List<AlertInfo> tempList = null;
|
|
if (alertitem.Category == AssetAlertCategory.PMAlert)
|
|
tempList = pmaalerts;
|
|
else if (alertitem.Category == AssetAlertCategory.InspectAlert)
|
|
tempList = inspectalerts;
|
|
else if (alertitem.Category == AssetAlertCategory.OilSampleAlert)
|
|
tempList = oilalerts;
|
|
else
|
|
tempList = dtcalerts;
|
|
|
|
var existalert = tempList.FirstOrDefault((ai) => ai.Description == alertitem.Description);
|
|
if (existalert != null)
|
|
{
|
|
existalert.AlertCount++;
|
|
if (existalert.RepeatedAlerts == null)
|
|
existalert.RepeatedAlerts = new List<long>();
|
|
existalert.RepeatedAlerts.Add(alertitem.ID);
|
|
}
|
|
else
|
|
{
|
|
var a = ConvertAlert(alertitem);
|
|
a.AlertCount = 1;
|
|
tempList.Add(a);
|
|
|
|
if (alertitem.Category == AssetAlertCategory.PMAlert)
|
|
{
|
|
if (!pmalertdic.ContainsKey(a.ScheduleID))
|
|
pmalertdic[a.ScheduleID] = new List<AlertInfo>();
|
|
pmalertdic[a.ScheduleID].Add(a);
|
|
}
|
|
}
|
|
}
|
|
items.DTCAlerts = dtcalerts.ToArray();
|
|
items.PMAlerts = pmaalerts.ToArray();
|
|
items.InspectAlerts = inspectalerts.ToArray();
|
|
items.OilAlerts = oilalerts.ToArray();
|
|
items.AllExpectedCost = 0;
|
|
|
|
foreach (var dic in pmalertdic)
|
|
{
|
|
items.AllExpectedCost += dic.Value.Where(m => !m.Recurring).Sum(m => m.ExpectedCost);
|
|
|
|
int minPriority = dic.Value.Select(m => m.Priority).Min();
|
|
var recalerts = dic.Value.Where(m => m.Priority == minPriority && m.Recurring && m.ExpectedCost > 0);
|
|
if (recalerts != null && recalerts.Count() > 0)
|
|
items.AllExpectedCost += recalerts.Sum(m => m.ExpectedCost);
|
|
}
|
|
|
|
return items;
|
|
}
|
|
return null;
|
|
}
|
|
private static AlertInfo ConvertAlert(AssetAlertItem alertitem)
|
|
{
|
|
AlertInfo ai = new AlertInfo();
|
|
ai.AlertID = alertitem.ID;
|
|
ai.MachineID = alertitem.AssetID;
|
|
ai.AlertType = alertitem.AlertType;
|
|
ai.Description = alertitem.Description;
|
|
ai.Description = ai.FormatDescription(ai.Description);
|
|
ai.AlertTime_UTC = alertitem.AlertTime;
|
|
ai.AlertLocalTime = alertitem.AlertLocalTime;
|
|
ai.EngineHours = alertitem.EngineHours;
|
|
ai.ServiceDescription = alertitem.ServiceDescription;
|
|
ai.ScheduleID = alertitem.ScheduleID;
|
|
ai.IntervalID = alertitem.IntervalID;
|
|
ai.Recurring = alertitem.Recurring;
|
|
ai.Priority = alertitem.Priority;
|
|
ai.ExpectedCost = alertitem.ExpectedCost;
|
|
|
|
return ai;
|
|
}
|
|
|
|
public static (string body, KeyValuePair<string, byte[]>[]) GetSurveyReportEmail(SurveyReportInfo report)
|
|
{
|
|
var list = new List<KeyValuePair<string, byte[]>>();
|
|
|
|
var sb = new StringBuilder();
|
|
sb.AppendLine("<div>");
|
|
sb.AppendLine($"<div style=\"font-size: 24px; font-weight: bold; text-align: center\">{HttpUtility.HtmlEncode(report.TemplateName)}</div>");
|
|
sb.AppendLine($"<div style=\"font-size: 16px; font-weight: bold; text-align: center\">There are {report.SurveyCount} survey(s) in total.</div>");
|
|
sb.AppendLine("<br/><br/>");
|
|
int count = 0;
|
|
foreach (var q in report.Questions)
|
|
{
|
|
string imgid;
|
|
if (q.QuestionType == SurveyQuestionTypes.Choose)
|
|
{
|
|
sb.AppendLine($"<div style=\"font-size: 24px; font-weight: bold; padding-left: 10px\">{HttpUtility.HtmlEncode(q.Title)}</div>");
|
|
imgid = "img" + (++count).ToString("000");
|
|
sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
|
|
var chooseBarDrawer = new ColumnChartDrawer
|
|
{
|
|
Data = new ChartData
|
|
{
|
|
XAxis = q.Values.Select(v => new XValue { Label = v.DisplayText }).ToArray(),
|
|
XInclinedValue = -45,
|
|
Series = new[]
|
|
{
|
|
new DataSeries
|
|
{
|
|
SeriesType = SeriesType.Column,
|
|
Color = Color.FromArgb(0x43, 0x86, 0xd8),
|
|
DataPoints = q.Values.Select(v => new DataPoint { Y = v.Count }).ToArray()
|
|
}
|
|
}
|
|
}
|
|
};
|
|
var bitmap = new Bitmap(800, 300);
|
|
var result = chooseBarDrawer.DrawChart(bitmap);
|
|
var ms = new MemoryStream();
|
|
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
|
ms.Flush();
|
|
list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));
|
|
|
|
imgid = "img" + (++count).ToString("000");
|
|
sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
|
|
var pieDrawer = new PieChartDrawer
|
|
{
|
|
Data = new ChartData
|
|
{
|
|
Series = new[]
|
|
{
|
|
new DataSeries
|
|
{
|
|
SeriesType = SeriesType.Pie,
|
|
DataPoints = q.Values.Select(v => new DataPoint { Name = v.DisplayText, Y = v.Count, DisplayValue = v.Count.ToString() }).ToArray()
|
|
}
|
|
},
|
|
ShowLegend = true
|
|
}
|
|
};
|
|
bitmap = new Bitmap(800, 300);
|
|
result = pieDrawer.DrawChart(bitmap);
|
|
ms = new MemoryStream();
|
|
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
|
ms.Flush();
|
|
list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));
|
|
}
|
|
else if (q.QuestionType == SurveyQuestionTypes.YesOrNo)
|
|
{
|
|
sb.AppendLine($"<div style=\"font-size: 24px; font-weight: bold; padding-left: 10px\">{HttpUtility.HtmlEncode(q.Title)}</div>");
|
|
imgid = "img" + (++count).ToString("000");
|
|
sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
|
|
var barDrawer = new BarChartDrawer
|
|
{
|
|
Data = new ChartData
|
|
{
|
|
XAxis = new[]
|
|
{
|
|
new XValue
|
|
{
|
|
Label = string.Empty
|
|
}
|
|
},
|
|
Series = new[]
|
|
{
|
|
new DataSeries
|
|
{
|
|
Name = q.Values[0].DisplayText,
|
|
SeriesType = SeriesType.Bar,
|
|
DataPoints = new[]
|
|
{
|
|
new DataPoint { Y = q.Values[0].Count }
|
|
}
|
|
},
|
|
new DataSeries
|
|
{
|
|
Name = q.Values[1].DisplayText,
|
|
SeriesType = SeriesType.Bar,
|
|
DataPoints = new[]
|
|
{
|
|
new DataPoint { Y = q.Values[1].Count }
|
|
}
|
|
}
|
|
},
|
|
ShowLegend = true
|
|
}
|
|
};
|
|
var bitmap = new Bitmap(700, 220);
|
|
var result = barDrawer.DrawChart(bitmap);
|
|
var ms = new MemoryStream();
|
|
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
|
ms.Flush();
|
|
list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));
|
|
}
|
|
else if (q.QuestionType == SurveyQuestionTypes.Score)
|
|
{
|
|
sb.AppendLine($"<div style=\"font-size: 24px; font-weight: bold; padding-left: 10px\">{HttpUtility.HtmlEncode(q.Title)}</div>");
|
|
imgid = "img" + (++count).ToString("000");
|
|
sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
|
|
var chooseBarDrawer = new ColumnChartDrawer
|
|
{
|
|
Data = new ChartData
|
|
{
|
|
XAxis = q.Values.Select(v => new XValue { Label = v.DisplayText }).ToArray(),
|
|
XInclinedValue = -45,
|
|
Series = new[]
|
|
{
|
|
new DataSeries
|
|
{
|
|
SeriesType = SeriesType.Column,
|
|
Color = Color.FromArgb(0x43, 0x86, 0xd8),
|
|
DataPoints = q.Values.Select(v => new DataPoint { Y = v.Count }).ToArray()
|
|
}
|
|
}
|
|
}
|
|
};
|
|
var bitmap = new Bitmap(800, 300);
|
|
var result = chooseBarDrawer.DrawChart(bitmap);
|
|
var ms = new MemoryStream();
|
|
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
|
ms.Flush();
|
|
list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));
|
|
|
|
imgid = "img" + (++count).ToString("000");
|
|
sb.AppendLine($"<img src=\"cid:{imgid}\"/>");
|
|
var pieDrawer = new PieChartDrawer
|
|
{
|
|
Data = new ChartData
|
|
{
|
|
Series = new[]
|
|
{
|
|
new DataSeries
|
|
{
|
|
SeriesType = SeriesType.Pie,
|
|
DataPoints = q.Values.Select(v => new DataPoint { Name = v.DisplayText, Y = v.Count, DisplayValue = v.Count.ToString() }).ToArray()
|
|
}
|
|
},
|
|
ShowLegend = true
|
|
}
|
|
};
|
|
bitmap = new Bitmap(800, 300);
|
|
result = pieDrawer.DrawChart(bitmap);
|
|
ms = new MemoryStream();
|
|
bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
|
|
ms.Flush();
|
|
list.Add(new KeyValuePair<string, byte[]>(imgid, ms.ToArray()));
|
|
}
|
|
else
|
|
{
|
|
continue;
|
|
}
|
|
sb.AppendLine("<br/><br/>");
|
|
}
|
|
sb.AppendLine("</div>");
|
|
|
|
return (sb.ToString(), list.ToArray());
|
|
}
|
|
}
|
|
|
|
public class AlertItems
|
|
{
|
|
public AlertInfo[] DTCAlerts { get; set; }
|
|
public AlertInfo[] PMAlerts { get; set; }
|
|
public AlertInfo[] InspectAlerts { get; set; }
|
|
public AlertInfo[] OilAlerts { get; set; }
|
|
public double AllExpectedCost { get; set; }
|
|
}
|
|
}
|