|
@@ -17,1244 +17,1243 @@ using System.Drawing;
|
|
|
using System.ComponentModel;
|
|
|
using InABox.Wpf;
|
|
|
|
|
|
-namespace PRSDesktop
|
|
|
+namespace PRSDesktop;
|
|
|
+
|
|
|
+public class TaskPanelProperties : BaseObject, IGlobalConfigurationSettings
|
|
|
+{
|
|
|
+ [Comment("Require that all tasks are given a task type.")]
|
|
|
+ public bool RequireTaskTypes { get; set; } = false;
|
|
|
+}
|
|
|
+
|
|
|
+public class TaskPanelFilterButton : FilterButton<Kanban>
|
|
|
{
|
|
|
- public class TaskPanelProperties : BaseObject, IGlobalConfigurationSettings
|
|
|
+ public TaskPanelFilterButton() : base(
|
|
|
+ new GlobalConfiguration<CoreFilterDefinitions>(nameof(Kanban)),
|
|
|
+ new UserConfiguration<CoreFilterDefinitions>(nameof(Kanban)))
|
|
|
{
|
|
|
- [CheckBoxEditor(ToolTip = "Require that all tasks are given a task type.")]
|
|
|
- public bool RequireTaskTypes { get; set; } = false;
|
|
|
}
|
|
|
|
|
|
- public class TaskPanelFilterButton : FilterButton<Kanban>
|
|
|
+ public static Filter<Kanban> ConvertFilterToKanbanFilter(Filter<Kanban>? kanbanFilter)
|
|
|
{
|
|
|
- public TaskPanelFilterButton() : base(
|
|
|
- new GlobalConfiguration<CoreFilterDefinitions>(nameof(Kanban)),
|
|
|
- new UserConfiguration<CoreFilterDefinitions>(nameof(Kanban)))
|
|
|
+ if (kanbanFilter is null)
|
|
|
{
|
|
|
+ return new Filter<Kanban>().All();
|
|
|
}
|
|
|
-
|
|
|
- public static Filter<Kanban> ConvertFilterToKanbanFilter(Filter<Kanban>? kanbanFilter)
|
|
|
+ else if (CoreUtils.TryFindMemberExpression(kanbanFilter.Expression, out var mexp))
|
|
|
{
|
|
|
- if (kanbanFilter is null)
|
|
|
+ var prop = CoreUtils.GetFullPropertyName(mexp, ".");
|
|
|
+ var filter = new Filter<Kanban>(prop)
|
|
|
{
|
|
|
- return new Filter<Kanban>().All();
|
|
|
- }
|
|
|
- else if (CoreUtils.TryFindMemberExpression(kanbanFilter.Expression, out var mexp))
|
|
|
- {
|
|
|
- var prop = CoreUtils.GetFullPropertyName(mexp, ".");
|
|
|
- var filter = new Filter<Kanban>(prop)
|
|
|
- {
|
|
|
- Operator = kanbanFilter.Operator,
|
|
|
- Value = kanbanFilter.Value
|
|
|
- };
|
|
|
+ Operator = kanbanFilter.Operator,
|
|
|
+ Value = kanbanFilter.Value
|
|
|
+ };
|
|
|
|
|
|
- filter.Ands.AddRange(kanbanFilter.Ands.Select(ConvertFilterToKanbanFilter));
|
|
|
- filter.Ors.AddRange(kanbanFilter.Ors.Select(ConvertFilterToKanbanFilter));
|
|
|
+ filter.Ands.AddRange(kanbanFilter.Ands.Select(ConvertFilterToKanbanFilter));
|
|
|
+ filter.Ors.AddRange(kanbanFilter.Ors.Select(ConvertFilterToKanbanFilter));
|
|
|
|
|
|
- return filter;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return new Filter<Kanban>().None();
|
|
|
- }
|
|
|
+ return filter;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return new Filter<Kanban>().None();
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public static Filter<KanbanSubscriber> ConvertFilterToSubscriberFilter(Filter<IKanban>? kanbanFilter)
|
|
|
+ public static Filter<KanbanSubscriber> ConvertFilterToSubscriberFilter(Filter<IKanban>? kanbanFilter)
|
|
|
+ {
|
|
|
+ if (kanbanFilter is null)
|
|
|
{
|
|
|
- if (kanbanFilter is null)
|
|
|
- {
|
|
|
- return new Filter<KanbanSubscriber>().All();
|
|
|
- }
|
|
|
- else if (CoreUtils.TryFindMemberExpression(kanbanFilter.Expression, out var mexp))
|
|
|
+ return new Filter<KanbanSubscriber>().All();
|
|
|
+ }
|
|
|
+ else if (CoreUtils.TryFindMemberExpression(kanbanFilter.Expression, out var mexp))
|
|
|
+ {
|
|
|
+ var prop = CoreUtils.GetFullPropertyName(mexp, ".");
|
|
|
+ var filter = new Filter<KanbanSubscriber>(nameof(KanbanSubscriber.Kanban) + "." + prop)
|
|
|
{
|
|
|
- var prop = CoreUtils.GetFullPropertyName(mexp, ".");
|
|
|
- var filter = new Filter<KanbanSubscriber>(nameof(KanbanSubscriber.Kanban) + "." + prop)
|
|
|
- {
|
|
|
- Operator = kanbanFilter.Operator,
|
|
|
- Value = kanbanFilter.Value
|
|
|
- };
|
|
|
+ Operator = kanbanFilter.Operator,
|
|
|
+ Value = kanbanFilter.Value
|
|
|
+ };
|
|
|
|
|
|
- filter.Ands.AddRange(kanbanFilter.Ands.Select(ConvertFilterToSubscriberFilter));
|
|
|
- filter.Ors.AddRange(kanbanFilter.Ors.Select(ConvertFilterToSubscriberFilter));
|
|
|
+ filter.Ands.AddRange(kanbanFilter.Ands.Select(ConvertFilterToSubscriberFilter));
|
|
|
+ filter.Ors.AddRange(kanbanFilter.Ors.Select(ConvertFilterToSubscriberFilter));
|
|
|
|
|
|
- return filter;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- return new Filter<KanbanSubscriber>().None();
|
|
|
- }
|
|
|
+ return filter;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return new Filter<KanbanSubscriber>().None();
|
|
|
}
|
|
|
}
|
|
|
+}
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Interaction logic for TaskPanel.xaml
|
|
|
- /// </summary>
|
|
|
- public partial class TaskPanel : UserControl, IPanel<Kanban>, ITaskHost, IMasterDetailControl<Job>, IPropertiesPanel<TaskPanelProperties, CanConfigureTasksPanel>
|
|
|
+/// <summary>
|
|
|
+/// Interaction logic for TaskPanel.xaml
|
|
|
+/// </summary>
|
|
|
+public partial class TaskPanel : UserControl, IPanel<Kanban>, ITaskHost, IMasterDetailControl<Job>, IPropertiesPanel<TaskPanelProperties, CanConfigureTasksPanel>
|
|
|
+{
|
|
|
+ private bool _bTabChanging;
|
|
|
+ private KanbanType[] kanbanTypes = null!; // Initialized in Setup()
|
|
|
+
|
|
|
+ public IList<KanbanType> KanbanTypes => kanbanTypes;
|
|
|
+
|
|
|
+ public Job? Master { get; set; }
|
|
|
+
|
|
|
+ public TaskPanel()
|
|
|
{
|
|
|
- private bool _bTabChanging;
|
|
|
- private KanbanType[] kanbanTypes = null!; // Initialized in Setup()
|
|
|
-
|
|
|
- public IList<KanbanType> KanbanTypes => kanbanTypes;
|
|
|
+ InitializeComponent();
|
|
|
|
|
|
- public Job? Master { get; set; }
|
|
|
-
|
|
|
- public TaskPanel()
|
|
|
+ foreach (TabItem tab in TaskPanels.Items)
|
|
|
{
|
|
|
- InitializeComponent();
|
|
|
-
|
|
|
- foreach (TabItem tab in TaskPanels.Items)
|
|
|
- {
|
|
|
- var panel = (tab.Content as ITaskControl)!;
|
|
|
- _viewmap[panel.KanbanViewType] = tab;
|
|
|
- panel.Host = this;
|
|
|
- }
|
|
|
+ var panel = (tab.Content as ITaskControl)!;
|
|
|
+ _viewmap[panel.KanbanViewType] = tab;
|
|
|
+ panel.Host = this;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- #region Menu
|
|
|
+ #region Menu
|
|
|
|
|
|
- private void CompleteTask(ITaskControl control, RoutedEventArgs e, DateTime completed)
|
|
|
+ private void CompleteTask(ITaskControl control, RoutedEventArgs e, DateTime completed)
|
|
|
+ {
|
|
|
+ if (!MessageWindow.ShowYesNo("Are you sure you want to complete the selected tasks?", "Confirm Completion"))
|
|
|
+ return;
|
|
|
+ var tasks = (((FrameworkElement)e.Source).Tag as IEnumerable<TaskModel>)!;
|
|
|
+ Progress.ShowModal("Completing Tasks", progress =>
|
|
|
{
|
|
|
- if (!MessageWindow.ShowYesNo("Are you sure you want to complete the selected tasks?", "Confirm Completion"))
|
|
|
- return;
|
|
|
- var tasks = (((FrameworkElement)e.Source).Tag as IEnumerable<TaskModel>)!;
|
|
|
- Progress.ShowModal("Completing Tasks", progress =>
|
|
|
+ var kanbans = LoadKanbans(tasks, Columns.Required<Kanban>().Add(x => x.ID, x => x.Completed, x => x.Status));
|
|
|
+ foreach (var kanban in kanbans)
|
|
|
{
|
|
|
- var kanbans = LoadKanbans(tasks, Columns.Required<Kanban>().Add(x => x.ID, x => x.Completed, x => x.Status));
|
|
|
- foreach (var kanban in kanbans)
|
|
|
- {
|
|
|
- kanban.Completed = completed;
|
|
|
- kanban.Status = KanbanStatus.Complete;
|
|
|
- }
|
|
|
+ kanban.Completed = completed;
|
|
|
+ kanban.Status = KanbanStatus.Complete;
|
|
|
+ }
|
|
|
|
|
|
- Client.Save(kanbans, $"Kanban Marked as Complete");
|
|
|
- });
|
|
|
- control.Refresh();
|
|
|
- }
|
|
|
- private void AddChangeStatusButton(ITaskControl control, TaskModel[] models, MenuItem menu, string header, KanbanStatus status)
|
|
|
- {
|
|
|
- menu.AddItem(header, null, Tuple.Create(control, models, status), ChangeStatus_Click);
|
|
|
- }
|
|
|
+ Client.Save(kanbans, $"Kanban Marked as Complete");
|
|
|
+ });
|
|
|
+ control.Refresh();
|
|
|
+ }
|
|
|
+ private void AddChangeStatusButton(ITaskControl control, TaskModel[] models, MenuItem menu, string header, KanbanStatus status)
|
|
|
+ {
|
|
|
+ menu.AddItem(header, null, Tuple.Create(control, models, status), ChangeStatus_Click);
|
|
|
+ }
|
|
|
|
|
|
- private void ChangeStatus_Click(Tuple<ITaskControl, TaskModel[], KanbanStatus> obj)
|
|
|
+ private void ChangeStatus_Click(Tuple<ITaskControl, TaskModel[], KanbanStatus> obj)
|
|
|
+ {
|
|
|
+ var (control, tasks, status) = obj;
|
|
|
+ if (!MessageWindow.ShowYesNo($"Are you sure you want to mark the selected tasks as {status}?", "Confirm Change Status"))
|
|
|
+ return;
|
|
|
+ Progress.ShowModal("Changing Status", progress =>
|
|
|
{
|
|
|
- var (control, tasks, status) = obj;
|
|
|
- if (!MessageWindow.ShowYesNo($"Are you sure you want to mark the selected tasks as {status}?", "Confirm Change Status"))
|
|
|
- return;
|
|
|
- Progress.ShowModal("Changing Status", progress =>
|
|
|
+ var kanbans = LoadKanbans(tasks, Columns.Required<Kanban>().Add(x => x.ID, x => x.Completed, x => x.Status));
|
|
|
+ foreach (var kanban in kanbans)
|
|
|
{
|
|
|
- var kanbans = LoadKanbans(tasks, Columns.Required<Kanban>().Add(x => x.ID, x => x.Completed, x => x.Status));
|
|
|
- foreach (var kanban in kanbans)
|
|
|
+ if (status == KanbanStatus.Complete)
|
|
|
{
|
|
|
- if (status == KanbanStatus.Complete)
|
|
|
- {
|
|
|
- kanban.Completed = DateTime.Now;
|
|
|
- }
|
|
|
- kanban.Status = status;
|
|
|
+ kanban.Completed = DateTime.Now;
|
|
|
}
|
|
|
+ kanban.Status = status;
|
|
|
+ }
|
|
|
|
|
|
- new Client<Kanban>().Save(kanbans, $"Kanban Marked as {status}");
|
|
|
- });
|
|
|
- control.Refresh();
|
|
|
- }
|
|
|
+ new Client<Kanban>().Save(kanbans, $"Kanban Marked as {status}");
|
|
|
+ });
|
|
|
+ control.Refresh();
|
|
|
+ }
|
|
|
|
|
|
- public bool CanChangeTasks(IEnumerable<TaskModel> models)
|
|
|
+ public bool CanChangeTasks(IEnumerable<TaskModel> models)
|
|
|
+ {
|
|
|
+ foreach (var task in models)
|
|
|
{
|
|
|
- foreach (var task in models)
|
|
|
+ if (!App.EmployeeID.Equals(task.ManagerID) && !App.EmployeeID.Equals(task.EmployeeID))
|
|
|
{
|
|
|
- if (!App.EmployeeID.Equals(task.ManagerID) && !App.EmployeeID.Equals(task.EmployeeID))
|
|
|
- {
|
|
|
- // If you can change others tasks, IsFullControl is true - but we don't check at the beginning of the function
|
|
|
- // to save checking security tokens every time.
|
|
|
- return Security.IsAllowed<CanChangeOthersTasks>();
|
|
|
- }
|
|
|
+ // If you can change others tasks, IsFullControl is true - but we don't check at the beginning of the function
|
|
|
+ // to save checking security tokens every time.
|
|
|
+ return Security.IsAllowed<CanChangeOthersTasks>();
|
|
|
}
|
|
|
- return true;
|
|
|
}
|
|
|
+ return true;
|
|
|
+ }
|
|
|
|
|
|
- public void PopulateMenu(ITaskControl control, TaskModel task, ContextMenu menu)
|
|
|
+ public void PopulateMenu(ITaskControl control, TaskModel task, ContextMenu menu)
|
|
|
+ {
|
|
|
+ menu.Items.Clear();
|
|
|
+
|
|
|
+ var models = control.SelectedModels(task).ToArray();
|
|
|
+ var references = GetReferences(models);
|
|
|
+ var bLinks = references.Any(x => x.ReferenceType() != null);
|
|
|
+ var referencetypes = references.Select(x => x.ReferenceType()).Distinct().ToArray();
|
|
|
+ var bSingle = models.Length == 1;
|
|
|
+ var canChange = CanChangeTasks(models);
|
|
|
+
|
|
|
+ var edit = new MenuItem
|
|
|
{
|
|
|
- menu.Items.Clear();
|
|
|
-
|
|
|
- var models = control.SelectedModels(task).ToArray();
|
|
|
- var references = GetReferences(models);
|
|
|
- var bLinks = references.Any(x => x.ReferenceType() != null);
|
|
|
- var referencetypes = references.Select(x => x.ReferenceType()).Distinct().ToArray();
|
|
|
- var bSingle = models.Length == 1;
|
|
|
- var canChange = CanChangeTasks(models);
|
|
|
-
|
|
|
- var edit = new MenuItem
|
|
|
- {
|
|
|
- Tag = models,
|
|
|
- Header = referencetypes.SingleOrDefault() == typeof(Requisition)
|
|
|
- ? "Edit Requisition Details"
|
|
|
- : referencetypes.SingleOrDefault() == typeof(Setout)
|
|
|
- ? "Edit Setout Details"
|
|
|
- : referencetypes.SingleOrDefault() == typeof(Delivery)
|
|
|
- ? "Edit Delivery Details"
|
|
|
- : referencetypes.SingleOrDefault() == typeof(PurchaseOrder)
|
|
|
- ? "Edit Order Details"
|
|
|
- : "Edit Task" + (bSingle ? "" : "s")
|
|
|
- };
|
|
|
- edit.Click += (o, e) =>
|
|
|
- {
|
|
|
- var tasks = (((MenuItem)e.Source).Tag as IEnumerable<TaskModel>)!;
|
|
|
- if (EditReferences(tasks))
|
|
|
- control.Refresh();
|
|
|
- e.Handled = true;
|
|
|
- };
|
|
|
- edit.IsEnabled = referencetypes.Length == 1;
|
|
|
- menu.Items.Add(edit);
|
|
|
+ Tag = models,
|
|
|
+ Header = referencetypes.SingleOrDefault() == typeof(Requisition)
|
|
|
+ ? "Edit Requisition Details"
|
|
|
+ : referencetypes.SingleOrDefault() == typeof(Setout)
|
|
|
+ ? "Edit Setout Details"
|
|
|
+ : referencetypes.SingleOrDefault() == typeof(Delivery)
|
|
|
+ ? "Edit Delivery Details"
|
|
|
+ : referencetypes.SingleOrDefault() == typeof(PurchaseOrder)
|
|
|
+ ? "Edit Order Details"
|
|
|
+ : "Edit Task" + (bSingle ? "" : "s")
|
|
|
+ };
|
|
|
+ edit.Click += (o, e) =>
|
|
|
+ {
|
|
|
+ var tasks = (((MenuItem)e.Source).Tag as IEnumerable<TaskModel>)!;
|
|
|
+ if (EditReferences(tasks))
|
|
|
+ control.Refresh();
|
|
|
+ e.Handled = true;
|
|
|
+ };
|
|
|
+ edit.IsEnabled = referencetypes.Length == 1;
|
|
|
+ menu.Items.Add(edit);
|
|
|
+
|
|
|
+ if (!bLinks && models.Length == 1)
|
|
|
+ {
|
|
|
+ var digitalForms = new MenuItem { Header = "Digital Forms" };
|
|
|
|
|
|
- if (!bLinks && models.Length == 1)
|
|
|
- {
|
|
|
- var digitalForms = new MenuItem { Header = "Digital Forms" };
|
|
|
+ var model = models.First();
|
|
|
|
|
|
- var model = models.First();
|
|
|
+ DynamicGridUtils.PopulateFormMenu<KanbanForm, Kanban, KanbanLink>(
|
|
|
+ digitalForms,
|
|
|
+ model.ID,
|
|
|
+ () => new Client<Kanban>().Load(new Filter<Kanban>(x => x.ID).IsEqualTo(model.ID)).First(),
|
|
|
+ model.EmployeeID == App.EmployeeID);
|
|
|
|
|
|
- DynamicGridUtils.PopulateFormMenu<KanbanForm, Kanban, KanbanLink>(
|
|
|
- digitalForms,
|
|
|
- model.ID,
|
|
|
- () => new Client<Kanban>().Load(new Filter<Kanban>(x => x.ID).IsEqualTo(model.ID)).First(),
|
|
|
- model.EmployeeID == App.EmployeeID);
|
|
|
+ menu.Items.Add(digitalForms);
|
|
|
+ }
|
|
|
|
|
|
- menu.Items.Add(digitalForms);
|
|
|
- }
|
|
|
+ if (!models.Any(x => !x.CompletedDate.IsEmpty()) && !bLinks)
|
|
|
+ {
|
|
|
+ menu.Items.Add(new Separator());
|
|
|
+
|
|
|
+ var job = new MenuItem
|
|
|
+ {
|
|
|
+ Tag = models,
|
|
|
+ Header = "Link to Job"
|
|
|
+ };
|
|
|
+ job.SubmenuOpened += (o, e) => CreateJobSubMenu(control, job, models);
|
|
|
+ menu.Items.Add(job);
|
|
|
|
|
|
- if (!models.Any(x => !x.CompletedDate.IsEmpty()) && !bLinks)
|
|
|
+ if (bSingle)
|
|
|
{
|
|
|
- menu.Items.Add(new Separator());
|
|
|
|
|
|
- var job = new MenuItem
|
|
|
+ menu.AddItem("Create Setout from Task", null, models.First(), task =>
|
|
|
{
|
|
|
- Tag = models,
|
|
|
- Header = "Link to Job"
|
|
|
- };
|
|
|
- job.SubmenuOpened += (o, e) => CreateJobSubMenu(control, job, models);
|
|
|
- menu.Items.Add(job);
|
|
|
+ if (!MessageWindow.ShowYesNo("This will convert this task into a Setout.\n\nDo you wish to continue?", "Confirmation"))
|
|
|
+ return;
|
|
|
|
|
|
- if (bSingle)
|
|
|
- {
|
|
|
+ ManufacturingTemplate? template = new Client<ManufacturingTemplate>()
|
|
|
+ .Load(new Filter<ManufacturingTemplate>(x => x.Code).IsEqualTo("PRS")).FirstOrDefault();
|
|
|
+ if (template == null)
|
|
|
+ {
|
|
|
+ MessageWindow.ShowMessage("[Pressing] Template does not exist!", "No template");
|
|
|
+ return;
|
|
|
+ }
|
|
|
|
|
|
- menu.AddItem("Create Setout from Task", null, models.First(), task =>
|
|
|
+ string? setoutNumber = null;
|
|
|
+ Kanban? kanban = null;
|
|
|
+ ManufacturingTemplateStage[] tstages = Array.Empty<ManufacturingTemplateStage>();
|
|
|
+ Progress.ShowModal("Creating Setout", (progress) =>
|
|
|
{
|
|
|
- if (!MessageWindow.ShowYesNo("This will convert this task into a Setout.\n\nDo you wish to continue?", "Confirmation"))
|
|
|
- return;
|
|
|
+ var kanbanFilter = new Filter<Kanban>(x => x.ID).IsEqualTo(task.ID);
|
|
|
+ var tables = Client.QueryMultiple(new Dictionary<string, IQueryDef>
|
|
|
+ {
|
|
|
+ { "ManufacturingTemplateStage", new QueryDef<ManufacturingTemplateStage>(
|
|
|
+ new Filter<ManufacturingTemplateStage>(x => x.Template.ID).IsEqualTo(template.ID),
|
|
|
+ null,
|
|
|
+ new SortOrder<ManufacturingTemplateStage>(x => x.Sequence)) },
|
|
|
+ { "Kanban", new QueryDef<Kanban>(
|
|
|
+ kanbanFilter,
|
|
|
+ null,
|
|
|
+ null) },
|
|
|
+ { "Setout", new QueryDef<Setout>(
|
|
|
+ new Filter<Setout>(x => x.JobLink.ID)
|
|
|
+ .InQuery(new SubQuery<Kanban>(kanbanFilter, new Column<Kanban>(x => x.JobLink.ID))),
|
|
|
+ Columns.None<Setout>().Add(x => x.JobLink.JobNumber, x => x.Number),
|
|
|
+ null) }
|
|
|
+ });
|
|
|
|
|
|
- ManufacturingTemplate? template = new Client<ManufacturingTemplate>()
|
|
|
- .Load(new Filter<ManufacturingTemplate>(x => x.Code).IsEqualTo("PRS")).FirstOrDefault();
|
|
|
- if (template == null)
|
|
|
+ tstages = tables["ManufacturingTemplateStage"].Rows
|
|
|
+ .Select(x => x.ToObject<ManufacturingTemplateStage>()).ToArray();
|
|
|
+ kanban = tables["Kanban"].Rows.FirstOrDefault()?.ToObject<Kanban>();
|
|
|
+ if (kanban == null)
|
|
|
{
|
|
|
- MessageWindow.ShowMessage("[Pressing] Template does not exist!", "No template");
|
|
|
+ MessageWindow.ShowMessage("Task does not exist!", "No task");
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
- string? setoutNumber = null;
|
|
|
- Kanban? kanban = null;
|
|
|
- ManufacturingTemplateStage[] tstages = Array.Empty<ManufacturingTemplateStage>();
|
|
|
- Progress.ShowModal("Creating Setout", (progress) =>
|
|
|
- {
|
|
|
- var kanbanFilter = new Filter<Kanban>(x => x.ID).IsEqualTo(task.ID);
|
|
|
- var tables = Client.QueryMultiple(new Dictionary<string, IQueryDef>
|
|
|
- {
|
|
|
- { "ManufacturingTemplateStage", new QueryDef<ManufacturingTemplateStage>(
|
|
|
- new Filter<ManufacturingTemplateStage>(x => x.Template.ID).IsEqualTo(template.ID),
|
|
|
- null,
|
|
|
- new SortOrder<ManufacturingTemplateStage>(x => x.Sequence)) },
|
|
|
- { "Kanban", new QueryDef<Kanban>(
|
|
|
- kanbanFilter,
|
|
|
- null,
|
|
|
- null) },
|
|
|
- { "Setout", new QueryDef<Setout>(
|
|
|
- new Filter<Setout>(x => x.JobLink.ID)
|
|
|
- .InQuery(new SubQuery<Kanban>(kanbanFilter, new Column<Kanban>(x => x.JobLink.ID))),
|
|
|
- Columns.None<Setout>().Add(x => x.JobLink.JobNumber, x => x.Number),
|
|
|
- null) }
|
|
|
- });
|
|
|
-
|
|
|
- tstages = tables["ManufacturingTemplateStage"].Rows
|
|
|
- .Select(x => x.ToObject<ManufacturingTemplateStage>()).ToArray();
|
|
|
- kanban = tables["Kanban"].Rows.FirstOrDefault()?.ToObject<Kanban>();
|
|
|
- if (kanban == null)
|
|
|
- {
|
|
|
- MessageWindow.ShowMessage("Task does not exist!", "No task");
|
|
|
- return;
|
|
|
- }
|
|
|
+ progress.Report("Creating Setouts");
|
|
|
+ CoreTable setouts = tables["Setout"];
|
|
|
|
|
|
- progress.Report("Creating Setouts");
|
|
|
- CoreTable setouts = tables["Setout"];
|
|
|
+ int ireq = 0;
|
|
|
+ string sreq = "";
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ ireq++;
|
|
|
+ sreq = string.Format("{0}-{1:yyMMdd}-{2}", kanban.JobLink.JobNumber, DateTime.Now, ireq);
|
|
|
+ if (!setouts.Rows.Any(r => sreq.Equals(r.Get<Setout, String>(c => c.Number))))
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ setoutNumber = sreq;
|
|
|
+ });
|
|
|
+ if (setoutNumber == null || kanban == null)
|
|
|
+ {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ var result = CreateSetout(
|
|
|
+ task,
|
|
|
+ s =>
|
|
|
+ {
|
|
|
+ s.Number = setoutNumber;
|
|
|
+ s.JobLink.ID = task.JobID;
|
|
|
|
|
|
- int ireq = 0;
|
|
|
- string sreq = "";
|
|
|
- while (true)
|
|
|
+ var notes = kanban.Notes.ToList();
|
|
|
+ var description = kanban.Summary;
|
|
|
+ if (string.IsNullOrWhiteSpace(description))
|
|
|
{
|
|
|
- ireq++;
|
|
|
- sreq = string.Format("{0}-{1:yyMMdd}-{2}", kanban.JobLink.JobNumber, DateTime.Now, ireq);
|
|
|
- if (!setouts.Rows.Any(r => sreq.Equals(r.Get<Setout, String>(c => c.Number))))
|
|
|
- break;
|
|
|
+ description = CoreUtils.StripHTML(kanban.Description);
|
|
|
}
|
|
|
- setoutNumber = sreq;
|
|
|
- });
|
|
|
- if (setoutNumber == null || kanban == null)
|
|
|
- {
|
|
|
- return;
|
|
|
- }
|
|
|
- var result = CreateSetout(
|
|
|
- task,
|
|
|
- s =>
|
|
|
+ if (!string.IsNullOrWhiteSpace(description))
|
|
|
{
|
|
|
- s.Number = setoutNumber;
|
|
|
- s.JobLink.ID = task.JobID;
|
|
|
-
|
|
|
- var notes = kanban.Notes.ToList();
|
|
|
- var description = kanban.Summary;
|
|
|
- if (string.IsNullOrWhiteSpace(description))
|
|
|
- {
|
|
|
- description = CoreUtils.StripHTML(kanban.Description);
|
|
|
- }
|
|
|
- if (!string.IsNullOrWhiteSpace(description))
|
|
|
- {
|
|
|
- notes.Insert(0, description);
|
|
|
- }
|
|
|
- s.Description = string.Join("\n==========================================\n", notes);
|
|
|
+ notes.Insert(0, description);
|
|
|
}
|
|
|
- );
|
|
|
- if (result != null)
|
|
|
+ s.Description = string.Join("\n==========================================\n", notes);
|
|
|
+ }
|
|
|
+ );
|
|
|
+ if (result != null)
|
|
|
+ {
|
|
|
+ Progress.ShowModal("Creating Manufacturing Packet", progress =>
|
|
|
{
|
|
|
- Progress.ShowModal("Creating Manufacturing Packet", progress =>
|
|
|
+ ManufacturingPacket packet = new ManufacturingPacket()
|
|
|
{
|
|
|
- ManufacturingPacket packet = new ManufacturingPacket()
|
|
|
+ Serial = template.Code,
|
|
|
+ Title = kanban.Title,
|
|
|
+ Quantity = 1,
|
|
|
+ BarcodeQty = 1,
|
|
|
+ DueDate = kanban.DueDate
|
|
|
+ };
|
|
|
+ packet.ManufacturingTemplateLink.ID = template.ID;
|
|
|
+ packet.ManufacturingTemplateLink.Code = template.Code;
|
|
|
+ packet.ManufacturingTemplateLink.Factory.ID = template.Factory.ID;
|
|
|
+ packet.SetoutLink.ID = result.ID;
|
|
|
+ new Client<ManufacturingPacket>().Save(packet, "Created from Task");
|
|
|
+
|
|
|
+ DoLink<ManufacturingPacketKanban, ManufacturingPacket, ManufacturingPacketLink>(task, packet.ID);
|
|
|
+
|
|
|
+ List<ManufacturingPacketStage> pstages = new List<ManufacturingPacketStage>();
|
|
|
+ foreach (var tstage in tstages)
|
|
|
+ {
|
|
|
+ var pstage = new ManufacturingPacketStage()
|
|
|
{
|
|
|
- Serial = template.Code,
|
|
|
- Title = kanban.Title,
|
|
|
- Quantity = 1,
|
|
|
- BarcodeQty = 1,
|
|
|
- DueDate = kanban.DueDate
|
|
|
+ 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 = "",
|
|
|
};
|
|
|
- packet.ManufacturingTemplateLink.ID = template.ID;
|
|
|
- packet.ManufacturingTemplateLink.Code = template.Code;
|
|
|
- packet.ManufacturingTemplateLink.Factory.ID = template.Factory.ID;
|
|
|
- packet.SetoutLink.ID = result.ID;
|
|
|
- new Client<ManufacturingPacket>().Save(packet, "Created from Task");
|
|
|
-
|
|
|
- DoLink<ManufacturingPacketKanban, ManufacturingPacket, ManufacturingPacketLink>(task, packet.ID);
|
|
|
-
|
|
|
- List<ManufacturingPacketStage> pstages = new List<ManufacturingPacketStage>();
|
|
|
- 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 = "",
|
|
|
- };
|
|
|
- pstage.Parent.ID = packet.ID;
|
|
|
- pstage.ManufacturingSectionLink.ID = tstage.Section.ID;
|
|
|
- pstage.ManufacturingSectionLink.Name = tstage.Section.Name;
|
|
|
- pstages.Add(pstage);
|
|
|
- }
|
|
|
- new Client<ManufacturingPacketStage>().Save(pstages, "Created from Task", (_, __) => { });
|
|
|
-
|
|
|
- progress.Report("Processing Documents");
|
|
|
- List<SetoutDocument> _setoutdocuments = new List<SetoutDocument>();
|
|
|
- List<KanbanDocument> _kanbandocuments = new List<KanbanDocument>();
|
|
|
- KanbanDocument[] docrefs = new Client<KanbanDocument>()
|
|
|
- .Load(new Filter<KanbanDocument>(x => x.EntityLink.ID).IsEqualTo(kanban.ID));
|
|
|
- foreach (var docref in docrefs)
|
|
|
- {
|
|
|
- // Convert the document to a PDF
|
|
|
- var docid = ProcessKanbanDocument(docref);
|
|
|
- var newdoc = new SetoutDocument();
|
|
|
- newdoc.EntityLink.ID = result.ID;
|
|
|
- newdoc.DocumentLink.ID = docid;
|
|
|
- _setoutdocuments.Add(newdoc);
|
|
|
-
|
|
|
- if (docid != docref.DocumentLink.ID)
|
|
|
- {
|
|
|
- docref.DocumentLink.ID = docid;
|
|
|
- _kanbandocuments.Add(docref);
|
|
|
- }
|
|
|
- }
|
|
|
- new Client<SetoutDocument>().Save(_setoutdocuments, "Converted from Task", (_, __) => { });
|
|
|
- new Client<KanbanDocument>().Save(_kanbandocuments, "Converted to PDF", (_, __) => { });
|
|
|
-
|
|
|
- progress.Report("Updating Task");
|
|
|
- kanban.Title = kanban.Title + " (" + result.Number + ")";
|
|
|
- new Client<Kanban>().Save(kanban, "Converting Kanban to Setout");
|
|
|
- });
|
|
|
- control.Refresh();
|
|
|
- }
|
|
|
- });
|
|
|
- menu.AddItem("Create Requisition from Task", null, models, tasks =>
|
|
|
- {
|
|
|
- var taskModel = tasks.First();
|
|
|
-
|
|
|
- var kanbanTable = new Client<Kanban>().Query(new Filter<Kanban>(x => x.ID).IsEqualTo(taskModel.ID));
|
|
|
- var kanban = kanbanTable.Rows.First().ToObject<Kanban>();
|
|
|
-
|
|
|
- var result = CreateRequisition(
|
|
|
- taskModel,
|
|
|
- r =>
|
|
|
- {
|
|
|
- r.RequestedBy.ID = kanban.ManagerLink.ID;
|
|
|
- r.Employee.ID = Guid.Empty;
|
|
|
- r.Title = kanban.Title;
|
|
|
-
|
|
|
- r.Request = string.IsNullOrWhiteSpace(kanban.Summary)
|
|
|
- ? String.IsNullOrWhiteSpace(kanban.Description)
|
|
|
- ? String.Join("\n", kanban.Notes)
|
|
|
- : CoreUtils.StripHTML(kanban.Description)
|
|
|
- : kanban.Summary;
|
|
|
-
|
|
|
- r.Notes = kanban.Notes;
|
|
|
- r.Due = kanban.DueDate;
|
|
|
- r.JobLink.ID = taskModel.JobID;
|
|
|
+ pstage.Parent.ID = packet.ID;
|
|
|
+ pstage.ManufacturingSectionLink.ID = tstage.Section.ID;
|
|
|
+ pstage.ManufacturingSectionLink.Name = tstage.Section.Name;
|
|
|
+ pstages.Add(pstage);
|
|
|
}
|
|
|
- );
|
|
|
- if (result != null)
|
|
|
- {
|
|
|
- Progress.ShowModal("Updating Documents", progress =>
|
|
|
+ new Client<ManufacturingPacketStage>().Save(pstages, "Created from Task", (_, __) => { });
|
|
|
+
|
|
|
+ progress.Report("Processing Documents");
|
|
|
+ List<SetoutDocument> _setoutdocuments = new List<SetoutDocument>();
|
|
|
+ List<KanbanDocument> _kanbandocuments = new List<KanbanDocument>();
|
|
|
+ KanbanDocument[] docrefs = new Client<KanbanDocument>()
|
|
|
+ .Load(new Filter<KanbanDocument>(x => x.EntityLink.ID).IsEqualTo(kanban.ID));
|
|
|
+ foreach (var docref in docrefs)
|
|
|
{
|
|
|
- progress.Report("Updating Documents");
|
|
|
- List<RequisitionDocument> requiDocuments = new();
|
|
|
- KanbanDocument[] kanbanDocuments = new Client<KanbanDocument>()
|
|
|
- .Load(new Filter<KanbanDocument>(x => x.EntityLink.ID).IsEqualTo(kanban.ID));
|
|
|
- foreach (var document in kanbanDocuments)
|
|
|
+ // Convert the document to a PDF
|
|
|
+ var docid = ProcessKanbanDocument(docref);
|
|
|
+ var newdoc = new SetoutDocument();
|
|
|
+ newdoc.EntityLink.ID = result.ID;
|
|
|
+ newdoc.DocumentLink.ID = docid;
|
|
|
+ _setoutdocuments.Add(newdoc);
|
|
|
+
|
|
|
+ if (docid != docref.DocumentLink.ID)
|
|
|
{
|
|
|
- var newdoc = new RequisitionDocument();
|
|
|
- newdoc.EntityLink.ID = result.ID;
|
|
|
- newdoc.DocumentLink.ID = document.DocumentLink.ID;
|
|
|
- requiDocuments.Add(newdoc);
|
|
|
+ docref.DocumentLink.ID = docid;
|
|
|
+ _kanbandocuments.Add(docref);
|
|
|
}
|
|
|
- new Client<RequisitionDocument>().Save(requiDocuments, "Converted from Task", (_, __) => { });
|
|
|
-
|
|
|
- /*RequisitionKanban link = new();
|
|
|
- link.Entity.ID = result.ID;
|
|
|
- link.Kanban.ID = kanban.ID;
|
|
|
- new Client<RequisitionKanban>().Save(link, "Converting Task -> Requisition", (_, __) => { });*/
|
|
|
-
|
|
|
- progress.Report("Updating Task");
|
|
|
- kanban.Status = KanbanStatus.Open;
|
|
|
- kanban.Completed = DateTime.MinValue;
|
|
|
- kanban.Title += $" (Requi #{result.Number})";
|
|
|
- new Client<Kanban>().Save(kanban, "Converted to Requisition", (_, __) => { });
|
|
|
- });
|
|
|
- MessageWindow.ShowMessage($"Created Requisition {result.Number}", "Success");
|
|
|
- control.Refresh();
|
|
|
- }
|
|
|
- });
|
|
|
- menu.AddItem("Create Delivery from Task", null, models, tasks =>
|
|
|
- {
|
|
|
- var result = CreateDelivery(
|
|
|
- tasks.First(),
|
|
|
- d =>
|
|
|
- {
|
|
|
- // Post-Process Requi Here
|
|
|
}
|
|
|
- );
|
|
|
- if (result != null)
|
|
|
- control.Refresh();
|
|
|
- });
|
|
|
- menu.AddItem("Create Purchase Order from Task", null, models, tasks =>
|
|
|
+ new Client<SetoutDocument>().Save(_setoutdocuments, "Converted from Task", (_, __) => { });
|
|
|
+ new Client<KanbanDocument>().Save(_kanbandocuments, "Converted to PDF", (_, __) => { });
|
|
|
+
|
|
|
+ progress.Report("Updating Task");
|
|
|
+ kanban.Title = kanban.Title + " (" + result.Number + ")";
|
|
|
+ new Client<Kanban>().Save(kanban, "Converting Kanban to Setout");
|
|
|
+ });
|
|
|
+ control.Refresh();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ menu.AddItem("Create Requisition from Task", null, models, tasks =>
|
|
|
+ {
|
|
|
+ var taskModel = tasks.First();
|
|
|
+
|
|
|
+ var kanbanTable = new Client<Kanban>().Query(new Filter<Kanban>(x => x.ID).IsEqualTo(taskModel.ID));
|
|
|
+ var kanban = kanbanTable.Rows.First().ToObject<Kanban>();
|
|
|
+
|
|
|
+ var result = CreateRequisition(
|
|
|
+ taskModel,
|
|
|
+ r =>
|
|
|
+ {
|
|
|
+ r.RequestedBy.ID = kanban.ManagerLink.ID;
|
|
|
+ r.Employee.ID = Guid.Empty;
|
|
|
+ r.Title = kanban.Title;
|
|
|
+
|
|
|
+ r.Request = string.IsNullOrWhiteSpace(kanban.Summary)
|
|
|
+ ? String.IsNullOrWhiteSpace(kanban.Description)
|
|
|
+ ? String.Join("\n", kanban.Notes)
|
|
|
+ : CoreUtils.StripHTML(kanban.Description)
|
|
|
+ : kanban.Summary;
|
|
|
+
|
|
|
+ r.Notes = kanban.Notes;
|
|
|
+ r.Due = kanban.DueDate;
|
|
|
+ r.JobLink.ID = taskModel.JobID;
|
|
|
+ }
|
|
|
+ );
|
|
|
+ if (result != null)
|
|
|
{
|
|
|
- var result = CreateOrder(
|
|
|
- tasks.First(),
|
|
|
- p =>
|
|
|
+ Progress.ShowModal("Updating Documents", progress =>
|
|
|
+ {
|
|
|
+ progress.Report("Updating Documents");
|
|
|
+ List<RequisitionDocument> requiDocuments = new();
|
|
|
+ KanbanDocument[] kanbanDocuments = new Client<KanbanDocument>()
|
|
|
+ .Load(new Filter<KanbanDocument>(x => x.EntityLink.ID).IsEqualTo(kanban.ID));
|
|
|
+ foreach (var document in kanbanDocuments)
|
|
|
{
|
|
|
- // Post-Process Requi Here
|
|
|
+ var newdoc = new RequisitionDocument();
|
|
|
+ newdoc.EntityLink.ID = result.ID;
|
|
|
+ newdoc.DocumentLink.ID = document.DocumentLink.ID;
|
|
|
+ requiDocuments.Add(newdoc);
|
|
|
}
|
|
|
- );
|
|
|
- if (result != null)
|
|
|
- control.Refresh();
|
|
|
- });
|
|
|
- }
|
|
|
+ new Client<RequisitionDocument>().Save(requiDocuments, "Converted from Task", (_, __) => { });
|
|
|
+
|
|
|
+ /*RequisitionKanban link = new();
|
|
|
+ link.Entity.ID = result.ID;
|
|
|
+ link.Kanban.ID = kanban.ID;
|
|
|
+ new Client<RequisitionKanban>().Save(link, "Converting Task -> Requisition", (_, __) => { });*/
|
|
|
+
|
|
|
+ progress.Report("Updating Task");
|
|
|
+ kanban.Status = KanbanStatus.Open;
|
|
|
+ kanban.Completed = DateTime.MinValue;
|
|
|
+ kanban.Title += $" (Requi #{result.Number})";
|
|
|
+ new Client<Kanban>().Save(kanban, "Converted to Requisition", (_, __) => { });
|
|
|
+ });
|
|
|
+ MessageWindow.ShowMessage($"Created Requisition {result.Number}", "Success");
|
|
|
+ control.Refresh();
|
|
|
+ }
|
|
|
+ });
|
|
|
+ menu.AddItem("Create Delivery from Task", null, models, tasks =>
|
|
|
+ {
|
|
|
+ var result = CreateDelivery(
|
|
|
+ tasks.First(),
|
|
|
+ d =>
|
|
|
+ {
|
|
|
+ // Post-Process Requi Here
|
|
|
+ }
|
|
|
+ );
|
|
|
+ if (result != null)
|
|
|
+ control.Refresh();
|
|
|
+ });
|
|
|
+ menu.AddItem("Create Purchase Order from Task", null, models, tasks =>
|
|
|
+ {
|
|
|
+ var result = CreateOrder(
|
|
|
+ tasks.First(),
|
|
|
+ p =>
|
|
|
+ {
|
|
|
+ // Post-Process Requi Here
|
|
|
+ }
|
|
|
+ );
|
|
|
+ if (result != null)
|
|
|
+ control.Refresh();
|
|
|
+ });
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- if (!bLinks && canChange)
|
|
|
- {
|
|
|
- menu.Items.Add(new Separator());
|
|
|
+ if (!bLinks && canChange)
|
|
|
+ {
|
|
|
+ menu.Items.Add(new Separator());
|
|
|
|
|
|
- var changeStatus = new MenuItem { Header = "Change Status" };
|
|
|
+ var changeStatus = new MenuItem { Header = "Change Status" };
|
|
|
|
|
|
- AddChangeStatusButton(control, models, changeStatus, "Open", KanbanStatus.Open);
|
|
|
- AddChangeStatusButton(control, models, changeStatus, "In Progress", KanbanStatus.InProgress);
|
|
|
- AddChangeStatusButton(control, models, changeStatus, "Waiting", KanbanStatus.Waiting);
|
|
|
+ AddChangeStatusButton(control, models, changeStatus, "Open", KanbanStatus.Open);
|
|
|
+ AddChangeStatusButton(control, models, changeStatus, "In Progress", KanbanStatus.InProgress);
|
|
|
+ AddChangeStatusButton(control, models, changeStatus, "Waiting", KanbanStatus.Waiting);
|
|
|
|
|
|
- if (models.Any(x => x.CompletedDate.IsEmpty()))
|
|
|
+ if (models.Any(x => x.CompletedDate.IsEmpty()))
|
|
|
+ {
|
|
|
+ var complete = new MenuItem
|
|
|
+ {
|
|
|
+ Tag = models,
|
|
|
+ Header = models.Length > 1 ? "Complete Tasks" : "Complete Task"
|
|
|
+ };
|
|
|
+ complete.Click += (o, e) =>
|
|
|
{
|
|
|
- var complete = new MenuItem
|
|
|
+ CompleteTask(control, e, DateTime.Now);
|
|
|
+ };
|
|
|
+ menu.Items.Add(complete);
|
|
|
+
|
|
|
+ if (Security.IsAllowed<CanSetKanbanCompletedDate>())
|
|
|
+ {
|
|
|
+ var completeDate = new MenuItem
|
|
|
{
|
|
|
Tag = models,
|
|
|
- Header = models.Length > 1 ? "Complete Tasks" : "Complete Task"
|
|
|
- };
|
|
|
- complete.Click += (o, e) =>
|
|
|
- {
|
|
|
- CompleteTask(control, e, DateTime.Now);
|
|
|
+ Header = "Set Completed Date"
|
|
|
};
|
|
|
- menu.Items.Add(complete);
|
|
|
|
|
|
- if (Security.IsAllowed<CanSetKanbanCompletedDate>())
|
|
|
- {
|
|
|
- var completeDate = new MenuItem
|
|
|
- {
|
|
|
- Tag = models,
|
|
|
- Header = "Set Completed Date"
|
|
|
- };
|
|
|
-
|
|
|
- var dateItem = new MenuItem();
|
|
|
+ var dateItem = new MenuItem();
|
|
|
|
|
|
- var dateCalendar = new System.Windows.Controls.Calendar { SelectedDate = DateTime.MinValue };
|
|
|
- dateCalendar.Tag = models;
|
|
|
- dateCalendar.SelectedDatesChanged += (o, e) =>
|
|
|
- {
|
|
|
- if (e.Source is not System.Windows.Controls.Calendar calendar) return;
|
|
|
- menu.IsOpen = false;
|
|
|
+ var dateCalendar = new System.Windows.Controls.Calendar { SelectedDate = DateTime.MinValue };
|
|
|
+ dateCalendar.Tag = models;
|
|
|
+ dateCalendar.SelectedDatesChanged += (o, e) =>
|
|
|
+ {
|
|
|
+ if (e.Source is not System.Windows.Controls.Calendar calendar) return;
|
|
|
+ menu.IsOpen = false;
|
|
|
|
|
|
- var selectedDate = calendar.SelectedDate ?? DateTime.Now;
|
|
|
- CompleteTask(control, e, selectedDate);
|
|
|
- };
|
|
|
+ var selectedDate = calendar.SelectedDate ?? DateTime.Now;
|
|
|
+ CompleteTask(control, e, selectedDate);
|
|
|
+ };
|
|
|
|
|
|
- dateItem.Header = dateCalendar;
|
|
|
- dateItem.Style = Resources["calendarItem"] as Style;
|
|
|
+ dateItem.Header = dateCalendar;
|
|
|
+ dateItem.Style = Resources["calendarItem"] as Style;
|
|
|
|
|
|
- completeDate.Items.Add(dateItem);
|
|
|
+ completeDate.Items.Add(dateItem);
|
|
|
|
|
|
- menu.Items.Add(completeDate);
|
|
|
- }
|
|
|
+ menu.Items.Add(completeDate);
|
|
|
}
|
|
|
- else
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ menu.AddItem(models.Length > 1 ? "Archive Tasks" : "Archive Task", null, models, tasks =>
|
|
|
{
|
|
|
- menu.AddItem(models.Length > 1 ? "Archive Tasks" : "Archive Task", null, models, tasks =>
|
|
|
- {
|
|
|
- if (!MessageWindow.ShowYesNo("Are you sure you want to remove the selected tasks from the list?", "Confirm removal"))
|
|
|
- return;
|
|
|
+ if (!MessageWindow.ShowYesNo("Are you sure you want to remove the selected tasks from the list?", "Confirm removal"))
|
|
|
+ return;
|
|
|
|
|
|
- Progress.ShowModal("Closing Kanbans", progress =>
|
|
|
- {
|
|
|
- var kanbans = LoadKanbans(tasks, Columns.Required<Kanban>().Add(x => x.ID, x => x.Closed));
|
|
|
- foreach (var kanban in kanbans)
|
|
|
- kanban.Closed = DateTime.Now;
|
|
|
- new Client<Kanban>().Save(kanbans, "Kanban Marked as Closed");
|
|
|
- });
|
|
|
- control.Refresh();
|
|
|
+ Progress.ShowModal("Closing Kanbans", progress =>
|
|
|
+ {
|
|
|
+ var kanbans = LoadKanbans(tasks, Columns.Required<Kanban>().Add(x => x.ID, x => x.Closed));
|
|
|
+ foreach (var kanban in kanbans)
|
|
|
+ kanban.Closed = DateTime.Now;
|
|
|
+ new Client<Kanban>().Save(kanbans, "Kanban Marked as Closed");
|
|
|
});
|
|
|
- }
|
|
|
+ control.Refresh();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- menu.Items.Add(changeStatus);
|
|
|
+ menu.Items.Add(changeStatus);
|
|
|
|
|
|
- var changeType = new MenuItem { Header = "Change Task Type", Tag = models };
|
|
|
+ var changeType = new MenuItem { Header = "Change Task Type", Tag = models };
|
|
|
|
|
|
- foreach(var type in KanbanTypes)
|
|
|
+ foreach(var type in KanbanTypes)
|
|
|
+ {
|
|
|
+ changeType.AddItem($"{type.Code}: {type.Description}", null, type, type =>
|
|
|
{
|
|
|
- changeType.AddItem($"{type.Code}: {type.Description}", null, type, type =>
|
|
|
+ Progress.ShowModal("Changing Task Type", progress =>
|
|
|
{
|
|
|
- Progress.ShowModal("Changing Task Type", progress =>
|
|
|
+ var kanbans = LoadKanbans(models, Columns.Required<Kanban>().Add(x => x.ID, x => x.Type.ID));
|
|
|
+ foreach (var kanban in kanbans)
|
|
|
{
|
|
|
- var kanbans = LoadKanbans(models, Columns.Required<Kanban>().Add(x => x.ID, x => x.Type.ID));
|
|
|
- foreach (var kanban in kanbans)
|
|
|
- {
|
|
|
- kanban.Type.ID = type.ID;
|
|
|
- }
|
|
|
+ kanban.Type.ID = type.ID;
|
|
|
+ }
|
|
|
|
|
|
- new Client<Kanban>().Save(kanbans, $"Kanban Task Type changed to {type}");
|
|
|
- });
|
|
|
- control.Refresh();
|
|
|
+ new Client<Kanban>().Save(kanbans, $"Kanban Task Type changed to {type}");
|
|
|
});
|
|
|
- }
|
|
|
+ control.Refresh();
|
|
|
+ });
|
|
|
+ }
|
|
|
|
|
|
- menu.Items.Add(changeType);
|
|
|
+ menu.Items.Add(changeType);
|
|
|
|
|
|
|
|
|
- var changeDueDate = new MenuItem { Header = "Change Due Date" };
|
|
|
+ var changeDueDate = new MenuItem { Header = "Change Due Date" };
|
|
|
|
|
|
- var calendarItem = new MenuItem();
|
|
|
+ var calendarItem = new MenuItem();
|
|
|
|
|
|
- var calendar = new System.Windows.Controls.Calendar { SelectedDate = models.Length == 1 ? models[0].DueDate : DateTime.Today };
|
|
|
- calendar.Tag = models;
|
|
|
- calendar.SelectedDatesChanged += (o, e) =>
|
|
|
- {
|
|
|
- if (e.Source is not System.Windows.Controls.Calendar calendar) return;
|
|
|
+ var calendar = new System.Windows.Controls.Calendar { SelectedDate = models.Length == 1 ? models[0].DueDate : DateTime.Today };
|
|
|
+ calendar.Tag = models;
|
|
|
+ calendar.SelectedDatesChanged += (o, e) =>
|
|
|
+ {
|
|
|
+ if (e.Source is not System.Windows.Controls.Calendar calendar) return;
|
|
|
|
|
|
- var selectedDate = calendar.SelectedDate ?? DateTime.Now;
|
|
|
- var models = (calendar.Tag as IList<TaskModel>)!;
|
|
|
- Progress.ShowModal("Changing Due Date", progress =>
|
|
|
+ var selectedDate = calendar.SelectedDate ?? DateTime.Now;
|
|
|
+ var models = (calendar.Tag as IList<TaskModel>)!;
|
|
|
+ Progress.ShowModal("Changing Due Date", progress =>
|
|
|
+ {
|
|
|
+ var kanbans = LoadKanbans(models, Columns.Required<Kanban>().Add(x => x.ID, x => x.DueDate));
|
|
|
+ foreach (var kanban in kanbans)
|
|
|
{
|
|
|
- var kanbans = LoadKanbans(models, Columns.Required<Kanban>().Add(x => x.ID, x => x.DueDate));
|
|
|
- foreach (var kanban in kanbans)
|
|
|
- {
|
|
|
- kanban.DueDate = selectedDate;
|
|
|
- }
|
|
|
+ kanban.DueDate = selectedDate;
|
|
|
+ }
|
|
|
|
|
|
- new Client<Kanban>().Save(kanbans, $"Kanban Due Date changed to {selectedDate:dd MMM yyyy}");
|
|
|
- });
|
|
|
- control.Refresh();
|
|
|
+ new Client<Kanban>().Save(kanbans, $"Kanban Due Date changed to {selectedDate:dd MMM yyyy}");
|
|
|
+ });
|
|
|
+ control.Refresh();
|
|
|
|
|
|
- menu.IsOpen = false;
|
|
|
- };
|
|
|
+ menu.IsOpen = false;
|
|
|
+ };
|
|
|
|
|
|
- calendarItem.Header = calendar;
|
|
|
- calendarItem.Style = Resources["calendarItem"] as Style;
|
|
|
+ calendarItem.Header = calendar;
|
|
|
+ calendarItem.Style = Resources["calendarItem"] as Style;
|
|
|
|
|
|
- changeDueDate.Items.Add(calendarItem);
|
|
|
+ changeDueDate.Items.Add(calendarItem);
|
|
|
|
|
|
- menu.Items.Add(changeDueDate);
|
|
|
- }
|
|
|
+ menu.Items.Add(changeDueDate);
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Takes a <see cref="KanbanDocument"/>, and if it is a .txt or an image (".png", ".jpg", ".jpeg" or ".bmp"), converts to a PDF
|
|
|
- /// with the content of the document, saving a new document with extension changed to ".pdf".
|
|
|
- /// </summary>
|
|
|
- /// <param name="docref">The original document.</param>
|
|
|
- /// <returns>
|
|
|
- /// The ID of the new <see cref="Document"/> or,
|
|
|
- /// if not one of the given types, the original document ID.
|
|
|
- /// </returns>
|
|
|
- private static Guid ProcessKanbanDocument(KanbanDocument docref)
|
|
|
- {
|
|
|
- var result = docref.DocumentLink.ID;
|
|
|
+ /// <summary>
|
|
|
+ /// Takes a <see cref="KanbanDocument"/>, and if it is a .txt or an image (".png", ".jpg", ".jpeg" or ".bmp"), converts to a PDF
|
|
|
+ /// with the content of the document, saving a new document with extension changed to ".pdf".
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="docref">The original document.</param>
|
|
|
+ /// <returns>
|
|
|
+ /// The ID of the new <see cref="Document"/> or,
|
|
|
+ /// if not one of the given types, the original document ID.
|
|
|
+ /// </returns>
|
|
|
+ private static Guid ProcessKanbanDocument(KanbanDocument docref)
|
|
|
+ {
|
|
|
+ var result = docref.DocumentLink.ID;
|
|
|
|
|
|
- var ext = System.IO.Path.GetExtension(docref.DocumentLink.FileName).ToLower();
|
|
|
+ var ext = System.IO.Path.GetExtension(docref.DocumentLink.FileName).ToLower();
|
|
|
|
|
|
- if (ext.EndsWith("txt"))
|
|
|
+ if (ext.EndsWith("txt"))
|
|
|
+ {
|
|
|
+ var doc = new Client<Document>().Load(new Filter<Document>(x => x.ID).IsEqualTo(docref.DocumentLink.ID)).FirstOrDefault();
|
|
|
+ if (doc is null)
|
|
|
{
|
|
|
- var doc = new Client<Document>().Load(new Filter<Document>(x => x.ID).IsEqualTo(docref.DocumentLink.ID)).FirstOrDefault();
|
|
|
- if (doc is null)
|
|
|
- {
|
|
|
- Logger.Send(LogType.Error, "", $"Document {docref.DocumentLink.ID} does not exist!");
|
|
|
- return docref.DocumentLink.ID;
|
|
|
- }
|
|
|
-
|
|
|
- PdfDocument pdf = new PdfDocument();
|
|
|
- PdfPage page = pdf.Pages.Add();
|
|
|
- PdfGraphics graphics = page.Graphics;
|
|
|
- PdfFont font = new PdfStandardFont(PdfFontFamily.Courier, 12);
|
|
|
- String text = System.Text.Encoding.UTF8.GetString(doc.Data);
|
|
|
- graphics.DrawString(text, font, PdfBrushes.Black, new PointF(0, 0));
|
|
|
- MemoryStream ms = new MemoryStream();
|
|
|
- pdf.Save(ms);
|
|
|
- pdf.Close(true);
|
|
|
- byte[] data = ms.ToArray();
|
|
|
- var newdoc = new Document()
|
|
|
- {
|
|
|
- Data = data,
|
|
|
- FileName = System.IO.Path.ChangeExtension(docref.DocumentLink.FileName, "pdf"),
|
|
|
- CRC = CoreUtils.CalculateCRC(data),
|
|
|
- TimeStamp = DateTime.Now,
|
|
|
- };
|
|
|
- new Client<Document>().Save(newdoc, "Converted from Text");
|
|
|
- return newdoc.ID;
|
|
|
+ Logger.Send(LogType.Error, "", $"Document {docref.DocumentLink.ID} does not exist!");
|
|
|
+ return docref.DocumentLink.ID;
|
|
|
}
|
|
|
|
|
|
- else if (ext.EndsWith("png") || ext.EndsWith("bmp") || ext.EndsWith("jpg") || ext.EndsWith("jpeg"))
|
|
|
+ PdfDocument pdf = new PdfDocument();
|
|
|
+ PdfPage page = pdf.Pages.Add();
|
|
|
+ PdfGraphics graphics = page.Graphics;
|
|
|
+ PdfFont font = new PdfStandardFont(PdfFontFamily.Courier, 12);
|
|
|
+ String text = System.Text.Encoding.UTF8.GetString(doc.Data);
|
|
|
+ graphics.DrawString(text, font, PdfBrushes.Black, new PointF(0, 0));
|
|
|
+ MemoryStream ms = new MemoryStream();
|
|
|
+ pdf.Save(ms);
|
|
|
+ pdf.Close(true);
|
|
|
+ byte[] data = ms.ToArray();
|
|
|
+ var newdoc = new Document()
|
|
|
{
|
|
|
- var doc = new Client<Document>().Load(new Filter<Document>(x => x.ID).IsEqualTo(docref.DocumentLink.ID)).FirstOrDefault();
|
|
|
- if (doc is null)
|
|
|
- {
|
|
|
- Logger.Send(LogType.Error, "", $"Document {docref.DocumentLink.ID} does not exist!");
|
|
|
- return docref.DocumentLink.ID;
|
|
|
- }
|
|
|
+ Data = data,
|
|
|
+ FileName = System.IO.Path.ChangeExtension(docref.DocumentLink.FileName, "pdf"),
|
|
|
+ CRC = CoreUtils.CalculateCRC(data),
|
|
|
+ TimeStamp = DateTime.Now,
|
|
|
+ };
|
|
|
+ new Client<Document>().Save(newdoc, "Converted from Text");
|
|
|
+ return newdoc.ID;
|
|
|
+ }
|
|
|
|
|
|
- PdfBitmap image = new PdfBitmap(new MemoryStream(doc.Data));
|
|
|
- PdfDocument pdf = new PdfDocument();
|
|
|
- pdf.PageSettings.Orientation = image.Height > image.Width ? PdfPageOrientation.Portrait : PdfPageOrientation.Landscape;
|
|
|
- pdf.PageSettings.Size = new SizeF(image.Width, image.Height);
|
|
|
- PdfPage page = pdf.Pages.Add();
|
|
|
- PdfGraphics graphics = page.Graphics;
|
|
|
- graphics.DrawImage(image, 0.0F, 0.0F);
|
|
|
- MemoryStream ms = new MemoryStream();
|
|
|
- pdf.Save(ms);
|
|
|
- pdf.Close(true);
|
|
|
- byte[] data = ms.ToArray();
|
|
|
- var newdoc = new Document()
|
|
|
- {
|
|
|
- Data = data,
|
|
|
- FileName = System.IO.Path.ChangeExtension(docref.DocumentLink.FileName, "pdf"),
|
|
|
- CRC = CoreUtils.CalculateCRC(data),
|
|
|
- TimeStamp = DateTime.Now,
|
|
|
- };
|
|
|
- new Client<Document>().Save(newdoc, "Converted from Image");
|
|
|
- return newdoc.ID;
|
|
|
+ else if (ext.EndsWith("png") || ext.EndsWith("bmp") || ext.EndsWith("jpg") || ext.EndsWith("jpeg"))
|
|
|
+ {
|
|
|
+ var doc = new Client<Document>().Load(new Filter<Document>(x => x.ID).IsEqualTo(docref.DocumentLink.ID)).FirstOrDefault();
|
|
|
+ if (doc is null)
|
|
|
+ {
|
|
|
+ Logger.Send(LogType.Error, "", $"Document {docref.DocumentLink.ID} does not exist!");
|
|
|
+ return docref.DocumentLink.ID;
|
|
|
}
|
|
|
|
|
|
- return result;
|
|
|
+ PdfBitmap image = new PdfBitmap(new MemoryStream(doc.Data));
|
|
|
+ PdfDocument pdf = new PdfDocument();
|
|
|
+ pdf.PageSettings.Orientation = image.Height > image.Width ? PdfPageOrientation.Portrait : PdfPageOrientation.Landscape;
|
|
|
+ pdf.PageSettings.Size = new SizeF(image.Width, image.Height);
|
|
|
+ PdfPage page = pdf.Pages.Add();
|
|
|
+ PdfGraphics graphics = page.Graphics;
|
|
|
+ graphics.DrawImage(image, 0.0F, 0.0F);
|
|
|
+ MemoryStream ms = new MemoryStream();
|
|
|
+ pdf.Save(ms);
|
|
|
+ pdf.Close(true);
|
|
|
+ byte[] data = ms.ToArray();
|
|
|
+ var newdoc = new Document()
|
|
|
+ {
|
|
|
+ Data = data,
|
|
|
+ FileName = System.IO.Path.ChangeExtension(docref.DocumentLink.FileName, "pdf"),
|
|
|
+ CRC = CoreUtils.CalculateCRC(data),
|
|
|
+ TimeStamp = DateTime.Now,
|
|
|
+ };
|
|
|
+ new Client<Document>().Save(newdoc, "Converted from Image");
|
|
|
+ return newdoc.ID;
|
|
|
}
|
|
|
- private void CreateJobSubMenu(ITaskControl control, MenuItem job, IEnumerable<TaskModel> tasks)
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+ private void CreateJobSubMenu(ITaskControl control, MenuItem job, IEnumerable<TaskModel> tasks)
|
|
|
+ {
|
|
|
+ job.Items.Clear();
|
|
|
+ job.Items.Add(new MenuItem { Header = "Loading...", IsEnabled = false });
|
|
|
+ using (new WaitCursor())
|
|
|
{
|
|
|
job.Items.Clear();
|
|
|
- job.Items.Add(new MenuItem { Header = "Loading...", IsEnabled = false });
|
|
|
- using (new WaitCursor())
|
|
|
+ var jobs = new Client<Job>().Query(
|
|
|
+ LookupFactory.DefineFilter<Job>(),
|
|
|
+ LookupFactory.DefineColumns<Job>(),
|
|
|
+ LookupFactory.DefineSort<Job>()
|
|
|
+ );
|
|
|
+ foreach (var row in jobs.Rows)
|
|
|
{
|
|
|
- job.Items.Clear();
|
|
|
- var jobs = new Client<Job>().Query(
|
|
|
- LookupFactory.DefineFilter<Job>(),
|
|
|
- LookupFactory.DefineColumns<Job>(),
|
|
|
- LookupFactory.DefineSort<Job>()
|
|
|
- );
|
|
|
- foreach (var row in jobs.Rows)
|
|
|
+ var jobNumber = row.Get<Job, string>(x => x.JobNumber);
|
|
|
+ var jobName = row.Get<Job, string>(x => x.Name);
|
|
|
+ job.AddItem($"{jobNumber}: {jobName}", null, tasks, tasks =>
|
|
|
{
|
|
|
- var jobNumber = row.Get<Job, string>(x => x.JobNumber);
|
|
|
- var jobName = row.Get<Job, string>(x => x.Name);
|
|
|
- job.AddItem($"{jobNumber}: {jobName}", null, tasks, tasks =>
|
|
|
+ using (new WaitCursor())
|
|
|
{
|
|
|
- using (new WaitCursor())
|
|
|
- {
|
|
|
- var kanbans = LoadKanbans(tasks, Columns.Required<Kanban>().Add(x => x.ID, x => x.JobLink.ID));
|
|
|
- foreach (var kanban in kanbans)
|
|
|
- kanban.JobLink.ID = row.Get<Job, Guid>(x => x.ID);
|
|
|
- new Client<Kanban>().Save(kanbans, "Updated Job Number");
|
|
|
- control.Refresh();
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
+ var kanbans = LoadKanbans(tasks, Columns.Required<Kanban>().Add(x => x.ID, x => x.JobLink.ID));
|
|
|
+ foreach (var kanban in kanbans)
|
|
|
+ kanban.JobLink.ID = row.Get<Job, Guid>(x => x.ID);
|
|
|
+ new Client<Kanban>().Save(kanbans, "Updated Job Number");
|
|
|
+ control.Refresh();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
+ #endregion
|
|
|
|
|
|
- private void TaskPanels_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
- {
|
|
|
- if (!IsReady)
|
|
|
- return;
|
|
|
+ private void TaskPanels_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
|
|
+ {
|
|
|
+ if (!IsReady)
|
|
|
+ return;
|
|
|
|
|
|
- if (e.Source is not TabControl)
|
|
|
- return;
|
|
|
+ if (e.Source is not TabControl)
|
|
|
+ return;
|
|
|
|
|
|
- if (_bTabChanging)
|
|
|
- return;
|
|
|
- try
|
|
|
- {
|
|
|
- _bTabChanging = true;
|
|
|
- var panel = GetCurrentPanel();
|
|
|
- if(panel is not null)
|
|
|
- {
|
|
|
- KanbanSettings.ViewType = panel.KanbanViewType;
|
|
|
- new UserConfiguration<KanbanSettings>().Save(KanbanSettings);
|
|
|
- panel.Refresh();
|
|
|
- }
|
|
|
- }
|
|
|
- finally
|
|
|
+ if (_bTabChanging)
|
|
|
+ return;
|
|
|
+ try
|
|
|
+ {
|
|
|
+ _bTabChanging = true;
|
|
|
+ var panel = GetCurrentPanel();
|
|
|
+ if(panel is not null)
|
|
|
{
|
|
|
- _bTabChanging = false;
|
|
|
+ KanbanSettings.ViewType = panel.KanbanViewType;
|
|
|
+ new UserConfiguration<KanbanSettings>().Save(KanbanSettings);
|
|
|
+ panel.Refresh();
|
|
|
}
|
|
|
}
|
|
|
+ finally
|
|
|
+ {
|
|
|
+ _bTabChanging = false;
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- #region Get/Save Settings
|
|
|
+ #region Get/Save Settings
|
|
|
|
|
|
- private KanbanSettings? _settings;
|
|
|
+ private KanbanSettings? _settings;
|
|
|
|
|
|
- public KanbanSettings KanbanSettings
|
|
|
+ public KanbanSettings KanbanSettings
|
|
|
+ {
|
|
|
+ get
|
|
|
{
|
|
|
- get
|
|
|
- {
|
|
|
- _settings ??= new UserConfiguration<KanbanSettings>().Load();
|
|
|
- return _settings;
|
|
|
- }
|
|
|
+ _settings ??= new UserConfiguration<KanbanSettings>().Load();
|
|
|
+ return _settings;
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public void SaveSettings()
|
|
|
- {
|
|
|
- if(_settings != null)
|
|
|
- new UserConfiguration<KanbanSettings>().Save(_settings);
|
|
|
- }
|
|
|
+ public void SaveSettings()
|
|
|
+ {
|
|
|
+ if(_settings != null)
|
|
|
+ new UserConfiguration<KanbanSettings>().Save(_settings);
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
+ #endregion
|
|
|
|
|
|
- #region IPanel Stuff
|
|
|
+ #region IPanel Stuff
|
|
|
|
|
|
- public event DataModelUpdateEvent? OnUpdateDataModel;
|
|
|
+ public event DataModelUpdateEvent? OnUpdateDataModel;
|
|
|
|
|
|
- public bool IsReady { get; set; }
|
|
|
+ public bool IsReady { get; set; }
|
|
|
|
|
|
- public void CreateToolbarButtons(IPanelHost host)
|
|
|
+ public void CreateToolbarButtons(IPanelHost host)
|
|
|
+ {
|
|
|
+ host.CreatePanelAction(
|
|
|
+ new PanelAction
|
|
|
+ {
|
|
|
+ Caption = "New Task",
|
|
|
+ OnExecute = a => {
|
|
|
+ if(CreateKanban(k => { }) != null)
|
|
|
+ {
|
|
|
+ Refresh();
|
|
|
+ }
|
|
|
+ },
|
|
|
+ Image = InABox.Wpf.Resources.add
|
|
|
+ }
|
|
|
+ );
|
|
|
+ if (Security.CanView<KanbanType>())
|
|
|
{
|
|
|
- host.CreatePanelAction(
|
|
|
+ host.CreateSetupAction(
|
|
|
new PanelAction
|
|
|
{
|
|
|
- Caption = "New Task",
|
|
|
- OnExecute = a => {
|
|
|
- if(CreateKanban(k => { }) != null)
|
|
|
- {
|
|
|
- Refresh();
|
|
|
- }
|
|
|
- },
|
|
|
- Image = InABox.Wpf.Resources.add
|
|
|
- }
|
|
|
- );
|
|
|
- if (Security.CanView<KanbanType>())
|
|
|
- {
|
|
|
- host.CreateSetupAction(
|
|
|
- new PanelAction
|
|
|
+ Caption = "Task Types",
|
|
|
+ Image = PRSDesktop.Resources.kanbantype,
|
|
|
+ OnExecute = a =>
|
|
|
{
|
|
|
- Caption = "Task Types",
|
|
|
- Image = PRSDesktop.Resources.kanbantype,
|
|
|
- OnExecute = a =>
|
|
|
- {
|
|
|
- var list = new MasterList(typeof(KanbanType));
|
|
|
- list.ShowDialog();
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
+ var list = new MasterList(typeof(KanbanType));
|
|
|
+ list.ShowDialog();
|
|
|
+ }
|
|
|
+ });
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public Dictionary<string, object[]> Selected()
|
|
|
- {
|
|
|
- return new Dictionary<string, object[]>();
|
|
|
- }
|
|
|
+ public Dictionary<string, object[]> Selected()
|
|
|
+ {
|
|
|
+ return new Dictionary<string, object[]>();
|
|
|
+ }
|
|
|
|
|
|
- public void Heartbeat(TimeSpan time)
|
|
|
- {
|
|
|
- }
|
|
|
+ public void Heartbeat(TimeSpan time)
|
|
|
+ {
|
|
|
+ }
|
|
|
|
|
|
- private readonly Dictionary<KanbanViewType, TabItem> _viewmap = new();
|
|
|
+ private readonly Dictionary<KanbanViewType, TabItem> _viewmap = new();
|
|
|
|
|
|
- private readonly List<ITaskControl> _initialized = new();
|
|
|
+ private readonly List<ITaskControl> _initialized = new();
|
|
|
|
|
|
- private ITaskControl GetCurrentPanel()
|
|
|
+ private ITaskControl GetCurrentPanel()
|
|
|
+ {
|
|
|
+ var result = (TaskPanels.SelectedContent as ITaskControl)!;
|
|
|
+ if (result == null)
|
|
|
+ result = (TaskPanels.Items[0] as DynamicTabItem)?.Content as ITaskControl;
|
|
|
+ try
|
|
|
{
|
|
|
- var result = (TaskPanels.SelectedContent as ITaskControl)!;
|
|
|
- if (result == null)
|
|
|
- result = (TaskPanels.Items[0] as DynamicTabItem)?.Content as ITaskControl;
|
|
|
- try
|
|
|
- {
|
|
|
- //if (result != null)
|
|
|
- if (!_initialized.Contains(result))
|
|
|
- {
|
|
|
- result.Setup();
|
|
|
- result.IsReady = true;
|
|
|
- _initialized.Add(result);
|
|
|
- }
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
+ //if (result != null)
|
|
|
+ if (!_initialized.Contains(result))
|
|
|
{
|
|
|
- Logger.Send(LogType.Error, "", $"Error in TaskPanel.GetCurrentPanel: {CoreUtils.FormatException(e)}");
|
|
|
+ result.Setup();
|
|
|
+ result.IsReady = true;
|
|
|
+ _initialized.Add(result);
|
|
|
}
|
|
|
-
|
|
|
- return result;
|
|
|
}
|
|
|
-
|
|
|
- public void Setup()
|
|
|
+ catch (Exception e)
|
|
|
{
|
|
|
- _settings = new UserConfiguration<KanbanSettings>().Load();
|
|
|
-
|
|
|
+ Logger.Send(LogType.Error, "", $"Error in TaskPanel.GetCurrentPanel: {CoreUtils.FormatException(e)}");
|
|
|
+ }
|
|
|
|
|
|
- TaskPanels.SelectedItem = _viewmap[_settings.ViewType];
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- kanbanTypes = new Client<KanbanType>()
|
|
|
- .Query(
|
|
|
- new Filter<KanbanType>(x => x.Hidden).IsEqualTo(false),
|
|
|
- Columns.None<KanbanType>().Add(x => x.ID, x => x.Code, x => x.Description))
|
|
|
- .Rows.Select(x => x.ToObject<KanbanType>()).ToArray();
|
|
|
- }
|
|
|
+ public void Setup()
|
|
|
+ {
|
|
|
+ _settings = new UserConfiguration<KanbanSettings>().Load();
|
|
|
|
|
|
- public void Shutdown(CancelEventArgs? cancel)
|
|
|
- {
|
|
|
- }
|
|
|
|
|
|
- public void Refresh()
|
|
|
- {
|
|
|
- if (Master == null)
|
|
|
- {
|
|
|
- if (Equals(TaskPanels.SelectedItem, TasksPlannerTabItem))
|
|
|
- TaskPanels.SelectedItem = _viewmap[KanbanViewType.Status];
|
|
|
- TasksPlannerTabItem.Visibility = Visibility.Collapsed;
|
|
|
- }
|
|
|
- else
|
|
|
- TasksPlannerTabItem.Visibility = Visibility.Visible;
|
|
|
-
|
|
|
- GetCurrentPanel()?.Refresh();
|
|
|
- }
|
|
|
+ TaskPanels.SelectedItem = _viewmap[_settings.ViewType];
|
|
|
|
|
|
- public string SectionName => GetCurrentPanel().SectionName;
|
|
|
+ kanbanTypes = new Client<KanbanType>()
|
|
|
+ .Query(
|
|
|
+ new Filter<KanbanType>(x => x.Hidden).IsEqualTo(false),
|
|
|
+ Columns.None<KanbanType>().Add(x => x.ID, x => x.Code, x => x.Description))
|
|
|
+ .Rows.Select(x => x.ToObject<KanbanType>()).ToArray();
|
|
|
+ }
|
|
|
|
|
|
- public TaskPanelProperties Properties { get; set; }
|
|
|
+ public void Shutdown(CancelEventArgs? cancel)
|
|
|
+ {
|
|
|
+ }
|
|
|
|
|
|
- public DataModel DataModel(Selection selection)
|
|
|
+ public void Refresh()
|
|
|
+ {
|
|
|
+ if (Master == null)
|
|
|
{
|
|
|
- return GetCurrentPanel().DataModel(selection);
|
|
|
- //return new AutoDataModel<Kanban>(new Filter<Kanban>(x => x.ID).IsEqualTo(Guid.Empty));
|
|
|
+ if (Equals(TaskPanels.SelectedItem, TasksPlannerTabItem))
|
|
|
+ TaskPanels.SelectedItem = _viewmap[KanbanViewType.Status];
|
|
|
+ TasksPlannerTabItem.Visibility = Visibility.Collapsed;
|
|
|
}
|
|
|
+ else
|
|
|
+ TasksPlannerTabItem.Visibility = Visibility.Visible;
|
|
|
+
|
|
|
+ GetCurrentPanel()?.Refresh();
|
|
|
+ }
|
|
|
|
|
|
- #endregion
|
|
|
+ public string SectionName => GetCurrentPanel().SectionName;
|
|
|
|
|
|
- #region CRUD Functionality
|
|
|
+ public TaskPanelProperties Properties { get; set; }
|
|
|
|
|
|
- private TEntity? DoCreate<TEntity>(Action<TEntity> customise)
|
|
|
- where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
- {
|
|
|
- var result = new TEntity();
|
|
|
- customise?.Invoke(result);
|
|
|
- if (DoEdit(new[] { result }, null))
|
|
|
- return result;
|
|
|
- return null;
|
|
|
- }
|
|
|
+ public DataModel DataModel(Selection selection)
|
|
|
+ {
|
|
|
+ return GetCurrentPanel().DataModel(selection);
|
|
|
+ //return new AutoDataModel<Kanban>(new Filter<Kanban>(x => x.ID).IsEqualTo(Guid.Empty));
|
|
|
+ }
|
|
|
|
|
|
- private readonly Dictionary<Type, IDynamicGrid> _grids = new();
|
|
|
+ #endregion
|
|
|
|
|
|
- private readonly List<Tuple<Guid, Entity>> _entitycache = new();
|
|
|
+ #region CRUD Functionality
|
|
|
|
|
|
- private DynamicDataGrid<TEntity> GetGrid<TEntity>() where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
- {
|
|
|
- if(!_grids.TryGetValue(typeof(TEntity), out var grid))
|
|
|
- {
|
|
|
- grid = (DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), typeof(TEntity)) as DynamicDataGrid<TEntity>)!;
|
|
|
- _grids[typeof(TEntity)] = grid;
|
|
|
+ private TEntity? DoCreate<TEntity>(Action<TEntity> customise)
|
|
|
+ where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ {
|
|
|
+ var result = new TEntity();
|
|
|
+ customise?.Invoke(result);
|
|
|
+ if (DoEdit(new[] { result }, null))
|
|
|
+ return result;
|
|
|
+ return null;
|
|
|
+ }
|
|
|
|
|
|
- if (typeof(TEntity) == typeof(Kanban))
|
|
|
- {
|
|
|
- CustomiseKanbanGrid((grid as DynamicDataGrid<Kanban>)!);
|
|
|
- }
|
|
|
- }
|
|
|
+ private readonly Dictionary<Type, IDynamicGrid> _grids = new();
|
|
|
|
|
|
- return (grid as DynamicDataGrid<TEntity>)!;
|
|
|
- }
|
|
|
+ private readonly List<Tuple<Guid, Entity>> _entitycache = new();
|
|
|
|
|
|
- private IEnumerable<TEntity> DoLoad<TEntity>(IEnumerable<TaskModel> models, Columns<TEntity> columns)
|
|
|
- where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ private DynamicDataGrid<TEntity> GetGrid<TEntity>() where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ {
|
|
|
+ if(!_grids.TryGetValue(typeof(TEntity), out var grid))
|
|
|
{
|
|
|
- var result = new List<TEntity>();
|
|
|
- var load = new List<Guid>();
|
|
|
- foreach (var model in models)
|
|
|
- {
|
|
|
- var entity = _entitycache.FirstOrDefault(x => Equals(x.Item1, model.ID) && x.Item2 is TEntity) as TEntity;
|
|
|
- if (entity is not null)
|
|
|
- result.Add(entity);
|
|
|
- else
|
|
|
- load.Add(model.ID);
|
|
|
- }
|
|
|
+ grid = (DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), typeof(TEntity)) as DynamicDataGrid<TEntity>)!;
|
|
|
+ _grids[typeof(TEntity)] = grid;
|
|
|
|
|
|
- if (load.Any())
|
|
|
+ if (typeof(TEntity) == typeof(Kanban))
|
|
|
{
|
|
|
- var entities = new Client<TEntity>()
|
|
|
- .Query(new Filter<TEntity>(x => x.ID).InList(load.ToArray()), columns)
|
|
|
- .Rows.Select(x => x.ToObject<TEntity>()).ToList();
|
|
|
- foreach (var entity in entities)
|
|
|
- _entitycache.Add(new Tuple<Guid, Entity>(entity.ID, entity));
|
|
|
- result.AddRange(entities);
|
|
|
+ CustomiseKanbanGrid((grid as DynamicDataGrid<Kanban>)!);
|
|
|
}
|
|
|
-
|
|
|
- return result;
|
|
|
}
|
|
|
|
|
|
- private IEnumerable<TEntity> DoLoad<TEntityKanban, TEntity, TLink>(IEnumerable<TaskModel> models, Columns<TEntity> columns)
|
|
|
- where TEntityKanban : EntityKanban<TEntity, TLink>, new()
|
|
|
- where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
- where TLink : IEntityLink<TEntity>, new()
|
|
|
- {
|
|
|
- var result = DoLoad(models, columns);
|
|
|
- if (!result.Any())
|
|
|
- foreach (var model in models)
|
|
|
- {
|
|
|
- result = new Client<TEntity>().Load(
|
|
|
- new Filter<TEntity>(x => x.ID).InQuery(new Filter<TEntityKanban>(x => x.Kanban.ID).IsEqualTo(model.ID),
|
|
|
- x => x.Entity.ID));
|
|
|
- foreach (var r in result)
|
|
|
- _entitycache.Add(new Tuple<Guid, Entity>(model.ID, r));
|
|
|
- }
|
|
|
-
|
|
|
- return result;
|
|
|
- }
|
|
|
+ return (grid as DynamicDataGrid<TEntity>)!;
|
|
|
+ }
|
|
|
|
|
|
- private void DoCache<TEntity>(Guid kanbanid, TEntity entity) where TEntity : Entity
|
|
|
+ private IEnumerable<TEntity> DoLoad<TEntity>(IEnumerable<TaskModel> models, Columns<TEntity> columns)
|
|
|
+ where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ {
|
|
|
+ var result = new List<TEntity>();
|
|
|
+ var load = new List<Guid>();
|
|
|
+ foreach (var model in models)
|
|
|
{
|
|
|
- if (!_entitycache.Any(x => Equals(x.Item1, kanbanid) && x.Item2 is TEntity && Equals(x.Item2.ID, entity.ID)))
|
|
|
- _entitycache.Add(new Tuple<Guid, Entity>(kanbanid, entity));
|
|
|
+ var entity = _entitycache.FirstOrDefault(x => Equals(x.Item1, model.ID) && x.Item2 is TEntity) as TEntity;
|
|
|
+ if (entity is not null)
|
|
|
+ result.Add(entity);
|
|
|
+ else
|
|
|
+ load.Add(model.ID);
|
|
|
}
|
|
|
|
|
|
- private bool DoEdit<TEntity>(IEnumerable<TEntity> entities, Action<TEntity>? action = null)
|
|
|
- where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ if (load.Any())
|
|
|
{
|
|
|
- if (entities == null || !entities.Any())
|
|
|
- return false;
|
|
|
-
|
|
|
+ var entities = new Client<TEntity>()
|
|
|
+ .Query(new Filter<TEntity>(x => x.ID).InList(load.ToArray()), columns)
|
|
|
+ .Rows.Select(x => x.ToObject<TEntity>()).ToList();
|
|
|
foreach (var entity in entities)
|
|
|
- action?.Invoke(entity);
|
|
|
-
|
|
|
- return GetGrid<TEntity>().EditItems(entities.ToArray());
|
|
|
+ _entitycache.Add(new Tuple<Guid, Entity>(entity.ID, entity));
|
|
|
+ result.AddRange(entities);
|
|
|
}
|
|
|
|
|
|
- private void DoLink<TEntityKanban, TEntity, TLink>(TaskModel model, Guid entityid)
|
|
|
- where TEntityKanban : EntityKanban<TEntity, TLink>, new()
|
|
|
- where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
- where TLink : IEntityLink<TEntity>, new()
|
|
|
- {
|
|
|
- var linktask = Task.Run(() =>
|
|
|
- {
|
|
|
- var link = new TEntityKanban();
|
|
|
- link.Kanban.ID = model.ID;
|
|
|
- link.Entity.ID = entityid;
|
|
|
- new Client<TEntityKanban>().Save(link, "");
|
|
|
- });
|
|
|
- var kanbantask = Task.Run(() =>
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private IEnumerable<TEntity> DoLoad<TEntityKanban, TEntity, TLink>(IEnumerable<TaskModel> models, Columns<TEntity> columns)
|
|
|
+ where TEntityKanban : EntityKanban<TEntity, TLink>, new()
|
|
|
+ where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ where TLink : IEntityLink<TEntity>, new()
|
|
|
+ {
|
|
|
+ var result = DoLoad(models, columns);
|
|
|
+ if (!result.Any())
|
|
|
+ foreach (var model in models)
|
|
|
{
|
|
|
- var kanban = LoadKanbans(
|
|
|
- new[] { model },
|
|
|
- Columns.Required<Kanban>().Add(x => x.ID, x => x.Locked)).FirstOrDefault();
|
|
|
- if (kanban is not null)
|
|
|
- {
|
|
|
- kanban.Locked = true;
|
|
|
- new Client<Kanban>().Save(kanban, "Locked because of linked " + typeof(TEntity).EntityName().Split('.').Last());
|
|
|
- }
|
|
|
- });
|
|
|
- Task.WaitAll(linktask, kanbantask);
|
|
|
- }
|
|
|
+ result = new Client<TEntity>().Load(
|
|
|
+ new Filter<TEntity>(x => x.ID).InQuery(new Filter<TEntityKanban>(x => x.Kanban.ID).IsEqualTo(model.ID),
|
|
|
+ x => x.Entity.ID));
|
|
|
+ foreach (var r in result)
|
|
|
+ _entitycache.Add(new Tuple<Guid, Entity>(model.ID, r));
|
|
|
+ }
|
|
|
|
|
|
- private static void DoDelete<TEntity>(IList<TEntity> entities, string auditnote)
|
|
|
- where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
- {
|
|
|
- new Client<TEntity>().Delete(entities, auditnote);
|
|
|
- }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- public Kanban? CreateKanban(Action<Kanban> customise)
|
|
|
- {
|
|
|
- var result = DoCreate<Kanban>(
|
|
|
- kanban =>
|
|
|
- {
|
|
|
- kanban.Title = "New Task";
|
|
|
- kanban.Description = "";
|
|
|
- kanban.Status = KanbanStatus.Open;
|
|
|
- kanban.DueDate = DateTime.Today;
|
|
|
- kanban.Private = false;
|
|
|
- kanban.JobLink.ID = Master?.ID ?? Guid.Empty;
|
|
|
- kanban.JobLink.Synchronise(Master ?? new Job());
|
|
|
- kanban.EmployeeLink.ID = App.EmployeeID;
|
|
|
- kanban.ManagerLink.ID = App.EmployeeID;
|
|
|
- customise?.Invoke(kanban);
|
|
|
- });
|
|
|
- if (result != null)
|
|
|
- DoCache(result.ID, result);
|
|
|
- return result;
|
|
|
- }
|
|
|
+ private void DoCache<TEntity>(Guid kanbanid, TEntity entity) where TEntity : Entity
|
|
|
+ {
|
|
|
+ if (!_entitycache.Any(x => Equals(x.Item1, kanbanid) && x.Item2 is TEntity && Equals(x.Item2.ID, entity.ID)))
|
|
|
+ _entitycache.Add(new Tuple<Guid, Entity>(kanbanid, entity));
|
|
|
+ }
|
|
|
|
|
|
- public IEnumerable<Kanban> LoadKanbans(IEnumerable<TaskModel> models, Columns<Kanban> columns)
|
|
|
- {
|
|
|
- columns.Add(x => x.ID);
|
|
|
- columns.Add(x => x.Number);
|
|
|
- columns.Add(x => x.Title);
|
|
|
- columns.Add(x => x.Notes);
|
|
|
- columns.Add(x => x.Summary);
|
|
|
- columns.Add(x => x.Completed);
|
|
|
- columns.Add(x => x.DueDate);
|
|
|
- columns.Add(x => x.ManagerLink.ID);
|
|
|
- columns.Add(x => x.EmployeeLink.ID);
|
|
|
- return DoLoad(models, columns);
|
|
|
- }
|
|
|
+ private bool DoEdit<TEntity>(IEnumerable<TEntity> entities, Action<TEntity>? action = null)
|
|
|
+ where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ {
|
|
|
+ if (entities == null || !entities.Any())
|
|
|
+ return false;
|
|
|
+
|
|
|
+ foreach (var entity in entities)
|
|
|
+ action?.Invoke(entity);
|
|
|
|
|
|
- public void OnValidateKanban(object sender, Kanban[] items, List<string> errors)
|
|
|
+ return GetGrid<TEntity>().EditItems(entities.ToArray());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void DoLink<TEntityKanban, TEntity, TLink>(TaskModel model, Guid entityid)
|
|
|
+ where TEntityKanban : EntityKanban<TEntity, TLink>, new()
|
|
|
+ where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ where TLink : IEntityLink<TEntity>, new()
|
|
|
+ {
|
|
|
+ var linktask = Task.Run(() =>
|
|
|
+ {
|
|
|
+ var link = new TEntityKanban();
|
|
|
+ link.Kanban.ID = model.ID;
|
|
|
+ link.Entity.ID = entityid;
|
|
|
+ new Client<TEntityKanban>().Save(link, "");
|
|
|
+ });
|
|
|
+ var kanbantask = Task.Run(() =>
|
|
|
{
|
|
|
- if (Properties.RequireTaskTypes && items.Any(x => x.Type.ID == Guid.Empty))
|
|
|
+ var kanban = LoadKanbans(
|
|
|
+ new[] { model },
|
|
|
+ Columns.Required<Kanban>().Add(x => x.ID, x => x.Locked)).FirstOrDefault();
|
|
|
+ if (kanban is not null)
|
|
|
{
|
|
|
- errors.Add("[Task Type] may not be blank!");
|
|
|
+ kanban.Locked = true;
|
|
|
+ new Client<Kanban>().Save(kanban, "Locked because of linked " + typeof(TEntity).EntityName().Split('.').Last());
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
+ Task.WaitAll(linktask, kanbantask);
|
|
|
+ }
|
|
|
|
|
|
- public void CustomiseKanbanGrid(DynamicDataGrid<Kanban> grid)
|
|
|
- {
|
|
|
- grid.OnValidate += OnValidateKanban;
|
|
|
- }
|
|
|
+ private static void DoDelete<TEntity>(IList<TEntity> entities, string auditnote)
|
|
|
+ where TEntity : Entity, IRemotable, IPersistent, new()
|
|
|
+ {
|
|
|
+ new Client<TEntity>().Delete(entities, auditnote);
|
|
|
+ }
|
|
|
|
|
|
- public bool EditKanbans(IEnumerable<TaskModel> models, Action<Kanban>? customise = null)
|
|
|
- {
|
|
|
- var entities = LoadKanbans(models, GetGrid<Kanban>().LoadEditorColumns());
|
|
|
- return DoEdit(entities, customise);
|
|
|
- }
|
|
|
+ public Kanban? CreateKanban(Action<Kanban> customise)
|
|
|
+ {
|
|
|
+ var result = DoCreate<Kanban>(
|
|
|
+ kanban =>
|
|
|
+ {
|
|
|
+ kanban.Title = "New Task";
|
|
|
+ kanban.Description = "";
|
|
|
+ kanban.Status = KanbanStatus.Open;
|
|
|
+ kanban.DueDate = DateTime.Today;
|
|
|
+ kanban.Private = false;
|
|
|
+ kanban.JobLink.ID = Master?.ID ?? Guid.Empty;
|
|
|
+ kanban.JobLink.Synchronise(Master ?? new Job());
|
|
|
+ kanban.EmployeeLink.ID = App.EmployeeID;
|
|
|
+ kanban.ManagerLink.ID = App.EmployeeID;
|
|
|
+ customise?.Invoke(kanban);
|
|
|
+ });
|
|
|
+ if (result != null)
|
|
|
+ DoCache(result.ID, result);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public IEnumerable<Kanban> LoadKanbans(IEnumerable<TaskModel> models, Columns<Kanban> columns)
|
|
|
+ {
|
|
|
+ columns.Add(x => x.ID);
|
|
|
+ columns.Add(x => x.Number);
|
|
|
+ columns.Add(x => x.Title);
|
|
|
+ columns.Add(x => x.Notes);
|
|
|
+ columns.Add(x => x.Summary);
|
|
|
+ columns.Add(x => x.Completed);
|
|
|
+ columns.Add(x => x.DueDate);
|
|
|
+ columns.Add(x => x.ManagerLink.ID);
|
|
|
+ columns.Add(x => x.EmployeeLink.ID);
|
|
|
+ return DoLoad(models, columns);
|
|
|
+ }
|
|
|
|
|
|
- public void DeleteKanbans(IEnumerable<TaskModel> models, string auditnote)
|
|
|
+ public void OnValidateKanban(object sender, Kanban[] items, List<string> errors)
|
|
|
+ {
|
|
|
+ if (Properties.RequireTaskTypes && items.Any(x => x.Type.ID == Guid.Empty))
|
|
|
{
|
|
|
- var kanbans = models.Select(x => new Kanban { ID = x.ID }).ToList();
|
|
|
- DoDelete(kanbans, auditnote);
|
|
|
+ errors.Add("[Task Type] may not be blank!");
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- public Requisition? CreateRequisition(TaskModel model, Action<Requisition>? customise)
|
|
|
- {
|
|
|
- var result = DoCreate<Requisition>(
|
|
|
- requi =>
|
|
|
- {
|
|
|
- requi.JobLink.ID = Master?.ID ?? Guid.Empty;
|
|
|
- requi.JobLink.Synchronise(Master ?? new Job());
|
|
|
- customise?.Invoke(requi);
|
|
|
- });
|
|
|
- if (result != null)
|
|
|
- {
|
|
|
- DoCache(model.ID, result);
|
|
|
- DoLink<RequisitionKanban, Requisition, RequisitionLink>(model, result.ID);
|
|
|
- }
|
|
|
+ public void CustomiseKanbanGrid(DynamicDataGrid<Kanban> grid)
|
|
|
+ {
|
|
|
+ grid.OnValidate += OnValidateKanban;
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
- }
|
|
|
+ public bool EditKanbans(IEnumerable<TaskModel> models, Action<Kanban>? customise = null)
|
|
|
+ {
|
|
|
+ var entities = LoadKanbans(models, GetGrid<Kanban>().LoadEditorColumns());
|
|
|
+ return DoEdit(entities, customise);
|
|
|
+ }
|
|
|
|
|
|
+ public void DeleteKanbans(IEnumerable<TaskModel> models, string auditnote)
|
|
|
+ {
|
|
|
+ var kanbans = models.Select(x => new Kanban { ID = x.ID }).ToList();
|
|
|
+ DoDelete(kanbans, auditnote);
|
|
|
+ }
|
|
|
|
|
|
- public bool EditRequisitions(IEnumerable<TaskModel> models, Action<Requisition>? customise = null)
|
|
|
+ public Requisition? CreateRequisition(TaskModel model, Action<Requisition>? customise)
|
|
|
+ {
|
|
|
+ var result = DoCreate<Requisition>(
|
|
|
+ requi =>
|
|
|
+ {
|
|
|
+ requi.JobLink.ID = Master?.ID ?? Guid.Empty;
|
|
|
+ requi.JobLink.Synchronise(Master ?? new Job());
|
|
|
+ customise?.Invoke(requi);
|
|
|
+ });
|
|
|
+ if (result != null)
|
|
|
{
|
|
|
- var requis = DoLoad<RequisitionKanban, Requisition, RequisitionLink>(models, GetGrid<Requisition>().LoadEditorColumns());
|
|
|
- if (requis.Any())
|
|
|
- return DoEdit(requis, customise);
|
|
|
- return false;
|
|
|
+ DoCache(model.ID, result);
|
|
|
+ DoLink<RequisitionKanban, Requisition, RequisitionLink>(model, result.ID);
|
|
|
}
|
|
|
|
|
|
- public Setout? CreateSetout(TaskModel model, Action<Setout> customise)
|
|
|
- {
|
|
|
- var result = DoCreate<Setout>(
|
|
|
- setout =>
|
|
|
- {
|
|
|
- setout.JobLink.ID = Master?.ID ?? Guid.Empty;
|
|
|
- setout.JobLink.Synchronise(Master ?? new Job());
|
|
|
- customise?.Invoke(setout);
|
|
|
- });
|
|
|
- if (result != null)
|
|
|
- {
|
|
|
- DoCache(model.ID, result);
|
|
|
- //DoLink<SetoutKanban, Setout, SetoutLink>(model, result.ID);
|
|
|
- }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
- }
|
|
|
|
|
|
- public bool EditSetouts(IEnumerable<TaskModel> models, Action<Setout>? customise = null)
|
|
|
+ public bool EditRequisitions(IEnumerable<TaskModel> models, Action<Requisition>? customise = null)
|
|
|
+ {
|
|
|
+ var requis = DoLoad<RequisitionKanban, Requisition, RequisitionLink>(models, GetGrid<Requisition>().LoadEditorColumns());
|
|
|
+ if (requis.Any())
|
|
|
+ return DoEdit(requis, customise);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ public Setout? CreateSetout(TaskModel model, Action<Setout> customise)
|
|
|
+ {
|
|
|
+ var result = DoCreate<Setout>(
|
|
|
+ setout =>
|
|
|
+ {
|
|
|
+ setout.JobLink.ID = Master?.ID ?? Guid.Empty;
|
|
|
+ setout.JobLink.Synchronise(Master ?? new Job());
|
|
|
+ customise?.Invoke(setout);
|
|
|
+ });
|
|
|
+ if (result != null)
|
|
|
{
|
|
|
- var setouts = DoLoad<SetoutKanban, Setout, SetoutLink>(models, GetGrid<Setout>().LoadEditorColumns());
|
|
|
- if (setouts.Any())
|
|
|
- return DoEdit(setouts, customise);
|
|
|
- return false;
|
|
|
+ DoCache(model.ID, result);
|
|
|
+ //DoLink<SetoutKanban, Setout, SetoutLink>(model, result.ID);
|
|
|
}
|
|
|
|
|
|
- public Delivery? CreateDelivery(TaskModel model, Action<Delivery> customise)
|
|
|
- {
|
|
|
- var result = DoCreate<Delivery>(
|
|
|
- delivery =>
|
|
|
- {
|
|
|
- delivery.Job.ID = Master?.ID ?? Guid.Empty;
|
|
|
- delivery.Job.Synchronise(Master ?? new Job());
|
|
|
- customise?.Invoke(delivery);
|
|
|
- });
|
|
|
- if (result != null)
|
|
|
- {
|
|
|
- DoCache(model.ID, result);
|
|
|
- DoLink<DeliveryKanban, Delivery, DeliveryLink>(model, result.ID);
|
|
|
- }
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
- }
|
|
|
+ public bool EditSetouts(IEnumerable<TaskModel> models, Action<Setout>? customise = null)
|
|
|
+ {
|
|
|
+ var setouts = DoLoad<SetoutKanban, Setout, SetoutLink>(models, GetGrid<Setout>().LoadEditorColumns());
|
|
|
+ if (setouts.Any())
|
|
|
+ return DoEdit(setouts, customise);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- public bool EditDeliveries(IEnumerable<TaskModel> models, Action<Delivery>? customise = null)
|
|
|
+ public Delivery? CreateDelivery(TaskModel model, Action<Delivery> customise)
|
|
|
+ {
|
|
|
+ var result = DoCreate<Delivery>(
|
|
|
+ delivery =>
|
|
|
+ {
|
|
|
+ delivery.Job.ID = Master?.ID ?? Guid.Empty;
|
|
|
+ delivery.Job.Synchronise(Master ?? new Job());
|
|
|
+ customise?.Invoke(delivery);
|
|
|
+ });
|
|
|
+ if (result != null)
|
|
|
{
|
|
|
- var deliveries = DoLoad<DeliveryKanban, Delivery, DeliveryLink>(models, GetGrid<Delivery>().LoadEditorColumns());
|
|
|
- if (deliveries.Any())
|
|
|
- return DoEdit(deliveries, customise);
|
|
|
- return false;
|
|
|
+ DoCache(model.ID, result);
|
|
|
+ DoLink<DeliveryKanban, Delivery, DeliveryLink>(model, result.ID);
|
|
|
}
|
|
|
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- public PurchaseOrder? CreateOrder(TaskModel model, Action<PurchaseOrder> customise)
|
|
|
- {
|
|
|
- var result = DoCreate<PurchaseOrder>(
|
|
|
- order => { customise?.Invoke(order); });
|
|
|
- if (result != null)
|
|
|
- {
|
|
|
- DoCache(model.ID, result);
|
|
|
- DoLink<PurchaseOrderKanban, PurchaseOrder, PurchaseOrderLink>(model, result.ID);
|
|
|
- }
|
|
|
+ public bool EditDeliveries(IEnumerable<TaskModel> models, Action<Delivery>? customise = null)
|
|
|
+ {
|
|
|
+ var deliveries = DoLoad<DeliveryKanban, Delivery, DeliveryLink>(models, GetGrid<Delivery>().LoadEditorColumns());
|
|
|
+ if (deliveries.Any())
|
|
|
+ return DoEdit(deliveries, customise);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- return result;
|
|
|
- }
|
|
|
|
|
|
- public bool EditPurchaseOrders(IEnumerable<TaskModel> models, Action<PurchaseOrder>? customise = null)
|
|
|
+ public PurchaseOrder? CreateOrder(TaskModel model, Action<PurchaseOrder> customise)
|
|
|
+ {
|
|
|
+ var result = DoCreate<PurchaseOrder>(
|
|
|
+ order => { customise?.Invoke(order); });
|
|
|
+ if (result != null)
|
|
|
{
|
|
|
- var orders = DoLoad<PurchaseOrderKanban, PurchaseOrder, PurchaseOrderLink>(models, GetGrid<PurchaseOrder>().LoadEditorColumns());
|
|
|
- if (orders.Any())
|
|
|
- return DoEdit(orders, customise);
|
|
|
- return false;
|
|
|
+ DoCache(model.ID, result);
|
|
|
+ DoLink<PurchaseOrderKanban, PurchaseOrder, PurchaseOrderLink>(model, result.ID);
|
|
|
}
|
|
|
|
|
|
- #endregion
|
|
|
+ return result;
|
|
|
+ }
|
|
|
|
|
|
- #region EntityReferences
|
|
|
+ public bool EditPurchaseOrders(IEnumerable<TaskModel> models, Action<PurchaseOrder>? customise = null)
|
|
|
+ {
|
|
|
+ var orders = DoLoad<PurchaseOrderKanban, PurchaseOrder, PurchaseOrderLink>(models, GetGrid<PurchaseOrder>().LoadEditorColumns());
|
|
|
+ if (orders.Any())
|
|
|
+ return DoEdit(orders, customise);
|
|
|
+ return false;
|
|
|
+ }
|
|
|
|
|
|
- private static void AddQuery<TEntityKanban, TEntity, TLink>(MultiQuery query, Guid[] taskids)
|
|
|
- where TEntityKanban : EntityKanban<TEntity, TLink>, new()
|
|
|
- where TEntity : Entity
|
|
|
- where TLink : IEntityLink<TEntity>, new()
|
|
|
- {
|
|
|
- query.Add(
|
|
|
- new Filter<TEntityKanban>(x => x.Kanban.ID).InList(taskids),
|
|
|
- Columns.None<TEntityKanban>().Add(x => x.Entity.ID).Add(x => x.Kanban.ID)
|
|
|
- );
|
|
|
- }
|
|
|
+ #endregion
|
|
|
|
|
|
- private static Guid[] ExtractIDs<TEntityKanban, TEntity, TLink>(MultiQuery query)
|
|
|
- where TEntityKanban : EntityKanban<TEntity, TLink>, new()
|
|
|
- where TEntity : Entity
|
|
|
- where TLink : IEntityLink<TEntity>, new()
|
|
|
- {
|
|
|
- var lookup = query.Get<TEntityKanban>().ToLookup<TEntityKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
- return query.Get<TEntityKanban>().ExtractValues<TEntityKanban, Guid>(x => x.Entity.ID).ToArray();
|
|
|
- }
|
|
|
+ #region EntityReferences
|
|
|
|
|
|
- public KanbanReferences[] GetReferences(IEnumerable<TaskModel> models)
|
|
|
- {
|
|
|
- var result = new List<KanbanReferences>();
|
|
|
+ private static void AddQuery<TEntityKanban, TEntity, TLink>(MultiQuery query, Guid[] taskids)
|
|
|
+ where TEntityKanban : EntityKanban<TEntity, TLink>, new()
|
|
|
+ where TEntity : Entity
|
|
|
+ where TLink : IEntityLink<TEntity>, new()
|
|
|
+ {
|
|
|
+ query.Add(
|
|
|
+ new Filter<TEntityKanban>(x => x.Kanban.ID).InList(taskids),
|
|
|
+ Columns.None<TEntityKanban>().Add(x => x.Entity.ID).Add(x => x.Kanban.ID)
|
|
|
+ );
|
|
|
+ }
|
|
|
|
|
|
- var ids = models.Select(x => x.ID).ToArray();
|
|
|
+ private static Guid[] ExtractIDs<TEntityKanban, TEntity, TLink>(MultiQuery query)
|
|
|
+ where TEntityKanban : EntityKanban<TEntity, TLink>, new()
|
|
|
+ where TEntity : Entity
|
|
|
+ where TLink : IEntityLink<TEntity>, new()
|
|
|
+ {
|
|
|
+ var lookup = query.Get<TEntityKanban>().ToLookup<TEntityKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
+ return query.Get<TEntityKanban>().ExtractValues<TEntityKanban, Guid>(x => x.Entity.ID).ToArray();
|
|
|
+ }
|
|
|
|
|
|
- var query = new MultiQuery();
|
|
|
+ public KanbanReferences[] GetReferences(IEnumerable<TaskModel> models)
|
|
|
+ {
|
|
|
+ var result = new List<KanbanReferences>();
|
|
|
|
|
|
- AddQuery<RequisitionKanban, Requisition, RequisitionLink>(query, ids);
|
|
|
- AddQuery<SetoutKanban, Setout, SetoutLink>(query, ids);
|
|
|
- AddQuery<DeliveryKanban, Delivery, DeliveryLink>(query, ids);
|
|
|
- AddQuery<PurchaseOrderKanban, PurchaseOrder, PurchaseOrderLink>(query, ids);
|
|
|
+ var ids = models.Select(x => x.ID).ToArray();
|
|
|
|
|
|
- query.Query();
|
|
|
+ var query = new MultiQuery();
|
|
|
|
|
|
- var requis = query.Get<RequisitionKanban>().ToLookup<RequisitionKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
- var setouts = query.Get<SetoutKanban>().ToLookup<SetoutKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
- var deliveries = query.Get<DeliveryKanban>().ToLookup<DeliveryKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
- var orders = query.Get<PurchaseOrderKanban>().ToLookup<PurchaseOrderKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
+ AddQuery<RequisitionKanban, Requisition, RequisitionLink>(query, ids);
|
|
|
+ AddQuery<SetoutKanban, Setout, SetoutLink>(query, ids);
|
|
|
+ AddQuery<DeliveryKanban, Delivery, DeliveryLink>(query, ids);
|
|
|
+ AddQuery<PurchaseOrderKanban, PurchaseOrder, PurchaseOrderLink>(query, ids);
|
|
|
|
|
|
- foreach (var id in ids)
|
|
|
- {
|
|
|
- var references = new KanbanReferences
|
|
|
- {
|
|
|
- Kanban = id,
|
|
|
- Requisitions = requis.Contains(id) ? requis[id].ToArray() : Array.Empty<Guid>(),
|
|
|
- Setouts = setouts.Contains(id) ? setouts[id].ToArray() : Array.Empty<Guid>(),
|
|
|
- Deliveries = deliveries.Contains(id) ? deliveries[id].ToArray() : Array.Empty<Guid>(),
|
|
|
- Orders = orders.Contains(id) ? orders[id].ToArray() : Array.Empty<Guid>()
|
|
|
- };
|
|
|
- result.Add(references);
|
|
|
- }
|
|
|
+ query.Query();
|
|
|
|
|
|
- return result.ToArray();
|
|
|
- }
|
|
|
+ var requis = query.Get<RequisitionKanban>().ToLookup<RequisitionKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
+ var setouts = query.Get<SetoutKanban>().ToLookup<SetoutKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
+ var deliveries = query.Get<DeliveryKanban>().ToLookup<DeliveryKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
+ var orders = query.Get<PurchaseOrderKanban>().ToLookup<PurchaseOrderKanban, Guid, Guid>(x => x.Kanban.ID, x => x.Entity.ID);
|
|
|
|
|
|
- public bool EditReferences(IEnumerable<TaskModel> models)
|
|
|
+ foreach (var id in ids)
|
|
|
{
|
|
|
- var result = false;
|
|
|
- var refs = GetReferences(models).First();
|
|
|
- if (refs.ReferenceType() == typeof(Requisition))
|
|
|
- result = EditRequisitions(
|
|
|
- models,
|
|
|
- requi =>
|
|
|
- {
|
|
|
- requi.Notes = Utility.ProcessNotes(requi.Notes, requi.Request);
|
|
|
- requi.Request = "";
|
|
|
- }
|
|
|
- );
|
|
|
- else if (refs.ReferenceType() == typeof(Setout))
|
|
|
- result = EditSetouts(models);
|
|
|
- else if (refs.ReferenceType() == typeof(Delivery))
|
|
|
- result = EditDeliveries(models);
|
|
|
- else if (refs.ReferenceType() == typeof(PurchaseOrder))
|
|
|
- result = EditPurchaseOrders(models);
|
|
|
- else
|
|
|
- result = EditKanbans(models);
|
|
|
- return result;
|
|
|
+ var references = new KanbanReferences
|
|
|
+ {
|
|
|
+ Kanban = id,
|
|
|
+ Requisitions = requis.Contains(id) ? requis[id].ToArray() : Array.Empty<Guid>(),
|
|
|
+ Setouts = setouts.Contains(id) ? setouts[id].ToArray() : Array.Empty<Guid>(),
|
|
|
+ Deliveries = deliveries.Contains(id) ? deliveries[id].ToArray() : Array.Empty<Guid>(),
|
|
|
+ Orders = orders.Contains(id) ? orders[id].ToArray() : Array.Empty<Guid>()
|
|
|
+ };
|
|
|
+ result.Add(references);
|
|
|
}
|
|
|
|
|
|
- #endregion
|
|
|
+ return result.ToArray();
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool EditReferences(IEnumerable<TaskModel> models)
|
|
|
+ {
|
|
|
+ var result = false;
|
|
|
+ var refs = GetReferences(models).First();
|
|
|
+ if (refs.ReferenceType() == typeof(Requisition))
|
|
|
+ result = EditRequisitions(
|
|
|
+ models,
|
|
|
+ requi =>
|
|
|
+ {
|
|
|
+ requi.Notes = Utility.ProcessNotes(requi.Notes, requi.Request);
|
|
|
+ requi.Request = "";
|
|
|
+ }
|
|
|
+ );
|
|
|
+ else if (refs.ReferenceType() == typeof(Setout))
|
|
|
+ result = EditSetouts(models);
|
|
|
+ else if (refs.ReferenceType() == typeof(Delivery))
|
|
|
+ result = EditDeliveries(models);
|
|
|
+ else if (refs.ReferenceType() == typeof(PurchaseOrder))
|
|
|
+ result = EditPurchaseOrders(models);
|
|
|
+ else
|
|
|
+ result = EditKanbans(models);
|
|
|
+ return result;
|
|
|
}
|
|
|
+
|
|
|
+ #endregion
|
|
|
}
|