Files

551 lines
23 KiB
C#
Raw Permalink Normal View History

2016-06-27 01:45:38 +02:00
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using BeWo.Data;
2016-06-27 01:45:38 +02:00
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
2016-06-27 01:45:38 +02:00
using BS.Shared.Extensions;
using Utils = BeWo.Service.Core.Utils;
2016-06-27 01:45:38 +02:00
namespace BeWo.Report.ReportObjects
{
public class KalenderRO : AbstractBeWoReportObject<KalenderRO>
{
public string PrintingEmployee { get; set; }
public List<SchedulerAppointment> Appointments { get; set; }
public List<KalenderTag> KalenderTageSortiert { get; set; }
public Dictionary<int, KalenderWoche> Wochen { get; set; }
public string PrintingDate => DateTime.Now.ToShortDateString();
public List<DateTime> SelectedDates { get; set; }
public List<long> AbsenceTimeOids { get; set; } = new List<long>();
2016-06-27 01:45:38 +02:00
public static KalenderRO Create(IEnumerable<long> appointmentOids, long? employeeOid, IEnumerable<SchedulerAppointmentDC> serientermine, IEnumerable<DateTime> selectedDates, IEnumerable<SchedulerAppointmentDC> mehrtaegigeTermine)
2016-06-27 01:45:38 +02:00
{
var appointments = DAOFactory.GenericDAO.LoadByIDs<SchedulerAppointment>(appointmentOids);
var employeeName = DAOFactory.GenericDAO.GetByID<Employee>(employeeOid.Value).Person.FirstNameLastName;
var kalendertage = new HashSet<KalenderTag>();
2016-06-27 01:45:38 +02:00
var wochen = new Dictionary<int, KalenderWoche>();
var recurringAppointments = CreateRecurringAppointments(serientermine);
2016-06-27 01:45:38 +02:00
var mapper = new SchedulerAppointmentDC_SchedulerAppointment();
var recurringSchedulerAppointments = mapper.MapToNewEntities(recurringAppointments);
var mehrtaegigeSchedulerAppointments = mapper.MapToNewEntities(mehrtaegigeTermine);
2016-06-27 01:45:38 +02:00
appointments.AddRange(mehrtaegigeSchedulerAppointments);
appointments.AddRange(recurringSchedulerAppointments);
appointments = appointments.Where(w => w.StartDate != null && selectedDates.Any(a => a.CompareShortDates(w.StartDate.Value))).OrderBy(o => o.StartDate).ToList();
2016-06-27 01:45:38 +02:00
// ganztägige Termine beachten
foreach (var app in appointments)
{
var datum = app.StartDate.Value.ToString("dd. MMMM yyyy");
if (!kalendertage.Any(k => k.Datum.Equals(datum)))
2016-06-27 01:45:38 +02:00
{
kalendertage.Add(new KalenderTag(new List<AppointmentStruct> {new AppointmentStruct {Appointment = DAOFactory.GenericDAO.Unproxy(app)}}));
2016-06-27 01:45:38 +02:00
}
else
{
var kt = kalendertage.First(f => f.Datum.Equals(datum));
2017-08-28 16:41:19 +02:00
kt.Termine.Add(new AppointmentStruct { Appointment = DAOFactory.GenericDAO.Unproxy(app) });
2016-06-27 01:45:38 +02:00
}
}
Calendar calendar = new GregorianCalendar();
2016-06-27 01:45:38 +02:00
foreach (var kalendertag in kalendertage)
2016-06-27 01:45:38 +02:00
{
var wt = calendar.GetWeekOfYear(kalendertag.Date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
2016-06-27 01:45:38 +02:00
if (wochen.ContainsKey(wt))
{
wochen[wt].AddDayToWeek(kalendertag);
2016-06-27 01:45:38 +02:00
}
else
{
wochen.Add(wt, new KalenderWoche(wt, kalendertag));
2016-06-27 01:45:38 +02:00
}
}
return new KalenderRO
{
Appointments = appointments,
PrintingEmployee = employeeName,
KalenderTageSortiert = kalendertage.ToList().OrderBy(o=>o.Date).ToList(),
Wochen = wochen,
SelectedDates = selectedDates.ToList()
2016-06-27 01:45:38 +02:00
};
}
public static KalenderRO CreateWithAbsenceTimes(IEnumerable<long> appointmentOids, long? employeeOid, IEnumerable<SchedulerAppointmentDC> serientermine, IList<DateTime> selectedDates, IEnumerable<SchedulerAppointmentDC> mehrtaegigeTermine, List<long> absenceTimeOids)
{
var appointments = DAOFactory.GenericDAO.LoadByIDs<SchedulerAppointment>(appointmentOids);
var employeeName = DAOFactory.GenericDAO.GetByID<Employee>(employeeOid.Value).Person.FirstNameLastName;
var kalendertage = new HashSet<KalenderTag>();
var wochen = new Dictionary<int, KalenderWoche>();
var absenceTimes = MapperFactory.AbsenceTimeDC_AbsenceTime.MapToNewDCs(DAOFactory.GenericDAO.LoadByIDs<AbsenceTime>(absenceTimeOids));
var absenceTimeEmployees = MapperFactory.CompactEmployeeDC_Employee.MapToNewDCs(DAOFactory.GenericDAO.LoadByIDs<Employee>(absenceTimes.Where(at => at.EmployeeOid.HasValue).Select(at => at.EmployeeOid.Value)));
var absenceTimeCustomers = MapperFactory.CompactCustomerDC_Customer.MapToNewDCs(DAOFactory.GenericDAO.LoadByIDs<Customer>(absenceTimes.Where(at => at.CustomerOid.HasValue).Select(at => at.CustomerOid.Value)));
var mehrtaegigeAbwesenheiten = GenerateSeveralDaysAbsenceTimeAppointments(absenceTimes.Where(absenceTime => absenceTime.Start.HasValue && (absenceTime.End is null || absenceTime.Start.Value.GetDayNumberBetweenTwoDates(absenceTime.End.Value) > 0)).ToList(), selectedDates.ToList(), absenceTimeEmployees, absenceTimeCustomers);
var eintagsabwesenheiten = ConvertSingleDayAbsenceTimes(absenceTimes.Where(w => w.Start.HasValue && w.End.HasValue && w.Start.Value.GetDayNumberBetweenTwoDates(w.End.Value) == 0).ToList(), selectedDates.ToList());
var recurringAppointments = CreateRecurringAppointments(serientermine);
var mapper = new SchedulerAppointmentDC_SchedulerAppointment();
var recurringSchedulerAppointments = mapper.MapToNewEntities(recurringAppointments);
var mehrtaegigeSchedulerAppointments = mapper.MapToNewEntities(mehrtaegigeTermine);
appointments.AddRange(mapper.MapToNewEntities(eintagsabwesenheiten));
appointments.AddRange(mapper.MapToNewEntities(mehrtaegigeAbwesenheiten));
appointments.AddRange(mehrtaegigeSchedulerAppointments);
appointments.AddRange(recurringSchedulerAppointments);
appointments = appointments.Where(w => w.StartDate.HasValue && selectedDates.Any(a => a.CompareShortDates(w.StartDate.Value))).OrderBy(o => o.StartDate).ToList();
// Die KalenderTag-Objekte werden aus SchedulerAppointments erstellt
CreateKalendertage(kalendertage, appointments);
CreateKalenderwochen(wochen, kalendertage);
return new KalenderRO
{
Appointments = appointments,
PrintingEmployee = employeeName,
KalenderTageSortiert = kalendertage.ToList().OrderBy(o => o.Date).ToList(),
Wochen = wochen,
SelectedDates = selectedDates.ToList(),
AbsenceTimeOids = absenceTimeOids
};
}
public static List<SchedulerAppointmentDC> GenerateSeveralDaysAbsenceTimeAppointments(List<AbsenceTimeDC> absenceTimes, List<DateTime> selectedDates, List<CompactEmployeeDC> employees, List<CompactCustomerDC> customers)
{
var intervalEnd = selectedDates[0];
var intervalStart = selectedDates[0];
foreach(var date in selectedDates)
{
if(date > intervalEnd)
{
intervalEnd = date;
}
if(date < intervalStart)
{
intervalStart = date;
}
}
var result = new List<SchedulerAppointmentDC>();
foreach(var absenceTime in absenceTimes)
{
if(absenceTime.Start is null)
{
continue;
}
if(absenceTime.End is null)
{
absenceTime.End = intervalEnd.AddDays(1);
}
var employee = employees.FirstOrDefault(e => e.EmployeeOid.Equals(absenceTime.EmployeeOid));
var customer = customers.FirstOrDefault(c => c.CustomerOid.Equals(absenceTime.CustomerOid));
var isAllDayAbsenceTime = absenceTime.Start.Value.IsTimeZero() && absenceTime.End.Value.IsTimeZero();
// Bei einem Tag gibt die Funktion 0 zurück!
var dayCount = absenceTime.Start.Value.GetDayNumberBetweenTwoDates(absenceTime.End.Value) + 1;
if(dayCount > 31)
{
dayCount = 31;
}
if(dayCount > 0)
{
if(isAllDayAbsenceTime)
{
for(var i = 0; i < dayCount; i++)
{
var startDate = new DateTime(absenceTime.Start.Value.AddDays(i).Year, absenceTime.Start.Value.AddDays(i).Month, absenceTime.Start.Value.AddDays(i).Day);
var endDate = new DateTime(absenceTime.Start.Value.AddDays(i + 1).Year, absenceTime.Start.Value.AddDays(i + 1).Month, absenceTime.Start.Value.AddDays(i + 1).Day);
if(startDate < intervalStart || startDate > intervalEnd)
{
continue;
}
result.Add(CreateAppointmentFromAbsenceTime(startDate, endDate, absenceTime, employee, customer));
}
}
else
{
for(var i = 0; i < dayCount; i++)
{
DateTime startDate;
DateTime endDate;
if(i == 0)
{
startDate = absenceTime.Start.Value;
endDate = new DateTime(absenceTime.Start.Value.AddDays(1).Year, absenceTime.Start.Value.AddDays(1).Month, absenceTime.Start.Value.AddDays(1).Day);
}
else if(i == dayCount - 1)
{
startDate = new DateTime(absenceTime.End.Value.Year, absenceTime.End.Value.Month, absenceTime.End.Value.Day);
endDate = absenceTime.End.Value;
}
else
{
startDate = new DateTime(absenceTime.Start.Value.AddDays(i).Year, absenceTime.Start.Value.AddDays(i).Month, absenceTime.Start.Value.AddDays(i).Day);
endDate = new DateTime(absenceTime.Start.Value.AddDays(i + 1).Year, absenceTime.Start.Value.AddDays(i + 1).Month, absenceTime.Start.Value.AddDays(i + 1).Day);
}
if(startDate < intervalStart || startDate > intervalEnd)
{
continue;
}
result.Add(CreateAppointmentFromAbsenceTime(startDate, endDate, absenceTime, employee, customer));
}
}
}
}
return result;
}
private static SchedulerAppointmentDC CreateAppointmentFromAbsenceTime(DateTime start, DateTime end, AbsenceTimeDC absenceTime, CompactEmployeeDC employee, CompactCustomerDC customer)
{
if(employee is null && customer is null)
{
throw new ArgumentNullException(nameof(employee), "employee und customer dürfen nicht beide null sein!");
}
var isCustomerAbsenceTime = employee is null;
var originator = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(DAOFactory.SearchDAO.FindEmployeeByFullname(absenceTime.InsUser));
if(originator is null)
{
if(isCustomerAbsenceTime)
{
var user = LoggedInUserOperationContextExt.Current?.User != null ? LoggedInUserOperationContextExt.Current.User : SessionFacade.LoggedInUser;
if(user?.Employee is null)
{
return null;
}
originator = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(user.Employee);
}
else
{
originator = employee;
}
}
var simpleDescription = isCustomerAbsenceTime ? customer.SimpleDescription : employee.SimpleDescription;
var isAllDay = start.IsTimeZero() && end.IsTimeZero();
var appointment = new SchedulerAppointmentDC
{
AllDay = isAllDay,
StartDate = start,
EndDate = end,
Originator = originator,
Subject = $"{absenceTime.Reason} ({simpleDescription})"
};
#if DEBUG
appointment.Subject = $"({(isCustomerAbsenceTime ? "K" : "M")}{absenceTime.AbsenceTimeOid}) {absenceTime.Reason} ({simpleDescription})";
#endif
return appointment;
}
public static List<SchedulerAppointmentDC> CreateRecurringAppointments(IEnumerable<SchedulerAppointmentDC> serientermine)
{
var recurringAppointments = serientermine.ToList();
var recurrenceIds2Appointments = new Dictionary<string, List<SchedulerAppointment>>();
var test = recurringAppointments.Where(w => !(w.RecurrenceInfo is null)).Select(s => s.RecurrenceInfo).ToList();
foreach(var recurrenceInfo in test)
{
var id = Utils.GetRecurrenceIdFromRecurrenceInfo(recurrenceInfo);
if(!recurrenceIds2Appointments.ContainsKey(id))
{
recurrenceIds2Appointments.Add(id, new List<SchedulerAppointment>());
}
}
foreach(var kvp in recurrenceIds2Appointments)
{
kvp.Value.AddRange(DAOFactory.SearchDAO.FindDeletedRecurrencesByRecurrenceId(kvp.Key).ToList());
}
foreach(var kvp in recurrenceIds2Appointments)
{
foreach(var appointment in kvp.Value)
{
var start = appointment.StartDate;
var end = appointment.EndDate;
var theOneToDelete = recurringAppointments.FirstOrDefault(w => w.RecurrenceInfo.Contains(kvp.Key) && w.StartDate == start && w.EndDate == end);
if(!(theOneToDelete is null))
{
recurringAppointments.Remove(theOneToDelete);
}
}
}
return recurringAppointments;
}
public static void CreateKalendertage(HashSet<KalenderTag> kalendertage, List<SchedulerAppointment> appointments)
{
foreach(var app in appointments)
{
if(app.StartDate is null)
{
continue;
}
var datum = app.StartDate.Value.ToString("dd. MMMM yyyy");
if(!kalendertage.Any(k => k.Datum.Equals(datum)))
{
kalendertage.Add(new KalenderTag(new List<AppointmentStruct> { new AppointmentStruct { Appointment = DAOFactory.GenericDAO.Unproxy(app) } }));
}
else
{
var kt = kalendertage.First(f => f.Datum.Equals(datum));
kt.Termine.Add(new AppointmentStruct { Appointment = DAOFactory.GenericDAO.Unproxy(app) });
}
}
}
public static void CreateKalenderwochen(Dictionary<int, KalenderWoche> weeks, HashSet<KalenderTag> kalendertage)
{
Calendar calendar = new GregorianCalendar();
foreach(var kalendertag in kalendertage)
{
var weekOfYear = calendar.GetWeekOfYear(kalendertag.Date, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
if(weeks.ContainsKey(weekOfYear))
{
weeks[weekOfYear].AddDayToWeek(kalendertag);
}
else
{
weeks.Add(weekOfYear, new KalenderWoche(weekOfYear, kalendertag));
}
}
}
/// <summary>
/// Konvertiert AbsenceTimeDCs in SchedulerAppointmentDCs von eintägigen Abwesenheiten.
/// </summary>
/// <param name="absenceTimes">Die eintägiten Abwesenheiten.</param>
/// <param name="selectedDates">Zeitraum der ausgedruckt werden soll.</param>
/// <returns></returns>
public static List<SchedulerAppointmentDC> ConvertSingleDayAbsenceTimes(List<AbsenceTimeDC> absenceTimes, List<DateTime> selectedDates)
{
var result = new List<SchedulerAppointmentDC>();
var lastDate = selectedDates[0];
foreach(var date in selectedDates)
{
if(date < lastDate)
{
lastDate = date;
}
}
var employees = MapperFactory.CompactEmployeeDC_Employee.MapToNewDCs(DAOFactory.GenericDAO.LoadByIDs<Employee>(absenceTimes.Where(absenceTime => absenceTime.EmployeeOid.HasValue).Select(absenceTime => absenceTime.EmployeeOid.Value)));
var customers = MapperFactory.CompactCustomerDC_Customer.MapToNewDCs(DAOFactory.GenericDAO.LoadByIDs<Customer>(absenceTimes.Where(absenceTime => absenceTime.CustomerOid.HasValue).Select(absenceTime => absenceTime.CustomerOid.Value)));
foreach(var absenceTime in absenceTimes)
{
var appointment = ConvertAbsenceTimeToAppointment(absenceTime, lastDate, employees, customers);
if(!(appointment is null))
{
result.Add(appointment);
}
}
return result;
}
public static SchedulerAppointmentDC ConvertAbsenceTimeToAppointment(AbsenceTimeDC absenceTime, DateTime intervalEnd, List<CompactEmployeeDC> employees, List<CompactCustomerDC> customers)
{
if(absenceTime.Start is null)
{
return null;
}
var employee = absenceTime.EmployeeOid.HasValue ? employees.FirstOrDefault(emp => emp.EmployeeOid == absenceTime.EmployeeOid.Value) : null;
var customer = absenceTime.CustomerOid.HasValue ? customers.FirstOrDefault(cus => cus.CustomerOid == absenceTime.CustomerOid.Value) : null;
var isEmployeeAbsenceTime = !(employee is null);
var originator = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(DAOFactory.SearchDAO.FindEmployeeByFullname(absenceTime.InsUser));
if(isEmployeeAbsenceTime && originator is null)
{
originator = employee;
}
if(!isEmployeeAbsenceTime && originator is null)
{
var user = LoggedInUserOperationContextExt.Current?.User != null ? LoggedInUserOperationContextExt.Current.User : SessionFacade.LoggedInUser;
if(user?.Employee is null)
{
return null;
}
originator = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(user.Employee);
}
var lastNameCommaFirstName = isEmployeeAbsenceTime ? employee.SimpleDescription : customer?.SimpleDescription;
var endDate = intervalEnd;
if(absenceTime.End.HasValue)
{
endDate = absenceTime.End.Value;
}
var isAllDay = absenceTime.Start.Value.IsTimeZero() && endDate.IsTimeZero();
var appointment = new SchedulerAppointmentDC
{
AllDay = isAllDay,
StartDate = absenceTime.Start.Value,
EndDate = endDate,
Originator = originator,
Subject = $"{absenceTime.Reason} ({lastNameCommaFirstName})"
};
#if DEBUG
appointment.Subject = $"({(isEmployeeAbsenceTime ? "M" : "K")}{absenceTime.AbsenceTimeOid}) {absenceTime.Reason} ({lastNameCommaFirstName})";
#endif
return appointment;
}
2016-06-27 01:45:38 +02:00
}
public class KalenderWoche
{
public KalenderTag Montag { get; set; }
public KalenderTag Dienstag { get; set; }
public KalenderTag Mittwoch { get; set; }
public KalenderTag Donnerstag { get; set; }
public KalenderTag Freitag { get; set; }
public KalenderTag Samstag { get; set; }
public KalenderTag Sonntag { get; set; }
public int Wochennummer { get; set; }
public KalenderWoche(int wochennummer, KalenderTag kalenderTag)
{
Wochennummer = wochennummer;
var eWt = kalenderTag.Date.FirstDateOfWeek(wochennummer);
Montag = new KalenderTag(new List<AppointmentStruct>()) { Datum = eWt.ToShortDateString(), Date = eWt };
Dienstag = new KalenderTag(new List<AppointmentStruct>()) { Datum = eWt.AddDays(1).ToShortDateString(), Date = eWt.AddDays(1) };
Mittwoch = new KalenderTag(new List<AppointmentStruct>()) { Datum = eWt.AddDays(2).ToShortDateString(), Date = eWt.AddDays(2) };
Donnerstag = new KalenderTag(new List<AppointmentStruct>()) { Datum = eWt.AddDays(3).ToShortDateString(), Date = eWt.AddDays(3) };
Freitag = new KalenderTag(new List<AppointmentStruct>()) { Datum = eWt.AddDays(4).ToShortDateString(), Date = eWt.AddDays(4) };
Samstag = new KalenderTag(new List<AppointmentStruct>()) { Datum = eWt.AddDays(5).ToShortDateString(), Date = eWt.AddDays(5) };
Sonntag = new KalenderTag(new List<AppointmentStruct>()) { Datum = eWt.AddDays(6).ToShortDateString(), Date = eWt.AddDays(6) };
AddDayToWeek(kalenderTag);
}
public void AddDayToWeek(KalenderTag day)
{
switch (day.Date.DayOfWeek)
{
case DayOfWeek.Monday:
Montag = day;
break;
case DayOfWeek.Tuesday:
Dienstag = day;
break;
case DayOfWeek.Wednesday:
Mittwoch = day;
break;
case DayOfWeek.Thursday:
Donnerstag = day;
break;
case DayOfWeek.Friday:
Freitag = day;
break;
case DayOfWeek.Saturday:
Samstag = day;
break;
case DayOfWeek.Sunday:
Sonntag = day;
break;
}
}
}
public class KalenderTag
{
public string Datum { get; set; }
public DateTime Date { get; set; }
public List<AppointmentStruct> Termine { get; set; }
public KalenderTag(List<AppointmentStruct> termine)
{
Termine = termine;
Datum = termine.Count > 0 ? termine.First().Appointment.StartDate.Value.ToString("dd. MMMM yyyy") : string.Empty;
if (termine.Count > 0)
{
var d = termine.First().Appointment.StartDate.Value;
Date = new DateTime(d.Year, d.Month, d.Day);
}
}
}
public struct AppointmentStruct
{
public string VonBisString
{
get
{
var result = string.Empty;
2016-06-27 01:45:38 +02:00
if (Appointment.AllDay)
{
result = "Ganztägig";
}
else
{
result = Appointment.StartDate.HasValue ? $"{Appointment.StartDate.Value.ToShortTimeString()} - {Appointment.EndDate.Value.ToShortTimeString()}"
: string.Empty;
2016-06-27 01:45:38 +02:00
}
return result;
}
}
public string SubjectLocationString => !string.IsNullOrEmpty(Appointment.Location) ? $"{Appointment.Subject} ({Appointment.Location})" : Appointment.Subject;
2016-06-27 01:45:38 +02:00
public SchedulerAppointment Appointment { get; set; }
2016-06-27 01:45:38 +02:00
}
}