Files
Disco/Disco.Services/Jobs/JobExtensions.cs
T
Gary Sharp 9bfeff8c42 feature: expose custom details to expressions
custom details can now be easily retrieved from any expression
2021-02-07 18:17:03 +11:00

429 lines
19 KiB
C#

using Disco.Data.Repository;
using Disco.Models.Repository;
using Disco.Models.Services.Documents;
using Disco.Models.Services.Jobs.JobLists;
using Disco.Services.Authorization;
using Disco.Services.Documents;
using Disco.Services.Expressions;
using Disco.Services.Interop.ActiveDirectory;
using Disco.Services.Plugins;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Disco.Services
{
public static class JobExtensions
{
public static JobTableStatusItemModel ToJobTableStatusItemModel(this Job j)
{
var i = new JobTableStatusItemModel()
{
JobId = j.Id,
OpenedDate = j.OpenedDate,
ClosedDate = j.ClosedDate,
JobTypeId = j.JobTypeId,
JobTypeDescription = j.JobType.Description,
DeviceHeldLocation = j.DeviceHeldLocation,
Flags = j.Flags,
WaitingForUserAction = j.WaitingForUserAction,
DeviceReadyForReturn = j.DeviceReadyForReturn,
DeviceHeld = j.DeviceHeld,
DeviceReturnedDate = j.DeviceReturnedDate
};
if (j.Device != null)
{
i.DeviceSerialNumber = j.DeviceSerialNumber;
i.DeviceModelDescription = j.Device.DeviceModel.Description;
i.DeviceAddressId = j.Device.DeviceProfile.DefaultOrganisationAddress;
if (j.JobMetaWarranty != null)
{
i.JobMetaWarranty_ExternalReference = j.JobMetaWarranty.ExternalReference;
i.JobMetaWarranty_ExternalLoggedDate = j.JobMetaWarranty.ExternalLoggedDate;
i.JobMetaWarranty_ExternalCompletedDate = j.JobMetaWarranty.ExternalCompletedDate;
i.JobMetaWarranty_ExternalName = j.JobMetaWarranty.ExternalName;
}
if (j.JobMetaNonWarranty != null)
{
i.JobMetaNonWarranty_RepairerLoggedDate = j.JobMetaNonWarranty.RepairerLoggedDate;
i.JobMetaNonWarranty_RepairerCompletedDate = j.JobMetaNonWarranty.RepairerCompletedDate;
i.JobMetaNonWarranty_AccountingChargeAddedDate = j.JobMetaNonWarranty.AccountingChargeAddedDate;
i.JobMetaNonWarranty_AccountingChargePaidDate = j.JobMetaNonWarranty.AccountingChargePaidDate;
i.JobMetaNonWarranty_AccountingChargeRequiredDate = j.JobMetaNonWarranty.AccountingChargeRequiredDate;
i.JobMetaNonWarranty_IsInsuranceClaim = j.JobMetaNonWarranty.IsInsuranceClaim;
i.JobMetaNonWarranty_RepairerName = j.JobMetaNonWarranty.RepairerName;
if (j.JobMetaInsurance != null)
{
i.JobMetaInsurance_ClaimFormSentDate = j.JobMetaInsurance.ClaimFormSentDate;
}
}
}
if (j.User != null)
{
i.UserId = j.UserId;
i.UserDisplayName = j.User.DisplayName;
i.UserFriendlyId = ActiveDirectory.FriendlyAccountId(j.UserId);
}
if (j.OpenedTechUser != null)
{
i.OpenedTechUserId = j.OpenedTechUserId;
i.OpenedTechUserFriendlyId = ActiveDirectory.FriendlyAccountId(j.OpenedTechUserId);
i.OpenedTechUserDisplayName = j.OpenedTechUser.DisplayName;
}
return i;
}
public static string JobStatusDescription(string StatusId, Job j = null)
{
switch (StatusId)
{
case Job.JobStatusIds.Open:
return "Open";
case Job.JobStatusIds.Closed:
return "Closed";
case Job.JobStatusIds.AwaitingWarrantyRepair:
if (j == null)
return "Awaiting Warranty Repair";
else
if (j.DeviceHeld.HasValue)
return string.Format("Awaiting Warranty Repair ({0})", j.JobMetaWarranty.ExternalName);
else
return string.Format("Awaiting Warranty Repair - Not Held ({0})", j.JobMetaWarranty.ExternalName);
case Job.JobStatusIds.AwaitingRepairs:
if (j == null)
return "Awaiting Repairs";
else
if (j.DeviceHeld.HasValue)
return string.Format("Awaiting Repairs ({0})", j.JobMetaNonWarranty.RepairerName);
else
return string.Format("Awaiting Repairs - Not Held ({0})", j.JobMetaNonWarranty.RepairerName);
case Job.JobStatusIds.AwaitingDeviceReturn:
return "Awaiting Device Return";
case Job.JobStatusIds.AwaitingUserAction:
return "Awaiting User Action";
case Job.JobStatusIds.AwaitingAccountingPayment:
return "Awaiting Accounting Payment";
case Job.JobStatusIds.AwaitingAccountingCharge:
return "Awaiting Accounting Charge";
case Job.JobStatusIds.AwaitingInsuranceProcessing:
return "Awaiting Insurance Processing";
default:
return "Unknown";
}
}
public static string JobStatusDescription(string StatusId, JobTableStatusItemModel j = null)
{
switch (StatusId)
{
case Job.JobStatusIds.Open:
return "Open";
case Job.JobStatusIds.Closed:
return "Closed";
case Job.JobStatusIds.AwaitingWarrantyRepair:
if (j == null)
return "Awaiting Warranty Repair";
else
if (j.DeviceHeld.HasValue)
return string.Format("Awaiting Warranty Repair ({0})", j.JobMetaWarranty_ExternalName);
else
return string.Format("Awaiting Warranty Repair - Not Held ({0})", j.JobMetaWarranty_ExternalName);
case Job.JobStatusIds.AwaitingRepairs:
if (j == null)
return "Awaiting Repairs";
else
if (j.DeviceHeld.HasValue)
return string.Format("Awaiting Repairs ({0})", j.JobMetaNonWarranty_RepairerName);
else
return string.Format("Awaiting Repairs - Not Held ({0})", j.JobMetaNonWarranty_RepairerName);
case Job.JobStatusIds.AwaitingDeviceReturn:
return "Awaiting Device Return";
case Job.JobStatusIds.AwaitingUserAction:
return "Awaiting User Action";
case Job.JobStatusIds.AwaitingAccountingPayment:
return "Awaiting Accounting Payment";
case Job.JobStatusIds.AwaitingAccountingCharge:
return "Awaiting Accounting Charge";
case Job.JobStatusIds.AwaitingInsuranceProcessing:
return "Awaiting Insurance Processing";
default:
return "Unknown";
}
}
public static string CalculateStatusId(this Job j)
{
return j.ToJobTableStatusItemModel().CalculateStatusId();
}
public static string CalculateStatusId(this JobTableStatusItemModel j)
{
if (j.ClosedDate.HasValue)
return Job.JobStatusIds.Closed;
if (j.JobTypeId == JobType.JobTypeIds.HWar)
{
if (j.JobMetaWarranty_ExternalLoggedDate.HasValue && !j.JobMetaWarranty_ExternalCompletedDate.HasValue)
return Job.JobStatusIds.AwaitingWarrantyRepair; // Job Logged - but not marked as completed
}
if (j.JobTypeId == JobType.JobTypeIds.HNWar)
{
if (j.JobMetaNonWarranty_RepairerLoggedDate.HasValue && !j.JobMetaNonWarranty_RepairerCompletedDate.HasValue)
return Job.JobStatusIds.AwaitingRepairs; // Repairs logged - but not complete
if (j.JobMetaNonWarranty_AccountingChargeAddedDate.HasValue && !j.JobMetaNonWarranty_AccountingChargePaidDate.HasValue)
return Job.JobStatusIds.AwaitingAccountingPayment; // Accounting Charge Added, but not paid
if (j.JobMetaNonWarranty_AccountingChargeRequiredDate.HasValue && (!j.JobMetaNonWarranty_AccountingChargePaidDate.HasValue || !j.JobMetaNonWarranty_AccountingChargeAddedDate.HasValue))
return Job.JobStatusIds.AwaitingAccountingCharge; // Accounting Charge Required, but not added or paid
if (j.JobMetaNonWarranty_RepairerLoggedDate.HasValue && j.JobMetaNonWarranty_IsInsuranceClaim.Value && !j.JobMetaInsurance_ClaimFormSentDate.HasValue)
return Job.JobStatusIds.AwaitingInsuranceProcessing; // Is insurance claim, but no Claim Form Sent
}
if (j.WaitingForUserAction.HasValue)
return Job.JobStatusIds.AwaitingUserAction; // Awaiting for User
if (j.DeviceReadyForReturn.HasValue && !j.DeviceReturnedDate.HasValue)
return Job.JobStatusIds.AwaitingDeviceReturn; // Device not returned to User
return Job.JobStatusIds.Open;
}
public static Tuple<string, string> Status(this Job j)
{
var statusId = j.CalculateStatusId();
return new Tuple<string, string>(statusId, JobStatusDescription(statusId, j));
}
public static List<DocumentTemplate> AvailableDocumentTemplates(this Job j, DiscoDataContext Database, User User, DateTime TimeStamp)
{
var dts = Database.DocumentTemplates.Include("JobSubTypes")
.Where(dt => !dt.IsHidden && dt.Scope == DocumentTemplate.DocumentTemplateScopes.Job)
.ToList();
foreach (var dt in dts.ToArray())
{
if (dt.JobSubTypes.Count != 0)
{ // Filter Applied
bool match = false;
foreach (var st in j.JobSubTypes)
{
if (dt.JobSubTypes.Contains(st))
{
match = true;
break;
}
}
if (!match)
dts.Remove(dt);
}
}
// Evaluate Filters
dts = dts.Where(dt => dt.FilterExpressionMatches(j, Database, User, TimeStamp, DocumentState.DefaultState())).ToList();
return dts;
}
public static List<DocumentTemplatePackage> AvailableDocumentTemplatePackages(this Job j, DiscoDataContext Database, User TechnicianUser)
{
return DocumentTemplatePackages.AvailablePackages(j, Database, TechnicianUser);
}
public static DateTime ValidateDateAfterOpened(this Job j, DateTime d)
{
if (d < j.OpenedDate)
{
if (d > j.OpenedDate.AddMinutes(-1))
return j.OpenedDate;
else
throw new ArgumentException("The Date must be >= the Open Date.", "d");
}
return d;
}
public static string GenerateFaultDescription(this Job j, DiscoDataContext Database)
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Faulty Components:");
foreach (var jst in j.JobSubTypes)
sb.Append("- ").AppendLine(jst.Description).AppendLine(" - ");
return sb.ToString();
}
public static string GenerateFaultDescriptionFooter(this Job j, DiscoDataContext Database, PluginFeatureManifest WarrantyProviderDefinition)
{
var versionDisco = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
return string.Format("Automation by Disco v{0}.{1}.{2:0000}.{3:0000} (Provider: {4} v{5})",
versionDisco.Major, versionDisco.Minor, versionDisco.Build, versionDisco.Revision, WarrantyProviderDefinition.Id, WarrantyProviderDefinition.PluginManifest.Version.ToString(4));
}
public static void UpdateSubTypes(this Job j, DiscoDataContext Database, List<JobSubType> SubTypes, bool AddComponents, User TechUser)
{
if (SubTypes == null || SubTypes.Count == 0)
throw new ArgumentException("The Job must contain at least one Sub Type");
List<JobSubType> addedSubTypes = new List<JobSubType>();
List<JobSubType> removedSubTypes = new List<JobSubType>();
// Removed Sub Types
foreach (var t in j.JobSubTypes.ToArray())
if (!SubTypes.Contains(t))
{
removedSubTypes.Add(t);
j.JobSubTypes.Remove(t);
}
// Added Sub Types
foreach (var t in SubTypes)
if (!j.JobSubTypes.Contains(t))
{
addedSubTypes.Add(t);
j.JobSubTypes.Add(t);
}
// Write Log
if (addedSubTypes.Count > 0 || removedSubTypes.Count > 0)
{
StringBuilder logBuilder = new StringBuilder();
logBuilder.AppendLine("# Updated Job Sub Types");
if (removedSubTypes.Count > 0)
{
logBuilder.AppendLine().AppendLine("Removed:");
foreach (var t in removedSubTypes)
logBuilder.Append("- **").Append(t.ToString()).AppendLine("**");
}
if (addedSubTypes.Count > 0)
{
logBuilder.AppendLine().AppendLine("Added:");
foreach (var t in addedSubTypes)
logBuilder.Append("- **").Append(t.ToString()).AppendLine("**");
}
Database.JobLogs.Add(new JobLog()
{
JobId = j.Id,
TechUserId = TechUser.UserId,
Timestamp = DateTime.Now,
Comments = logBuilder.ToString()
});
}
// Add Components
if (AddComponents && addedSubTypes.Count > 0 && j.DeviceSerialNumber != null)
{
var components = Database.DeviceComponents.Include("JobSubTypes").Where(c => !c.DeviceModelId.HasValue || c.DeviceModelId == j.Device.DeviceModelId);
var addedComponents = new List<DeviceComponent>();
foreach (var c in components)
{
foreach (var st in c.JobSubTypes)
{
foreach (var jst in addedSubTypes)
{
if (st.JobTypeId == jst.JobTypeId && st.Id == jst.Id)
{
addedComponents.Add(c);
break;
}
}
if (addedComponents.Contains(c))
break;
}
}
foreach (var c in addedComponents)
{
if (!j.JobComponents.Any(jc => jc.Description.Equals(c.Description, StringComparison.OrdinalIgnoreCase)))
{ // Job Component with matching Description doesn't exist.
Database.JobComponents.Add(new JobComponent()
{
Job = j,
TechUserId = TechUser.UserId,
Cost = c.Cost,
Description = c.Description
});
}
}
}
}
private static List<string> FilterCreatableTypePermissions(AuthorizationToken Authorization)
{
if (!Authorization.HasAll(Claims.Job.Types.CreateHMisc, Claims.Job.Types.CreateHNWar, Claims.Job.Types.CreateHWar, Claims.Job.Types.CreateSApp, Claims.Job.Types.CreateSImg, Claims.Job.Types.CreateSOS, Claims.Job.Types.CreateUMgmt))
{
// Must Filter
List<string> allowedTypes = new List<string>(6);
if (Authorization.Has(Claims.Job.Types.CreateHMisc))
allowedTypes.Add(JobType.JobTypeIds.HMisc);
if (Authorization.Has(Claims.Job.Types.CreateHNWar))
allowedTypes.Add(JobType.JobTypeIds.HNWar);
if (Authorization.Has(Claims.Job.Types.CreateHWar))
allowedTypes.Add(JobType.JobTypeIds.HWar);
if (Authorization.Has(Claims.Job.Types.CreateSApp))
allowedTypes.Add(JobType.JobTypeIds.SApp);
if (Authorization.Has(Claims.Job.Types.CreateSImg))
allowedTypes.Add(JobType.JobTypeIds.SImg);
if (Authorization.Has(Claims.Job.Types.CreateSOS))
allowedTypes.Add(JobType.JobTypeIds.SOS);
if (Authorization.Has(Claims.Job.Types.CreateUMgmt))
allowedTypes.Add(JobType.JobTypeIds.UMgmt);
return allowedTypes;
}
return null;
}
public static IQueryable<JobType> FilterCreatableTypePermissions(this IQueryable<JobType> JobTypes, AuthorizationToken Authorization)
{
var allowedTypes = FilterCreatableTypePermissions(Authorization);
if (allowedTypes != null)
{
return JobTypes.Where(jt => allowedTypes.Contains(jt.Id));
}
return JobTypes;
}
#region Expressions
public static string EvaluateOnCreateExpression(this Job job, DiscoDataContext Database)
{
if (!string.IsNullOrEmpty(Database.DiscoConfiguration.JobPreferences.OnCreateExpression))
{
Expression compiledExpression = Jobs.Jobs.OnCreateExpressionFromCache(Database);
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null, job);
object result = compiledExpression.EvaluateFirst<object>(job, evaluatorVariables);
if (result == null)
return null;
else
return result.ToString();
}
return null;
}
public static string EvaluateOnCloseExpression(this Job job, DiscoDataContext Database)
{
if (!string.IsNullOrEmpty(Database.DiscoConfiguration.JobPreferences.OnCloseExpression))
{
Expression compiledExpression = Jobs.Jobs.OnCloseExpressionFromCache(Database);
IDictionary evaluatorVariables = Expression.StandardVariables(null, Database, job.OpenedTechUser, DateTime.Now, null, job);
object result = compiledExpression.EvaluateFirst<object>(job, evaluatorVariables);
if (result == null)
return null;
else
return result.ToString();
}
return null;
}
#endregion
}
}