Feature #2: Implement Repair Provider

Logging Repair for Non-Warranty jobs has been brought into line with
Logging Warranty. RepairProviderFeature implemented which allows plugins
to be used in submitting jobs to third-parties for repair.
This commit is contained in:
Gary Sharp
2014-07-10 17:45:13 +10:00
parent 5ba9fde10f
commit f4394fe2a0
47 changed files with 4471 additions and 1163 deletions
+8
View File
@@ -133,6 +133,7 @@ namespace Disco.Services.Authorization
{ "Job.Properties.NonWarrantyProperties.PurchaseOrderRaised", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Properties.NonWarrantyProperties.PurchaseOrderRaised, (c, v) => c.Job.Properties.NonWarrantyProperties.PurchaseOrderRaised = v, "Purchase Order Raised Property", "Can update property", false) },
{ "Job.Properties.NonWarrantyProperties.PurchaseOrderReference", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Properties.NonWarrantyProperties.PurchaseOrderReference, (c, v) => c.Job.Properties.NonWarrantyProperties.PurchaseOrderReference = v, "Purchase Order Reference Property", "Can update property", false) },
{ "Job.Properties.NonWarrantyProperties.PurchaseOrderSent", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Properties.NonWarrantyProperties.PurchaseOrderSent, (c, v) => c.Job.Properties.NonWarrantyProperties.PurchaseOrderSent = v, "Purchase Order Sent Property", "Can update property", false) },
{ "Job.Properties.NonWarrantyProperties.RepairProviderDetails", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Properties.NonWarrantyProperties.RepairProviderDetails, (c, v) => c.Job.Properties.NonWarrantyProperties.RepairProviderDetails = v, "Repair Provider Details", "Can access repair provider details", false) },
{ "Job.Properties.NonWarrantyProperties.RepairerCompletedDate", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Properties.NonWarrantyProperties.RepairerCompletedDate, (c, v) => c.Job.Properties.NonWarrantyProperties.RepairerCompletedDate = v, "Repairer Completed Date Property", "Can update property", false) },
{ "Job.Properties.NonWarrantyProperties.RepairerLoggedDate", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Properties.NonWarrantyProperties.RepairerLoggedDate, (c, v) => c.Job.Properties.NonWarrantyProperties.RepairerLoggedDate = v, "Repairer Logged Date Property", "Can update property", false) },
{ "Job.Properties.NonWarrantyProperties.RepairerName", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Properties.NonWarrantyProperties.RepairerName, (c, v) => c.Job.Properties.NonWarrantyProperties.RepairerName = v, "Repairer Name Property", "Can update property", false) },
@@ -352,6 +353,7 @@ namespace Disco.Services.Authorization
new ClaimNavigatorItem("Job.Properties.NonWarrantyProperties.PurchaseOrderRaised", false),
new ClaimNavigatorItem("Job.Properties.NonWarrantyProperties.PurchaseOrderReference", false),
new ClaimNavigatorItem("Job.Properties.NonWarrantyProperties.PurchaseOrderSent", false),
new ClaimNavigatorItem("Job.Properties.NonWarrantyProperties.RepairProviderDetails", false),
new ClaimNavigatorItem("Job.Properties.NonWarrantyProperties.RepairerCompletedDate", false),
new ClaimNavigatorItem("Job.Properties.NonWarrantyProperties.RepairerLoggedDate", false),
new ClaimNavigatorItem("Job.Properties.NonWarrantyProperties.RepairerName", false),
@@ -645,6 +647,7 @@ namespace Disco.Services.Authorization
c.Job.Properties.NonWarrantyProperties.PurchaseOrderRaised = true;
c.Job.Properties.NonWarrantyProperties.PurchaseOrderReference = true;
c.Job.Properties.NonWarrantyProperties.PurchaseOrderSent = true;
c.Job.Properties.NonWarrantyProperties.RepairProviderDetails = true;
c.Job.Properties.NonWarrantyProperties.RepairerCompletedDate = true;
c.Job.Properties.NonWarrantyProperties.RepairerLoggedDate = true;
c.Job.Properties.NonWarrantyProperties.RepairerName = true;
@@ -1424,6 +1427,11 @@ namespace Disco.Services.Authorization
/// </summary>
public const string PurchaseOrderSent = "Job.Properties.NonWarrantyProperties.PurchaseOrderSent";
/// <summary>Repair Provider Details
/// <para>Can access repair provider details</para>
/// </summary>
public const string RepairProviderDetails = "Job.Properties.NonWarrantyProperties.RepairProviderDetails";
/// <summary>Repairer Completed Date Property
/// <para>Can update property</para>
/// </summary>
@@ -44,6 +44,9 @@ namespace Disco.Services.Authorization.Roles.ClaimGroups.Job
[ClaimDetails("Repairer Reference Property", "Can update property")]
public bool RepairerReference { get; set; }
[ClaimDetails("Repair Provider Details", "Can access repair provider details")]
public bool RepairProviderDetails { get; set; }
[ClaimDetails("Insurance Detail Properties", "Can update insurance detail properties")]
public bool InsuranceDetails { get; set; }
}
@@ -157,12 +157,15 @@ namespace Disco.Services.Authorization.Roles
/// </summary>
private static void MigrateAuthorizationRoles(DiscoDataContext Database)
{
// Use 'MyJobs' (A new claim) to detect if the Role hasn't been migrated yet
var affectedRoles = Database.AuthorizationRoles.Where(r => !r.ClaimsJson.Contains("MyJobs")).ToList();
// Determine roles which need migration from DBv11 -> DBv14
var affectedRoles_DBv14 = Database.AuthorizationRoles.Where(r => !r.ClaimsJson.Contains("MyJobs")).ToList();
// Determine roles which need migration from DBv14 -> DBv15
var affectedRoles_DBv15 = Database.AuthorizationRoles.Where(r => !r.ClaimsJson.Contains("RepairProviderDetails")).ToList();
if (affectedRoles.Count > 0)
if (affectedRoles_DBv14.Count > 0)
{
foreach (var role in affectedRoles)
foreach (var role in affectedRoles_DBv14)
{
var claims = JsonConvert.DeserializeObject<RoleClaims>(role.ClaimsJson);
@@ -204,6 +207,24 @@ namespace Disco.Services.Authorization.Roles
Database.SaveChanges();
}
if (affectedRoles_DBv15.Count > 0)
{
foreach (var role in affectedRoles_DBv15)
{
var claims = JsonConvert.DeserializeObject<RoleClaims>(role.ClaimsJson);
// If the user previously had the ability to view warranty provider details, they probably should be able to view repair provider details (new feature).
if (claims.Job.Properties.WarrantyProperties.ProviderDetails)
{
claims.Job.Properties.NonWarrantyProperties.RepairProviderDetails = true;
}
role.ClaimsJson = Newtonsoft.Json.JsonConvert.SerializeObject(claims);
}
Database.SaveChanges();
}
}
}
}
+2
View File
@@ -261,6 +261,8 @@
<Compile Include="Logging\Persistance\LogPersistContextInitializer.cs" />
<Compile Include="Logging\Utilities.cs" />
<Compile Include="Plugins\CommunityInterop\PluginLibraryUpdateTask.cs" />
<Compile Include="Plugins\Features\RepairProvider\RepairProviderFeature.cs" />
<Compile Include="Plugins\Features\RepairProvider\RepairProviderSubmitJobException.cs" />
<Compile Include="Plugins\Features\UIExtension\Results\LiteralResult.cs" />
<Compile Include="Plugins\Features\UIExtension\Results\MultipleResult.cs" />
<Compile Include="Plugins\Features\UIExtension\Results\PluginResourceCssResult.cs" />
@@ -0,0 +1,94 @@
using Disco.Data.Repository;
using Disco.Models.BI.Config;
using Disco.Models.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
namespace Disco.Services.Plugins.Features.RepairProvider
{
[PluginFeatureCategory(DisplayName = "Repair Providers")]
public abstract class RepairProviderFeature : PluginFeature
{
/// <summary>
/// The repairer identifier. Used to link this provider to any <see cref="Disco.Models.Repository.RepairerName"/>. This identifier is used to automatically set the RepairerName when a job is submitted using this plugin.
/// </summary>
public abstract string ProviderId { get; }
#region Job Submission
/// <summary>
/// Called when a user selects this plugin to repair and allows a plugin to inject a View to collect additional information.
/// </summary>
/// <returns>A Tuple consisting of the Razor View type and a View Model</returns>
public virtual Tuple<Type, dynamic> SubmitJobBegin(DiscoDataContext Database, Controller controller, Job Job, OrganisationAddress Address, User TechUser)
{
return null;
}
/// <summary>
/// Called after the RepairDescription is completed and allows the plugin to parse any data collected from SubmitJobBegin.
/// </summary>
/// <returns>A Dictionary of key/value items which are persisted throughout the submission and passed into the final SubmitJob method.</returns>
public virtual Dictionary<string, string> SubmitJobParseProperties(DiscoDataContext Database, FormCollection form, Controller controller, Job Job, OrganisationAddress Address, User TechUser, string RepairDescription)
{
return null;
}
/// <summary>
/// Plugins are required to disclose any information that will be transmitted to any external party. This method is expected to return a clear list all data which will be transmitted.
/// </summary>
/// <returns>A Dictionary of key/value items which contain all information which will be disclosed to the plugin provider.</returns>
public abstract Dictionary<string, string> SubmitJobDiscloseInfo(DiscoDataContext Database, Job Job, OrganisationAddress Address, User TechUser, string RepairDescription, Dictionary<string, string> ProviderProperties);
/// <summary>
/// Called when the plugin should submit the job to the external party.
/// </summary>
/// <returns>A reference number/identifier from the external party which is stored in <see cref="Disco.Models.Repository.RepairerReference"/></returns>
public abstract string SubmitJob(DiscoDataContext Database, Job Job, OrganisationAddress Address, User TechUser, string RepairDescription, Dictionary<string, string> ProviderProperties);
#endregion
#region Job Details
/// <summary>
/// <see cref="true"/> when additional Job Details are supported by the external party. When <see cref="true"/>, JobDetailsViewModel must be implemented.
/// </summary>
public abstract bool JobDetailsSupported { get; }
/// <summary>
/// Called when a job repair information is shown. Allows a plugin to inject a View to display additional information.
/// </summary>
/// <returns>A Tuple consisting of the Razor View type and a View Model</returns>
public virtual Tuple<Type, dynamic> JobDetails(DiscoDataContext Database, Controller controller, Job Job)
{
return null;
}
#endregion
public static PluginFeatureManifest FindPluginFeature(string PluginIdOrRepairProviderId)
{
var defs = Plugins.GetPluginFeatures(typeof(RepairProviderFeature));
var def = defs.FirstOrDefault(d => d.PluginManifest.Id.Equals(PluginIdOrRepairProviderId, StringComparison.OrdinalIgnoreCase));
if (def != null)
return def;
else
foreach (var d in defs)
{
using (var providerInstance = d.CreateInstance<RepairProviderFeature>())
{
if (providerInstance.ProviderId != null && providerInstance.ProviderId.Equals(PluginIdOrRepairProviderId, StringComparison.OrdinalIgnoreCase))
{
return d;
}
}
}
return null;
}
}
}
@@ -0,0 +1,12 @@
using System;
namespace Disco.Services.Plugins.Features.RepairProvider
{
public class RepairProviderSubmitJobException : Exception
{
public RepairProviderSubmitJobException(string Message)
: base(Message)
{
}
}
}