TasksByStatusControl.xaml.cs 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Collections.ObjectModel;
  4. using System.Globalization;
  5. using System.Linq;
  6. using System.Linq.Expressions;
  7. using System.Reflection;
  8. using System.Windows;
  9. using System.Windows.Controls;
  10. using System.Windows.Data;
  11. using System.Windows.Input;
  12. using System.Windows.Media;
  13. using System.Windows.Media.Imaging;
  14. using Comal.Classes;
  15. using InABox.Clients;
  16. using InABox.Core;
  17. using InABox.DynamicGrid;
  18. using InABox.WPF;
  19. using org.omg.CORBA;
  20. using Syncfusion.UI.Xaml.Kanban;
  21. using Color = System.Drawing.Color;
  22. namespace PRSDesktop
  23. {
  24. public class EmployeeModel
  25. {
  26. public EmployeeModel(Guid id, string name, Guid thumbnail, BitmapImage image)
  27. {
  28. ID = id;
  29. Name = name;
  30. Image = image;
  31. ThumbnailID = thumbnail;
  32. }
  33. public Guid ID { get; set; }
  34. public string Name { get; set; }
  35. public BitmapImage Image { get; set; }
  36. public Guid ThumbnailID { get; set; }
  37. }
  38. public class StatusTasksHeaderTimeConverter : IValueConverter
  39. {
  40. public static IEnumerable<TaskModel> Tasks { get; set; }
  41. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  42. {
  43. if (Tasks == null)
  44. return "0:00";
  45. var dataContext = value as ColumnTag;
  46. if (dataContext == null)
  47. return "0:00";
  48. var getter = dataContext.GetType().GetProperty("Column", BindingFlags.NonPublic | BindingFlags.Instance);
  49. if (getter == null)
  50. return "0:00";
  51. var column = (KanbanColumn)getter.GetValue(dataContext);
  52. if (column == null)
  53. return "0:00";
  54. double result = 0.0F;
  55. foreach (var kanban in Tasks.Where(x => Equals(x.Category, column.Categories)))
  56. result += kanban.EstimatedTime.TotalHours;
  57. return string.Format("{0:F2}", result);
  58. }
  59. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  60. {
  61. throw new NotImplementedException();
  62. }
  63. }
  64. public class BoolToVisibilityConverter : IValueConverter
  65. {
  66. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  67. {
  68. if (Equals(value, true))
  69. return Visibility.Visible;
  70. return Visibility.Collapsed;
  71. }
  72. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  73. {
  74. throw new NotImplementedException();
  75. }
  76. }
  77. /// <summary>
  78. /// Interaction logic for KanbanPanel.xaml
  79. /// </summary>
  80. public partial class TasksByStatusControl : UserControl, ITaskControl
  81. {
  82. private BitmapImage _attachimg = PRSDesktop.Resources.attachment.AsBitmapImage();
  83. private readonly ObservableCollection<EmployeeModel> _employeelist = new();
  84. private CoreTable _employees;
  85. public CoreTable _kanbans;
  86. private BitmapImage _lockimg = PRSDesktop.Resources.lock_sml.AsBitmapImage();
  87. private ObservableCollection<TaskModel> _models = new();
  88. private CoreTable _types;
  89. public List<string> CheckedKanbans = new();
  90. // CoreUtils.FullGuid => All Staff
  91. // Guid.Empty => Unallocated
  92. // Anything Else => Actual Staff Member
  93. private Guid EmployeeID = Guid.Empty;
  94. private Guid? MyID;
  95. private string MyName = "";
  96. private string searchtext = "";
  97. private Guid selectedtype = CoreUtils.FullGuid;
  98. public TasksByStatusControl()
  99. {
  100. InitializeComponent();
  101. }
  102. public string SectionName => "Tasks By Status";
  103. public DataModel DataModel(Selection selection)
  104. {
  105. var ids = SelectedModels().Select(x => Guid.Parse(x.ID)).ToArray();
  106. return new AutoDataModel<Kanban>(new Filter<Kanban>(x => x.ID).InList(ids));
  107. }
  108. private void ResizeColumns()
  109. {
  110. //if (!bResizeRequired)
  111. // return;
  112. using (var d = Dispatcher.DisableProcessing())
  113. {
  114. var CollapsedWidth = 50;
  115. var CollapsedColumns = 0;
  116. Array.ForEach(Kanban.Columns.ToArray(), x => { CollapsedColumns += x.IsExpanded ? 0 : 1; });
  117. if (Kanban.Columns.Count > 0 && CollapsedColumns != Kanban.Columns.Count)
  118. {
  119. var ColumnWidth = (Kanban.ActualWidth - CollapsedColumns * CollapsedWidth) / (Kanban.Columns.Count - CollapsedColumns) - 2;
  120. if (ColumnWidth != Kanban.ColumnWidth) Kanban.ColumnWidth = ColumnWidth;
  121. //bResizeRequired = false;
  122. }
  123. }
  124. }
  125. private void TaskMenu_Opened(object sender, RoutedEventArgs e)
  126. {
  127. Host.PopulateMenu(this, sender as ContextMenu);
  128. }
  129. private void Kanban_SizeChanged(object sender, SizeChangedEventArgs e)
  130. {
  131. Kanban.ColumnWidth = Kanban.ActualWidth / Kanban.Columns.Count - 1.0F;
  132. }
  133. private void Kanban_CardDragStart(object sender, KanbanDragStartEventArgs e)
  134. {
  135. var models = SelectedModels(e.SelectedCard.Content as TaskModel);
  136. if (models.Any(x => x.Locked))
  137. e.IsCancel = true;
  138. }
  139. private void Kanban_CardDragEnd(object sender, KanbanDragEndEventArgs e)
  140. {
  141. using (new WaitCursor())
  142. {
  143. var target = e.TargetColumn.Categories;
  144. var models = SelectedModels(e.SelectedCard.Content as TaskModel).Where(x => !Equals(x.Category, target)).ToArray();
  145. if (!models.Any())
  146. return;
  147. var kanbans = Host.LoadKanbans(models, new Columns<Kanban>(x => x.ID, x => x.Category));
  148. foreach (var kanban in kanbans)
  149. kanban.Category = target;
  150. new Client<Kanban>().Save(kanbans, string.Format("Task Status Updated to {0}", target), (o, err) => { });
  151. foreach (var model in models)
  152. {
  153. model.Checked = false;
  154. model.Category = target;
  155. }
  156. FilterKanbans();
  157. }
  158. }
  159. private void Search_KeyUp(object sender, KeyEventArgs e)
  160. {
  161. if (string.IsNullOrWhiteSpace(Search.Text) || e.Key == Key.Return)
  162. {
  163. searchtext = Search.Text;
  164. Refresh(true);
  165. }
  166. }
  167. private void TaskTypes_SelectionChanged(object sender, SelectionChangedEventArgs e)
  168. {
  169. if (!IsReady)
  170. return;
  171. if (e.AddedItems.Count > 0)
  172. {
  173. var item = (KeyValuePair<Guid, string>)e.AddedItems[0];
  174. selectedtype = item.Key;
  175. }
  176. else
  177. {
  178. selectedtype = CoreUtils.FullGuid;
  179. }
  180. Host.Settings.StatusSettings.SelectedType = selectedtype;
  181. Host.SaveSettings();
  182. ReloadKanbans();
  183. }
  184. private void IncludeCompleted_Checked(object sender, RoutedEventArgs e)
  185. {
  186. if (!IsReady)
  187. return;
  188. Host.Settings.StatusSettings.IncludeCompleted = IncludeCompleted.IsChecked.Value;
  189. Host.SaveSettings();
  190. SetupColumns();
  191. ReloadKanbans();
  192. }
  193. private void IncludeObserved_Checked(object sender, RoutedEventArgs e)
  194. {
  195. if (!IsReady)
  196. return;
  197. Host.Settings.StatusSettings.IncludeObserved = IncludeObserved.IsChecked.Value;
  198. Host.SaveSettings();
  199. ReloadKanbans();
  200. }
  201. private void IncludeLocked_Checked(object sender, RoutedEventArgs e)
  202. {
  203. if (!IsReady)
  204. return;
  205. Host.Settings.StatusSettings.IncludeLocked = IncludeLocked.IsChecked.Value;
  206. Host.SaveSettings();
  207. ReloadKanbans();
  208. }
  209. private void ViewType_SelectionChanged(object sender, SelectionChangedEventArgs e)
  210. {
  211. if (Kanban != null)
  212. Kanban.CardTemplate = ViewType.SelectedIndex > 0
  213. ? Resources["CompactKanban"] as DataTemplate
  214. : Resources["FullKanban"] as DataTemplate;
  215. if (IsReady)
  216. {
  217. Host.Settings.StatusSettings.CompactView = ViewType.SelectedIndex > 0;
  218. Host.SaveSettings();
  219. }
  220. }
  221. private void Employees_SelectionChanged(object sender, SelectionChangedEventArgs e)
  222. {
  223. //if (!IsReady)
  224. // return;
  225. if (e.AddedItems.Count == 0)
  226. {
  227. EmployeeID = Guid.Empty;
  228. }
  229. else
  230. {
  231. var model = _employeelist[Employees.SelectedIndex];
  232. EmployeeID = model.ID;
  233. }
  234. CheckedKanbans.Clear();
  235. if (IsReady)
  236. Refresh(true);
  237. }
  238. private void Export_Click(object sender, RoutedEventArgs e)
  239. {
  240. var form = new DynamicExportForm(typeof(Kanban), _kanbans.Columns.Select(x => x.ColumnName));
  241. if (form.ShowDialog() != true)
  242. return;
  243. var export = new Client<Kanban>().Query(
  244. GetKanbanFilter(),
  245. new Columns<Kanban>(form.Fields),
  246. LookupFactory.DefineSort<Kanban>()
  247. );
  248. var employee = "Tasks for All Staff";
  249. if (EmployeeID != CoreUtils.FullGuid)
  250. {
  251. if (EmployeeID == Guid.Empty)
  252. {
  253. employee = "Unallocated Tasks";
  254. }
  255. else
  256. {
  257. var model = _employeelist.FirstOrDefault(x => x.ID.Equals(EmployeeID));
  258. employee = model == null ? "Tasks for (Unknown)" : "Tasks for " + (model.ID == MyID ? MyName : model.Name);
  259. }
  260. }
  261. ExcelExporter.DoExport<Kanban>(
  262. export,
  263. string.Format(
  264. "{0} ({1:dd-MMM-yy})",
  265. employee,
  266. DateTime.Today
  267. )
  268. );
  269. }
  270. #region ITaskControl Support
  271. public bool IsReady { get; set; }
  272. public ITaskHost Host { get; set; }
  273. public KanbanView KanbanView => KanbanView.Status;
  274. public IEnumerable<TaskModel> SelectedModels(TaskModel sender = null)
  275. {
  276. var result = _models.Where(x => x.Checked).ToList();
  277. if (sender != null && !result.Contains(sender))
  278. result.Add(sender);
  279. return result;
  280. }
  281. #endregion
  282. #region Setup
  283. public void Setup()
  284. {
  285. SetupToolbar();
  286. SetupColumns();
  287. SetupData();
  288. SetupKanbanTypesLookup();
  289. SetupMyEmployee();
  290. SetupEmployeeList();
  291. }
  292. private void SetupMyEmployee()
  293. {
  294. var row = _employees.Rows.FirstOrDefault(r => r.Get<Employee, Guid>(c => c.UserLink.ID) == ClientFactory.UserGuid);
  295. if (row != null)
  296. {
  297. MyID = row.Get<Employee, Guid>(c => c.ID);
  298. MyName = row.Get<Employee, string>(x => x.Name);
  299. }
  300. }
  301. private void SetupEmployeeList()
  302. {
  303. IEnumerable<CoreRow> active = null;
  304. var anonymous = PRSDesktop.Resources.anonymous.AsBitmapImage();
  305. if (Security.IsAllowed<CanViewOthersTasks>())
  306. {
  307. active = _employees.Rows.Where(r =>
  308. r.Get<Employee, bool>(x => x.CanAllocateTasks) && (r.Get<Employee, DateTime>(x => x.FinishDate).IsEmpty() ||
  309. r.Get<Employee, DateTime>(x => x.FinishDate) > DateTime.Today));
  310. _employeelist.Add(new EmployeeModel(CoreUtils.FullGuid, "All Staff", Guid.Empty, PRSDesktop.Resources.everyone.AsBitmapImage()));
  311. _employeelist.Add(new EmployeeModel(Guid.Empty, "Unallocated", Guid.Empty, null));
  312. }
  313. else
  314. {
  315. active = _employees.Rows.Where(r => r.Get<Employee, Guid>(c => c.UserLink.ID).Equals(ClientFactory.UserGuid));
  316. }
  317. EmployeeModel selected = null;
  318. foreach (var row in active)
  319. {
  320. var id = row.Get<Employee, Guid>(x => x.ID);
  321. var userid = row.Get<Employee, Guid>(x => x.UserLink.ID);
  322. var thumbnailid = row.Get<Employee, Guid>(x => x.Thumbnail.ID);
  323. var name = userid.Equals(ClientFactory.UserGuid) ? "My Tasks" : row.Get<Employee, string>(x => x.Name);
  324. var model = new EmployeeModel(id, name, thumbnailid, anonymous);
  325. if (userid.Equals(ClientFactory.UserGuid))
  326. {
  327. _employeelist.Insert(0, model);
  328. selected = model;
  329. }
  330. else
  331. {
  332. _employeelist.Add(model);
  333. }
  334. }
  335. if (Security.IsAllowed<CanViewOthersTasks>())
  336. {
  337. EmployeeListColumn.Width = new GridLength(1.0F, GridUnitType.Auto);
  338. var thumbnails = active
  339. .Select(r => r.EntityLinkID<Employee, ImageDocumentLink>(x => x.Thumbnail) ?? Guid.Empty)
  340. .Where(x => x != Guid.Empty).ToArray();
  341. if (thumbnails.Any())
  342. new Client<Document>().Query(
  343. new Filter<Document>(x => x.ID).InList(thumbnails),
  344. new Columns<Document>(x => x.ID, x => x.Data),
  345. null,
  346. (data, error) =>
  347. {
  348. if (data != null)
  349. ProcessThumbnails(data);
  350. }
  351. );
  352. else
  353. {
  354. Employees.ItemsSource = _employeelist;
  355. Employees.SelectedItem = _employeelist.First();
  356. }
  357. }
  358. else
  359. {
  360. EmployeeListColumn.Width = new GridLength(0.0F, GridUnitType.Pixel);
  361. Employees.ItemsSource = _employeelist;
  362. Employees.SelectedItem = _employeelist.First();
  363. }
  364. }
  365. private void ProcessThumbnails(CoreTable data)
  366. {
  367. Dispatcher.Invoke(() =>
  368. {
  369. foreach (var row in data.Rows)
  370. {
  371. var id = row.Get<Document, Guid>(x => x.ID);
  372. var model = _employeelist.FirstOrDefault(x => x.ThumbnailID.Equals(id));
  373. if (model != null)
  374. {
  375. model.Image = new BitmapImage();
  376. model.Image.LoadImage(row.Get<Document, byte[]>(x => x.Data));
  377. }
  378. }
  379. Employees.ItemsSource = _employeelist;
  380. Employees.SelectedItem = _employeelist.First();
  381. });
  382. }
  383. private void SetupKanbanTypesLookup()
  384. {
  385. if (ClientFactory.IsSupported<KanbanType>())
  386. {
  387. var tasktypes = new Dictionary<Guid, string>
  388. {
  389. { CoreUtils.FullGuid, "All Types" },
  390. { Guid.Empty, "Unallocated Types" }
  391. };
  392. _types.IntoDictionary<KanbanType, Guid, string>(tasktypes, x => x.ID, row => row.Get<KanbanType, string>(x => x.Description));
  393. TaskTypes.ItemsSource = tasktypes;
  394. if (tasktypes.ContainsKey(Host.Settings.StatusSettings.SelectedType))
  395. TaskTypes.SelectedValue = Host.Settings.StatusSettings.SelectedType;
  396. else
  397. TaskTypes.SelectedValue = CoreUtils.FullGuid;
  398. TaskTypesLabel.Visibility = Visibility.Visible;
  399. TaskTypes.Visibility = Visibility.Visible;
  400. }
  401. else
  402. {
  403. TaskTypesLabel.Visibility = Visibility.Collapsed;
  404. TaskTypes.Visibility = Visibility.Collapsed;
  405. }
  406. }
  407. private void SetupToolbar()
  408. {
  409. IncludeCompleted.Visibility = Security.IsAllowed<CanHideTaskCompletedColumn>() ? Visibility.Visible : Visibility.Collapsed;
  410. IncludeCompleted.IsChecked = IncludeCompleted.Visibility == Visibility.Visible ? Host.Settings.StatusSettings.IncludeCompleted : true;
  411. IncludeObserved.IsChecked = Host.Settings.StatusSettings.IncludeObserved;
  412. ViewType.SelectedIndex = Host.Settings.StatusSettings.CompactView ? 1 : 0;
  413. }
  414. private void SetupColumns()
  415. {
  416. Kanban.Columns.Clear();
  417. var indicatorColorPalette = new IndicatorColorPalette();
  418. indicatorColorPalette.Add(new ColorMapping { Key = "Red", Color = Colors.LightSalmon });
  419. indicatorColorPalette.Add(new ColorMapping { Key = "Orange", Color = Colors.Orange });
  420. indicatorColorPalette.Add(new ColorMapping { Key = "Yellow", Color = Colors.LightYellow });
  421. indicatorColorPalette.Add(new ColorMapping { Key = "Green", Color = Colors.LightGreen });
  422. Kanban.IndicatorColorPalette = indicatorColorPalette;
  423. Kanban.Columns.Add(new KanbanColumn
  424. {
  425. Categories = "Open",
  426. Title = "To Do"
  427. });
  428. Kanban.Columns.Add(new KanbanColumn
  429. {
  430. Categories = "In Progress",
  431. Title = "In Progress"
  432. });
  433. Kanban.Columns.Add(new KanbanColumn
  434. {
  435. Categories = "Waiting",
  436. Title = "Waiting for Others"
  437. });
  438. if (Host.Settings.StatusSettings.IncludeCompleted)
  439. Kanban.Columns.Add(new KanbanColumn
  440. {
  441. Categories = "Complete",
  442. Title = "Completed"
  443. });
  444. Kanban.InvalidateVisual();
  445. foreach (var column in Kanban.Columns)
  446. {
  447. var menu = new ContextMenu();
  448. menu.Tag = column;
  449. var item = new MenuItem { Header = "New Task" };
  450. item.Click += CreateTask;
  451. menu.Items.Add(item);
  452. menu.Items.Add(new Separator());
  453. item = new MenuItem { Header = "Select All " + column.Title + " Tasks", Tag = column };
  454. item.Click += SelectAll_Click;
  455. menu.Items.Add(item);
  456. item = new MenuItem { Header = "Unselect All " + column.Title + " Tasks", Tag = column };
  457. item.Click += UnSelectAll_Click;
  458. menu.Items.Add(item);
  459. column.ContextMenu = menu;
  460. }
  461. Kanban.ColumnWidth = Kanban.ActualWidth / Kanban.Columns.Count - 1.0F;
  462. }
  463. private void SetupData()
  464. {
  465. var query = new MultiQuery();
  466. query.Add(
  467. null,
  468. new Columns<Employee>(x => x.ID, x => x.Name, x => x.Thumbnail.ID, x => x.CanAllocateTasks, x => x.Email, x => x.Mobile,
  469. x => x.FinishDate, x => x.UserLink.ID),
  470. new SortOrder<Employee>(x => x.Name)
  471. );
  472. if (ClientFactory.IsSupported<KanbanType>())
  473. query.Add(
  474. new Filter<KanbanType>(x => x.Hidden).IsEqualTo(false),
  475. new Columns<KanbanType>(x => x.ID, x => x.Description),
  476. new SortOrder<KanbanType>(x => x.Description)
  477. );
  478. query.Query();
  479. _employees = query.Get<Employee>();
  480. _types = ClientFactory.IsSupported<KanbanType>()
  481. ? query.Get<KanbanType>()
  482. : null;
  483. }
  484. #endregion
  485. #region Refresh / Reload
  486. private Filter<T> GetSearchFilter<T>(Expression<Func<T, object>> expression) where T : Entity, new()
  487. {
  488. Filter<T> result = null;
  489. var comps = searchtext.Trim().Split(' ');
  490. foreach (var comp in comps)
  491. result = result == null ? new Filter<T>(expression).Contains(comp) : result.And(expression).Contains(comp);
  492. return result;
  493. }
  494. private Filter<KanbanSubscriber> GetKanbanSubscriberFilter()
  495. {
  496. var filter = new Filter<KanbanSubscriber>(x => x.Kanban.Closed).IsEqualTo(DateTime.MinValue);
  497. if (Host.JobID != Guid.Empty)
  498. filter = filter.And(x => x.Kanban.JobLink.ID).IsEqualTo(Host.JobID);
  499. // All Tasks (EmployeeID.HasValue == false) or Unallocated (EmployeeID = Guid.Empty) are retrieved directly from the Kanban Table
  500. // so if we are here, we can assume that we are pulling subscriber data
  501. var empfilter = new Filter<KanbanSubscriber>(x => x.Employee.ID).IsEqualTo(EmployeeID);
  502. filter.Ands.Add(empfilter);
  503. if (EmployeeID != MyID)
  504. filter = filter.And(x => x.Kanban.Private).IsEqualTo(false);
  505. //if (!includeobserved)
  506. // filter = filter.And(new Filter<KanbanSubscriber>(x => x.Assignee).IsEqualTo(true).Or(x => x.Manager).IsEqualTo(true));
  507. //if (!includecompleted)
  508. // filter = filter.And(x => x.Kanban.Completed).IsEqualTo(DateTime.MinValue);
  509. //if (selectedtype != CoreUtils.FullGuid)
  510. // filter = filter.And(x => x.Kanban.Type.ID).IsEqualTo(selectedtype);
  511. if (!string.IsNullOrWhiteSpace(searchtext))
  512. {
  513. var search = GetSearchFilter<KanbanSubscriber>(x => x.Kanban.JobLink.Name);
  514. search.Ors.Add(GetSearchFilter<KanbanSubscriber>(x => x.Kanban.JobLink.JobNumber));
  515. search.Ors.Add(GetSearchFilter<KanbanSubscriber>(x => x.Kanban.Summary));
  516. search.Ors.Add(GetSearchFilter<KanbanSubscriber>(x => x.Kanban.Title));
  517. search.Ors.Add(GetSearchFilter<KanbanSubscriber>(x => x.Kanban.ManagerLink.Name));
  518. search.Ors.Add(GetSearchFilter<KanbanSubscriber>(x => x.Kanban.EmployeeLink.Name));
  519. if (int.TryParse(searchtext.Trim(), out var tasknumber))
  520. search.Ors.Add(new Filter<KanbanSubscriber>(x => x.Kanban.Number).IsEqualTo(tasknumber));
  521. filter.Ands.Add(search);
  522. }
  523. return filter;
  524. }
  525. private Filter<Kanban> GetKanbanFilter()
  526. {
  527. var filter = new Filter<Kanban>(x => x.Closed).IsEqualTo(DateTime.MinValue);
  528. if (Host.JobID != Guid.Empty)
  529. filter = filter.And(x => x.JobLink.ID).IsEqualTo(Host.JobID);
  530. if (EmployeeID != CoreUtils.FullGuid)
  531. {
  532. if (EmployeeID != Guid.Empty)
  533. {
  534. var empfilter = new Filter<Kanban>(x => x.EmployeeLink.ID).IsEqualTo(EmployeeID).Or(x => x.ManagerLink.ID).IsEqualTo(EmployeeID);
  535. filter.Ands.Add(empfilter);
  536. }
  537. else
  538. {
  539. filter = filter.And(x => x.EmployeeLink.ID).IsEqualTo(EmployeeID);
  540. }
  541. }
  542. if (EmployeeID != MyID)
  543. filter = filter.And(x => x.Private).IsEqualTo(false);
  544. //if (!includecompleted)
  545. // filter = filter.And(x => x.Completed).IsEqualTo(DateTime.MinValue);
  546. //if (selectedtype != CoreUtils.FullGuid)
  547. // filter = filter.And(x => x.Type.ID).IsEqualTo(selectedtype);
  548. return filter;
  549. }
  550. public void Refresh(bool resetselection)
  551. {
  552. Application.Current.Dispatcher.Invoke(() => { Mouse.OverrideCursor = Cursors.Wait; });
  553. if (EmployeeID != CoreUtils.FullGuid && EmployeeID != Guid.Empty)
  554. {
  555. _kanbans = new Client<KanbanSubscriber>().Query(
  556. GetKanbanSubscriberFilter(),
  557. new Columns<KanbanSubscriber>
  558. (
  559. x => x.Kanban.ID,
  560. x => x.Kanban.DueDate,
  561. x => x.Kanban.Completed,
  562. //x => x.Kanban.Description,
  563. x => x.Kanban.Summary,
  564. x => x.Kanban.Category,
  565. x => x.Kanban.EmployeeLink.ID,
  566. x => x.Kanban.ManagerLink.ID,
  567. x => x.Kanban.Notes,
  568. x => x.Kanban.Title,
  569. x => x.Kanban.JobLink.ID,
  570. x => x.Kanban.JobLink.JobNumber,
  571. x => x.Kanban.JobLink.Name,
  572. x => x.Kanban.Type.ID,
  573. x => x.Kanban.Type.Code,
  574. x => x.Kanban.Number,
  575. x => x.Kanban.Attachments,
  576. x => x.Kanban.Locked
  577. ),
  578. new SortOrder<KanbanSubscriber>(x => x.Kanban.DueDate) { Direction = SortDirection.Ascending }
  579. );
  580. foreach (var column in _kanbans.Columns)
  581. column.ColumnName = column.ColumnName.Replace("Kanban.", "");
  582. }
  583. else
  584. {
  585. _kanbans = new Client<Kanban>().Query(
  586. GetKanbanFilter(),
  587. new Columns<Kanban>
  588. (
  589. x => x.ID,
  590. x => x.DueDate,
  591. x => x.Completed,
  592. //x => x.Description,
  593. x => x.Summary,
  594. x => x.Category,
  595. x => x.EmployeeLink.ID,
  596. x => x.ManagerLink.ID,
  597. x => x.Notes,
  598. x => x.Title,
  599. x => x.JobLink.ID,
  600. x => x.JobLink.JobNumber,
  601. x => x.JobLink.Name,
  602. x => x.Type.ID,
  603. x => x.Type.Code,
  604. x => x.Number,
  605. x => x.Attachments,
  606. x => x.Locked
  607. ),
  608. new SortOrder<Kanban>(x => x.DueDate) { Direction = SortDirection.Ascending }
  609. );
  610. }
  611. ReloadKanbans();
  612. Application.Current.Dispatcher.Invoke(() => { Mouse.OverrideCursor = null; });
  613. }
  614. private void ReloadKanbans()
  615. {
  616. //SetupColumns();
  617. //ResizeColumns();
  618. _models = new ObservableCollection<TaskModel>();
  619. foreach (var row in _kanbans.Rows)
  620. try
  621. {
  622. var empid = row.Get<IKanban, Guid>(e => e.EmployeeLink.ID);
  623. var mgrid = row.EntityLinkID<IKanban, EmployeeLink>(x => x.ManagerLink) ?? Guid.Empty;
  624. var completed = row.Get<IKanban, DateTime>(e => e.Completed);
  625. var locked = row.Get<IKanban, bool>(e => e.Locked);
  626. var type = row.Get<IKanban, Guid>(e => e.Type.ID);
  627. var category = row.Get<IKanban, string>(x => x.Category);
  628. if (string.IsNullOrWhiteSpace(category))
  629. category = "Open";
  630. var bLockedOK = Host.Settings.StatusSettings.IncludeLocked || locked == false;
  631. var bObserveOK = EmployeeID == CoreUtils.FullGuid || Host.Settings.StatusSettings.IncludeObserved || empid == EmployeeID || mgrid == EmployeeID;
  632. var bCompleteOK = Host.Settings.StatusSettings.IncludeCompleted || completed.IsEmpty();
  633. var bTypeOK = selectedtype == CoreUtils.FullGuid || type == selectedtype;
  634. if (bLockedOK && bCompleteOK && bObserveOK && bTypeOK)
  635. {
  636. var model = new TaskModel();
  637. var EmployeeEntry = _employeelist.Where(x => x.ID.Equals(empid)).FirstOrDefault();
  638. var empimg = EmployeeEntry?.Image;
  639. var ManagerEntry = _employeelist.Where(x => x.ID.Equals(mgrid)).FirstOrDefault();
  640. //var description = row.Get<IKanban, String>(x => x.Summary);
  641. //if (String.IsNullOrWhiteSpace(description))
  642. // description = String.Join("\r\n", row.Get<IKanban, String[]>(x => x.Notes)).Split(new String[] { "===============" }, StringSplitOptions.RemoveEmptyEntries).FirstOrDefault();
  643. //if (String.IsNullOrWhiteSpace(description))
  644. // description = CoreUtils.StripHTML(row.Get<IKanban, String>(x => x.Description));
  645. //if (String.IsNullOrWhiteSpace(description))
  646. // description = "";
  647. var job = row.Get<IKanban, string>(x => x.JobLink.JobNumber);
  648. model.Title = row.Get<IKanban, string>(x => x.Title);
  649. model.ID = row.Get<IKanban, Guid>(x => x.ID).ToString();
  650. model.Description = row.Get<IKanban, string>(x => x.Summary) ?? "";
  651. model.Category = category;
  652. var color = EmployeeID == Guid.Empty || empid == EmployeeID || EmployeeID == CoreUtils.FullGuid
  653. ? TaskModel.KanbanColor(
  654. row.Get<IKanban, DateTime>(x => x.DueDate),
  655. row.Get<IKanban, DateTime>(x => x.Completed))
  656. : mgrid == EmployeeID
  657. ? Color.Silver
  658. : Color.Plum;
  659. if (row.Get<IKanban, bool>(x => x.Locked))
  660. color = color.MixColors(0.5F, Color.White);
  661. model.ColorKey = ImageUtils.ColorToString(color);
  662. model.Image = empimg;
  663. model.ImageURL = null;
  664. model.Attachments = row.Get<IKanban, int>(x => x.Attachments) > 0; // ? _attachimg : null;
  665. model.DueDate = row.Get<IKanban, DateTime>(x => x.DueDate);
  666. model.CompletedDate = row.Get<IKanban, DateTime>(x => x.Completed);
  667. model.Locked = row.Get<IKanban, bool>(x => x.Locked); // ? _lockimg : null;
  668. var notes = new List<List<string>> { new() };
  669. foreach (var line in row.Get<IKanban, string[]>(x => x.Notes))
  670. {
  671. if (line == "===================================")
  672. {
  673. notes.Add(new());
  674. }
  675. else
  676. {
  677. notes.Last().Add(line);
  678. }
  679. }
  680. model.Notes = string.Join("\n===================================\n", notes.Reverse<List<string>>().Select(x => string.Join('\n', x)));
  681. model.EmployeeID = empid;
  682. model.ManagerID = mgrid;
  683. var sEmp = "";
  684. if (empid != EmployeeID)
  685. {
  686. if (!Entity.IsEntityLinkValid<IKanban, EmployeeLink>(x => x.EmployeeLink, row))
  687. {
  688. sEmp = "Unallocated";
  689. }
  690. else
  691. {
  692. var tuple = _employeelist.FirstOrDefault(x => x.ID.Equals(empid));
  693. sEmp = tuple != null ? tuple.ID == MyID ? MyName : tuple.Name : "";
  694. }
  695. }
  696. var sMgr = "";
  697. if (mgrid != EmployeeID)
  698. if (mgrid != Guid.Empty)
  699. {
  700. var tuple = _employeelist.FirstOrDefault(x => x.ID.Equals(mgrid));
  701. sMgr = tuple != null ? tuple.ID == MyID ? MyName : tuple.Name : "";
  702. }
  703. if (!string.IsNullOrEmpty(sEmp))
  704. {
  705. if (!string.IsNullOrWhiteSpace(sMgr) && !string.Equals(sMgr, sEmp))
  706. model.AssignedTo = string.Format("Assigned to {0} by {1}", sEmp, sMgr);
  707. else
  708. model.AssignedTo = string.Format("Assigned to {0} ", sEmp);
  709. }
  710. else
  711. {
  712. if (!string.IsNullOrWhiteSpace(sMgr))
  713. model.AssignedTo = string.Format("Allocated by {0} ", sMgr);
  714. }
  715. //model.AssignedTo = String.Format("M: {0} / E: {1}", sMgr, sEmp);
  716. model.JobID = row.Get<IKanban, Guid>(x => x.JobLink.ID);
  717. model.JobNumber = row.Get<IKanban, string>(x => x.JobLink.JobNumber);
  718. if (string.IsNullOrWhiteSpace(model.JobNumber))
  719. model.JobNumber = "";
  720. model.JobName = row.Get<IKanban, string>(x => x.JobLink.Name);
  721. model.Checked = CheckedKanbans.Contains(row.Get<IKanban, Guid>(x => x.ID).ToString());
  722. model.Type = new KanbanType
  723. {
  724. ID = row.Get<IKanban, Guid>(x => x.Type.ID),
  725. Code = row.Get<IKanban, string>(x => x.Type.Code)
  726. };
  727. model.Number = row.Get<IKanban, int>(x => x.Number);
  728. _models.Add(model);
  729. }
  730. }
  731. catch (Exception e)
  732. {
  733. Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
  734. }
  735. StatusTasksHeaderTimeConverter.Tasks = _models;
  736. FilterKanbans();
  737. }
  738. private void FilterKanbans()
  739. {
  740. Kanban.ItemsSource = _models
  741. .Where(x => x.Search(Search.Text.Split()))
  742. .OrderBy(x => x.EmployeeID == EmployeeID ? 0 : 1).ThenBy(x => x.DueDate);
  743. ;
  744. }
  745. #endregion
  746. #region Kanban Selection Stuff
  747. private void SelectColumn(KanbanColumn column, bool selected)
  748. {
  749. CheckedKanbans.Clear();
  750. if (selected)
  751. {
  752. CheckedKanbans.AddRange(_models.Where(x => Equals(x.Category, column.Categories)).Select(x => x.ID));
  753. foreach (var model in _models)
  754. model.Checked = Equals(model.Category, column.Categories);
  755. }
  756. FilterKanbans();
  757. }
  758. private void UnSelectAll_Click(object sender, RoutedEventArgs e)
  759. {
  760. var column = ((MenuItem)sender).Tag as KanbanColumn;
  761. SelectColumn(column, false);
  762. }
  763. private void SelectAll_Click(object sender, RoutedEventArgs e)
  764. {
  765. var column = ((MenuItem)sender).Tag as KanbanColumn;
  766. SelectColumn(column, true);
  767. }
  768. //private IEnumerable<Guid> GetSelectedKanbanIDs(String currentid)
  769. //{
  770. // List<Guid> result = new List<Guid>();
  771. // if (!CheckedKanbans.Contains(currentid))
  772. // result.Add(Guid.Parse(currentid));
  773. // CheckedKanbans.ForEach((id) => result.Add(Guid.Parse(id)));
  774. // return result;
  775. //}
  776. //private Kanban[] GetSelectedKanbans(String currentid)
  777. //{
  778. // var ids = GetSelectedKanbanIDs(currentid);
  779. // return Host.LoadKanbans(ids).ToArray();
  780. //}
  781. private void CheckBox_Checked(object sender, RoutedEventArgs e)
  782. {
  783. var task = ((CheckBox)sender).Tag as TaskModel;
  784. if (task == null)
  785. return;
  786. if (CheckedKanbans.Contains(task.ID))
  787. CheckedKanbans.Remove(task.ID);
  788. else
  789. CheckedKanbans.Add(task.ID);
  790. }
  791. #endregion
  792. #region Context Menu Actions
  793. private void CreateTask(object sender, RoutedEventArgs e)
  794. {
  795. CreateKanban();
  796. }
  797. private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
  798. {
  799. if (e.ClickCount > 1)
  800. {
  801. var task = ((Border)sender).Tag as TaskModel;
  802. DoEdit(task);
  803. e.Handled = true;
  804. }
  805. }
  806. private void EditTask_Click(object sender, RoutedEventArgs e)
  807. {
  808. var task = ((MenuItem)e.Source).Tag as TaskModel;
  809. DoEdit(task);
  810. e.Handled = true;
  811. }
  812. //private void CreateSetout_Click(object sender, RoutedEventArgs e)
  813. //{
  814. // MenuItem menu = sender as MenuItem;
  815. // TaskModel task = menu.Tag as TaskModel;
  816. // if (task.JobID.Equals(Guid.Empty))
  817. // {
  818. // MessageBox.Show("Please link this task to a job before creating a setout!");
  819. // return;
  820. // }
  821. // if (MessageBox.Show("This will convert this task into a Setout.\n\nDo you wish to continue?", "Confirmation", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
  822. // return;
  823. // ManufacturingTemplate template = new Client<ManufacturingTemplate>().Load(new Filter<ManufacturingTemplate>(x => x.Code).IsEqualTo("PRS")).FirstOrDefault();
  824. // if (template == null)
  825. // {
  826. // MessageBox.Show("[Pressing] Template does not exist!");
  827. // return;
  828. // }
  829. // String setoutnumber = "";
  830. // Progress.ShowModal("Creating Setout", (progress) =>
  831. // {
  832. // MultiQuery query = new MultiQuery();
  833. // query.Add<ManufacturingTemplateStage>(
  834. // new Filter<ManufacturingTemplateStage>(x => x.Template.ID).IsEqualTo(template.ID),
  835. // null,
  836. // new SortOrder<ManufacturingTemplateStage>(x => x.Sequence)
  837. // );
  838. // query.Add<Kanban>(
  839. // new Filter<Kanban>(x => x.ID).IsEqualTo(task.ID),
  840. // null,
  841. // null
  842. // );
  843. // query.Query();
  844. // ManufacturingTemplateStage[] tstages = query.Get<ManufacturingTemplateStage>().Rows.Select(x => x.ToObject<ManufacturingTemplateStage>()).ToArray();
  845. // Kanban kanban = query.Get<Kanban>().Rows.FirstOrDefault()?.ToObject<Kanban>();
  846. // progress.Report("Creating Setouts");
  847. // CoreTable setouts = new Client<Setout>().Query(
  848. // new Filter<Setout>(x => x.JobLink.ID).IsEqualTo(kanban.JobLink.ID),
  849. // new Columns<Setout>(x => x.JobLink.JobNumber, x => x.Number),
  850. // null
  851. // );
  852. // int ireq = 0;
  853. // String sreq = "";
  854. // while (true)
  855. // {
  856. // ireq++;
  857. // sreq = String.Format("{0}-{1:yyMMdd}-{2}", kanban.JobLink.JobNumber, DateTime.Now, ireq);
  858. // if (!setouts.Rows.Any(r => sreq.Equals(r.Get<Setout, String>(c => c.Number))))
  859. // break;
  860. // }
  861. // Setout setout = new Setout();
  862. // setout.Number = sreq;
  863. // setout.JobLink.ID = kanban.JobLink.ID; // = new Client<Job>().Load(new Filter<Job>(x => x.ID).IsEqualTo(kanban.JobLink.ID)).FirstOrDefault();
  864. // setout.Reference = kanban.Title;
  865. // var notes = kanban.Notes.ToList();
  866. // var description = kanban.Summary;
  867. // if (String.IsNullOrWhiteSpace(description))
  868. // description = CoreUtils.StripHTML(kanban.Description);
  869. // if (!String.IsNullOrWhiteSpace(description))
  870. // notes.Insert(0, description);
  871. // setout.Description = String.Join("\n==========================================\n", notes);
  872. // new Client<Setout>().Save(setout, "Created from Task");
  873. // setoutnumber = setout.Number;
  874. // progress.Report("Creating Manufacturing Packet");
  875. // ManufacturingPacket packet = new ManufacturingPacket()
  876. // {
  877. // Group = template.Factory.Name,
  878. // Serial = template.Code,
  879. // Title = kanban.Title,
  880. // Quantity = 1,
  881. // BarcodeQty = 1,
  882. // DueDate = kanban.DueDate
  883. // };
  884. // packet.SetoutLink.ID = setout.ID;
  885. // //packet.JobLink.ID = setout.JobLink.ID;
  886. // packet.ManufacturingTemplateLink.ID = template.ID;
  887. // packet.ManufacturingTemplateLink.Code = template.Code;
  888. // new Client<ManufacturingPacket>().Save(packet, "Created from Task");
  889. // List<ManufacturingPacketStage> pstages = new List<ManufacturingPacketStage>();
  890. // foreach (var tstage in tstages)
  891. // {
  892. // var pstage = new ManufacturingPacketStage()
  893. // {
  894. // Time = tstage.Time,
  895. // Sequence = tstage.Sequence,
  896. // SequenceType = tstage.SequenceType,
  897. // Started = DateTime.MinValue,
  898. // PercentageComplete = 0.0F,
  899. // Completed = DateTime.MinValue,
  900. // QualityChecks = tstage.QualityChecks,
  901. // QualityStatus = QualityStatus.NotChecked,
  902. // QualityNotes = "",
  903. // };
  904. // pstage.Parent.ID = packet.ID;
  905. // pstage.ManufacturingSectionLink.ID = tstage.Section.ID;
  906. // pstage.ManufacturingSectionLink.Name = tstage.Section.Name;
  907. // pstages.Add(pstage);
  908. // }
  909. // new Client<ManufacturingPacketStage>().Save(pstages, "Created from Task", (_, __) => { });
  910. // progress.Report("Processing Documents");
  911. // List<SetoutDocument> _setoutdocuments = new List<SetoutDocument>();
  912. // List<KanbanDocument> _kanbandocuments = new List<KanbanDocument>();
  913. // KanbanDocument[] docrefs = new Client<KanbanDocument>().Load(new Filter<KanbanDocument>(x => x.EntityLink.ID).IsEqualTo(kanban.ID));
  914. // foreach (var docref in docrefs)
  915. // {
  916. // Guid docid = ProcessSetoutDocument(docref);
  917. // var newdoc = new SetoutDocument();
  918. // newdoc.EntityLink.ID = setout.ID;
  919. // newdoc.DocumentLink.ID = docid;
  920. // _setoutdocuments.Add(newdoc);
  921. // if (docid != docref.DocumentLink.ID)
  922. // {
  923. // docref.DocumentLink.ID = docid;
  924. // _kanbandocuments.Add(docref);
  925. // }
  926. // }
  927. // new Client<SetoutDocument>().Save(_setoutdocuments, "Converted from Task", (_, __) => { });
  928. // new Client<KanbanDocument>().Save(_kanbandocuments, "Converted to PDF", (_, __) => { });
  929. // SetoutKanban link = new SetoutKanban();
  930. // link.Entity.ID = setout.ID;
  931. // link.Kanban.ID = kanban.ID;
  932. // new Client<SetoutKanban>().Save(link, "Converting Task -> Setout", (_, __) => { });
  933. // progress.Report("Updating Task");
  934. // kanban.Title = kanban.Title + " (" + setoutnumber + ")";
  935. // kanban.Locked = true;
  936. // new Client<Kanban>().Save(kanban, "Converting Kanban to Setout");
  937. // });
  938. // MessageBox.Show(String.Format("Created Setout {0}", setoutnumber));
  939. // Refresh();
  940. //}
  941. //private Guid ProcessSetoutDocument(KanbanDocument docref)
  942. //{
  943. // Guid result = docref.DocumentLink.ID;
  944. // String ext = System.IO.Path.GetExtension(docref.DocumentLink.FileName).ToLower();
  945. // if (ext.EndsWith("txt"))
  946. // {
  947. // var doc = new Client<Document>().Load(new Filter<Document>(x => x.ID).IsEqualTo(docref.DocumentLink.ID)).FirstOrDefault();
  948. // PdfDocument pdf = new PdfDocument();
  949. // PdfPage page = pdf.Pages.Add();
  950. // PdfGraphics graphics = page.Graphics;
  951. // PdfFont font = new PdfStandardFont(PdfFontFamily.Courier, 12);
  952. // String text = System.Text.Encoding.UTF8.GetString(doc.Data);
  953. // graphics.DrawString(text, font, PdfBrushes.Black, new PointF(0, 0));
  954. // MemoryStream ms = new MemoryStream();
  955. // pdf.Save(ms);
  956. // pdf.Close(true);
  957. // byte[] data = ms.ToArray();
  958. // var newdoc = new Document()
  959. // {
  960. // Data = data,
  961. // FileName = System.IO.Path.ChangeExtension(docref.DocumentLink.FileName, "pdf"),
  962. // CRC = CoreUtils.CalculateCRC(data),
  963. // TimeStamp = DateTime.Now,
  964. // };
  965. // new Client<Document>().Save(newdoc, "Converted from Text");
  966. // return newdoc.ID;
  967. // }
  968. // else if (ext.EndsWith("png") || ext.EndsWith("bmp") || ext.EndsWith("jpg") || ext.EndsWith("jpeg"))
  969. // {
  970. // var doc = new Client<Document>().Load(new Filter<Document>(x => x.ID).IsEqualTo(docref.DocumentLink.ID)).FirstOrDefault();
  971. // PdfBitmap image = new PdfBitmap(new MemoryStream(doc.Data));
  972. // PdfDocument pdf = new PdfDocument();
  973. // pdf.PageSettings.Orientation = image.Height > image.Width ? PdfPageOrientation.Portrait : PdfPageOrientation.Landscape;
  974. // pdf.PageSettings.Size = new SizeF(image.Width, image.Height);
  975. // PdfPage page = pdf.Pages.Add();
  976. // PdfGraphics graphics = page.Graphics;
  977. // graphics.DrawImage(image, 0.0F, 0.0F);
  978. // MemoryStream ms = new MemoryStream();
  979. // pdf.Save(ms);
  980. // pdf.Close(true);
  981. // byte[] data = ms.ToArray();
  982. // var newdoc = new Document()
  983. // {
  984. // Data = data,
  985. // FileName = System.IO.Path.ChangeExtension(docref.DocumentLink.FileName, "pdf"),
  986. // CRC = CoreUtils.CalculateCRC(data),
  987. // TimeStamp = DateTime.Now,
  988. // };
  989. // new Client<Document>().Save(newdoc, "Converted from Image");
  990. // return newdoc.ID;
  991. // }
  992. // return result;
  993. //}
  994. //private void CreateRequisition_Click(object sender, RoutedEventArgs e)
  995. //{
  996. // MenuItem menu = sender as MenuItem;
  997. // TaskModel task = menu.Tag as TaskModel;
  998. // if (task.JobID.Equals(Guid.Empty))
  999. // {
  1000. // MessageBox.Show("Please link this task to a job before creating a requisition!");
  1001. // return;
  1002. // }
  1003. // if (MessageBox.Show("This will convert this task into a Requisition.\n\nDo you wish to continue?", "Confirmation", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
  1004. // return;
  1005. // int requinumber = 0;
  1006. // Progress.ShowModal("Creating Requisition", (progress) =>
  1007. // {
  1008. // Kanban kanban = new Client<Kanban>().Load(new Filter<Kanban>(x => x.ID).IsEqualTo(task.ID)).FirstOrDefault();
  1009. // Requisition requi = new Requisition();
  1010. // requi.JobLink.ID = kanban.JobLink.ID;
  1011. // requi.RequestedBy.ID = kanban.ManagerLink.ID;
  1012. // requi.Employee.ID = Guid.Empty;
  1013. // requi.Title = kanban.Title;
  1014. // requi.Request = String.IsNullOrWhiteSpace(kanban.Summary)
  1015. // ? String.IsNullOrWhiteSpace(kanban.Summary)
  1016. // ? String.Join("\n", kanban.Notes)
  1017. // : CoreUtils.StripHTML(kanban.Description)
  1018. // : kanban.Summary;
  1019. // requi.Notes = kanban.Notes;
  1020. // requi.Due = kanban.DueDate;
  1021. // new Client<Requisition>().Save(requi, "Created from Task");
  1022. // requinumber = requi.Number;
  1023. // progress.Report("Updating Documents");
  1024. // List<RequisitionDocument> _documents = new List<RequisitionDocument>();
  1025. // KanbanDocument[] documents = new Client<KanbanDocument>().Load(new Filter<KanbanDocument>(x => x.EntityLink.ID).IsEqualTo(kanban.ID));
  1026. // foreach (var document in documents)
  1027. // {
  1028. // var newdoc = new RequisitionDocument();
  1029. // newdoc.EntityLink.ID = requi.ID;
  1030. // newdoc.DocumentLink.ID = document.DocumentLink.ID;
  1031. // _documents.Add(newdoc);
  1032. // }
  1033. // new Client<RequisitionDocument>().Save(_documents, "Converted from Task", (_, __) => { });
  1034. // RequisitionKanban link = new RequisitionKanban();
  1035. // link.Entity.ID = requi.ID;
  1036. // link.Kanban.ID = kanban.ID;
  1037. // new Client<RequisitionKanban>().Save(link, "Converting Task -> Requisition", (_, __) => { });
  1038. // progress.Report("Updating Task");
  1039. // kanban.Category = "Open";
  1040. // kanban.Completed = DateTime.MinValue;
  1041. // kanban.Locked = true;
  1042. // kanban.Title = kanban.Title + " (Requi #" + requi.Number.ToString() + ")";
  1043. // new Client<Kanban>().Save(kanban, "Converted to Requisition", (_, __) => { });
  1044. // });
  1045. // MessageBox.Show(String.Format("Created Requisition {0}", requinumber));
  1046. // Refresh();
  1047. //}
  1048. //private void CreatePurchaseOrder_Click(object sender, RoutedEventArgs e)
  1049. //{
  1050. // MenuItem menu = sender as MenuItem;
  1051. // TaskModel task = menu.Tag as TaskModel;
  1052. // if (MessageBox.Show("This will convert this task into a Purchase Order.\n\nDo you wish to continue?", "Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes)
  1053. // {
  1054. // String ponumber = "";
  1055. // Progress.ShowModal("Creating Purchase Order", (progress) =>
  1056. // {
  1057. // Kanban kanban = new Client<Kanban>().Load(new Filter<Kanban>(x => x.ID).IsEqualTo(task.ID)).FirstOrDefault();
  1058. // PurchaseOrder order = new PurchaseOrder();
  1059. // order.Notes = kanban.Summary;
  1060. // order.RaisedBy.ID = kanban.EmployeeLink.ID;
  1061. // new Client<PurchaseOrder>().Save(order, "Created from Task Screen");
  1062. // ponumber = order.PONumber;
  1063. // progress.Report("Updating Documents");
  1064. // List<PurchaseOrderDocument> docs = new List<PurchaseOrderDocument>();
  1065. // var taskdocs = new Client<KanbanDocument>().Load(new Filter<KanbanDocument>(x => x.EntityLink.ID).IsEqualTo(Guid.Parse(task.ID)));
  1066. // foreach (var taskdoc in taskdocs)
  1067. // {
  1068. // PurchaseOrderDocument doc = new PurchaseOrderDocument();
  1069. // doc.DocumentLink.ID = taskdoc.DocumentLink.ID;
  1070. // doc.EntityLink.ID = order.ID;
  1071. // docs.Add(doc);
  1072. // }
  1073. // new Client<PurchaseOrderDocument>().Save(docs, "", (_, __) => { });
  1074. // progress.Report("Creating Links");
  1075. // PurchaseOrderKanban link = new PurchaseOrderKanban();
  1076. // link.Entity.ID = order.ID;
  1077. // link.Kanban.ID = kanban.ID;
  1078. // new Client<PurchaseOrderKanban>().Save(link, "Converting Task -> Purchase Order", (_, __) => { });
  1079. // progress.Report("Updating Task");
  1080. // kanban.Category = "Open";
  1081. // kanban.Completed = DateTime.MinValue;
  1082. // kanban.Locked = true;
  1083. // kanban.Title = "(PO#" + order.PONumber.ToString() + ") " + kanban.Title;
  1084. // new Client<Kanban>().Save(kanban, "Converted to Purchase Order", (_, __) => { });
  1085. // });
  1086. // MessageBox.Show(String.Format("Created Purchase Order {0}", ponumber));
  1087. // Refresh();
  1088. // }
  1089. //}
  1090. //private void CreateDelivery_Click(object sender, RoutedEventArgs e)
  1091. //{
  1092. // MenuItem menu = sender as MenuItem;
  1093. // TaskModel task = menu.Tag as TaskModel;
  1094. // if (MessageBox.Show("This will convert this task into a Delivery.\n\nDo you wish to continue?", "Confirmation", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
  1095. // return;
  1096. // int deliverynumber = 0;
  1097. // Progress.ShowModal("Creating Delivery", (progress) =>
  1098. // {
  1099. // Kanban kanban = new Client<Kanban>().Query(new Filter<Kanban>(x => x.ID).IsEqualTo(task.ID)).Rows.FirstOrDefault()?.ToObject<Kanban>();
  1100. // Delivery delivery = new Delivery();
  1101. // delivery.Due = kanban.DueDate;
  1102. // delivery.Job.ID = kanban.JobLink.ID;
  1103. // delivery.Job.Synchronise(kanban.JobLink);
  1104. // delivery.Notes = kanban.Summary;
  1105. // delivery.Employee.ID = kanban.ManagerLink.ID;
  1106. // delivery.Employee.Synchronise(kanban.ManagerLink);
  1107. // new Client<Delivery>().Save(delivery, "Created From Task");
  1108. // deliverynumber = delivery.Number;
  1109. // progress.Report("Updating Documents");
  1110. // List<DeliveryDocument> docs = new List<DeliveryDocument>();
  1111. // var taskdocs = new Client<KanbanDocument>().Load(new Filter<KanbanDocument>(x => x.EntityLink.ID).IsEqualTo(Guid.Parse(task.ID)));
  1112. // foreach (var taskdoc in taskdocs)
  1113. // {
  1114. // DeliveryDocument doc = new DeliveryDocument();
  1115. // doc.DocumentLink.ID = taskdoc.DocumentLink.ID;
  1116. // doc.EntityLink.ID = delivery.ID;
  1117. // docs.Add(doc);
  1118. // }
  1119. // new Client<DeliveryDocument>().Save(docs, "", (_, __) => { });
  1120. // progress.Report("Creating Links");
  1121. // DeliveryKanban link = new DeliveryKanban();
  1122. // link.Entity.ID = delivery.ID;
  1123. // link.Kanban.ID = kanban.ID;
  1124. // new Client<DeliveryKanban>().Save(link, "Converting Task -> Delivery", (_, __) => { });
  1125. // progress.Report("Updating Task");
  1126. // kanban.Category = "Open";
  1127. // kanban.Completed = DateTime.MinValue;
  1128. // kanban.Locked = true;
  1129. // kanban.Title = "(Del#" + delivery.Number.ToString() + ") " + kanban.Title;
  1130. // new Client<Kanban>().Save(kanban, "Converted to Delivery", (_, __) => { });
  1131. // });
  1132. // MessageBox.Show(String.Format("Created Delivery {0}", deliverynumber));
  1133. // Refresh();
  1134. //}
  1135. //private void CloseTask_Click(object sender, RoutedEventArgs e)
  1136. //{
  1137. // if (MessageBox.Show("Are you sure you want to remove the selected tasks from the list?", "Confirm removal", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
  1138. // return;
  1139. // Progress.ShowModal("Closing Kanbans", (progress) =>
  1140. // {
  1141. // TaskModel task = ((MenuItem)e.Source).Tag as TaskModel;
  1142. // Kanban[] kanbans = GetSelectedKanbans(task.ID);
  1143. // for (int i = 0; i < kanbans.Length; i++)
  1144. // {
  1145. // Kanban kanban = kanbans[i];
  1146. // kanban.Closed = DateTime.Now;
  1147. // }
  1148. // new Client<Kanban>().Save(kanbans, "Kanban Marked as Closed");
  1149. // CheckedKanbans.Clear();
  1150. // });
  1151. // Refresh();
  1152. //}
  1153. //private void EmailTask_Click(object sender, RoutedEventArgs e)
  1154. //{
  1155. // MenuItem menu = sender as MenuItem;
  1156. // TaskModel task = menu.Tag as TaskModel;
  1157. // Kanban kanban = new Client<Kanban>().Load(new Filter<Kanban>(x => x.ID).IsEqualTo(task.ID)).FirstOrDefault();
  1158. // List<String> to = new List<string>();
  1159. // String from = "";
  1160. // String salutation = "";
  1161. // if (MyID.HasValue)
  1162. // {
  1163. // CoreRow me = _employees.Rows.FirstOrDefault(r => r.Get<Employee, Guid>(c => c.ID).Equals(MyID));
  1164. // if (me != null)
  1165. // from = me.Get<Employee, String>(c => c.Name).Split(' ').FirstOrDefault();
  1166. // if (kanban.EmployeeLink.ID != MyID.Value)
  1167. // {
  1168. // CoreRow emp = _employees.Rows.FirstOrDefault(r => r.Get<Employee, Guid>(c => c.ID).Equals(kanban.EmployeeLink.ID));
  1169. // if (emp != null)
  1170. // {
  1171. // String email = emp.Get<Employee, String>(c => c.Email);
  1172. // if (!string.IsNullOrEmpty(email))
  1173. // {
  1174. // to.Add(email);
  1175. // String name = emp.Get<Employee, String>(c => c.Name).Split(' ').FirstOrDefault();
  1176. // salutation = salutation + (String.IsNullOrEmpty(salutation) ? "Hi " : " and ") + name;
  1177. // }
  1178. // }
  1179. // }
  1180. // if (kanban.ManagerLink.ID != MyID.Value)
  1181. // {
  1182. // CoreRow emp = _employees.Rows.FirstOrDefault(r => r.Get<Employee, Guid>(c => c.ID).Equals(kanban.ManagerLink.ID));
  1183. // if (emp != null)
  1184. // {
  1185. // String email = emp.Get<Employee, String>(c => c.Email);
  1186. // if (!string.IsNullOrEmpty(email))
  1187. // {
  1188. // to.Add(email);
  1189. // String name = emp.Get<Employee, String>(c => c.Name).Split(' ').FirstOrDefault();
  1190. // salutation = salutation + (String.IsNullOrEmpty(salutation) ? "Hi " : " and ") + name;
  1191. // }
  1192. // }
  1193. // }
  1194. // }
  1195. // Outlook.Application outlookApp = new Outlook.Application();
  1196. // Outlook.MailItem mailItem = (Outlook.MailItem)outlookApp.CreateItem(Outlook.OlItemType.olMailItem);
  1197. // mailItem.Subject = "PRS Task: " + kanban.Title;
  1198. // mailItem.To = String.Join("; ", to);
  1199. // mailItem.HTMLBody = String.Format("{0},<br><br>Please see the above task in PRS.<br><br>Regards,<br><br>{1}<br><br><b><u>Task Description:</u></b><br><i>{2}</i><br><br><b><u>Additional Notes:</u></b><br>{3}", salutation, from, CoreUtils.StripHTML(kanban.Description), String.Join("\r\n", kanban.Notes));
  1200. // //mailItem.Attachments.Add(filename, Outlook.OlAttachmentType.olByValue, Type.Missing, Type.Missing);
  1201. // mailItem.Display(false);
  1202. //}
  1203. //private void CompleteTask_Click(object sender, RoutedEventArgs e)
  1204. //{
  1205. // if (MessageBox.Show("Are you sure you want to mark the selected tasks as complete?", "Confirm Completion", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
  1206. // return;
  1207. // TaskModel task = ((MenuItem)e.Source).Tag as TaskModel;
  1208. // Progress.ShowModal("Completing Task", (progress) =>
  1209. // {
  1210. // Kanban[] kanbans = GetSelectedKanbans(task.ID);
  1211. // for (int i = 0; i < kanbans.Length; i++)
  1212. // {
  1213. // Kanban kanban = kanbans[i];
  1214. // kanban.Completed = DateTime.Now;
  1215. // kanban.Category = "Complete";
  1216. // }
  1217. // new Client<Kanban>().Save(kanbans, "Kanban Marked as Completed");
  1218. // CheckedKanbans.Clear();
  1219. // });
  1220. // Refresh();
  1221. //}
  1222. #endregion
  1223. #region Kanban Creation / Editing
  1224. public void CreateKanban()
  1225. {
  1226. var result = Host.CreateKanban(
  1227. kanban =>
  1228. {
  1229. kanban.EmployeeLink.ID = EmployeeID != CoreUtils.FullGuid ? EmployeeID : MyID.Value;
  1230. kanban.ManagerLink.ID = MyID.Value;
  1231. kanban.ManagerLink.UserLink.ID = ClientFactory.UserGuid;
  1232. });
  1233. if (result != null)
  1234. Refresh(true);
  1235. }
  1236. private void DoEdit(TaskModel task)
  1237. {
  1238. if (task == null)
  1239. return;
  1240. var result = Host.EditReferences(new[] { task });
  1241. if (result)
  1242. Refresh(true);
  1243. }
  1244. #endregion
  1245. }
  1246. }