using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.WPF; namespace PRSDesktop { public static class NotificationUtils { private static Entity LoadEntity(Type type, Guid id, params string[] columnnames) { var filter = Activator.CreateInstance(typeof(Filter<>).MakeGenericType(type), "ID", Operator.IsEqualTo, id); IColumns? columns = null; if (columnnames.Any()) { columns = Columns.Create(type); foreach (var columnname in columnnames) columns.Add(columnname); } var table = ClientFactory.CreateClient(type).Query(filter, columns); var result = table.Rows.FirstOrDefault()?.ToObject(type) as Entity; return result; } private static IDynamicGrid FindDataGrid(Type type) { var gridtypes = CoreUtils.TypeList( AppDomain.CurrentDomain.GetAssemblies(), myType => myType.IsClass && !myType.IsAbstract && !myType.IsGenericType && myType.BaseType != null && myType.BaseType.Name == typeof(DynamicDataGrid<>).Name && myType.ContainsInheritedGenericType(type) ).ToArray(); var gridtype = gridtypes.Any() ? gridtypes.First() : typeof(DynamicDataGrid<>).MakeGenericType(type); var grid = Activator.CreateInstance(gridtype) as IDynamicGrid; return grid; } private static bool PerformAction(Guid[] ids, Func action) { if (!ids.Any()) //if (Notifications.SelectedRows?.FirstOrDefault() == null) { MessageBox.Show("Please select a message first!"); return false; } var updates = new List(); Notification[] notifications = { }; var columns = new Columns().Default(ColumnType.IncludeForeignKeys); columns.Add(x => x.EntityID); columns.Add(x => x.EntityType); columns.Add(x => x.Closed); columns.Add(x => x.Sender.Name); columns.Add(x => x.Description); using (new WaitCursor()) { notifications = new Client().Query( new Filter(x => x.ID).InList(ids), columns ).Rows.Select(x => x.ToObject()).ToArray(); } foreach (var notification in notifications) if (action.Invoke(notification)) updates.Add(notification); if (updates.Any()) { using (new WaitCursor()) { new Client().Save(updates, ""); } return true; } return false; } public static bool IsDigitalForm(string name) { if (string.IsNullOrWhiteSpace(name)) return false; var type = CoreUtils.GetEntity(name); var result = type.GetInterfaces().Contains(typeof(IDigitalFormInstance)); return result; } public static Type? GetEntityType(string name) { if (string.IsNullOrWhiteSpace(name)) return null; if (!IsDigitalForm(name)) return CoreUtils.GetEntityOrNull(name); var form = CoreUtils.GetEntityOrNull(name); if (form is null) return null; var parent = CoreUtils.GetProperty(form, "Parent"); var type = parent.PropertyType.GetInheritedGenericTypeArguments().FirstOrDefault(); return type; } public static bool MakeVisible(FrameworkElement element, float left, float right, params bool[] visibleconditions) { var visible = true; foreach (var condition in visibleconditions) visible = visible && condition; element.Visibility = visible ? Visibility.Visible : Visibility.Collapsed; element.Margin = new Thickness(left, element.Margin.Top, right, element.Margin.Bottom); return visible; } public static bool ViewEntity(Guid[] ids) { return PerformAction(ids, notification => { var type = GetEntityType(notification.EntityType); var id = notification.EntityID; if (IsDigitalForm(notification.EntityType)) { var form = (LoadEntity( CoreUtils.GetEntity(notification.EntityType), notification.EntityID, "ID", "Parent.ID") as IDigitalFormInstance)!; id = form.ParentID(); } var entity = LoadEntity(type, id); var grid = FindDataGrid(type); return grid.EditItems(new object[] { entity }); }); } public static bool ViewForm(Guid[] ids) { return PerformAction(ids, notification => { var type = CoreUtils.GetEntity(notification.EntityType); var form = LoadEntity(type, notification.EntityID); if(form is IDigitalFormInstance formInstance) { if(DynamicFormEditWindow.EditDigitalForm(formInstance, out var dataModel)){ dataModel.Update(null); return true; } } return false; }); } public static bool ReplyOrForward(Guid[] ids, string prefix, bool selectrecipient, bool sentfolder) { return PerformAction(ids, notification => { var sb = new StringBuilder(string.Format("\n\nAt {0:HH:mmtt} on {0:dd MMM yy}, {1} wrote:\n", notification.Created, notification.Sender.Name)); var desc = string.IsNullOrWhiteSpace(notification.Description) ? "" : CoreUtils.StripHTML(notification.Description); foreach (var line in desc.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries).Where(x => !string.IsNullOrWhiteSpace(x))) sb.AppendFormat("> {0}\n", line.Trim()); var form = new NotificationForm { Subject = string.Format("{0} {1}", prefix, notification.Title), Recipient = selectrecipient ? sentfolder ? notification.Employee.ID : notification.Sender.ID : Guid.Empty, JobID = notification.Job.ID, Description = sb.ToString() }; if (form.ShowDialog() == true) { notification.Description = string.Format("{0}\nReplied to Message", notification.Description); if (MessageBox.Show("Do you want to dismiss this message?", "Task Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes) notification.Closed = DateTime.Now; return true; } return false; }); } public static bool CreateTask(Guid[] ids, Guid employeeid) { return PerformAction(ids, notification => { var task = new Kanban { Title = notification.Title, Notes = new[] { notification.Description }, Status = KanbanStatus.Open }; task.JobLink.ID = notification.Job.ID; task.EmployeeLink.ID = employeeid; task.ManagerLink.ID = notification.Sender.ID; var kg = new TaskGrid(); if (kg.EditItems(new[] { task })) { using (new WaitCursor()) { task = new Client().Load(new Filter(x => x.ID).IsEqualTo(task.ID)).FirstOrDefault(); } notification.Description = string.Format("{0}\nCreated Task for {1}", notification.Description, task.EmployeeLink.Name); //notification.Kanban.ID = task.ID; if (MessageBox.Show("Do you want to dismiss this message?", "Task Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes) notification.Closed = DateTime.Now; return true; } return false; }); } public static bool CreateRequi(Guid[] ids, Guid employeeid) { return PerformAction(ids, notification => { var requi = new Requisition { Title = notification.Title, Notes = new[] { notification.Description } }; requi.JobLink.ID = notification.Job.ID; requi.Employee.ID = employeeid; requi.RequestedBy.ID = notification.Sender.ID; var grid = new DynamicDataGrid(); if (grid.EditItems(new[] { requi })) { notification.Description = string.Format("{0}\nCreated Requi# {1}", notification.Description, requi.Number); //notification.Requisition.ID = requi.ID; if (MessageBox.Show("Do you want to dismiss this message?", "Requisition Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes) notification.Closed = DateTime.Now; return true; } return false; }); } public static bool CreateDelivery(Guid[] ids) { return PerformAction(ids, notification => { var delivery = new Delivery { Notes = notification.Description, Due = DateTime.Today.AddDays(1) }; delivery.Employee.ID = notification.Sender.ID; delivery.Job.ID = notification.Job.ID; var grid = new DynamicDataGrid(); if (grid.EditItems(new[] { delivery })) { notification.Description = string.Format("{0}\nCreated Delivery# {1}", notification.Description, delivery.Number); //notification.Delivery.ID = delivery.ID; if (MessageBox.Show("Do you want to dismiss this message?", "Delivery Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes) notification.Closed = DateTime.Now; return true; } return false; }); } public static bool AttachToJob(Guid[] ids) { return PerformAction(ids, notification => { var jobs = new MultiSelectDialog( null, new Columns(x => x.ID), //new System.Linq.Expressions.Expression>[] { x=>x.ID }, false ); if (jobs.ShowDialog() != true) return false; notification.Job.ID = jobs.IDs().First(); return true; }); } public static bool ViewJob(Guid[] ids) { return PerformAction(ids, notification => { var job = new Client().Load(new Filter(x => x.ID).IsEqualTo(notification.Job.ID)).FirstOrDefault(); if (job != null) FindDataGrid(typeof(Job)).EditItems(new[] { job }); return false; }); } public static bool CreateSetout(Guid[] ids) { return PerformAction(ids, notification => { var templates = new MultiSelectDialog( null, new Columns(x => x.ID), //new System.Linq.Expressions.Expression>[] { x=>x.ID }, false ); if (templates.ShowDialog() != true) return false; var template = templates.Items().FirstOrDefault(); Setout setout = null; ManufacturingPacket packet = null; var pstages = new List(); using (new WaitCursor()) { var setoutnumber = string.Format("{0}-{1:yyMMdd}-", notification.Job.JobNumber, DateTime.Today); var setouts = new Client().Query( new Filter(x => x.JobLink.ID).IsEqualTo(notification.Job.ID).And(x => x.Number).BeginsWith(setoutnumber), new Columns(x => x.Number), new SortOrder(x => x.Number) ).Rows; var i = 1; while (setouts.Any(r => r.Get(c => c.Number).Equals(string.Format("{0}{1:D3}", setoutnumber, i)))) i++; setout = new Setout { Description = notification.Description, Reference = notification.Title, Number = string.Format("{0}{1:D2}", setoutnumber, i) }; setout.JobLink.ID = notification.Job.ID; new Client().Save(setout, "Created from Notification"); packet = new ManufacturingPacket(); packet.SetoutLink.ID = setout.ID; //packet.JobLink.ID = notification.Job.ID; packet.Serial = string.Format("{0}-001", setout.Number); packet.Group = template.Factory.Name; packet.ManufacturingTemplateLink.ID = template.ID; packet.ManufacturingTemplateLink.Code = template.Code; packet.Title = notification.Title; packet.Quantity = 1; new Client().Save(packet, "Created from Notification"); var tstages = new Client().Load( new Filter(x => x.Template.ID).IsEqualTo(packet.ManufacturingTemplateLink.ID), new SortOrder(x => x.Sequence) ); foreach (var tstage in tstages) { var pstage = new ManufacturingPacketStage { Time = tstage.Time, Sequence = tstage.Sequence, SequenceType = tstage.SequenceType, Started = DateTime.MinValue, PercentageComplete = 0.0F, Completed = DateTime.MinValue, QualityChecks = tstage.QualityChecks, QualityStatus = QualityStatus.NotChecked, QualityNotes = "" }; var section = new Client() .Load(new Filter(x => x.ID).IsEqualTo(tstage.Section.ID)) .FirstOrDefault(); if (section != null) { pstage.ManufacturingSectionLink.ID = tstage.Section.ID; pstage.ManufacturingSectionLink.Name = tstage.Section.Name; } pstages.Add(pstage); } new Client().Save(pstages, "Created from Notification"); } var grid = new DynamicDataGrid(); if (grid.EditItems(new[] { setout })) { notification.Description = string.Format("{0}\nCreated Setout# {1}", notification.Description, setout.Number); //notification.Setout.ID = setout.ID; if (MessageBox.Show("Do you want to dismiss this message?", "Setout Created", MessageBoxButton.YesNo) == MessageBoxResult.Yes) notification.Closed = DateTime.Now; return true; } using (new WaitCursor()) { // Cascade on PAcket / PacketStage should** take care of the child records // Be good to keep an eye on that! new Client().Delete(setout, ""); } return false; }); } public static bool Archive(Guid[] ids) { return PerformAction(ids, notification => { notification.Closed = DateTime.Now; return true; }); } public static bool Reopen(Guid[] ids) { return PerformAction(ids, notification => { notification.Closed = DateTime.MinValue; return true; }); } } }