feature: job exporting (resolves #155)

This commit is contained in:
Gary Sharp
2024-12-12 16:02:12 +11:00
parent 90c709c4c1
commit a6b9cd1af2
55 changed files with 3197 additions and 412 deletions
@@ -1,5 +1,7 @@
using Disco.Data.Repository; using Disco.Data.Repository;
using Disco.Models.Services.Job; using Disco.Models.Services.Devices.Exporting;
using Disco.Models.Services.Jobs;
using Disco.Models.Services.Jobs.Exporting;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@@ -92,5 +94,20 @@ namespace Disco.Data.Configuration.Modules
get { return Get<string>(null); } get { return Get<string>(null); }
set { Set(value); } set { Set(value); }
} }
public JobExportOptions LastExportOptions
{
get { return this.Get(JobExportOptions.DefaultOptions()); }
set {
this.Set(value);
this.LastExportDate = DateTime.Now;
}
}
public DateTime? LastExportDate
{
get { return this.Get<DateTime?>(null); }
set { this.Set(value); }
}
} }
} }
+3
View File
@@ -80,6 +80,8 @@
<Compile Include="Services\Documents\DocumentTemplatePackage.cs" /> <Compile Include="Services\Documents\DocumentTemplatePackage.cs" />
<Compile Include="Services\Documents\OnImportUserFlagRule.cs" /> <Compile Include="Services\Documents\OnImportUserFlagRule.cs" />
<Compile Include="Exporting\IExportOptions.cs" /> <Compile Include="Exporting\IExportOptions.cs" />
<Compile Include="Services\Jobs\Exporting\JobExportOptions.cs" />
<Compile Include="Services\Jobs\Exporting\JobExportRecord.cs" />
<Compile Include="Services\Jobs\LocationModes.cs" /> <Compile Include="Services\Jobs\LocationModes.cs" />
<Compile Include="ClientServices\EnrolmentInformation\Certificate.cs" /> <Compile Include="ClientServices\EnrolmentInformation\Certificate.cs" />
<Compile Include="ClientServices\Register.cs" /> <Compile Include="ClientServices\Register.cs" />
@@ -217,6 +219,7 @@
<Compile Include="UI\Device\DeviceImportReviewModel.cs" /> <Compile Include="UI\Device\DeviceImportReviewModel.cs" />
<Compile Include="UI\Device\DeviceIndexModel.cs" /> <Compile Include="UI\Device\DeviceIndexModel.cs" />
<Compile Include="UI\Device\DeviceShowModel.cs" /> <Compile Include="UI\Device\DeviceShowModel.cs" />
<Compile Include="UI\Job\JobExportModel.cs" />
<Compile Include="UI\Job\JobCreateModel.cs" /> <Compile Include="UI\Job\JobCreateModel.cs" />
<Compile Include="UI\Job\JobIndexModel.cs" /> <Compile Include="UI\Job\JobIndexModel.cs" />
<Compile Include="UI\Job\JobListModel.cs" /> <Compile Include="UI\Job\JobListModel.cs" />
+22 -10
View File
@@ -1,7 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
@@ -99,15 +98,28 @@ namespace Disco.Models.Repository
public static class JobStatusIds public static class JobStatusIds
{ {
public const string AwaitingAccountingPayment = "AwaitingAccountingPayment"; public const string AwaitingAccountingPayment = nameof(AwaitingAccountingPayment);
public const string AwaitingAccountingCharge = "AwaitingAccountingCharge"; public const string AwaitingAccountingCharge = nameof(AwaitingAccountingCharge);
public const string AwaitingDeviceReturn = "AwaitingDeviceReturn"; public const string AwaitingDeviceReturn = nameof(AwaitingDeviceReturn);
public const string AwaitingInsuranceProcessing = "AwaitingInsuranceProcessing"; public const string AwaitingInsuranceProcessing = nameof(AwaitingInsuranceProcessing);
public const string AwaitingRepairs = "AwaitingRepairs"; public const string AwaitingRepairs = nameof(AwaitingRepairs);
public const string AwaitingUserAction = "AwaitingUserAction"; public const string AwaitingUserAction = nameof(AwaitingUserAction);
public const string AwaitingWarrantyRepair = "AwaitingWarrantyRepair"; public const string AwaitingWarrantyRepair = nameof(AwaitingWarrantyRepair);
public const string Closed = "Closed"; public const string Closed = nameof(Closed);
public const string Open = "Open"; public const string Open = nameof(Open);
public static readonly Dictionary<string, string> StatusDescriptions = new Dictionary<string, string>
{
{ AwaitingAccountingPayment, "Awaiting Accounting Payment" },
{ AwaitingAccountingCharge, "Awaiting Accounting Charge" },
{ AwaitingDeviceReturn, "Awaiting Device Return" },
{ AwaitingInsuranceProcessing, "Awaiting Insurance Processing" },
{ AwaitingRepairs, "Awaiting Repairs" },
{ AwaitingUserAction, "Awaiting User Action" },
{ AwaitingWarrantyRepair, "Awaiting Warranty Repair" },
{ Closed, "Closed" },
{ Open, "Open" }
};
} }
[Flags] [Flags]
@@ -0,0 +1,269 @@
using Disco.Models.Exporting;
using Disco.Models.Services.Exporting;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Disco.Models.Services.Jobs.Exporting
{
public class JobExportOptions : IExportOptions
{
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true, HtmlEncode = false)]
public DateTime FilterStartDate { get; set; }
[DisplayFormat(DataFormatString = "{0:yyyy-MM-dd}", ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true, HtmlEncode = false)]
public DateTime? FilterEndDate { get; set; }
public string FilterJobStatusId { get; set; }
public string FilterJobTypeId { get; set; }
public List<string> FilterJobSubTypeIds { get; set; }
public int? FilterJobQueueId { get; set; }
public ExportFormat Format { get; set; }
public string FilenamePrefix { get; } = "DiscoJobExport";
public string ExcelWorksheetName { get; } = "JobExport";
public string ExcelTableName { get; } = "Jobs";
// Job
[Display(ShortName = "Job", Name = "Identifier", Description = "The identifier of the job")]
public bool JobId { get; set; }
[Display(ShortName = "Job", Name = "Status", Description = "The status of the job")]
public bool JobStatus { get; set; }
[Display(ShortName = "Job", Name = "Type", Description = "The type of the job")]
public bool JobType { get; set; }
[Display(ShortName = "Job", Name = "Sub Types", Description = "The sub types of the job")]
public bool JobSubTypes { get; set; }
[Display(ShortName = "Job", Name = "Opened Date", Description = "The date the job was opened")]
public bool JobOpenedDate { get; set; }
[Display(ShortName = "Job", Name = "Opened User", Description = "The user who opened the job")]
public bool JobOpenedUser { get; set; }
[Display(ShortName = "Job", Name = "Expected Closed Date", Description = "The expected closed date of the job")]
public bool JobExpectedClosedDate { get; set; }
[Display(ShortName = "Job", Name = "Closed Date", Description = "The date the job was closed")]
public bool JobClosedDate { get; set; }
[Display(ShortName = "Job", Name = "Closed User", Description = "The user who closed the job")]
public bool JobClosedUser { get; set; }
// Job Details
[Display(ShortName = "Job Details", Name = "Held Date", Description = "The date the device was held")]
public bool JobDeviceHeldDate { get; set; }
[Display(ShortName = "Job Details", Name = "Held User", Description = "The user who held the device")]
public bool JobDeviceHeldUser { get; set; }
[Display(ShortName = "Job Details", Name = "Held Location", Description = "The location the device was held")]
public bool JobDeviceHeldLocation { get; set; }
[Display(ShortName = "Job Details", Name = "Ready For Return Date", Description = "The date the device was ready for return")]
public bool JobDeviceReadyForReturnDate { get; set; }
[Display(ShortName = "Job Details", Name = "Ready For Return User", Description = "The user who made the device ready for return")]
public bool JobDeviceReadyForReturnUser { get; set; }
[Display(ShortName = "Job Details", Name = "Returned Date", Description = "The date the device was returned")]
public bool JobDeviceReturnedDate { get; set; }
[Display(ShortName = "Job Details", Name = "Returned User", Description = "The user who returned the device")]
public bool JobDeviceReturnedUser { get; set; }
[Display(ShortName = "Job Details", Name = "Waiting For User Action Date", Description = "The date the job was waiting for user action")]
public bool JobWaitingForUserActionDate { get; set; }
// Job Log
[Display(ShortName = "Job Log", Name = "Count", Description = "The number of log entries for the job")]
public bool LogCount { get; set; }
[Display(ShortName = "Job Log", Name = "First Date", Description = "The date of the first log entry for the job")]
public bool LogFirstDate { get; set; }
[Display(ShortName = "Job Log", Name = "First User", Description = "The user who made the first log entry for the job")]
public bool LogFirstUser { get; set; }
[Display(ShortName = "Job Log", Name = "First Content", Description = "The content of the first log entry for the job")]
public bool LogFirstContent { get; set; }
[Display(ShortName = "Job Log", Name = "Last Date", Description = "The date of the last log entry for the job")]
public bool LogLastDate { get; set; }
[Display(ShortName = "Job Log", Name = "Last User", Description = "The user who made the last log entry for the job")]
public bool LogLastUser { get; set; }
[Display(ShortName = "Job Log", Name = "Last Content", Description = "The content of the last log entry for the job")]
public bool LogLastContent { get; set; }
// Job Attachments
[Display(ShortName = "Job Attachments", Name = "Count", Description = "The number of attachments for the job")]
public bool AttachmentsCount { get; set; }
// Job Queues
[Display(ShortName = "Job Queues", Name = "Count", Description = "The number of times the job has been associated with a queue")]
public bool JobQueueCount { get; set; }
[Display(ShortName = "Job Queues", Name = "Active Count", Description = "The number of active queues the job is associated with")]
public bool JobQueueActiveCount { get; set; }
[Display(ShortName = "Job Queues", Name = "Active Latest", Description = "The latest queue the job is associated with")]
public bool JobQueueActiveLatest { get; set; }
[Display(ShortName = "Job Queues", Name = "Active Latest Date", Description = "The date the latest queue was added")]
public bool JobQueueActiveLatestAddedDate { get; set; }
[Display(ShortName = "Job Queues", Name = "Active Latest User", Description = "The user who added the latest queue")]
public bool JobQueueActiveLatestAddedUser { get; set; }
// Job Type - Warranty
[Display(ShortName = "Job Warranty", Name = "External Name", Description = "The name of the external warranty provider")]
public bool JobWarrantyExternalName { get; set; }
[Display(ShortName = "Job Warranty", Name = "External Logged Date", Description = "The date the warranty was logged with the external provider")]
public bool JobWarrantyExternalLoggedDate { get; set; }
[Display(ShortName = "Job Warranty", Name = "External Reference", Description = "The reference of the warranty with the external provider")]
public bool JobWarrantyExternalReference { get; set; }
[Display(ShortName = "Job Warranty", Name = "External Completed Date", Description = "The date the warranty was completed with the external provider")]
public bool JobWarrantyExternalCompletedDate { get; set; }
// Job Type - NonWarranty
[Display(ShortName = "Job Non Warranty", Name = "Accounting Charge Required Date", Description = "The date the accounting charge was required")]
public bool JobNonWarrantyAccountingChargeRequiredDate { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Accounting Charge Added Date", Description = "The date the accounting charge was added")]
public bool JobNonWarrantyAccountingChargeAddedDate { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Accounting Charge Paid Date", Description = "The date the accounting charge was paid")]
public bool JobNonWarrantyAccountingChargePaidDate { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Purchase Order Raised Date", Description = "The date the purchase order was raised")]
public bool JobNonWarrantyPurchaseOrderRaisedDate { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Purchase Order Reference", Description = "The reference of the purchase order")]
public bool JobNonWarrantyPurchaseOrderReference { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Purchase Order Sent Date", Description = "The date the purchase order was sent")]
public bool JobNonWarrantyPurchaseOrderSentDate { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Invoice Received Date", Description = "The date the invoice was received")]
public bool JobNonWarrantyInvoiceReceivedDate { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Repairer Name", Description = "The name of the repairer")]
public bool JobNonWarrantyRepairerName { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Repairer Logged Date", Description = "The date the job was logged with the repairer")]
public bool JobNonWarrantyRepairerLoggedDate { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Repairer Reference", Description = "The repairer reference for the job")]
public bool JobNonWarrantyRepairerReference { get; set; }
[Display(ShortName = "Job Non Warranty", Name = "Repairer Completed Date", Description = "The date the repairer completed the job")]
public bool JobNonWarrantyRepairerCompletedDate { get; set; }
// Job Type - Insurance
[Display(ShortName = "Job Insurance", Name = "Loss Or Damage Date", Description = "The date of the loss or damage")]
public bool JobMetaInsuranceLossOrDamageDate { get; set; }
[Display(ShortName = "Job Insurance", Name = "Event Location", Description = "The location of the event")]
public bool JobMetaInsuranceEventLocation { get; set; }
[Display(ShortName = "Job Insurance", Name = "Description", Description = "The description of the event")]
public bool JobMetaInsuranceDescription { get; set; }
[Display(ShortName = "Job Insurance", Name = "Third Party Caused Name", Description = "The name of the third party which caused the event")]
public bool JobMetaInsuranceThirdPartyCausedName { get; set; }
[Display(ShortName = "Job Insurance", Name = "Third Party Caused Why", Description = "The reason the third party caused the event")]
public bool JobMetaInsuranceThirdPartyCausedWhy { get; set; }
[Display(ShortName = "Job Insurance", Name = "Witnesses Names Addresses", Description = "The names and addresses of the witnesses")]
public bool JobMetaInsuranceWitnessesNamesAddresses { get; set; }
[Display(ShortName = "Job Insurance", Name = "Burglary Theft Method Of Entry", Description = "The method of entry for a burglary or theft")]
public bool JobMetaInsuranceBurglaryTheftMethodOfEntry { get; set; }
[Display(ShortName = "Job Insurance", Name = "Property Last Seen Date", Description = "The date the property was last seen")]
public bool JobMetaInsurancePropertyLastSeenDate { get; set; }
[Display(ShortName = "Job Insurance", Name = "Police Station Notified", Description = "The police station which was notified")]
public bool JobMetaInsurancePoliceNotifiedStation { get; set; }
[Display(ShortName = "Job Insurance", Name = "Police Notified Date", Description = "The date the police were notified")]
public bool JobMetaInsurancePoliceNotifiedDate { get; set; }
[Display(ShortName = "Job Insurance", Name = "Police Crime Report Number", Description = "The crime report number provided by the police")]
public bool JobMetaInsurancePoliceNotifiedCrimeReportNo { get; set; }
[Display(ShortName = "Job Insurance", Name = "Recover Reduce Action", Description = "The action taken to recover or reduce the loss")]
public bool JobMetaInsuranceRecoverReduceAction { get; set; }
[Display(ShortName = "Job Insurance", Name = "Other Interested Parties", Description = "Other parties interested in the event")]
public bool JobMetaInsuranceOtherInterestedParties { get; set; }
[Display(ShortName = "Job Insurance", Name = "Date Of Purchase", Description = "The date the item was purchased")]
public bool JobMetaInsuranceDateOfPurchase { get; set; }
[Display(ShortName = "Job Insurance", Name = "Claim Form Sent Date", Description = "The date the claim form was sent")]
public bool JobMetaInsuranceClaimFormSentDate { get; set; }
[Display(ShortName = "Job Insurance", Name = "Insurer", Description = "The insurer associated with the claim")]
public bool JobMetaInsuranceInsurer { get; set; }
[Display(ShortName = "Job Insurance", Name = "Insurer Reference", Description = "The reference provided by the insurer")]
public bool JobMetaInsuranceInsurerReference { get; set; }
// Job Type = User Management
[Display(ShortName = "Job User Management", Name = "Flags", Description = "The user management flags associated with the job")]
public bool JobUserManagementFlags { get; set; }
// User
[Display(ShortName = "User", Name = "Identifier", Description = "The identifier of the user associated with the job")]
public bool UserId { get; set; }
[Display(ShortName = "User", Name = "Display Name", Description = "The display name of the user associated with the job")]
public bool UserDisplayName { get; set; }
[Display(ShortName = "User", Name = "Surname", Description = "The surname of the user associated with the job")]
public bool UserSurname { get; set; }
[Display(ShortName = "User", Name = "Given Name", Description = "The given name of the user associated with the job")]
public bool UserGivenName { get; set; }
[Display(ShortName = "User", Name = "Phone Number", Description = "The phone number of the user associated with the job")]
public bool UserPhoneNumber { get; set; }
[Display(ShortName = "User", Name = "Email Address", Description = "The email address of the user associated with the job")]
public bool UserEmailAddress { get; set; }
[Display(ShortName = "User", Name = "Custom Details", Description = "The custom details provided by plugins for the user associated with the job")]
public bool UserDetailCustom { get; set; }
// Device
[Display(ShortName = "Device", Name = "Serial Number", Description = "The device serial number")]
public bool DeviceSerialNumber { get; set; }
[Display(ShortName = "Device", Name = "Asset Number", Description = "The device asset number")]
public bool DeviceAssetNumber { get; set; }
[Display(ShortName = "Device", Name = "Location", Description = "The device location")]
public bool DeviceLocation { get; set; }
[Display(ShortName = "Device", Name = "Computer Name", Description = "The device computer name")]
public bool DeviceComputerName { get; set; }
[Display(ShortName = "Device", Name = "Last Network Logon", Description = "The last recorded time the device access the network")]
public bool DeviceLastNetworkLogon { get; set; }
[Display(ShortName = "Device", Name = "Created Date", Description = "The date the device was created in Disco ICT")]
public bool DeviceCreatedDate { get; set; }
[Display(ShortName = "Device", Name = "First Enrolled Date", Description = "The date the device was first enrolled in Disco ICT")]
public bool DeviceFirstEnrolledDate { get; set; }
[Display(ShortName = "Device", Name = "Last Enrolled Date", Description = "The date the device was last enrolled in Disco ICT")]
public bool DeviceLastEnrolledDate { get; set; }
[Display(ShortName = "Device", Name = "Enrolment Trusted", Description = "The device is trusted to complete an unauthenticated enrolment")]
public bool DeviceAllowUnauthenticatedEnrol { get; set; }
[Display(ShortName = "Device", Name = "Decommissioned Date", Description = "The date the device was decommissioned in Disco ICT")]
public bool DeviceDecommissionedDate { get; set; }
[Display(ShortName = "Device", Name = "Decommissioned Reason", Description = "The reason the device was decommissioned")]
public bool DeviceDecommissionedReason { get; set; }
// Model
[Display(ShortName = "Device Model", Name = "Identifier", Description = "The identifier of the device model associated with the job")]
public bool DeviceModelId { get; set; }
[Display(ShortName = "Device Model", Name = "Description", Description = "The description of the device model associated with the job")]
public bool DeviceModelDescription { get; set; }
[Display(ShortName = "Device Model", Name = "Manufacturer", Description = "The manufacturer of the device model associated with the job")]
public bool DeviceModelManufacturer { get; set; }
[Display(ShortName = "Device Model", Name = "Model", Description = "The model of the device model associated with the job")]
public bool DeviceModelModel { get; set; }
[Display(ShortName = "Device Model", Name = "Type", Description = "The type of device model associated with the job")]
public bool DeviceModelType { get; set; }
// Batch
[Display(ShortName = "Device Batch", Name = "Identifier", Description = "The identifier of the device batch associated with the job")]
public bool DeviceBatchId { get; set; }
[Display(ShortName = "Device Batch", Name = "Name", Description = "The name of the device batch associated with the job")]
public bool DeviceBatchName { get; set; }
[Display(ShortName = "Device Batch", Name = "Purchase Date", Description = "The purchase date of the device batch associated with the job")]
public bool DeviceBatchPurchaseDate { get; set; }
[Display(ShortName = "Device Batch", Name = "Supplier", Description = "The supplier of the device batch associated with the job")]
public bool DeviceBatchSupplier { get; set; }
[Display(ShortName = "Device Batch", Name = "Unit Cost", Description = "The unit cost of the device batch associated with the job")]
public bool DeviceBatchUnitCost { get; set; }
[Display(ShortName = "Device Batch", Name = "Warranty Valid Until Date", Description = "The warranty valid until date of the device batch associated with the job")]
public bool DeviceBatchWarrantyValidUntilDate { get; set; }
[Display(ShortName = "Device Batch", Name = "Insured Date", Description = "The insured date of the device batch associated with the job")]
public bool DeviceBatchInsuredDate { get; set; }
[Display(ShortName = "Device Batch", Name = "Insurance Supplier", Description = "The insurance supplier of the device batch associated with the job")]
public bool DeviceBatchInsuranceSupplier { get; set; }
[Display(ShortName = "Device Batch", Name = "Insured Until Date", Description = "The insured until date of the device batch associated with the job")]
public bool DeviceBatchInsuredUntilDate { get; set; }
// Profile
[Display(ShortName = "Device Profile", Name = "Identifier", Description = "The identifier of the device profile associated with the job")]
public bool DeviceProfileId { get; set; }
[Display(ShortName = "Device Profile", Name = "Name", Description = "The name of the device profile associated with the job")]
public bool DeviceProfileName { get; set; }
[Display(ShortName = "Device Profile", Name = "Short Name", Description = "The short name of the device profile associated with the job")]
public bool DeviceProfileShortName { get; set; }
public static JobExportOptions DefaultOptions()
{
return new JobExportOptions()
{
FilterJobStatusId = "Open",
FilterStartDate = new DateTime(DateTime.Now.Year, 1, 1),
Format = ExportFormat.Xlsx,
JobId = true,
JobStatus = true,
JobType = true,
JobSubTypes = true,
JobOpenedDate = true,
DeviceSerialNumber = true,
DeviceModelDescription = true,
DeviceProfileName = true,
UserId = true,
UserDisplayName = true,
};
}
}
}
@@ -0,0 +1,64 @@
using Disco.Models.Exporting;
using Disco.Models.Repository;
using Disco.Models.Services.Jobs.JobLists;
using System;
using System.Collections.Generic;
namespace Disco.Models.Services.Jobs.Exporting
{
public class JobExportRecord : IExportRecord
{
public Job Job { get; set; }
public string JobStatus { get; set; }
public string JobTypeDescription { get; set; }
public IEnumerable<string> JobSubTypeDescriptions { get; set; }
// Logs
public int? LogCount { get; set; }
public JobLog FirstLog { get; set; }
public JobLog LastLog { get; set; }
// Attachments
public int? AttachmentsCount { get; set; }
public DateTime? AttachmentsLastDate { get; set; }
// Queues
public int? QueueCount { get; set; }
public int? QueueActiveCount { get; set; }
public JobQueueJob QueueLatestActive { get; set; }
public JobMetaWarranty JobMetaWarranty { get; set; }
public JobMetaNonWarranty JobMetaNonWarranty { get; set; }
public JobMetaInsurance JobMetaInsurance { get; set; }
// User
public User User { get; set; }
public Dictionary<string, string> UserCustomDetails { get; set; }
// Device
public Device Device { get; set; }
// Device Model
public int? DeviceModelId { get; set; }
public string DeviceModelDescription { get; set; }
public string DeviceModelManufacturer { get; set; }
public string DeviceModelModel { get; set; }
public string DeviceModelType { get; set; }
// Device Batch
public int? DeviceBatchId { get; set; }
public string DeviceBatchName { get; set; }
public DateTime? DeviceBatchPurchaseDate { get; set; }
public string DeviceBatchSupplier { get; set; }
public decimal? DeviceBatchUnitCost { get; set; }
public DateTime? DeviceBatchWarrantyValidUntilDate { get; set; }
public DateTime? DeviceBatchInsuredDate { get; set; }
public string DeviceBatchInsuranceSupplier { get; set; }
public DateTime? DeviceBatchInsuredUntilDate { get; set; }
// Profile
public int? DeviceProfileId { get; set; }
public string DeviceProfileName { get; set; }
public string DeviceProfileShortName { get; set; }
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
namespace Disco.Models.Services.Job namespace Disco.Models.Services.Jobs
{ {
public enum LocationModes public enum LocationModes
{ {
@@ -1,6 +1,6 @@
using System; using System;
namespace Disco.Models.Services.Job.Statistics namespace Disco.Models.Services.Jobs.Statistics
{ {
public class DailyOpenedClosedItem public class DailyOpenedClosedItem
{ {
@@ -1,4 +1,4 @@
using Disco.Models.Services.Job; using Disco.Models.Services.Jobs;
using System.Collections.Generic; using System.Collections.Generic;
namespace Disco.Models.UI.Config.JobPreferences namespace Disco.Models.UI.Config.JobPreferences
+19
View File
@@ -0,0 +1,19 @@
using Disco.Models.Repository;
using Disco.Models.Services.Exporting;
using Disco.Models.Services.Jobs.Exporting;
using System.Collections.Generic;
namespace Disco.Models.UI.Job
{
public interface JobExportModel : BaseUIModel
{
JobExportOptions Options { get; set; }
string ExportSessionId { get; set; }
ExportResult ExportSessionResult { get; set; }
List<JobQueue> JobQueues { get; set; }
List<KeyValuePair<string, string>> JobStatuses { get; set; }
List<JobType> JobTypes { get; set; }
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
using Disco.Models.Services.Documents; using Disco.Models.Services.Documents;
using Disco.Models.Services.Job; using Disco.Models.Services.Jobs;
using Disco.Models.Services.Jobs.JobLists; using Disco.Models.Services.Jobs.JobLists;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
+17 -9
View File
@@ -107,11 +107,12 @@ namespace Disco.Services.Authorization
{ "Job.Actions.ConvertHWarToHNWar", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.ConvertHWarToHNWar, (c, v) => c.Job.Actions.ConvertHWarToHNWar = v, "Convert HWar Jobs To HNWar", "Can convert warranty jobs to non-warranty jobs", false) }, { "Job.Actions.ConvertHWarToHNWar", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.ConvertHWarToHNWar, (c, v) => c.Job.Actions.ConvertHWarToHNWar = v, "Convert HWar Jobs To HNWar", "Can convert warranty jobs to non-warranty jobs", false) },
{ "Job.Actions.Create", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.Create, (c, v) => c.Job.Actions.Create = v, "Create Jobs", "Can create jobs", false) }, { "Job.Actions.Create", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.Create, (c, v) => c.Job.Actions.Create = v, "Create Jobs", "Can create jobs", false) },
{ "Job.Actions.Delete", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.Delete, (c, v) => c.Job.Actions.Delete = v, "Delete Jobs", "Can delete jobs", false) }, { "Job.Actions.Delete", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.Delete, (c, v) => c.Job.Actions.Delete = v, "Delete Jobs", "Can delete jobs", false) },
{ "Job.Actions.Export", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.Export, (c, v) => c.Job.Actions.Export = v, "Export Jobs", "Can export jobs in a bulk format", false) },
{ "Job.Actions.ForceClose", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.ForceClose, (c, v) => c.Job.Actions.ForceClose = v, "Force Close Jobs", "Can force close jobs", false) }, { "Job.Actions.ForceClose", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.ForceClose, (c, v) => c.Job.Actions.ForceClose = v, "Force Close Jobs", "Can force close jobs", false) },
{ "Job.Actions.GenerateDocuments", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.GenerateDocuments, (c, v) => c.Job.Actions.GenerateDocuments = v, "Generate Documents", "Can generate documents for jobs", false) }, { "Job.Actions.GenerateDocuments", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.GenerateDocuments, (c, v) => c.Job.Actions.GenerateDocuments = v, "Generate Documents", "Can generate documents for jobs", false) },
{ "Job.Actions.LogInsurance", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.LogInsurance, (c, v) => c.Job.Actions.LogInsurance = v, "Log Insurance", "Can log insurance for non-warranty jobs", false) }, { "Job.Actions.LogInsurance", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.LogInsurance, (c, v) => c.Job.Actions.LogInsurance = v, "Lodge Insurance", "Can lodge insurance for non-warranty jobs", false) },
{ "Job.Actions.LogRepair", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.LogRepair, (c, v) => c.Job.Actions.LogRepair = v, "Log Repair", "Can log repair for non-warranty jobs", false) }, { "Job.Actions.LogRepair", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.LogRepair, (c, v) => c.Job.Actions.LogRepair = v, "Lodge Repair", "Can lodge repair for non-warranty jobs", false) },
{ "Job.Actions.LogWarranty", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.LogWarranty, (c, v) => c.Job.Actions.LogWarranty = v, "Log Warranty", "Can log warranty for jobs", false) }, { "Job.Actions.LogWarranty", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.LogWarranty, (c, v) => c.Job.Actions.LogWarranty = v, "Lodge Warranty", "Can lodge warranty for jobs", false) },
{ "Job.Actions.RemoveAnyAttachments", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.RemoveAnyAttachments, (c, v) => c.Job.Actions.RemoveAnyAttachments = v, "Remove Any Attachments", "Can remove any attachments from jobs", false) }, { "Job.Actions.RemoveAnyAttachments", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.RemoveAnyAttachments, (c, v) => c.Job.Actions.RemoveAnyAttachments = v, "Remove Any Attachments", "Can remove any attachments from jobs", false) },
{ "Job.Actions.RemoveAnyLogs", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.RemoveAnyLogs, (c, v) => c.Job.Actions.RemoveAnyLogs = v, "Remove Any Logs", "Can remove any job logs", false) }, { "Job.Actions.RemoveAnyLogs", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.RemoveAnyLogs, (c, v) => c.Job.Actions.RemoveAnyLogs = v, "Remove Any Logs", "Can remove any job logs", false) },
{ "Job.Actions.RemoveAnyQueues", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.RemoveAnyQueues, (c, v) => c.Job.Actions.RemoveAnyQueues = v, "Remove from Any Queues", "Can remove from any job queues", false) }, { "Job.Actions.RemoveAnyQueues", new Tuple<Func<RoleClaims, bool>, Action<RoleClaims, bool>, string, string, bool>(c => c.Job.Actions.RemoveAnyQueues, (c, v) => c.Job.Actions.RemoveAnyQueues = v, "Remove from Any Queues", "Can remove from any job queues", false) },
@@ -336,6 +337,7 @@ namespace Disco.Services.Authorization
new ClaimNavigatorItem("Job.Actions.ConvertHWarToHNWar", false), new ClaimNavigatorItem("Job.Actions.ConvertHWarToHNWar", false),
new ClaimNavigatorItem("Job.Actions.Create", false), new ClaimNavigatorItem("Job.Actions.Create", false),
new ClaimNavigatorItem("Job.Actions.Delete", false), new ClaimNavigatorItem("Job.Actions.Delete", false),
new ClaimNavigatorItem("Job.Actions.Export", false),
new ClaimNavigatorItem("Job.Actions.ForceClose", false), new ClaimNavigatorItem("Job.Actions.ForceClose", false),
new ClaimNavigatorItem("Job.Actions.GenerateDocuments", false), new ClaimNavigatorItem("Job.Actions.GenerateDocuments", false),
new ClaimNavigatorItem("Job.Actions.LogInsurance", false), new ClaimNavigatorItem("Job.Actions.LogInsurance", false),
@@ -647,6 +649,7 @@ namespace Disco.Services.Authorization
c.Job.Actions.ConvertHWarToHNWar = true; c.Job.Actions.ConvertHWarToHNWar = true;
c.Job.Actions.Create = true; c.Job.Actions.Create = true;
c.Job.Actions.Delete = true; c.Job.Actions.Delete = true;
c.Job.Actions.Export = true;
c.Job.Actions.ForceClose = true; c.Job.Actions.ForceClose = true;
c.Job.Actions.GenerateDocuments = true; c.Job.Actions.GenerateDocuments = true;
c.Job.Actions.LogInsurance = true; c.Job.Actions.LogInsurance = true;
@@ -1334,6 +1337,11 @@ namespace Disco.Services.Authorization
/// </summary> /// </summary>
public const string Delete = "Job.Actions.Delete"; public const string Delete = "Job.Actions.Delete";
/// <summary>Export Jobs
/// <para>Can export jobs in a bulk format</para>
/// </summary>
public const string Export = "Job.Actions.Export";
/// <summary>Force Close Jobs /// <summary>Force Close Jobs
/// <para>Can force close jobs</para> /// <para>Can force close jobs</para>
/// </summary> /// </summary>
@@ -1344,18 +1352,18 @@ namespace Disco.Services.Authorization
/// </summary> /// </summary>
public const string GenerateDocuments = "Job.Actions.GenerateDocuments"; public const string GenerateDocuments = "Job.Actions.GenerateDocuments";
/// <summary>Log Insurance /// <summary>Lodge Insurance
/// <para>Can log insurance for non-warranty jobs</para> /// <para>Can lodge insurance for non-warranty jobs</para>
/// </summary> /// </summary>
public const string LogInsurance = "Job.Actions.LogInsurance"; public const string LogInsurance = "Job.Actions.LogInsurance";
/// <summary>Log Repair /// <summary>Lodge Repair
/// <para>Can log repair for non-warranty jobs</para> /// <para>Can lodge repair for non-warranty jobs</para>
/// </summary> /// </summary>
public const string LogRepair = "Job.Actions.LogRepair"; public const string LogRepair = "Job.Actions.LogRepair";
/// <summary>Log Warranty /// <summary>Lodge Warranty
/// <para>Can log warranty for jobs</para> /// <para>Can lodge warranty for jobs</para>
/// </summary> /// </summary>
public const string LogWarranty = "Job.Actions.LogWarranty"; public const string LogWarranty = "Job.Actions.LogWarranty";
+1 -1
View File
@@ -7,7 +7,7 @@
<#@ assembly name="VSLangProj" #> <#@ assembly name="VSLangProj" #>
<#@ assembly name="System.Xml" #> <#@ assembly name="System.Xml" #>
<#@ assembly name="System.Xml.Linq" #> <#@ assembly name="System.Xml.Linq" #>
<#@ assembly name="C:\Windows\Microsoft.NET\Framework\v4.0.30319\CustomMarshalers.dll" #> <#@ assembly name="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\CustomMarshalers.dll" #>
<#@ import namespace="System.Collections.Generic" #> <#@ import namespace="System.Collections.Generic" #>
<#@ import namespace="System.IO" #> <#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #> <#@ import namespace="System.Linq" #>
@@ -52,5 +52,7 @@
[ClaimDetails("Update Sub Types", "Can update sub types for jobs")] [ClaimDetails("Update Sub Types", "Can update sub types for jobs")]
public bool UpdateSubTypes { get; set; } public bool UpdateSubTypes { get; set; }
[ClaimDetails("Export Jobs", "Can export jobs in a bulk format")]
public bool Export { get; set; }
} }
} }
+2
View File
@@ -381,6 +381,8 @@
<Compile Include="Interop\VicEduDept\VicSmart.cs" /> <Compile Include="Interop\VicEduDept\VicSmart.cs" />
<Compile Include="Interop\DiscoServices\UpdateQuery.cs" /> <Compile Include="Interop\DiscoServices\UpdateQuery.cs" />
<Compile Include="Interop\DiscoServices\UpdateQueryTask.cs" /> <Compile Include="Interop\DiscoServices\UpdateQueryTask.cs" />
<Compile Include="Jobs\Exporting\JobExport.cs" />
<Compile Include="Jobs\Exporting\JobExportTask.cs" />
<Compile Include="Jobs\JobActionExtensions.cs" /> <Compile Include="Jobs\JobActionExtensions.cs" />
<Compile Include="Jobs\JobExtensions.cs" /> <Compile Include="Jobs\JobExtensions.cs" />
<Compile Include="Jobs\JobFlagExtensions.cs" /> <Compile Include="Jobs\JobFlagExtensions.cs" />
@@ -15,6 +15,9 @@ namespace Disco.Services
{ {
public static ExportResult WriteExport<T>(IExportOptions options, IScheduledTaskStatus status, List<ExportFieldMetadata<T>> metadata, List<T> records) where T : IExportRecord public static ExportResult WriteExport<T>(IExportOptions options, IScheduledTaskStatus status, List<ExportFieldMetadata<T>> metadata, List<T> records) where T : IExportRecord
{ {
if (records.Count == 0)
return new ExportResult();
var filenameWithoutExtension = $"{options.FilenamePrefix}-{status.StartedTimestamp.Value:yyyyMMdd-HHmmss}"; var filenameWithoutExtension = $"{options.FilenamePrefix}-{status.StartedTimestamp.Value:yyyyMMdd-HHmmss}";
MemoryStream stream; MemoryStream stream;
string filename; string filename;
+402
View File
@@ -0,0 +1,402 @@
using Disco.Data.Repository;
using Disco.Models.Exporting;
using Disco.Models.Repository;
using Disco.Models.Services.Exporting;
using Disco.Models.Services.Jobs.Exporting;
using Disco.Services.Jobs.JobQueues;
using Disco.Services.Plugins.Features.DetailsProvider;
using Disco.Services.Tasks;
using Disco.Services.Users;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Data;
using System.Linq;
namespace Disco.Services.Jobs.Exporting
{
using Metadata = ExportFieldMetadata<JobExportRecord>;
public static class JobExport
{
public static ExportResult GenerateExport(DiscoDataContext database, Func<IQueryable<Job>, IQueryable<Job>> filter, JobExportOptions options, IScheduledTaskStatus taskStatus)
{
database.Configuration.LazyLoadingEnabled = false;
database.Configuration.ProxyCreationEnabled = false;
var jobQuery = (IQueryable<Job>)database.Jobs;
if (filter != null)
jobQuery = filter(jobQuery);
// Update Users
if (options.UserDisplayName ||
options.UserSurname ||
options.UserGivenName ||
options.UserPhoneNumber ||
options.UserEmailAddress)
{
taskStatus.UpdateStatus(5, "Refreshing user details from Active Directory");
var userIds = jobQuery.Where(d => d.UserId != null).Select(d => d.UserId).Distinct().ToList();
foreach (var userId in userIds)
{
try
{
UserService.GetUser(userId, database);
}
catch (Exception) { } // Ignore Errors
}
}
// Update Last Network Logon Date
if (options.DeviceLastNetworkLogon)
{
taskStatus.UpdateStatus(15, "Refreshing device last network logon dates from Active Directory");
try
{
Interop.ActiveDirectory.ADNetworkLogonDatesUpdateTask.UpdateLastNetworkLogonDates(database, ScheduledTaskMockStatus.Create("UpdateLastNetworkLogonDates"));
database.SaveChanges();
}
catch (Exception) { } // Ignore Errors
}
taskStatus.UpdateStatus(25, "Extracting records from the database");
var records = BuildRecords(jobQuery).ToList();
records.ForEach(r =>
{
if (options.JobStatus)
{
r.JobStatus = JobExtensions.CalculateStatusId(
r.Job.ClosedDate,
r.Job.JobTypeId,
r.JobMetaWarranty?.ExternalLoggedDate,
r.JobMetaWarranty?.ExternalCompletedDate,
r.JobMetaNonWarranty?.RepairerLoggedDate,
r.JobMetaNonWarranty?.RepairerCompletedDate,
r.JobMetaNonWarranty?.AccountingChargeRequiredDate,
r.JobMetaNonWarranty?.AccountingChargeAddedDate,
r.JobMetaNonWarranty?.AccountingChargePaidDate,
r.JobMetaNonWarranty?.IsInsuranceClaim,
r.JobMetaInsurance?.ClaimFormSentDate,
r.Job.WaitingForUserAction,
r.Job.DeviceReadyForReturn,
r.Job.DeviceReturnedDate);
}
if (options.UserDetailCustom && r.User != null)
{
var detailsService = new DetailsProviderService(database);
r.UserCustomDetails = detailsService.GetDetails(r.User);
}
});
taskStatus.UpdateStatus(70, "Building metadata");
var metadata = options.BuildMetadata(records);
if (metadata.Count == 0)
throw new ArgumentException("At least one export field must be specified", "Options");
taskStatus.UpdateStatus(80, $"Formatting {records.Count} records for export");
return ExportHelpers.WriteExport(options, taskStatus, metadata, records);
}
public static ExportResult GenerateExport(DiscoDataContext database, JobExportOptions options, IScheduledTaskStatus taskStatus)
{
Func<IQueryable<Job>, IQueryable<Job>> filter = q =>
{
var r = q.Where(j => j.OpenedDate >= options.FilterStartDate);
if (options.FilterEndDate.HasValue)
r = r.Where(j => j.OpenedDate <= options.FilterEndDate);
if (options.FilterJobTypeId != null)
r = r.Where(j => j.JobTypeId == options.FilterJobTypeId);
if (options.FilterJobSubTypeIds?.Any() ?? false)
r = r.Where(j => j.JobSubTypes.Any(st => options.FilterJobSubTypeIds.Contains(st.Id)));
if (options.FilterJobQueueId.HasValue)
r = r.Where(j => j.JobQueues.Any(jq => !jq.RemovedDate.HasValue && jq.JobQueueId == options.FilterJobQueueId));
if (options.FilterJobStatusId != null)
{
if (options.FilterJobStatusId != Job.JobStatusIds.Closed)
r = r.Where(j => j.ClosedDate == null);
switch (options.FilterJobStatusId)
{
case Job.JobStatusIds.Open:
// already filtered
break;
case Job.JobStatusIds.AwaitingAccountingPayment:
r = r.Where(j => j.JobTypeId == JobType.JobTypeIds.HNWar && j.JobMetaNonWarranty.AccountingChargeAddedDate != null && j.JobMetaNonWarranty.AccountingChargePaidDate == null);
break;
case Job.JobStatusIds.AwaitingAccountingCharge:
r = r.Where(j => j.JobTypeId == JobType.JobTypeIds.HNWar && j.JobMetaNonWarranty.AccountingChargeRequiredDate == null && (j.JobMetaNonWarranty.AccountingChargePaidDate != null || j.JobMetaNonWarranty.AccountingChargeAddedDate != null));
break;
case Job.JobStatusIds.AwaitingDeviceReturn:
r = r.Where(j => j.DeviceReadyForReturn != null && j.DeviceReturnedDate == null);
break;
case Job.JobStatusIds.AwaitingInsuranceProcessing:
r = r.Where(j => j.JobTypeId == JobType.JobTypeIds.HNWar && j.JobMetaNonWarranty.IsInsuranceClaim && j.JobMetaInsurance.ClaimFormSentDate == null);
break;
case Job.JobStatusIds.AwaitingRepairs:
r = r.Where(j => j.JobTypeId == JobType.JobTypeIds.HNWar && j.JobMetaNonWarranty.RepairerLoggedDate != null && j.JobMetaNonWarranty.RepairerCompletedDate == null);
break;
case Job.JobStatusIds.AwaitingUserAction:
r = r.Where(j => j.WaitingForUserAction != null);
break;
case Job.JobStatusIds.AwaitingWarrantyRepair:
r = r.Where(j => j.JobTypeId == JobType.JobTypeIds.HWar && j.JobMetaWarranty.ExternalLoggedDate != null && j.JobMetaWarranty.ExternalCompletedDate == null);
break;
case Job.JobStatusIds.Closed:
r = r.Where(j => j.ClosedDate != null);
break;
default:
throw new ArgumentException($"Unknown Job Status Id: {options.FilterJobStatusId}", nameof(options.FilterJobStatusId));
}
}
return r;
};
return GenerateExport(database, filter, options, taskStatus);
}
public static ExportResult GenerateExport(DiscoDataContext database, JobExportOptions options)
{
return GenerateExport(database, options, ScheduledTaskMockStatus.Create("Job Export"));
}
private static IEnumerable<JobExportRecord> BuildRecords(IQueryable<Job> jobs)
{
return jobs.Select(j => new JobExportRecord()
{
Job = j,
JobTypeDescription = j.JobType.Description,
JobSubTypeDescriptions = j.JobSubTypes.Select(st => st.Description),
LogCount = j.JobLogs.Count(),
FirstLog = j.JobLogs.OrderBy(l => l.Id).FirstOrDefault(),
LastLog = j.JobLogs.OrderByDescending(l => l.Id).FirstOrDefault(),
AttachmentsCount = j.JobAttachments.Count(),
QueueCount = j.JobQueues.Count(),
QueueActiveCount = j.JobQueues.Count(q => !q.RemovedDate.HasValue),
QueueLatestActive = j.JobQueues.Where(q => !q.RemovedDate.HasValue).OrderByDescending(q => q.Id).FirstOrDefault(),
JobMetaWarranty = j.JobMetaWarranty,
JobMetaNonWarranty = j.JobMetaNonWarranty,
JobMetaInsurance = j.JobMetaInsurance,
User = j.User,
Device = j.Device,
DeviceModelId = j.Device.DeviceModelId,
DeviceModelDescription = j.Device.DeviceModel.Description,
DeviceModelManufacturer = j.Device.DeviceModel.Manufacturer,
DeviceModelModel = j.Device.DeviceModel.Model,
DeviceModelType = j.Device.DeviceModel.ModelType,
DeviceBatchId = j.Device.DeviceBatchId,
DeviceBatchName = j.Device.DeviceBatch.Name,
DeviceBatchPurchaseDate = j.Device.DeviceBatch.PurchaseDate,
DeviceBatchSupplier = j.Device.DeviceBatch.Supplier,
DeviceBatchUnitCost = j.Device.DeviceBatch.UnitCost,
DeviceBatchWarrantyValidUntilDate = j.Device.DeviceBatch.WarrantyValidUntil,
DeviceBatchInsuredDate = j.Device.DeviceBatch.InsuredDate,
DeviceBatchInsuranceSupplier = j.Device.DeviceBatch.InsuranceSupplier,
DeviceBatchInsuredUntilDate = j.Device.DeviceBatch.InsuredUntil,
DeviceProfileId = j.Device.DeviceProfileId,
DeviceProfileName = j.Device.DeviceProfile.Name,
DeviceProfileShortName = j.Device.DeviceProfile.ShortName,
});
}
private static List<Metadata> BuildMetadata(this JobExportOptions options, List<JobExportRecord> records)
{
IEnumerable<string> userDetailCustomKeys = null;
if (options.UserDetailCustom)
userDetailCustomKeys = records.Where(r => r.UserCustomDetails != null).SelectMany(r => r.UserCustomDetails.Keys).Distinct(StringComparer.OrdinalIgnoreCase).ToList();
var allAccessors = BuildRecordAccessors(userDetailCustomKeys);
return typeof(JobExportOptions).GetProperties()
.Where(p => p.PropertyType == typeof(bool))
.Select(p => new
{
property = p,
details = (DisplayAttribute)p.GetCustomAttributes(typeof(DisplayAttribute), false).FirstOrDefault()
})
.Where(p => p.details != null && (bool)p.property.GetValue(options))
.SelectMany(p =>
{
var fieldMetadata = allAccessors[p.property.Name];
fieldMetadata.ForEach(f =>
{
if (f.ColumnName == null)
f.ColumnName = (p.details.ShortName == "Job" || p.details.ShortName == "Job Details") ? p.details.Name : $"{p.details.ShortName} {p.details.Name}";
});
return fieldMetadata;
}).ToList();
}
private static Dictionary<string, List<Metadata>> BuildRecordAccessors(IEnumerable<string> userDetailCustomKeys)
{
const string DateFormat = "yyyy-MM-dd";
const string DateTimeFormat = DateFormat + " HH:mm:ss";
Func<object, string> csvStringEncoded = (o) => o == null ? null : $"\"{((string)o).Replace("\"", "\"\"")}\"";
Func<object, string> csvToStringEncoded = (o) => o == null ? null : o.ToString();
Func<object, string> csvCurrencyEncoded = (o) => ((decimal?)o).HasValue ? ((decimal?)o).Value.ToString("C") : null;
Func<object, string> csvDateEncoded = (o) => ((DateTime)o).ToString(DateFormat);
Func<object, string> csvDateTimeEncoded = (o) => ((DateTime)o).ToString(DateTimeFormat);
Func<object, string> csvNullableDateEncoded = (o) => ((DateTime?)o).HasValue ? csvDateEncoded(o) : null;
Func<object, string> csvNullableDateTimeEncoded = (o) => ((DateTime?)o).HasValue ? csvDateTimeEncoded(o) : null;
var metadata = new Dictionary<string, List<Metadata>>();
// Job
metadata.Add(nameof(JobExportOptions.JobId), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobId), typeof(int), r => r.Job.Id, csvToStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobStatus), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobStatus), typeof(string), r => Job.JobStatusIds.StatusDescriptions.TryGetValue(r.JobStatus, out var status) ? status : "Unknown", csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobType), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobType), typeof(string), r => r.JobTypeDescription, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobSubTypes), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobSubTypes), typeof(string), r => string.Join(", ", r.JobSubTypeDescriptions), csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobOpenedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobOpenedDate), typeof(DateTime), r => r.Job.OpenedDate, csvDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobOpenedUser), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobOpenedUser), typeof(string), r => r.Job.OpenedTechUserId, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobExpectedClosedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobExpectedClosedDate), typeof(DateTime), r => r.Job.ExpectedClosedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobClosedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobClosedDate), typeof(DateTime), r => r.Job.ClosedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobClosedUser), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobClosedUser), typeof(string), r => r.Job.ClosedTechUserId, csvStringEncoded) });
// Job Details
metadata.Add(nameof(JobExportOptions.JobDeviceHeldDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobDeviceHeldDate), typeof(DateTime), r => r.Job.DeviceHeld, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobDeviceHeldUser), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobDeviceHeldUser), typeof(string), r => r.Job.DeviceHeldTechUserId, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobDeviceHeldLocation), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobDeviceHeldLocation), typeof(string), r => r.Job.DeviceHeldLocation, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobDeviceReadyForReturnDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobDeviceReadyForReturnDate), typeof(DateTime), r => r.Job.DeviceReadyForReturn, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobDeviceReadyForReturnUser), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobDeviceReadyForReturnUser), typeof(string), r => r.Job.DeviceReadyForReturnTechUserId, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobDeviceReturnedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobDeviceReturnedDate), typeof(DateTime), r => r.Job.DeviceReturnedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobDeviceReturnedUser), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobDeviceReturnedUser), typeof(string), r => r.Job.DeviceReturnedTechUserId, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobWaitingForUserActionDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobWaitingForUserActionDate), typeof(DateTime), r => r.Job.WaitingForUserAction, csvNullableDateTimeEncoded) });
// Job Logs
metadata.Add(nameof(JobExportOptions.LogCount), new List<Metadata>() { new Metadata(nameof(JobExportOptions.LogCount), typeof(int), r => r.LogCount, csvToStringEncoded) });
metadata.Add(nameof(JobExportOptions.LogFirstDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.LogFirstDate), typeof(DateTime), r => r.FirstLog?.Timestamp, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.LogFirstUser), new List<Metadata>() { new Metadata(nameof(JobExportOptions.LogFirstUser), typeof(string), r => r.FirstLog?.TechUserId, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.LogFirstContent), new List<Metadata>() { new Metadata(nameof(JobExportOptions.LogFirstContent), typeof(string), r => r.FirstLog?.Comments, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.LogLastDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.LogLastDate), typeof(DateTime), r => r.LastLog?.Timestamp, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.LogLastUser), new List<Metadata>() { new Metadata(nameof(JobExportOptions.LogLastUser), typeof(string), r => r.LastLog?.TechUserId, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.LogLastContent), new List<Metadata>() { new Metadata(nameof(JobExportOptions.LogLastContent), typeof(string), r => r.LastLog?.Comments, csvStringEncoded) });
// Attachments
metadata.Add(nameof(JobExportOptions.AttachmentsCount), new List<Metadata>() { new Metadata(nameof(JobExportOptions.AttachmentsCount), typeof(int), r => r.AttachmentsCount, csvToStringEncoded) });
// Job Queues
metadata.Add(nameof(JobExportOptions.JobQueueCount), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobQueueCount), typeof(int), r => r.QueueCount, csvToStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobQueueActiveCount), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobQueueActiveCount), typeof(int), r => r.QueueActiveCount, csvToStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobQueueActiveLatest), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobQueueActiveLatest), typeof(DateTime), r => r.QueueLatestActive?.JobQueueId == null ? null : JobQueueService.GetQueue(r.QueueLatestActive.JobQueueId).JobQueue.Name, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobQueueActiveLatestAddedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobQueueActiveLatestAddedDate), typeof(DateTime), r => r.QueueLatestActive?.AddedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobQueueActiveLatestAddedUser), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobQueueActiveLatestAddedUser), typeof(string), r => r.QueueLatestActive?.AddedUserId, csvStringEncoded) });
// Warranty
metadata.Add(nameof(JobExportOptions.JobWarrantyExternalName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobWarrantyExternalName), typeof(string), r => r.JobMetaWarranty?.ExternalName, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobWarrantyExternalReference), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobWarrantyExternalReference), typeof(string), r => r.JobMetaWarranty?.ExternalReference, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobWarrantyExternalLoggedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobWarrantyExternalLoggedDate), typeof(DateTime), r => r.JobMetaWarranty?.ExternalLoggedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobWarrantyExternalCompletedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobWarrantyExternalCompletedDate), typeof(DateTime), r => r.JobMetaWarranty?.ExternalCompletedDate, csvNullableDateTimeEncoded) });
// Non-Warranty
metadata.Add(nameof(JobExportOptions.JobNonWarrantyAccountingChargeRequiredDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyAccountingChargeRequiredDate), typeof(DateTime), r => r.JobMetaNonWarranty?.AccountingChargeRequiredDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyAccountingChargeAddedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyAccountingChargeAddedDate), typeof(DateTime), r => r.JobMetaNonWarranty?.AccountingChargeAddedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyAccountingChargePaidDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyAccountingChargePaidDate), typeof(DateTime), r => r.JobMetaNonWarranty?.AccountingChargePaidDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyPurchaseOrderRaisedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyPurchaseOrderRaisedDate), typeof(DateTime), r => r.JobMetaNonWarranty?.PurchaseOrderRaisedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyPurchaseOrderReference), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyPurchaseOrderReference), typeof(string), r => r.JobMetaNonWarranty?.PurchaseOrderReference, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyPurchaseOrderSentDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyPurchaseOrderSentDate), typeof(DateTime), r => r.JobMetaNonWarranty?.PurchaseOrderSentDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyInvoiceReceivedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyInvoiceReceivedDate), typeof(DateTime), r => r.JobMetaNonWarranty?.InvoiceReceivedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyRepairerName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyRepairerName), typeof(string), r => r.JobMetaNonWarranty?.RepairerName, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyRepairerLoggedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyRepairerLoggedDate), typeof(DateTime), r => r.JobMetaNonWarranty?.RepairerLoggedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyRepairerReference), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyRepairerReference), typeof(string), r => r.JobMetaNonWarranty?.RepairerReference, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobNonWarrantyRepairerCompletedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobNonWarrantyRepairerCompletedDate), typeof(DateTime), r => r.JobMetaNonWarranty?.RepairerCompletedDate, csvNullableDateTimeEncoded) });
// Insurance
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceLossOrDamageDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceLossOrDamageDate), typeof(DateTime), r => r.JobMetaInsurance?.LossOrDamageDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceEventLocation), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceEventLocation), typeof(string), r => r.JobMetaInsurance?.EventLocation, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceDescription), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceDescription), typeof(string), r => r.JobMetaInsurance?.Description, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceThirdPartyCausedName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceThirdPartyCausedName), typeof(string), r => r.JobMetaInsurance?.ThirdPartyCausedName, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceThirdPartyCausedWhy), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceThirdPartyCausedWhy), typeof(string), r => r.JobMetaInsurance?.ThirdPartyCausedWhy, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceWitnessesNamesAddresses), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceWitnessesNamesAddresses), typeof(string), r => r.JobMetaInsurance?.WitnessesNamesAddresses, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceBurglaryTheftMethodOfEntry), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceBurglaryTheftMethodOfEntry), typeof(string), r => r.JobMetaInsurance?.BurglaryTheftMethodOfEntry, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsurancePropertyLastSeenDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsurancePropertyLastSeenDate), typeof(DateTime), r => r.JobMetaInsurance?.PropertyLastSeenDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsurancePoliceNotifiedStation), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsurancePoliceNotifiedStation), typeof(string), r => r.JobMetaInsurance?.PoliceNotifiedStation, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsurancePoliceNotifiedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsurancePoliceNotifiedDate), typeof(DateTime), r => r.JobMetaInsurance?.PoliceNotifiedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsurancePoliceNotifiedCrimeReportNo), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsurancePoliceNotifiedCrimeReportNo), typeof(string), r => r.JobMetaInsurance?.PoliceNotifiedCrimeReportNo, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceRecoverReduceAction), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceRecoverReduceAction), typeof(string), r => r.JobMetaInsurance?.RecoverReduceAction, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceOtherInterestedParties), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceOtherInterestedParties), typeof(string), r => r.JobMetaInsurance?.OtherInterestedParties, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceDateOfPurchase), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceDateOfPurchase), typeof(DateTime), r => r.JobMetaInsurance?.DateOfPurchase, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceClaimFormSentDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceClaimFormSentDate), typeof(DateTime), r => r.JobMetaInsurance?.ClaimFormSentDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceInsurer), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceInsurer), typeof(string), r => r.JobMetaInsurance?.Insurer, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.JobMetaInsuranceInsurerReference), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobMetaInsuranceInsurerReference), typeof(string), r => r.JobMetaInsurance?.InsurerReference, csvStringEncoded) });
// User Management
metadata.Add(nameof(JobExportOptions.JobUserManagementFlags), new List<Metadata>() { new Metadata(nameof(JobExportOptions.JobUserManagementFlags), typeof(string), r => r.Job.Flags, csvToStringEncoded) });
// User
metadata.Add(nameof(JobExportOptions.UserId), new List<Metadata>() { new Metadata(nameof(JobExportOptions.UserId), typeof(string), r => r.User?.UserId, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.UserDisplayName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.UserDisplayName), typeof(string), r => r.User?.DisplayName, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.UserSurname), new List<Metadata>() { new Metadata(nameof(JobExportOptions.UserSurname), typeof(string), r => r.User?.Surname, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.UserGivenName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.UserGivenName), typeof(string), r => r.User?.GivenName, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.UserPhoneNumber), new List<Metadata>() { new Metadata(nameof(JobExportOptions.UserPhoneNumber), typeof(string), r => r.User?.PhoneNumber, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.UserEmailAddress), new List<Metadata>() { new Metadata(nameof(JobExportOptions.UserEmailAddress), typeof(string), r => r.User?.EmailAddress, csvStringEncoded) });
if (userDetailCustomKeys != null)
{
var assignedUserDetailCustomFields = new List<Metadata>();
foreach (var detailKey in userDetailCustomKeys.OrderBy(k => k, StringComparer.OrdinalIgnoreCase))
{
var key = detailKey;
assignedUserDetailCustomFields.Add(new Metadata(detailKey, detailKey, typeof(string), r => r.UserCustomDetails != null && r.UserCustomDetails.TryGetValue(key, out var value) ? value : null, csvStringEncoded));
}
metadata.Add(nameof(JobExportOptions.UserDetailCustom), assignedUserDetailCustomFields);
}
// Device
metadata.Add(nameof(JobExportOptions.DeviceSerialNumber), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceSerialNumber), typeof(string), r => r.Device?.SerialNumber, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceAssetNumber), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceAssetNumber), typeof(string), r => r.Device?.AssetNumber, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceLocation), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceLocation), typeof(string), r => r.Device?.Location, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceComputerName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceComputerName), typeof(string), r => r.Device?.DeviceDomainId, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceLastNetworkLogon), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceLastNetworkLogon), typeof(DateTime), r => r.Device?.LastNetworkLogonDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceCreatedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceCreatedDate), typeof(DateTime), r => r.Device?.CreatedDate, csvDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceFirstEnrolledDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceFirstEnrolledDate), typeof(DateTime), r => r.Device?.EnrolledDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceLastEnrolledDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceLastEnrolledDate), typeof(DateTime), r => r.Device?.LastEnrolDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceAllowUnauthenticatedEnrol), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceAllowUnauthenticatedEnrol), typeof(bool), r => r.Device?.AllowUnauthenticatedEnrol, csvToStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceDecommissionedDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceDecommissionedDate), typeof(DateTime), r => r.Device?.DecommissionedDate, csvNullableDateTimeEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceDecommissionedReason), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceDecommissionedReason), typeof(string), r => r.Device?.DecommissionReason, csvToStringEncoded) });
// Model
metadata.Add(nameof(JobExportOptions.DeviceModelId), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceModelId), typeof(int), r => r.DeviceModelId, csvToStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceModelDescription), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceModelDescription), typeof(string), r => r.DeviceModelDescription, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceModelManufacturer), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceModelManufacturer), typeof(string), r => r.DeviceModelManufacturer, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceModelModel), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceModelModel), typeof(string), r => r.DeviceModelModel, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceModelType), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceModelType), typeof(string), r => r.DeviceModelType, csvStringEncoded) });
// Batch
metadata.Add(nameof(JobExportOptions.DeviceBatchId), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchId), typeof(int), r => r.DeviceBatchId, csvToStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceBatchName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchName), typeof(string), r => r.DeviceBatchName, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceBatchPurchaseDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchPurchaseDate), typeof(DateTime), r => r.DeviceBatchPurchaseDate, csvNullableDateEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceBatchSupplier), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchSupplier), typeof(string), r => r.DeviceBatchSupplier, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceBatchUnitCost), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchUnitCost), typeof(decimal), r => r.DeviceBatchUnitCost, csvCurrencyEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceBatchWarrantyValidUntilDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchWarrantyValidUntilDate), typeof(DateTime), r => r.DeviceBatchWarrantyValidUntilDate, csvNullableDateEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceBatchInsuredDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchInsuredDate), typeof(DateTime), r => r.DeviceBatchInsuredDate, csvNullableDateEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceBatchInsuranceSupplier), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchInsuranceSupplier), typeof(string), r => r.DeviceBatchInsuranceSupplier, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceBatchInsuredUntilDate), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceBatchInsuredUntilDate), typeof(DateTime), r => r.DeviceBatchInsuredUntilDate, csvNullableDateEncoded) });
// Profile
metadata.Add(nameof(JobExportOptions.DeviceProfileId), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceProfileId), typeof(int), r => r.DeviceProfileId, csvToStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceProfileName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceProfileName), typeof(string), r => r.DeviceProfileName, csvStringEncoded) });
metadata.Add(nameof(JobExportOptions.DeviceProfileShortName), new List<Metadata>() { new Metadata(nameof(JobExportOptions.DeviceProfileShortName), typeof(string), r => r.DeviceProfileShortName, csvStringEncoded) });
return metadata;
}
}
}
@@ -0,0 +1,44 @@
using Disco.Data.Repository;
using Disco.Models.Services.Jobs.Exporting;
using Disco.Services.Exporting;
using Disco.Services.Tasks;
using Quartz;
namespace Disco.Services.Jobs.Exporting
{
public class JobExportTask : ScheduledTask
{
private const string JobDataMapContext = "Context";
public override string TaskName { get { return "Export Jobs"; } }
public override bool SingleInstanceTask { get { return false; } }
public override bool CancelInitiallySupported { get { return false; } }
public static ExportTaskContext<JobExportOptions> ScheduleNow(JobExportOptions Options)
{
// Build Context
var context = new ExportTaskContext<JobExportOptions>(Options);
// Build Data Map
var task = new JobExportTask();
JobDataMap taskData = new JobDataMap() { { JobDataMapContext, context} };
// Schedule Task
context.TaskStatus = task.ScheduleTask(taskData);
return context;
}
protected override void ExecuteTask()
{
var context = (ExportTaskContext<JobExportOptions>)ExecutionContext.JobDetail.JobDataMap[JobDataMapContext];
Status.UpdateStatus(10, "Exporting Job Records", "Starting...");
using (DiscoDataContext Database = new DiscoDataContext())
{
context.Result = JobExport.GenerateExport(Database, context.Options, Status);
}
}
}
}
+88 -83
View File
@@ -81,116 +81,121 @@ namespace Disco.Services
return i; return i;
} }
public static string JobStatusDescription(string StatusId, Job j = null) public static string JobStatusDescription(string StatusId, Job j)
{ => JobStatusDescription(StatusId, j?.DeviceHeld, j?.JobMetaWarranty?.ExternalName, j?.JobMetaNonWarranty?.RepairerName);
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) public static string JobStatusDescription(string StatusId, JobTableStatusItemModel j)
=> JobStatusDescription(StatusId, j?.DeviceHeld, j?.JobMetaWarranty_ExternalName, j?.JobMetaNonWarranty_RepairerName);
public static string JobStatusDescription(string statusId, DateTime? deviceHeld = null, string warrantyExternalName = null, string nonWarrantyRepairerName = null)
{ {
switch (StatusId) if (!Job.JobStatusIds.StatusDescriptions.TryGetValue(statusId, out var statusDescription))
{
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"; return "Unknown";
switch (statusId)
{
case Job.JobStatusIds.AwaitingWarrantyRepair:
var warrantyName = string.Empty;
if (!string.IsNullOrWhiteSpace(warrantyExternalName))
warrantyName = $" ({warrantyExternalName})";
if (deviceHeld.HasValue)
return statusDescription + warrantyName;
else
return $"{statusDescription} - Not Held{warrantyExternalName}";
case Job.JobStatusIds.AwaitingRepairs:
var repairerName = string.Empty;
if (!string.IsNullOrWhiteSpace(nonWarrantyRepairerName))
repairerName = $" ({nonWarrantyRepairerName})";
if (deviceHeld.HasValue)
return statusDescription + repairerName;
else
return $"{statusDescription} - Not Held{repairerName}";
default:
return statusDescription;
} }
} }
public static string CalculateStatusId(this Job j) public static string CalculateStatusId(this Job j)
{ {
return j.ToJobTableStatusItemModel().CalculateStatusId(); return CalculateStatusId(
j.ClosedDate,
j.JobTypeId,
j.JobMetaWarranty?.ExternalLoggedDate,
j.JobMetaWarranty?.ExternalCompletedDate,
j.JobMetaNonWarranty?.RepairerLoggedDate,
j.JobMetaNonWarranty?.RepairerCompletedDate,
j.JobMetaNonWarranty?.AccountingChargeRequiredDate,
j.JobMetaNonWarranty?.AccountingChargeAddedDate,
j.JobMetaNonWarranty?.AccountingChargePaidDate,
j.JobMetaNonWarranty?.IsInsuranceClaim,
j.JobMetaInsurance?.ClaimFormSentDate,
j.WaitingForUserAction,
j.DeviceReadyForReturn,
j.DeviceReturnedDate);
} }
public static string CalculateStatusId(this JobTableStatusItemModel j) public static string CalculateStatusId(this JobTableStatusItemModel j)
{ {
if (j.ClosedDate.HasValue) return CalculateStatusId(
j.ClosedDate,
j.JobTypeId,
j.JobMetaWarranty_ExternalLoggedDate,
j.JobMetaWarranty_ExternalCompletedDate,
j.JobMetaNonWarranty_RepairerLoggedDate,
j.JobMetaNonWarranty_RepairerCompletedDate,
j.JobMetaNonWarranty_AccountingChargeRequiredDate,
j.JobMetaNonWarranty_AccountingChargeAddedDate,
j.JobMetaNonWarranty_AccountingChargePaidDate,
j.JobMetaNonWarranty_IsInsuranceClaim,
j.JobMetaInsurance_ClaimFormSentDate,
j.WaitingForUserAction,
j.DeviceReadyForReturn,
j.DeviceReturnedDate);
}
public static string CalculateStatusId(
DateTime? closedDate,
string jobTypeId,
DateTime? warrantyExternallyLoggedDate,
DateTime? warrantyExternallyCompletedDate,
DateTime? nonWarrantyRepairerLoggedDate,
DateTime? nonWarrantyRepairerCompletedDate,
DateTime? nonWarrantyAccountingChargeRequiredDate,
DateTime? nonWarrantyAccountintChargeAddedDate,
DateTime? nonWarrantyAccountintChargePaidDate,
bool? nonWarrantyIsInsuranceClaim,
DateTime? insuranceClaimFormSentDate,
DateTime? waitingForUserActionDate,
DateTime? deviceReadyForReturnDate,
DateTime? deviceReturnedDate)
{
if (closedDate.HasValue)
return Job.JobStatusIds.Closed; return Job.JobStatusIds.Closed;
if (j.JobTypeId == JobType.JobTypeIds.HWar) if (jobTypeId == JobType.JobTypeIds.HWar)
{ {
if (j.JobMetaWarranty_ExternalLoggedDate.HasValue && !j.JobMetaWarranty_ExternalCompletedDate.HasValue) if (warrantyExternallyLoggedDate.HasValue && !warrantyExternallyCompletedDate.HasValue)
return Job.JobStatusIds.AwaitingWarrantyRepair; // Job Logged - but not marked as completed return Job.JobStatusIds.AwaitingWarrantyRepair; // Job Logged - but not marked as completed
} }
if (j.JobTypeId == JobType.JobTypeIds.HNWar) if (jobTypeId == JobType.JobTypeIds.HNWar)
{ {
if (j.JobMetaNonWarranty_RepairerLoggedDate.HasValue && !j.JobMetaNonWarranty_RepairerCompletedDate.HasValue) if (nonWarrantyRepairerLoggedDate.HasValue && !nonWarrantyRepairerCompletedDate.HasValue)
return Job.JobStatusIds.AwaitingRepairs; // Repairs logged - but not complete return Job.JobStatusIds.AwaitingRepairs; // Repairs logged - but not complete
if (j.JobMetaNonWarranty_AccountingChargeAddedDate.HasValue && !j.JobMetaNonWarranty_AccountingChargePaidDate.HasValue) if (nonWarrantyAccountintChargeAddedDate.HasValue && !nonWarrantyAccountintChargePaidDate.HasValue)
return Job.JobStatusIds.AwaitingAccountingPayment; // Accounting Charge Added, but not paid return Job.JobStatusIds.AwaitingAccountingPayment; // Accounting Charge Added, but not paid
if (j.JobMetaNonWarranty_AccountingChargeRequiredDate.HasValue && (!j.JobMetaNonWarranty_AccountingChargePaidDate.HasValue || !j.JobMetaNonWarranty_AccountingChargeAddedDate.HasValue)) if (nonWarrantyAccountingChargeRequiredDate.HasValue && (!nonWarrantyAccountintChargePaidDate.HasValue || !nonWarrantyAccountintChargeAddedDate.HasValue))
return Job.JobStatusIds.AwaitingAccountingCharge; // Accounting Charge Required, but not added or paid 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) if (nonWarrantyRepairerLoggedDate.HasValue && nonWarrantyIsInsuranceClaim.GetValueOrDefault() && !insuranceClaimFormSentDate.HasValue)
return Job.JobStatusIds.AwaitingInsuranceProcessing; // Is insurance claim, but no Claim Form Sent return Job.JobStatusIds.AwaitingInsuranceProcessing; // Is insurance claim, but no Claim Form Sent
} }
if (j.WaitingForUserAction.HasValue) if (waitingForUserActionDate.HasValue)
return Job.JobStatusIds.AwaitingUserAction; // Awaiting for User return Job.JobStatusIds.AwaitingUserAction; // Awaiting for User
if (j.DeviceReadyForReturn.HasValue && !j.DeviceReturnedDate.HasValue) if (deviceReadyForReturnDate.HasValue && !deviceReturnedDate.HasValue)
return Job.JobStatusIds.AwaitingDeviceReturn; // Device not returned to User return Job.JobStatusIds.AwaitingDeviceReturn; // Device not returned to User
return Job.JobStatusIds.Open; return Job.JobStatusIds.Open;
@@ -1,7 +1,7 @@
using Disco.Data.Repository; using Disco.Data.Repository;
using Disco.Data.Repository.Monitor; using Disco.Data.Repository.Monitor;
using Disco.Models.Repository; using Disco.Models.Repository;
using Disco.Models.Services.Job.Statistics; using Disco.Models.Services.Jobs.Statistics;
using Disco.Services.Tasks; using Disco.Services.Tasks;
using Quartz; using Quartz;
using System; using System;
@@ -111,6 +111,7 @@
<Compile Include="MvcExtensions\PartialCompiled\PartialCompiledHtmlExtensions.cs" /> <Compile Include="MvcExtensions\PartialCompiled\PartialCompiledHtmlExtensions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="MvcExtensions\XmlResult.cs" /> <Compile Include="MvcExtensions\XmlResult.cs" />
<Compile Include="RazorExtensions\DropDownListExtensions.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Disco.BI\Disco.BI.csproj"> <ProjectReference Include="..\Disco.BI\Disco.BI.csproj">
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc.Html;
using System.Web.Mvc;
namespace Disco.Web.Extensions
{
public static class DropDownListExtensions
{
public static MvcHtmlString DropDownListFor<TModel, TObject, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Func<TModel, IEnumerable<TObject>> source, Func<TObject, string> valueGenerator, Func<TObject, string> textGenerator, string instructionMessage = null)
{
var selectList = source(htmlHelper.ViewData.Model)
.Select(i => new SelectListItem() { Value = valueGenerator(i), Text = textGenerator(i) });
if (instructionMessage != null)
{
selectList = new SelectListItem[]
{ new SelectListItem { Text = instructionMessage, Value = string.Empty } }
.Concat(selectList);
}
return htmlHelper.DropDownListFor(expression, selectList);
}
}
}
@@ -693,6 +693,7 @@ namespace Disco.Web.Areas.API.Controllers
internal const string ExportSessionCacheKey = "DeviceExportContext_{0}"; internal const string ExportSessionCacheKey = "DeviceExportContext_{0}";
[DiscoAuthorize(Claims.Device.Actions.Export)] [DiscoAuthorize(Claims.Device.Actions.Export)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult Export(ExportModel Model) public virtual ActionResult Export(ExportModel Model)
{ {
if (Model == null || Model.Options == null) if (Model == null || Model.Options == null)
@@ -734,6 +735,9 @@ namespace Disco.Web.Areas.API.Controllers
if (context.Result == null || context.Result.Result == null) if (context.Result == null || context.Result.Result == null)
throw new ArgumentException("The export session is still running, or failed to complete successfully", "Id"); throw new ArgumentException("The export session is still running, or failed to complete successfully", "Id");
if (context.Result.RecordCount == 0)
throw new ArgumentException("No records were found to export", nameof(Id));
var fileStream = context.Result.Result; var fileStream = context.Result.Result;
return this.File(fileStream.GetBuffer(), 0, (int)fileStream.Length, context.Result.MimeType, context.Result.Filename); return this.File(fileStream.GetBuffer(), 0, (int)fileStream.Length, context.Result.MimeType, context.Result.Filename);
@@ -444,6 +444,9 @@ namespace Disco.Web.Areas.API.Controllers
if (context.Result == null || context.Result.Result == null) if (context.Result == null || context.Result.Result == null)
throw new ArgumentException("The export session is still running, or failed to complete successfully", nameof(Id)); throw new ArgumentException("The export session is still running, or failed to complete successfully", nameof(Id));
if (context.Result.RecordCount == 0)
throw new ArgumentException("No records were found to export", nameof(Id));
var fileStream = context.Result.Result; var fileStream = context.Result.Result;
return this.File(fileStream.GetBuffer(), 0, (int)fileStream.Length, context.Result.MimeType, context.Result.Filename); return this.File(fileStream.GetBuffer(), 0, (int)fileStream.Length, context.Result.MimeType, context.Result.Filename);
@@ -1,18 +1,25 @@
using Disco.Models.Repository; using Disco.Models.Repository;
using Disco.Models.Services.Job; using Disco.Models.Services.Jobs;
using Disco.Models.Services.Jobs.Exporting;
using Disco.Models.Services.Jobs.JobLists; using Disco.Models.Services.Jobs.JobLists;
using Disco.Services; using Disco.Services;
using Disco.Services.Authorization; using Disco.Services.Authorization;
using Disco.Services.Exporting;
using Disco.Services.Interop; using Disco.Services.Interop;
using Disco.Services.Jobs.Exporting;
using Disco.Services.Jobs.JobLists; using Disco.Services.Jobs.JobLists;
using Disco.Services.Jobs.Statistics; using Disco.Services.Jobs.Statistics;
using Disco.Services.Users; using Disco.Services.Users;
using Disco.Services.Web; using Disco.Services.Web;
using Disco.Web.Extensions;
using Disco.Web.Models.Job;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Entity; using System.Data.Entity;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Web;
using System.Web.Caching;
using System.Web.Mvc; using System.Web.Mvc;
namespace Disco.Web.Areas.API.Controllers namespace Disco.Web.Areas.API.Controllers
@@ -2152,5 +2159,62 @@ namespace Disco.Web.Areas.API.Controllers
return Json(results, JsonRequestBehavior.AllowGet); return Json(results, JsonRequestBehavior.AllowGet);
} }
#region Exporting
internal const string ExportSessionCacheKey = "JobExportContext_{0}";
[DiscoAuthorize(Claims.Job.Actions.Export)]
[HttpPost, ValidateAntiForgeryToken]
public virtual ActionResult Export(ExportModel model)
{
if (model == null || model.Options == null)
throw new ArgumentNullException(nameof(model));
// Write Options to Configuration
Database.DiscoConfiguration.JobPreferences.LastExportOptions = model.Options;
Database.SaveChanges();
// Start Export
var exportContext = JobExportTask.ScheduleNow(model.Options);
// Store Export Context in Web Cache
string key = string.Format(ExportSessionCacheKey, exportContext.TaskStatus.SessionId);
HttpRuntime.Cache.Insert(key, exportContext, null, DateTime.Now.AddMinutes(60), Cache.NoSlidingExpiration, CacheItemPriority.NotRemovable, null);
// Set Task Finished Url
var finishedActionResult = MVC.Job.Export(exportContext.TaskStatus.SessionId);
exportContext.TaskStatus.SetFinishedUrl(Url.Action(finishedActionResult));
// Try waiting for completion
if (exportContext.TaskStatus.WaitUntilFinished(TimeSpan.FromSeconds(2)))
return RedirectToAction(finishedActionResult);
else
return RedirectToAction(MVC.Config.Logging.TaskStatus(exportContext.TaskStatus.SessionId));
}
[DiscoAuthorize(Claims.Job.Actions.Export)]
public virtual ActionResult ExportRetrieve(string id)
{
if (string.IsNullOrWhiteSpace(id))
throw new ArgumentNullException("Id");
string key = string.Format(ExportSessionCacheKey, id);
var context = HttpRuntime.Cache.Get(key) as ExportTaskContext<JobExportOptions>;
if (context == null)
throw new ArgumentException("The Id specified is invalid, or the export data expired (60 minutes)", nameof(id));
if (context.Result == null || context.Result.Result == null)
throw new ArgumentException("The export session is still running, or failed to complete successfully", nameof(id));
if (context.Result.RecordCount == 0)
throw new ArgumentException("No records were found to export", nameof(id));
var fileStream = context.Result.Result;
return this.File(fileStream.GetBuffer(), 0, (int)fileStream.Length, context.Result.MimeType, context.Result.Filename);
}
#endregion
} }
} }
@@ -1,4 +1,4 @@
using Disco.Models.Services.Job; using Disco.Models.Services.Jobs;
using Disco.Services.Authorization; using Disco.Services.Authorization;
using Disco.Services.Jobs; using Disco.Services.Jobs;
using Disco.Services.Web; using Disco.Services.Web;
@@ -449,6 +449,9 @@ namespace Disco.Web.Areas.API.Controllers
if (context.Result == null || context.Result.Result == null) if (context.Result == null || context.Result.Result == null)
throw new ArgumentException("The export session is still running, or failed to complete successfully", nameof(Id)); throw new ArgumentException("The export session is still running, or failed to complete successfully", nameof(Id));
if (context.Result.RecordCount == 0)
throw new ArgumentException("No records were found to export", nameof(Id));
var fileStream = context.Result.Result; var fileStream = context.Result.Result;
return this.File(fileStream.GetBuffer(), 0, (int)fileStream.Length, context.Result.MimeType, context.Result.Filename); return this.File(fileStream.GetBuffer(), 0, (int)fileStream.Length, context.Result.MimeType, context.Result.Filename);
@@ -1,5 +1,5 @@
using Disco.Data.Repository; using Disco.Data.Repository;
using Disco.Models.Services.Job; using Disco.Models.Services.Jobs;
using Disco.Models.UI.Config.JobPreferences; using Disco.Models.UI.Config.JobPreferences;
using Disco.Services.Extensions; using Disco.Services.Extensions;
using System; using System;
@@ -71,7 +71,8 @@
@foreach (var optionItem in optionFields.Take(itemsPerColumn)) @foreach (var optionItem in optionFields.Take(itemsPerColumn))
{ {
<li title="@optionItem.Description"> <li title="@optionItem.Description">
<input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null)/><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label></li> <input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null) /><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label>
</li>
} }
</ul> </ul>
</td> </td>
@@ -80,7 +81,8 @@
@foreach (var optionItem in optionFields.Skip(itemsPerColumn)) @foreach (var optionItem in optionFields.Skip(itemsPerColumn))
{ {
<li title="@optionItem.Description"> <li title="@optionItem.Description">
<input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null)/><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label></li> <input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null) /><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label>
</li>
} }
</ul> </ul>
</td> </td>
@@ -89,6 +91,7 @@
</div> </div>
</td> </td>
</tr> </tr>
} }
</table> </table>
</div> </div>
@@ -161,8 +164,15 @@
@if (Model.ExportSessionId != null) @if (Model.ExportSessionId != null)
{ {
<div id="DeviceFlag_Export_Download_Dialog" class="dialog" title="Export Device Flags"> <div id="DeviceFlag_Export_Download_Dialog" class="dialog" title="Export Device Flags">
@if (Model.ExportSessionResult.RecordCount == 0)
{
<h4>No records matched the filter criteria</h4>
}
else
{
<h4>@Model.ExportSessionResult.RecordCount record@(Model.ExportSessionResult.RecordCount != 1 ? "s" : null) were successfully exported.</h4> <h4>@Model.ExportSessionResult.RecordCount record@(Model.ExportSessionResult.RecordCount != 1 ? "s" : null) were successfully exported.</h4>
<a href="@Url.Action(MVC.API.DeviceFlag.ExportRetrieve(Model.ExportSessionId))" class="button"><i class="fa fa-download fa-lg"></i>Download Device Flag Export</a> <a href="@Url.Action(MVC.API.DeviceFlag.ExportRetrieve(Model.ExportSessionId))" class="button"><i class="fa fa-download fa-lg"></i>Download Device Flag Export</a>
}
</div> </div>
<script> <script>
$(function () { $(function () {
@@ -402,17 +402,17 @@ WriteLiteral(" ");
#line default #line default
#line hidden #line hidden
WriteLiteral("/><label"); WriteLiteral(" /><label");
WriteAttribute("for", Tuple.Create(" for=\"", 4092), Tuple.Create("\"", 4130) WriteAttribute("for", Tuple.Create(" for=\"", 4093), Tuple.Create("\"", 4131)
, Tuple.Create(Tuple.Create("", 4098), Tuple.Create("Options_", 4098), true) , Tuple.Create(Tuple.Create("", 4099), Tuple.Create("Options_", 4099), true)
#line 74 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 74 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4106), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4107), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4106), false) , 4107), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -424,10 +424,10 @@ WriteLiteral(">");
#line default #line default
#line hidden #line hidden
WriteLiteral("</label></li>\r\n"); WriteLiteral("</label>\r\n </li>\r\n");
#line 75 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 76 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
} }
@@ -445,13 +445,13 @@ WriteLiteral(" class=\"none\"");
WriteLiteral(">\r\n"); WriteLiteral(">\r\n");
#line 80 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 81 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
#line default #line default
#line hidden #line hidden
#line 80 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 81 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
foreach (var optionItem in optionFields.Skip(itemsPerColumn)) foreach (var optionItem in optionFields.Skip(itemsPerColumn))
{ {
@@ -460,40 +460,40 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <li"); WriteLiteral(" <li");
WriteAttribute("title", Tuple.Create(" title=\"", 4665), Tuple.Create("\"", 4696) WriteAttribute("title", Tuple.Create(" title=\"", 4720), Tuple.Create("\"", 4751)
#line 82 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 83 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4673), Tuple.Create<System.Object, System.Int32>(optionItem.Description , Tuple.Create(Tuple.Create("", 4728), Tuple.Create<System.Object, System.Int32>(optionItem.Description
#line default #line default
#line hidden #line hidden
, 4673), false) , 4728), false)
); );
WriteLiteral(">\r\n <input"); WriteLiteral(">\r\n <input");
WriteLiteral(" type=\"checkbox\""); WriteLiteral(" type=\"checkbox\"");
WriteAttribute("id", Tuple.Create(" id=\"", 4778), Tuple.Create("\"", 4815) WriteAttribute("id", Tuple.Create(" id=\"", 4833), Tuple.Create("\"", 4870)
, Tuple.Create(Tuple.Create("", 4783), Tuple.Create("Options_", 4783), true) , Tuple.Create(Tuple.Create("", 4838), Tuple.Create("Options_", 4838), true)
#line 83 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4791), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4846), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4791), false) , 4846), false)
); );
WriteAttribute("name", Tuple.Create(" name=\"", 4816), Tuple.Create("\"", 4855) WriteAttribute("name", Tuple.Create(" name=\"", 4871), Tuple.Create("\"", 4910)
, Tuple.Create(Tuple.Create("", 4823), Tuple.Create("Options.", 4823), true) , Tuple.Create(Tuple.Create("", 4878), Tuple.Create("Options.", 4878), true)
#line 83 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4831), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4886), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4831), false) , 4886), false)
); );
WriteLiteral(" value=\"true\""); WriteLiteral(" value=\"true\"");
@@ -501,38 +501,38 @@ WriteLiteral(" value=\"true\"");
WriteLiteral(" "); WriteLiteral(" ");
#line 83 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
Write(((bool)optionItem.Model) ? "checked " : null); Write(((bool)optionItem.Model) ? "checked " : null);
#line default #line default
#line hidden #line hidden
WriteLiteral("/><label"); WriteLiteral(" /><label");
WriteAttribute("for", Tuple.Create(" for=\"", 4925), Tuple.Create("\"", 4963) WriteAttribute("for", Tuple.Create(" for=\"", 4981), Tuple.Create("\"", 5019)
, Tuple.Create(Tuple.Create("", 4931), Tuple.Create("Options_", 4931), true) , Tuple.Create(Tuple.Create("", 4987), Tuple.Create("Options_", 4987), true)
#line 83 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4939), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4995), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4939), false) , 4995), false)
); );
WriteLiteral(">"); WriteLiteral(">");
#line 83 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
Write(optionItem.DisplayName); Write(optionItem.DisplayName);
#line default #line default
#line hidden #line hidden
WriteLiteral("</label></li>\r\n"); WriteLiteral("</label>\r\n </li>\r\n");
#line 84 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 86 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
} }
@@ -548,7 +548,8 @@ WriteLiteral(@" </ul>
"); ");
#line 92 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 94 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
} }
@@ -590,7 +591,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n
");\r\n });\r\n });\r\n </script>\r\n"); ");\r\n });\r\n });\r\n </script>\r\n");
#line 159 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 162 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
} }
@@ -599,7 +600,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n
WriteLiteral("</div>\r\n"); WriteLiteral("</div>\r\n");
#line 161 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 164 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
if (Model.ExportSessionId != null) if (Model.ExportSessionId != null)
{ {
@@ -614,10 +615,37 @@ WriteLiteral(" class=\"dialog\"");
WriteLiteral(" title=\"Export Device Flags\""); WriteLiteral(" title=\"Export Device Flags\"");
WriteLiteral(">\r\n <h4>"); WriteLiteral(">\r\n");
#line 164 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 167 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
#line default
#line hidden
#line 167 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
if (Model.ExportSessionResult.RecordCount == 0)
{
#line default
#line hidden
WriteLiteral(" <h4>No records matched the filter criteria</h4>\r\n");
#line 170 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
}
else
{
#line default
#line hidden
WriteLiteral(" <h4>");
#line 173 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
Write(Model.ExportSessionResult.RecordCount); Write(Model.ExportSessionResult.RecordCount);
@@ -626,22 +654,24 @@ WriteLiteral(">\r\n <h4>");
WriteLiteral(" record"); WriteLiteral(" record");
#line 164 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 173 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
Write(Model.ExportSessionResult.RecordCount != 1 ? "s" : null); Write(Model.ExportSessionResult.RecordCount != 1 ? "s" : null);
#line default #line default
#line hidden #line hidden
WriteLiteral(" were successfully exported.</h4>\r\n <a"); WriteLiteral(" were successfully exported.</h4>\r\n");
WriteAttribute("href", Tuple.Create(" href=\"", 8250), Tuple.Create("\"", 8326) WriteLiteral(" <a");
#line 165 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" WriteAttribute("href", Tuple.Create(" href=\"", 8524), Tuple.Create("\"", 8600)
, Tuple.Create(Tuple.Create("", 8257), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.DeviceFlag.ExportRetrieve(Model.ExportSessionId))
#line 174 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 8531), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.DeviceFlag.ExportRetrieve(Model.ExportSessionId))
#line default #line default
#line hidden #line hidden
, 8257), false) , 8531), false)
); );
WriteLiteral(" class=\"button\""); WriteLiteral(" class=\"button\"");
@@ -650,7 +680,16 @@ WriteLiteral("><i");
WriteLiteral(" class=\"fa fa-download fa-lg\""); WriteLiteral(" class=\"fa fa-download fa-lg\"");
WriteLiteral("></i>Download Device Flag Export</a>\r\n </div>\r\n"); WriteLiteral("></i>Download Device Flag Export</a>\r\n");
#line 175 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n");
WriteLiteral(@" <script> WriteLiteral(@" <script>
$(function () { $(function () {
@@ -667,7 +706,7 @@ WriteLiteral(@" <script>
"); ");
#line 179 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml" #line 189 "..\..\Areas\Config\Views\DeviceFlag\Export.cshtml"
} }
@@ -71,7 +71,8 @@
@foreach (var optionItem in optionFields.Take(itemsPerColumn)) @foreach (var optionItem in optionFields.Take(itemsPerColumn))
{ {
<li title="@optionItem.Description"> <li title="@optionItem.Description">
<input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null)/><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label></li> <input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null) /><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label>
</li>
} }
</ul> </ul>
</td> </td>
@@ -80,7 +81,8 @@
@foreach (var optionItem in optionFields.Skip(itemsPerColumn)) @foreach (var optionItem in optionFields.Skip(itemsPerColumn))
{ {
<li title="@optionItem.Description"> <li title="@optionItem.Description">
<input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null)/><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label></li> <input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null) /><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label>
</li>
} }
</ul> </ul>
</td> </td>
@@ -89,6 +91,7 @@
</div> </div>
</td> </td>
</tr> </tr>
} }
</table> </table>
</div> </div>
@@ -161,8 +164,15 @@
@if (Model.ExportSessionId != null) @if (Model.ExportSessionId != null)
{ {
<div id="UserFlag_Export_Download_Dialog" class="dialog" title="Export User Flags"> <div id="UserFlag_Export_Download_Dialog" class="dialog" title="Export User Flags">
@if (Model.ExportSessionResult.RecordCount == 0)
{
<h4>No records matched the filter criteria</h4>
}
else
{
<h4>@Model.ExportSessionResult.RecordCount record@(Model.ExportSessionResult.RecordCount != 1 ? "s" : null) were successfully exported.</h4> <h4>@Model.ExportSessionResult.RecordCount record@(Model.ExportSessionResult.RecordCount != 1 ? "s" : null) were successfully exported.</h4>
<a href="@Url.Action(MVC.API.UserFlag.ExportRetrieve(Model.ExportSessionId))" class="button"><i class="fa fa-download fa-lg"></i>Download User Flag Export</a> <a href="@Url.Action(MVC.API.UserFlag.ExportRetrieve(Model.ExportSessionId))" class="button"><i class="fa fa-download fa-lg"></i>Download User Flag Export</a>
}
</div> </div>
<script> <script>
$(function () { $(function () {
@@ -402,17 +402,17 @@ WriteLiteral(" ");
#line default #line default
#line hidden #line hidden
WriteLiteral("/><label"); WriteLiteral(" /><label");
WriteAttribute("for", Tuple.Create(" for=\"", 4084), Tuple.Create("\"", 4122) WriteAttribute("for", Tuple.Create(" for=\"", 4085), Tuple.Create("\"", 4123)
, Tuple.Create(Tuple.Create("", 4090), Tuple.Create("Options_", 4090), true) , Tuple.Create(Tuple.Create("", 4091), Tuple.Create("Options_", 4091), true)
#line 74 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 74 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4098), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4099), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4098), false) , 4099), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -424,10 +424,10 @@ WriteLiteral(">");
#line default #line default
#line hidden #line hidden
WriteLiteral("</label></li>\r\n"); WriteLiteral("</label>\r\n </li>\r\n");
#line 75 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 76 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
} }
@@ -445,13 +445,13 @@ WriteLiteral(" class=\"none\"");
WriteLiteral(">\r\n"); WriteLiteral(">\r\n");
#line 80 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 81 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
#line default #line default
#line hidden #line hidden
#line 80 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 81 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
foreach (var optionItem in optionFields.Skip(itemsPerColumn)) foreach (var optionItem in optionFields.Skip(itemsPerColumn))
{ {
@@ -460,40 +460,40 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <li"); WriteLiteral(" <li");
WriteAttribute("title", Tuple.Create(" title=\"", 4657), Tuple.Create("\"", 4688) WriteAttribute("title", Tuple.Create(" title=\"", 4712), Tuple.Create("\"", 4743)
#line 82 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4665), Tuple.Create<System.Object, System.Int32>(optionItem.Description , Tuple.Create(Tuple.Create("", 4720), Tuple.Create<System.Object, System.Int32>(optionItem.Description
#line default #line default
#line hidden #line hidden
, 4665), false) , 4720), false)
); );
WriteLiteral(">\r\n <input"); WriteLiteral(">\r\n <input");
WriteLiteral(" type=\"checkbox\""); WriteLiteral(" type=\"checkbox\"");
WriteAttribute("id", Tuple.Create(" id=\"", 4770), Tuple.Create("\"", 4807) WriteAttribute("id", Tuple.Create(" id=\"", 4825), Tuple.Create("\"", 4862)
, Tuple.Create(Tuple.Create("", 4775), Tuple.Create("Options_", 4775), true) , Tuple.Create(Tuple.Create("", 4830), Tuple.Create("Options_", 4830), true)
#line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4783), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4838), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4783), false) , 4838), false)
); );
WriteAttribute("name", Tuple.Create(" name=\"", 4808), Tuple.Create("\"", 4847) WriteAttribute("name", Tuple.Create(" name=\"", 4863), Tuple.Create("\"", 4902)
, Tuple.Create(Tuple.Create("", 4815), Tuple.Create("Options.", 4815), true) , Tuple.Create(Tuple.Create("", 4870), Tuple.Create("Options.", 4870), true)
#line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4823), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4878), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4823), false) , 4878), false)
); );
WriteLiteral(" value=\"true\""); WriteLiteral(" value=\"true\"");
@@ -501,38 +501,38 @@ WriteLiteral(" value=\"true\"");
WriteLiteral(" "); WriteLiteral(" ");
#line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
Write(((bool)optionItem.Model) ? "checked " : null); Write(((bool)optionItem.Model) ? "checked " : null);
#line default #line default
#line hidden #line hidden
WriteLiteral("/><label"); WriteLiteral(" /><label");
WriteAttribute("for", Tuple.Create(" for=\"", 4917), Tuple.Create("\"", 4955) WriteAttribute("for", Tuple.Create(" for=\"", 4973), Tuple.Create("\"", 5011)
, Tuple.Create(Tuple.Create("", 4923), Tuple.Create("Options_", 4923), true) , Tuple.Create(Tuple.Create("", 4979), Tuple.Create("Options_", 4979), true)
#line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4931), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4987), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4931), false) , 4987), false)
); );
WriteLiteral(">"); WriteLiteral(">");
#line 83 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 84 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
Write(optionItem.DisplayName); Write(optionItem.DisplayName);
#line default #line default
#line hidden #line hidden
WriteLiteral("</label></li>\r\n"); WriteLiteral("</label>\r\n </li>\r\n");
#line 84 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 86 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
} }
@@ -548,7 +548,8 @@ WriteLiteral(@" </ul>
"); ");
#line 92 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 94 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
} }
@@ -590,7 +591,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n
" });\r\n });\r\n </script>\r\n"); " });\r\n });\r\n </script>\r\n");
#line 159 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 162 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
} }
@@ -599,7 +600,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n
WriteLiteral("</div>\r\n"); WriteLiteral("</div>\r\n");
#line 161 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 164 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
if (Model.ExportSessionId != null) if (Model.ExportSessionId != null)
{ {
@@ -614,10 +615,37 @@ WriteLiteral(" class=\"dialog\"");
WriteLiteral(" title=\"Export User Flags\""); WriteLiteral(" title=\"Export User Flags\"");
WriteLiteral(">\r\n <h4>"); WriteLiteral(">\r\n");
#line 164 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 167 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
#line default
#line hidden
#line 167 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
if (Model.ExportSessionResult.RecordCount == 0)
{
#line default
#line hidden
WriteLiteral(" <h4>No records matched the filter criteria</h4>\r\n");
#line 170 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
}
else
{
#line default
#line hidden
WriteLiteral(" <h4>");
#line 173 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
Write(Model.ExportSessionResult.RecordCount); Write(Model.ExportSessionResult.RecordCount);
@@ -626,22 +654,24 @@ WriteLiteral(">\r\n <h4>");
WriteLiteral(" record"); WriteLiteral(" record");
#line 164 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 173 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
Write(Model.ExportSessionResult.RecordCount != 1 ? "s" : null); Write(Model.ExportSessionResult.RecordCount != 1 ? "s" : null);
#line default #line default
#line hidden #line hidden
WriteLiteral(" were successfully exported.</h4>\r\n <a"); WriteLiteral(" were successfully exported.</h4>\r\n");
WriteAttribute("href", Tuple.Create(" href=\"", 8226), Tuple.Create("\"", 8300) WriteLiteral(" <a");
#line 165 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" WriteAttribute("href", Tuple.Create(" href=\"", 8500), Tuple.Create("\"", 8574)
, Tuple.Create(Tuple.Create("", 8233), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.UserFlag.ExportRetrieve(Model.ExportSessionId))
#line 174 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
, Tuple.Create(Tuple.Create("", 8507), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.UserFlag.ExportRetrieve(Model.ExportSessionId))
#line default #line default
#line hidden #line hidden
, 8233), false) , 8507), false)
); );
WriteLiteral(" class=\"button\""); WriteLiteral(" class=\"button\"");
@@ -650,7 +680,16 @@ WriteLiteral("><i");
WriteLiteral(" class=\"fa fa-download fa-lg\""); WriteLiteral(" class=\"fa fa-download fa-lg\"");
WriteLiteral("></i>Download User Flag Export</a>\r\n </div>\r\n"); WriteLiteral("></i>Download User Flag Export</a>\r\n");
#line 175 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n");
WriteLiteral(@" <script> WriteLiteral(@" <script>
$(function () { $(function () {
@@ -667,7 +706,7 @@ WriteLiteral(@" <script>
"); ");
#line 179 "..\..\Areas\Config\Views\UserFlag\Export.cshtml" #line 189 "..\..\Areas\Config\Views\UserFlag\Export.cshtml"
} }
@@ -5514,6 +5514,9 @@ div.form > table > tbody > tr > th.name {
width: 150px; width: 150px;
text-align: right; text-align: right;
} }
div.form > table > tbody > tr > td.none {
padding: 0;
}
div.form > table table.sub > tbody > tr:not(:first-child) > th, div.form > table table.sub > tbody > tr:not(:first-child) > th,
div.form > table table.sub > tbody > tr:not(:first-child) > td { div.form > table table.sub > tbody > tr:not(:first-child) > td {
border-top: 1px dashed #aaa; border-top: 1px dashed #aaa;
File diff suppressed because one or more lines are too long
+32
View File
@@ -1001,3 +1001,35 @@
#createJobRedirect > div i { #createJobRedirect > div i {
margin-right: 10px; margin-right: 10px;
} }
#Jobs_Export #Jobs_Export_SubTypes {
display: none;
padding-left: 10px;
}
#Jobs_Export #Jobs_Export_Fields #Jobs_Export_Fields_Defaults {
font-size: 0.75em;
}
#Jobs_Export #Jobs_Export_Fields th {
font-size: 1.05em;
}
#Jobs_Export #Jobs_Export_Fields th span {
margin-top: 4px;
font-size: 0.8em;
}
#Jobs_Export_Download_Dialog {
padding-top: 20px;
text-align: center;
}
#Jobs_Export_Download_Dialog h4 {
margin-bottom: 30px;
}
#Jobs_Export_Download_Dialog a {
margin-bottom: 20px;
}
#Jobs_Export_Exporting {
padding-top: 50px;
text-align: center;
}
#Jobs_Export_Exporting i {
margin-right: 10px;
color: #1e6dab;
}
+45
View File
@@ -1096,3 +1096,48 @@
} }
} }
} }
#Jobs_Export {
#Jobs_Export_SubTypes {
display: none;
padding-left: 10px;
}
#Jobs_Export_Fields {
#Jobs_Export_Fields_Defaults {
font-size: .75em;
}
th {
font-size: 1.05em;
span {
margin-top: 4px;
font-size: .8em;
}
}
}
}
#Jobs_Export_Download_Dialog {
padding-top: 20px;
text-align: center;
h4 {
margin-bottom: 30px;
}
a {
margin-bottom: 20px;
}
}
#Jobs_Export_Exporting {
padding-top: 50px;
text-align: center;
i {
margin-right: 10px;
color: @StatusInformation;
}
}
File diff suppressed because one or more lines are too long
+3
View File
@@ -1082,6 +1082,9 @@ div.form > table > tbody > tr > th.name {
width: 150px; width: 150px;
text-align: right; text-align: right;
} }
div.form > table > tbody > tr > td.none {
padding: 0;
}
div.form > table table.sub > tbody > tr:not(:first-child) > th, div.form > table table.sub > tbody > tr:not(:first-child) > th,
div.form > table table.sub > tbody > tr:not(:first-child) > td { div.form > table table.sub > tbody > tr:not(:first-child) > td {
border-top: 1px dashed #aaa; border-top: 1px dashed #aaa;
+4
View File
@@ -1064,6 +1064,10 @@ div.form {
width: 150px; width: 150px;
text-align: right; text-align: right;
} }
& > td.none {
padding: 0;
}
} }
} }
File diff suppressed because one or more lines are too long
+43 -1
View File
@@ -1,10 +1,12 @@
using Disco.Models.Repository; using Disco.Models.Repository;
using Disco.Models.Services.Job; using Disco.Models.Services.Jobs;
using Disco.Models.Services.Jobs.Exporting;
using Disco.Models.Services.Jobs.JobLists; using Disco.Models.Services.Jobs.JobLists;
using Disco.Models.UI.Job; using Disco.Models.UI.Job;
using Disco.Services; using Disco.Services;
using Disco.Services.Authorization; using Disco.Services.Authorization;
using Disco.Services.Devices.Enrolment; using Disco.Services.Devices.Enrolment;
using Disco.Services.Exporting;
using Disco.Services.Jobs; using Disco.Services.Jobs;
using Disco.Services.Jobs.JobLists; using Disco.Services.Jobs.JobLists;
using Disco.Services.Jobs.JobQueues; using Disco.Services.Jobs.JobQueues;
@@ -22,6 +24,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Data.Entity; using System.Data.Entity;
using System.Linq; using System.Linq;
using System.Web;
using System.Web.Mvc; using System.Web.Mvc;
namespace Disco.Web.Controllers namespace Disco.Web.Controllers
@@ -1075,5 +1078,44 @@ namespace Disco.Web.Controllers
} }
#endregion #endregion
#region Export
[DiscoAuthorizeAny(Claims.Job.Actions.Export), HttpGet]
public virtual ActionResult Export(string downloadId)
{
var m = new Models.Job.ExportModel()
{
Options = Database.DiscoConfiguration.JobPreferences.LastExportOptions,
JobQueues = JobQueueService.GetQueues().Select(q => q.JobQueue).ToList(),
JobTypes = Database.JobTypes.Include(t => t.JobSubTypes).ToList(),
JobStatuses = Job.JobStatusIds.StatusDescriptions.ToList(),
};
if (Database.DiscoConfiguration.JobPreferences.LastExportDate.GetValueOrDefault() < DateTime.Today.AddDays(-1))
{
m.Options.FilterStartDate = new DateTime(DateTime.Today.Year, 1, 1);
m.Options.FilterEndDate = null;
}
if (!string.IsNullOrWhiteSpace(downloadId))
{
string key = string.Format(Areas.API.Controllers.JobController.ExportSessionCacheKey, downloadId);
var context = HttpRuntime.Cache.Get(key) as ExportTaskContext<JobExportOptions>;
if (context != null)
{
m.ExportSessionResult = context.Result;
m.ExportSessionId = downloadId;
}
}
// UI Extensions
UIExtensions.ExecuteExtensions<JobExportModel>(this.ControllerContext, m);
return View(m);
}
#endregion
} }
} }
+12 -2
View File
@@ -838,6 +838,7 @@
<Compile Include="Models\Device\ExportModel.cs" /> <Compile Include="Models\Device\ExportModel.cs" />
<Compile Include="Models\Device\ImportHeadersModel.cs" /> <Compile Include="Models\Device\ImportHeadersModel.cs" />
<Compile Include="Models\InitialConfig\AdministratorsModel.cs" /> <Compile Include="Models\InitialConfig\AdministratorsModel.cs" />
<Compile Include="Models\Job\ExportModel.cs" />
<Compile Include="Models\Job\LogInsuranceModel.cs" /> <Compile Include="Models\Job\LogInsuranceModel.cs" />
<Compile Include="Models\Job\LogRepairModel.cs" /> <Compile Include="Models\Job\LogRepairModel.cs" />
<Compile Include="Extensions\T4MVC\T4MVC.cs"> <Compile Include="Extensions\T4MVC\T4MVC.cs">
@@ -866,6 +867,11 @@
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>
</Compile> </Compile>
<Compile Include="Views\Job\Export.generated.cs">
<DependentUpon>Export.cshtml</DependentUpon>
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
</Compile>
<Compile Include="Views\Job\LogInsurance.generated.cs"> <Compile Include="Views\Job\LogInsurance.generated.cs">
<DependentUpon>LogInsurance.cshtml</DependentUpon> <DependentUpon>LogInsurance.cshtml</DependentUpon>
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
@@ -1329,10 +1335,10 @@
<Generator>RazorGenerator</Generator> <Generator>RazorGenerator</Generator>
<LastGenOutput>General.generated.cs</LastGenOutput> <LastGenOutput>General.generated.cs</LastGenOutput>
</None> </None>
<Content Include="Areas\Config\Views\JobPreferences\Parts\Lodgment.cshtml"> <None Include="Areas\Config\Views\JobPreferences\Parts\Lodgment.cshtml">
<Generator>RazorGenerator</Generator> <Generator>RazorGenerator</Generator>
<LastGenOutput>Lodgment.generated.cs</LastGenOutput> <LastGenOutput>Lodgment.generated.cs</LastGenOutput>
</Content> </None>
<None Include="Areas\Config\Views\JobPreferences\Parts\Locations.cshtml"> <None Include="Areas\Config\Views\JobPreferences\Parts\Locations.cshtml">
<Generator>RazorGenerator</Generator> <Generator>RazorGenerator</Generator>
<LastGenOutput>Locations.generated.cs</LastGenOutput> <LastGenOutput>Locations.generated.cs</LastGenOutput>
@@ -2073,6 +2079,10 @@
<None Include="ClientSource\Scripts\Modules\tinymce\themes\modern\theme.min.js" /> <None Include="ClientSource\Scripts\Modules\tinymce\themes\modern\theme.min.js" />
<None Include="ClientSource\Scripts\Modules\tinymce\tinymce.js" /> <None Include="ClientSource\Scripts\Modules\tinymce\tinymce.js" />
<None Include="ClientSource\Scripts\Modules\tinymce\tinymce.min.js" /> <None Include="ClientSource\Scripts\Modules\tinymce\tinymce.min.js" />
<None Include="Views\Job\Export.cshtml">
<Generator>RazorGenerator</Generator>
<LastGenOutput>Export.generated.cs</LastGenOutput>
</None>
<None Include="Views\Job\LogInsurance.cshtml"> <None Include="Views\Job\LogInsurance.cshtml">
<Generator>RazorGenerator</Generator> <Generator>RazorGenerator</Generator>
<LastGenOutput>LogInsurance.generated.cs</LastGenOutput> <LastGenOutput>LogInsurance.generated.cs</LastGenOutput>
@@ -449,6 +449,18 @@ namespace Disco.Web.Areas.API.Controllers
{ {
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.GeneratePdfPackage); return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.GeneratePdfPackage);
} }
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult Export()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Export);
}
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult ExportRetrieve()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.ExportRetrieve);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public JobController Actions { get { return MVC.API.Job; } } public JobController Actions { get { return MVC.API.Job; } }
@@ -532,6 +544,8 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string GeneratePdf = "GeneratePdf"; public readonly string GeneratePdf = "GeneratePdf";
public readonly string GeneratePdfPackage = "GeneratePdfPackage"; public readonly string GeneratePdfPackage = "GeneratePdfPackage";
public readonly string DeviceHeldLocations = "DeviceHeldLocations"; public readonly string DeviceHeldLocations = "DeviceHeldLocations";
public readonly string Export = "Export";
public readonly string ExportRetrieve = "ExportRetrieve";
} }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -604,6 +618,8 @@ namespace Disco.Web.Areas.API.Controllers
public const string GeneratePdf = "GeneratePdf"; public const string GeneratePdf = "GeneratePdf";
public const string GeneratePdfPackage = "GeneratePdfPackage"; public const string GeneratePdfPackage = "GeneratePdfPackage";
public const string DeviceHeldLocations = "DeviceHeldLocations"; public const string DeviceHeldLocations = "DeviceHeldLocations";
public const string Export = "Export";
public const string ExportRetrieve = "ExportRetrieve";
} }
@@ -1231,6 +1247,22 @@ namespace Disco.Web.Areas.API.Controllers
public readonly string id = "id"; public readonly string id = "id";
public readonly string DocumentTemplatePackageId = "DocumentTemplatePackageId"; public readonly string DocumentTemplatePackageId = "DocumentTemplatePackageId";
} }
static readonly ActionParamsClass_Export s_params_Export = new ActionParamsClass_Export();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_Export ExportParams { get { return s_params_Export; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_Export
{
public readonly string Model = "Model";
}
static readonly ActionParamsClass_ExportRetrieve s_params_ExportRetrieve = new ActionParamsClass_ExportRetrieve();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_ExportRetrieve ExportRetrieveParams { get { return s_params_ExportRetrieve; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_ExportRetrieve
{
public readonly string id = "id";
}
static readonly ViewsClass s_views = new ViewsClass(); static readonly ViewsClass s_views = new ViewsClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ViewsClass Views { get { return s_views; } } public ViewsClass Views { get { return s_views; } }
@@ -2156,6 +2188,30 @@ namespace Disco.Web.Areas.API.Controllers
return callInfo; return callInfo;
} }
[NonAction]
partial void ExportOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, Disco.Web.Models.Job.ExportModel Model);
[NonAction]
public override System.Web.Mvc.ActionResult Export(Disco.Web.Models.Job.ExportModel Model)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Export);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "Model", Model);
ExportOverride(callInfo, Model);
return callInfo;
}
[NonAction]
partial void ExportRetrieveOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string id);
[NonAction]
public override System.Web.Mvc.ActionResult ExportRetrieve(string id)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.ExportRetrieve);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "id", id);
ExportRetrieveOverride(callInfo, id);
return callInfo;
}
} }
} }
@@ -327,10 +327,10 @@ namespace Disco.Web.Areas.API.Controllers
} }
[NonAction] [NonAction]
partial void UpdateLocationModeOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, Disco.Models.Services.Job.LocationModes LocationMode, bool redirect); partial void UpdateLocationModeOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, Disco.Models.Services.Jobs.LocationModes LocationMode, bool redirect);
[NonAction] [NonAction]
public override System.Web.Mvc.ActionResult UpdateLocationMode(Disco.Models.Services.Job.LocationModes LocationMode, bool redirect) public override System.Web.Mvc.ActionResult UpdateLocationMode(Disco.Models.Services.Jobs.LocationModes LocationMode, bool redirect)
{ {
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpdateLocationMode); var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.UpdateLocationMode);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "LocationMode", LocationMode); ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "LocationMode", LocationMode);
@@ -113,6 +113,12 @@ namespace Disco.Web.Controllers
{ {
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.InsuranceProviderJobDetails); return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.InsuranceProviderJobDetails);
} }
[NonAction]
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public virtual System.Web.Mvc.ActionResult Export()
{
return new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Export);
}
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public JobController Actions { get { return MVC.Job; } } public JobController Actions { get { return MVC.Job; } }
@@ -153,6 +159,7 @@ namespace Disco.Web.Controllers
public readonly string RepairProviderJobDetails = "RepairProviderJobDetails"; public readonly string RepairProviderJobDetails = "RepairProviderJobDetails";
public readonly string LogInsurance = "LogInsurance"; public readonly string LogInsurance = "LogInsurance";
public readonly string InsuranceProviderJobDetails = "InsuranceProviderJobDetails"; public readonly string InsuranceProviderJobDetails = "InsuranceProviderJobDetails";
public readonly string Export = "Export";
} }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
@@ -182,6 +189,7 @@ namespace Disco.Web.Controllers
public const string RepairProviderJobDetails = "RepairProviderJobDetails"; public const string RepairProviderJobDetails = "RepairProviderJobDetails";
public const string LogInsurance = "LogInsurance"; public const string LogInsurance = "LogInsurance";
public const string InsuranceProviderJobDetails = "InsuranceProviderJobDetails"; public const string InsuranceProviderJobDetails = "InsuranceProviderJobDetails";
public const string Export = "Export";
} }
@@ -271,6 +279,14 @@ namespace Disco.Web.Controllers
{ {
public readonly string id = "id"; public readonly string id = "id";
} }
static readonly ActionParamsClass_Export s_params_Export = new ActionParamsClass_Export();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ActionParamsClass_Export ExportParams { get { return s_params_Export; } }
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public class ActionParamsClass_Export
{
public readonly string downloadId = "downloadId";
}
static readonly ViewsClass s_views = new ViewsClass(); static readonly ViewsClass s_views = new ViewsClass();
[GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode] [GeneratedCode("T4MVC", "2.0"), DebuggerNonUserCode]
public ViewsClass Views { get { return s_views; } } public ViewsClass Views { get { return s_views; } }
@@ -285,6 +301,7 @@ namespace Disco.Web.Controllers
public readonly string _ViewStart = "_ViewStart"; public readonly string _ViewStart = "_ViewStart";
public readonly string Create = "Create"; public readonly string Create = "Create";
public readonly string Create_Redirect = "Create_Redirect"; public readonly string Create_Redirect = "Create_Redirect";
public readonly string Export = "Export";
public readonly string Index = "Index"; public readonly string Index = "Index";
public readonly string InsuranceProviderJobDetails = "InsuranceProviderJobDetails"; public readonly string InsuranceProviderJobDetails = "InsuranceProviderJobDetails";
public readonly string List = "List"; public readonly string List = "List";
@@ -305,6 +322,7 @@ namespace Disco.Web.Controllers
public readonly string _ViewStart = "~/Views/Job/_ViewStart.cshtml"; public readonly string _ViewStart = "~/Views/Job/_ViewStart.cshtml";
public readonly string Create = "~/Views/Job/Create.cshtml"; public readonly string Create = "~/Views/Job/Create.cshtml";
public readonly string Create_Redirect = "~/Views/Job/Create_Redirect.cshtml"; public readonly string Create_Redirect = "~/Views/Job/Create_Redirect.cshtml";
public readonly string Export = "~/Views/Job/Export.cshtml";
public readonly string Index = "~/Views/Job/Index.cshtml"; public readonly string Index = "~/Views/Job/Index.cshtml";
public readonly string InsuranceProviderJobDetails = "~/Views/Job/InsuranceProviderJobDetails.cshtml"; public readonly string InsuranceProviderJobDetails = "~/Views/Job/InsuranceProviderJobDetails.cshtml";
public readonly string List = "~/Views/Job/List.cshtml"; public readonly string List = "~/Views/Job/List.cshtml";
@@ -692,6 +710,18 @@ namespace Disco.Web.Controllers
return callInfo; return callInfo;
} }
[NonAction]
partial void ExportOverride(T4MVC_System_Web_Mvc_ActionResult callInfo, string downloadId);
[NonAction]
public override System.Web.Mvc.ActionResult Export(string downloadId)
{
var callInfo = new T4MVC_System_Web_Mvc_ActionResult(Area, Name, ActionNames.Export);
ModelUnbinderHelpers.AddRouteValues(callInfo.RouteValueDictionary, "downloadId", downloadId);
ExportOverride(callInfo, downloadId);
return callInfo;
}
} }
} }
+21
View File
@@ -0,0 +1,21 @@
using Disco.Models.Repository;
using Disco.Models.Services.Exporting;
using Disco.Models.Services.Jobs.Exporting;
using Disco.Models.UI.Job;
using System.Collections.Generic;
namespace Disco.Web.Models.Job
{
public class ExportModel : JobExportModel
{
public JobExportOptions Options { get; set; }
public string ExportSessionId { get; set; }
public ExportResult ExportSessionResult { get; set; }
public List<JobQueue> JobQueues { get; set; }
public List<KeyValuePair<string, string>> JobStatuses { get; set; }
public List<JobType> JobTypes { get; set; }
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
using Disco.Models.ClientServices; using Disco.Models.ClientServices;
using Disco.Models.Services.Job.Statistics; using Disco.Models.Services.Jobs.Statistics;
using Disco.Models.Services.Jobs.JobLists; using Disco.Models.Services.Jobs.JobLists;
using Disco.Models.UI.Job; using Disco.Models.UI.Job;
using System.Collections.Generic; using System.Collections.Generic;
+1 -1
View File
@@ -1,5 +1,5 @@
using Disco.Models.Services.Documents; using Disco.Models.Services.Documents;
using Disco.Models.Services.Job; using Disco.Models.Services.Jobs;
using Disco.Models.Services.Jobs.JobLists; using Disco.Models.Services.Jobs.JobLists;
using Disco.Models.UI.Job; using Disco.Models.UI.Job;
using Disco.Services.Plugins; using Disco.Services.Plugins;
+15 -4
View File
@@ -1,5 +1,4 @@
@using Disco.Web.Models.Device; @using Disco.Web.Models.Device;
@using Disco.Models.Services.Devices;
@model ExportModel @model ExportModel
@{ @{
Authorization.RequireAny(Claims.Device.Actions.Export); Authorization.RequireAny(Claims.Device.Actions.Export);
@@ -13,11 +12,13 @@
<div id="Devices_Export"> <div id="Devices_Export">
@using (Html.BeginForm(MVC.API.Device.Export())) @using (Html.BeginForm(MVC.API.Device.Export()))
{ {
@Html.AntiForgeryToken()
<div id="Devices_Export_Type" class="form" style="width: 570px"> <div id="Devices_Export_Type" class="form" style="width: 570px">
<h2>Export Type</h2> <h2>Export Type</h2>
<table> <table>
<tr> <tr>
<th style="width: 150px">Type: <th style="width: 150px">
Type:
</th> </th>
<td> <td>
@Html.DropDownListFor(m => m.Options.ExportType, Enum.GetNames(typeof(Disco.Models.Services.Devices.Exporting.DeviceExportTypes)).Select(t => new SelectListItem() { Text = t, Value = t })) @Html.DropDownListFor(m => m.Options.ExportType, Enum.GetNames(typeof(Disco.Models.Services.Devices.Exporting.DeviceExportTypes)).Select(t => new SelectListItem() { Text = t, Value = t }))
@@ -64,7 +65,8 @@
@foreach (var optionItem in optionFields.Take(itemsPerColumn)) @foreach (var optionItem in optionFields.Take(itemsPerColumn))
{ {
<li title="@optionItem.Description"> <li title="@optionItem.Description">
<input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null)/><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label></li> <input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null) /><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label>
</li>
} }
</ul> </ul>
</td> </td>
@@ -73,7 +75,8 @@
@foreach (var optionItem in optionFields.Skip(itemsPerColumn)) @foreach (var optionItem in optionFields.Skip(itemsPerColumn))
{ {
<li title="@optionItem.Description"> <li title="@optionItem.Description">
<input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null)/><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label></li> <input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null) /><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label>
</li>
} }
</ul> </ul>
</td> </td>
@@ -82,6 +85,7 @@
</div> </div>
</td> </td>
</tr> </tr>
} }
</table> </table>
</div> </div>
@@ -174,8 +178,15 @@
@if (Model.ExportSessionId != null) @if (Model.ExportSessionId != null)
{ {
<div id="Devices_Export_Download_Dialog" class="dialog" title="Export Devices"> <div id="Devices_Export_Download_Dialog" class="dialog" title="Export Devices">
@if (Model.ExportSessionResult.RecordCount == 0)
{
<h4>No records matched the filter criteria</h4>
}
else
{
<h4>@Model.ExportSessionResult.RecordCount record@(Model.ExportSessionResult.RecordCount != 1 ? "s" : null) were successfully exported.</h4> <h4>@Model.ExportSessionResult.RecordCount record@(Model.ExportSessionResult.RecordCount != 1 ? "s" : null) were successfully exported.</h4>
<a href="@Url.Action(MVC.API.Device.ExportRetrieve(Model.ExportSessionId))" class="button"><i class="fa fa-download fa-lg"></i>Download Device Export</a> <a href="@Url.Action(MVC.API.Device.ExportRetrieve(Model.ExportSessionId))" class="button"><i class="fa fa-download fa-lg"></i>Download Device Export</a>
}
</div> </div>
<script> <script>
$(function () { $(function () {
+135 -87
View File
@@ -28,12 +28,6 @@ namespace Disco.Web.Views.Device
using System.Web.WebPages; using System.Web.WebPages;
using Disco; using Disco;
using Disco.Models.Repository; using Disco.Models.Repository;
#line 2 "..\..\Views\Device\Export.cshtml"
using Disco.Models.Services.Devices;
#line default
#line hidden
using Disco.Services; using Disco.Services;
using Disco.Services.Authorization; using Disco.Services.Authorization;
using Disco.Services.Web; using Disco.Services.Web;
@@ -56,7 +50,7 @@ namespace Disco.Web.Views.Device
public override void Execute() public override void Execute()
{ {
#line 4 "..\..\Views\Device\Export.cshtml" #line 3 "..\..\Views\Device\Export.cshtml"
Authorization.RequireAny(Claims.Device.Actions.Export); Authorization.RequireAny(Claims.Device.Actions.Export);
@@ -76,17 +70,31 @@ WriteLiteral(" id=\"Devices_Export\"");
WriteLiteral(">\r\n"); WriteLiteral(">\r\n");
#line 14 "..\..\Views\Device\Export.cshtml" #line 13 "..\..\Views\Device\Export.cshtml"
#line default #line default
#line hidden #line hidden
#line 14 "..\..\Views\Device\Export.cshtml" #line 13 "..\..\Views\Device\Export.cshtml"
using (Html.BeginForm(MVC.API.Device.Export())) using (Html.BeginForm(MVC.API.Device.Export()))
{ {
#line default
#line hidden
#line 15 "..\..\Views\Device\Export.cshtml"
Write(Html.AntiForgeryToken());
#line default
#line hidden
#line 15 "..\..\Views\Device\Export.cshtml"
#line default #line default
#line hidden #line hidden
WriteLiteral(" <div"); WriteLiteral(" <div");
@@ -102,12 +110,13 @@ WriteLiteral(">\r\n <h2>Export Type</h2>\r\n <table>\r\n
WriteLiteral(" style=\"width: 150px\""); WriteLiteral(" style=\"width: 150px\"");
WriteLiteral(">Type:\r\n </th>\r\n <td>\r\n"); WriteLiteral(">\r\n Type:\r\n </th>\r\n " +
"<td>\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 23 "..\..\Views\Device\Export.cshtml" #line 24 "..\..\Views\Device\Export.cshtml"
Write(Html.DropDownListFor(m => m.Options.ExportType, Enum.GetNames(typeof(Disco.Models.Services.Devices.Exporting.DeviceExportTypes)).Select(t => new SelectListItem() { Text = t, Value = t }))); Write(Html.DropDownListFor(m => m.Options.ExportType, Enum.GetNames(typeof(Disco.Models.Services.Devices.Exporting.DeviceExportTypes)).Select(t => new SelectListItem() { Text = t, Value = t })));
@@ -124,7 +133,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 25 "..\..\Views\Device\Export.cshtml" #line 26 "..\..\Views\Device\Export.cshtml"
Write(Html.DropDownListFor(m => m.Options.ExportTypeTargetId, Model.DeviceBatches.Select(i => new SelectListItem() { Value = i.Key.ToString(), Text = i.Value }))); Write(Html.DropDownListFor(m => m.Options.ExportTypeTargetId, Model.DeviceBatches.Select(i => new SelectListItem() { Value = i.Key.ToString(), Text = i.Value })));
@@ -141,7 +150,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 28 "..\..\Views\Device\Export.cshtml" #line 29 "..\..\Views\Device\Export.cshtml"
Write(Html.DropDownListFor(m => m.Options.ExportTypeTargetId, Model.DeviceModels.Select(i => new SelectListItem() { Value = i.Key.ToString(), Text = i.Value }))); Write(Html.DropDownListFor(m => m.Options.ExportTypeTargetId, Model.DeviceModels.Select(i => new SelectListItem() { Value = i.Key.ToString(), Text = i.Value })));
@@ -158,7 +167,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 31 "..\..\Views\Device\Export.cshtml" #line 32 "..\..\Views\Device\Export.cshtml"
Write(Html.DropDownListFor(m => m.Options.ExportTypeTargetId, Model.DeviceProfiles.Select(i => new SelectListItem() { Value = i.Key.ToString(), Text = i.Value }))); Write(Html.DropDownListFor(m => m.Options.ExportTypeTargetId, Model.DeviceProfiles.Select(i => new SelectListItem() { Value = i.Key.ToString(), Text = i.Value })));
@@ -168,7 +177,7 @@ WriteLiteral("\r\n </div>\r\n </td>\r\
">\r\n <tr>\r\n <th>"); ">\r\n <tr>\r\n <th>");
#line 36 "..\..\Views\Device\Export.cshtml" #line 37 "..\..\Views\Device\Export.cshtml"
Write(Html.LabelFor(m => m.Options.Format)); Write(Html.LabelFor(m => m.Options.Format));
@@ -179,7 +188,7 @@ WriteLiteral("</th>\r\n <td>\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 38 "..\..\Views\Device\Export.cshtml" #line 39 "..\..\Views\Device\Export.cshtml"
Write(Html.DropDownListFor(m => m.Options.Format, Enum.GetNames(typeof(Disco.Models.Exporting.ExportFormat)).Select(v => new SelectListItem() { Value = v, Text = v }))); Write(Html.DropDownListFor(m => m.Options.Format, Enum.GetNames(typeof(Disco.Models.Exporting.ExportFormat)).Select(v => new SelectListItem() { Value = v, Text = v })));
@@ -205,13 +214,13 @@ WriteLiteral(" href=\"#\"");
WriteLiteral(">(Defaults)</a></h2>\r\n <table>\r\n"); WriteLiteral(">(Defaults)</a></h2>\r\n <table>\r\n");
#line 46 "..\..\Views\Device\Export.cshtml" #line 47 "..\..\Views\Device\Export.cshtml"
#line default #line default
#line hidden #line hidden
#line 46 "..\..\Views\Device\Export.cshtml" #line 47 "..\..\Views\Device\Export.cshtml"
foreach (var optionGroup in optionGroups) foreach (var optionGroup in optionGroups)
{ {
var optionFields = optionGroup.ToList(); var optionFields = optionGroup.ToList();
@@ -229,7 +238,7 @@ WriteLiteral(">\r\n");
WriteLiteral(" "); WriteLiteral(" ");
#line 52 "..\..\Views\Device\Export.cshtml" #line 53 "..\..\Views\Device\Export.cshtml"
Write(optionGroup.Key); Write(optionGroup.Key);
@@ -238,13 +247,13 @@ WriteLiteral(" ");
WriteLiteral("\r\n"); WriteLiteral("\r\n");
#line 53 "..\..\Views\Device\Export.cshtml" #line 54 "..\..\Views\Device\Export.cshtml"
#line default #line default
#line hidden #line hidden
#line 53 "..\..\Views\Device\Export.cshtml" #line 54 "..\..\Views\Device\Export.cshtml"
if (optionFields.Count > 2) if (optionFields.Count > 2)
{ {
@@ -272,7 +281,7 @@ WriteLiteral(" href=\"#\"");
WriteLiteral(">NONE</a></span>\r\n"); WriteLiteral(">NONE</a></span>\r\n");
#line 56 "..\..\Views\Device\Export.cshtml" #line 57 "..\..\Views\Device\Export.cshtml"
} }
@@ -299,13 +308,13 @@ WriteLiteral(" class=\"none\"");
WriteLiteral(">\r\n"); WriteLiteral(">\r\n");
#line 64 "..\..\Views\Device\Export.cshtml" #line 65 "..\..\Views\Device\Export.cshtml"
#line default #line default
#line hidden #line hidden
#line 64 "..\..\Views\Device\Export.cshtml" #line 65 "..\..\Views\Device\Export.cshtml"
foreach (var optionItem in optionFields.Take(itemsPerColumn)) foreach (var optionItem in optionFields.Take(itemsPerColumn))
{ {
@@ -314,40 +323,40 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <li"); WriteLiteral(" <li");
WriteAttribute("title", Tuple.Create(" title=\"", 3907), Tuple.Create("\"", 3938) WriteAttribute("title", Tuple.Create(" title=\"", 3928), Tuple.Create("\"", 3959)
#line 66 "..\..\Views\Device\Export.cshtml" #line 67 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 3915), Tuple.Create<System.Object, System.Int32>(optionItem.Description , Tuple.Create(Tuple.Create("", 3936), Tuple.Create<System.Object, System.Int32>(optionItem.Description
#line default #line default
#line hidden #line hidden
, 3915), false) , 3936), false)
); );
WriteLiteral(">\r\n <input"); WriteLiteral(">\r\n <input");
WriteLiteral(" type=\"checkbox\""); WriteLiteral(" type=\"checkbox\"");
WriteAttribute("id", Tuple.Create(" id=\"", 4020), Tuple.Create("\"", 4057) WriteAttribute("id", Tuple.Create(" id=\"", 4041), Tuple.Create("\"", 4078)
, Tuple.Create(Tuple.Create("", 4025), Tuple.Create("Options_", 4025), true) , Tuple.Create(Tuple.Create("", 4046), Tuple.Create("Options_", 4046), true)
#line 67 "..\..\Views\Device\Export.cshtml" #line 68 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4033), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4054), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4033), false) , 4054), false)
); );
WriteAttribute("name", Tuple.Create(" name=\"", 4058), Tuple.Create("\"", 4097) WriteAttribute("name", Tuple.Create(" name=\"", 4079), Tuple.Create("\"", 4118)
, Tuple.Create(Tuple.Create("", 4065), Tuple.Create("Options.", 4065), true) , Tuple.Create(Tuple.Create("", 4086), Tuple.Create("Options.", 4086), true)
#line 67 "..\..\Views\Device\Export.cshtml" #line 68 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4073), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4094), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4073), false) , 4094), false)
); );
WriteLiteral(" value=\"true\""); WriteLiteral(" value=\"true\"");
@@ -355,38 +364,38 @@ WriteLiteral(" value=\"true\"");
WriteLiteral(" "); WriteLiteral(" ");
#line 67 "..\..\Views\Device\Export.cshtml" #line 68 "..\..\Views\Device\Export.cshtml"
Write(((bool)optionItem.Model) ? "checked " : null); Write(((bool)optionItem.Model) ? "checked " : null);
#line default #line default
#line hidden #line hidden
WriteLiteral("/><label"); WriteLiteral(" /><label");
WriteAttribute("for", Tuple.Create(" for=\"", 4167), Tuple.Create("\"", 4205) WriteAttribute("for", Tuple.Create(" for=\"", 4189), Tuple.Create("\"", 4227)
, Tuple.Create(Tuple.Create("", 4173), Tuple.Create("Options_", 4173), true) , Tuple.Create(Tuple.Create("", 4195), Tuple.Create("Options_", 4195), true)
#line 67 "..\..\Views\Device\Export.cshtml" #line 68 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4181), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4203), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4181), false) , 4203), false)
); );
WriteLiteral(">"); WriteLiteral(">");
#line 67 "..\..\Views\Device\Export.cshtml" #line 68 "..\..\Views\Device\Export.cshtml"
Write(optionItem.DisplayName); Write(optionItem.DisplayName);
#line default #line default
#line hidden #line hidden
WriteLiteral("</label></li>\r\n"); WriteLiteral("</label>\r\n </li>\r\n");
#line 68 "..\..\Views\Device\Export.cshtml" #line 70 "..\..\Views\Device\Export.cshtml"
} }
@@ -404,13 +413,13 @@ WriteLiteral(" class=\"none\"");
WriteLiteral(">\r\n"); WriteLiteral(">\r\n");
#line 73 "..\..\Views\Device\Export.cshtml" #line 75 "..\..\Views\Device\Export.cshtml"
#line default #line default
#line hidden #line hidden
#line 73 "..\..\Views\Device\Export.cshtml" #line 75 "..\..\Views\Device\Export.cshtml"
foreach (var optionItem in optionFields.Skip(itemsPerColumn)) foreach (var optionItem in optionFields.Skip(itemsPerColumn))
{ {
@@ -419,40 +428,40 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <li"); WriteLiteral(" <li");
WriteAttribute("title", Tuple.Create(" title=\"", 4740), Tuple.Create("\"", 4771) WriteAttribute("title", Tuple.Create(" title=\"", 4816), Tuple.Create("\"", 4847)
#line 75 "..\..\Views\Device\Export.cshtml" #line 77 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4748), Tuple.Create<System.Object, System.Int32>(optionItem.Description , Tuple.Create(Tuple.Create("", 4824), Tuple.Create<System.Object, System.Int32>(optionItem.Description
#line default #line default
#line hidden #line hidden
, 4748), false) , 4824), false)
); );
WriteLiteral(">\r\n <input"); WriteLiteral(">\r\n <input");
WriteLiteral(" type=\"checkbox\""); WriteLiteral(" type=\"checkbox\"");
WriteAttribute("id", Tuple.Create(" id=\"", 4853), Tuple.Create("\"", 4890) WriteAttribute("id", Tuple.Create(" id=\"", 4929), Tuple.Create("\"", 4966)
, Tuple.Create(Tuple.Create("", 4858), Tuple.Create("Options_", 4858), true) , Tuple.Create(Tuple.Create("", 4934), Tuple.Create("Options_", 4934), true)
#line 76 "..\..\Views\Device\Export.cshtml" #line 78 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4866), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4942), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4866), false) , 4942), false)
); );
WriteAttribute("name", Tuple.Create(" name=\"", 4891), Tuple.Create("\"", 4930) WriteAttribute("name", Tuple.Create(" name=\"", 4967), Tuple.Create("\"", 5006)
, Tuple.Create(Tuple.Create("", 4898), Tuple.Create("Options.", 4898), true) , Tuple.Create(Tuple.Create("", 4974), Tuple.Create("Options.", 4974), true)
#line 76 "..\..\Views\Device\Export.cshtml" #line 78 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 4906), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 4982), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 4906), false) , 4982), false)
); );
WriteLiteral(" value=\"true\""); WriteLiteral(" value=\"true\"");
@@ -460,38 +469,38 @@ WriteLiteral(" value=\"true\"");
WriteLiteral(" "); WriteLiteral(" ");
#line 76 "..\..\Views\Device\Export.cshtml" #line 78 "..\..\Views\Device\Export.cshtml"
Write(((bool)optionItem.Model) ? "checked " : null); Write(((bool)optionItem.Model) ? "checked " : null);
#line default #line default
#line hidden #line hidden
WriteLiteral("/><label"); WriteLiteral(" /><label");
WriteAttribute("for", Tuple.Create(" for=\"", 5000), Tuple.Create("\"", 5038) WriteAttribute("for", Tuple.Create(" for=\"", 5077), Tuple.Create("\"", 5115)
, Tuple.Create(Tuple.Create("", 5006), Tuple.Create("Options_", 5006), true) , Tuple.Create(Tuple.Create("", 5083), Tuple.Create("Options_", 5083), true)
#line 76 "..\..\Views\Device\Export.cshtml" #line 78 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 5014), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName , Tuple.Create(Tuple.Create("", 5091), Tuple.Create<System.Object, System.Int32>(optionItem.PropertyName
#line default #line default
#line hidden #line hidden
, 5014), false) , 5091), false)
); );
WriteLiteral(">"); WriteLiteral(">");
#line 76 "..\..\Views\Device\Export.cshtml" #line 78 "..\..\Views\Device\Export.cshtml"
Write(optionItem.DisplayName); Write(optionItem.DisplayName);
#line default #line default
#line hidden #line hidden
WriteLiteral("</label></li>\r\n"); WriteLiteral("</label>\r\n </li>\r\n");
#line 77 "..\..\Views\Device\Export.cshtml" #line 80 "..\..\Views\Device\Export.cshtml"
} }
@@ -507,7 +516,8 @@ WriteLiteral(@" </ul>
"); ");
#line 85 "..\..\Views\Device\Export.cshtml" #line 88 "..\..\Views\Device\Export.cshtml"
} }
@@ -563,7 +573,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n
";\r\n });\r\n </script>\r\n"); ";\r\n });\r\n </script>\r\n");
#line 172 "..\..\Views\Device\Export.cshtml" #line 176 "..\..\Views\Device\Export.cshtml"
} }
@@ -572,7 +582,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n
WriteLiteral("</div>\r\n"); WriteLiteral("</div>\r\n");
#line 174 "..\..\Views\Device\Export.cshtml" #line 178 "..\..\Views\Device\Export.cshtml"
if (Model.ExportSessionId != null) if (Model.ExportSessionId != null)
{ {
@@ -587,10 +597,37 @@ WriteLiteral(" class=\"dialog\"");
WriteLiteral(" title=\"Export Devices\""); WriteLiteral(" title=\"Export Devices\"");
WriteLiteral(">\r\n <h4>"); WriteLiteral(">\r\n");
#line 177 "..\..\Views\Device\Export.cshtml" #line 181 "..\..\Views\Device\Export.cshtml"
#line default
#line hidden
#line 181 "..\..\Views\Device\Export.cshtml"
if (Model.ExportSessionResult.RecordCount == 0)
{
#line default
#line hidden
WriteLiteral(" <h4>No records matched the filter criteria</h4>\r\n");
#line 184 "..\..\Views\Device\Export.cshtml"
}
else
{
#line default
#line hidden
WriteLiteral(" <h4>");
#line 187 "..\..\Views\Device\Export.cshtml"
Write(Model.ExportSessionResult.RecordCount); Write(Model.ExportSessionResult.RecordCount);
@@ -599,22 +636,24 @@ WriteLiteral(">\r\n <h4>");
WriteLiteral(" record"); WriteLiteral(" record");
#line 177 "..\..\Views\Device\Export.cshtml" #line 187 "..\..\Views\Device\Export.cshtml"
Write(Model.ExportSessionResult.RecordCount != 1 ? "s" : null); Write(Model.ExportSessionResult.RecordCount != 1 ? "s" : null);
#line default #line default
#line hidden #line hidden
WriteLiteral(" were successfully exported.</h4>\r\n <a"); WriteLiteral(" were successfully exported.</h4>\r\n");
WriteAttribute("href", Tuple.Create(" href=\"", 9415), Tuple.Create("\"", 9487) WriteLiteral(" <a");
#line 178 "..\..\Views\Device\Export.cshtml" WriteAttribute("href", Tuple.Create(" href=\"", 9710), Tuple.Create("\"", 9782)
, Tuple.Create(Tuple.Create("", 9422), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.Device.ExportRetrieve(Model.ExportSessionId))
#line 188 "..\..\Views\Device\Export.cshtml"
, Tuple.Create(Tuple.Create("", 9717), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.Device.ExportRetrieve(Model.ExportSessionId))
#line default #line default
#line hidden #line hidden
, 9422), false) , 9717), false)
); );
WriteLiteral(" class=\"button\""); WriteLiteral(" class=\"button\"");
@@ -623,7 +662,16 @@ WriteLiteral("><i");
WriteLiteral(" class=\"fa fa-download fa-lg\""); WriteLiteral(" class=\"fa fa-download fa-lg\"");
WriteLiteral("></i>Download Device Export</a>\r\n </div>\r\n"); WriteLiteral("></i>Download Device Export</a>\r\n");
#line 189 "..\..\Views\Device\Export.cshtml"
}
#line default
#line hidden
WriteLiteral(" </div>\r\n");
WriteLiteral(@" <script> WriteLiteral(@" <script>
$(function () { $(function () {
@@ -640,7 +688,7 @@ WriteLiteral(@" <script>
"); ");
#line 192 "..\..\Views\Device\Export.cshtml" #line 203 "..\..\Views\Device\Export.cshtml"
} }
+287
View File
@@ -0,0 +1,287 @@
@using Disco.Web.Models.Job;
@model ExportModel
@{
Authorization.RequireAny(Claims.Job.Actions.Export);
ViewBag.Title = Html.ToBreadcrumb("Jobs", MVC.Job.Index(), "Export Jobs");
var optionsMetadata = ModelMetadata.FromLambdaExpression(m => m.Options, ViewData);
var optionGroups = optionsMetadata.Properties.Where(p => p.ShortDisplayName != null && p.ModelType == typeof(bool))
.GroupBy(m => m.ShortDisplayName);
}
<div id="Jobs_Export">
@using (Html.BeginForm(MVC.API.Job.Export()))
{
@Html.AntiForgeryToken()
<div id="Jobs_Export_Type" class="form" style="width: 570px">
<h2>Export Filter</h2>
<table>
<tr>
<th style="width: 150px">
Start Date:
</th>
<td>
@Html.EditorFor(m => m.Options.FilterStartDate)
@Html.ValidationMessageFor(m => m.Options.FilterStartDate)
</td>
</tr>
<tr>
<th>End Date:</th>
<td>
@Html.EditorFor(m => m.Options.FilterEndDate)
@Html.ValidationMessageFor(m => m.Options.FilterEndDate)
</td>
</tr>
<tr>
<th>Status:</th>
<td>
@Html.DropDownListFor(m => m.Options.FilterJobStatusId, m => m.JobStatuses, i => i.Key, i => i.Value, "-- All Jobs --")
</td>
</tr>
<tr>
<td colspan="2" class="none">
<table class="sub">
<tr>
<th style="width: 150px; text-align: right;">Type:</th>
<td>
@Html.DropDownListFor(m => m.Options.FilterJobTypeId, m => m.JobTypes, i => i.Id, i => i.Description, "-- All Jobs --")
</td>
</tr>
<tr>
<td colspan="2" id="Jobs_Export_SubTypes">
@foreach (var jobType in Model.JobTypes)
{
var subTypes = jobType.JobSubTypes.OrderBy(s => s.Description).ToList();
var itemsPerColumn = (int)Math.Ceiling((double)subTypes.Count / 2);
<div id="Jobs_Export_SubTypes_@(jobType.Id)" class="Jobs_Export_SubType_Target" data-typeid="@jobType.Id">
@if (jobType.JobSubTypes.Count > 2)
{
<span class="select"><a class="selectAll" href="#">ALL</a> | <a class="selectNone" href="#">NONE</a></span>
}
<table class="none">
<tr>
<td style="width: 50%">
<ul class="none">
@foreach (var subType in subTypes.Take(itemsPerColumn))
{
<li>
<input type="checkbox" id="Jobs_Export_SubTypes_@(jobType.Id)_@(subType.Id)" name="Options.FilterJobSubTypeIds" value="@subType.Id" @((Model.Options.FilterJobTypeId == jobType.Id && Model.Options.FilterJobSubTypeIds.Contains(subType.Id)) ? "checked " : null) /><label for="Jobs_Export_SubTypes_@(jobType.Id)_@(subType.Id)">@subType.Description</label>
</li>
}
</ul>
</td>
<td style="width: 50%">
<ul class="none">
@foreach (var subType in subTypes.Skip(itemsPerColumn))
{
<li>
<input type="checkbox" id="Jobs_Export_SubTypes_@(jobType.Id)_@(subType.Id)" name="Options.FilterJobSubTypeIds" value="@subType.Id" @((Model.Options.FilterJobTypeId == jobType.Id && Model.Options.FilterJobSubTypeIds.Contains(subType.Id)) ? "checked " : null) /><label for="Jobs_Export_SubTypes_@(jobType.Id)_@(subType.Id)">@subType.Description</label>
</li>
}
</ul>
</td>
</tr>
</table>
</div>
}
</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>Job Queue:</th>
<td>
@Html.DropDownListFor(m => m.Options.FilterJobQueueId, m => m.JobQueues, i => i.Id.ToString(), i => i.Name, "-- All Jobs --")
</td>
</tr>
<tr>
<th>@Html.LabelFor(m => m.Options.Format)</th>
<td>
@Html.DropDownListFor(m => m.Options.Format, m => Enum.GetNames(typeof(Disco.Models.Exporting.ExportFormat)), i => i, i => i)
</td>
</tr>
</table>
</div>
<div id="Jobs_Export_Fields" class="form" style="width: 570px; margin-top: 15px;">
<h2>Export Fields <a id="Jobs_Export_Fields_Defaults" href="#">(Defaults)</a></h2>
<table>
@foreach (var optionGroup in optionGroups)
{
var optionFields = optionGroup.ToList();
var itemsPerColumn = (int)Math.Ceiling((double)optionFields.Count / 2);
<tr>
<th style="width: 120px;">
@optionGroup.Key
@if (optionFields.Count > 2)
{
<span style="display: block;" class="select"><a class="selectAll" href="#">ALL</a> | <a class="selectNone" href="#">NONE</a></span>
}
</th>
<td>
<div class="Jobs_Export_Fields_Group">
<table class="none">
<tr>
<td style="width: 50%">
<ul class="none">
@foreach (var optionItem in optionFields.Take(itemsPerColumn))
{
<li title="@optionItem.Description">
<input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null) /><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label>
</li>
}
</ul>
</td>
<td style="width: 50%">
<ul class="none">
@foreach (var optionItem in optionFields.Skip(itemsPerColumn))
{
<li title="@optionItem.Description">
<input type="checkbox" id="Options_@optionItem.PropertyName" name="Options.@optionItem.PropertyName" value="true" @(((bool)optionItem.Model) ? "checked " : null) /><label for="Options_@optionItem.PropertyName">@optionItem.DisplayName</label>
</li>
}
</ul>
</td>
</tr>
</table>
</div>
</td>
</tr>
}
</table>
</div>
<script>
$(function () {
const $FilterStartDate = $('#Options_FilterStartDate');
const $FilterEndDate = $('#Options_FilterEndDate');
const $FilterJobTypeId = $('#Options_FilterJobTypeId');
$FilterStartDate.attr('type', 'date');
$FilterEndDate.attr('type', 'date');
var exportDefaultFields = ['JobId', 'JobStatus', 'JobType', 'JobSubTypes', 'JobOpenedDate', 'DeviceSerialNumber', 'DeviceModelDescription', 'DeviceProfileName', 'UserId', 'UserDisplayName'];
var $exportFields = $('#Jobs_Export_Fields');
var $form = $FilterStartDate.closest('form');
function exportTypeChange() {
$exportTypeTargetContainers.hide();
$exportTypeTargetContainers.find('select').prop('disabled', true);
switch ($exportType.val()) {
case 'Batch':
$('#Devices_Export_Type_Target_Batch').show().find('select').prop('disabled', false);
break;
case 'Profile':
$('#Devices_Export_Type_Target_Profile').show().find('select').prop('disabled', false);
break;
case 'Model':
$('#Devices_Export_Type_Target_Model').show().find('select').prop('disabled', false);
break;
}
}
$FilterJobTypeId
.on('change', function (e) {
$('#Jobs_Export_SubTypes').hide()
.find('.Jobs_Export_SubType_Target').hide()
.find('input').prop('disabled', true);
const type = $(e.currentTarget).val();
if (type) {
$('#Jobs_Export_SubTypes').show()
$('#Jobs_Export_SubTypes_' + type).show()
.find('input').prop('disabled', false);
}
}).trigger('change');
$('#Jobs_Export_SubTypes').on('click', 'a.selectAll,a.selectNone', function (e) {
e.preventDefault();
var $this = $(this);
$this.closest('div').find('input').prop('checked', $this.is('.selectAll'));
return false;
});
$exportFields.on('click', 'a.selectAll,a.selectNone', function (e) {
e.preventDefault();
var $this = $(this);
$this.closest('tr').find('input').prop('checked', $this.is('.selectAll'));
return false;
});
$('#Jobs_Export_Fields_Defaults').click(function (e) {
e.preventDefault();
$exportFields.find('input').prop('checked', false);
$.each(exportDefaultFields, function (index, value) {
$('#Options_' + value).prop('checked', true);
});
return false;
});
$.validator.unobtrusive.parse($form);
$form.data("validator").settings.submitHandler = function () {
var exportFieldCount = $exportFields.find('input:checked').length;
if (exportFieldCount > 0) {
const $exportingDialog = $('#Devices_Export_Exporting').dialog({
width: 400,
height: 164,
resizable: false,
modal: true,
autoOpen: true
});
$form[0].submit();
}
else
alert('Select at least one field to export.');
};
$('#Devices_Export_Download_Dialog').dialog({
width: 400,
height: 164,
resizable: false,
modal: true,
autoOpen: true
});
$('#Jobs_Export_Button').click(function () {
$form.submit();
});
});
</script>
}
</div>
@if (Model.ExportSessionId != null)
{
<div id="Jobs_Export_Download_Dialog" class="dialog" title="Export Jobs">
@if (Model.ExportSessionResult.RecordCount == 0)
{
<h4>No records matched the filter criteria</h4>
}
else
{
<h4>@Model.ExportSessionResult.RecordCount record@(Model.ExportSessionResult.RecordCount != 1 ? "s" : null) were successfully exported.</h4>
<a href="@Url.Action(MVC.API.Job.ExportRetrieve(Model.ExportSessionId))" class="button"><i class="fa fa-download fa-lg"></i>Download Job Export</a>
}
</div>
<script>
$(function () {
$('#Jobs_Export_Download_Dialog')
.dialog({
width: 400,
height: 164,
resizable: false,
modal: true,
autoOpen: true
});
});
</script>
}
<div id="Jobs_Export_Exporting" class="dialog" title="Exporting Jobs...">
<h4><i class="fa fa-lg fa-cog fa-spin" title="Please Wait"></i>Exporting jobs...</h4>
</div>
<div class="actionBar">
<button id="Jobs_Export_Button" type="button" class="button">Export Jobs</button>
</div>
File diff suppressed because it is too large Load Diff
+6
View File
@@ -145,6 +145,12 @@
@Html.Partial(MVC.Shared.Views._JobTable, Model.StaleJobs, new ViewDataDictionary()) @Html.Partial(MVC.Shared.Views._JobTable, Model.StaleJobs, new ViewDataDictionary())
</div> </div>
} }
@if (Authorization.Has(Claims.Job.Actions.Export))
{
<div class="actionBar">
@Html.ActionLinkButton("Export Jobs", MVC.Job.Export())
</div>
}
@if (Model.PendingEnrollments != null && Model.PendingEnrollments.Count > 0 && Authorization.Has(Claims.Device.Actions.EnrolDevices)) @if (Model.PendingEnrollments != null && Model.PendingEnrollments.Count > 0 && Authorization.Has(Claims.Device.Actions.EnrolDevices))
{ {
<div id="pendingEnrollments"> <div id="pendingEnrollments">
+37 -5
View File
@@ -306,6 +306,38 @@ WriteLiteral("\r\n </div>\r\n");
#line hidden #line hidden
#line 148 "..\..\Views\Job\Index.cshtml" #line 148 "..\..\Views\Job\Index.cshtml"
if (Authorization.Has(Claims.Job.Actions.Export))
{
#line default
#line hidden
WriteLiteral(" <div");
WriteLiteral(" class=\"actionBar\"");
WriteLiteral(">\r\n");
WriteLiteral(" ");
#line 151 "..\..\Views\Job\Index.cshtml"
Write(Html.ActionLinkButton("Export Jobs", MVC.Job.Export()));
#line default
#line hidden
WriteLiteral("\r\n </div>\r\n");
#line 153 "..\..\Views\Job\Index.cshtml"
}
#line default
#line hidden
#line 154 "..\..\Views\Job\Index.cshtml"
if (Model.PendingEnrollments != null && Model.PendingEnrollments.Count > 0 && Authorization.Has(Claims.Device.Actions.EnrolDevices)) if (Model.PendingEnrollments != null && Model.PendingEnrollments.Count > 0 && Authorization.Has(Claims.Device.Actions.EnrolDevices))
{ {
@@ -323,14 +355,14 @@ WriteLiteral(" class=\"fa fa-exclamation-circle info\"");
WriteLiteral("></i>\r\n <div>There are device enrollments pending approval.</div>\r\n " + WriteLiteral("></i>\r\n <div>There are device enrollments pending approval.</div>\r\n " +
" <a"); " <a");
WriteAttribute("href", Tuple.Create(" href=\"", 6766), Tuple.Create("\"", 6815) WriteAttribute("href", Tuple.Create(" href=\"", 6930), Tuple.Create("\"", 6979)
#line 153 "..\..\Views\Job\Index.cshtml" #line 159 "..\..\Views\Job\Index.cshtml"
, Tuple.Create(Tuple.Create("", 6773), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.Config.Enrolment.Status()) , Tuple.Create(Tuple.Create("", 6937), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.Config.Enrolment.Status())
#line default #line default
#line hidden #line hidden
, 6773), false) , 6937), false)
); );
WriteLiteral(" class=\"button small alert\""); WriteLiteral(" class=\"button small alert\"");
@@ -345,7 +377,7 @@ WriteLiteral(" <script>\r\n $(function () {\r\n var layout_
" </script>\r\n"); " </script>\r\n");
#line 163 "..\..\Views\Job\Index.cshtml" #line 169 "..\..\Views\Job\Index.cshtml"
} }
#line default #line default
+1 -1
View File
@@ -1,5 +1,5 @@
@model Disco.Web.Models.Job.ShowModel @model Disco.Web.Models.Job.ShowModel
@using Disco.Models.Services.Job; @using Disco.Models.Services.Jobs;
@using Disco.Services.Users.UserFlags; @using Disco.Services.Users.UserFlags;
@using Disco.Services.Devices.DeviceFlags; @using Disco.Services.Devices.DeviceFlags;
@{ @{
@@ -30,7 +30,7 @@ namespace Disco.Web.Views.Job.JobParts
using Disco.Models.Repository; using Disco.Models.Repository;
#line 2 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 2 "..\..\Views\Job\JobParts\_Subject.cshtml"
using Disco.Models.Services.Job; using Disco.Models.Services.Jobs;
#line default #line default
#line hidden #line hidden
@@ -317,14 +317,14 @@ WriteLiteral(" class=\"status\"");
WriteLiteral(">\r\n <h2"); WriteLiteral(">\r\n <h2");
WriteAttribute("title", Tuple.Create(" title=\"", 5822), Tuple.Create("\"", 5851) WriteAttribute("title", Tuple.Create(" title=\"", 5823), Tuple.Create("\"", 5852)
#line 90 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 90 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 5830), Tuple.Create<System.Object, System.Int32>(Model.Job.JobType.Id , Tuple.Create(Tuple.Create("", 5831), Tuple.Create<System.Object, System.Int32>(Model.Job.JobType.Id
#line default #line default
#line hidden #line hidden
, 5830), false) , 5831), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -378,14 +378,14 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <li"); WriteLiteral(" <li");
WriteAttribute("title", Tuple.Create(" title=\"", 6439), Tuple.Create("\"", 6461) WriteAttribute("title", Tuple.Create(" title=\"", 6440), Tuple.Create("\"", 6462)
#line 100 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 100 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 6447), Tuple.Create<System.Object, System.Int32>(jobSubType.Id , Tuple.Create(Tuple.Create("", 6448), Tuple.Create<System.Object, System.Int32>(jobSubType.Id
#line default #line default
#line hidden #line hidden
, 6447), false) , 6448), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -429,14 +429,14 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <li"); WriteLiteral(" <li");
WriteAttribute("title", Tuple.Create(" title=\"", 6899), Tuple.Create("\"", 6921) WriteAttribute("title", Tuple.Create(" title=\"", 6900), Tuple.Create("\"", 6922)
#line 108 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 108 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 6907), Tuple.Create<System.Object, System.Int32>(jobSubType.Id , Tuple.Create(Tuple.Create("", 6908), Tuple.Create<System.Object, System.Int32>(jobSubType.Id
#line default #line default
#line hidden #line hidden
, 6907), false) , 6908), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -739,14 +739,14 @@ WriteLiteral(" id=\"Job_Show_Device_Model_Image\"");
WriteLiteral(" alt=\"Model Image\""); WriteLiteral(" alt=\"Model Image\"");
WriteAttribute("src", Tuple.Create(" src=\"", 11534), Tuple.Create("\"", 11652) WriteAttribute("src", Tuple.Create(" src=\"", 11535), Tuple.Create("\"", 11653)
#line 187 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 187 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 11540), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.DeviceModel.Image(Model.Job.Device.DeviceModelId, Model.Job.Device.DeviceModel.ImageHash())) , Tuple.Create(Tuple.Create("", 11541), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.DeviceModel.Image(Model.Job.Device.DeviceModelId, Model.Job.Device.DeviceModel.ImageHash()))
#line default #line default
#line hidden #line hidden
, 11540), false) , 11541), false)
); );
WriteLiteral(" />\r\n <div"); WriteLiteral(" />\r\n <div");
@@ -890,17 +890,17 @@ WriteLiteral(" id=\"Job_Show_Device_Details_HWar_Details_Dialog\"");
WriteLiteral(" class=\"dialog\""); WriteLiteral(" class=\"dialog\"");
WriteAttribute("title", Tuple.Create(" title=\"", 13356), Tuple.Create("\"", 13421) WriteAttribute("title", Tuple.Create(" title=\"", 13357), Tuple.Create("\"", 13422)
, Tuple.Create(Tuple.Create("", 13364), Tuple.Create("Warranty", 13364), true) , Tuple.Create(Tuple.Create("", 13365), Tuple.Create("Warranty", 13365), true)
, Tuple.Create(Tuple.Create(" ", 13372), Tuple.Create("Details", 13373), true) , Tuple.Create(Tuple.Create(" ", 13373), Tuple.Create("Details", 13374), true)
, Tuple.Create(Tuple.Create(" ", 13380), Tuple.Create("for", 13381), true) , Tuple.Create(Tuple.Create(" ", 13381), Tuple.Create("for", 13382), true)
#line 204 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 204 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create(" ", 13384), Tuple.Create<System.Object, System.Int32>(Model.Job.Device.DeviceBatch.Name , Tuple.Create(Tuple.Create(" ", 13385), Tuple.Create<System.Object, System.Int32>(Model.Job.Device.DeviceBatch.Name
#line default #line default
#line hidden #line hidden
, 13385), false) , 13386), false)
); );
WriteLiteral(">\r\n <div>"); WriteLiteral(">\r\n <div>");
@@ -1025,17 +1025,17 @@ WriteLiteral(" id=\"Job_Show_Device_Details_HNWar_Details_Dialog\"");
WriteLiteral(" class=\"dialog\""); WriteLiteral(" class=\"dialog\"");
WriteAttribute("title", Tuple.Create(" title=\"", 15908), Tuple.Create("\"", 15974) WriteAttribute("title", Tuple.Create(" title=\"", 15909), Tuple.Create("\"", 15975)
, Tuple.Create(Tuple.Create("", 15916), Tuple.Create("Insurance", 15916), true) , Tuple.Create(Tuple.Create("", 15917), Tuple.Create("Insurance", 15917), true)
, Tuple.Create(Tuple.Create(" ", 15925), Tuple.Create("Details", 15926), true) , Tuple.Create(Tuple.Create(" ", 15926), Tuple.Create("Details", 15927), true)
, Tuple.Create(Tuple.Create(" ", 15933), Tuple.Create("for", 15934), true) , Tuple.Create(Tuple.Create(" ", 15934), Tuple.Create("for", 15935), true)
#line 234 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 234 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create(" ", 15937), Tuple.Create<System.Object, System.Int32>(Model.Job.Device.DeviceBatch.Name , Tuple.Create(Tuple.Create(" ", 15938), Tuple.Create<System.Object, System.Int32>(Model.Job.Device.DeviceBatch.Name
#line default #line default
#line hidden #line hidden
, 15938), false) , 15939), false)
); );
WriteLiteral(">\r\n <div>"); WriteLiteral(">\r\n <div>");
@@ -1121,26 +1121,26 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <i"); WriteLiteral(" <i");
WriteAttribute("class", Tuple.Create(" class=\"", 18091), Tuple.Create("\"", 18161) WriteAttribute("class", Tuple.Create(" class=\"", 18092), Tuple.Create("\"", 18162)
, Tuple.Create(Tuple.Create("", 18099), Tuple.Create("flag", 18099), true) , Tuple.Create(Tuple.Create("", 18100), Tuple.Create("flag", 18100), true)
, Tuple.Create(Tuple.Create(" ", 18103), Tuple.Create("fa", 18104), true) , Tuple.Create(Tuple.Create(" ", 18104), Tuple.Create("fa", 18105), true)
, Tuple.Create(Tuple.Create(" ", 18106), Tuple.Create("fa-", 18107), true) , Tuple.Create(Tuple.Create(" ", 18107), Tuple.Create("fa-", 18108), true)
#line 263 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 263 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 18110), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon , Tuple.Create(Tuple.Create("", 18111), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon
#line default #line default
#line hidden #line hidden
, 18110), false) , 18111), false)
, Tuple.Create(Tuple.Create(" ", 18128), Tuple.Create("fa-fw", 18129), true) , Tuple.Create(Tuple.Create(" ", 18129), Tuple.Create("fa-fw", 18130), true)
, Tuple.Create(Tuple.Create(" ", 18134), Tuple.Create("d-", 18135), true) , Tuple.Create(Tuple.Create(" ", 18135), Tuple.Create("d-", 18136), true)
#line 263 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 263 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 18137), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour , Tuple.Create(Tuple.Create("", 18138), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour
#line default #line default
#line hidden #line hidden
, 18137), false) , 18138), false)
); );
WriteLiteral(">\r\n <span"); WriteLiteral(">\r\n <span");
@@ -1735,14 +1735,14 @@ WriteLiteral(">\r\n <img");
WriteLiteral(" id=\"Job_Show_User_Photo\""); WriteLiteral(" id=\"Job_Show_User_Photo\"");
WriteAttribute("src", Tuple.Create(" src=\"", 33689), Tuple.Create("\"", 33744) WriteAttribute("src", Tuple.Create(" src=\"", 33690), Tuple.Create("\"", 33745)
#line 481 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 481 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 33695), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.User.Photo(Model.Job.UserId)) , Tuple.Create(Tuple.Create("", 33696), Tuple.Create<System.Object, System.Int32>(Url.Action(MVC.API.User.Photo(Model.Job.UserId))
#line default #line default
#line hidden #line hidden
, 33695), false) , 33696), false)
); );
WriteLiteral(" />\r\n </div>\r\n"); WriteLiteral(" />\r\n </div>\r\n");
@@ -1844,15 +1844,15 @@ WriteLiteral(" title=\"Phone Number\"");
WriteLiteral(">Phone: <a"); WriteLiteral(">Phone: <a");
WriteAttribute("href", Tuple.Create(" href=\"", 34522), Tuple.Create("\"", 34560) WriteAttribute("href", Tuple.Create(" href=\"", 34523), Tuple.Create("\"", 34561)
, Tuple.Create(Tuple.Create("", 34529), Tuple.Create("tel:", 34529), true) , Tuple.Create(Tuple.Create("", 34530), Tuple.Create("tel:", 34530), true)
#line 494 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 494 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 34533), Tuple.Create<System.Object, System.Int32>(Model.Job.User.PhoneNumber , Tuple.Create(Tuple.Create("", 34534), Tuple.Create<System.Object, System.Int32>(Model.Job.User.PhoneNumber
#line default #line default
#line hidden #line hidden
, 34533), false) , 34534), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -1882,15 +1882,15 @@ WriteLiteral(" title=\"Email Address\"");
WriteLiteral(">Email: <a"); WriteLiteral(">Email: <a");
WriteAttribute("href", Tuple.Create(" href=\"", 34773), Tuple.Create("\"", 34817) WriteAttribute("href", Tuple.Create(" href=\"", 34774), Tuple.Create("\"", 34818)
, Tuple.Create(Tuple.Create("", 34780), Tuple.Create("mailto:", 34780), true) , Tuple.Create(Tuple.Create("", 34781), Tuple.Create("mailto:", 34781), true)
#line 496 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 496 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 34787), Tuple.Create<System.Object, System.Int32>(Model.Job.User.EmailAddress , Tuple.Create(Tuple.Create("", 34788), Tuple.Create<System.Object, System.Int32>(Model.Job.User.EmailAddress
#line default #line default
#line hidden #line hidden
, 34787), false) , 34788), false)
); );
WriteLiteral(">"); WriteLiteral(">");
@@ -1944,26 +1944,26 @@ WriteLiteral(">\r\n");
#line hidden #line hidden
WriteLiteral(" <i"); WriteLiteral(" <i");
WriteAttribute("class", Tuple.Create(" class=\"", 35292), Tuple.Create("\"", 35362) WriteAttribute("class", Tuple.Create(" class=\"", 35293), Tuple.Create("\"", 35363)
, Tuple.Create(Tuple.Create("", 35300), Tuple.Create("flag", 35300), true) , Tuple.Create(Tuple.Create("", 35301), Tuple.Create("flag", 35301), true)
, Tuple.Create(Tuple.Create(" ", 35304), Tuple.Create("fa", 35305), true) , Tuple.Create(Tuple.Create(" ", 35305), Tuple.Create("fa", 35306), true)
, Tuple.Create(Tuple.Create(" ", 35307), Tuple.Create("fa-", 35308), true) , Tuple.Create(Tuple.Create(" ", 35308), Tuple.Create("fa-", 35309), true)
#line 503 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 503 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 35311), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon , Tuple.Create(Tuple.Create("", 35312), Tuple.Create<System.Object, System.Int32>(flag.Item2.Icon
#line default #line default
#line hidden #line hidden
, 35311), false) , 35312), false)
, Tuple.Create(Tuple.Create(" ", 35329), Tuple.Create("fa-fw", 35330), true) , Tuple.Create(Tuple.Create(" ", 35330), Tuple.Create("fa-fw", 35331), true)
, Tuple.Create(Tuple.Create(" ", 35335), Tuple.Create("d-", 35336), true) , Tuple.Create(Tuple.Create(" ", 35336), Tuple.Create("d-", 35337), true)
#line 503 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 503 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 35338), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour , Tuple.Create(Tuple.Create("", 35339), Tuple.Create<System.Object, System.Int32>(flag.Item2.IconColour
#line default #line default
#line hidden #line hidden
, 35338), false) , 35339), false)
); );
WriteLiteral(">\r\n <span"); WriteLiteral(">\r\n <span");
@@ -2722,14 +2722,14 @@ WriteLiteral(" type=\"hidden\"");
WriteLiteral(" name=\"JobId\""); WriteLiteral(" name=\"JobId\"");
WriteAttribute("value", Tuple.Create(" value=\"", 50881), Tuple.Create("\"", 50902) WriteAttribute("value", Tuple.Create(" value=\"", 50882), Tuple.Create("\"", 50903)
#line 780 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 780 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 50889), Tuple.Create<System.Object, System.Int32>(Model.Job.Id , Tuple.Create(Tuple.Create("", 50890), Tuple.Create<System.Object, System.Int32>(Model.Job.Id
#line default #line default
#line hidden #line hidden
, 50889), false) , 50890), false)
); );
WriteLiteral(" />\r\n"); WriteLiteral(" />\r\n");
@@ -2793,26 +2793,26 @@ WriteLiteral("\"");
WriteLiteral(">\r\n <i"); WriteLiteral(">\r\n <i");
WriteAttribute("class", Tuple.Create(" class=\"", 51371), Tuple.Create("\"", 51438) WriteAttribute("class", Tuple.Create(" class=\"", 51372), Tuple.Create("\"", 51439)
, Tuple.Create(Tuple.Create("", 51379), Tuple.Create("fa", 51379), true) , Tuple.Create(Tuple.Create("", 51380), Tuple.Create("fa", 51380), true)
, Tuple.Create(Tuple.Create(" ", 51381), Tuple.Create("fa-", 51382), true) , Tuple.Create(Tuple.Create(" ", 51382), Tuple.Create("fa-", 51383), true)
#line 785 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 785 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 51385), Tuple.Create<System.Object, System.Int32>(jobQueue.Icon , Tuple.Create(Tuple.Create("", 51386), Tuple.Create<System.Object, System.Int32>(jobQueue.Icon
#line default #line default
#line hidden #line hidden
, 51385), false) , 51386), false)
, Tuple.Create(Tuple.Create(" ", 51401), Tuple.Create("fa-fw", 51402), true) , Tuple.Create(Tuple.Create(" ", 51402), Tuple.Create("fa-fw", 51403), true)
, Tuple.Create(Tuple.Create(" ", 51407), Tuple.Create("fa-lg", 51408), true) , Tuple.Create(Tuple.Create(" ", 51408), Tuple.Create("fa-lg", 51409), true)
, Tuple.Create(Tuple.Create(" ", 51413), Tuple.Create("d-", 51414), true) , Tuple.Create(Tuple.Create(" ", 51414), Tuple.Create("d-", 51415), true)
#line 785 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 785 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 51416), Tuple.Create<System.Object, System.Int32>(jobQueue.IconColour , Tuple.Create(Tuple.Create("", 51417), Tuple.Create<System.Object, System.Int32>(jobQueue.IconColour
#line default #line default
#line hidden #line hidden
, 51416), false) , 51417), false)
); );
WriteLiteral("></i>"); WriteLiteral("></i>");
@@ -2853,27 +2853,27 @@ WriteLiteral(" ");
#line hidden #line hidden
WriteLiteral(" <i"); WriteLiteral(" <i");
WriteAttribute("class", Tuple.Create(" class=\"", 51835), Tuple.Create("\"", 51883) WriteAttribute("class", Tuple.Create(" class=\"", 51836), Tuple.Create("\"", 51884)
, Tuple.Create(Tuple.Create("", 51843), Tuple.Create("fa", 51843), true) , Tuple.Create(Tuple.Create("", 51844), Tuple.Create("fa", 51844), true)
, Tuple.Create(Tuple.Create(" ", 51845), Tuple.Create("d-priority-", 51846), true) , Tuple.Create(Tuple.Create(" ", 51846), Tuple.Create("d-priority-", 51847), true)
#line 792 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 792 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 51857), Tuple.Create<System.Object, System.Int32>(priorityValue.ToLower() , Tuple.Create(Tuple.Create("", 51858), Tuple.Create<System.Object, System.Int32>(priorityValue.ToLower()
#line default #line default
#line hidden #line hidden
, 51857), false) , 51858), false)
); );
WriteAttribute("title", Tuple.Create(" title=\"", 51884), Tuple.Create("\"", 51917) WriteAttribute("title", Tuple.Create(" title=\"", 51885), Tuple.Create("\"", 51918)
#line 792 "..\..\Views\Job\JobParts\_Subject.cshtml" #line 792 "..\..\Views\Job\JobParts\_Subject.cshtml"
, Tuple.Create(Tuple.Create("", 51892), Tuple.Create<System.Object, System.Int32>(priorityValue , Tuple.Create(Tuple.Create("", 51893), Tuple.Create<System.Object, System.Int32>(priorityValue
#line default #line default
#line hidden #line hidden
, 51892), false) , 51893), false)
, Tuple.Create(Tuple.Create(" ", 51908), Tuple.Create("Priority", 51909), true) , Tuple.Create(Tuple.Create(" ", 51909), Tuple.Create("Priority", 51910), true)
); );
WriteLiteral("></i>\r\n </div>\r\n <div>\r\n " + WriteLiteral("></i>\r\n </div>\r\n <div>\r\n " +