Files
BeWoPlaner/BeWo/View/Detail/Report/AbwesenheitsView.xaml.cs

624 lines
26 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Forms;
using System.Windows.Navigation;
using System.Windows.Media;
using BeWo.Controls;
using BeWo.Core;
using BeWo.ServiceProxy;
using BeWo.ViewModel;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using BS.Shared.Translation;
using DevExpress.Services;
using DevExpress.Xpf.Scheduler;
using SchedulerStorage = DevExpress.Xpf.Scheduler.SchedulerStorage;
using ResourceStorage = DevExpress.Xpf.Scheduler.ResourceStorage;
using AppointmentStorage = DevExpress.Xpf.Scheduler.AppointmentStorage;
using IAppointmentLabelStorage = DevExpress.Xpf.Scheduler.AppointmentLabelCollection;
using ColorConverter = System.Windows.Media.ColorConverter;
using SchedulerControl = DevExpress.Xpf.Scheduler.SchedulerControl;
using AppointmentViewInfoCustomizingEventArgs = DevExpress.Xpf.Scheduler.AppointmentViewInfoCustomizingEventArgs;
using DevExpress.XtraScheduler;
using System.Collections.ObjectModel;
using DevExpress.Xpf.Scheduler.Drawing;
//using System.Windows.Markup;
namespace BeWo.View.Detail.Report
{
/// <summary>
/// Interaction logic for AbwesenheitstabelleView.xaml
/// </summary>
public partial class AbwesenheitstabelleView : BeWoView
{
private SchedulerStorage _SchedulerStorage;
private IAppointmentLabelStorage _LabelStorage;
private ResourceStorage _ResourceStorage;
private AppointmentStorage _AppointmentStorage;
private List<AbsenceReasonDC> _AbsenceReasonDCs;
private List<CompactTeamDC> _TeamDCs;
private Dictionary<long, EmployeeDC> _EmployeeDict;
private AbsenceOverviewFilterDC _SelectedFilter;
public UrlaubsplanerRootDC UrlaubsplanerRootObj { get; set; }
public int SelectedMonth { get; set; }
public int SelectedYear { get; set; }
public AbwesenheitstabelleView()
{
InitializeComponent();
InitializeFilter();
InitializeDateSelction();
InitializeScheduler();
linkPdfExport.NavigateUri = BeWoApp.SiteOfOrigin;
linkGiftLeaveday.NavigateUri = BeWoApp.SiteOfOrigin;
_EmployeeDict = new Dictionary<long, EmployeeDC>();
ApplyCellStyles();
ApplySelectionTemplate();
}
public List<AbsenceReasonDC> SelectedAbsenceReasons => FilterAbwesenheit.SelectedItems.Cast<AbsenceReasonDC>().ToList();
public List<EmploymentTypeDC> SelectedEmploymentTypes => FilterBeschaftigungsart.SelectedItems.Cast<EmploymentTypeDC>().ToList();
public List<CompactTeamDC> SelectedTeams => FilterTeams.SelectedItems.Cast<CompactTeamDC>().ToList();
private void Button_Click(object sender, RoutedEventArgs e)
{
UpdateFilter();
SelectedMonth = _MonthPicker.SelectedMonth;
SelectedYear = (int)_YearPicker.SelectedItem;
UrlaubsplanerRootObj = ServiceFacade.DoOperationsServiceSync(s => s.BuildUrlaubsplanerRootObject(SelectedYear, SelectedMonth));
UpdateScheduler();
ColorizeFeiertage();
ApplyFeiertagCellStyle();
}
private void ColorizeFeiertage()
{
}
private void SchedularControl_EditAppointmentFormShowing(object sender, EditAppointmentFormEventArgs e)
{
var apt = e.Appointment;
e.AllowResize = false;
e.Form = new AbwesenheitsEditView(this, apt, _AbsenceReasonDCs);
}
private void SchedularControl_EditRecurrentAppointmentFormShowing(object sender, EditAppointmentFormEventArgs e)
{
e.Cancel = true;
}
private void SchedulerControl_AppointmentViewInfoCustomizing(object sender, AppointmentViewInfoCustomizingEventArgs e)
{
}
private void SpinEdit_EditValueChanged(object sender, DevExpress.Xpf.Editors.EditValueChangedEventArgs e)
{
if (e.NewValue == null || !int.TryParse(e.NewValue.ToString(), out var count))
return;
if (count > 0 && count <= DateTime.DaysInMonth(_SelectedFilter.Year, _SelectedFilter.Month))
_SchedulerControl.TimelineView.IntervalCount = count;
}
private void LinkPdfExport_OnRequestNavigate(object sender, RequestNavigateEventArgs e)
{
var control = new AbwesenheitsPrintControl(_SchedulerControl.Start);
var beWoWindow = new BeWoWindow();
control.ButtonCancelClicked += () => beWoWindow.Close();
control.ButtonAcceptClicked += delegate
{
UpdateReportUrl(control.SelectedDate);
BeWoUtils.NavigateToReportUri((sender as System.Windows.Documents.Hyperlink).NavigateUri.ToString(), Translator.Translate("Abwesenheitsübersicht"));
beWoWindow.Close();
};
beWoWindow.Height = 200;
beWoWindow.MinHeight = 200;
beWoWindow.Width = 250;
beWoWindow.MinWidth = 250;
beWoWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
beWoWindow.GroupBoxContent = control;
beWoWindow.Owner = BeWoApp.CurrentBeWo.MainWindow;
beWoWindow.rootGroupBox.Header = "Drucken";
beWoWindow.ShowDialog();
}
private void LinkGiftLeaveday_OnRequestNavigate(object sender, RequestNavigateEventArgs e)
{
if (_EmployeeDict.Count > 0)
{
var employee = ServiceFacade.DoEmployeeServiceSync(s => s.GetAllActiveEmployees());
var control = new UrlaubstagSchenkenView(employee);
var beWoWindow = new BeWoWindow
{
rootGroupBox = { Header = "Urlaub schenken" },
Height = 350,
MinHeight = 350,
Width = 300,
MinWidth = 300,
WindowStartupLocation = WindowStartupLocation.CenterOwner,
GroupBoxContent = control,
Owner = BeWoApp.CurrentBeWo.MainWindow
};
control.ButtonCancelClicked += () =>
{
beWoWindow.Close();
};
control.ButtonConfirmClicked += () =>
{
beWoWindow.Close();
};
beWoWindow.ShowDialog();
}
else
{
System.Windows.MessageBox.Show("Erstellen Sie zuerst die Abwesenheitsübersicht!", "BeWoPlaner", MessageBoxButton.OK, MessageBoxImage.Information);
}
}
private void SchedulerControl_PopupMenuShowing(object sender, SchedulerMenuEventArgs e)
{
e.Handled = true;
}
private void InitializeFilter()
{
var absenceReasons = ServiceFacade.DoOperationsServiceSync(x => x.GetAllAbsenceReason());
var employmentTypes = ServiceFacade.DoEmployeeServiceSync(x => x.GetAllEmploymentTypes());
var teams = ServiceFacade.DoEmployeeServiceSync(x => x.GetAllTeamsCompact());
FilterAbwesenheit.Items.AddRange(absenceReasons.ToArray());
FilterBeschaftigungsart.Items.AddRange(employmentTypes.ToArray());
FilterTeams.Items.AddRange(teams.ToArray());
_AbsenceReasonDCs = absenceReasons;
_TeamDCs = teams;
}
private void InitializeDateSelction()
{
var year = new List<int>();
for (int i = DateTime.Today.Year + 1; i > 2010; i--)
{
year.Add(i);
}
_YearPicker.ItemsSource = year;
_MonthPicker.SelectedMonth = DateTime.Today.Month;
_YearPicker.SelectedItem = DateTime.Today.Year;
}
private void InitializeScheduler()
{
try
{
_SchedulerControl.BeginInit();
_SchedulerStorage = _SchedulerControl.Storage;
_LabelStorage = _SchedulerControl.Storage.AppointmentStorage.Labels;
_ResourceStorage = _SchedulerControl.Storage.ResourceStorage;
_AppointmentStorage = _SchedulerControl.Storage.AppointmentStorage;
_AppointmentStorage.CustomFieldMappings.Add(new SchedulerCustomFieldMapping(nameof(AbsenceTimeDC), nameof(AbsenceTimeDC))); //MA-Namen setzen
//_ResourceStorage.CustomFieldMappings.Add(new SchedulerCustomFieldMapping(nameof(EmployeeDC), nameof(EmployeeDC))); //Urlaubskonto setzen
_ResourceStorage.CustomFieldMappings.Add(new SchedulerCustomFieldMapping(nameof(AbwesenheitsInformationDC), nameof(AbwesenheitsInformationDC)));
//_ResourceStorage.CustomFieldMappings.Add(new SchedulerCustomFieldMapping("int", "int"));
//_ResourceStorage.CustomFieldMappings.Add(new SchedulerCustomFieldMapping("Jahr","int"));
_SchedulerControl.TimelineView.VerticalResourceHeaderStyle = (Style)FindResource("VerticalResourceHeaderStyle");
IMouseHandlerService oldMouseHandler = (IMouseHandlerService)_SchedulerControl.GetService(typeof(IMouseHandlerService));
if (oldMouseHandler != null)
{
MouseHandlerService newMouseHandler =
new MouseHandlerService(_SchedulerControl, oldMouseHandler);
_SchedulerControl.RemoveService(typeof(IMouseHandlerService));
_SchedulerControl.AddService(typeof(IMouseHandlerService), newMouseHandler);
}
_SchedulerControl.TimelineView.VerticalResourceHeaderStyle = (Style)FindResource("VerticalResourceHeaderStyle");
}
finally
{
_SchedulerControl.EndInit();
}
}
public void UpdateUrlaubkonto(long empOid)
{
_EmployeeDict[empOid].Urlaubskonto = ServiceFacade.DoOperationsServiceSync(x => x.GetUrlaubskontoByEmployee(empOid, 2020));
var xx = _ResourceStorage.GetResourceById(empOid.ToString());
xx.CustomFields[nameof(EmployeeDC)] = null;
xx.CustomFields[nameof(EmployeeDC)] = _EmployeeDict[empOid];
}
private void UpdateFilter()
{
_SelectedFilter = new AbsenceOverviewFilterDC
{
Year = (int)_YearPicker.SelectedItem,
Month = _MonthPicker.SelectedMonth
};
if (SelectedAbsenceReasons.Any())
_SelectedFilter.AbsenceReasons = SelectedAbsenceReasons.Select(x => x.AbsenceReasonOid.Value).ToList();
if (SelectedEmploymentTypes.Any())
_SelectedFilter.EmploymentType = SelectedEmploymentTypes.Select(x => x.EmploymentTypeOid.Value).ToList();
if (SelectedTeams.Any())
_SelectedFilter.Teams = SelectedTeams.Select(x => x.TeamOid).ToList();
}
public void UpdateScheduler()
{
var absenceReasons = _AbsenceReasonDCs;
var absenceOverview = ServiceFacade.DoOperationsServiceSync(x => x.GetAbsenceOverview(_SelectedFilter));
var start = new DateTime(_SelectedFilter.Year, _SelectedFilter.Month, 1);
try
{
_SchedulerStorage.BeginUpdate();
_SchedulerControl.LimitInterval = new TimeInterval(start, start.AddMonths(1).AddTicks(-1));
//var s = _SchedulerControl.SelectedInterval.Start;
_SchedulerControl.Start = start;
_SpinEdit.MinValue = 1;
_SpinEdit.MaxValue = DateTime.DaysInMonth(_SelectedFilter.Year, _SelectedFilter.Month);
_SpinEdit.Value = _SpinEdit.MaxValue.Value;
_LabelStorage.Clear();
foreach (var reason in absenceReasons)
{
var label = _LabelStorage.CreateNewLabel(reason.AbsenceReasonOid.ToString(), reason.Description);
if (!string.IsNullOrEmpty(reason.Color))
{
label.Color = (Color)ColorConverter.ConvertFromString(reason.Color);
}
_LabelStorage.Add(label);
}
_EmployeeDict.Clear();
_ResourceStorage.Clear();
_AppointmentStorage.Clear();
foreach (var employee in absenceOverview)
{
AbwesenheitsInformationDC infoDC = new AbwesenheitsInformationDC()
{
Employee = employee,
Month = _MonthPicker.SelectedMonth,
Year = (int)_YearPicker.SelectedItem,
AbsenceTimes = UrlaubsplanerRootObj.Abwesenheiten.Where(a => a.EmployeeOid == employee.EmployeeOid).ToList(),
GeschenkteUrlaubstage = UrlaubsplanerRootObj.GeschenkteUrlaubstage.Where(u => u.Employee == employee.EmployeeOid).ToList()
};
infoDC.TageUrlaub = CountUrlaubstage(infoDC);
infoDC.TageKrankheit = CountKrankheitstage(infoDC);
var resource = _SchedulerStorage.CreateResource(employee.EmployeeOid.Value.ToString());
resource.Caption = employee.LastNameFirstName;
resource.CustomFields[nameof(AbwesenheitsInformationDC)] = infoDC;
_EmployeeDict.Add(employee.EmployeeOid.Value, employee);
_ResourceStorage.Add(resource);
foreach (var absence in employee.AbsenceTimes)
{
var appointment = _SchedulerStorage.CreateAppointment(AppointmentType.Normal);
SchedulerHelper.OverrideAppointmentWithAbsenceTime(appointment, absence); //Auskommentieren entfernt Einträge aus Planer
_AppointmentStorage.Add(appointment);
}
}
}
finally
{
_SchedulerStorage.EndUpdate();
_SchedulerControl.Visibility = Visibility.Visible;
}
}
private void UpdateReportUrl(DateTime date) // Hier um gewählte Teams erweitern, um bei Druck danach filtern zu können
{
var url = BeWoApp.SiteOfOrigin
+ "/ReportView.aspx"
+ "?type=" + Utils.EnumName(ReportTypes.AbsenceReport)
+ "&dt=" + date.ToString("MM.yyyy");
if (SelectedAbsenceReasons.Any())
url += "&ar=" + string.Join(";", SelectedAbsenceReasons.Select(x => x.AbsenceReasonOid.Value));
if (SelectedEmploymentTypes.Any())
url += "&et=" + string.Join(";", SelectedEmploymentTypes.Select(x => x.EmploymentTypeOid.Value));
if (SelectedTeams.Any())
url += "&t=" + string.Join(";", SelectedTeams.Select(x => x.TeamOid));
if (_SelectedFilter == null)
_SelectedFilter = new AbsenceOverviewFilterDC() { Month = date.Month, Year = date.Year };
if (UrlaubsplanerRootObj.Feiertage != null)
{
List<int> feiertageInMonat = new List<int>();
foreach (var tag in UrlaubsplanerRootObj.Feiertage)
{
feiertageInMonat.Add(tag.Datum.Day);
}
if (feiertageInMonat.Count > 0)
{
url += "&f=" + string.Join(";", feiertageInMonat);
}
}
linkPdfExport.NavigateUri = new Uri(url);
}
private void VerticalHeaderControl_MouseDown(object sender, MouseButtonEventArgs e)
{
var temp = (VerticalHeaderControl)sender;
var c = (VisualResourceHeaderContent)temp.Content;
var info = c.CustomFields["AbwesenheitsInformationDC"] as AbwesenheitsInformationDC; //Hierin steht das AbwesenheitsInformationDC, aber man kommt nicht dran
var urlaubskonto = info.Employee.Urlaubskonto;
bool urlaubVerfallen = info.Month >= urlaubskonto.UrlaubsVerfallsdatum.Month ? true : false;
string xamlstring = ServiceFacade.DoOperationsServiceSync(s => s.GetInformationStringForUrlaubsplaner(urlaubskonto, info.TageUrlaub, info.TageKrankheit, urlaubVerfallen));
var control = new InformationView();
control.SetXaml(xamlstring);
var beWoWindow = new BeWoWindow();
control.ButtonCloseClicked += () => beWoWindow.Close();
beWoWindow.Height = 100;
beWoWindow.Width = 400;
beWoWindow.WindowStartupLocation = WindowStartupLocation.CenterOwner;
beWoWindow.GroupBoxContent = control;
beWoWindow.Owner = BeWoApp.CurrentBeWo.MainWindow;
beWoWindow.rootGroupBox.Header = "Infos zu " + info.Employee.LastNameFirstName;
beWoWindow.ShowDialog();
}
private decimal CountUrlaubstage(AbwesenheitsInformationDC info)
{
decimal tageUrlaub = 0;
List<AbsenceTimeDC> urlaubstage = new List<AbsenceTimeDC>();
foreach (var tag in info.AbsenceTimes)
{
if (tag.Reason.Description.Equals("Urlaub"))
urlaubstage.Add(tag);
}
if (urlaubstage.Count > 0)
{
foreach (var spanne in urlaubstage)
{
if (spanne.End == null)
spanne.End = new DateTime(info.Year, info.Month, DateTime.DaysInMonth(info.Year, info.Month));
// Nur ein Tag
if (spanne.Start == spanne.End)
tageUrlaub++;
// Mehrere Tage
else
{
// Alle Tage in einem Monat
if (spanne.Start.Value.Month == spanne.End.Value.Month)
tageUrlaub += Convert.ToInt32((spanne.End.Value.Date - spanne.Start.Value.Date).TotalDays + 1);
// Tage über Monate verteilt
else
{
DateTime? tempStart = null;
DateTime? tempEnd = null;
// Prüfen, ob Start und/oder Ende nicht dem ausgewählten Monat entspricht
if (spanne.Start.Value.Month != info.Month)
{
tempStart = new DateTime(info.Year, info.Month, 1);
}
if (spanne.End.Value.Month != info.Month)
{
tempEnd = new DateTime(info.Year, info.Month, 1).AddMonths(1).AddTicks(-1);
}
if (tempStart != null && tempEnd != null)
tageUrlaub += Convert.ToInt32((tempEnd.Value.Date - tempStart.Value.Date).TotalDays + 1);
else if (tempStart != null && tempEnd == null)
tageUrlaub += Convert.ToInt32((spanne.End.Value.Date - tempStart.Value.Date).TotalDays + 1);
else if (tempStart == null && tempEnd != null)
tageUrlaub += Convert.ToInt32((tempEnd.Value.Date - spanne.Start.Value.Date).TotalDays + 1);
}
}
}
}
return tageUrlaub;
}
private void ApplyCellStyles()
{
_SchedulerControl.TimelineView.CellStyle = (Style)this.FindResource("TimelineViewCellStyle");
}
private void ApplySelectionTemplate()
{
_SchedulerControl.TimelineView.SelectionTemplate = (ControlTemplate)this.FindResource("SelectionTemplate");
}
public void ApplyFeiertagCellStyle()
{
foreach (var feiertag in UrlaubsplanerRootObj.Feiertage)
{
_SchedulerControl.WorkDays.AddHoliday(feiertag.Datum, feiertag.Name);
}
}
private decimal CountKrankheitstage(AbwesenheitsInformationDC info)
{
int tageKrankheit = 0;
List<AbsenceTimeDC> krankheitstage = new List<AbsenceTimeDC>();
foreach (var tag in info.AbsenceTimes)
{
if (tag.Reason.Description.Equals("Krankheit"))
krankheitstage.Add(tag);
}
if (krankheitstage.Count > 0)
{
foreach (var spanne in krankheitstage)
{
// Nur ein Tag
if (spanne.Start == spanne.End)
tageKrankheit++;
// Mehrere Tage
else
{
// Wenn Krankheit ein Enddatum hat
if (spanne.End != null)
{
// Alle Tage in einem Monat
if (spanne.Start.Value.Month == spanne.End.Value.Month)
tageKrankheit += Convert.ToInt32((spanne.End.Value.Date - spanne.Start.Value.Date).TotalDays + 1);
// Tage über mehrere Monate verteilt
else
{
// Prüfen, ob Start und/oder Ende nicht dem ausgewählten Monat entspricht
DateTime? tempStart = null;
DateTime? tempEnd = null;
if (spanne.Start.Value.Month != info.Month)
{
tempStart = new DateTime(info.Year, info.Month, 1);
}
if (spanne.End.Value.Month != info.Month)
{
tempEnd = new DateTime(info.Year, info.Month, 1).AddMonths(1).AddTicks(-1);
}
if (tempStart != null && tempEnd != null)
tageKrankheit += Convert.ToInt32((tempEnd.Value.Date - tempStart.Value.Date).TotalDays + 1);
else if (tempStart != null && tempEnd == null)
tageKrankheit += Convert.ToInt32((spanne.End.Value.Date - tempStart.Value.Date).TotalDays + 1);
else if (tempStart == null && tempEnd != null)
tageKrankheit += Convert.ToInt32((tempEnd.Value.Date - spanne.Start.Value.Date).TotalDays + 1);
}
}
// Wenn Krankheit kein Enddatum gesetzt wurde
else
{
if (spanne.Start.Value.Month != info.Month)
{
DateTime tempEnd = new DateTime(info.Year, info.Month, DateTime.DaysInMonth(info.Year, info.Month));
DateTime tempStart = new DateTime(info.Year, info.Month, 1); ;
tageKrankheit += Convert.ToInt32((tempEnd.Date - tempStart.Date).TotalDays + 1);
}
else
{
DateTime tempEnd = new DateTime(spanne.Start.Value.Year, spanne.Start.Value.Month, DateTime.DaysInMonth(spanne.Start.Value.Year, spanne.Start.Value.Month));
tageKrankheit += Convert.ToInt32((tempEnd.Date - spanne.Start.Value.Date).TotalDays + 1);
}
}
}
}
}
return tageKrankheit;
}
}
public class MouseHandlerService : MouseHandlerServiceWrapper
{
IServiceProvider provider;
public MouseHandlerService(IServiceProvider provider, IMouseHandlerService service)
: base(service)
{
this.provider = provider;
}
public override void OnMouseWheel(System.Windows.Forms.MouseEventArgs e)
{
if ((System.Windows.Forms.Control.ModifierKeys & Keys.Control) != Keys.Control)
base.OnMouseWheel(e);
}
}
//public class TestConverter : MarkupExtension, IMultiValueConverter
//{
// public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
// {
// return values[0] is DateTime && values[1] is System.Collections.IList ? ((System.Collections.IList)values[1]).Contains(values[0]) : false;
// }
// public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
// {
// throw new NotImplementedException();
// }
// public override object ProvideValue(IServiceProvider serviceProvider)
// {
// return this;
// }
//}
public static class SchedulerHelper
{
public static void OverrideAppointmentWithAbsenceTime(Appointment appointment, AbsenceTimeDC absenceTime)
{
appointment.AllDay = true;
appointment.Subject = absenceTime.Reason.Description;
appointment.Start = absenceTime.Start.Value;
appointment.End = (absenceTime.End ?? DateTime.MaxValue.AddDays(-1)).AddHours(23);
appointment.ResourceId = absenceTime.EmployeeOid.Value.ToString();
appointment.LabelKey = absenceTime.Reason.AbsenceReasonOid.ToString();
appointment.Description = absenceTime.Notice;
appointment.CustomFields[nameof(AbsenceTimeDC)] = null;
appointment.CustomFields[nameof(AbsenceTimeDC)] = absenceTime;
}
}
}