DailyReport.xaml.cs 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using System.Windows;
  7. using System.Windows.Controls;
  8. using System.Windows.Data;
  9. using System.Windows.Input;
  10. using System.Windows.Media;
  11. using com.sun.xml.@internal.ws.client;
  12. using Comal.Classes;
  13. using InABox.Clients;
  14. using InABox.Configuration;
  15. using InABox.Core;
  16. using InABox.DynamicGrid;
  17. using InABox.WPF;
  18. namespace PRSDesktop
  19. {
  20. public class HTMLConverter : IValueConverter
  21. {
  22. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  23. {
  24. var str = value as string;
  25. return CoreUtils.StripHTML(str);
  26. }
  27. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  28. {
  29. throw new NotImplementedException();
  30. }
  31. }
  32. public class HideIfMineConverter : IValueConverter
  33. {
  34. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  35. {
  36. var guid = (Guid)value;
  37. return guid.Equals(ClientFactory.UserGuid) ? Visibility.Collapsed : Visibility.Visible;
  38. }
  39. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  40. {
  41. throw new NotImplementedException();
  42. }
  43. }
  44. public class DueDateToColorConverter : IValueConverter
  45. {
  46. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  47. {
  48. var duedate = (DateTime)value;
  49. return duedate < DateTime.Today
  50. ? "Salmon"
  51. : duedate < DateTime.Today.AddDays(7)
  52. ? "LightYellow"
  53. : "LightGreen";
  54. }
  55. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  56. {
  57. throw new NotImplementedException();
  58. }
  59. }
  60. public class DateIsInListConverter : IMultiValueConverter
  61. {
  62. public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  63. {
  64. if (values.Length < 2 || !(values[0] is DateTime) || !(values[1] is IEnumerable<HighlightedDate>))
  65. return false;
  66. var date = (DateTime)values[0];
  67. var dateList = (IEnumerable<HighlightedDate>)values[1];
  68. return dateList.Any(hd => hd.Date.Equals(date));
  69. }
  70. public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
  71. {
  72. throw new NotImplementedException();
  73. }
  74. }
  75. public class HighlightedDateDescriptionConverter : IMultiValueConverter
  76. {
  77. public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
  78. {
  79. if (values.Length < 2 || !(values[0] is DateTime) || !(values[1] is IEnumerable<HighlightedDate>))
  80. return false;
  81. var date = (DateTime)values[0];
  82. var dateList = (IEnumerable<HighlightedDate>)values[1];
  83. var highlightedDate = dateList.FirstOrDefault(hd => hd.Date.Equals(date));
  84. return highlightedDate != null ? highlightedDate.Description : string.Empty;
  85. }
  86. public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
  87. {
  88. throw new NotImplementedException();
  89. }
  90. }
  91. public class HighlightDatePicker : DatePicker
  92. {
  93. public static readonly DependencyProperty HighlightedDatesProperty =
  94. DependencyProperty.Register("HighlightedDates", typeof(IList<HighlightedDate>), typeof(HighlightDatePicker));
  95. public static readonly DependencyProperty HighlightBrushProperty = DependencyProperty.Register("HighlightBrush", typeof(Brush),
  96. typeof(HighlightDatePicker), new PropertyMetadata(Brushes.Orange));
  97. static HighlightDatePicker()
  98. {
  99. DefaultStyleKeyProperty.OverrideMetadata(typeof(HighlightDatePicker), new FrameworkPropertyMetadata(typeof(HighlightDatePicker)));
  100. }
  101. public IList<HighlightedDate> HighlightedDates
  102. {
  103. get => (IList<HighlightedDate>)GetValue(HighlightedDatesProperty);
  104. set => SetValue(HighlightedDatesProperty, value);
  105. }
  106. public Brush HighlightBrush
  107. {
  108. get => (Brush)GetValue(HighlightBrushProperty);
  109. set => SetValue(HighlightBrushProperty, value);
  110. }
  111. }
  112. public class HighlightedDate
  113. {
  114. public HighlightedDate(DateTime date, string description)
  115. {
  116. Date = date;
  117. Description = description;
  118. }
  119. public DateTime Date { get; set; }
  120. public string Description { get; set; }
  121. }
  122. public class RequiredReport
  123. {
  124. public RequiredReport(Guid id, DateTime date, TimeSpan start, TimeSpan finish, string notes)
  125. {
  126. ID = id;
  127. Date = date;
  128. Start = start;
  129. Finish = finish;
  130. Notes = notes;
  131. }
  132. public Guid ID { get; set; }
  133. public DateTime Date { get; set; }
  134. public TimeSpan Start { get; set; }
  135. public TimeSpan Finish { get; set; }
  136. public string Notes { get; set; }
  137. }
  138. public class TimeSheetConfirmedArgs : EventArgs
  139. {
  140. public DateTime Date { get; set; }
  141. }
  142. public delegate void TimeSheetConfirmedEvent(TimeSheetConfirmedArgs e);
  143. /// <summary>
  144. /// Interaction logic for DailyReport.xaml
  145. /// </summary>
  146. public partial class DailyReport : UserControl, IPanel<Assignment>
  147. {
  148. private DailyActivityScreenSettings _settings;
  149. private string _taskcategory = "Open";
  150. private bool bProgramaticallyChanging;
  151. private bool bSelectingAssignment;
  152. private AssignmentModel copiedAssignment;
  153. private KanbanGrid kg = new();
  154. private MenuItem MoveToComplete;
  155. private MenuItem MoveToCurrent;
  156. private MenuItem MoveToOpen;
  157. private MenuItem MoveToWaiting;
  158. private int RequiredReportIndex;
  159. private readonly List<RequiredReport> RequiredReports = new();
  160. private Assignment SelectedAssignment;
  161. private Point startPoint;
  162. private CalendarSettings Calendar_OnLoadSettings(object sender)
  163. {
  164. var settings = new CalendarSettings();
  165. settings.SettingsVisible = CalendarSettingsVisibility.Disabled;
  166. settings.AssignmentType = CalendarAssignmentType.Automatic;
  167. settings.CalendarView = CalendarViewType.Day;
  168. settings.BackgroundType = CalendarBackgroundType.Automatic;
  169. settings.TimeInterval = CalendarTimeInterval.FifteenMinutes;
  170. settings.EmployeeSelection = new EmployeeSelectorData(new Guid[] { Guid.Empty }, new Guid[] { Employee.ID });
  171. settings.Zoom = _settings.Zoom;
  172. return settings;
  173. }
  174. private void Calendar_OnSaveSettings(object sender, CalendarSettings properties)
  175. {
  176. _settings.Zoom = properties.Zoom;
  177. new UserConfiguration<DailyActivityScreenSettings>().Save(_settings);
  178. }
  179. public DailyReport()
  180. {
  181. InitializeComponent();
  182. ImportEmails.Visibility = Security.CanImport<Email>() ? Visibility.Visible : Visibility.Collapsed;
  183. ImportEmailsImage.Source = PRSDesktop.Resources.target.AsBitmapImage();
  184. ProcessWindowTrackers.Visibility = Security.IsAllowed<MonitorApplicationWindows>() ? Visibility.Visible : Visibility.Collapsed;
  185. ImportHistoryImage.Source = PRSDesktop.Resources.email.AsBitmapImage();
  186. ConfirmTimeSheetImage.Source = PRSDesktop.Resources.tick.AsBitmapImage();
  187. }
  188. public void Setup()
  189. {
  190. Calendar.DisableUpdate();
  191. try
  192. {
  193. Parallel.ForEach(
  194. new Action[]
  195. {
  196. () => _settings = new UserConfiguration<DailyActivityScreenSettings>().Load(),
  197. () => Employee = new Client<Employee>().Load(new Filter<Employee>(x => x.UserLink.ID).IsEqualTo(ClientFactory.UserGuid)).FirstOrDefault(),
  198. },
  199. (a => a())
  200. );
  201. Calendar.Setup();
  202. LoadRequiredReports();
  203. if (!RequiredReports.Any())
  204. {
  205. var start = TimeSpan.FromHours(6);
  206. var finish = TimeSpan.FromHours(18);
  207. var blocks = Calendar.GetRoster(Employee.ID, DateTime.Today)?.GetBlocks(DateTime.Today, TimeSpan.FromSeconds(0), TimeSpan.FromDays(1));
  208. if (blocks?.Any() == true)
  209. {
  210. start = blocks.Aggregate(TimeSpan.FromDays(1), (time, block) => time.Ticks < block.Start.Ticks ? time : block.Start);
  211. finish = blocks.Aggregate(TimeSpan.Zero, (time, block) => time.Ticks > block.Finish.Ticks ? time : block.Start);
  212. }
  213. RequiredReports.Add(new RequiredReport(Guid.Empty, DateTime.Today, start, finish, ""));
  214. ConfirmDock.Visibility = Visibility.Collapsed;
  215. }
  216. ConfigureEditor(Title, new TextBoxEditor());
  217. ConfigureEditor(ActivityNotes, new MemoEditor());
  218. ConfigureEditor(Start, new TimeOfDayEditor());
  219. ConfigureEditor(Duration, new TimeOfDayEditor());
  220. ConfigureEditor(Finish, new TimeOfDayEditor());
  221. ConfigureEditor(Notes, new MemoEditor());
  222. Activity.EditorDefinition = DatabaseSchema.Property(typeof(Assignment), CoreUtils.GetFullPropertyName<Assignment,Guid>(c=>c.ActivityLink.ID,".")).Editor;
  223. Activity.OtherColumns["Color"] = CoreUtils.GetFullPropertyName<Assignment,String>(c=>c.ActivityLink.Color,".");
  224. Activity.OtherColumns["Description"] = CoreUtils.GetFullPropertyName<Assignment,String>(c=>c.ActivityLink.Description,".");
  225. ConfigureEditor(Activity);
  226. ITP.EditorDefinition = DatabaseSchema.Property(typeof(Assignment), "ITP.ID").Editor;
  227. ITP.OtherColumns["Code"] = "ITP.Code";
  228. //ConfigureEditor(ITP);
  229. Kanban.EditorDefinition = DatabaseSchema.Property(typeof(Assignment), "Task.ID").Editor;
  230. Kanban.OtherColumns["JobLink.ID"] = "JobLink.ID";
  231. Kanban.OtherColumns["JobLink.JobNumber"] = "JobLink.JobNumber";
  232. Kanban.OtherColumns["JobLink.Name"] = "JobLink.Name";
  233. ConfigureEditor(Kanban);
  234. Job.EditorDefinition = DatabaseSchema.Property(typeof(Assignment), "JobLink.ID").Editor;
  235. Job.OtherColumns["JobNumber"] = "JobLink.JobNumber";
  236. Job.OtherColumns["Name"] = "JobLink.Name";
  237. Job.OnDefineFilter += (sender, type) => { return LookupFactory.DefineFilter<Assignment, Job>(new[] { SelectedAssignment }); };
  238. ConfigureEditor(Job);
  239. GotoCurrentRequiredReport();
  240. LoadKanbans("Open");
  241. }
  242. finally
  243. {
  244. Calendar.EnableUpdate();
  245. }
  246. }
  247. public void Shutdown()
  248. {
  249. }
  250. private void LoadRequiredReports()
  251. {
  252. var unconfirmed = new Client<TimeSheet>().Query(
  253. new Filter<TimeSheet>(x => x.EmployeeLink.ID).IsEqualTo(Employee.ID).And(x => x.Confirmed).IsEqualTo(DateTime.MinValue)
  254. .And(x => x.LeaveRequestLink).NotLinkValid(),
  255. new Columns<TimeSheet>(x => x.ID, x => x.Date, x => x.Start, x => x.Finish, x => x.Notes),
  256. new SortOrder<TimeSheet>(x => x.Date)
  257. );
  258. var id = Guid.Empty;
  259. var date = DateTime.MinValue;
  260. var start = TimeSpan.MaxValue;
  261. var end = TimeSpan.MinValue;
  262. var notes = new List<string>();
  263. foreach (var row in unconfirmed.Rows)
  264. {
  265. var curid = row.Get<TimeSheet, Guid>(x => x.ID);
  266. var curdate = row.Get<TimeSheet, DateTime>(c => c.Date).Date;
  267. var curstart = row.Get<TimeSheet, TimeSpan>(c => c.Start);
  268. var curend = row.Get<TimeSheet, TimeSpan>(c => c.Finish);
  269. var curnotes = row.Get<TimeSheet, string>(c => c.Notes);
  270. if (date != curdate)
  271. {
  272. if (id != Guid.Empty)
  273. RequiredReports.Add(new RequiredReport(id, date, start, end, string.Join("\n===================================\n", notes)));
  274. id = curid;
  275. date = curdate;
  276. start = TimeSpan.MaxValue;
  277. end = TimeSpan.MinValue;
  278. notes.Clear();
  279. }
  280. start = start > curstart ? curstart : start;
  281. end = end < curend ? curend : end;
  282. if (!string.IsNullOrEmpty(curnotes))
  283. notes.Add(curnotes);
  284. }
  285. if (id != Guid.Empty)
  286. RequiredReports.Add(new RequiredReport(id, date, start, end, string.Join("\n===================================\n", notes)));
  287. }
  288. public Employee Employee { get; set; }
  289. public event DataModelUpdateEvent OnUpdateDataModel;
  290. public bool IsReady { get; set; }
  291. public void CreateToolbarButtons(IPanelHost host)
  292. {
  293. }
  294. public string SectionName => "Daily Report";
  295. public DataModel DataModel(Selection selected) => Calendar.DataModel(selected);
  296. public void Heartbeat(TimeSpan time)
  297. {
  298. }
  299. public void Refresh()
  300. {
  301. RefreshAssignments();
  302. LoadKanbans();
  303. }
  304. public Dictionary<string, object[]> Selected()
  305. {
  306. return new Dictionary<string, object[]>();
  307. }
  308. public event TimeSheetConfirmedEvent OnTimeSheetConfirmed;
  309. private void PopulateFavourites(ItemsControl menu, RoutedEventHandler action, DateTime time, bool filltime)
  310. {
  311. menu.Items.RemoveAt(0);
  312. var create = new MenuItem { Header = "Create New Assignment" };
  313. create.Tag = new Tuple<DateTime, AssignmentFavourite>(time, null);
  314. create.Click += action;
  315. menu.Items.Insert(0,create);
  316. if (_settings.Favourites?.Any() == true)
  317. {
  318. menu.Items.Insert(1,new Separator());
  319. int i = 2;
  320. foreach (var favourite in _settings.Favourites)
  321. {
  322. var fav = new MenuItem { Header = favourite.Title };
  323. fav.Tag = new Tuple<DateTime, AssignmentFavourite>(time, favourite);
  324. fav.Click += action;
  325. menu.Items.Insert(i,fav);
  326. i++;
  327. }
  328. }
  329. }
  330. private void Assignments_OnCustomiseContextMenu(object sender, ICalendarDataEventArgs args)
  331. {
  332. if (sender is not ContextMenu menu)
  333. return;
  334. if (args is CalendarDataDataEventArgs<CalendarTimeSlot> slot)
  335. {
  336. PopulateFavourites(menu, CreateAssignment_Click, slot.Item.Time, false);
  337. }
  338. else if (args is CalendarDataDataEventArgs<AssignmentModel> model)
  339. {
  340. menu.Items.Insert(1,new Separator());
  341. var SetAsFavouriteMenu = new MenuItem { Header = GetFavourite(model.Item) == null ? "Set As Favourite" : "Update Favourite"};
  342. SetAsFavouriteMenu.Click += (o, args) => SetAsFavourite(model.Item);
  343. menu.Items.Insert(2,SetAsFavouriteMenu);
  344. if (_settings.Favourites.Any())
  345. {
  346. var ManageFavouritesMenu = new MenuItem { Header = "Manage Favourites" };
  347. ManageFavouritesMenu.Click += ManageFavourites_Click;
  348. menu.Items.Insert(3,ManageFavouritesMenu);
  349. }
  350. }
  351. }
  352. private AssignmentFavourite GetFavourite(AssignmentModel model)
  353. {
  354. return model == null ? null : _settings.Favourites.FirstOrDefault(x => string.Equals(x.Title, model.Subject));
  355. }
  356. private void SetAsFavourite(AssignmentModel model)
  357. {
  358. if (model == null)
  359. {
  360. MessageBox.Show("Please select an Assignment first!");
  361. return;
  362. }
  363. var bCreated = false;
  364. var favourite = GetFavourite(model);
  365. if (favourite == null)
  366. {
  367. bCreated = true;
  368. favourite = new AssignmentFavourite { Title = model.Subject };
  369. _settings.Favourites.Add(favourite);
  370. }
  371. favourite.JobID = model.JobID;
  372. favourite.JobNumber = model.JobNumber;
  373. favourite.ITPID = model.ItpID;
  374. favourite.ITPCode = model.ItpCode;
  375. favourite.ActivityID = model.ActivityID;
  376. favourite.ActivityColor = model.Color;
  377. favourite.ActivityName = model.ActivityCode;
  378. new UserConfiguration<DailyActivityScreenSettings>().Save(_settings);
  379. MessageBox.Show(bCreated ? "Favourite Created!" : "Favourite Updated!");
  380. }
  381. private void ManageFavourites_Click(object sender, RoutedEventArgs e)
  382. {
  383. new DailyReportFavouriteWindow(_settings.Favourites).ShowDialog();
  384. new UserConfiguration<DailyActivityScreenSettings>().Save(_settings);
  385. }
  386. private void ViewEmailInterfaceForm_Click(object sender, RoutedEventArgs e)
  387. {
  388. var form = new EmailInterfaceForm { FromDate = Calendar.SelectedDate, ToDate = Calendar.SelectedDate };
  389. form.ShowDialog();
  390. //UpdateDayButtons();
  391. }
  392. private void ProcessWindowTrackerMenu_Click(object sender, RoutedEventArgs e)
  393. {
  394. var history = new WindowTrackerSummary(Employee.ID, Calendar.SelectedDate);
  395. history.ShowDialog();
  396. //UpdateDayButtons();
  397. }
  398. private void CreateAssignment_Click(object sender, RoutedEventArgs e)
  399. {
  400. var fav = (sender as MenuItem)?.Tag as Tuple<DateTime, AssignmentFavourite>;
  401. var start = fav != null ? fav.Item1.TimeOfDay : Calendar.SelectedDate.TimeOfDay;
  402. CreateNewAssignment(start, fav?.Item2);
  403. }
  404. private void CreateNewAssignment(TimeSpan start, AssignmentFavourite? favourite)
  405. {
  406. CalendarDataEvent populate = (sender, args) => PopulateFavourite(args.Item as Assignment, favourite);
  407. Calendar.ItemCreated += populate;
  408. var ass = Calendar.CreateAssignment(new CalendarTimeSlot(Employee.ID, Calendar.SelectedDate.Add(start)));
  409. Calendar.ItemCreated -= populate;
  410. SelectAssignment(ass);
  411. }
  412. private void PopulateFavourite(Assignment? assignment, AssignmentFavourite? favourite)
  413. {
  414. if (assignment == null)
  415. return;
  416. assignment.Title = favourite != null ? favourite.Title : "";
  417. assignment.JobLink.ID = favourite != null ? favourite.JobID : Guid.Empty;
  418. assignment.ITP.ID = favourite != null ? favourite.ITPID : Guid.Empty;
  419. assignment.ActivityLink.ID = favourite != null ? favourite.ActivityID : Guid.Empty;
  420. assignment.ActivityLink.Color = favourite != null ? favourite.ActivityColor : "";
  421. new Client<Assignment>().Save(assignment, "Created by Daily Report");
  422. }
  423. private void RefreshAssignments()
  424. {
  425. Calendar.Refresh();
  426. }
  427. private void Assignments_OnSelectionChanged(object sender, ICalendarDataEventArgs args)
  428. {
  429. if (args is CalendarDataDataEventArgs<Assignment> ass)
  430. {
  431. CheckandSaveAssignment();
  432. SelectAssignment(ass.Item);
  433. }
  434. else
  435. SelectAssignment(null);
  436. }
  437. private void CheckandSaveAssignment()
  438. {
  439. if (SelectedAssignment != null && SelectedAssignment.IsChanged())
  440. {
  441. new Client<Assignment>().Save(SelectedAssignment, "", (o, e) => { });
  442. //SelectedAssignment.CommitChanges();
  443. }
  444. }
  445. private void SelectAssignment(Assignment? assignment)
  446. {
  447. Logger.Send(LogType.Information, ClientFactory.UserID, "Into Assignment_SelectionChanged()");
  448. bSelectingAssignment = true;
  449. try
  450. {
  451. SelectedAssignment = assignment;
  452. var bOK = assignment != null;
  453. //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (1/9): Setting Title");
  454. SetEditorValue(Title, bOK ? assignment.Title : "", bOK);
  455. //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (2/9): Setting Description");
  456. SetEditorValue(ActivityNotes, bOK ? assignment.Description : "", bOK);
  457. //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (3/9): Setting Start/Duration/Finish");
  458. SetEditorValue(Start, bOK ? assignment.Actual.Start : TimeSpan.MinValue, bOK);
  459. SetEditorValue(Duration, bOK ? assignment.Actual.Finish - assignment.Actual.Start : TimeSpan.MinValue, bOK);
  460. SetEditorValue(Finish, bOK ? assignment.Actual.Finish : TimeSpan.MinValue, bOK);
  461. var jobid = Job.Value;
  462. //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (4/9): Setting JobLink");
  463. SetEditorValue(Job, bOK ? assignment.JobLink.ID : Guid.Empty, bOK);
  464. if (bOK && !Equals(jobid, Job.Value))
  465. //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (5/9): Configuring ITP");
  466. ConfigureEditor(ITP);
  467. //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (6/9): Setting ITP");
  468. SetEditorValue(ITP, bOK ? assignment.ITP.ID : Guid.Empty, bOK);
  469. //if (bOK)
  470. //{
  471. // //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (7/9): Configuring Activity");
  472. // ConfigureEditor(Activity);
  473. //}
  474. //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (8/9): Setting Activity");
  475. //SetEditorValue(Activity, bOK ? assignment.ActivityLink.ID : Guid.Empty, bOK);
  476. Activity.Value = bOK ? assignment.ActivityLink.ID : Guid.Empty;
  477. Activity.IsEnabled = bOK;
  478. //if (bOK)
  479. //{
  480. // //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (9/9): Configuring Task");
  481. // ConfigureEditor(Kanban);
  482. //}
  483. //Logger.Send(LogType.Information, ClientFactory.UserID, "ASC (8/9): Setting Task");
  484. //SetEditorValue(Kanban, bOK ? assignment.Task.ID : Guid.Empty, bOK);
  485. Kanban.Value = bOK ? assignment.Task.ID : Guid.Empty;
  486. Kanban.IsEnabled = bOK;
  487. Job.IsEnabled = bOK ? !assignment.Task.IsValid() : false;
  488. if (assignment != null)
  489. {
  490. if (string.IsNullOrWhiteSpace(Title.Value))
  491. Title.SetFocus();
  492. else
  493. Notes.SetFocus();
  494. }
  495. }
  496. finally
  497. {
  498. bSelectingAssignment = false;
  499. }
  500. Logger.Send(LogType.Information, ClientFactory.UserID, "Out Of Assignment_SelectionChanged()");
  501. }
  502. private void ConfigureEditor(BaseDynamicEditorControl editor, BaseEditor definition = null)
  503. {
  504. if (definition != null)
  505. editor.EditorDefinition = definition;
  506. editor.Configure();
  507. editor.Loaded = true;
  508. }
  509. private void SetEditorValue(BaseDynamicEditorControl editor, object value, bool enabled)
  510. {
  511. editor.Loaded = false;
  512. editor.SetValue(editor.ColumnName, value);
  513. editor.IsEnabled = enabled;
  514. editor.Loaded = true;
  515. }
  516. private void Assignments_OnItemChanged(object sender, ICalendarDataEventArgs args)
  517. {
  518. if (args is CalendarDataDataEventArgs<Assignment> ass)
  519. {
  520. if (ass.Item.ID == Guid.Empty)
  521. using (new WaitCursor())
  522. {
  523. ass.Item.Actual.Duration = new TimeSpan(0, 30, 0);
  524. new Client<Assignment>().Save(ass.Item, "Created from Daily Report Drag & Drop");
  525. }
  526. }
  527. }
  528. private void EditorValueChanged(IDynamicEditorControl sender, Dictionary<string, object> values)
  529. {
  530. if (SelectedAssignment == null || bSelectingAssignment)
  531. return;
  532. DumpAssignmentValues(SelectedAssignment);
  533. var before = SelectedAssignment.GetValues(true);
  534. foreach (var key in values.Keys)
  535. {
  536. CoreUtils.SetPropertyValue(SelectedAssignment, key, values[key]);
  537. if (key.Equals("Task.ID"))
  538. Job.IsEnabled = values[key] == null || ((Guid)values[key]).Equals(Guid.Empty);
  539. if (key.Equals("JobLink.ID"))
  540. {
  541. ConfigureEditor(ITP);
  542. SelectedAssignment.ITP.ID = Guid.Empty;
  543. }
  544. }
  545. var after = SelectedAssignment.GetValues(true);
  546. var changes = before.Keys.Where(x =>
  547. !values.Keys.Contains(x) && ((before[x] == null && after[x] != null) || (before[x] != null && !before[x].Equals(after[x]))));
  548. foreach (var change in changes)
  549. if (change.Equals("Actual.Start"))
  550. SetEditorValue(Start, SelectedAssignment.Actual.Start, Start.IsEnabled);
  551. else if (change.Equals("Actual.Duration"))
  552. SetEditorValue(Duration, SelectedAssignment.Actual.Duration, Duration.IsEnabled);
  553. else if (change.Equals("Actual.Finish"))
  554. SetEditorValue(Finish, SelectedAssignment.Actual.Finish, Finish.IsEnabled);
  555. if (SelectedAssignment.Actual.Duration < new TimeSpan(0, 15, 0))
  556. {
  557. SelectedAssignment.Actual.Duration = new TimeSpan(0, 15, 0);
  558. SetEditorValue(Duration, SelectedAssignment.Actual.Duration, Duration.IsEnabled);
  559. SelectedAssignment.Actual.Finish = SelectedAssignment.Actual.Start.Add(SelectedAssignment.Actual.Duration);
  560. SetEditorValue(Finish, SelectedAssignment.Actual.Finish, Finish.IsEnabled);
  561. }
  562. if (SelectedAssignment.IsChanged())
  563. {
  564. new Client<Assignment>().Save(SelectedAssignment, "",
  565. (o, e) =>
  566. {
  567. if (e != null)
  568. Logger.Send(LogType.Error, "", String.Format("Error Updating Assignment: {0}\n{1}", e.Message, e.StackTrace));
  569. }
  570. );
  571. Calendar.UpdateAssignment(SelectedAssignment);
  572. }
  573. }
  574. private void DumpAssignmentValues(Assignment assignment)
  575. {
  576. Logger.Send(LogType.Information, "",
  577. string.Format("Updating Assignment: Start:{0} Duration={1} Finish={2}", assignment.Actual.Start, assignment.Actual.Duration, assignment.Actual.Finish));
  578. }
  579. private void TimeSheetEditorValueChanged(IDynamicEditorControl sender, Dictionary<string, object> values)
  580. {
  581. if (RequiredReportIndex < 0 || RequiredReportIndex >= RequiredReports.Count)
  582. return;
  583. var report = RequiredReports[RequiredReportIndex];
  584. report.Notes = sender.GetValue(sender.ColumnName) as string;
  585. var timesheet = new TimeSheet
  586. {
  587. ID = report.ID,
  588. Notes = report.Notes
  589. };
  590. new Client<TimeSheet>().Save(timesheet, "", (o, e) => { });
  591. }
  592. private void Activity_OnDefineLookups(ILookupEditorControl sender)
  593. {
  594. var editor = sender.EditorDefinition as ILookupEditor;
  595. var colname = sender.ColumnName;
  596. var assignment = new Assignment();
  597. assignment.EmployeeLink.ID = Employee.ID;
  598. var values = editor.Values(colname, new[] { assignment });
  599. sender.LoadLookups(values);
  600. }
  601. private void Task_OnDefineLookups(ILookupEditorControl sender)
  602. {
  603. var editor = sender.EditorDefinition as ILookupEditor;
  604. var colname = sender.ColumnName;
  605. var assignment = new Assignment();
  606. assignment.EmployeeLink.ID = Employee.ID;
  607. var values = editor.Values(colname, new[] { assignment });
  608. sender.LoadLookups(values);
  609. }
  610. private void ITP_OnDefineLookups(ILookupEditorControl sender)
  611. {
  612. var editor = sender.EditorDefinition as ILookupEditor;
  613. var colname = sender.ColumnName;
  614. var values = editor.Values(colname, SelectedAssignment == null ? new Assignment[] { } : new[] { SelectedAssignment });
  615. sender.LoadLookups(values);
  616. }
  617. private void FirstDay_Click(object sender, RoutedEventArgs e)
  618. {
  619. RequiredReportIndex = 0;
  620. GotoCurrentRequiredReport();
  621. }
  622. private void SetCurrentDay(DateTime date)
  623. {
  624. bProgramaticallyChanging = true;
  625. DatePicker.SelectedDate = date;
  626. bProgramaticallyChanging = false;
  627. ConfigureBookingsList();
  628. }
  629. private void PrevDay_Click(object sender, RoutedEventArgs e)
  630. {
  631. var requiredreport = RequiredReports.OrderBy(x => x.Date).LastOrDefault(x => x.Date < DatePicker.SelectedDate);
  632. if (requiredreport != null)
  633. SetCurrentDay(requiredreport.Date);
  634. }
  635. private void NextDay_Click(object sender, RoutedEventArgs e)
  636. {
  637. var requiredreport = RequiredReports.OrderBy(x => x.Date).FirstOrDefault(x => x.Date > DatePicker.SelectedDate);
  638. if (requiredreport != null)
  639. SetCurrentDay(requiredreport.Date);
  640. }
  641. private void LastDay_Click(object sender, RoutedEventArgs e)
  642. {
  643. RequiredReportIndex = RequiredReports.Count - 1;
  644. GotoCurrentRequiredReport();
  645. }
  646. private void DatePicker_SelectedDateChanged(object sender, SelectionChangedEventArgs e)
  647. {
  648. if (!bProgramaticallyChanging)
  649. ConfigureBookingsList();
  650. }
  651. private void ConfigureBookingsList()
  652. {
  653. DatePicker.HighlightedDates = RequiredReports.Select(x => new HighlightedDate(x.Date, "Report Required")).ToList();
  654. FirstDay.IsEnabled = RequiredReports.Count > 0 && DatePicker.SelectedDate > RequiredReports[0].Date; //RequiredReportIndex > 0;
  655. FirstDay.Content = new Image
  656. {
  657. Source = FirstDay.IsEnabled
  658. ? PRSDesktop.Resources.first.AsBitmapImage(32, 32)
  659. : PRSDesktop.Resources.first.Fade(0.2F).AsBitmapImage(32, 32)
  660. };
  661. PrevDay.IsEnabled = RequiredReports.Count > 0 && DatePicker.SelectedDate > RequiredReports[0].Date; //RequiredReportIndex > 0;
  662. PrevDay.Content = new Image
  663. {
  664. Source = PrevDay.IsEnabled
  665. ? PRSDesktop.Resources.back.AsBitmapImage(32, 32)
  666. : PRSDesktop.Resources.back.Fade(0.2F).AsBitmapImage(32, 32)
  667. };
  668. NextDay.IsEnabled =
  669. RequiredReports.Count > 0 &&
  670. DatePicker.SelectedDate < RequiredReports[RequiredReports.Count - 1].Date; //RequiredReportIndex < RequiredReports.Count - 1;
  671. NextDay.Content = new Image
  672. {
  673. Source = NextDay.IsEnabled
  674. ? PRSDesktop.Resources.next.AsBitmapImage(32, 32)
  675. : PRSDesktop.Resources.next.Fade(0.2F).AsBitmapImage(32, 32)
  676. };
  677. LastDay.IsEnabled =
  678. RequiredReports.Count > 0 &&
  679. DatePicker.SelectedDate < RequiredReports[RequiredReports.Count - 1].Date; //RequiredReportIndex < RequiredReports.Count - 1;
  680. LastDay.Content = new Image
  681. {
  682. Source = LastDay.IsEnabled
  683. ? PRSDesktop.Resources.last.AsBitmapImage(32, 32)
  684. : PRSDesktop.Resources.last.Fade(0.2F).AsBitmapImage(32, 32)
  685. };
  686. Calendar.SelectedDate = DatePicker.SelectedDate.Value.Date; // RequiredReports[RequiredReportIndex].Item2.Date;
  687. //Assignments.Refresh();
  688. //Assignments.StartHour = 0;
  689. //Assignments.EndHour = 24;
  690. var start = TimeSpan.FromHours(6);
  691. var finish = TimeSpan.FromHours(18);
  692. if ((DatePicker.SelectedDate.Value == DateTime.Today) && (DateTime.Now.TimeOfDay > finish))
  693. finish = DateTime.Now.TimeOfDay;
  694. String notes = "";
  695. var blocks = Calendar.GetRoster(Employee.ID, DatePicker.SelectedDate.Value)?.GetBlocks(DatePicker.SelectedDate.Value, TimeSpan.FromSeconds(0), TimeSpan.FromDays(1));
  696. if (blocks?.Any() == true)
  697. {
  698. start = blocks.Aggregate(start, (time, block) => time.Ticks < block.Start.Ticks ? time : block.Start);
  699. finish = blocks.Aggregate(finish, (time, block) => time.Ticks > block.Finish.Ticks ? time : block.Start);
  700. }
  701. var requiredreport = RequiredReports.FirstOrDefault(x => x.Date.Equals(DatePicker.SelectedDate)); //[RequiredReportIndex];
  702. if (requiredreport != null)
  703. {
  704. start = start > requiredreport.Start ? requiredreport.Start : start;
  705. finish = finish < requiredreport.Finish ? requiredreport.Finish : finish;
  706. notes = requiredreport.Notes;
  707. }
  708. else
  709. {
  710. var row = new Client<TimeSheet>().Query(
  711. new Filter<TimeSheet>(x => x.Date).IsEqualTo(DatePicker.SelectedDate.Value).And(x => x.EmployeeLink.UserLink.ID).IsEqualTo(ClientFactory.UserGuid),
  712. new Columns<TimeSheet>(
  713. x => x.Start,
  714. x => x.Finish,
  715. x => x.Notes
  716. )
  717. ).Rows.FirstOrDefault();
  718. if (row != null)
  719. {
  720. notes = requiredreport.Notes;
  721. var tstart = row.Get<TimeSheet, TimeSpan>(x => x.Start);
  722. start = start > tstart ? tstart : start;
  723. var tfinish = row.Get<TimeSheet, TimeSpan>(x => x.Finish);
  724. finish = finish < tfinish ? tfinish : finish;
  725. }
  726. }
  727. if (IsReady)
  728. Calendar.Refresh();
  729. Calendar.GetActiveWindow(Employee.ID, DatePicker.SelectedDate.Value, ref start, ref finish);
  730. Calendar.StartHour = start.Floor(TimeSpan.FromHours(1)).Hours;
  731. Calendar.EndHour = finish.Ceiling(TimeSpan.FromHours(1)).Hours;
  732. Notes.Value = notes;
  733. SelectAssignment(null);
  734. EnableScreen(requiredreport != null);
  735. }
  736. private void EnableScreen(bool enabled)
  737. {
  738. Title.IsEnabled = enabled && (SelectedAssignment != null);
  739. ActivityNotes.IsEnabled = enabled && (SelectedAssignment != null);
  740. Start.IsEnabled = enabled && (SelectedAssignment != null);
  741. Duration.IsEnabled = enabled && (SelectedAssignment != null);
  742. Finish.IsEnabled = enabled && (SelectedAssignment != null);
  743. Kanban.IsEnabled = enabled && (SelectedAssignment != null);
  744. ITP.IsEnabled = enabled && (SelectedAssignment != null);
  745. Job.IsEnabled = enabled && (SelectedAssignment != null);
  746. Activity.IsEnabled = enabled && (SelectedAssignment != null);
  747. Notes.IsEnabled = enabled;
  748. ProcessWindowTrackers.IsEnabled = enabled;
  749. ImportEmails.IsEnabled = enabled;
  750. ConfirmTimesheet.IsEnabled = enabled;
  751. Calendar.IsEnabled = enabled;
  752. }
  753. private void Splitpanel_OnChanged(object sender, DynamicSplitPanelSettings e)
  754. {
  755. _settings.ActivityColumnWidth = e.AnchorWidth;
  756. new UserConfiguration<DailyActivityScreenSettings>().Save(_settings);
  757. }
  758. private void ConfirmTimesheet_Click(object sender, RoutedEventArgs e)
  759. {
  760. var bBlankActivities = false;
  761. var bOverlapping = true;
  762. var rows = Calendar.GetAssignments(Employee.ID, DatePicker.SelectedDate.Value);
  763. foreach (var row in rows)
  764. {
  765. var id = row.Get<Assignment, Guid>(c => c.ID);
  766. var date = row.Get<Assignment, DateTime>(c => c.Date);
  767. var start = row.Get<Assignment, TimeSpan>(c => c.Actual.Start);
  768. var finish = row.Get<Assignment, TimeSpan>(c => c.Actual.Finish);
  769. if (rows.Any(r =>
  770. r.Get<Assignment, Guid>(c => c.ID) != id
  771. && r.Get<Assignment, DateTime>(c => c.Date) == date
  772. && r.Get<Assignment, TimeSpan>(c => c.Actual.Finish) > start
  773. && r.Get<Assignment, TimeSpan>(c => c.Actual.Start) < finish
  774. ))
  775. bOverlapping = false;
  776. if (Security.IsAllowed<RequireActivityCodesOnDailyReports>())
  777. bBlankActivities = rows.Any(r => !Entity.IsEntityLinkValid<Assignment, AssignmentActivityLink>(x => x.ActivityLink, r));
  778. }
  779. if (!bOverlapping)
  780. {
  781. MessageBox.Show("This report contains overlapping blocks!\n\nPlease correct before confirming this timesheet.");
  782. return;
  783. }
  784. if (bBlankActivities)
  785. {
  786. MessageBox.Show("All Daily Report entries must have a valid Activity Code!\n\nPlease correct before confirming this timesheet.");
  787. return;
  788. }
  789. if (MessageBox.Show(
  790. "Confirming your timesheet will prevent you from making any further changes or additions.\n\nAre you sure you want to do this?",
  791. "Confirm TimeSheet", MessageBoxButton.YesNo, MessageBoxImage.Warning) != MessageBoxResult.Yes)
  792. return;
  793. using (new WaitCursor())
  794. {
  795. var timesheets = new Client<TimeSheet>().Query(
  796. new Filter<TimeSheet>(x => x.EmployeeLink.ID).IsEqualTo(Employee.ID).And(x => x.Date).IsEqualTo(Calendar.SelectedDate),
  797. new Columns<TimeSheet>(x => x.ID, x => x.Confirmed)
  798. ).Rows.Select(r => r.ToObject<TimeSheet>()).ToArray();
  799. for (var i = 0; i < timesheets.Length; i++) timesheets[i].Confirmed = DateTime.Now;
  800. new Client<TimeSheet>().Save(timesheets, "Confirmed by Daily Activity Report");
  801. RequiredReports.RemoveAll(x => x.Date.Equals(Calendar.SelectedDate));
  802. if (!RequiredReports.Any())
  803. {
  804. var start = TimeSpan.FromSeconds(0);
  805. var finish = TimeSpan.FromDays(1);
  806. var blocks = Calendar.GetRoster(Employee.ID, DatePicker.SelectedDate.Value)?.GetBlocks(DatePicker.SelectedDate.Value, start, finish);
  807. if (blocks?.Any() == true)
  808. {
  809. start = blocks.Aggregate(start, (time, block) => time.Ticks < block.Start.Ticks ? time : block.Start);
  810. finish = blocks.Aggregate(finish, (time, block) => time.Ticks > block.Finish.Ticks ? time : block.Start);
  811. }
  812. RequiredReports.Add(new RequiredReport(Guid.Empty, DateTime.Today, start, finish, ""));
  813. ConfirmDock.Visibility = Visibility.Collapsed;
  814. }
  815. GotoCurrentRequiredReport();
  816. OnTimeSheetConfirmed?.Invoke(new TimeSheetConfirmedArgs { Date = Calendar.SelectedDate });
  817. }
  818. }
  819. private void GotoCurrentRequiredReport()
  820. {
  821. if (RequiredReportIndex >= RequiredReports.Count)
  822. RequiredReportIndex = RequiredReports.Count - 1;
  823. SetCurrentDay(RequiredReports[RequiredReportIndex].Date);
  824. }
  825. private void LoadKanbans(string category = null)
  826. {
  827. if (!string.IsNullOrWhiteSpace(category))
  828. _taskcategory = category;
  829. Tasks.ItemsSource = null;
  830. var filter = new Filter<KanbanSubscriber>(x => x.Kanban.Closed).IsEqualTo(DateTime.MinValue).And(x => x.Kanban.Category)
  831. .IsEqualTo(_taskcategory);
  832. if (ShowPublicTasks.IsChecked != true)
  833. filter = filter.And(x => x.Kanban.Private).IsEqualTo(true);
  834. filter = filter.And(x => x.Employee.UserLink.ID).IsEqualTo(ClientFactory.UserGuid);
  835. filter = filter.And(x => x.Assignee).IsEqualTo(true);
  836. new Client<KanbanSubscriber>().Query(
  837. filter,
  838. new Columns<KanbanSubscriber>
  839. (
  840. x => x.Kanban.ID,
  841. x => x.Kanban.DueDate,
  842. x => x.Kanban.Completed,
  843. x => x.Kanban.Description,
  844. x => x.Kanban.Summary,
  845. x => x.Kanban.Category,
  846. x => x.Kanban.EmployeeLink.ID,
  847. x => x.Kanban.EmployeeLink.UserLink.ID,
  848. x => x.Kanban.EmployeeLink.Name,
  849. x => x.Kanban.ManagerLink.ID,
  850. x => x.Kanban.ManagerLink.UserLink.ID,
  851. x => x.Kanban.ManagerLink.Name,
  852. x => x.Kanban.Notes,
  853. x => x.Kanban.Title,
  854. x => x.Kanban.JobLink.ID,
  855. x => x.Kanban.JobLink.JobNumber,
  856. x => x.Kanban.JobLink.Name,
  857. x => x.Kanban.Type.Code,
  858. x => x.Kanban.Number
  859. ),
  860. new SortOrder<KanbanSubscriber>(x => x.Kanban.DueDate),
  861. (kanbans, error) =>
  862. {
  863. Dispatcher.Invoke(() =>
  864. {
  865. foreach (var column in kanbans.Columns)
  866. column.ColumnName = column.ColumnName.Replace("Kanban.", "");
  867. Tasks.ItemsSource = kanbans.Rows.Select(x => x.ToObject<Kanban>());
  868. });
  869. }
  870. );
  871. }
  872. private void OpenTasks_Click(object sender, RoutedEventArgs e)
  873. {
  874. LoadKanbans("Open");
  875. CurrentTasks.SetValue(Grid.RowProperty, 6);
  876. WaitingTasks.SetValue(Grid.RowProperty, 7);
  877. ClosedTasks.SetValue(Grid.RowProperty, 8);
  878. }
  879. private void CurrentTasks_Click(object sender, RoutedEventArgs e)
  880. {
  881. LoadKanbans("In Progress");
  882. CurrentTasks.SetValue(Grid.RowProperty, 2);
  883. WaitingTasks.SetValue(Grid.RowProperty, 7);
  884. ClosedTasks.SetValue(Grid.RowProperty, 8);
  885. }
  886. private void WaitingTasks_Click(object sender, RoutedEventArgs e)
  887. {
  888. LoadKanbans("Waiting");
  889. CurrentTasks.SetValue(Grid.RowProperty, 2);
  890. WaitingTasks.SetValue(Grid.RowProperty, 3);
  891. ClosedTasks.SetValue(Grid.RowProperty, 8);
  892. }
  893. private void ClosedTasks_Click(object sender, RoutedEventArgs e)
  894. {
  895. LoadKanbans("Complete");
  896. CurrentTasks.SetValue(Grid.RowProperty, 2);
  897. WaitingTasks.SetValue(Grid.RowProperty, 3);
  898. ClosedTasks.SetValue(Grid.RowProperty, 4);
  899. }
  900. private void Tasks_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  901. {
  902. var startPoint = e.GetPosition(null);
  903. }
  904. // Helper to search up the VisualTree
  905. private static T FindAncestor<T>(DependencyObject current)
  906. where T : DependencyObject
  907. {
  908. try
  909. {
  910. do
  911. {
  912. if (current is T) return (T)current;
  913. current = VisualTreeHelper.GetParent(current);
  914. } while (current != null);
  915. }
  916. catch (Exception e)
  917. {
  918. Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
  919. }
  920. return null;
  921. }
  922. private void Tasks_MouseMove(object sender, MouseEventArgs e)
  923. {
  924. // Get the current mouse position
  925. var mousePos = e.GetPosition(null);
  926. var diff = startPoint - mousePos;
  927. if (e.LeftButton == MouseButtonState.Pressed &&
  928. (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
  929. Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
  930. {
  931. // Get the dragged ListViewItem
  932. var listView = sender as ListView;
  933. var depobj = (DependencyObject)e.OriginalSource;
  934. var kanban = listView.SelectedItem as Kanban;
  935. if (kanban != null)
  936. {
  937. var dragData = new DataObject("Comal.Classes.Kanban", kanban);
  938. DragDrop.DoDragDrop(depobj, dragData, DragDropEffects.Move);
  939. }
  940. }
  941. }
  942. private void NewTask_Click(object sender, RoutedEventArgs e)
  943. {
  944. var task = new Kanban();
  945. task.EmployeeLink.ID = Employee.ID;
  946. task.ManagerLink.ID = Employee.ID;
  947. task.Private = true;
  948. task.Category = "Open";
  949. if(DynamicGridUtils.CreateDynamicGrid(typeof(DynamicDataGrid<>), typeof(Kanban)).EditItems(new[] { task }))
  950. {
  951. using (new WaitCursor())
  952. {
  953. /*var task = new Kanban();
  954. task.Title = form.Title;
  955. task.Description = form.Description;
  956. task.DueDate = DateTime.Today;
  957. task.EmployeeLink.ID = Employee.ID;
  958. task.ManagerLink.ID = Employee.ID;
  959. task.Category = "Open";
  960. task.Private = true;*/
  961. new Client<Kanban>().Save(task, "Created from Daily Report screen");
  962. /*var subscriber = new KanbanSubscriber();
  963. subscriber.Kanban.ID = task.ID;
  964. subscriber.Employee.ID = Employee.ID;
  965. subscriber.Assignee = true;
  966. subscriber.Manager = true;
  967. new Client<KanbanSubscriber>().Save(subscriber, "");*/
  968. LoadKanbans();
  969. }
  970. }
  971. //var form = new QuickTask();
  972. //if (form.ShowDialog() == true)
  973. }
  974. private void ShowPublicTasks_Checked(object sender, RoutedEventArgs e)
  975. {
  976. LoadKanbans();
  977. }
  978. private void Tasks_MouseDoubleClick(object sender, MouseButtonEventArgs e)
  979. {
  980. var listview = sender as ListView;
  981. if (listview == null)
  982. return;
  983. var kanban = listview.SelectedItem as Kanban;
  984. if (kanban == null)
  985. return;
  986. if (kg == null)
  987. kg = new KanbanGrid();
  988. var bEdited = kg.EditItems(new[] { kanban });
  989. if (bEdited)
  990. LoadKanbans();
  991. }
  992. private void TaskMenu_ContextMenuOpening(object sender, ContextMenuEventArgs e)
  993. {
  994. var kanban = (sender as Border).Tag as Kanban;
  995. var menu = (sender as Border).ContextMenu;
  996. menu.Items.Clear();
  997. if (!string.Equals(_taskcategory, "Open"))
  998. MoveToOpen = CreateTaskMenu(menu, "Move To [Open Tasks]", kanban, MoveTask_Click);
  999. if (!string.Equals(_taskcategory, "In Progress"))
  1000. MoveToCurrent = CreateTaskMenu(menu, "Move To [Tasks In Progress]", kanban, MoveTask_Click);
  1001. else
  1002. menu.Items.Add(new Separator());
  1003. if (!string.Equals(_taskcategory, "Waiting"))
  1004. MoveToWaiting = CreateTaskMenu(menu, "Move To [Waiting For Others]", kanban, MoveTask_Click);
  1005. else
  1006. menu.Items.Add(new Separator());
  1007. if (!string.Equals(_taskcategory, "Complete"))
  1008. MoveToComplete = CreateTaskMenu(menu, "Move To [Completed Tasks]", kanban, MoveTask_Click);
  1009. menu.Items.Add(new Separator());
  1010. CreateTaskMenu(menu, "Change Due Date", kanban, ChangeKanbanDueDate_Click);
  1011. }
  1012. private MenuItem CreateTaskMenu(ContextMenu menu, string header, Kanban kanban, RoutedEventHandler action)
  1013. {
  1014. var item = new MenuItem();
  1015. item.Header = header;
  1016. item.Tag = kanban;
  1017. item.Click += action;
  1018. menu.Items.Add(item);
  1019. return item;
  1020. }
  1021. private void ChangeKanbanDueDate_Click(object sender, RoutedEventArgs e)
  1022. {
  1023. var kanban = (sender as MenuItem)?.Tag as Kanban;
  1024. var date = kanban.DueDate;
  1025. if (DateEdit.Execute("Change Due Date", ref date))
  1026. {
  1027. kanban.DueDate = date;
  1028. new Client<Kanban>().Save(kanban, "");
  1029. LoadKanbans();
  1030. }
  1031. }
  1032. private void MoveTask_Click(object sender, RoutedEventArgs e)
  1033. {
  1034. var kanban = (sender as MenuItem)?.Tag as Kanban;
  1035. if (kanban == null)
  1036. return;
  1037. var category = sender == MoveToComplete
  1038. ? "Complete"
  1039. : sender == MoveToWaiting
  1040. ? "Waiting"
  1041. : sender == MoveToCurrent
  1042. ? "In Progress"
  1043. : "Open";
  1044. kanban.Category = category;
  1045. new Client<Kanban>().Save(kanban, "");
  1046. LoadKanbans();
  1047. }
  1048. private void Assignments_OnItemEditing(object sender, ICalendarHandledEventArgs args)
  1049. {
  1050. args.Status = CalendarHandledStatus.Handled;
  1051. }
  1052. }
  1053. }