diff --git a/BeWo/Scheduler/View/NewSchedulerView.xaml b/BeWo/Scheduler/View/NewSchedulerView.xaml index 580f4aa95..e2fad1077 100644 --- a/BeWo/Scheduler/View/NewSchedulerView.xaml +++ b/BeWo/Scheduler/View/NewSchedulerView.xaml @@ -1009,7 +1009,7 @@ diff --git a/Data/Access/SearchDAO.cs b/Data/Access/SearchDAO.cs index ed62bb428..6def5d32d 100644 --- a/Data/Access/SearchDAO.cs +++ b/Data/Access/SearchDAO.cs @@ -17,12 +17,16 @@ using NHibernate.SqlCommand; using BS.Shared.Core; using BS.Shared; +using BS.Shared.DataContracts; +using static System.String; using Login = BeWo.Data.Entities.Login; namespace BeWo.Data.Access { public class SearchDAO : AbstractBaseDAO { + private static Regex RecurrenceIdRegex = new Regex("(Id=\\\"[a-z0-9-]+\\\")"); + public IEnumerable FindValueListEntry(ValueListEntryType pType) { return CreateCriteria().Add(Restrictions.Eq(ValueListEntry.PropertyName_Type, pType)).AddOrder(Order.Asc(ValueListEntry.PropertyName_Value)).List(); @@ -45,7 +49,7 @@ namespace BeWo.Data.Access public virtual Employee FindEmployeeByFullname(string pFullname) { - var q = Session.CreateSQLQuery(string.Format("SELECT Oid FROM Person WHERE CONCAT_WS(' ', FirstName, LastName) LIKE '%{0}%'", pFullname)); + var q = Session.CreateSQLQuery(Format("SELECT Oid FROM Person WHERE CONCAT_WS(' ', FirstName, LastName) LIKE '%{0}%'", pFullname)); var x = q.List(); return x.Count > 0 ? DAOFactory.GenericDAO.GetByID(x.First()) : null; @@ -63,7 +67,7 @@ namespace BeWo.Data.Access public virtual Wohnheim FindWohnheimByFullname(string pWohnheimName) { - var q = Session.CreateSQLQuery(string.Format("SELECT Oid FROM Wohnheim WHERE CONCAT_WS(' ', WohnheimName) LIKE '%{0}%'", pWohnheimName)); + var q = Session.CreateSQLQuery(Format("SELECT Oid FROM Wohnheim WHERE CONCAT_WS(' ', WohnheimName) LIKE '%{0}%'", pWohnheimName)); var x = q.List(); return x.Count > 0 ? DAOFactory.GenericDAO.GetByID(x.First()) : null; @@ -401,7 +405,7 @@ namespace BeWo.Data.Access lCriteria = lCriteria.CreateCriteria(SupportConcept.PropertyName_Customer, JoinType.InnerJoin); - if (!String.IsNullOrEmpty(pCustomerReferenceNumber)) + if (!IsNullOrEmpty(pCustomerReferenceNumber)) lCriteria.Add(Restrictions.Eq(Customer.PropertyName_ReferenceNumber, pCustomerReferenceNumber)); if (!Utils.AreAllNullOrEmpty(pCustomerFirstName, pCustomerLastName)) @@ -1555,7 +1559,7 @@ namespace BeWo.Data.Access var c = CreateCriteriaIsActive(); c.Add(Restrictions.Eq(Wohnheimbuchung.PropertyName_Buchungsdatum, pBuchungsdatum)) - .Add(Restrictions.Eq(String.Format("{0}.Oid", Wohnheimbuchung.PropertyName_Wohnheim), pWohnheimOid)); + .Add(Restrictions.Eq(Format("{0}.Oid", Wohnheimbuchung.PropertyName_Wohnheim), pWohnheimOid)); return c.UniqueResult(); } @@ -1986,7 +1990,7 @@ namespace BeWo.Data.Access .Add(Restrictions.Eq(ChatMessage.PropertyName_TeamOid, pRecipientOid)); } - if (!string.IsNullOrEmpty(pMessageId)) + if (!IsNullOrEmpty(pMessageId)) { var c1 = CreateCriteriaIsActive() .Add(Restrictions.Eq(ChatMessage.PropertyName_MessageId, pMessageId)) @@ -2224,7 +2228,7 @@ namespace BeWo.Data.Access public IList LoadFilteredAppointments(bool pHasRightToSeeAllEmployeeAppointments, long pEmployeeOid, DateTime pIntervalStart, DateTime pIntervalEnd, List pSelectedEmployees, List pSelectedCustomers, List pSelectedResources, bool pEmployeesOnly, bool pCustomersOnly, bool pResourcesOnly, bool pPrivateAppointmentsOnly, bool pOnlyMyAppointments, bool pIncludeInactiveOnes) { - var recurrenceBetween = string.Format("'{0:yyyy-MM-dd} 00:00:00' BETWEEN STR_TO_DATE(SUBSTRING({1}, 24, 19), '%m/%d/%Y %H:%i:%s') AND STR_TO_DATE(SUBSTRING({1}, 50, 19), '%m/%d/%Y %H:%i:%s')", pIntervalStart, SchedulerAppointment.PropertyName_RecurrenceInfo); + var recurrenceBetween = Format("'{0:yyyy-MM-dd} 00:00:00' BETWEEN STR_TO_DATE(SUBSTRING({1}, 24, 19), '%m/%d/%Y %H:%i:%s') AND STR_TO_DATE(SUBSTRING({1}, 50, 19), '%m/%d/%Y %H:%i:%s')", pIntervalStart, SchedulerAppointment.PropertyName_RecurrenceInfo); var criteria = CreateCriteria(); @@ -2451,11 +2455,10 @@ namespace BeWo.Data.Access var exceptionalRecurrenceInfos = appointments.Where(w => w.RecurrenceInfo != null && w.Type == 3).ToList(); var exceptionIds = new List(); - var regex = new Regex("(Id=\\\"[a-z0-9-]+\\\")"); foreach(var appointment in exceptionalRecurrenceInfos) { - var match = regex.Match(appointment.RecurrenceInfo); + var match = RecurrenceIdRegex.Match(appointment.RecurrenceInfo); if(match.Success) { var value = match.Value; @@ -2472,6 +2475,8 @@ namespace BeWo.Data.Access } } + // Serienausnahmen werden als gelöscht markiert und es wird die RecurrenceInfo entfernt. + // Der Type wird auf "normal" gesetzt, damit nicht die ganze Serie angezeigt werden muss, die unter Umständen nichts mit den Filterkriterien zu tun hat. var exceptionsToModify = appointments.Where(w => w.Oid.HasValue && exceptionIds.Contains(w.Oid.Value)).ToList(); foreach(var exception in exceptionsToModify) @@ -2493,28 +2498,12 @@ namespace BeWo.Data.Access appointments.Add(replacingAppointment); } - // Wenn ein Serientermin bearbeitet wird, sodass er außerhalb des Fetch-Zeitraumes liegt, wird er nicht mehr korrekt angezeigt. // Deshalb werden hier alle Ausnahmen von den in der appointments-Collection enthaltenen Terminen mitgeladen. - var recurrenceIds = new List(); - var allExceptionalRecurrenceInfos = appointments.Where(w => w.RecurrenceInfo != null); - foreach(var appointment in allExceptionalRecurrenceInfos) - { - var match = regex.Match(appointment.RecurrenceInfo); - if(match.Success) - { - var value = match.Value; - var actualId = value.Split("\""); - if(actualId.Count > 1) - { - recurrenceIds.AddIfNotIn(actualId[1]); - } - } - } - - var changedOrDeletedOccurences = FindAppointmentsByRecurrenceId(recurrenceIds, true); + + var changedOrDeletedOccurences = FindAppointmentsByRecurrenceId(ExtractRecurrenceIdFromRecurrenceInfo(allExceptionalRecurrenceInfos.Select(s => s.RecurrenceInfo).ToList()), true); appointments.AddRangeIfElementsNotIn(changedOrDeletedOccurences); @@ -2562,7 +2551,7 @@ namespace BeWo.Data.Access private ICriteria CreateRecurrenceCriteria(DateTime start, DateTime end, bool pIncludeInactiveOnes = false) { - var recurrenceBetween = string.Format("'{0:yyyy-MM-dd} 00:00:00' BETWEEN STR_TO_DATE(SUBSTRING({1}, 24, 19), '%m/%d/%Y %H:%i:%s') AND STR_TO_DATE(SUBSTRING({1}, 50, 19), '%m/%d/%Y %H:%i:%s')", start, SchedulerAppointment.PropertyName_RecurrenceInfo); + var recurrenceBetween = Format("'{0:yyyy-MM-dd} 00:00:00' BETWEEN STR_TO_DATE(SUBSTRING({1}, 24, 19), '%m/%d/%Y %H:%i:%s') AND STR_TO_DATE(SUBSTRING({1}, 50, 19), '%m/%d/%Y %H:%i:%s')", start, SchedulerAppointment.PropertyName_RecurrenceInfo); var recurrenceAfter = $"'{start:yyyy-MM-dd} 00:00:00' > STR_TO_DATE(SUBSTRING({SchedulerAppointment.PropertyName_RecurrenceInfo}, 24, 19), '%m/%d/%Y %H:%i:%s')"; var criteria = CreateCriteria("sa"); @@ -2602,12 +2591,23 @@ namespace BeWo.Data.Access return c.List(); } + public IList FindAppointmentsByRecurrenecInfo(List pRecurrenceInfos, bool pExcludeRootAppointments = false) + { + if(pRecurrenceInfos == null || pRecurrenceInfos.Count == 0) + { + return new List(); + } + + return FindAppointmentsByRecurrenceId(ExtractRecurrenceIdFromRecurrenceInfo(pRecurrenceInfos), pExcludeRootAppointments); + } + public IList FindAppointmentsByRecurrenceId(List pRecurrenceIds, bool pExcludeRootAppointments = false) { if (pRecurrenceIds == null || pRecurrenceIds.Count == 0) { return new List(); } + var criterionList = new List(); pRecurrenceIds.DoForEach(id => @@ -2669,5 +2669,96 @@ namespace BeWo.Data.Access return q.List(); } + + public SchedulerAppointment FindRootAppointmentForException(SchedulerAppointmentDC pAppointment) + { + if(pAppointment?.RecurrenceInfo == null) + { + return null; + } + + var match = RecurrenceIdRegex.Match(pAppointment.RecurrenceInfo); + if(match.Success) + { + var value = match.Value; + var actualId = value.Split("\""); + if(actualId.Count > 1) + { + var id = actualId[1]; + + var criteria = CreateCriteria() + .Add(Restrictions.IsNotNull(nameof(SchedulerAppointment.RecurrenceInfo))) + .Add(Restrictions.Like(nameof(SchedulerAppointment.RecurrenceInfo), id, MatchMode.Anywhere)) + .Add(Restrictions.Eq(nameof(Appointment.Type), 1)); + + var resultList = criteria.List(); + + if(resultList == null || resultList.Count == 0) + { + return null; + } + + return resultList.First(); + } + } + + return null; + } + + public SchedulerAppointment FindRootAppointmentForException(SchedulerAppointment pAppointment) + { + if(pAppointment?.RecurrenceInfo == null) + { + return null; + } + + var match = RecurrenceIdRegex.Match(pAppointment.RecurrenceInfo); + if(match.Success) + { + var value = match.Value; + var actualId = value.Split("\""); + if(actualId.Count > 1) + { + var id = actualId[1]; + + var criteria = CreateCriteria() + .Add(Restrictions.IsNotNull(nameof(SchedulerAppointment.RecurrenceInfo))) + .Add(Restrictions.Like(nameof(SchedulerAppointment.RecurrenceInfo), id, MatchMode.Anywhere)) + .Add(Restrictions.Eq(nameof(Appointment.Type), 1)); + + var resultList = criteria.List(); + + if(resultList == null || resultList.Count == 0) + { + return null; + } + + return resultList.First(); + } + } + + return null; + } + + private static List ExtractRecurrenceIdFromRecurrenceInfo(List pRecurrenceInfos) + { + var recurrenceIds = new List(); + + foreach(var info in pRecurrenceInfos) + { + var match = RecurrenceIdRegex.Match(info); + if(match.Success) + { + var value = match.Value; + var actualId = value.Split("\""); + if(actualId.Count > 1) + { + recurrenceIds.AddIfNotIn(actualId[1]); + } + } + } + + return recurrenceIds; + } } } diff --git a/Service/ServiceImplementations/ResourceServiceImp.cs b/Service/ServiceImplementations/ResourceServiceImp.cs index 7cca04e02..2d737b106 100644 --- a/Service/ServiceImplementations/ResourceServiceImp.cs +++ b/Service/ServiceImplementations/ResourceServiceImp.cs @@ -18,6 +18,7 @@ using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using DevExpress.XtraScheduler; +using static System.String; using Resource = BeWo.Data.Entities.Resource; using Utils = BeWo.Service.Core.Utils; @@ -1061,11 +1062,13 @@ namespace BeWo.Service.ServiceImplementations { ownerOid = pEmployeeOid; } + //Benutzer hat sich selber selektiert if (pSelectedEmployees != null && pSelectedEmployees.Exists(e => e == pEmployeeOid)) { ownerOid = pEmployeeOid; } + //Man hat nur Customer und/oder Resourcen ausgewählt, dann dürfen die eigenen nicht angezeigt werden if ((pSelectedEmployees == null || pSelectedEmployees.Count == 0) && (pSelectedCustomer != null && pSelectedCustomer.Count > 0 || @@ -1073,6 +1076,7 @@ namespace BeWo.Service.ServiceImplementations { ownerOid = null; } + //Wenn man kein Recht hat alle zu sehen, muss immer auf Owner gefiltert werden if (!pHasRightToSeeAllEmployeeAppointments) { @@ -1098,7 +1102,7 @@ namespace BeWo.Service.ServiceImplementations var all = MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDCs(appointments).OrderBy(a => a.StartDate).ToList(); - List filteredEmployeeOids = new List(); + var filteredEmployeeOids = new List(); if (ownerOid.HasValue) { filteredEmployeeOids.Add(ownerOid.Value); @@ -1112,82 +1116,12 @@ namespace BeWo.Service.ServiceImplementations } } - List result = new List(); - - //Filter alle Termine raus, die vom Ersteller für andere MAs erstellt wurden - foreach (var app in all) - { - bool add = true; - if (app.Originator != null && app.Originator.EmployeeOid == pEmployeeOid) - { - if (app.EmployeeList != null && app.EmployeeList.Count > 0) - { - add = false; - foreach (var emp in app.EmployeeList) - { - if (filteredEmployeeOids.Contains(emp.Employee.EmployeeOid)) - { - add = true; - } - } - } - } - //Prüfe Klienten Filter - if (!add) - { - if (app.CustomerList != null && app.CustomerList.Count > 0) - { - if (pCustomersOnly) - { - add = true; - } - else if (pSelectedCustomer != null && pSelectedCustomer.Count > 0) - { - foreach (var cust in app.CustomerList) - { - if (pSelectedCustomer.Contains(cust.CustomerOid)) - { - add = true; - } - } - } - - - } - } - //Prüfe Resourcen Filter - if (!add) - { - if (app.ResourceList != null && app.ResourceList.Count > 0) - { - if (pResourcesOnly) - { - add = true; - } - else if (pSelectedResources != null && pSelectedResources.Count > 0) - { - foreach (var res in app.ResourceList) - { - if (pSelectedResources.Contains(res.ResourceOid.Value)) - { - add = true; - } - } - } - - - } - } - if (add) - { - result.Add(app); - } - } - + var result = FilterAppointments(all, pEmployeeOid, filteredEmployeeOids, pSelectedCustomer, pSelectedResources, pCustomersOnly, pResourcesOnly); + //Check fehlerhaftes RecurrenceInfos foreach (var app in result) { - if (!String.IsNullOrEmpty(app.RecurrenceInfo)) + if (!IsNullOrEmpty(app.RecurrenceInfo)) { if (app.RecurrenceInfo.Contains("WeekDays=\"0\"")) { @@ -1195,24 +1129,109 @@ namespace BeWo.Service.ServiceImplementations } } } - return result; - ////var appointments = DAOFactory.GenericDAO.GetAll(); - //var test = MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDCs(appointments).OrderBy(a => a.StartDate).ToList(); + + // Ausnahmen immer laden. Entsprechen die Ausnahmen nicht den Filterkriterien, werden sie als gelöscht markiert, um nicht auf dem Client angezeigt zu werden. + var ausnahmen = MapperFactory.SchedulerAppointmentDCSchedulerAppointment.MapToNewDCs(DAOFactory.SearchDAO.FindAppointmentsByRecurrenecInfo(result.Where(w => w.Type == 1).Select(s => s.RecurrenceInfo).ToList(), true)); + var demFilterEntsprechendeTermine = FilterAppointments(ausnahmen, pEmployeeOid, filteredEmployeeOids, pSelectedCustomer, pSelectedResources, pCustomersOnly, pResourcesOnly); - //foreach (var dc in test) - //{ - // if (dc.Type == 3) - // { - // dc.RecurrenceInfo = null; - // dc.Type = 0; - // } - //} - //return test; + foreach(var appointment in ausnahmen.Where(w => !demFilterEntsprechendeTermine.Contains(w))) + { + var kosmetisch = new SchedulerAppointmentDC + { + SchedulerAppointmentOid = appointment.SchedulerAppointmentOid * -1, + NewSchedulerAppointmentVersion = 1, + Type = 4, + RecurrenceInfo = appointment.RecurrenceInfo, + EmployeeList = appointment.EmployeeList, + CustomerList = appointment.CustomerList, + ResourceList = appointment.ResourceList, + Originator = appointment.Originator + }; + + result.Add(kosmetisch); + } + + return result; } catch(Exception e) { throw Utils.CreateBeWoFaultException(e); } } + + private static List FilterAppointments(IEnumerable pAppointments, long pEmployeeOid, ICollection pFilteredEmployeeOids, ICollection pSelectedCustomers, ICollection pSelectedResources, bool pCustomersOnly, bool pResourcesOnly) + { + var result = new List(); + + foreach(var app in pAppointments) + { + var add = true; + if(app.Originator != null && app.Originator.EmployeeOid == pEmployeeOid) + { + if(app.EmployeeList != null && app.EmployeeList.Count > 0) + { + add = false; + foreach(var emp in app.EmployeeList) + { + if(pFilteredEmployeeOids.Contains(emp.Employee.EmployeeOid)) + { + add = true; + } + } + } + } + + //Prüfe Klientenfilter + if(!add) + { + if(app.CustomerList != null && app.CustomerList.Count > 0) + { + if(pCustomersOnly) + { + add = true; + } + else if(pSelectedCustomers != null && pSelectedCustomers.Count > 0) + { + foreach(var cust in app.CustomerList) + { + if(pSelectedCustomers.Contains(cust.CustomerOid)) + { + add = true; + } + } + } + } + } + + //Prüfe Ressourcenfilter + if(!add) + { + if(app.ResourceList != null && app.ResourceList.Count > 0) + { + if(pResourcesOnly) + { + add = true; + } + else if(pSelectedResources != null && pSelectedResources.Count > 0) + { + foreach(var res in app.ResourceList) + { + if(pSelectedResources.Contains(res.ResourceOid.Value)) + { + add = true; + } + } + } + } + } + + if(add) + { + result.Add(app); + } + } + + return result; + } } } \ No newline at end of file