using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; using Comal.Classes; using InABox.Clients; using InABox.Core; using InABox.DynamicGrid; using InABox.WPF; using Syncfusion.Linq; namespace PRSDesktop { public class LeaveRequestGrid : DynamicDataGrid { //public bool FutureOnly = true; //private bool InProgressOnly = true; protected override void Init() { base.Init(); HiddenColumns.Add(x=>x.OpenForms); HiddenColumns.Add(x=>x.FormCount); HiddenColumns.Add(x=>x.ApprovalSet.ID); HiddenColumns.Add(x=>x.OutstandingApprovals); ActionColumns.Add(new DynamicImageColumn(FormImage, FormAction) { Position = DynamicActionColumnPosition.End, ToolTip = FormToolTip}); ActionColumns.Add(new DynamicMenuColumn(BuildMenu)); } private Guid[]? availableApprovalSets = null; private void BuildMenu(DynamicMenuColumn column, CoreRow? row) { if (row is null) return; var menu = column.GetMenu(); availableApprovalSets ??= Client.Query( new Filter(x=>x.Employee.ID).IsEqualTo(App.EmployeeID), Columns.None().Add(x=>x.ApprovalSet.ID) ).Rows .Select(r =>r.Get(c=>c.ApprovalSet.ID)) .Distinct() .ToArray(); if (availableApprovalSets.Contains(row.Get(x => x.ApprovalSet.ID))) { var approvals = row.Get(x => x.OutstandingApprovals).Split(','); if (approvals.Contains(App.EmployeeCode)) { menu.AddItem("Approve", null, () => UpdateLeaveRequest(row,LeaveRequestApprovalStatus.Approved)); menu.AddItem("Reject", null, () => UpdateLeaveRequest(row,LeaveRequestApprovalStatus.Rejected, true)); } else menu.AddItem("Reset", null, () => UpdateLeaveRequest(row,LeaveRequestApprovalStatus.NotYetApproved)); } if (Security.IsAllowed()) { if (menu.Items.Count > 0) menu.AddSeparator(); var approvalSetItem = menu.AddItem("Approval Set", null, null); approvalSetItem.AddItem("Loading...", null, null, enabled: false); menu.AddItem("Manage Approvals", null, row, ManageApprovals_Click); var id = row.Get(x => x.ID); var selectedApproval = row.Get(x => x.ApprovalSet.ID); Task.Run(() => { return Client.Query( null, Columns.None().Add(x => x.ID).Add(x => x.Code).Add(x => x.Description)) .ToArray(); }).ContinueWith(approvals => { approvalSetItem.Items.Clear(); foreach(var approval in approvals.Result) { var item = approvalSetItem.AddItem($"{approval.Code}: {approval.Description}", null, (row, approval), ApprovalSet_Click); item.IsChecked = approval.ID == selectedApproval; } if (row.Get(x => x.ApprovalSet.ID) != Guid.Empty) { if (approvalSetItem.Items.Count > 0) approvalSetItem.AddSeparator(); approvalSetItem.AddItem("Clear Approval Set", null, row, ApprovalSetClear_Click); } }, TaskScheduler.FromCurrentSynchronizationContext()); } } private void UpdateLeaveRequest(CoreRow row, LeaveRequestApprovalStatus status, bool requireNotes = false) { var note = ""; if (requireNotes) { if (!TextBoxDialog.Execute("Reason for Rejection", ref note, false)) return; } var requestid = row.Get(x => x.ID); var approval = Client.Query( new Filter(x => x.LeaveRequest.ID).IsEqualTo(requestid) .And(x => x.Employee.ID).IsEqualTo(App.EmployeeID), Columns.None().Add(x=>x.ID).Add(x=>x.Status) ).Rows .FirstOrDefault()? .ToObject(); if ((approval != null) && (approval.Status != status)) { approval.Status = status; approval.Notes = note; Client.Save(approval,$"Status Updated to {status}"); Refresh(false, true); } } private void ApprovalSetClear_Click(CoreRow row) { var bill = row.ToObject(); bill.ApprovalSet.ID = Guid.Empty; SaveItem(bill); Refresh(false, true); } private void ManageApprovals_Click(CoreRow row) { var request = row.ToObject(); var grid = new LeaveRequestApprovalGrid(request); var dlg = new DynamicContentDialog(grid, buttonsVisible: false) { Title = "Manage Approvals" }; grid.Refresh(true, true); dlg.ShowDialog(); request = LoadItem(row); UpdateRow(row, request); DoChanged(); } private void ApprovalSet_Click((CoreRow row, LeaveRequestApprovalSet approvalSet) item) { var request = item.row.ToObject(); if (request.ApprovalSet.ID == item.approvalSet.ID) return; request.ApprovalSet.CopyFrom(item.approvalSet); SaveItem(request); Refresh(false, true); } private readonly BitmapImage _openforms = PRSDesktop.Resources.warning.AsBitmapImage(); private readonly BitmapImage _completedforms = PRSDesktop.Resources.contract.AsBitmapImage(); private BitmapImage? FormImage(CoreRow? row) { return row == null ? _completedforms : row?.Get(x => x.OpenForms) != 0 ? _openforms : row?.Get(x => x.FormCount) != 0 ? _completedforms : null; } private bool FormAction(CoreRow? row) { if (row is null) return false; var leaveRequestID = row.Get(x => x.ID); var menu = new ContextMenu(); DynamicGridUtils.PopulateFormMenu(menu, leaveRequestID, () => row.ToObject()); menu.IsOpen = true; return false; } private FrameworkElement? FormToolTip(DynamicActionColumn column, CoreRow? row) { if (row == null) return column.TextToolTip("Leave Request Form Status?"); int open = row.Get(x => x.OpenForms); int total = row.Get(x => x.FormCount); if (open != 0) return column.TextToolTip($"{open} incomplete forms"); if (total != 0) return column.TextToolTip($"{total} forms"); return null; } protected override void DoReconfigure(DynamicGridOptions options) { base.DoReconfigure(options); options.RecordCount = true; options.FilterRows = true; options.SelectColumns = true; } protected override Dictionary EditorValueChanged(IDynamicEditorForm editor, LeaveRequest[] items, string name, object value) { var result = base.EditorValueChanged(editor, items, name, value); if (name == "LeaveType.ID") { ReloadForms(editor, items.FirstOrDefault(), x => x.Activity.ID, value != null ? (Guid)value : Guid.Empty); } else if (name.Equals("EmployeeLink.ID")) { var activity = editor.FindEditor("LeaveType.ID") as ILookupEditorControl; if (activity != null) DefineLookups(activity, items); } return result; } protected override void AfterLoad(IDynamicEditorForm editor, LeaveRequest[] items) { base.AfterLoad(editor, items); if (items.First().ID == Guid.Empty) ReloadForms(editor, items.First(), x => x.Activity.ID, items.First().LeaveType.ID); } protected override BaseEditor? GetEditor(object item, DynamicGridColumn column) { var result = base.GetEditor(item, column); if (result == null) return null; if (!Security.IsAllowed() && (column.ColumnName.Equals("Approved") || column.ColumnName.Equals("Status"))) { result = result.CloneEditor(); result.Editable = Editable.Disabled; } return result; } } }