LeaveCalendar.xaml.cs 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Data;
  4. using System.Diagnostics;
  5. using System.Diagnostics.CodeAnalysis;
  6. using System.Globalization;
  7. using System.Linq;
  8. using System.Threading.Tasks;
  9. using System.Windows;
  10. using System.Windows.Controls;
  11. using System.Windows.Data;
  12. using System.Windows.Input;
  13. using System.Windows.Media;
  14. using Comal.Classes;
  15. using InABox.Clients;
  16. using InABox.Configuration;
  17. using InABox.Core;
  18. using InABox.DynamicGrid;
  19. using InABox.WPF;
  20. using Microsoft.Win32;
  21. using PRSDesktop.Grids;
  22. using Syncfusion.UI.Xaml.Grid;
  23. using Syncfusion.UI.Xaml.Grid.Converter;
  24. using Syncfusion.UI.Xaml.Grid.Helpers;
  25. using Syncfusion.Windows.Tools.Controls;
  26. using Syncfusion.XlsIO;
  27. using Activity = Comal.Classes.Activity;
  28. using SelectionChangedEventArgs = System.Windows.Controls.SelectionChangedEventArgs;
  29. namespace PRSDesktop
  30. {
  31. public class LeaveValue
  32. {
  33. public LeaveValue(Guid id, Guid employee, DateTime date, Guid activity, LeaveRequestStatus status, bool standard)
  34. {
  35. ID = id;
  36. Employee = employee;
  37. Date = date;
  38. Activity = activity;
  39. Status = status;
  40. Standard = standard;
  41. }
  42. public Guid ID { get; set; }
  43. public Guid Employee { get; set; }
  44. public DateTime Date { get; set; }
  45. public Guid Activity { get; set; }
  46. public LeaveRequestStatus Status { get; set; }
  47. public bool Standard { get; set; }
  48. }
  49. public class LeaveBackgroundConverter : IValueConverter
  50. {
  51. public Dictionary<Guid, Color>? Colors { get; set; }
  52. // Guid - EmployeeID
  53. // DateTime - Employee Start Date
  54. // DateTime - Employee Finish Date
  55. // EmployeeRoster[] Roster Data
  56. // DateTime - Roster Start
  57. public List<Tuple<Guid, DateTime, DateTime, EmployeeRosterItem[], DateTime>> Rosters { get; set; }
  58. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  59. {
  60. if(value is not LeaveValue val)
  61. return DependencyProperty.UnsetValue;
  62. if (val.ID == Guid.Empty)
  63. {
  64. var tuple = Rosters?.FirstOrDefault(x => x.Item1 == val.Employee);
  65. if (tuple == null)
  66. return new SolidColorBrush(System.Windows.Media.Colors.Red) { Opacity = 0.8 };
  67. if ( (!tuple.Item2.IsEmpty() && (tuple.Item2 > val.Date)) || (!tuple.Item3.IsEmpty() && (tuple.Item3 < val.Date)))
  68. return new SolidColorBrush(System.Windows.Media.Colors.LightGray) { Opacity = 0.8 };
  69. var roster = RosterUtils.GetRoster(tuple?.Item4, tuple?.Item5, val.Date);
  70. return (roster?.Enabled == true)
  71. ? roster?.Duration < 5.0F
  72. ? new System.Windows.Media.LinearGradientBrush(
  73. System.Windows.Media.Colors.LightYellow,
  74. System.Windows.Media.Colors.LightGray,
  75. 90.0F
  76. ) { Opacity = 0.8 }
  77. : new SolidColorBrush(System.Windows.Media.Colors.LightYellow) { Opacity = 0.8 }
  78. : new SolidColorBrush(System.Windows.Media.Colors.LightGray) { Opacity = 0.8 };
  79. }
  80. else
  81. {
  82. if (val.Status != LeaveRequestStatus.Approved)
  83. return new SolidColorBrush(System.Windows.Media.Colors.DimGray) { Opacity = 0.8 };
  84. if (Colors != null)
  85. if (Colors.ContainsKey(val.Activity))
  86. return new SolidColorBrush(Colors[val.Activity]) { Opacity = 0.5 };
  87. }
  88. return DependencyProperty.UnsetValue;
  89. }
  90. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  91. {
  92. throw new NotImplementedException();
  93. }
  94. }
  95. public class LeaveForegroundConverter : IValueConverter
  96. {
  97. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  98. {
  99. if (value is LeaveValue val
  100. && val.ID != Guid.Empty
  101. && val.Status != LeaveRequestStatus.Approved)
  102. {
  103. return new SolidColorBrush(Colors.LightGray);
  104. }
  105. return DependencyProperty.UnsetValue;
  106. }
  107. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  108. {
  109. throw new NotImplementedException();
  110. }
  111. }
  112. public class LeaveFontStyleConverter : IValueConverter
  113. {
  114. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  115. {
  116. if (value is LeaveValue val
  117. && val.ID != Guid.Empty
  118. && val.Status != LeaveRequestStatus.Approved)
  119. {
  120. return FontStyles.Italic;
  121. }
  122. return DependencyProperty.UnsetValue;
  123. }
  124. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  125. {
  126. throw new NotImplementedException();
  127. }
  128. }
  129. public class LeaveFontWeightConverter : IValueConverter
  130. {
  131. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  132. {
  133. return FontWeights.Bold;
  134. }
  135. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  136. {
  137. throw new NotImplementedException();
  138. }
  139. }
  140. public class LeaveContentConverter : IValueConverter
  141. {
  142. public Dictionary<Guid, string>? Abbreviations { get; set; }
  143. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  144. {
  145. if (value is not LeaveValue val)
  146. return DependencyProperty.UnsetValue;
  147. return Abbreviations?.ContainsKey(val.Activity) == true ? Abbreviations[val.Activity] : DependencyProperty.UnsetValue;
  148. }
  149. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  150. {
  151. throw new NotImplementedException();
  152. }
  153. }
  154. /// <summary>
  155. /// Interaction logic for LeaveCalendar.xaml
  156. /// </summary>
  157. public partial class LeaveCalendar : UserControl
  158. {
  159. private readonly CoreTable _activities;
  160. private readonly Dictionary<Guid, string> _activityCodes = new();
  161. private readonly Dictionary<Guid, Color> _activityColors = new();
  162. private readonly Dictionary<Guid, string> _employees = new();
  163. private readonly List<Tuple<Guid, DateTime, DateTime, EmployeeRosterItem[], DateTime>> _rosters = new();
  164. private readonly CoreTable _employeeteams;
  165. private LeaveSettings _settings;
  166. private readonly Dictionary<Guid, string> _teams = new();
  167. private bool bReady;
  168. private LeaveRequestGrid? lg;
  169. private StandardLeaveGrid? sg;
  170. public LeaveCalendar()
  171. {
  172. InitializeComponent();
  173. //dataGrid.ScrollMode = ScrollMode.Async;
  174. LoadSettings();
  175. StartDate.DateTime = DateTime.Today;
  176. EndDate.DateTime = DateTime.Today.AddYears(1);
  177. var setups = new MultiQuery();
  178. setups.Add<EmployeeTeam>(null, null, new SortOrder<EmployeeTeam>(x => x.TeamLink.Code).ThenBy(x => x.EmployeeLink.Name));
  179. setups.Add<Activity>(new Filter<Activity>(x => x.IsLeave).IsEqualTo(true));
  180. setups.Query();
  181. _employeeteams = setups.Get<EmployeeTeam>();
  182. _activities = setups.Get<Activity>();
  183. _teams = _employeeteams.ToDictionary<EmployeeTeam, Guid, string>(c => c.TeamLink.ID, c => c.TeamLink.Name);
  184. if (_teams.ContainsKey(Guid.Empty))
  185. _teams.Remove(Guid.Empty);
  186. var teams = _employeeteams.ToDictionary<EmployeeTeam, Guid, string>(c => c.TeamLink.ID, c => c.TeamLink.Name);
  187. teams[CoreUtils.FullGuid] = "Multiple Teams";
  188. Teams.ItemsSource = teams;
  189. Teams.SelectedValue = _settings.GroupID;
  190. ChangeSelectedTeams(_settings.GroupID);
  191. SelectedTeams.ItemsSource = _teams;
  192. foreach (KeyValuePair<Guid, string> pair in SelectedTeams.Items)
  193. if (_settings.SelectedGroups.Contains(pair.Key))
  194. SelectedTeams.SelectedItems.Add(pair);
  195. LoadEmployees(false);
  196. foreach (var row in _activities.Rows)
  197. {
  198. var id = row.Get<Activity, Guid>(c => c.ID);
  199. var color = row.Get<Activity, string>(c => c.Color);
  200. if (!string.IsNullOrWhiteSpace(color))
  201. _activityColors[id] = (Color)ColorConverter.ConvertFromString(color);
  202. var code = Codify(row.Get<Activity, string>(c => c.Description));
  203. _activityCodes[id] = Codify(code);
  204. }
  205. var rosterstarts = _employeeteams.ToDictionary<EmployeeTeam, Guid, DateTime>(x => x.EmployeeLink.ID, x => x.EmployeeLink.RosterStart);
  206. var startdates = _employeeteams.ToDictionary<EmployeeTeam, Guid, DateTime>(x => x.EmployeeLink.ID, x => x.EmployeeLink.StartDate);
  207. var finishdates = _employeeteams.ToDictionary<EmployeeTeam, Guid, DateTime>(x => x.EmployeeLink.ID, x => x.EmployeeLink.FinishDate);
  208. var rosters = _employeeteams.ToDictionary<EmployeeTeam, Guid, String>(x => x.EmployeeLink.ID, x => x.EmployeeLink.Roster);
  209. foreach (var empid in startdates.Keys)
  210. {
  211. var startdate = startdates[empid];
  212. var finishdate = finishdates[empid];
  213. var roster = !String.IsNullOrWhiteSpace(rosters[empid])
  214. ? Serialization.Deserialize<List<EmployeeRosterItem>>(rosters[empid]).ToArray()
  215. : null;
  216. var rosterstart = rosterstarts[empid];
  217. _rosters.Add(new Tuple<Guid, DateTime, DateTime, EmployeeRosterItem[], DateTime>(empid, startdate, finishdate, roster, rosterstart));
  218. }
  219. bReady = true;
  220. }
  221. private static string Codify(string name)
  222. {
  223. if (string.IsNullOrWhiteSpace(name))
  224. return "??";
  225. var result = "";
  226. var comps = name.ToUpper().Split(' ');
  227. foreach (var comp in comps)
  228. if (comp.Any())
  229. result += comp.First();
  230. return string.IsNullOrWhiteSpace(result) ? "??" : result;
  231. }
  232. [MemberNotNull(nameof(_settings))]
  233. private void LoadSettings()
  234. {
  235. _settings = new UserConfiguration<LeaveSettings>().Load();
  236. if (!_settings.SelectedGroups.Any() && _settings.GroupID != Guid.Empty)
  237. _settings.SelectedGroups.Add(_settings.GroupID);
  238. if (_settings.ListSize == 0.0F)
  239. _settings.ListSize = 200.0F;
  240. }
  241. private void SaveSettings()
  242. {
  243. if (!bReady)
  244. return;
  245. try
  246. {
  247. _settings.GroupID = Teams.SelectedValue != null ? (Guid)Teams.SelectedValue : Guid.Empty;
  248. _settings.SelectedGroups.Clear();
  249. foreach (var sel in SelectedTeams.SelectedItems)
  250. {
  251. var grp = (KeyValuePair<Guid, string>)sel;
  252. _settings.SelectedGroups.Add(grp.Key);
  253. }
  254. _settings.SelectedEmployees.Clear();
  255. foreach (var sel in SelectedEmployees.SelectedItems)
  256. {
  257. var grp = (KeyValuePair<Guid, string>)sel;
  258. _settings.SelectedEmployees.Add(grp.Key);
  259. }
  260. if (EmployeeGrid.RowDefinitions[1].ActualHeight != 0.0F)
  261. _settings.ListSize = EmployeeGrid.RowDefinitions[1].ActualHeight;
  262. }
  263. catch (Exception e)
  264. {
  265. Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace));
  266. }
  267. Task.Run(() => { new UserConfiguration<LeaveSettings>().Save(_settings); });
  268. }
  269. public void Refresh()
  270. {
  271. if (!bReady)
  272. return;
  273. using (new WaitCursor())
  274. {
  275. _employees.Clear();
  276. var crosstab = new List<LeaveValue>();
  277. MultiQuery query = new MultiQuery();
  278. var empfilter = new Filter<LeaveRequest>(x => x.EmployeeLink.ID).IsEqualTo(CoreUtils.FullGuid);
  279. foreach (var sel in SelectedEmployees.Items)
  280. {
  281. var emp = (KeyValuePair<Guid, string>)sel;
  282. if (SelectedEmployees.SelectedItems.Contains(emp))
  283. {
  284. empfilter = empfilter.Or(x => x.EmployeeLink.ID).IsEqualTo(emp.Key);
  285. _employees[emp.Key] = emp.Value;
  286. }
  287. }
  288. var start = StartDate.DateTime ?? DateTime.Today;
  289. var end = EndDate.DateTime ?? DateTime.Today.AddYears(1);
  290. var leavefilter = new Filter<LeaveRequest>(x => x.To).IsGreaterThanOrEqualTo(start)
  291. .And(x => x.From).IsLessThanOrEqualTo(end)
  292. .And(x => x.Status).IsNotEqualTo(LeaveRequestStatus.Rejected);
  293. leavefilter.Ands.Add(empfilter);
  294. query.Add<LeaveRequest>(
  295. leavefilter,
  296. new Columns<LeaveRequest>(x => x.ID)
  297. .Add(x => x.EmployeeLink.ID)
  298. .Add(x => x.From)
  299. .Add(x=>x.FromTime)
  300. .Add(x => x.To)
  301. .Add(x=>x.ToTime)
  302. .Add(x => x.LeaveType.ID)
  303. .Add(x => x.LeaveType.Description)
  304. .Add(x => x.Status)
  305. );
  306. query.Add<StandardLeave>(
  307. new Filter<StandardLeave>(x => x.To).IsGreaterThanOrEqualTo(start).And(x => x.From).IsLessThanOrEqualTo(end),
  308. new Columns<StandardLeave>(x => x.ID)
  309. .Add(x => x.From)
  310. .Add(x=>x.FromTime)
  311. .Add(x => x.To)
  312. .Add(x=>x.ToTime)
  313. .Add(x => x.LeaveType.ID)
  314. );
  315. query.Query();
  316. var leaverequests = query.Get<LeaveRequest>();
  317. var standardleaves = query.Get<StandardLeave>();
  318. foreach (var standardrow in standardleaves.Rows)
  319. {
  320. var id = standardrow.Get<StandardLeave, Guid>(x => x.ID);
  321. var actid = standardrow.Get<StandardLeave, Guid>(x => x.LeaveType.ID);
  322. var from = standardrow.Get<StandardLeave, DateTime>(x => x.From);
  323. from = from < start ? start : from;
  324. var to = standardrow.Get<StandardLeave, DateTime>(x => x.To);
  325. to = to > end ? end : to;
  326. for (var date = from; date <= to; date = date.AddDays(1))
  327. foreach (var empid in _employees.Keys)
  328. crosstab.Add(new LeaveValue(id, empid, date, actid, LeaveRequestStatus.Approved, true));
  329. }
  330. foreach (var leaverow in leaverequests.Rows)
  331. {
  332. var id = leaverow.Get<LeaveRequest, Guid>(x => x.ID);
  333. var empid = leaverow.Get<LeaveRequest, Guid>(x => x.EmployeeLink.ID);
  334. var actid = leaverow.Get<LeaveRequest, Guid>(x => x.LeaveType.ID);
  335. var status = leaverow.Get<LeaveRequest, LeaveRequestStatus>(x => x.Status);
  336. var from = leaverow.Get<LeaveRequest, DateTime>(x => x.From);
  337. from = from < start ? start : from;
  338. var to = leaverow.Get<LeaveRequest, DateTime>(x => x.To);
  339. to = to > end ? end : to;
  340. var totime = leaverow.Get<LeaveRequest, TimeSpan>(x => x.ToTime);
  341. for (var date = from; date < to.Add(totime); date = date.AddDays(1))
  342. crosstab.Add(new LeaveValue(id, empid, date, actid, status, false));
  343. }
  344. var data = new DataTable();
  345. data.Columns.Add("Date", typeof(DateTime));
  346. foreach (var employee in _employees.Keys)
  347. data.Columns.Add(employee.ToString(), typeof(object));
  348. for (var date = start; date <= end; date = date.AddDays(1))
  349. {
  350. var values = new List<object> { date };
  351. foreach (var employee in _employees.Keys)
  352. {
  353. LeaveValue value = null;
  354. var roster = _rosters.FirstOrDefault(x => x.Item1 == employee);
  355. if (roster != null)
  356. {
  357. var curroster = RosterUtils.GetRoster(roster.Item4, roster.Item5, date);
  358. if (curroster?.Enabled == true)
  359. {
  360. value = crosstab.FirstOrDefault(x => x.Employee.Equals(employee) && x.Date.Equals(date) && x.Standard);
  361. if (value == null)
  362. value = crosstab.FirstOrDefault(x => x.Employee.Equals(employee) && x.Date.Equals(date) && !x.Standard);
  363. }
  364. }
  365. values.Add(value ?? new LeaveValue(Guid.Empty, employee, date, Guid.Empty, LeaveRequestStatus.InProgress, false));
  366. }
  367. data.Rows.Add(values.ToArray());
  368. }
  369. dataGrid.ItemsSource = data;
  370. }
  371. }
  372. private void DataGrid_AutoGeneratingColumn(object sender, AutoGeneratingColumnArgs e)
  373. {
  374. e.Column.TextAlignment = TextAlignment.Center;
  375. e.Column.HorizontalHeaderContentAlignment = HorizontalAlignment.Center;
  376. e.Column.ColumnSizer = GridLengthUnitType.None;
  377. var value = (e.Column.ValueBinding as Binding)!;
  378. if (value.Path.Path.Equals("Date"))
  379. {
  380. e.Column.Width = 100;
  381. e.Column.HeaderStyle = Resources["DateHeaderStyle"] as Style;
  382. e.Column.AllowFocus = false;
  383. }
  384. else
  385. {
  386. var style = new Style(typeof(GridCell));
  387. style.Setters.Add(new Setter(BackgroundProperty,
  388. new Binding(value.Path.Path)
  389. {
  390. Converter = new LeaveBackgroundConverter
  391. {
  392. Colors = _activityColors,
  393. Rosters = _rosters
  394. }
  395. }));
  396. style.Setters.Add(new Setter(ForegroundProperty, new Binding(value.Path.Path) { Converter = new LeaveForegroundConverter() }));
  397. style.Setters.Add(new Setter(FontStyleProperty, new Binding(value.Path.Path) { Converter = new LeaveFontStyleConverter() }));
  398. style.Setters.Add(new Setter(FontWeightProperty, new Binding(value.Path.Path) { Converter = new LeaveFontWeightConverter() }));
  399. e.Column.CellStyle = style;
  400. e.Column.Width = 30;
  401. e.Column.HeaderStyle = Resources["ContentHeaderStyle"] as Style;
  402. e.Column.HeaderText = _employees[Guid.Parse(value.Path.Path)];
  403. e.Column.DisplayBinding = new Binding
  404. { Path = new PropertyPath(e.Column.MappingName), Converter = new LeaveContentConverter { Abbreviations = _activityCodes } };
  405. //e.Column.ValueBinding = new Binding() { Path = new PropertyPath(e.Column.MappingName), Converter = new LeaveContentConverter() };
  406. //e.Column.UseBindingValue = true;
  407. e.Column.AllowFocus = true;
  408. }
  409. }
  410. //private void DataGrid_FilterItemsPopulating(object sender, GridFilterItemsPopulatingEventArgs e)
  411. //{
  412. // e.FilterControl.FilterMode = FilterMode.AdvancedFilter;
  413. //}
  414. private void GetSelectionData(out DateTime from, out DateTime to, out Guid[] ids)
  415. {
  416. var emps = new List<Guid>();
  417. from = DateTime.MaxValue;
  418. to = DateTime.MinValue;
  419. foreach (var cell in dataGrid.GetSelectedCells())
  420. {
  421. var binding = (cell.Column.ValueBinding as Binding)!;
  422. if (Guid.TryParse(binding.Path.Path, out var emp))
  423. if (!emps.Contains(emp))
  424. emps.Add(emp);
  425. var row = (cell.RowData as DataRowView)!;
  426. var date = (DateTime)row.Row.ItemArray.First()!;
  427. if (date < from)
  428. from = date;
  429. if (date > to)
  430. to = date;
  431. }
  432. ids = emps.Any() ? emps.ToArray() : _employees.Keys.ToArray();
  433. }
  434. private bool HasData()
  435. {
  436. foreach (var cell in dataGrid.GetSelectedCells())
  437. {
  438. if (!cell.IsDataRowCell)
  439. continue;
  440. var propertyCollection = dataGrid.View.GetPropertyAccessProvider();
  441. var cellValue = propertyCollection.GetValue(cell.RowData, cell.Column.MappingName);
  442. if (cellValue is LeaveValue leaveValue && leaveValue.ID != Guid.Empty)
  443. return true;
  444. }
  445. return false;
  446. }
  447. private Guid[] GetLeaveIDs(bool standard)
  448. {
  449. List<Guid> result = new List<Guid>();
  450. foreach (var cell in dataGrid.GetSelectedCells())
  451. {
  452. if (cell.IsDataRowCell)
  453. {
  454. var propertyCollection = dataGrid.View.GetPropertyAccessProvider();
  455. var cellvalue = propertyCollection.GetValue(cell.RowData, cell.Column.MappingName) as LeaveValue;
  456. if (cellvalue != null && (cellvalue.ID != Guid.Empty) && (cellvalue.Standard == standard) && !result.Contains(cellvalue.ID))
  457. result.Add(cellvalue.ID);
  458. }
  459. }
  460. return result.ToArray();
  461. }
  462. private LeaveValue? GetData(GridCellInfo cell)
  463. {
  464. if (!cell.IsDataRowCell)
  465. return null;
  466. var propertyCollection = dataGrid.View.GetPropertyAccessProvider();
  467. var cellValue = propertyCollection.GetValue(cell.RowData, cell.Column.MappingName);
  468. return cellValue is LeaveValue leaveValue && leaveValue.ID != Guid.Empty ? leaveValue : null;
  469. }
  470. private bool HasData(GridCellInfo cell)
  471. {
  472. if (!cell.IsDataRowCell)
  473. return false;
  474. var propertyCollection = dataGrid.View.GetPropertyAccessProvider();
  475. var cellValue = propertyCollection.GetValue(cell.RowData, cell.Column.MappingName);
  476. return cellValue is LeaveValue leaveValue && leaveValue.ID != Guid.Empty;
  477. }
  478. private void CreateLeaveRequestClick(object sender, RoutedEventArgs e)
  479. {
  480. var activity = ((sender as MenuItem)!.Tag as Activity)!;
  481. GetSelectionData(out var from, out var to, out var ids);
  482. var leaves = new List<LeaveRequest>();
  483. foreach (var id in ids)
  484. {
  485. var leave = new LeaveRequest
  486. {
  487. From = from,
  488. To = to
  489. };
  490. leave.LeaveType.ID = activity.ID;
  491. leave.EmployeeLink.ID = id;
  492. leaves.Add(leave);
  493. }
  494. lg ??= new LeaveRequestGrid();
  495. if (lg.EditItems(leaves.ToArray()))
  496. Refresh();
  497. }
  498. private void CreateStandardLeaveClick(object sender, RoutedEventArgs e)
  499. {
  500. GetSelectionData(out var from, out var to, out var ids);
  501. var leave = new StandardLeave
  502. {
  503. From = from,
  504. To = to
  505. };
  506. sg ??= new StandardLeaveGrid();
  507. if (sg.EditItems(new StandardLeave[] { leave }))
  508. Refresh();
  509. }
  510. private IEnumerable<LeaveRequest> GetSelectedLeaveRequests()
  511. {
  512. var ids = GetLeaveIDs(false);
  513. if (ids.Any())
  514. {
  515. lg ??= new LeaveRequests();
  516. var table = new Client<LeaveRequest>().Query(
  517. new Filter<LeaveRequest>(x => x.ID).InList(ids),
  518. lg.LoadEditorColumns()
  519. );
  520. var result = table.Rows.Select(x => x.ToObject<LeaveRequest>()).ToArray();
  521. return result;
  522. }
  523. return new LeaveRequest[] { };
  524. }
  525. private IEnumerable<StandardLeave> GetSelectedStandardLeaves()
  526. {
  527. var ids = GetLeaveIDs(true);
  528. if (ids.Any())
  529. {
  530. sg ??= new StandardLeaveGrid();
  531. var table = new Client<StandardLeave>().Query(
  532. new Filter<StandardLeave>(x => x.ID).InList(ids),
  533. sg.LoadEditorColumns()
  534. );
  535. var result = table.Rows.Select(x => x.ToObject<StandardLeave>()).ToArray();
  536. return result;
  537. }
  538. return new StandardLeave[] { };
  539. }
  540. private void EditLeaveClick(object sender, RoutedEventArgs e)
  541. {
  542. var requests = GetSelectedLeaveRequests().ToArray();
  543. if (requests.Any())
  544. {
  545. lg ??= new LeaveRequests();
  546. if (lg.EditItems(requests))
  547. Refresh();
  548. return;
  549. }
  550. var standards = GetSelectedStandardLeaves().ToArray();
  551. if (standards.Any())
  552. {
  553. sg ??= new StandardLeaveGrid();
  554. if (sg.EditItems(standards))
  555. Refresh();
  556. return;
  557. }
  558. MessageBox.Show("Nothing to edit!");
  559. }
  560. private void DeleteLeaveClick(object sender, RoutedEventArgs e)
  561. {
  562. var requests = GetSelectedLeaveRequests().ToArray();
  563. if (requests.Any())
  564. {
  565. if (MessageBox.Show("Delete Leave Request Information?", "Confirm Delete", MessageBoxButton.YesNo, MessageBoxImage.Warning) ==
  566. MessageBoxResult.Yes)
  567. {
  568. using (new WaitCursor())
  569. new Client<LeaveRequest>().Delete(requests, "Deleted from Calendar");
  570. Refresh();
  571. }
  572. return;
  573. }
  574. var standards = GetSelectedStandardLeaves().ToArray();
  575. if (standards.Any())
  576. {
  577. if (MessageBox.Show("Delete Standard Leave Information?", "Confirm Delete", MessageBoxButton.YesNo, MessageBoxImage.Warning) ==
  578. MessageBoxResult.Yes)
  579. {
  580. using (new WaitCursor())
  581. new Client<StandardLeave>().Delete(standards, "Deleted from Calendar");
  582. Refresh();
  583. }
  584. return;
  585. }
  586. MessageBox.Show("Nothing to delete!");
  587. }
  588. // private void DataGrid_PreviewMouseDown(object sender, MouseButtonEventArgs e)
  589. // {
  590. // if (e.RightButton == MouseButtonState.Pressed)
  591. // {
  592. // var vc = dataGrid.GetVisualContainer();
  593. // var point = e.GetPosition(vc);
  594. // var rci = vc.PointToCellRowColumnIndex(point);
  595. //
  596. // if (rci.RowIndex == 0 || rci.ColumnIndex == 0)
  597. // return;
  598. //
  599. // var menu = new ContextMenu();
  600. // if (!HasData(dataGrid.CurrentCellInfo))
  601. // foreach (var row in _activities.Rows)
  602. // {
  603. // var createleave = new MenuItem
  604. // {
  605. // Header = row.Get<Activity, string>(c => c.Description),
  606. // Tag = row.ToObject<Activity>()
  607. // };
  608. // createleave.Click += CreateLeaveRequestClick;
  609. // menu.Items.Add(createleave);
  610. // }
  611. //
  612. // if (HasData())
  613. // {
  614. // var deleteleave = new MenuItem { Header = "Delete Leave" };
  615. // deleteleave.Click += DeleteLeaveClick;
  616. // menu.Items.Add(deleteleave);
  617. // }
  618. //
  619. // dataGrid.ContextMenu = menu;
  620. // menu.IsOpen = true;
  621. // }
  622. // }
  623. private void DataGrid_ContextMenuOpening(object sender, ContextMenuEventArgs e)
  624. {
  625. var vc = dataGrid.GetVisualContainer();
  626. var p = Mouse.GetPosition(vc);
  627. var rci = vc.PointToCellRowColumnIndex(p);
  628. if (rci.RowIndex < 1 || rci.ColumnIndex < 1)
  629. {
  630. e.Handled = true;
  631. return;
  632. }
  633. dataGrid.ContextMenu.Items.Clear();
  634. var bCreate = !HasData(dataGrid.CurrentCellInfo);
  635. var bEdit = HasData();
  636. if (bCreate)
  637. {
  638. var createleaveheader = new MenuItem { Header = "Create Leave Request" };
  639. foreach (var row in _activities.Rows)
  640. {
  641. var createleave = new MenuItem
  642. {
  643. Header = row.Get<Activity, string>(c => c.Description),
  644. Tag = row.ToObject<Activity>()
  645. };
  646. createleave.Click += CreateLeaveRequestClick;
  647. createleaveheader.Items.Add(createleave);
  648. }
  649. dataGrid.ContextMenu.Items.Add(createleaveheader);
  650. dataGrid.ContextMenu.Items.Add(new Separator());
  651. var createstandardleave = new MenuItem { Header = "Create Standard Leave" };
  652. createstandardleave.Click += CreateStandardLeaveClick;
  653. dataGrid.ContextMenu.Items.Add(createstandardleave);
  654. }
  655. if (bEdit && bCreate)
  656. dataGrid.ContextMenu.Items.Add(new Separator());
  657. if (bEdit)
  658. {
  659. var editleave = new MenuItem { Header = "Edit Leave" };
  660. editleave.Click += EditLeaveClick;
  661. dataGrid.ContextMenu.Items.Add(editleave);
  662. dataGrid.ContextMenu.Items.Add(new Separator());
  663. var deleteleave = new MenuItem { Header = "Delete Leave" };
  664. deleteleave.Click += DeleteLeaveClick;
  665. dataGrid.ContextMenu.Items.Add(deleteleave);
  666. var cell = GetData(dataGrid.CurrentCellInfo); // not-null because bEdit.
  667. if (cell != null)
  668. {
  669. dataGrid.ContextMenu.Items.Add(new Separator());
  670. var formsItem = new MenuItem { Header = "Digital Forms" };
  671. DynamicGridUtils.PopulateFormMenu<LeaveRequestForm, LeaveRequest, LeaveRequestLink>(
  672. formsItem,
  673. cell.ID,
  674. () => new Client<LeaveRequest>().Load(new Filter<LeaveRequest>(x => x.ID).IsEqualTo(cell.ID)).First());
  675. dataGrid.ContextMenu.Items.Add(formsItem);
  676. }
  677. }
  678. }
  679. private void DateTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  680. {
  681. if (!bReady)
  682. return;
  683. Refresh();
  684. }
  685. private void SyncSelectedTeams(Guid teamid)
  686. {
  687. var bOldReady = bReady;
  688. bReady = false;
  689. if (teamid != CoreUtils.FullGuid)
  690. {
  691. SelectedTeams.SelectedItems.Clear();
  692. foreach (KeyValuePair<Guid, string> sel in SelectedTeams.Items)
  693. if (sel.Key == teamid)
  694. SelectedTeams.SelectedItems.Add(sel);
  695. }
  696. LoadEmployees(true);
  697. bReady = bOldReady;
  698. }
  699. private void GroupsSelectionChanged(object sender, SelectionChangedEventArgs e)
  700. {
  701. if (Teams.SelectedValue == null)
  702. return;
  703. var teamid = (Guid)Teams.SelectedValue;
  704. ChangeSelectedTeams(teamid);
  705. SyncSelectedTeams(teamid);
  706. }
  707. private void ChangeSelectedTeams(Guid teamid)
  708. {
  709. if (teamid == CoreUtils.FullGuid)
  710. {
  711. EmployeeGrid.RowDefinitions[1].Height = new GridLength(_settings.ListSize, GridUnitType.Pixel);
  712. EmployeeGrid.RowDefinitions[2].Height = new GridLength(1, GridUnitType.Auto);
  713. }
  714. else
  715. {
  716. var oldbReady = bReady;
  717. bReady = false;
  718. EmployeeGrid.RowDefinitions[1].Height = new GridLength(0, GridUnitType.Pixel);
  719. EmployeeGrid.RowDefinitions[2].Height = new GridLength(0, GridUnitType.Pixel);
  720. bReady = oldbReady;
  721. }
  722. //bHandled = false;
  723. }
  724. //bool bHandled = false;
  725. //private void SelectedTeams_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
  726. //{
  727. // if (!bReady)
  728. // return;
  729. // if (!bHandled)
  730. // LoadEmployees();
  731. // bHandled = !bHandled;
  732. //}
  733. private void SelectedTeams_ItemChecked(object sender, ItemCheckedEventArgs e)
  734. {
  735. if (!bReady)
  736. return;
  737. LoadEmployees(true);
  738. }
  739. private void LoadEmployees(bool selectall)
  740. {
  741. var emps = new Dictionary<Guid, string>();
  742. foreach (var pair in SelectedTeams.SelectedItems)
  743. if (pair != null)
  744. {
  745. var key = ((KeyValuePair<Guid, string>)pair).Key;
  746. foreach (var row in _employeeteams.Rows.Where(r =>
  747. r.Get<EmployeeTeam, Guid>(c => c.TeamLink.ID).Equals(key) || key.Equals(CoreUtils.FullGuid)))
  748. emps[row.Get<EmployeeTeam, Guid>(c => c.EmployeeLink.ID)] = row.Get<EmployeeTeam, string>(c => c.EmployeeLink.Name);
  749. }
  750. var bOldReady = bReady;
  751. bReady = false;
  752. SelectedEmployees.ItemsSource = emps;
  753. foreach (var item in SelectedEmployees.Items)
  754. {
  755. var pair = (KeyValuePair<Guid, string>)item;
  756. if (_settings.SelectedEmployees.Contains(pair.Key) || selectall)
  757. SelectedEmployees.SelectedItems.Add(item);
  758. }
  759. bReady = bOldReady;
  760. SaveSettings();
  761. Refresh();
  762. }
  763. private void EmployeesSelectionChanged(object sender, SelectionChangedEventArgs e)
  764. {
  765. if (!bReady || e.AddedItems.Count == 0 || e.AddedItems[0] == null)
  766. return;
  767. //ReloadColumns();
  768. SaveSettings();
  769. Refresh();
  770. }
  771. private void Export_Click(object sender, RoutedEventArgs e)
  772. {
  773. var options = new ExcelExportingOptions
  774. {
  775. ExcelVersion = ExcelVersion.Excel2013
  776. };
  777. var excelEngine = dataGrid.ExportToExcel(dataGrid.View, options);
  778. var workBook = excelEngine.Excel.Workbooks[0];
  779. var dlg = new SaveFileDialog
  780. {
  781. Filter = "Excel Files (*.xlsx)|*.xlsx",
  782. FileName = typeof(LeaveRequest).EntityName().Split('.').Last() + ".xlsx"
  783. };
  784. if (dlg.ShowDialog() == true)
  785. try
  786. {
  787. workBook.SaveAs(dlg.FileName);
  788. Process.Start(new ProcessStartInfo(dlg.FileName) { UseShellExecute = true });
  789. }
  790. catch (Exception e2)
  791. {
  792. MessageBox.Show("Error saving spreadsheet!\n\n" + e2.Message);
  793. }
  794. //workBook.SaveAs("Leave Requests.xlsx");
  795. }
  796. private void SelectedTeams_SizeChanged(object sender, SizeChangedEventArgs e)
  797. {
  798. SaveSettings();
  799. }
  800. }
  801. }