using comal.timesheets.QAForms; 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 comal.timesheets { 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 getLayout = Task.Run(() => { var loadLayout = Task.Run(() => { if (layout == null) DigitalFormLayout = QueryDigitalFormLayout(form); else DigitalFormLayout = layout; DFLayout.LoadLayout(DigitalFormLayout.Layout); }); // This needs to be set in the provided form, because layout may well be null //(form as EntityForm).Form.ID = layout.Form.ID; var getVariables = Task.Run(() => { variables = QueryVariables(form); }); Task.WaitAll(loadLayout, getVariables); DFLayout.LoadVariables(variables); }); var loadDFDataModel = Task.Run(() => { DigitalFormDataModel = new DigitalFormDataModel(parent.ID, form.ID); DigitalFormDataModel.Load(null); Entity = DigitalFormDataModel.Entity; }); Task.WaitAll(getLayout, loadDFDataModel); DigitalFormDataModel.Instance.Form.ID = DigitalFormLayout.Form.ID; 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((form as EntityForm).Form.ID) //.And(x => x.Type).IsEqualTo(DFLayoutType.Mobile) .And(x => x.Active).IsEqualTo(true), new Columns( x => x.ID, x => x.Form.ID, x => x.Layout, 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((form as EntityForm).Form.ID), new Columns(x => x.Code, x => x.Parameters, x => x.Description, 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.propertyResults) { 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.propertyResults) { 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, } } }