feature: lodge insurance

This commit is contained in:
Gary Sharp
2024-09-25 16:21:51 +10:00
parent 78b7b059ea
commit e0d620bf67
61 changed files with 5861 additions and 1808 deletions
@@ -0,0 +1,92 @@
using Disco.Data.Repository;
using Disco.Models.BI.Config;
using Disco.Models.Repository;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
namespace Disco.Services.Plugins.Features.InsuranceProvider
{
[PluginFeatureCategory(DisplayName = "Insurance Providers")]
public abstract class InsuranceProviderFeature : PluginFeature
{
/// <summary>
/// The insurer identifier. Used to link this provider to any <see cref="JobMetaInsurance.Insurer"/>. This identifier is used to automatically set the Insurer 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 submit the insurance claim 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)
{
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, 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="JobMetaInsurance.InsurerReference"/></returns>
public abstract string SubmitJob(DiscoDataContext database, Job job, OrganisationAddress address, User techUser, List<JobAttachment> attachments, 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's insurance 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 pluginIdOrInsuranceProviderId)
{
var defs = Plugins.GetPluginFeatures(typeof(InsuranceProviderFeature));
var def = defs.FirstOrDefault(d => d.PluginManifest.Id.Equals(pluginIdOrInsuranceProviderId, StringComparison.OrdinalIgnoreCase));
if (def != null)
return def;
else
foreach (var d in defs)
{
using (var providerInstance = d.CreateInstance<InsuranceProviderFeature>())
{
if (providerInstance.ProviderId != null && providerInstance.ProviderId.Equals(pluginIdOrInsuranceProviderId, StringComparison.OrdinalIgnoreCase))
{
return d;
}
}
}
return null;
}
}
}
@@ -0,0 +1,12 @@
using System;
namespace Disco.Services.Plugins.Features.InsuranceProvider
{
public class InsuranceProviderSubmitJobException : Exception
{
public InsuranceProviderSubmitJobException(string message)
: base(message)
{
}
}
}
@@ -0,0 +1,20 @@
using Disco.Data.Repository;
using Disco.Models.BI.Config;
using Disco.Models.Repository;
using System;
using System.Collections.Generic;
namespace Disco.Services.Plugins.Features.RepairProvider
{
[PluginFeatureCategory(DisplayName = "Repair Providers")]
public abstract class RepairProvider2Feature : RepairProviderFeature
{
public override sealed string SubmitJob(DiscoDataContext Database, Job Job, OrganisationAddress Address, User TechUser, string RepairDescription, Dictionary<string, string> ProviderProperties)
{
throw new NotSupportedException();
}
public abstract string SubmitJob(DiscoDataContext database, Job job, OrganisationAddress address, User techUser, string description, List<JobAttachment> attachments, Dictionary<string, string> providerProperties);
}
}
@@ -0,0 +1,19 @@
using Disco.Data.Repository;
using Disco.Models.BI.Config;
using Disco.Models.Repository;
using System;
using System.Collections.Generic;
namespace Disco.Services.Plugins.Features.WarrantyProvider
{
[PluginFeatureCategory(DisplayName = "Warranty Providers")]
public abstract class WarrantyProvider2Feature : WarrantyProviderFeature
{
public override sealed string SubmitJob(DiscoDataContext Database, Job Job, OrganisationAddress Address, User TechUser, string FaultDescription, Dictionary<string, string> WarrantyProviderProperties)
{
throw new NotSupportedException();
}
public abstract string SubmitJob(DiscoDataContext database, Job job, OrganisationAddress address, User techUser, string description, List<JobAttachment> attachments, Dictionary<string, string> providerProperties);
}
}
+2 -1
View File
@@ -530,6 +530,7 @@ namespace Disco.Services.Plugins
public void LogWarning(string Message)
{
LogWarning(Message, null);
PluginsLog.LogPluginWarning(this, Message);
}
public void LogWarning(string MessageFormat, params object[] Args)
{
@@ -537,7 +538,7 @@ namespace Disco.Services.Plugins
}
public void LogMessage(string Message)
{
LogMessage(Message, null);
PluginsLog.LogPluginMessage(this, Message);
}
public void LogMessage(string MessageFormat, params object[] Args)
{
+19 -4
View File
@@ -179,6 +179,15 @@ namespace Disco.Services.Plugins
return new HttpStatusCodeResult(System.Net.HttpStatusCode.OK, description);
}
public ActionResult BadRequest()
{
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
}
public ActionResult BadRequest(string description)
{
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest, description);
}
#endregion
#region Content
@@ -262,11 +271,17 @@ namespace Disco.Services.Plugins
}
public ActionResult RedirectToPluginAction(string PluginAction)
{
if (string.IsNullOrEmpty(PluginAction))
throw new ArgumentNullException("PluginAction");
return RedirectToPluginAction(PluginAction, null);
}
public ActionResult RedirectToPluginAction(string pluginAction, object routeValues)
{
if (string.IsNullOrEmpty(pluginAction))
throw new ArgumentNullException(nameof(pluginAction));
var routeValues = new RouteValueDictionary(new { PluginId = Manifest.Id, PluginAction = PluginAction });
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin", null, null, routeValues, RouteTable.Routes, HostController.Request.RequestContext, false);
var routeValueDictionary = new RouteValueDictionary(routeValues);
routeValueDictionary.Add("PluginId", Manifest.Id);
routeValueDictionary.Add("PluginAction", pluginAction);
string pluginActionUrl = UrlHelper.GenerateUrl("Plugin", null, null, routeValueDictionary, RouteTable.Routes, HostController.Request.RequestContext, false);
return new RedirectResult(pluginActionUrl, false);
}
@@ -134,6 +134,7 @@ namespace Disco.Services.Plugins
private readonly PluginControllerDescription controllerDescription;
private readonly MethodInfo methodInfo;
private readonly IAuthorizationFilter[] authorizationFilters;
private readonly ActionMethodSelectorAttribute methodSelector;
private readonly PluginParameterDescriptor[] parameterDescriptors;
public override string UniqueId { get; }
public override string ActionName { get; }
@@ -146,6 +147,7 @@ namespace Disco.Services.Plugins
UniqueId = $"{ControllerDescriptor.UniqueId}_{methodName}";
ActionName = methodName;
authorizationFilters = DiscoverAuthorizationFilters();
methodSelector = DiscoverMethodSelector();
parameterDescriptors = DiscoverParameters();
}
@@ -159,6 +161,11 @@ namespace Disco.Services.Plugins
return filters.ToArray();
}
private ActionMethodSelectorAttribute DiscoverMethodSelector()
{
return methodInfo.GetCustomAttributes<ActionMethodSelectorAttribute>(true).FirstOrDefault();
}
private PluginParameterDescriptor[] DiscoverParameters()
{
var methodParams = methodInfo.GetParameters();
@@ -187,6 +194,9 @@ namespace Disco.Services.Plugins
public ActionResult Execute(PluginWebHandlerController pluginController, ControllerContext controllerContext)
{
if (methodSelector != null && !methodSelector.IsValidForRequest(controllerContext, methodInfo))
return new HttpStatusCodeResult(System.Net.HttpStatusCode.BadRequest);
var methodParameters = BuildMethodParameters(methodInfo, controllerContext.Controller);
return (ActionResult)methodInfo.Invoke(pluginController, methodParameters);
+1 -1
View File
@@ -237,7 +237,7 @@ namespace Disco.Services.Plugins
if (_PluginManifests == null)
throw new InvalidOperationException("Plugins have not been initialized");
return _PluginManifests.Values.SelectMany(pm => pm.Features).Where(fm => fm.CategoryType.IsAssignableFrom(FeatureCategoryType)).OrderBy(fm => fm.PluginManifest.Name).ToList();
return _PluginManifests.Values.SelectMany(pm => pm.Features).Where(fm => FeatureCategoryType.IsAssignableFrom(fm.CategoryType)).OrderBy(fm => fm.PluginManifest.Name).ToList();
}
public static List<PluginFeatureManifest> GetPluginFeatures()
{