using System; using System.Collections.Generic; using System.Data; using System.Linq; using System.Windows.Controls; using Comal.Classes; using InABox.Clients; using InABox.Configuration; using InABox.Core; using PRSDesktop.WidgetGroups; namespace PRSDesktop { public class TimesheetWidgetProperties : IUserConfigurationSettings, IDashboardProperties { } public class TimesheetWidgetElement : DashboardElement { } /// /// Interaction logic for TimesheetWidget.xaml /// public partial class TimesheetWidget : UserControl, IDashboardWidget { private DateTime _date = DateTime.Today; private Guid _groupid = CoreUtils.FullGuid; private CoreTable activities; private CoreTable employees; private readonly DataTable report = new(); private CoreTable timesheets; public TimesheetWidget() { InitializeComponent(); report.Columns.Add("ID", typeof(Guid)); report.Columns.Add("Name", typeof(string)); report.Columns.Add("Leave", typeof(string)); report.Columns.Add("LateStart", typeof(TimeSpan)); report.Columns.Add("EarlyFinish", typeof(TimeSpan)); report.Columns.Add("ClockIn", typeof(string)); report.Columns.Add("ClockOut", typeof(string)); report.PrimaryKey = new[] { report.Columns[0] }; } public DateTime Date { get => _date; set { _date = value; LoadTimeSheets(); } } public Guid GroupID { get => _groupid; set { _groupid = value; LoadEmployees(value); } } public TimesheetWidgetProperties Properties { get; set; } public event LoadSettings? LoadSettings; public event SaveSettings? SaveSettings; public void Setup() { LoadEmployees(GroupID); LoadActivities(); } public void Refresh() { LoadTimeSheets(); } public void Shutdown() { } private void ClearReport() { Report.ItemsSource = null; } private void LoadEmployees(Guid id) { ClearReport(); employees = null; new Client().Query( id != CoreUtils.FullGuid ? new Filter(x => x.Group.ID).IsEqualTo(id) : null, null, null, (o, e) => { employees = o; CheckData(); } ); } private void LoadActivities() { ClearReport(); activities = null; new Client().Query( new Filter(x => x.IsLeave).IsEqualTo(true), new Columns( x => x.ID, x => x.Description ), null, (o, e) => { activities = o; CheckData(); } ); } private void LoadTimeSheets() { ClearReport(); timesheets = null; new Client().Query( new Filter(x => x.Date).IsEqualTo(_date), null, new SortOrder(x => x.EmployeeLink.Name), (o, e) => { timesheets = o; CheckData(); } ); } private void CheckData() { if (employees != null && activities != null && timesheets != null) ProcessData(); } private string Codify(string name) { var result = ""; var comps = name.ToUpper().Split(' '); foreach (var comp in comps) if (comp.Any()) result += comp.First(); return string.IsNullOrWhiteSpace(result) ? "??" : result; } private void ProcessData() { try { report.Rows.Clear(); foreach (var time in timesheets.Rows) { var empid = time.Get(x => x.EmployeeLink.ID); var empname = time.Get(x => x.EmployeeLink.Name); if (report.Rows.Find(empid) == null) { var emprow = employees.Rows.FirstOrDefault(r => r.Get(c => c.ID).Equals(empid)); if (emprow != null) { var userid = emprow.Get(x => x.UserLink.UserID); var date = time.Get(c => c.Date); var roster = EmployeeRosterItem.FromJSON(emprow.Get(c => c.Roster)); var rosterday = RosterUtils.GetRoster(roster, emprow.Get(c => c.RosterStart), date); var shifts = RosterUtils.GetBlocks(rosterday, date, TimeSpan.Zero, TimeSpan.FromDays(1)); var shiftstart = shifts.Aggregate(TimeSpan.MaxValue, (time, block) => block.Start < time ? block.Start : time); var shiftend = shifts.Aggregate(TimeSpan.Zero, (time, block) => block.Finish > time ? block.Finish : time); var rows = timesheets.Rows.Where(r => r.Get(c => c.EmployeeLink.ID).Equals(empid)); var start = new TimeSpan(long.MaxValue); TimeSpan? late = null; var finish = new TimeSpan(long.MinValue); TimeSpan? early = null; var leave = ""; var clockin = ""; var clockout = ""; var leaves = new List(); foreach (var row in rows) { var activity = row.Get(x => x.ActivityLink.ID); var activityrow = activities.Rows.FirstOrDefault(r => r.Get(c => c.ID).Equals(activity)); if (activityrow != null) { var thisleave = Codify(activityrow.Get(x => x.Description)); if (!leaves.Contains(thisleave)) leaves.Add(thisleave); } leave = string.Join(",", leaves); var createdby = row.Get(x => x.CreatedBy); if (createdby == null) createdby = ""; if (shiftstart.Ticks != 0) { var thisstart = row.Get(x => x.Start); if (thisstart < start) { start = thisstart; if (start > shiftstart) late = !late.HasValue || start < late.Value ? start : late; else late = null; clockin = createdby.Equals(userid) ? "" : createdby; } } if (shiftend.Ticks != 0) { var thisfinish = row.Get(x => x.Finish); if (thisfinish.Ticks == 0) { shiftend = new TimeSpan(0); early = null; } else { if (thisfinish > finish) { finish = thisfinish; if (finish < shiftend) early = !early.HasValue || finish > early.Value ? finish : early; else early = null; clockout = createdby.Equals(userid) ? "" : createdby; } } } } leave = string.Join(",", leaves); if (!string.IsNullOrEmpty(leave) || late.HasValue || early.HasValue || !string.IsNullOrEmpty(clockin) || !string.IsNullOrEmpty(clockout)) report.Rows.Add(empid, empname, leave, late, early, clockin, clockout); } } } } catch (Exception e) { Logger.Send(LogType.Error, "", string.Format("*** Unknown Error: {0}\n{1}", e.Message, e.StackTrace)); } Dispatcher.Invoke(() => { Report.ItemsSource = report; }); } } }