using Comal.Classes; using InABox.Clients; using InABox.Core; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using XF.Material.Forms.UI.Dialogs; using IDigitalFormInstance = InABox.Core.IDigitalFormInstance; namespace PRS.Mobile { public class DigitalFormHostModel : IDigitalFormHostModel where TEntity : Entity, IRemotable, IPersistent, new() where TEntityLink : EntityLink, new() where TInstance : Entity, IRemotable, IPersistent, IDigitalFormInstance, new() { public IDigitalFormDataModel DigitalFormDataModel { get; set; } public DFLayout DFLayout { get; set; } public DigitalFormLayout DigitalFormLayout { get; set; } public Entity Entity { get; set; } public bool ReadOnly { get; set; } public bool NewForm { get; set; } public event OnDigitalFormHostModelSaved OnDigitalFormHostModelSaved; public event OnDigitalFormHostModelBeforeSave OnDigitalFormHostModelBeforeSave; public DigitalFormHostModel() { DFLayout = new DFLayout(); NewForm = true; ReadOnly = false; } public void LoadItems(Entity parent, Entity form, DigitalFormLayout layout = null) { List variables = new List(); var loadLayout = Task.Run(() => { if (layout == null) DigitalFormLayout = QueryDigitalFormLayout(form); else DigitalFormLayout = layout; }); var getVariables = Task.Run(() => { variables = QueryVariables(form); }); var loadDFDataModel = Task.Run(() => { DigitalFormDataModel = new DigitalFormDataModel(parent.ID, form.ID); DigitalFormDataModel.Load(null); Entity = DigitalFormDataModel.Entity; }); Task.WaitAll(loadLayout, getVariables, loadDFDataModel); DFLayout.LoadLayout(DigitalFormLayout.Layout); DFLayout.LoadVariables(variables); DigitalFormDataModel.Instance.Form.ID = DigitalFormLayout.Form.ID; DigitalFormDataModel.Variables = variables.ToArray(); if (!string.IsNullOrWhiteSpace(DigitalFormDataModel.Instance.FormData)) NewForm = false; if (DigitalFormDataModel.Instance.FormCompleted != DateTime.MinValue) ReadOnly = true; DigitalFormDataModel.BeforeModelSaved += (m) => { OnDigitalFormHostModelBeforeSave?.Invoke(); DigitalFormDataModel.Entity = Entity; CheckEntity(SaveType.BeforeSave); }; DigitalFormDataModel.OnModelSaved += async (m) => { var userResponseRequest = CheckEntity(SaveType.AfterSave); var response = await OnDigitalFormHostModelSaved?.Invoke(userResponseRequest); if (response == DigitalFormHostUserResponse.Yes) DoResponseActions(userResponseRequest); }; } private IDigitalFormInstance GetInstance(Guid iD) { return new Client().Query( new Filter(x => x.ID).IsEqualTo(iD) ).Rows.FirstOrDefault().ToObject(); } public DigitalFormLayout QueryDigitalFormLayout(Entity form) { CoreTable layouts = QueryTableDigitalFormLayout(form); while (layouts == null) layouts = QueryTableDigitalFormLayout(form); DigitalFormLayout layout = layouts.Rows.FirstOrDefault(r => r.Get(c => c.Type) == DFLayoutType.Mobile)?.ToObject(); while (layout == null) layout = layouts.Rows.FirstOrDefault()?.ToObject(); return layout; } private CoreTable QueryTableDigitalFormLayout(Entity form) { try { return new Client().Query ( new Filter(x => x.Form.ID) .IsEqualTo(CoreUtils.GetPropertyValue(form,"Form.ID") ?? Guid.Empty) //(form as EntityForm).Form.ID) //.And(x => x.Type).IsEqualTo(DFLayoutType.Mobile) .And(x => x.Active).IsEqualTo(true), new Columns(x => x.ID) .Add(x => x.Form.ID) .Add(x => x.Form.AppliesTo) .Add(x => x.Layout) .Add(x => x.Type) ); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); return null; } } public List QueryVariables(Entity form) { List variables = new List(); var table = QueryVariablesTable(form); while (table == null) table = QueryVariablesTable(form); foreach (CoreRow coreRow in table.Rows) variables.Add(CreateVariable(coreRow)); return variables; } private CoreTable QueryVariablesTable(Entity form) { try { return new Client().Query( new Filter(x => x.Form.ID) .IsEqualTo(CoreUtils.GetPropertyValue(form,"Form.ID") ?? Guid.Empty), //(form as EntityForm).Form.ID), new Columns(x => x.Code) .Add(x => x.Parameters) .Add(x => x.Description) .Add(x => x.VariableType), null ); } catch (Exception ex) { InABox.Mobile.MobileLogging.Log(ex); return null; } } public List QueryVariables(DigitalFormLayout layout) { List variables = new List(); var table = new Client().Query( new Filter(x => x.Form.ID).IsEqualTo(layout.Form.ID), new Columns(x => x.Code, x => x.Parameters, x => x.Description, x => x.VariableType), null ); foreach (CoreRow coreRow in table.Rows) variables.Add(CreateVariable(coreRow)); return variables; } private DigitalFormVariable CreateVariable(CoreRow row) { DigitalFormVariable v = new DigitalFormVariable(); v.Code = row.Get(x => x.Code); v.Parameters = row.Get(x => x.Parameters); v.Description = row.Get(x => x.Description); v.VariableType = row.Get(x => x.VariableType); return v; } // public void SetPropertyValues(QAFormViewer viewer) //currently does not include Employee Forms // { // try // { // if (DigitalFormLayout.Form.AppliesTo.Equals("Kanban")) // { // foreach (KeyValuePair pair in viewer.EntityResults) // { // if (pair.Key.Contains("ID")) // { // //this only sets the entity lookup.ID, not the description or code - is this an issue?? // CoreUtils.SetPropertyValue(Entity, pair.Key, Guid.Parse(pair.Value)); // } // else if (DateTime.TryParse(pair.Value, out DateTime datetime)) // { // string parsedDate = ""; // parsedDate = datetime.ToString("yyyy-mm-dd hh:mm:ss.zzz"); ; // CoreUtils.SetPropertyValue(Entity, pair.Key, parsedDate); // } // else // { // CoreUtils.SetPropertyValue(Entity, pair.Key, pair.Value); // } // // } // } // else if (DigitalFormLayout.Form.AppliesTo.Equals("LeaveRequest")) // { // foreach (KeyValuePair pair in viewer.EntityResults) // { // if (pair.Key.Contains("ID")) // { // CoreUtils.SetPropertyValue(Entity, pair.Key, Guid.Parse(pair.Value)); // } // else if (pair.Key.Equals("From")) // { // (Entity as LeaveRequest).From = DateTime.Parse(pair.Value); // } // else if (pair.Key.Equals("To")) // { // (Entity as LeaveRequest).To = DateTime.Parse(pair.Value); // } // else if (pair.Key.Equals("FromTime")) // { // (Entity as LeaveRequest).FromTime = TimeSpan.Parse(pair.Value); // } // else if (pair.Key.Equals("ToTime")) // { // (Entity as LeaveRequest).ToTime = TimeSpan.Parse(pair.Value); // if ((Entity as LeaveRequest).ToTime == new TimeSpan(0)) // { // (Entity as LeaveRequest).ToTime = new TimeSpan(23, 59, 59); // } // } // else if (pair.Key.Equals("Notes")) // { // (Entity as LeaveRequest).Notes = (Entity as LeaveRequest).Notes + System.Environment.NewLine + pair.Value; // } // else // { // CoreUtils.SetPropertyValue(Entity, pair.Key, pair.Value); // } // } // } // } // catch (Exception e) // { // viewer.errors.Add(e.Message); // } // } private void DoResponseActions(DigitalFormHostResponseRequest userResponseRequest) { if (userResponseRequest == DigitalFormHostResponseRequest.CloseKanban) { var kanban = Entity as Kanban; kanban.Category = "Complete"; Task.Run(() => { new Client().Save(kanban, "Completed after completing all forms for task"); }); } } private DigitalFormHostResponseRequest CheckEntity(SaveType saveType) { if (Entity.GetType() == typeof(Kanban)) return DoKanbanActions(saveType); else if (Entity.GetType() == typeof(LeaveRequest)) (Entity as LeaveRequest).EmployeeLink.ID = App.Data.Me.ID; return DigitalFormHostResponseRequest.None; } private DigitalFormHostResponseRequest DoKanbanActions(SaveType saveType) { if (saveType == SaveType.BeforeSave) CheckAndCreateKanban(); else if (saveType == SaveType.AfterSave) { CheckSubscriber(); return CheckKanbanForms(); } return DigitalFormHostResponseRequest.None; } private DigitalFormHostResponseRequest CheckKanbanForms() { if (Entity.ID != Guid.Empty) { CoreTable table = new Client().Query(new Filter(x => x.Parent.ID).IsEqualTo(Entity.ID), new Columns(x => x.FormCompleted)); if (table.Rows.Any()) { List dates = new List(); foreach (CoreRow row in table.Rows) { dates.Add(row.Get(x => x.FormCompleted)); } var incompletedates = dates.Where(x => x.Equals(DateTime.MinValue)); if (!incompletedates.Any()) { return DigitalFormHostResponseRequest.CloseKanban; } } } return DigitalFormHostResponseRequest.None; } private void CheckAndCreateKanban() { if (Entity.ID == Guid.Empty) { Kanban kanban = Entity as Kanban; kanban.EmployeeLink.ID = App.Data.Me.ID; kanban.DueDate = DateTime.Today; kanban.Title = "Form - " + DigitalFormLayout.Form.Description; kanban.Notes = new string[] { "Created by Forms App" }; kanban.Category = "In Progress"; Entity = kanban; } } private void CheckSubscriber() { var sub = new Client().Query( new Filter(x => x.Kanban.ID).IsEqualTo(Entity.ID), new Columns(x => x.ID) ); if (sub.Rows.Count == 0) AddSubscriber(); } private void AddSubscriber() { KanbanSubscriber subscriber = new KanbanSubscriber(); subscriber.Kanban.ID = Entity.ID; subscriber.Assignee = true; subscriber.Employee.ID = App.Data.Me.ID; new Client().Save(subscriber, "Updated From Mobile Device"); } enum SaveType { BeforeSave, AfterSave, } } }