using Disco.Models.Repository; using Disco.Models.Services.Jobs; using Disco.Models.Services.Jobs.JobLists; using Disco.Services; using Disco.Services.Authorization; using Disco.Services.Exporting; using Disco.Services.Interop; using Disco.Services.Interop.DiscoServices.Upload; using Disco.Services.Jobs; using Disco.Services.Jobs.JobLists; using Disco.Services.Jobs.Statistics; using Disco.Services.Users; using Disco.Services.Web; using Disco.Web.Extensions; using Disco.Web.Models.Job; using System; using System.Collections.Generic; using System.Data.Entity; using System.IO; using System.IO.Compression; using System.Linq; using System.Threading.Tasks; using System.Web.Caching; using System.Web.Mvc; namespace Disco.Web.Areas.API.Controllers { public partial class JobController : AuthorizedDatabaseController { #region Property Constants private const string pExpectedClosedDate = "expectedcloseddate"; private const string pDeviceHeldLocation = "deviceheldlocation"; private const string pFlags = "flags"; private const string pNonWarrantyAccountingChargeRequired = "nonwarrantyaccountingchargerequired"; private const string pNonWarrantyAccountingChargeAdded = "nonwarrantyaccountingchargeadded"; private const string pNonWarrantyAccountingChargePaid = "nonwarrantyaccountingchargepaid"; private const string pNonWarrantyPurchaseOrderRaised = "nonwarrantypurchaseorderraised"; private const string pNonWarrantyPurchaseOrderReference = "nonwarrantypurchaseorderreference"; private const string pNonWarrantyPurchaseOrderSent = "nonwarrantypurchaseordersent"; private const string pNonWarrantyInvoiceReceived = "nonwarrantyinvoicereceived"; private const string pNonWarrantyRepairerName = "nonwarrantyrepairername"; private const string pNonWarrantyRepairerLoggedDate = "nonwarrantyrepairerloggeddate"; private const string pNonWarrantyRepairerReference = "nonwarrantyrepairerreference"; private const string pNonWarrantyRepairerCompletedDate = "nonwarrantyrepairercompleteddate"; private const string pNonWarrantyIsInsuranceClaim = "nonwarrantyinsuranceisinsuranceclaim"; private const string pInsuranceLossOrDamageDate = "insurancelossordamagedate"; private const string pInsuranceEventLocation = "insuranceeventlocation"; private const string pInsuranceDescription = "insurancedescription"; private const string pInsuranceThirdPartyCaused = "insurancethirdpartycaused"; private const string pInsuranceThirdPartyCausedName = "insurancethirdpartycausedname"; private const string pInsuranceThirdPartyCausedWhy = "insurancethirdpartycausedwhy"; private const string pInsuranceWitnessesNamesAddresses = "insurancewitnessesnamesaddresses"; private const string pInsuranceBurglaryTheftMethodOfEntry = "insuranceburglarytheftmethodofentry"; private const string pInsurancePropertyLastSeenDate = "insurancepropertylastseendate"; private const string pInsurancePoliceNotified = "insurancepolicenotified"; private const string pInsurancePoliceNotifiedStation = "insurancepolicenotifiedstation"; private const string pInsurancePoliceNotifiedDate = "insurancepolicenotifieddate"; private const string pInsurancePoliceNotifiedCrimeReportNo = "insurancepolicenotifiedcrimereportno"; private const string pInsuranceRecoverReduceAction = "insurancerecoverreduceaction"; private const string pInsuranceOtherInterestedParties = "insuranceotherinterestedparties"; private const string pInsuranceDateOfPurchase = "insurancedateofpurchase"; private const string pInsuranceClaimFormSentDate = "insuranceclaimformsentdate"; private const string pInsuranceClaimFormSentUserId = "insuranceclaimformsentuserid"; private const string pWarrantyExternalName = "warrantyexternalname"; private const string pWarrantyExternalLoggedDate = "warrantyexternalloggeddate"; private const string pWarrantyExternalReference = "warrantyexternalreference"; private const string pWarrantyExternalCompletedDate = "warrantyexternalcompleteddate"; private const string pJobDetailsTabResources = "jobDetailTab-Resources"; private const string pJobDetailsTabComponents = "jobDetailTab-Components"; private const string pJobDetailsTabNonWarrantyFinance = "jobDetailTab-NonWarrantyFinance"; private const string pJobDetailsTabNonWarrantyRepairs = "jobDetailTab-NonWarrantyRepairs"; private const string pJobDetailsTabNonWarrantyInsurance = "jobDetailTab-NonWarrantyInsurance"; private const string pJobDetailsTabWarranty = "jobDetailTab-Warranty"; private const string pJobDetailsTabFlags = "jobDetailTab-Flags"; #endregion [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult Update(int id, string key, string value = null, bool? redirect = null) { try { if (id < 0) throw new ArgumentOutOfRangeException("id"); if (string.IsNullOrEmpty(key)) throw new ArgumentNullException("key"); var authToken = UserService.CurrentAuthorization; Database.Configuration.LazyLoadingEnabled = true; var job = Database.Jobs.Find(id); object resultData = null; string resultUrlFragment = null; if (job != null) { switch (key.ToLower()) { case pExpectedClosedDate: Authorization.Require(Claims.Job.Properties.ExpectedClosedDate); UpdateExpectedClosedDate(job, value); break; case pDeviceHeldLocation: Authorization.Require(Claims.Job.Properties.DeviceHeldLocation); UpdateDeviceHeldLocation(job, value); break; case pFlags: Authorization.Require(Claims.Job.Properties.Flags); UpdateFlags(job, value); resultUrlFragment = pJobDetailsTabFlags; break; case pNonWarrantyAccountingChargeRequired: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.AccountingChargeRequired); resultData = UpdateNonWarrantyAccountingChargeRequired(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyFinance; break; case pNonWarrantyAccountingChargeAdded: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.AccountingChargeAdded); resultData = UpdateNonWarrantyAccountingChargeAdded(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyFinance; break; case pNonWarrantyAccountingChargePaid: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.AccountingChargePaid); resultData = UpdateNonWarrantyAccountingChargePaid(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyFinance; break; case pNonWarrantyPurchaseOrderRaised: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.PurchaseOrderRaised); resultData = UpdateNonWarrantyPurchaseOrderRaised(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyFinance; break; case pNonWarrantyPurchaseOrderReference: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.PurchaseOrderReference); UpdateNonWarrantyPurchaseOrderReference(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyFinance; break; case pNonWarrantyPurchaseOrderSent: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.PurchaseOrderSent); resultData = UpdateNonWarrantyPurchaseOrderSent(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyFinance; break; case pNonWarrantyInvoiceReceived: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InvoiceReceived); resultData = UpdateNonWarrantyInvoiceReceived(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyFinance; break; case pNonWarrantyRepairerName: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.RepairerName); UpdateNonWarrantyRepairerName(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyRepairs; break; case pNonWarrantyRepairerLoggedDate: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.RepairerLoggedDate); UpdateNonWarrantyRepairerLoggedDate(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyRepairs; break; case pNonWarrantyRepairerReference: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.RepairerReference); UpdateNonWarrantyRepairerReference(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyRepairs; break; case pNonWarrantyRepairerCompletedDate: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.RepairerCompletedDate); UpdateNonWarrantyRepairerCompletedDate(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyRepairs; break; case pNonWarrantyIsInsuranceClaim: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.IsInsuranceClaim); UpdateNonWarrantyIsInsuranceClaim(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceLossOrDamageDate: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceLossOrDamageDate(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceEventLocation: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceEventLocation(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceDescription: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceDescription(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceThirdPartyCaused: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceThirdPartyCaused(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceThirdPartyCausedName: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceThirdPartyCausedName(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceThirdPartyCausedWhy: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceThirdPartyCausedWhy(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceWitnessesNamesAddresses: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceWitnessesNamesAddresses(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceBurglaryTheftMethodOfEntry: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceBurglaryTheftMethodOfEntry(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsurancePropertyLastSeenDate: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsurancePropertyLastSeenDate(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsurancePoliceNotified: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsurancePoliceNotified(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsurancePoliceNotifiedStation: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsurancePoliceNotifiedStation(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsurancePoliceNotifiedDate: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsurancePoliceNotifiedDate(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsurancePoliceNotifiedCrimeReportNo: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsurancePoliceNotifiedCrimeReportNo(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceRecoverReduceAction: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceRecoverReduceAction(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceOtherInterestedParties: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceOtherInterestedParties(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceDateOfPurchase: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails); UpdateInsuranceDateOfPurchase(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pInsuranceClaimFormSentDate: Authorization.Require(Claims.Job.Properties.NonWarrantyProperties.InsuranceClaimFormSent); resultData = UpdateInsuranceClaimFormSentDate(job, value); resultUrlFragment = pJobDetailsTabNonWarrantyInsurance; break; case pWarrantyExternalName: Authorization.Require(Claims.Job.Properties.WarrantyProperties.ExternalName); UpdateWarrantyExternalName(job, value); resultUrlFragment = pJobDetailsTabWarranty; break; case pWarrantyExternalLoggedDate: Authorization.Require(Claims.Job.Properties.WarrantyProperties.ExternalLoggedDate); UpdateWarrantyExternalLoggedDate(job, value); resultUrlFragment = pJobDetailsTabWarranty; break; case pWarrantyExternalReference: Authorization.Require(Claims.Job.Properties.WarrantyProperties.ExternalReference); UpdateWarrantyExternalReference(job, value); resultUrlFragment = pJobDetailsTabWarranty; break; case pWarrantyExternalCompletedDate: Authorization.Require(Claims.Job.Properties.WarrantyProperties.ExternalCompletedDate); UpdateWarrantyExternalCompletedDate(job, value); resultUrlFragment = pJobDetailsTabWarranty; break; default: throw new Exception("Invalid Update Key"); } } else { throw new Exception("Invalid Job Id"); } if (redirect.HasValue && redirect.Value) return this.RedirectToAction(MVC.Job.Show(job.Id), resultUrlFragment); else { if (resultData != null) { return Json(resultData, JsonRequestBehavior.AllowGet); } else { return Ok(); } } } catch (Exception ex) { if (redirect.HasValue && redirect.Value) throw; else return BadRequest(ex.Message); } } #region Update Shortcut Methods [DiscoAuthorize(Claims.Job.Properties.ExpectedClosedDate)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateExpectedClosedDate(int id, string ExpectedClosedDate, bool? redirect = null) { return Update(id, pExpectedClosedDate, ExpectedClosedDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.DeviceHeldLocation)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateDeviceHeldLocation(int id, string DeviceHeldLocation, bool? redirect = null) { return Update(id, pDeviceHeldLocation, DeviceHeldLocation, redirect); } [DiscoAuthorize(Claims.Job.Properties.Flags)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateFlags(int id, string Flags, bool? redirect = null) { return Update(id, pFlags, Flags, redirect); } #region NonWarranty [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.AccountingChargeRequired)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyAccountingChargeRequired(int id, string AccountingChargeRequiredDate, bool? redirect = null) { return Update(id, pNonWarrantyAccountingChargeRequired, AccountingChargeRequiredDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.AccountingChargeAdded)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyAccountingChargeAdded(int id, string AccountingChargeAddedDate, bool? redirect = null) { return Update(id, pNonWarrantyAccountingChargeAdded, AccountingChargeAddedDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.AccountingChargePaid)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyAccountingChargePaid(int id, string AccountingChargePaidDate, bool? redirect = null) { return Update(id, pNonWarrantyAccountingChargePaid, AccountingChargePaidDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.PurchaseOrderRaised)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyPurchaseOrderRaised(int id, string PurchaseOrderRaisedDate, bool? redirect = null) { return Update(id, pNonWarrantyPurchaseOrderRaised, PurchaseOrderRaisedDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.PurchaseOrderReference)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyPurchaseOrderReference(int id, string PurchaseOrderReference, bool? redirect = null) { return Update(id, pNonWarrantyPurchaseOrderReference, PurchaseOrderReference, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.PurchaseOrderSent)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyPurchaseOrderSent(int id, string PurchaseOrderSentDate, bool? redirect = null) { return Update(id, pNonWarrantyPurchaseOrderSent, PurchaseOrderSentDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InvoiceReceived)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyInvoiceReceived(int id, string InvoiceReceivedDate, bool? redirect = null) { return Update(id, pNonWarrantyInvoiceReceived, InvoiceReceivedDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.RepairerName)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyRepairerName(int id, string RepairerName, bool? redirect = null) { return Update(id, pNonWarrantyRepairerName, RepairerName, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.RepairerLoggedDate)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyRepairerLoggedDate(int id, string RepairerLoggedDate, bool? redirect = null) { return Update(id, pNonWarrantyRepairerLoggedDate, RepairerLoggedDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.RepairerReference)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyRepairerReference(int id, string RepairerReference, bool? redirect = null) { return Update(id, pNonWarrantyRepairerReference, RepairerReference, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.RepairerCompletedDate)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyRepairerCompletedDate(int id, string RepairerCompletedDate, bool? redirect = null) { return Update(id, pNonWarrantyRepairerCompletedDate, RepairerCompletedDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.IsInsuranceClaim)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateNonWarrantyIsInsuranceClaim(int id, bool IsInsuranceClaim, bool? redirect = null) { return Update(id, pNonWarrantyIsInsuranceClaim, IsInsuranceClaim.ToString(), redirect); } #endregion #region Insurance [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceLossOrDamageDate(int id, string LossOrDamageDate, bool? redirect = null) { return Update(id, pInsuranceLossOrDamageDate, LossOrDamageDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceEventLocation(int id, string EventLocation, bool? redirect = null) { return Update(id, pInsuranceEventLocation, EventLocation, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceDescription(int id, string Description, bool? redirect = null) { return Update(id, pInsuranceDescription, Description, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceThirdPartyCaused(int id, string ThirdPartyCaused, bool? redirect = null) { return Update(id, pInsuranceThirdPartyCaused, ThirdPartyCaused, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceThirdPartyCausedName(int id, string ThirdPartyCausedName, bool? redirect = null) { return Update(id, pInsuranceThirdPartyCausedName, ThirdPartyCausedName, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceThirdPartyCausedWhy(int id, string ThirdPartyCausedWhy, bool? redirect = null) { return Update(id, pInsuranceThirdPartyCausedWhy, ThirdPartyCausedWhy, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceWitnessesNamesAddresses(int id, string WitnessesNamesAddresses, bool? redirect = null) { return Update(id, pInsuranceWitnessesNamesAddresses, WitnessesNamesAddresses, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceBurglaryTheftMethodOfEntry(int id, string BurglaryTheftMethodOfEntry, bool? redirect = null) { return Update(id, pInsuranceBurglaryTheftMethodOfEntry, BurglaryTheftMethodOfEntry, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsurancePropertyLastSeenDate(int id, string PropertyLastSeenDate, bool? redirect = null) { return Update(id, pInsurancePropertyLastSeenDate, PropertyLastSeenDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsurancePoliceNotified(int id, string PoliceNotified, bool? redirect = null) { return Update(id, pInsurancePoliceNotified, PoliceNotified, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsurancePoliceNotifiedStation(int id, string PoliceNotifiedStation, bool? redirect = null) { return Update(id, pInsurancePoliceNotifiedStation, PoliceNotifiedStation, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsurancePoliceNotifiedDate(int id, string PoliceNotifiedDate, bool? redirect = null) { return Update(id, pInsurancePoliceNotifiedDate, PoliceNotifiedDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsurancePoliceNotifiedCrimeReportNo(int id, string PoliceNotifiedCrimeReportNo, bool? redirect = null) { return Update(id, pInsurancePoliceNotifiedCrimeReportNo, PoliceNotifiedCrimeReportNo, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceRecoverReduceAction(int id, string RecoverReduceAction, bool? redirect = null) { return Update(id, pInsuranceRecoverReduceAction, RecoverReduceAction, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceOtherInterestedParties(int id, string OtherInterestedParties, bool? redirect = null) { return Update(id, pInsuranceOtherInterestedParties, OtherInterestedParties, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceDetails)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceDateOfPurchase(int id, string DateOfPurchase, bool? redirect = null) { return Update(id, pInsuranceDateOfPurchase, DateOfPurchase, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceClaimFormSent)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceClaimFormSentDate(int id, string ClaimFormSentDate, bool? redirect = null) { return Update(id, pInsuranceClaimFormSentDate, ClaimFormSentDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.InsuranceClaimFormSent)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateInsuranceClaimFormSentUserId(int id, string ClaimFormSentUserId, bool? redirect = null) { return Update(id, pInsuranceClaimFormSentUserId, ClaimFormSentUserId, redirect); } #endregion #region Warranty [DiscoAuthorize(Claims.Job.Properties.WarrantyProperties.ExternalName)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateWarrantyExternalName(int id, string ExternalName, bool? redirect = null) { return Update(id, pWarrantyExternalName, ExternalName, redirect); } [DiscoAuthorize(Claims.Job.Properties.WarrantyProperties.ExternalLoggedDate)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateWarrantyExternalLoggedDate(int id, string ExternalLoggedDate, bool? redirect = null) { return Update(id, pWarrantyExternalLoggedDate, ExternalLoggedDate, redirect); } [DiscoAuthorize(Claims.Job.Properties.WarrantyProperties.ExternalReference)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateWarrantyExternalReference(int id, string ExternalReference, bool? redirect = null) { return Update(id, pWarrantyExternalReference, ExternalReference, redirect); } [DiscoAuthorize(Claims.Job.Properties.WarrantyProperties.ExternalCompletedDate)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateWarrantyExternalCompletedDate(int id, string ExternalCompletedDate, bool? redirect = null) { return Update(id, pWarrantyExternalCompletedDate, ExternalCompletedDate, redirect); } #endregion #endregion #region Update Properties private void UpdateExpectedClosedDate(Job job, string ExpectedClosedDate) { if (!string.IsNullOrEmpty(ExpectedClosedDate)) { if (DateTime.TryParse(ExpectedClosedDate, out var ecd)) { ecd = job.ValidateDateAfterOpened(ecd); job.ExpectedClosedDate = ecd; } else { throw new Exception("Invalid Date Format"); } } else { job.ExpectedClosedDate = null; } Database.SaveChanges(); } private void UpdateDeviceHeldLocation(Job job, string DeviceHeldLocation) { if (!string.IsNullOrWhiteSpace(DeviceHeldLocation) && Database.DiscoConfiguration.JobPreferences.LocationMode == LocationModes.RestrictedList) { // Enforce Restricted List Mode var value = DeviceHeldLocation.Trim(); if (!Database.DiscoConfiguration.JobPreferences.LocationList.Contains(value, StringComparer.OrdinalIgnoreCase)) throw new ArgumentException("The location was not found in the list (Mode: Restricted List)"); } if (string.IsNullOrWhiteSpace(DeviceHeldLocation)) job.DeviceHeldLocation = null; else job.DeviceHeldLocation = DeviceHeldLocation.Trim(); Database.SaveChanges(); } private void UpdateFlags(Job job, string Flags) { // Only User Management Job Supports Flags at the moment if (!job.JobTypeId.Equals(JobType.JobTypeIds.UMgmt, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for User Management Jobs"); } if (string.IsNullOrWhiteSpace(Flags)) { if (!job.Flags.HasValue) { job.Flags = null; Database.SaveChanges(); } } else { long flags; if (Flags.Contains(',')) { flags = 0; foreach (var fs in Flags.Split(',')) { if (!long.TryParse(fs, out var fi)) throw new Exception("Invalid Int64 Format"); else flags = flags | fi; } } else { if (!long.TryParse(Flags, out flags)) throw new Exception("Invalid Int64 Format"); } if (flags == 0) { if (job.Flags.HasValue) { job.Flags = null; Database.SaveChanges(); } } else { if (!job.Flags.HasValue || (long)job.Flags.Value != flags) { job.Flags = (Job.UserManagementFlags)flags; Database.SaveChanges(); } } } } #region Job NonWarranty private void UpdateNonWarrantyIsInsuranceClaim(Job job, string IsInsuranceClaim) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(IsInsuranceClaim) || !bool.TryParse(IsInsuranceClaim, out var bIsInsuranceClaim)) { throw new Exception("Invalid IsInsuranceClaim Value"); } job.JobMetaNonWarranty.IsInsuranceClaim = bIsInsuranceClaim; if (job.JobMetaInsurance == null) { var jmi = new JobMetaInsurance(); jmi.JobId = job.Id; if (job.Device.DeviceBatch != null) { jmi.DateOfPurchase = job.Device.DeviceBatch.PurchaseDate; } else { if (!string.IsNullOrEmpty(job.DeviceSerialNumber)) { jmi.DateOfPurchase = job.Device.DeviceModel.DefaultPurchaseDate; } } if (job.User != null) jmi.OtherInterestedParties = job.User.DisplayName; job.JobMetaInsurance = jmi; Database.JobMetaInsurances.Add(jmi); } Database.SaveChanges(); } private Models.Job._DateChangeModel UpdateNonWarrantyAccountingChargeRequired(Job job, string AccountingChargeRequiredDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(AccountingChargeRequiredDate)) { job.JobMetaNonWarranty.AccountingChargeRequiredDate = null; } else { if (DateTime.TryParse(AccountingChargeRequiredDate, out var d)) { d = job.ValidateDateAfterOpened(d); job.JobMetaNonWarranty.AccountingChargeRequiredDate = d; } else { throw new Exception("Invalid Date Format"); } } job.JobMetaNonWarranty.AccountingChargeRequiredUserId = CurrentUser.UserId; Database.SaveChanges(); return new Models.Job._DateChangeModel() { Id = job.Id, Result = "OK", UserDescription = CurrentUser.ToString() }.SetDateTime(job.JobMetaNonWarranty.AccountingChargeRequiredDate); } private Models.Job._DateChangeModel UpdateNonWarrantyAccountingChargeAdded(Job job, string AccountingChargeAddedDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(AccountingChargeAddedDate)) { job.JobMetaNonWarranty.AccountingChargeAddedDate = null; } else { if (DateTime.TryParse(AccountingChargeAddedDate, out var d)) { d = job.ValidateDateAfterOpened(d); job.JobMetaNonWarranty.AccountingChargeAddedDate = d; } else { throw new Exception("Invalid Date Format"); } } job.JobMetaNonWarranty.AccountingChargeAddedUserId = CurrentUser.UserId; Database.SaveChanges(); return new Models.Job._DateChangeModel() { Id = job.Id, Result = "OK", UserDescription = CurrentUser.ToString() }.SetDateTime(job.JobMetaNonWarranty.AccountingChargeAddedDate); } private Models.Job._DateChangeModel UpdateNonWarrantyAccountingChargePaid(Job job, string AccountingChargePaidDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(AccountingChargePaidDate)) { job.JobMetaNonWarranty.AccountingChargePaidDate = null; } else { if (DateTime.TryParse(AccountingChargePaidDate, out var d)) { d = job.ValidateDateAfterOpened(d); job.JobMetaNonWarranty.AccountingChargePaidDate = d; } else { throw new Exception("Invalid Date Format"); } } job.JobMetaNonWarranty.AccountingChargePaidUserId = CurrentUser.UserId; Database.SaveChanges(); return new Models.Job._DateChangeModel() { Id = job.Id, Result = "OK", UserDescription = CurrentUser.ToString() }.SetDateTime(job.JobMetaNonWarranty.AccountingChargePaidDate); } private Models.Job._DateChangeModel UpdateNonWarrantyPurchaseOrderRaised(Job job, string PurchaseOrderRaisedDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(PurchaseOrderRaisedDate)) { job.JobMetaNonWarranty.PurchaseOrderRaisedDate = null; } else { if (DateTime.TryParse(PurchaseOrderRaisedDate, out var d)) { d = job.ValidateDateAfterOpened(d); job.JobMetaNonWarranty.PurchaseOrderRaisedDate = d; } else { throw new Exception("Invalid Date Format"); } } job.JobMetaNonWarranty.PurchaseOrderRaisedUserId = CurrentUser.UserId; Database.SaveChanges(); return new Models.Job._DateChangeModel() { Id = job.Id, Result = "OK", UserDescription = CurrentUser.ToString() }.SetDateTime(job.JobMetaNonWarranty.PurchaseOrderRaisedDate); } private void UpdateNonWarrantyPurchaseOrderReference(Job job, string PurchaseOrderReference) { if (string.IsNullOrWhiteSpace(PurchaseOrderReference)) job.JobMetaNonWarranty.PurchaseOrderReference = null; else job.JobMetaNonWarranty.PurchaseOrderReference = PurchaseOrderReference; Database.SaveChanges(); } private Models.Job._DateChangeModel UpdateNonWarrantyPurchaseOrderSent(Job job, string PurchaseOrderSentDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(PurchaseOrderSentDate)) { job.JobMetaNonWarranty.PurchaseOrderSentDate = null; } else { if (DateTime.TryParse(PurchaseOrderSentDate, out var d)) { d = job.ValidateDateAfterOpened(d); job.JobMetaNonWarranty.PurchaseOrderSentDate = d; } else { throw new Exception("Invalid Date Format"); } } job.JobMetaNonWarranty.PurchaseOrderSentUserId = CurrentUser.UserId; Database.SaveChanges(); return new Models.Job._DateChangeModel() { Id = job.Id, Result = "OK", UserDescription = CurrentUser.ToString() }.SetDateTime(job.JobMetaNonWarranty.PurchaseOrderSentDate); } private Models.Job._DateChangeModel UpdateNonWarrantyInvoiceReceived(Job job, string InvoiceReceivedDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(InvoiceReceivedDate)) { job.JobMetaNonWarranty.InvoiceReceivedDate = null; } else { if (DateTime.TryParse(InvoiceReceivedDate, out var d)) { d = job.ValidateDateAfterOpened(d); job.JobMetaNonWarranty.InvoiceReceivedDate = d; } else { throw new Exception("Invalid Date Format"); } } job.JobMetaNonWarranty.InvoiceReceivedUserId = CurrentUser.UserId; Database.SaveChanges(); return new Models.Job._DateChangeModel() { Id = job.Id, Result = "OK", UserDescription = CurrentUser.ToString() }.SetDateTime(job.JobMetaNonWarranty.InvoiceReceivedDate); } private void UpdateNonWarrantyRepairerName(Job job, string RepairerName) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(RepairerName)) { job.JobMetaNonWarranty.RepairerName = null; } else { job.JobMetaNonWarranty.RepairerName = RepairerName.Trim(); } Database.SaveChanges(); } private void UpdateNonWarrantyRepairerLoggedDate(Job job, string RepairerLoggedDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(RepairerLoggedDate)) { job.JobMetaNonWarranty.RepairerLoggedDate = null; job.JobMetaNonWarranty.RepairerCompletedDate = null; } else { if (RepairerLoggedDate.Equals("Now", StringComparison.OrdinalIgnoreCase)) { job.JobMetaNonWarranty.RepairerLoggedDate = DateTime.Now; } else { if (DateTime.TryParse(RepairerLoggedDate, out var d)) { job.JobMetaNonWarranty.RepairerLoggedDate = d; } else { throw new Exception("Invalid Date Format"); } } } Database.SaveChanges(); } private void UpdateNonWarrantyRepairerReference(Job job, string RepairerReference) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(RepairerReference)) { job.JobMetaNonWarranty.RepairerReference = null; } else { job.JobMetaNonWarranty.RepairerReference = RepairerReference.Trim(); } Database.SaveChanges(); } private void UpdateNonWarrantyRepairerCompletedDate(Job job, string RepairerCompletedDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(RepairerCompletedDate)) { job.JobMetaNonWarranty.RepairerCompletedDate = null; } else { if (RepairerCompletedDate.Equals("Now", StringComparison.OrdinalIgnoreCase)) { job.JobMetaNonWarranty.RepairerCompletedDate = DateTime.Now; } else { if (DateTime.TryParse(RepairerCompletedDate, out var d)) { job.JobMetaNonWarranty.RepairerCompletedDate = d; } else { throw new Exception("Invalid Date Format"); } } } Database.SaveChanges(); } #endregion #region Job Insurance private Models.Job._DateChangeModel UpdateInsuranceClaimFormSentDate(Job job, string ClaimFormSentDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(ClaimFormSentDate)) { job.JobMetaInsurance.ClaimFormSentDate = null; } else { if (ClaimFormSentDate.Equals("Now", StringComparison.OrdinalIgnoreCase)) { job.JobMetaInsurance.ClaimFormSentDate = DateTime.Now; } else { if (DateTime.TryParse(ClaimFormSentDate, out var d)) { d = job.ValidateDateAfterOpened(d); job.JobMetaInsurance.ClaimFormSentDate = d; } else { throw new Exception("Invalid Date Format"); } } } job.JobMetaInsurance.ClaimFormSentUserId = CurrentUser.UserId; Database.SaveChanges(); return new Models.Job._DateChangeModel() { Id = job.Id, Result = "OK", UserDescription = CurrentUser.ToString() }.SetDateTime(job.JobMetaInsurance.ClaimFormSentDate); } private void UpdateInsuranceDateOfPurchase(Job job, string DateOfPurchase) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(DateOfPurchase)) { job.JobMetaInsurance.DateOfPurchase = null; } else { if (!DateTime.TryParse(DateOfPurchase, out var dt)) { throw new Exception("Invalid DateTime Value"); } job.JobMetaInsurance.DateOfPurchase = dt; } Database.SaveChanges(); } private void UpdateInsuranceOtherInterestedParties(Job job, string OtherInterestedParties) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(OtherInterestedParties)) { job.JobMetaInsurance.OtherInterestedParties = null; } else { job.JobMetaInsurance.OtherInterestedParties = OtherInterestedParties.Trim(); } Database.SaveChanges(); } private void UpdateInsuranceRecoverReduceAction(Job job, string RecoverReduceAction) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(RecoverReduceAction)) { job.JobMetaInsurance.RecoverReduceAction = null; } else { job.JobMetaInsurance.RecoverReduceAction = RecoverReduceAction.Trim(); } Database.SaveChanges(); } private void UpdateInsurancePoliceNotifiedCrimeReportNo(Job job, string PoliceNotifiedCrimeReportNo) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(PoliceNotifiedCrimeReportNo)) { job.JobMetaInsurance.PoliceNotifiedCrimeReportNo = null; } else { job.JobMetaInsurance.PoliceNotifiedCrimeReportNo = PoliceNotifiedCrimeReportNo.Trim(); } Database.SaveChanges(); } private void UpdateInsurancePoliceNotifiedDate(Job job, string PoliceNotifiedDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(PoliceNotifiedDate)) { job.JobMetaInsurance.PoliceNotifiedDate = null; } else { if (!DateTime.TryParse(PoliceNotifiedDate, out var dt)) { throw new Exception("Invalid DateTime Value"); } job.JobMetaInsurance.PoliceNotifiedDate = dt; } Database.SaveChanges(); } private void UpdateInsurancePoliceNotifiedStation(Job job, string PoliceNotifiedStation) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(PoliceNotifiedStation)) { job.JobMetaInsurance.PoliceNotifiedStation = null; } else { job.JobMetaInsurance.PoliceNotifiedStation = PoliceNotifiedStation.Trim(); } Database.SaveChanges(); } private void UpdateInsurancePoliceNotified(Job job, string PoliceNotified) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(PoliceNotified) || !bool.TryParse(PoliceNotified, out var b)) { throw new Exception("Invalid Boolean Value"); } job.JobMetaInsurance.PoliceNotified = b; Database.SaveChanges(); } private void UpdateInsurancePropertyLastSeenDate(Job job, string PropertyLastSeenDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(PropertyLastSeenDate)) { job.JobMetaInsurance.PropertyLastSeenDate = null; } else { if (DateTime.TryParse(PropertyLastSeenDate, out var d)) { job.JobMetaInsurance.PropertyLastSeenDate = d; } else { throw new Exception("Invalid Date Format"); } } Database.SaveChanges(); } private void UpdateInsuranceBurglaryTheftMethodOfEntry(Job job, string BurglaryTheftMethodOfEntry) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(BurglaryTheftMethodOfEntry)) { job.JobMetaInsurance.BurglaryTheftMethodOfEntry = null; } else { job.JobMetaInsurance.BurglaryTheftMethodOfEntry = BurglaryTheftMethodOfEntry.Trim(); } Database.SaveChanges(); } private void UpdateInsuranceWitnessesNamesAddresses(Job job, string WitnessesNamesAddresses) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(WitnessesNamesAddresses)) { job.JobMetaInsurance.WitnessesNamesAddresses = null; } else { job.JobMetaInsurance.WitnessesNamesAddresses = WitnessesNamesAddresses.Trim(); } Database.SaveChanges(); } private void UpdateInsuranceThirdPartyCausedWhy(Job job, string ThirdPartyCausedWhy) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(ThirdPartyCausedWhy)) { job.JobMetaInsurance.ThirdPartyCausedWhy = null; } else { job.JobMetaInsurance.ThirdPartyCausedWhy = ThirdPartyCausedWhy.Trim(); } Database.SaveChanges(); } private void UpdateInsuranceThirdPartyCausedName(Job job, string ThirdPartyCausedName) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(ThirdPartyCausedName)) { job.JobMetaInsurance.ThirdPartyCausedName = null; } else { job.JobMetaInsurance.ThirdPartyCausedName = ThirdPartyCausedName.Trim(); } Database.SaveChanges(); } private void UpdateInsuranceThirdPartyCaused(Job job, string ThirdPartyCaused) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(ThirdPartyCaused) || !bool.TryParse(ThirdPartyCaused, out var b)) { throw new Exception("Invalid Boolean Value"); } job.JobMetaInsurance.ThirdPartyCaused = b; Database.SaveChanges(); } private void UpdateInsuranceDescription(Job job, string Description) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(Description)) { job.JobMetaInsurance.Description = null; } else { job.JobMetaInsurance.Description = Description.Trim(); } Database.SaveChanges(); } private void UpdateInsuranceEventLocation(Job job, string EventLocation) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrWhiteSpace(EventLocation)) { job.JobMetaInsurance.EventLocation = null; } else { job.JobMetaInsurance.EventLocation = EventLocation.Trim(); } Database.SaveChanges(); } private void UpdateInsuranceLossOrDamageDate(Job job, string LossOrDamageDate) { // Validate Is NonWarranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HNWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware NonWarranty Jobs"); } if (string.IsNullOrEmpty(LossOrDamageDate)) { job.JobMetaInsurance.LossOrDamageDate = null; } else { if (DateTime.TryParse(LossOrDamageDate, out var d)) { job.JobMetaInsurance.LossOrDamageDate = d; } else { throw new Exception("Invalid Date Format"); } } Database.SaveChanges(); } #endregion #region Job Warranty private void UpdateWarrantyExternalName(Job job, string ExternalName) { // Validate Is Warranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware Warranty Jobs"); } if (string.IsNullOrWhiteSpace(ExternalName)) { job.JobMetaWarranty.ExternalName = null; } else { job.JobMetaWarranty.ExternalName = ExternalName.Trim(); } Database.SaveChanges(); } private void UpdateWarrantyExternalLoggedDate(Job job, string ExternalLoggedDate) { // Validate Is Warranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware Warranty Jobs"); } if (string.IsNullOrEmpty(ExternalLoggedDate)) { job.JobMetaWarranty.ExternalLoggedDate = null; } else { if (DateTime.TryParse(ExternalLoggedDate, out var d)) { job.JobMetaWarranty.ExternalLoggedDate = d; } else { throw new Exception("Invalid Date Format"); } } Database.SaveChanges(); } private void UpdateWarrantyExternalReference(Job job, string ExternalReference) { // Validate Is Warranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware Warranty Jobs"); } if (string.IsNullOrWhiteSpace(ExternalReference)) { job.JobMetaWarranty.ExternalReference = null; } else { job.JobMetaWarranty.ExternalReference = ExternalReference.Trim(); } Database.SaveChanges(); } private void UpdateWarrantyExternalCompletedDate(Job job, string ExternalCompletedDate) { // Validate Is Warranty Job if (!job.JobTypeId.Equals(JobType.JobTypeIds.HWar, StringComparison.OrdinalIgnoreCase)) { throw new Exception("This property can only be set for Hardware Warranty Jobs"); } if (string.IsNullOrEmpty(ExternalCompletedDate)) { job.JobMetaWarranty.ExternalCompletedDate = null; } else { if (ExternalCompletedDate.Equals("Now", StringComparison.OrdinalIgnoreCase)) { job.JobMetaWarranty.ExternalCompletedDate = DateTime.Now; } else { if (DateTime.TryParse(ExternalCompletedDate, out var d)) { job.JobMetaWarranty.ExternalCompletedDate = d; } else { throw new Exception("Invalid Date Format"); } } } Database.SaveChanges(); } #endregion #endregion #region Job Actions [DiscoAuthorize(Claims.Job.Actions.UpdateSubTypes)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateSubTypes(int id, List SubTypes = null, bool? AddComponents = null, bool? redirect = null) { try { if (id < 0) throw new ArgumentOutOfRangeException("id"); if (SubTypes == null) throw new ArgumentNullException("SubTypes"); if (SubTypes.Count == 0) throw new ArgumentException("The job must contain at least one Sub Type", "SubTypes"); if (AddComponents == null) AddComponents = false; Database.Configuration.LazyLoadingEnabled = true; var job = Database.Jobs.Include("JobSubTypes").Where(j => j.Id == id).FirstOrDefault(); if (job == null) throw new Exception("Invalid Job Id"); var subTypes = Database.JobSubTypes.Where(jst => SubTypes.Contains(jst.JobTypeId + "_" + jst.Id)).ToList(); job.UpdateSubTypes(Database, subTypes, AddComponents.Value, CurrentUser); Database.SaveChanges(); if (redirect.HasValue && redirect.Value) return RedirectToAction(MVC.Job.Show(job.Id)); else return Ok(); } catch (Exception ex) { if (redirect.HasValue && redirect.Value) throw; else return BadRequest(ex.Message); } } [DiscoAuthorize(Claims.Job.Properties.Flags)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult UpdateFlag(int id, long? Flag, string Reason, bool? redirect = null) { try { if (id < 0) throw new ArgumentOutOfRangeException("id"); if (!Flag.HasValue || Flag.Value == 0) throw new ArgumentNullException("Flag"); var job = Database.Jobs.Include("JobSubTypes").Where(j => j.Id == id).FirstOrDefault(); if (job == null) throw new Exception("Invalid Job Id"); var flag = Flag.Value; var validFlags = job.ValidFlags(); if (validFlags.TryGetValue(flag < 0 ? flag * -1 : flag, out var flagStatus)) { if (flag < 0) { // Remove Flag if (flagStatus.Item2) { job.Flags = (Job.UserManagementFlags)((long)(job.Flags ?? 0) ^ (flag * -1)); Database.SaveChanges(); } } else { // Add Flag if (!flagStatus.Item2) { job.Flags = (Job.UserManagementFlags)((long)(job.Flags ?? 0) | flag); } // Write Reason JobLog jobLog = new JobLog() { JobId = job.Id, TechUserId = CurrentUser.UserId, Timestamp = DateTime.Now, Comments = $"# Added Flag\r\n**{flagStatus.Item1}**\r\n{(string.IsNullOrWhiteSpace(Reason) ? "" : Reason)}" }; Database.JobLogs.Add(jobLog); Database.SaveChanges(); } if (redirect.HasValue && redirect.Value) return RedirectToAction(MVC.Job.Show(job.Id)); else return Ok(); } else { throw new ArgumentOutOfRangeException("Flag", "Invalid Flag"); } } catch (Exception ex) { if (redirect.HasValue && redirect.Value) throw; else return BadRequest(ex.Message); } } [DiscoAuthorize(Claims.Job.Properties.WaitingForUserAction)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult WaitingForUserAction(int id, string Reason, bool? redirect = null) { try { if (id < 0) throw new ArgumentOutOfRangeException("id"); Database.Configuration.LazyLoadingEnabled = true; var job = Database.Jobs.Where(j => j.Id == id).FirstOrDefault(); if (job == null) throw new Exception("Invalid Job Id"); if (!job.CanWaitingForUserAction()) throw new InvalidOperationException("Unable to set Waiting For User Action"); job.OnWaitingForUserAction(Database, CurrentUser, Reason); Database.SaveChanges(); if (redirect.HasValue && redirect.Value) return RedirectToAction(MVC.Job.Show(job.Id)); else return Ok(); } catch (Exception ex) { if (redirect.HasValue && redirect.Value) throw; else return BadRequest(ex.Message); } } [DiscoAuthorize(Claims.Job.Properties.NotWaitingForUserAction)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult NotWaitingForUserAction(int id, string Resolution, bool? redirect = null) { try { if (id < 0) throw new ArgumentOutOfRangeException("id"); Database.Configuration.LazyLoadingEnabled = true; var job = Database.Jobs.Where(j => j.Id == id).FirstOrDefault(); if (job == null) throw new Exception("Invalid Job Id"); if (!job.CanNotWaitingForUserAction()) throw new InvalidOperationException("Unable to set Waiting For User Action"); job.OnNotWaitingForUserAction(Database, CurrentUser, Resolution); Database.SaveChanges(); if (redirect.HasValue && redirect.Value) return RedirectToAction(MVC.Job.Show(job.Id)); else return Ok(); } catch (Exception ex) { if (redirect.HasValue && redirect.Value) throw; else return BadRequest(ex.Message); } } [DiscoAuthorize(Claims.Job.Properties.DeviceReadyForReturn)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult DeviceReadyForReturn(int id, bool redirect) { Database.Configuration.LazyLoadingEnabled = true; var j = Database.Jobs.Find(id); if (j != null) { if (j.CanDeviceReadyForReturn()) { j.OnDeviceReadyForReturn(Database, Database.Users.Find(CurrentUser.UserId)); Database.SaveChanges(); if (redirect) return RedirectToAction(MVC.Job.Show(id)); else return Ok(); } else { return BadRequest("Job's state doesn't allow this action"); } } return BadRequest("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.Properties.DeviceHeld)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult DeviceHeld(int id, bool redirect) { var j = Database.Jobs.Find(id); if (j != null) { if (j.CanDeviceHeld()) { j.OnDeviceHeld(CurrentUser); Database.SaveChanges(); if (redirect) return RedirectToAction(MVC.Job.Show(id)); else return Ok(); } else { return BadRequest("Job's state doesn't allow this action"); } } return BadRequest("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.Properties.DeviceReturned)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult DeviceReturned(int id, bool redirect) { var j = Database.Jobs.Find(id); if (j != null) { if (j.CanDeviceReturned()) { j.OnDeviceReturned(CurrentUser); Database.SaveChanges(); if (redirect) return RedirectToAction(MVC.Job.Show(id)); else return Ok(); } else { return BadRequest("Job's state doesn't allow this action"); } } return BadRequest("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.Actions.ForceClose)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult ForceClose(int id, string Reason, bool? redirect = null) { var j = Database.Jobs.Find(id); Database.Configuration.LazyLoadingEnabled = true; if (j != null) { if (j.CanCloseForced()) { j.OnCloseForced(Database, Database.Users.Find(CurrentUser.UserId), Reason); Database.SaveChanges(); if (redirect.HasValue && redirect.Value) return RedirectToAction(MVC.Job.Show(id)); else return Ok(); } else { return BadRequest("Job's state doesn't allow this action"); } } return BadRequest("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.Actions.Close)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult Close(int id, bool redirect) { var j = Database.Jobs.Find(id); Database.Configuration.LazyLoadingEnabled = true; if (j != null) { if (j.CanCloseNormally()) { j.OnCloseNormally(Database, Database.Users.Find(CurrentUser.UserId)); Database.SaveChanges(); if (redirect) return RedirectToAction(MVC.Job.Show(id)); else return Ok(); } else { return BadRequest("Job's state doesn't allow this action"); } } return BadRequest("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.Actions.Reopen)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult Reopen(int id, bool redirect) { var j = Database.Jobs .Include(x => x.ClosedTechUser) .FirstOrDefault(x => x.Id == id); if (j != null) { if (j.CanReopen()) { j.OnReopen(Database, CurrentUser); Database.SaveChanges(); if (redirect) return RedirectToAction(MVC.Job.Show(id)); else return Ok(); } else { return BadRequest("Job's state doesn't allow this action"); } } return BadRequest("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.Actions.Delete)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult Delete(int id, bool redirect) { var j = Database.Jobs.Find(id); Database.Configuration.LazyLoadingEnabled = true; if (j != null) { if (j.CanDelete()) { j.OnDelete(Database); Database.SaveChanges(); if (redirect) return RedirectToAction(MVC.Job.Index()); else return Ok(); } else { return BadRequest("Job's state doesn't allow this action"); } } return BadRequest("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.Actions.ConvertHWarToHNWar)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult ConvertHWarToHNWar(int id, bool redirect) { var j = Database.Jobs.Find(id); Database.Configuration.LazyLoadingEnabled = true; if (j != null) { if (j.CanConvertHWarToHNWar()) { j.OnConvertHWarToHNWar(Database); Database.SaveChanges(); if (redirect) return RedirectToAction(MVC.Job.Show(j.Id)); else return Ok(); } else { return BadRequest("Job's state doesn't allow this action"); } } return BadRequest("Invalid Job Number"); } #endregion #region Job Comments [DiscoAuthorize(Claims.Job.Actions.Create)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult InitialComments(CreateModel m) { m.UpdateModel(Database, Authorization); return Json(Jobs.GenerateInitialComments(Database, m, CurrentUser, out _)); } [DiscoAuthorize(Claims.Job.ShowLogs)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult Comments(int id) { var job = Database.Jobs .Include(j => j.JobLogs.Select(l => l.TechUser)) .Where(j => j.Id == id).FirstOrDefault(); if (job == null) return BadRequest("Invalid Job Number"); var results = job.JobLogs.OrderByDescending(m => m.Timestamp).Select(jl => Models.Shared.CommentModel.FromEntity(jl)).ToList(); return Json(results); } [DiscoAuthorize(Claims.Job.ShowLogs)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult Comment(int id) { var jobLog = Database.JobLogs .Include(l => l.TechUser) .FirstOrDefault(l => l.Id == id); if (jobLog == null) return BadRequest("Invalid JobLog Id"); var c = Models.Shared.CommentModel.FromEntity(jobLog); return Json(c); } [DiscoAuthorize(Claims.Job.Actions.AddLogs)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult CommentAdd(int id, string comment = null) { if (string.IsNullOrWhiteSpace(comment)) return BadRequest("Comment is required"); var job = Database.Jobs.Find(id); if (job == null) return BadRequest("Invalid Job Number"); var jl = new JobLog() { JobId = job.Id, TechUserId = CurrentUser.UserId, Timestamp = DateTime.Now, Comments = comment }; Database.JobLogs.Add(jl); Database.SaveChanges(); return Json(jl.Id); } [DiscoAuthorizeAny(Claims.Job.Actions.RemoveAnyLogs, Claims.Job.Actions.RemoveOwnLogs)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult CommentRemove(int id) { var jobLog = Database.JobLogs.Find(id); if (jobLog != null) { if (jobLog.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)) Authorization.RequireAny(Claims.Job.Actions.RemoveAnyLogs, Claims.Job.Actions.RemoveOwnLogs); else Authorization.Require(Claims.Job.Actions.RemoveAnyLogs); Database.JobLogs.Remove(jobLog); Database.SaveChanges(); } // Doesn't Exist/Already Deleted - OK return Ok(); } #endregion #region Job Attachments [DiscoAuthorize(Claims.Job.ShowAttachments), OutputCache(Location = System.Web.UI.OutputCacheLocation.Client, Duration = 172800)] public virtual ActionResult AttachmentDownload(int id, bool? inline = null) { var ja = Database.JobAttachments.Find(id); if (ja != null) { var filePath = ja.RepositoryFilename(Database); if (System.IO.File.Exists(filePath)) { return File(filePath, ja.MimeType, (inline ?? false) ? null : ja.Filename); } else { return HttpNotFound("Attachment reference exists, but file not found"); } } return HttpNotFound("Invalid Attachment Number"); } [DiscoAuthorize(Claims.Job.ShowAttachments)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult AttachmentDownloadAll(int id) { var job = Database.Jobs .Include(u => u.JobAttachments) .Where(u => u.Id == id) .FirstOrDefault(); if (job == null || job.JobAttachments.Count == 0) return NotFound(); var responseStream = new MemoryStream(); using (var archive = new ZipArchive(responseStream, ZipArchiveMode.Create, true)) { foreach (var attachment in job.JobAttachments) { var repoFileName = attachment.RepositoryFilename(Database); if (System.IO.File.Exists(repoFileName)) { var fileName = $"{Path.GetFileNameWithoutExtension(attachment.Filename)}-{attachment.Timestamp:yyyyMMdd-HHmmss}{Path.GetExtension(attachment.Filename)}"; var entry = archive.CreateEntry(fileName, CompressionLevel.Fastest); entry.LastWriteTime = attachment.Timestamp; using (var entryStream = entry.Open()) { using (var attachmentStream = System.IO.File.OpenRead(repoFileName)) { attachmentStream.CopyTo(entryStream); } } } } } responseStream.Position = 0; return File(responseStream, "application/zip", $"{job.Id}_JobAttachments_{DateTime.Now:yyyyMMdd-HHmmss}.zip"); } [DiscoAuthorize(Claims.Job.ShowAttachments), OutputCache(Location = System.Web.UI.OutputCacheLocation.Client, Duration = 172800)] public virtual ActionResult AttachmentThumbnail(int id) { var ja = Database.JobAttachments.Find(id); if (ja != null) { if (ja.WaitForThumbnailGeneration(Database, out var thumbPath, out var mimeType)) return File(thumbPath, mimeType); else return File(ClientSource.Style.Images.AttachmentTypes.MimeTypeIcons.Icon(ja.MimeType), "image/png"); } return HttpNotFound("Invalid Attachment Number"); } [DiscoAuthorize(Claims.Job.Actions.AddAttachments)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult AttachmentUpload(int id, string comments) { var j = Database.Jobs.Find(id); if (j != null) { if (Request.Files.Count > 0) { var file = Request.Files.Get(0); if (file.ContentLength > 0) { var contentType = file.ContentType; if (string.IsNullOrEmpty(contentType) || contentType.Equals("unknown/unknown", StringComparison.OrdinalIgnoreCase)) contentType = MimeTypes.ResolveMimeType(file.FileName); if (string.IsNullOrWhiteSpace(comments)) comments = null; var ja = new JobAttachment() { JobId = j.Id, TechUserId = CurrentUser.UserId, Filename = file.FileName, MimeType = contentType, Timestamp = DateTime.Now, Comments = comments }; Database.JobAttachments.Add(ja); Database.SaveChanges(); ja.SaveAttachment(Database, file.InputStream); ja.GenerateThumbnail(Database); return Json(ja.Id, JsonRequestBehavior.AllowGet); } } throw new Exception("No Attachment Uploaded"); } throw new Exception("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.ShowAttachments)] public virtual ActionResult Attachment(int id) { var ja = Database.JobAttachments .Include(a => a.DocumentTemplate) .Include(a => a.TechUser) .Where(m => m.Id == id).FirstOrDefault(); if (ja != null) { var m = new Models.Attachment.AttachmentModel() { Attachment = Models.Attachment._AttachmentModel.FromAttachment(ja), Result = "OK" }; return Json(m, JsonRequestBehavior.AllowGet); } return Json(new Models.Attachment.AttachmentModel() { Result = "Invalid Attachment Number" }, JsonRequestBehavior.AllowGet); } [DiscoAuthorize(Claims.Job.ShowAttachments)] public virtual ActionResult Attachments(int id) { var j = Database.Jobs.Include("JobAttachments.DocumentTemplate").Include("JobAttachments.TechUser").Where(m => m.Id == id).FirstOrDefault(); if (j != null) { var m = new Models.Attachment.AttachmentsModel() { Attachments = j.JobAttachments.Select(ja => Models.Attachment._AttachmentModel.FromAttachment(ja)).ToList(), Result = "OK" }; return Json(m, JsonRequestBehavior.AllowGet); } return Json(new Models.Attachment.AttachmentsModel() { Result = "Invalid Attachment Number" }, JsonRequestBehavior.AllowGet); } [DiscoAuthorizeAny(Claims.Job.Actions.RemoveAnyAttachments, Claims.Job.Actions.RemoveOwnAttachments)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult AttachmentRemove(int id) { var ja = Database.JobAttachments.Include("TechUser").Where(m => m.Id == id).FirstOrDefault(); if (ja != null) { if (ja.TechUserId.Equals(CurrentUser.UserId, StringComparison.OrdinalIgnoreCase)) Authorization.RequireAny(Claims.Job.Actions.RemoveAnyAttachments, Claims.Job.Actions.RemoveOwnAttachments); else Authorization.Require(Claims.Job.Actions.RemoveAnyAttachments); ja.OnDelete(Database); Database.SaveChanges(); return Ok(); } return BadRequest("Invalid Attachment Number"); } [DiscoAuthorize(Claims.Job.Actions.AddAttachments)] [HttpPost, ValidateAntiForgeryToken] public virtual async Task AttachmentOnlineUploadSession(int id) { var job = Database.Jobs.Find(id) ?? throw new InvalidOperationException("Unknown Job Id"); try { if (!Database.DiscoConfiguration.IsActivated) throw new InvalidOperationException("Activation is required to use this feature (See: Configuration > System)"); var (uri, expiration) = await UploadOnlineService.CreateSession(CurrentUser, job); UploadOnlineSyncTask.ScheduleInOneHour(); return Json(new { Success = true, Expiration = expiration.ToUnixEpoc(), SessionUri = uri.ToString(), }); } catch (InvalidOperationException ex) { return BadRequest(ex.Message); } } #endregion #region Job Components [DiscoAuthorizeAll(Claims.Job.Properties.NonWarrantyProperties.AddComponents, Claims.Job.Properties.NonWarrantyProperties.EditComponents)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult ComponentAdd(int id, string description, string cost) { var j = Database.Jobs.Find(id); if (j != null) { if (string.IsNullOrEmpty(description)) description = "?"; if (!string.IsNullOrEmpty(cost) && cost.Contains("$")) cost = cost.Substring(cost.IndexOf("$") + 1); decimal.TryParse(cost, out var costValue); var jc = new JobComponent() { JobId = j.Id, Description = description, Cost = costValue, TechUserId = CurrentUser.UserId }; Database.JobComponents.Add(jc); Database.SaveChanges(); return Json(Models.Job.ComponentModel.FromJobComponent(jc)); } return BadRequest("Invalid Job Number"); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.EditComponents)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult ComponentUpdate(int id, string description, string cost) { var jc = Database.JobComponents.Find(id); if (jc != null) { if (string.IsNullOrEmpty(description)) description = "?"; if (!string.IsNullOrEmpty(cost) && cost.Contains("$")) cost = cost.Substring(cost.IndexOf("$") + 1); decimal.TryParse(cost, out var costValue); jc.Description = description; jc.Cost = costValue; Database.SaveChanges(); return Json(Models.Job.ComponentModel.FromJobComponent(jc)); } return BadRequest("Invalid Job Component Number"); } [DiscoAuthorize(Claims.Job.Properties.NonWarrantyProperties.EditComponents)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult ComponentRemove(int id) { var jc = Database.JobComponents.Find(id); if (jc != null) { Database.JobComponents.Remove(jc); Database.SaveChanges(); return Ok(); } return BadRequest("Invalid Job Component Number"); } #endregion #region Job Statistics [DiscoAuthorize(Claims.Job.Show)] public virtual ActionResult StatisticsDailyOpenedClosed() { var result = DailyOpenedClosed.Data(Database, true); return Json(result, JsonRequestBehavior.AllowGet); } #endregion [DiscoAuthorize(Claims.Job.Properties.DeviceHeldLocation)] public virtual ActionResult DeviceHeldLocations() { List locations; switch (Database.DiscoConfiguration.JobPreferences.LocationMode) { case LocationModes.Unrestricted: var jobDateThreshold = DateTime.Now.AddYears(-1); locations = Database.Jobs.Where(j => (j.OpenedDate > jobDateThreshold || !j.ClosedDate.HasValue) && j.DeviceHeldLocation != null).Select(j => j.DeviceHeldLocation).Distinct().OrderBy(l => l).ToList().Where(l => !string.IsNullOrWhiteSpace(l)).Select(l => l.Trim()).Distinct(StringComparer.OrdinalIgnoreCase).OrderBy(l => l).ToList(); break; case LocationModes.OptionalList: case LocationModes.RestrictedList: locations = Database.DiscoConfiguration.JobPreferences.LocationList; break; default: throw new InvalidOperationException("Unknown Location Mode Configured"); } var locationReferences = ManagedJobList.OpenJobsTable(j => j).Items.Cast().JobLocationReferences(locations); var results = locationReferences.Select(locRef => { string reference = null; if (locRef.References != null && locRef.References.Count > 0) { if (locRef.References.Count == 1) reference = $"Job {locRef.References[0].JobId}"; else reference = $"{locRef.References.Count} jobs"; } return new Models.Job.DeviceHeldLocationModel() { Location = locRef.Location, References = reference }; }).ToList(); return Json(results, JsonRequestBehavior.AllowGet); } #region Exporting [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 = new JobExport(model.Options); var taskContext = ExportTask.ScheduleNowCacheResult(exportContext, id => Url.Action(MVC.Job.Export(id))); // Try waiting for completion if (taskContext.TaskStatus.WaitUntilFinished(TimeSpan.FromSeconds(2))) return RedirectToAction(MVC.Job.Export(taskContext.Id)); else return RedirectToAction(MVC.Config.Logging.TaskStatus(taskContext.TaskStatus.SessionId)); } [DiscoAuthorize(Claims.Job.Actions.Export)] public virtual ActionResult ExportRetrieve(Guid id) { if (id == Guid.Empty) throw new ArgumentNullException(nameof(id)); if (!ExportTask.TryFromCache(id, out var context)) throw new ArgumentException("The export 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); } [DiscoAuthorizeAll(Claims.Config.ManageSavedExports, Claims.Job.Actions.Export)] [HttpPost, ValidateAntiForgeryToken] public virtual ActionResult SaveExport(ExportModel model) { // Write Options to Configuration Database.DiscoConfiguration.JobPreferences.LastExportOptions = model.Options; Database.SaveChanges(); var export = new JobExport(model.Options); var savedExport = SavedExports.SaveExport(export, Database, CurrentUser); return RedirectToAction(MVC.Config.Export.Create(savedExport.Id)); } #endregion } }