public virtual ActionResult UpdateFlag(int id, long? Flag, string Reason, Nullable<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(); Tuple<string, bool> flagStatus; if (validFlags.TryGetValue((flag < 0 ? flag * -1 : flag), out flagStatus)) { if (flag < 0) { // Remove Flag if (flagStatus.Item2) { job.Flags = (Disco.Models.Repository.Job.UserManagementFlags)((long)(job.Flags ?? 0) ^ (flag * -1)); Database.SaveChanges(); } } else { // Add Flag if (!flagStatus.Item2) { job.Flags = (Disco.Models.Repository.Job.UserManagementFlags)((long)(job.Flags ?? 0) | flag); } // Write Reason JobLog jobLog = new JobLog() { JobId = job.Id, TechUserId = CurrentUser.UserId, Timestamp = DateTime.Now, Comments = string.Format("# Added Flag\r\n**{0}**\r\n{1}", flagStatus.Item1, string.IsNullOrWhiteSpace(Reason) ? "<no reason provided>" : Reason) }; Database.JobLogs.Add(jobLog); Database.SaveChanges(); } if (redirect.HasValue && redirect.Value) return RedirectToAction(MVC.Job.Show(job.Id)); else return Json("OK", JsonRequestBehavior.AllowGet); } else { throw new ArgumentOutOfRangeException("Flag", "Invalid Flag"); } } catch (Exception ex) { if (redirect.HasValue && redirect.Value) throw; else return Json(string.Format("Error: {0}", ex.Message), JsonRequestBehavior.AllowGet); } }
public virtual ActionResult CommentPost(int id, string comment) { var j = Database.Jobs.Find(id); if (j != null) { var jl = new Disco.Models.Repository.JobLog() { JobId = j.Id, TechUserId = CurrentUser.UserId, Timestamp = DateTime.Now, Comments = comment }; Database.JobLogs.Add(jl); Database.SaveChanges(); jl = Database.JobLogs.Include("TechUser").Where(m => m.Id == jl.Id).FirstOrDefault(); return Json(new Models.Job.CommentPostModel() { Result = "OK", Comment = Models.Job._CommentModel.FromJobLog(jl) }, JsonRequestBehavior.AllowGet); } return Json(new Models.Job.CommentPostModel() { Result = "Invalid Job Number" }, JsonRequestBehavior.AllowGet); }
public static void OnCloseForced(this Job j, DiscoDataContext Database, User Technician, string Reason) { if (!j.CanCloseForced()) throw new InvalidOperationException("Force Close was Denied"); // Write Log JobLog jobLog = new JobLog() { JobId = j.Id, TechUserId = Technician.UserId, Timestamp = DateTime.Now, Comments = string.Format("# Job Forcibly Closed\r\n{0}", string.IsNullOrWhiteSpace(Reason) ? "<no reason provided>" : Reason) }; Database.JobLogs.Add(jobLog); j.ClosedDate = DateTime.Now; j.ClosedTechUserId = Technician.UserId; j.ClosedTechUser = Technician; // Evaluate OnClose Expression try { var onCloseResult = j.EvaluateOnCloseExpression(Database); if (!string.IsNullOrWhiteSpace(onCloseResult)) { var jl = new JobLog() { Job = j, TechUser = Technician, Timestamp = DateTime.Now, Comments = onCloseResult }; Database.JobLogs.Add(jl); } } catch (Exception ex) { SystemLog.LogException("Job Expression - OnCloseExpression", ex); } }
public static Stream GenerateFromTemplate(DocumentTemplate dt, DiscoDataContext Database, IAttachmentTarget Data, User CreatorUser, DateTime TimeStamp, DocumentState State, bool FlattenFields = false) { // Validate Data switch (dt.Scope) { case DocumentTemplate.DocumentTemplateScopes.Device: if (!(Data is Device)) throw new ArgumentException("This AttachmentType is configured for Devices only", "Data"); break; case DocumentTemplate.DocumentTemplateScopes.Job: if (!(Data is Job)) throw new ArgumentException("This AttachmentType is configured for Jobs only", "Data"); break; case DocumentTemplate.DocumentTemplateScopes.User: if (!(Data is User)) throw new ArgumentException("This AttachmentType is configured for Users only", "Data"); break; default: throw new InvalidOperationException("Invalid AttachmentType Scope"); } Database.Configuration.LazyLoadingEnabled = true; // Override FlattenFields if Document Template instructs. if (dt.FlattenForm) FlattenFields = true; ConcurrentDictionary<string, Expression> expressionCache = dt.PdfExpressionsFromCache(Database); string templateFilename = dt.RepositoryFilename(Database); PdfReader pdfReader = new PdfReader(templateFilename); MemoryStream pdfGeneratedStream = new MemoryStream(); PdfStamper pdfStamper = new PdfStamper(pdfReader, pdfGeneratedStream); pdfStamper.FormFlattening = FlattenFields; pdfStamper.Writer.CloseStream = false; IDictionary expressionVariables = Expression.StandardVariables(dt, Database, CreatorUser, TimeStamp, State); foreach (string pdfFieldKey in pdfStamper.AcroFields.Fields.Keys) { if (pdfFieldKey.Equals("DiscoAttachmentId", StringComparison.OrdinalIgnoreCase)) { AcroFields.Item fields = pdfStamper.AcroFields.Fields[pdfFieldKey]; string fieldValue = dt.CreateUniqueIdentifier(Database, Data, CreatorUser, TimeStamp, 0).ToJson(); if (FlattenFields) pdfStamper.AcroFields.SetField(pdfFieldKey, String.Empty); else pdfStamper.AcroFields.SetField(pdfFieldKey, fieldValue); IList<AcroFields.FieldPosition> pdfFieldPositions = pdfStamper.AcroFields.GetFieldPositions(pdfFieldKey); for (int pdfFieldOrdinal = 0; pdfFieldOrdinal < fields.Size; pdfFieldOrdinal++) { AcroFields.FieldPosition pdfFieldPosition = pdfFieldPositions[pdfFieldOrdinal]; // Create Binary Unique Identifier var pageUniqueId = dt.CreateUniqueIdentifier(Database, Data, CreatorUser, TimeStamp, pdfFieldPosition.page); var pageUniqueIdBytes = pageUniqueId.ToQRCodeBytes(); // Encode to QRCode byte array var pageUniqueIdWidth = (int)pdfFieldPosition.position.Width; var pageUniqueIdHeight = (int)pdfFieldPosition.position.Height; var pageUniqueIdEncoded = QRCodeBinaryEncoder.Encode(pageUniqueIdBytes, pageUniqueIdWidth, pageUniqueIdHeight); // Encode byte array to Image var pageUniqueIdImageData = CCITTG4Encoder.Compress(pageUniqueIdEncoded, pageUniqueIdWidth, pageUniqueIdHeight); var pageUniqueIdImage = iTextSharp.text.Image.GetInstance(pageUniqueIdWidth, pageUniqueIdHeight, false, 256, 1, pageUniqueIdImageData, null); // Add to the pdf page pageUniqueIdImage.SetAbsolutePosition(pdfFieldPosition.position.Left, pdfFieldPosition.position.Bottom); pdfStamper.GetOverContent(pdfFieldPosition.page).AddImage(pageUniqueIdImage); } // Hide Fields PdfDictionary field = fields.GetValue(0); if ((PdfName)field.Get(PdfName.TYPE) == PdfName.ANNOT) { field.Put(PdfName.F, new PdfNumber(6)); } else { PdfArray fieldKids = (PdfArray)field.Get(PdfName.KIDS); foreach (PdfIndirectReference fieldKidRef in fieldKids) { ((PdfDictionary)pdfReader.GetPdfObject(fieldKidRef.Number)).Put(PdfName.F, new PdfNumber(6)); } } } else { Expression fieldExpression = null; if (expressionCache.TryGetValue(pdfFieldKey, out fieldExpression)) { if (fieldExpression.IsDynamic) { Tuple<string, bool, object> fieldExpressionResult = fieldExpression.Evaluate(Data, expressionVariables); if (fieldExpressionResult.Item3 != null) { IImageExpressionResult imageResult = (fieldExpressionResult.Item3 as IImageExpressionResult); if (imageResult != null) { // Output Image AcroFields.Item fields = pdfStamper.AcroFields.Fields[pdfFieldKey]; IList<AcroFields.FieldPosition> pdfFieldPositions = pdfStamper.AcroFields.GetFieldPositions(pdfFieldKey); for (int pdfFieldOrdinal = 0; pdfFieldOrdinal < fields.Size; pdfFieldOrdinal++) { AcroFields.FieldPosition pdfFieldPosition = pdfFieldPositions[pdfFieldOrdinal]; iTextSharp.text.Image pdfImage = iTextSharp.text.Image.GetInstance(imageResult.GetImage((int)pdfFieldPosition.position.Width, (int)pdfFieldPosition.position.Height)); pdfImage.SetAbsolutePosition(pdfFieldPosition.position.Left, pdfFieldPosition.position.Bottom); pdfStamper.GetOverContent(pdfFieldPosition.page).AddImage(pdfImage); } if (!fieldExpressionResult.Item2 && !imageResult.ShowField) { // Hide Fields PdfDictionary field = fields.GetValue(0); if ((PdfName)field.Get(PdfName.TYPE) == PdfName.ANNOT) { field.Put(PdfName.F, new PdfNumber(6)); } else { PdfArray fieldKids = (PdfArray)field.Get(PdfName.KIDS); foreach (PdfIndirectReference fieldKidRef in fieldKids) { ((PdfDictionary)pdfReader.GetPdfObject(fieldKidRef.Number)).Put(PdfName.F, new PdfNumber(6)); } } } } } pdfStamper.AcroFields.SetField(pdfFieldKey, fieldExpressionResult.Item1); if (fieldExpressionResult.Item2) // Expression Error { AcroFields.Item fields = pdfStamper.AcroFields.Fields[pdfFieldKey]; for (int pdfFieldOrdinal = 0; pdfFieldOrdinal < fields.Size; pdfFieldOrdinal++) { PdfDictionary field = fields.GetValue(pdfFieldOrdinal); PdfDictionary fieldMK; if (field.Contains(PdfName.MK)) fieldMK = field.GetAsDict(PdfName.MK); else { fieldMK = new PdfDictionary(PdfName.MK); field.Put(PdfName.MK, fieldMK); } fieldMK.Put(PdfName.BC, new PdfArray(new float[] { 1, 0, 0 })); } } } } else { throw new InvalidOperationException("Pdf template field expressions are out of sync with the expression cache"); } } State.FlushFieldCache(); } pdfStamper.Close(); pdfReader.Close(); if (dt.Scope == DocumentTemplate.DocumentTemplateScopes.Job) { // Write Job Log Job j = (Job)Data; JobLog jl = new JobLog() { JobId = j.Id, TechUserId = CreatorUser.UserId, Timestamp = DateTime.Now }; jl.Comments = string.Format("# Document Generated\r\n**{0}** [{1}]", dt.Description, dt.Id); Database.JobLogs.Add(jl); } pdfGeneratedStream.Position = 0; return pdfGeneratedStream; }
public static void OnLogRepair(this Job j, DiscoDataContext Database, string FaultDescription, string ManualProviderName, string ManualProviderReference, OrganisationAddress Address, User TechUser) { if (!j.CanLogRepair()) throw new InvalidOperationException("Log Repair was Denied"); j.JobMetaNonWarranty.RepairerLoggedDate = DateTime.Now; j.JobMetaNonWarranty.RepairerName = ManualProviderName; if (ManualProviderReference != null && ManualProviderReference.Length > 100) j.JobMetaNonWarranty.RepairerReference = ManualProviderReference.Substring(0, 100); else j.JobMetaNonWarranty.RepairerReference = ManualProviderReference; // Write Log JobLog jobLog = new JobLog() { JobId = j.Id, TechUserId = TechUser.UserId, Timestamp = DateTime.Now, Comments = string.Format("# Manual Repair Request Submitted\r\nProvider: **{0}**\r\nAddress: **{1}**\r\nReference: **{2}**\r\n___\r\n```{3}```", ManualProviderName, Address.Name, ManualProviderReference ?? "<none>", FaultDescription) }; Database.JobLogs.Add(jobLog); }
public static void OnCloseNormally(this Job j, DiscoDataContext Database, User Technician) { if (!j.CanCloseNormally()) throw new InvalidOperationException("Close was Denied"); j.ClosedDate = DateTime.Now; j.ClosedTechUserId = Technician.UserId; j.ClosedTechUser = Technician; // Evaluate OnClose Expression try { var onCloseResult = j.EvaluateOnCloseExpression(Database); if (!string.IsNullOrWhiteSpace(onCloseResult)) { var jl = new JobLog() { Job = j, TechUser = Technician, Timestamp = DateTime.Now, Comments = onCloseResult }; Database.JobLogs.Add(jl); } } catch (Exception ex) { SystemLog.LogException("Job Expression - OnCloseExpression", ex); } }
public static void OnLogRepair(this Job j, DiscoDataContext Database, string RepairDescription, List<JobAttachment> SendAttachments, PluginFeatureManifest RepairProviderDefinition, OrganisationAddress Address, User TechUser, Dictionary<string, string> RepairProviderProperties) { if (!j.CanLogRepair()) throw new InvalidOperationException("Log Repair was Denied"); PublishJobResult publishJobResult = null; using (RepairProviderFeature RepairProvider = RepairProviderDefinition.CreateInstance<RepairProviderFeature>()) { if (SendAttachments != null && SendAttachments.Count > 0) { publishJobResult = DiscoServicesJobs.Publish( Database, j, TechUser, RepairProvider.ProviderId, null, RepairDescription, SendAttachments, AttachmentDataStoreExtensions.RepositoryFilename); if (!publishJobResult.Success) throw new Exception(string.Format("Disco ICT Online Services failed with the following message: ", publishJobResult.ErrorMessage)); if (string.IsNullOrWhiteSpace(RepairDescription)) RepairDescription = publishJobResult.PublishMessage; else RepairDescription = string.Concat(RepairDescription, Environment.NewLine, "___", Environment.NewLine, publishJobResult.PublishMessage); } string submitDescription; if (string.IsNullOrWhiteSpace(RepairDescription)) submitDescription = j.GenerateFaultDescriptionFooter(Database, RepairProviderDefinition); else submitDescription = string.Concat(RepairDescription, Environment.NewLine, Environment.NewLine, j.GenerateFaultDescriptionFooter(Database, RepairProviderDefinition)); string providerRef = RepairProvider.SubmitJob(Database, j, Address, TechUser, submitDescription, RepairProviderProperties); j.JobMetaNonWarranty.RepairerLoggedDate = DateTime.Now; j.JobMetaNonWarranty.RepairerName = RepairProvider.ProviderId; if (providerRef != null && providerRef.Length > 100) j.JobMetaNonWarranty.RepairerReference = providerRef.Substring(0, 100); else j.JobMetaNonWarranty.RepairerReference = providerRef; // Write Log JobLog jobLog = new JobLog() { JobId = j.Id, TechUserId = TechUser.UserId, Timestamp = DateTime.Now, Comments = string.Format("# Repair Request Submitted\r\nProvider: **{0}**\r\nAddress: **{1}**\r\nReference: **{2}**\r\n___\r\n```{3}```", RepairProvider.Manifest.Name, Address.Name, providerRef, RepairDescription) }; Database.JobLogs.Add(jobLog); if (publishJobResult != null) { try { DiscoServicesJobs.UpdateRecipientReference(Database, j, publishJobResult.Id, publishJobResult.Secret, j.JobMetaNonWarranty.RepairerReference); } catch (Exception ex) { ex.ToExceptionless().Submit(); } // Ignore Errors as this is not completely necessary } } }
public static void OnConvertHWarToHNWar(this Job j, DiscoDataContext Database) { if (!j.CanConvertHWarToHNWar()) throw new InvalidOperationException("Convert HWar to HNWar was Denied"); var techUser = UserService.CurrentUser; // Remove JobMetaWarranty if (j.JobMetaWarranty != null) Database.JobMetaWarranties.Remove(j.JobMetaWarranty); // Add JobMetaNonWarranty var metaHNWar = new JobMetaNonWarranty() { Job = j }; Database.JobMetaNonWarranties.Add(metaHNWar); // Swap Job Sub Types List<string> jobSubTypes = j.JobSubTypes.Select(jst => jst.Id).ToList(); j.JobSubTypes.Clear(); foreach (var jst in Database.JobSubTypes.Where(i => i.JobTypeId == JobType.JobTypeIds.HNWar && jobSubTypes.Contains(i.Id))) j.JobSubTypes.Add(jst); // Add Components var components = Database.DeviceComponents.Include("JobSubTypes").Where(c => !c.DeviceModelId.HasValue || c.DeviceModelId == j.Device.DeviceModelId); var jobComponents = new List<DeviceComponent>(); foreach (var component in components) { if (component.JobSubTypes.Count == 0) { jobComponents.Add(component); } else { foreach (var st in component.JobSubTypes) { foreach (var jst in j.JobSubTypes) { if (st.JobTypeId == jst.JobTypeId && st.Id == jst.Id) { jobComponents.Add(component); break; } } if (jobComponents.Contains(component)) break; } } } foreach (var component in jobComponents) { Database.JobComponents.Add(new JobComponent() { Job = j, TechUserId = techUser.UserId, Cost = component.Cost, Description = component.Description }); } // Write Log JobLog jobLog = new JobLog() { JobId = j.Id, TechUserId = techUser.UserId, Timestamp = DateTime.Now, Comments = string.Format("# Job Type Converted\r\nFrom: **{0}**\r\nTo: **{1}**", Database.JobTypes.Find(JobType.JobTypeIds.HWar), Database.JobTypes.Find(JobType.JobTypeIds.HNWar)) }; Database.JobLogs.Add(jobLog); j.JobTypeId = JobType.JobTypeIds.HNWar; }
public static void OnNotWaitingForUserAction(this Job j, DiscoDataContext Database, User Technician, string Resolution) { if (!j.CanNotWaitingForUserAction()) throw new InvalidOperationException("Not Waiting for User Action was Denied"); j.WaitingForUserAction = null; // Write Log JobLog jobLog = new JobLog() { JobId = j.Id, TechUserId = Technician.UserId, Timestamp = DateTime.Now, Comments = string.Format("# User Action Resolved\r\n{0}", string.IsNullOrWhiteSpace(Resolution) ? "<no comment provided>" : Resolution) }; Database.JobLogs.Add(jobLog); }
public virtual ActionResult Create(Models.Job.CreateModel m) { m.UpdateModel(Database, Authorization); if (!ModelState.IsValid) { // UI Extensions UIExtensions.ExecuteExtensions<JobCreateModel>(this.ControllerContext, m); return View(m); } else { Database.Configuration.LazyLoadingEnabled = true; // Create New Job var currentUser = Database.Users.Find(UserService.CurrentUserId); // Try QuickLog? bool addAutoQueues = !(Authorization.Has(Claims.Job.Actions.Close) && m.QuickLog.HasValue && m.QuickLog.Value && m.QuickLogTaskTimeMinutes.HasValue && m.QuickLogTaskTimeMinutes.Value > 0); var j = Jobs.Create(Database, m.Device, m.User, m.GetJobType, m.GetJobSubTypes, currentUser, addAutoQueues); if (m.DeviceHeld.Value) { j.OnDeviceHeld(currentUser); m.QuickLog = false; } else { if (Authorization.Has(Claims.Job.Actions.Close) && m.QuickLog.HasValue && m.QuickLog.Value && m.QuickLogTaskTimeMinutes.HasValue && m.QuickLogTaskTimeMinutes.Value > 0 && (j.JobQueues == null || j.JobQueues.All(jqj => jqj.RemovedDate.HasValue)) ) { // Quick Log // Set Opened Date in the past j.OpenedDate = DateTime.Now.AddMinutes(-1 * m.QuickLogTaskTimeMinutes.Value); // Close Job j.OnCloseNormally(Database, currentUser); } else { m.QuickLog = false; } } Database.SaveChanges(); // Evaluate OnCreate Expression try { var onCreateResult = j.EvaluateOnCreateExpression(Database); if (!string.IsNullOrWhiteSpace(onCreateResult)) { var jl = new JobLog() { Job = j, TechUser = currentUser, Timestamp = DateTime.Now, Comments = onCreateResult }; Database.JobLogs.Add(jl); } } catch (Exception ex) { SystemLog.LogException("Job Expression - OnCreateExpression", ex); } // Add Comments if (!string.IsNullOrWhiteSpace(m.Comments)) { var jl = new JobLog() { Job = j, TechUser = currentUser, Timestamp = DateTime.Now, Comments = m.Comments }; Database.JobLogs.Add(jl); } Database.SaveChanges(); // Return Dialog Redirect var redirectModel = new Models.Job.CreateRedirectModel() { JobId = j.Id }; redirectModel.RedirectDelay = TimeSpan.FromSeconds(2); if (m.QuickLog.HasValue && m.QuickLog.Value && !string.IsNullOrWhiteSpace(m.SourceUrl)) redirectModel.RedirectLink = m.SourceUrl; else if (!Authorization.Has(Claims.Job.Show)) if (!string.IsNullOrWhiteSpace(m.SourceUrl)) redirectModel.RedirectLink = m.SourceUrl; else redirectModel.RedirectLink = Url.Action(MVC.Job.Index()); else { redirectModel.RedirectLink = Url.Action(MVC.Job.Show(j.Id)); redirectModel.RedirectDelay = null; } return View(Views.Create_Redirect, redirectModel); } }
public static void OnDelete(this Device d, DiscoDataContext Database) { // Delete Jobs foreach (Job j in Database.Jobs.Where(i => i.DeviceSerialNumber == d.SerialNumber)) { if (j.UserId == null) { // No User associated, thus must Delete whole Job if (j.CanDelete()) j.OnDelete(Database); else throw new InvalidOperationException(string.Format("Deletion of Device is Denied (See Job# {0})", j.Id)); } else { // User associated to Job, thus just remove Devices' association j.DeviceSerialNumber = null; // Write Job Log JobLog jobLog = new JobLog() { JobId = j.Id, TechUserId = UserService.CurrentUser.UserId, Timestamp = DateTime.Now, Comments = string.Format("# Device Deleted\r\n\r\nSerial Number: **{0}**\r\nComputer Name: **{1}**\r\nModel: **{2}**\r\nProfile: **{3}**", d.SerialNumber, d.DeviceDomainId, d.DeviceModel, d.DeviceProfile) }; Database.JobLogs.Add(jobLog); } } // Disable Wireless Certificates foreach (var wc in Database.DeviceCertificates.Where(i => i.DeviceSerialNumber == d.SerialNumber)) { wc.DeviceSerialNumber = null; wc.Enabled = false; } // Delete Device Details foreach (var dd in Database.DeviceDetails.Where(i => i.DeviceSerialNumber == d.SerialNumber)) Database.DeviceDetails.Remove(dd); // Delete Device Attachments foreach (var da in Database.DeviceAttachments.Where(i => i.DeviceSerialNumber == d.SerialNumber)) { da.RepositoryDelete(Database); Database.DeviceAttachments.Remove(da); } // Delete Device User Assignments foreach (var dua in Database.DeviceUserAssignments.Where(i => i.DeviceSerialNumber == d.SerialNumber)) Database.DeviceUserAssignments.Remove(dua); Database.Devices.Remove(d); }