using System; using System.Collections.Generic; using System.Linq.Expressions; using InABox.Core; namespace Comal.Classes { public class KanbanDocumentCount : CoreAggregate { public override Expression> Aggregate => x => x.ID; public override AggregateCalculation Calculation => AggregateCalculation.Count; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>> () { { KanbanDocument => KanbanDocument.EntityLink.ID, Kanban => Kanban.ID } }; } public class KanbaAssignmentDuration : CoreAggregate { public override Expression> Aggregate => x => x.Actual.Duration; public override AggregateCalculation Calculation => AggregateCalculation.Sum; public override Dictionary>, Expression>> Links => new Dictionary>, Expression>>() { { Assignment => Assignment.Task.ID, Kanban => Kanban.ID } }; } public enum KanbanCategory { Open, InProgress, Waiting, Complete } [UserTracking("Task Management")] [Caption("Tasks")] public class Kanban : Entity, IPersistent, IRemotable, IKanban, IScheduleAction, IOneToMany, INumericAutoIncrement, IOneToMany, ILicense, IExportable, IImportable { public static String OPEN => "Open"; public static String INPROGRESS => "In Progress"; public static String WAITING => "Waiting"; public static String COMPLETE => "Complete"; public static String[] ALL = new String[] { Kanban.OPEN, Kanban.INPROGRESS, Kanban.WAITING, Kanban.COMPLETE }; private bool bChanging; [NullEditor] public DeliveryLink Delivery { get; set; } [IntegerEditor(Editable = Editable.Disabled)] [EditorSequence(-1)] public int Number { get; set; } [TextBoxEditor] [EditorSequence(0)] public string Title { get; set; } [EditorSequence(1)] [Caption("Attached to")] public JobLink JobLink { get; set; } [RichTextEditor] [EditorSequence(2)] public string Description { get; set; } [NotesEditor] [EditorSequence(3)] public string[] Notes { get; set; } = Array.Empty(); [MemoEditor(Visible = Visible.Optional, Editable = Editable.Hidden)] [EditorSequence(4)] public string Summary { get; set; } [EditorSequence(5)] [Caption("Task Type")] public KanbanTypeLink Type { get; set; } [DateEditor] [EditorSequence(6)] public DateTime DueDate { get; set; } = DateTime.Today; [EditorSequence(7)] [Caption("Assigned To")] public EmployeeLink EmployeeLink { get; set; } [EditorSequence(8)] [Caption("Allocated By")] public EmployeeLink ManagerLink { get; set; } [DateTimeEditor(Editable = Editable.Hidden)] [EditorSequence(9)] public DateTime Completed { get; set; } = DateTime.MinValue; [EditorSequence("Other", 1)] [Caption("Equipment Item")] public EquipmentLink Equipment { get; set; } [DateEditor] [EditorSequence("Other", 2)] public DateTime StartDate { get; set; } = DateTime.Today; [DurationEditor] [EditorSequence("Other", 3)] public TimeSpan EstimatedTime { get; set; } = TimeSpan.FromHours(1); [Aggregate(typeof(KanbaAssignmentDuration))] [EditorSequence("Other", 4)] public TimeSpan ActualTime { get; set; } [CheckBoxEditor] [EditorSequence("Other", 5)] public bool Private { get; set; } [EditorSequence("Other", 6)] [CheckBoxEditor] public bool Locked { get; set; } [ComboLookupEditor(typeof(KanbanCategoryLookups))] [EditorSequence("Other", 7)] [LoggableProperty] public string Category { get; set; } [SecondaryIndex] [NullEditor] public DateTime Closed { get; set; } = DateTime.MinValue; [NullEditor] [Aggregate(typeof(KanbanDocumentCount))] public int Attachments { get; set; } public Expression> AutoIncrementField() { return x => x.Number; } public Filter? AutoIncrementFilter() { return null; } [NullEditor] public ScheduleLink ScheduleLink { get; set; } public static KanbanCategory StringToCategory(string category) { return string.Equals(category, "Complete") ? KanbanCategory.Complete : string.Equals(category, "Waiting") ? KanbanCategory.Waiting : string.Equals(category, "In Progress") ? KanbanCategory.InProgress : KanbanCategory.Open; } public static string CategoryToString(KanbanCategory category) { return category.Equals(KanbanCategory.Complete) ? "Complete" : category.Equals(KanbanCategory.Waiting) ? "Waiting" : category.Equals(KanbanCategory.InProgress) ? "In Progress" : "Open"; } private bool IsCompleted(object? value) { if (value == null) return false; if (value is DateTime dateTime) return !dateTime.IsEmpty(); return value.Equals("Complete") || value.Equals("Completed"); } protected override void DoPropertyChanged(string name, object? before, object? after) { base.DoPropertyChanged(name, before, after); if (bChanging) return; bChanging = true; if (name.Equals("Completed")) // set the completed date { Category = IsCompleted(after) ? "Complete" : IsCompleted(Category) ? "In Progress" : Category; } else if (name.Equals("Category")) // set the completed date { Completed = IsCompleted(after) ? IsCompleted(Completed) ? Completed : DateTime.Now : DateTime.MinValue; } else if (name.Equals("Description")) { var summary = after as string; Summary = CoreUtils.StripHTML(summary); } bChanging = false; } private class KanbanCategoryLookups : LookupGenerator { public KanbanCategoryLookups(object[] items) : base(items) { AddValue(Kanban.OPEN, "To Do"); AddValue(Kanban.INPROGRESS, "In Progress"); AddValue(Kanban.WAITING, "Waiting For Others"); AddValue(Kanban.COMPLETE, "Completed"); } } } }