using System; using System.Collections.Generic; using System.Drawing; using System.Globalization; using System.Linq; using System.Text; using System.Web; using BeWo.Data; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Service.Configuration; using BeWo.Service.DCEntityMapper; using BeWo.Service.Plugins; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.Services; using BS.Shared.Extensions; using System.Diagnostics; using Customer = BeWo.Data.Entities.Customer; namespace BeWo.Report.ReportObjects { public class ServicesOverviewRO : AbstractBeWoReportObject { private List _Services = new List(); private List _ServicesDouble = new List(); public long CustomerOid { get; set; } public string AbsenceTimes { get; set; } public List Abwesenheiten { get; set; } public List AllEmployees { get; set; } = new List(); public string ApprovedEndDate { get; set; } public decimal ApprovedFLSPerMonth { get; set; } public decimal ApprovedFLSPerMonthTotal { get; set; } public decimal ApprovedFLSPerWeek { get; set; } public decimal ApprovedFLSPerWeekTotal { get; set; } public decimal ApprovedFLSTotal { get; set; } public string ApprovedStartDate { get; set; } public string ContactEmployee { get; set; } public string Costbearer { get; set; } public DateTime? CustomerBirthday { get; set; } public string CustomerCity { get; set; } public string CustomerFirstName { get; set; } public string CustomerLastName { get; set; } public string CustomerName { get; set; } public string CustomerPostalCode { get; set; } public string CustomerStreet { get; set; } public string CustomerInsuranceNumber { get; set; } public DateTime EndDate { get; set; } public decimal? FreeMinutesThisMonth { get; set; } // Restbudget inkl. aktueller Monat public decimal? FreeHoursThisMonth { get; set; } // Restbudget inkl. aktueller Monat public decimal MinutenGeleistetGesamt { get; set; } // Ist inkl. aktueller Monat public decimal StundenGeleistetGesamt { get; set; } // Ist inkl. aktueller Monat public decimal MinutenSollGesamt { get; set; } // Soll inkl. aktueller Monat public decimal StundenSollGesamt { get; set; } // Soll inkl. aktueller Monat public string MainAttendant { get; set; } public string MainAttendantCommaSeperated { get; set; } public string Month { get; set; } public string ReferenceNumber { get; set; } public string RequestedEndDate { get; set; } public string RequestedStartDate { get; set; } public string Salutation { get; set; } public decimal RateFactor { get; set; } public decimal MinutenGeleistetBisVormonat { get; set; } // Ist VOR aktuellem Monat public decimal StundenGeleistetBisVormonat { get; set; } // Ist VOR aktuellem Monat public decimal MinutenSollBisVormonat { get; set; } // Soll VOR aktuellem Monat public decimal StundenSollBisVormonat { get; set; } // Soll VOR aktuellem Monat public decimal FreeMinutesBisVormonat { get; set; } // Restbudget VOR aktuellem Monat public decimal FreeHoursBisVormonat { get; set; } // Restbudget VOR aktuellem Monat public List Services { get { return this._Services; } set { this._Services = value; } } public List ServicesDouble { get { return this._ServicesDouble; } set { this._ServicesDouble = value; } } public DateTime StartDate { get; set; } public SupportConceptCostBearerRelDC SupportConceptCostBearer { get; set; } public string TotalFLHoursMinutesString { get; set; } public double TotalFLM { get; set; } public double TotalFLMBillable { get; set; } public double TotalFLMoFehlkontakte { get; set; } public double TotalFLMFehlkontakte { get; set; } public string TotalFLMPerCostBearer { get; set; } public double TotalFLMQualified { get; set; } public string TotalFLMQualifiedString { get; set; } public string TotalFLMString { get; set; } public double TotalFLMUnqualified { get; set; } public string TotalFLMUnqualifiedString { get; set; } public double TotalFLS { get; set; } public double TotalFLSoFehlkontakte { get; set; } public double TotalFLSFehlkontakte { get; set; } public string TotalFLSPerCostBearer { get; set; } public double TotalFLSQualified { get; set; } public string TotalFLSQualifiedString { get; set; } public string TotalFLSString { get; set; } public double TotalFLSUnqualified { get; set; } public string TotalFLSUnqualifiedString { get; set; } public double TotalGefahreneKilometer { get; set; } public string TotalGefahreneKilometerString { get; set; } public Bitmap EmployeeSignature { get; set; } public DateTime? EmployeeSignatureDate { get; set; } public Bitmap CustomerSignature { get; set; } public DateTime? CustomerSignatureDate { get; set; } public int Year { get; set; } public IList CostBearer2SupportConceptList { get; set; } public MandatorDC Mandator { get; set; } public long? FilteredEmployeeOid { get; set; } // private CostBearer2SupportConceptData CostBearer2SupportConceptData { get; set; } public static List CreateAlt(int pMonth, int pYear, long orgaOid, long empOid, int startDay, int endDay, long? serviceCategoryOid = null, bool disableEmptySupportConcepts = true) { return Create(pMonth, pYear, orgaOid, empOid, startDay, endDay, false, serviceCategoryOid, disableEmptySupportConcepts); } public static List Create(int pMonth, int pYear, long orgaOid, long empOid, int startDay, int endDay, long? serviceCategoryOid = null, bool disableEmptySupportConcepts = true, bool checkQbStatus = false) { return Create(pMonth, pYear, orgaOid, empOid, startDay, endDay, false, serviceCategoryOid, disableEmptySupportConcepts, false, checkQbStatus); } public static List Create(int pMonth, int pYear, long orgaOid, long empOid, int startDay, int endDay, bool searchServiceRecordsByEndDate, long? serviceCategoryOid = null, bool disableEmptySupportConcepts = true, bool checkTeamCustomerRights = false, bool checkQbStatus = false) { var roList = new List(); List customers = null; var loggedInUser = LoggedInUserOperationContextExt.Current?.User ?? SessionFacade.LoggedInUser; if(loggedInUser?.Employee != null) { if(!HasRight(loggedInUser, UserRightType.CustomerView_View)) { customers = new List(); if(checkTeamCustomerRights && HasRight(loggedInUser, UserRightType.Customer_ViewMyTeams)) { var teamCustomers = DAOFactory.SearchDAO.FindCustomersOfTeams(loggedInUser.Employee.LeadingTeams.Select(team => team.Oid.Value)); customers.AddRangeIfElementsNotIn(teamCustomers); } else { foreach (var employee2Customer in loggedInUser.Employee.Employee2CustomerList) { customers.Add(employee2Customer.Customer); } } } } if(customers is null) { customers = DAOFactory.GenericDAO.GetAllActive().OrderBy(ob => ob.Person.LastName + ", " + ob.Person.FirstName).ToList(); } if(startDay > endDay) { (startDay, endDay) = (endDay, startDay); } var pSpan = new DateTimeSpan { StartDateTime = new DateTime(pYear, pMonth, startDay) }; pSpan.EndDateTime = pSpan.StartDateTime.AddDays(endDay - startDay + 1).AddTicks(-1); foreach(var customer in customers) { var servicesOverviewRO = Create(customer, pSpan, disableEmptySupportConcepts, orgaOid, empOid, searchServiceRecordsByEndDate, serviceCategoryOid, checkQbStatus); if (servicesOverviewRO != null) { roList.Add(servicesOverviewRO); } } var sortOrder = QBSortOrderEnum.NachKlient; if(HttpContext.Current != null) { var so = HttpContext.Current.Request.Params["sortorder"]; if (!string.IsNullOrWhiteSpace(so)) { sortOrder = (QBSortOrderEnum) int.Parse(so); } } return sortOrder == QBSortOrderEnum.NachHauptbetreuung ? roList.OrderBy(r => r.MainAttendant).ToList() : roList; } private static bool HasRight(ApplicationUser user, UserRightType right) { return GetGrantedRights(user).Contains(right); } public static List GetGrantedRights(ApplicationUser user) { var rights = new List(); foreach (var ug in user.UserGroups) { foreach (var rr in ug.Rights) { rights.Add(rr.RightType); } } return rights; } public static ServicesOverviewRO CreateAlt(long pCustomerOid, int pMonth, int pYear, bool disableEmptySupportConcepts, long orgaOid, long empOid, int start, int end, long? serviceCategoryOid = null) { return Create(pCustomerOid, pMonth, pYear, disableEmptySupportConcepts, orgaOid, empOid, start, end, false, serviceCategoryOid); } public static ServicesOverviewRO Create(long pCustomerOid, int pMonth, int pYear, bool disableEmptySupportConcepts, long orgaOid, long empOid, int start, int end, long? serviceCategoryOid = null, bool checkQbStatus = false) { return Create(pCustomerOid, pMonth, pYear, disableEmptySupportConcepts, orgaOid, empOid, start, end, false, serviceCategoryOid, checkQbStatus); } public static ServicesOverviewRO Create(long pCustomerOid, int pMonth, int pYear, bool disableEmptySupportConcepts, long orgaOid, long empOid, int start, int end, bool searchServiceRecordsByEndDate, long? serviceCategoryOid = null, bool checkQbStatus = false) { var pSpan = new DateTimeSpan(); if (start > end) { int temp = start; start = end; end = temp; } pSpan.StartDateTime = new DateTime(pYear, pMonth, start); pSpan.EndDateTime = pSpan.StartDateTime.AddDays(end - start + 1).AddTicks(-1); var lCustomer = DAOFactory.GenericDAO.LoadByID(pCustomerOid); return Create(lCustomer, pSpan, disableEmptySupportConcepts, orgaOid, empOid, searchServiceRecordsByEndDate, serviceCategoryOid, checkQbStatus); } public static List CreatePaginated(int firstResult, int maxResults, long[] customerOids, int month, int year, bool disableEmptySupportConcepts, long organizationOid, long employeeOid, int start, int end, out int rowCount, long? serviceCategoryOid = null, bool checkQbStatus = false, long? costbearerOid = null) { var reportObjects = new List(); var dateTimeSpan = new DateTimeSpan(); if(start > end) { (start, end) = (end, start); } dateTimeSpan.StartDateTime = new DateTime(year, month, start); dateTimeSpan.EndDateTime = new DateTime(year, month, end).AddDays(1).AddSeconds(-1); var customers = DAOFactory.SearchDAO.FindCustomersForPaginatedQbByOids(firstResult, maxResults, customerOids, dateTimeSpan.StartDate, dateTimeSpan.EndDateTime, out rowCount, serviceCategoryOid, costbearerOid); foreach(var customer in customers) { var servicesOverviewRO = Create(customer, dateTimeSpan, disableEmptySupportConcepts, organizationOid, employeeOid, false, serviceCategoryOid, checkQbStatus); if(servicesOverviewRO is null) { continue; } reportObjects.Add(servicesOverviewRO); } return reportObjects; } public static List CreatePaginated(int firstResult, int maxCount, int month, int year, long organizationOid, long employeeOid, int startDay, int endDay, out int rowCount, long? serviceCategoryOid = null, bool disableEmptySupportConcepts = true, bool checkQbStatus = false, long? costbearerOid = null) { var reportObjects = new List(); if(startDay > endDay) { (startDay, endDay) = (endDay, startDay); } var dateTimeSpan = new DateTimeSpan { StartDateTime = new DateTime(year, month, startDay) }; dateTimeSpan.EndDateTime = dateTimeSpan.StartDateTime.AddDays(endDay - startDay + 1).AddTicks(-1); var paginatedCustomers = DAOFactory.SearchDAO.FindCustomersForPaginatedQb(firstResult, maxCount, false, dateTimeSpan.StartDate, dateTimeSpan.EndDateTime, out rowCount, serviceCategoryOid, costbearerOid); foreach(var customer in paginatedCustomers) { var servicesOverviewRO = Create(customer, dateTimeSpan, disableEmptySupportConcepts, organizationOid, employeeOid, false, serviceCategoryOid, checkQbStatus); if(servicesOverviewRO != null) { reportObjects.Add(servicesOverviewRO); } } var sortOrder = QBSortOrderEnum.NachKlient; if(HttpContext.Current != null) { var so = HttpContext.Current.Request.Params["sortorder"]; if(!string.IsNullOrWhiteSpace(so)) { sortOrder = (QBSortOrderEnum) int.Parse(so); } } return sortOrder == QBSortOrderEnum.NachHauptbetreuung ? reportObjects.OrderBy(r => r.MainAttendant).ToList() : reportObjects; } public void CalculateFLSSollIst() //Berechnung von Soll/Ist inkl. aktueller Monat für den gesamten Hilfeplan -> BerechneJugendamtSollIst ist umfassender { if (this.SupportConceptCostBearer != null && this.SupportConceptCostBearer.CostBearer2SupportConceptOid != null) { if (this.SupportConceptCostBearer.StartDate != null) { CostBearer2SupportConcept c2s = DAOFactory.GenericDAO.LoadByID(this.SupportConceptCostBearer.CostBearer2SupportConceptOid.Value); IList allServiceRecords = c2s.ServiceRecords; var calc = PluginLoader.FindClass(c2s.CostBearer.ID) ?? Calculations.GetInstance(c2s.CostBearer.ID); decimal? flsnullable = calc.GetApprovedHoursPerWeekAverage(this.SupportConceptCostBearer, false); decimal fls = 0; if (flsnullable.HasValue) { fls = flsnullable.Value; } TimeSpan ts = this.EndDate.Subtract(this.SupportConceptCostBearer.StartDate.Value); int daysPassed = ts.Days + 1; decimal flmSoll = ((daysPassed / 7m) * fls) * 60; decimal minutenIst = 0; DateTime end = this.EndDate.Date.AddDays(1); Dictionary groupBookingDict = new Dictionary(); foreach (var item in allServiceRecords) { if (!item.GroupOid.HasValue || !groupBookingDict.ContainsKey(item.GroupOid.Value)) { if (item.Start != null) { if (item.Start >= this.SupportConceptCostBearer.StartDate.Value && item.Start.Value < end) { if (item.ServiceDescription != null && item.ServiceDescription.ServiceCategory != null && item.ServiceDescription.ServiceCategory.IsBillable) { decimal prozent = item.ServiceDescription.ServiceCategory.ProzentBudget ?? 100; if (item.ServiceDescription.ProzentBudget.HasValue) { prozent = item.ServiceDescription.ProzentBudget.Value; } minutenIst += (item.RoundedDuration * prozent) / 100; if (item.GroupOid.HasValue) { groupBookingDict.Add(item.GroupOid.Value, true); } } } } } } this.MinutenGeleistetGesamt = minutenIst; this.MinutenSollGesamt = flmSoll; this.FreeMinutesThisMonth = flmSoll - minutenIst; } } } public void CalculateFLSSollIst2() //Berechnung von Soll/Ist bis MONATSBEGINN/VORMONAT für den gesamten Hilfeplan, insbesondere für Niedersachsen verwendet -> BerechneJugendamtSollIst ist umfassender { if (this.SupportConceptCostBearer != null && this.SupportConceptCostBearer.CostBearer2SupportConceptOid != null) { var c2s = DAOFactory.GenericDAO.LoadByID(this.SupportConceptCostBearer.CostBearer2SupportConceptOid.Value); var calc = PluginLoader.FindClass(c2s.CostBearer.ID) ?? Calculations.GetInstance(c2s.CostBearer.ID); var costRatePeriods = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(c2s.CostBearer.CostRatePeriods); decimal sollGesamt = 0; DateTime start = c2s.StartDate ?? this.StartDate; DateTime ende = this.StartDate.AddTicks(-1); // Ein Tag vor aktuellem Monat, da ja das Soll der Vergangenheit berechnet werden soll // Erstelle Soll aus den Bewilligungen while (start < ende) { DateTime monatsEnde = new DateTime(start.Year, start.Month, 1).AddMonths(1).AddDays(-1); foreach (var scap in c2s.ApprovalPeriodList) { if (scap.StartDate.HasValue && scap.StartDate <= monatsEnde && scap.EndDate.HasValue && scap.EndDate >= start) { var scapdc = MapperFactory.SupportConceptApprovalPeriodDC_SupportConceptApprovalPeriod.MapToNewDC(scap); decimal soll = calc.GetApprovedHoursForPeriod(scapdc, costRatePeriods, start, monatsEnde) ?? 0; sollGesamt += Math.Round(soll, 2, MidpointRounding.AwayFromZero); } } start = monatsEnde.AddDays(1); } //Berechne Ist bis Ende des Vormonats start = c2s.StartDate ?? this.StartDate; decimal minutenIst = 0; IList allServiceRecords = c2s.ServiceRecords; Dictionary groupBookingDict = new Dictionary(); foreach (var item in allServiceRecords) { if (!item.GroupOid.HasValue || !groupBookingDict.ContainsKey(item.GroupOid.Value)) { if (item.Start != null) { if (item.Start >= start && item.Start.Value <= ende) { if (item.ServiceDescription != null && item.ServiceDescription.ServiceCategory != null && item.ServiceDescription.ServiceCategory.IsBillable) { decimal prozent = item.ServiceDescription.ServiceCategory.ProzentBudget ?? 100; if (item.ServiceDescription.ProzentBudget.HasValue) { prozent = item.ServiceDescription.ProzentBudget.Value; } minutenIst += (item.RoundedDuration * prozent) / 100; if (item.GroupOid.HasValue) { groupBookingDict.Add(item.GroupOid.Value, true); } } } } } } this.MinutenGeleistetBisVormonat = minutenIst; this.MinutenSollBisVormonat = sollGesamt * 60; } } public void CalculateFLSSollIstAktuelleBewilligung(SupportConceptApprovalPeriodDC scap, decimal? faktor = null) //Berechnung von Soll/Ist für den laufenden und vorherigen Monat nur für die aktuelle Bewilligung { if (this.SupportConceptCostBearer != null && this.SupportConceptCostBearer.CostBearer2SupportConceptOid != null) { var c2s = DAOFactory.GenericDAO.LoadByID(this.SupportConceptCostBearer.CostBearer2SupportConceptOid.Value); var calc = PluginLoader.FindClass(c2s.CostBearer.ID) ?? Calculations.GetInstance(c2s.CostBearer.ID); var costRatePeriods = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(c2s.CostBearer.CostRatePeriods); decimal sollGesamt = 0; decimal curFactor = 1; // Möglichkeit eingebaut, aber nicht gebraucht if (faktor.HasValue) { curFactor = faktor.Value; } // Setzen der allgemeinen Daten für Zeitraumbestimmung und Bewilligungen var scapStartDate = scap.StartDate ?? c2s.StartDate; var scapEndDate = scap.EndDate ?? c2s.EndDate; // Erstelle Soll aus der gewählten Bewilligung var start = scap.StartDate ?? StartDate; var ende = EndDate; if (scapEndDate.HasValue && scapEndDate < this.EndDate) { ende = scapEndDate.Value; } var endeVormonat = new DateTime(this.StartDate.Year, this.StartDate.Month, 1).AddDays(-1); decimal soll = calc.GetApprovedHoursForPeriod(scap, costRatePeriods, start, ende) ?? 0; decimal sollVormonat = 0; if (start < endeVormonat) { sollVormonat = calc.GetApprovedHoursForPeriod(scap, costRatePeriods, start, endeVormonat) ?? 0; } //Berechne Ist bis Ende und Ende des Vormonats IList allServiceRecords = c2s.ServiceRecords; List serviceRecordsScap = allServiceRecords.Where(i => { bool valid = i.Start.Value.InBetween(start, ende, true); if (valid && scap != null && scap.ServiceCategory != null) { valid = scap.ServiceCategory.ServiceCategoryOid == i.ServiceDescription.ServiceCategory.Oid; } return valid; }).ToList(); Dictionary groupBookingDict = new Dictionary(); decimal minutenIstBisEndeBeleg = 0; decimal minutenIstVormonat = 0; foreach (var item in serviceRecordsScap) { if (!item.GroupOid.HasValue || !groupBookingDict.ContainsKey(item.GroupOid.Value)) { if (item.GroupOid.HasValue) { groupBookingDict.Add(item.GroupOid.Value, true); } if (item.Start != null && item.Start >= start) { if (item.ServiceDescription != null && item.ServiceDescription.ServiceCategory != null && item.ServiceDescription.ServiceCategory.IsBillable) { decimal prozent = item.ServiceDescription.ServiceCategory.ProzentBudget ?? 100; if (item.ServiceDescription.ProzentBudget.HasValue) { prozent = item.ServiceDescription.ProzentBudget.Value; } if (item.Start.Value < this.EndDate) { minutenIstBisEndeBeleg += (item.RoundedDuration * prozent) / 100; if (item.Start.Value < endeVormonat.AddDays(1)) { minutenIstVormonat += (item.RoundedDuration * prozent) / 100; } } } } } } // Setzen der globalen Variablen für den laufenden und vorherigen Monat this.MinutenGeleistetGesamt = minutenIstBisEndeBeleg * curFactor; this.StundenGeleistetGesamt = Math.Round(this.MinutenGeleistetGesamt / 60, 2, MidpointRounding.AwayFromZero); this.MinutenSollGesamt = soll * 60 * curFactor; this.StundenSollGesamt = Math.Round(soll * curFactor, 2, MidpointRounding.AwayFromZero); this.FreeMinutesThisMonth = this.MinutenSollGesamt - this.MinutenGeleistetGesamt; this.FreeHoursThisMonth = Math.Round(this.StundenSollGesamt - this.StundenGeleistetGesamt, 2, MidpointRounding.AwayFromZero); this.MinutenGeleistetBisVormonat = minutenIstVormonat * curFactor; this.StundenGeleistetBisVormonat = Math.Round(this.MinutenGeleistetBisVormonat / 60, 2, MidpointRounding.AwayFromZero); this.MinutenSollBisVormonat = sollVormonat * 60 * curFactor; this.StundenSollBisVormonat = Math.Round(sollVormonat, 2, MidpointRounding.AwayFromZero); this.FreeMinutesBisVormonat = this.MinutenSollBisVormonat - this.MinutenGeleistetBisVormonat; this.FreeHoursBisVormonat = Math.Round(this.StundenSollBisVormonat - this.StundenGeleistetBisVormonat, 2, MidpointRounding.AwayFromZero); } } public ApprovalDetail BerechneJugendamtSollIst() { ApprovalDetail ad = new ApprovalDetail(); ad.TimeSpanStartDate = this.StartDate; ad.TimeSpanEndDate = this.EndDate; if (this.SupportConceptCostBearer != null && this.SupportConceptCostBearer.CostBearer2SupportConceptOid != null) { if (this.SupportConceptCostBearer.StartDate != null) { // Setzen der allgemeinen Daten für Zeitraumbestimmung und Bewilligungen CostBearer2SupportConcept c2s = DAOFactory.GenericDAO.LoadByID(this.SupportConceptCostBearer.CostBearer2SupportConceptOid.Value); var calc = PluginLoader.FindClass(c2s.CostBearer.ID) ?? Calculations.GetInstance(c2s.CostBearer.ID); ad.TotalStartDate = c2s.StartDate; ad.TotalEndDate = c2s.EndDate; if (ad.TotalStartDate.HasValue && ad.TotalStartDate > this.StartDate) { this.StartDate = ad.TotalStartDate.Value; } if (ad.TotalEndDate.HasValue && ad.TotalEndDate < this.EndDate) { this.EndDate = ad.TotalEndDate.Value; } ad.TimeSpanStartDate = this.StartDate; ad.TimeSpanEndDate = this.EndDate; TimeSpan ts = this.EndDate.Subtract(ad.TotalStartDate.Value); int daysPassed = ts.Days + 1; var endeVormonat = new DateTime(this.StartDate.Year, this.StartDate.Month, 1).AddDays(-1); int daysVormonat = 0; if (endeVormonat >= ad.TotalStartDate.Value) { ts = endeVormonat.Subtract(ad.TotalStartDate.Value); daysVormonat = ts.Days + 1; } // Bestimmung der Soll-Werte ad.ApprovedHoursPerWeek = calc.GetApprovedHoursPerWeekAverage(this.SupportConceptCostBearer, false) ?? 0; ad.ApprovedHoursInTimeSpan = ad.DaysInTimeSpan * (ad.ApprovedHoursPerWeek / 7m); ad.ApprovedHoursTotal = ad.DaysTotal * (ad.ApprovedHoursPerWeek / 7m); var flmSoll = ((daysPassed / 7m) * ad.ApprovedHoursPerWeek) * 60; var flmSollVormonat = ((daysVormonat / 7m) * ad.ApprovedHoursPerWeek) * 60; // Bestimmung der Ist-Werte DateTime end = this.EndDate.Date.AddDays(1); IList allServiceRecords = c2s.ServiceRecords; Dictionary groupBookingDict = new Dictionary(); decimal minutenIstBisEndeBeleg = 0; decimal minutenIstVormonat = 0; foreach (var item in allServiceRecords) { if (!item.GroupOid.HasValue || !groupBookingDict.ContainsKey(item.GroupOid.Value)) { if (item.GroupOid.HasValue) { groupBookingDict.Add(item.GroupOid.Value, true); } if (item.Start != null && item.Start >= ad.TotalStartDate) { if (item.ServiceDescription != null && item.ServiceDescription.ServiceCategory != null && item.ServiceDescription.ServiceCategory.IsBillable) { decimal prozent = item.ServiceDescription.ServiceCategory.ProzentBudget ?? 100; if (item.ServiceDescription.ProzentBudget.HasValue) { prozent = item.ServiceDescription.ProzentBudget.Value; } if (item.Start.Value < end) { minutenIstBisEndeBeleg += (item.RoundedDuration * prozent) / 100; if (item.Start.Value < endeVormonat.AddDays(1)) { minutenIstVormonat += (item.RoundedDuration * prozent) / 100; } } } } } } // Setzen der globalen Variablen für den laufenden und vorherigen Monat this.MinutenGeleistetGesamt = minutenIstBisEndeBeleg; this.MinutenSollGesamt = flmSoll; this.FreeMinutesThisMonth = flmSoll - minutenIstBisEndeBeleg; this.MinutenGeleistetBisVormonat = minutenIstVormonat; this.MinutenSollBisVormonat = flmSollVormonat; this.FreeMinutesBisVormonat = flmSollVormonat - minutenIstVormonat; ad.UsedHoursPreviousMonths = minutenIstVormonat / 60; } } return ad; } private static ServicesOverviewRO Create(Customer customer, DateTimeSpan span, bool disableEmptySupportConcepts, long orgaOid, long empOid, bool searchServiceRecordsByEndDate, long? serviceCategoryOid = null, bool checkQbStatus = true) { // IList lServiceRecords = pServiceRecords; // if (lServiceRecords == null) IList lServiceRecords = DAOFactory.SearchDAO.FindCustomerServiceRecords(customer.Oid.Value, span, null, null, searchServiceRecordsByEndDate); var serviceRecordSignatures = DAOFactory.GenericDAO.LoadByIDs(lServiceRecords.Where(sr => sr.SignatureOid.HasValue).Select(sr => sr.SignatureOid.Value)); var lResult = new ServicesOverviewRO(); if (checkQbStatus) { //gibt es für den customer schon einen QBStatus mit gleichen Werten für span, orga, emp, serviceCategory? var alle = DAOFactory.SearchDAO.GetAllQuittierungsbelegStatusForMonth(span.StartDate, span.EndDate); Customer richtigerKlient = null; long? orga, emp; if (orgaOid == 0) orga = null; else orga = orgaOid; if (empOid == 0) emp = null; else emp = empOid; foreach (var qbs in alle) { if (qbs.CustomerOid == customer.Oid && qbs.Startdatum == span.StartDate && qbs.Enddatum == span.EndDate && qbs.OrganisationOid == orga && qbs.EmployeeOid == emp && qbs.ServiceCategoryOid == serviceCategoryOid && qbs.Erstellt) { richtigerKlient = customer; } } if (richtigerKlient != null) { //Was tun, um nichts zu erstellen? //Methode weiter ausführen, wenn ein QB für einen einzelnen Klienten erstellt werden soll //Methode abbrechen, wenn für alle erstellt wird. (Warum geht Fenster so oft auf?) return null; } } if (empOid > 0) { lResult.FilteredEmployeeOid = empOid; } lResult.CustomerOid = customer.Oid.Value; lResult.Abwesenheiten = new List(); lResult.CostBearer2SupportConceptList = new List(); lResult.Month = ReportHelper.GetMonthName(span.StartDateTime.Month); lResult.Year = span.StartDateTime.Year; lResult.StartDate = span.StartDate; lResult.EndDate = span.EndDate; lResult.CustomerFirstName = customer.Person.FirstName; lResult.CustomerLastName = customer.Person.LastName; lResult.CustomerBirthday = customer.Person.DateOfBirth; lResult.CustomerName = customer.Person.FirstName + " " + customer.Person.LastName; lResult.CustomerInsuranceNumber = customer.InsuranceNumber; if (customer.Person.Address != null) { lResult.CustomerStreet = customer.Person.Address.Street; lResult.CustomerPostalCode = customer.Person.Address.PostalCode; lResult.CustomerCity = customer.Person.Address.Town; } foreach (var item in customer.Employee2CustomerList) { foreach (var valueEntry in item.ValueList) { if (valueEntry.Entry.SystemEntryID != null && valueEntry.Entry.SystemEntryID.Value == SystemEntryID.EmployeeRoleMainAttendant) { if (item.StartDate.HasValue || item.EndDate.HasValue) { // Claude: Name nur setzen, wenn sich der Gültigkeitszeitraum des Employee2Customer-Eintrags mit span überschneidet (Eintrag noch aktiv) bool ueberschneidetSichMitSpan = (!item.StartDate.HasValue || item.StartDate.Value <= span.EndDate) && (!item.EndDate.HasValue || item.EndDate.Value >= span.StartDate); if (!ueberschneidetSichMitSpan) { continue; } } var empName = item.Employee.Person.FirstName + " " + item.Employee.Person.LastName; var empName2 = string.Format("{0}, {1}", item.Employee.Person.LastName, item.Employee.Person.FirstName); if (String.IsNullOrEmpty(lResult.MainAttendantCommaSeperated)) { lResult.MainAttendantCommaSeperated = empName2; } else if (!lResult.MainAttendantCommaSeperated.Contains(empName2)) { if (lResult.MainAttendantCommaSeperated.Length > 0) { lResult.MainAttendantCommaSeperated += ", "; } lResult.MainAttendantCommaSeperated += empName2; } if (String.IsNullOrEmpty(lResult.MainAttendant)) { lResult.MainAttendant = empName; } else { if (!lResult.MainAttendant.Contains(empName)) { lResult.MainAttendant += ", " + empName; } } } } } var flmBillablePerCostBearer = new Dictionary(); var flmNotBillableServiceDescAbbr = new Dictionary(); var flmPerEmployee = new Dictionary(); Dictionary personPerEmployee = new Dictionary(); double flmNotBillable = 0; double flmBillable = 0; double flmQualified = 0; double flmUnqualified = 0; var allServices = new List(); var cb2scOid2Count = new Dictionary(); var cb2scOid2FLSApprovedPerWeek = new Dictionary(); var cb2scOid2FLSApprovedTotal = new Dictionary(); var cb2scOid2RefNumber = new Dictionary(); // Dictionary cb2scOid2Data = new Dictionary(); var cb2scs = new Dictionary(); var groupBookingDict = new Dictionary(); foreach (var iSr in lServiceRecords) { lResult.TotalGefahreneKilometer += Convert.ToDouble(iSr.DistanceInMeter); bool cont = !(empOid != 0 && iSr.EmployeeOid != null && iSr.EmployeeOid != empOid); CostBearer2SupportConcept cb2sc = null; if (cont) { cb2sc = iSr.CostBearer2SupportConcept; } if (cb2sc == null) { cont = false; } else if (cont && orgaOid != 0 && cb2sc.CostBearer.Organisation != null && cb2sc.CostBearer.Organisation.Oid.Value != orgaOid) { cont = false; } if (cont) { if (cb2sc.SupportConcept.IsActive == ActivationTypeId.Deleted) { cont = false; } } if (cont && iSr.GroupOid != null && groupBookingDict.ContainsKey(iSr.GroupOid.Value)) { cont = false; } if (cont && serviceCategoryOid.HasValue && iSr.ServiceDescription.ServiceCategory.Oid != serviceCategoryOid) cont = false; if (cont) { lResult.ApprovedStartDate = cb2sc.ApprovedStartDate != null ? String.Format("{0:dd.MM.yyyy}", cb2sc.ApprovedStartDate.Value) : string.Empty; lResult.ApprovedEndDate = cb2sc.ApprovedEndDate != null ? String.Format("{0:dd.MM.yyyy}", cb2sc.ApprovedEndDate.Value) : string.Empty; lResult.RequestedStartDate = cb2sc.RequestedStartDate != null ? String.Format("{0:dd.MM.yyyy}", cb2sc.RequestedStartDate.Value) : string.Empty; lResult.RequestedEndDate = cb2sc.RequestedEndDate != null ? String.Format("{0:dd.MM.yyyy}", cb2sc.RequestedEndDate.Value) : string.Empty; int count = 0; if (cb2scOid2Count.ContainsKey(cb2sc.Oid.Value)) { count = cb2scOid2Count[cb2sc.Oid.Value]; cb2scOid2Count.Remove(cb2sc.Oid.Value); } else { lResult.CostBearer2SupportConceptList.Add(cb2sc); } count++; cb2scOid2Count.Add(cb2sc.Oid.Value, count); if (!cb2scOid2FLSApprovedPerWeek.ContainsKey(cb2sc.Oid.Value)) { var cb2scDC = cb2sc.MapToNewDC(); if (cb2sc.CostBearer != null) { if (String.IsNullOrEmpty(lResult.Costbearer)) lResult.Costbearer = cb2sc.CostBearer.Organisation.Name; DateTime? start = cb2sc.ApprovedStartDate; if (!start.HasValue) start = cb2sc.RequestedStartDate; DateTime? end = cb2sc.ApprovedEndDate; if (!end.HasValue) end = cb2sc.RequestedEndDate; if (start.HasValue && end.HasValue) { var relDC = cb2sc.MapToNewDC(); var rateFactorsInSpanList = relDC.CostBearer.CostRatePeriods.GetSpans(CostRatePeriodType.RateFactor, lResult.StartDate, lResult.EndDate).ToList(); if (rateFactorsInSpanList.Count > 0) { var crv = rateFactorsInSpanList.Last().Key; if (crv != null && crv.CostRateValue.HasValue) { lResult.RateFactor = crv.CostRateValue.Value; lResult.RateFactor = (lResult.RateFactor + 100)/100; } } } } var calc = PluginLoader.FindClass(cb2sc.CostBearer.ID) ?? Calculations.GetInstance(cb2sc.CostBearer.ID); DateTime sdt = span.StartDateTime; if (sdt < cb2scDC.StartDate) sdt = cb2scDC.StartDate.Value; decimal? fls = calc.GetApprovedHoursPerWeek(cb2scDC, sdt, false); //decimal? fls = calc.GetApprovedHoursPerWeekAverage(cb2scDC, false); decimal? flsTotal = calc.GetApprovedHoursTotal(cb2scDC, false); if (!fls.HasValue) fls = 0; if (!flsTotal.HasValue) flsTotal = 0; // decimal fls = CostRateCalculationService.GetApprovedFLSPerWeek(data); // decimal flsTotal = CostRateCalculationService.GetApprovedFLSTotal(data); if (cb2scDC.GetApprovedDuration().HasValue) { foreach (var scap in cb2scDC.ApprovalPeriodList) { if (sdt.InBetween(scap.Span, true)) { lResult.ApprovedFLSPerWeekTotal += calc.GetApprovedHoursPerWeek(scap, cb2scDC.CostBearer.CostRatePeriods) ?? 0; } } } cb2scOid2FLSApprovedPerWeek.Add(cb2sc.Oid.Value, fls.Value); cb2scOid2FLSApprovedTotal.Add(cb2sc.Oid.Value, flsTotal.Value); // cb2scOid2Data.Add(cb2sc.Oid.Value, data); cb2scs.Add(cb2sc.Oid.Value, cb2scDC); } if (!cb2scOid2RefNumber.ContainsKey(cb2sc.Oid.Value) && !String.IsNullOrEmpty(cb2sc.CustomerReferenceNumber)) { cb2scOid2RefNumber.Add(cb2sc.Oid.Value, cb2sc.CustomerReferenceNumber); } ServiceDetail sd = new ServiceDetail { CostBearer = iSr.CostBearer2SupportConcept != null && iSr.CostBearer2SupportConcept.CostBearer.Organisation != null ? iSr.CostBearer2SupportConcept.CostBearer.Organisation.Name : string.Empty, StartDate = iSr.Start.Value }; sd.ServiceRecordOid = iSr.Oid.Value; sd.SignatureOid = iSr.SignatureOid; if(iSr.SignatureOid.HasValue) { var signature = serviceRecordSignatures.FirstOrDefault(s => s.Oid.HasValue && s.Oid.Value.Equals(iSr.SignatureOid)); if(signature != null) { sd.SignatureImage = ImageUtils.ConvertBase64StringToBitmap(signature.DataBild); } } sd.GefahreneKilometer = iSr.DistanceInMeter.HasValue ? (Convert.ToDouble(iSr.DistanceInMeter)).ToString("0.##") : string.Empty; decimal roundedDur = iSr.RoundedDuration; decimal prozent = iSr.ServiceDescription.ServiceCategory.ProzentAbrechnung; if (iSr.ServiceDescription.Name.ToLower().Contains("fehlkontakt") || (iSr.ServiceDescription.ProzentAbrechnung.HasValue && iSr.ServiceDescription.ProzentAbrechnung.Value < 100 && iSr.ServiceDescription.ProzentAbrechnung.Value > 0)) { prozent = 100; // Keine } //if (iSr.ServiceDescription.ProzentAbrechnung.HasValue) //{ // prozent = iSr.ServiceDescription.ProzentAbrechnung.Value; //} roundedDur *= (prozent / 100); sd.DurationInStunden = iSr.DurationInStunden.HasValue && iSr.DurationInStunden.Value == ZeiterfassungsDauer.Stunden; if (iSr.Employee.IsQualified == null || iSr.Employee.IsQualified.Value) { sd.MinutesQualified = Convert.ToDouble(roundedDur); sd.Minutes = sd.MinutesQualified; } else { sd.MinutesUnqualified = Convert.ToDouble(roundedDur); sd.Minutes = sd.MinutesUnqualified; } if (iSr.GroupEmployeeCount != null) { sd.EmployeeCount = iSr.GroupEmployeeCount.Value; } else { sd.EmployeeCount = 1; } if (iSr.GroupPersonCount != null) { sd.CustomerCount = iSr.GroupPersonCount.Value; } else { sd.CustomerCount = 1; } sd.GroupRoundedDuration = iSr.GroupRoundedDuration; if (iSr.GroupRoundedDuration != null) { sd.GroupMinutes = (double)iSr.GroupRoundedDuration.Value; } else { sd.GroupMinutes = sd.Minutes; } if (iSr.GroupOid != null) { sd.IsGroup = true; groupBookingDict.Add(iSr.GroupOid.Value, iSr); if ((!iSr.GroupEmployeeCount.HasValue || iSr.GroupEmployeeCount.Value < 2) && (!iSr.GroupPersonCount.HasValue || iSr.GroupPersonCount.Value < 2)) { sd.IsGroup = false; } } sd.MinutesDateTime = DateTime.Now.Date.AddMinutes(sd.Minutes); sd.EndDate = sd.StartDate.AddMinutes(sd.GroupMinutes); sd.EndDateNotRounded = iSr.End.Value; if (sd.StartDate.Second == 0) { sd.TimeRangeString = String.Format("{0} - {1}", sd.StartDate.ToShortTimeString(), sd.EndDate.ToShortTimeString()); sd.StartDateMinutes = sd.StartDate; sd.EndDateMinutes = sd.EndDate; } sd.StartDateString = iSr.Start.Value.ToShortDateString(); sd.KW = GetKW(sd.StartDate); flmQualified += sd.MinutesQualified; flmUnqualified += sd.MinutesUnqualified; sd.FLSQualified = sd.MinutesQualified / 60; sd.FLSUnqualified = sd.MinutesUnqualified / 60; sd.FLSQualifiedString = String.Format("{0:0.##}", sd.FLSQualified); sd.FLSQualifiedString = sd.FLSQualifiedString.Replace(".", ","); sd.FLSUnqualifiedString = String.Format("{0:0.##}", sd.FLSUnqualified); sd.FLSUnqualifiedString = sd.FLSUnqualifiedString.Replace(".", ","); sd.EmployeeOid = iSr.Employee.Oid.Value; string employeeAbbr = iSr.Employee.Person.Abbreviation; string employeeFullName = iSr.Employee.Person.FirstName + " " + iSr.Employee.Person.LastName; if (employeeAbbr == null || employeeAbbr.Length == 0) { employeeAbbr = iSr.Employee.Person.FirstName.Substring(0, 1) + ". " + iSr.Employee.Person.LastName; } sd.EmployeeAbbr = employeeAbbr; sd.EmployeeFullname = employeeFullName; sd.EmployeeFirstName = iSr.Employee.Person.FirstName; sd.EmployeeLastName = iSr.Employee.Person.LastName; sd.EmployeeNameCommaSeparated = string.Format("{0}, {1}", iSr.Employee.Person.LastName, iSr.Employee.Person.FirstName); sd.Notice = iSr.Notice; sd.Notice2 = iSr.Notice2; sd.Notice3 = iSr.Notice3; sd.Notice4 = iSr.Notice4; sd.Notice5 = iSr.Notice5; if (iSr.ServiceDescription != null) { sd.ServiceDescription = iSr.ServiceDescription.Name; sd.ServiceCategory = iSr.ServiceDescription.ServiceCategory.Name; sd.ServiceCategoryAbbr = iSr.ServiceDescription.ServiceCategory.Abbreviation; if (sd.ServiceCategoryAbbr == null || sd.ServiceCategoryAbbr.Length == 0) { sd.ServiceCategoryAbbr = iSr.ServiceDescription.ServiceCategory.Name; } } double flm = 0; decimal flmOFehlkontakte = 0; decimal flmFehlkontakte = 0; sd.ProzentAbrechenbar = iSr.ServiceDescription.ServiceCategory.ProzentAbrechnung; if (iSr.ServiceDescription.ProzentAbrechnung.HasValue) { sd.ProzentAbrechenbar = iSr.ServiceDescription.ProzentAbrechnung.Value; } if (iSr.ServiceDescription.ServiceCategory.IsBillable) { if (iSr.ServiceDescription.Name.ToLower().Contains("fehlkontakt") || (iSr.ServiceDescription.ProzentAbrechnung.HasValue && iSr.ServiceDescription.ProzentAbrechnung.Value < 100)) { flmFehlkontakte += iSr.RoundedDuration; } else { flmOFehlkontakte += iSr.RoundedDuration; } if (flmBillablePerCostBearer.ContainsKey(sd.CostBearer)) { flm = flmBillablePerCostBearer[sd.CostBearer]; } flm += sd.MinutesQualified + sd.MinutesUnqualified; flmBillablePerCostBearer[sd.CostBearer] = flm; flmBillable += sd.MinutesQualified + sd.MinutesUnqualified; sd.IsBillable = true; } else { sd.CostBearer = string.Empty; if (flmNotBillableServiceDescAbbr.ContainsKey(sd.ServiceCategoryAbbr)) { flm = flmNotBillableServiceDescAbbr[sd.ServiceCategoryAbbr]; } flm += sd.MinutesQualified + sd.MinutesUnqualified; flmNotBillableServiceDescAbbr[sd.ServiceCategoryAbbr] = flm; flmNotBillable += sd.MinutesQualified + sd.MinutesUnqualified; sd.IsBillable = false; } flm = 0; if (iSr.ServiceDescription.ServiceCategory.Name.IndexOf("Negativ") < 0) { if (flmPerEmployee.ContainsKey(iSr.Employee.Person)) { flm = flmPerEmployee[iSr.Employee.Person]; } else { personPerEmployee[iSr.Employee.Person] = iSr.Employee; } flm += sd.MinutesQualified + sd.MinutesUnqualified; flmPerEmployee[iSr.Employee.Person] = flm; } allServices.Add(sd); lResult.TotalFLMFehlkontakte += (double)flmFehlkontakte; lResult.TotalFLMoFehlkontakte += (double)flmOFehlkontakte; } } if (disableEmptySupportConcepts && allServices.Count == 0) { return null; } int max = 0; long oidWithMaxCount = 0; foreach (var key in cb2scOid2Count.Keys) { int count = cb2scOid2Count[key]; if (count > max) { oidWithMaxCount = key; max = count; } } if (oidWithMaxCount != 0) { if (cb2scOid2FLSApprovedPerWeek.ContainsKey(oidWithMaxCount)) { lResult.ApprovedFLSPerWeek = cb2scOid2FLSApprovedPerWeek[oidWithMaxCount]; } if (cb2scOid2FLSApprovedTotal.ContainsKey(oidWithMaxCount)) { lResult.ApprovedFLSTotal = cb2scOid2FLSApprovedTotal[oidWithMaxCount]; } if (cb2scOid2RefNumber.ContainsKey(oidWithMaxCount)) { lResult.ReferenceNumber = cb2scOid2RefNumber[oidWithMaxCount]; } } if (cb2scOid2Count.Count == 0) { foreach (var sc in customer.SupportConcepts.Where(s => s.IsActive == ActivationTypeId.Active)) { foreach (var c2s in sc.CostBearer2SupportConceptList) { if (orgaOid == 0 || (c2s.CostBearer.Organisation != null && c2s.CostBearer.Organisation.Oid.Value == orgaOid)) { if (c2s.StartDate < span.EndDate && c2s.EndDate >= span.StartDate) { lResult.ApprovedStartDate = c2s.ApprovedStartDate != null ? String.Format("{0:dd.MM.yyyy}", c2s.ApprovedStartDate.Value) : string.Empty; lResult.ApprovedEndDate = c2s.ApprovedEndDate != null ? String.Format("{0:dd.MM.yyyy}", c2s.ApprovedEndDate.Value) : string.Empty; lResult.RequestedStartDate = c2s.RequestedStartDate != null ? String.Format("{0:dd.MM.yyyy}", c2s.RequestedStartDate.Value) : string.Empty; lResult.RequestedEndDate = c2s.RequestedEndDate != null ? String.Format("{0:dd.MM.yyyy}", c2s.RequestedEndDate.Value) : string.Empty; var cb2scDC = c2s.MapToNewDC(); var calc = PluginLoader.FindClass(c2s.CostBearer.ID) ?? Calculations.GetInstance(c2s.CostBearer.ID); DateTime sdt = span.StartDateTime; if (sdt < cb2scDC.StartDate) sdt = cb2scDC.StartDate.Value; lResult.ApprovedFLSPerWeek = calc.GetApprovedHoursPerWeek(cb2scDC, sdt, false) ?? 0; lResult.ApprovedFLSTotal = calc.GetApprovedHoursTotal(cb2scDC, false) ?? 0; lResult.ReferenceNumber = c2s.CustomerReferenceNumber; } } } } } int days = DateTime.DaysInMonth(span.StartDateTime.Year, span.StartDateTime.Month); lResult.ApprovedFLSPerMonth = (lResult.ApprovedFLSPerWeek / 7) * days; lResult.ApprovedFLSPerMonthTotal = (lResult.ApprovedFLSPerWeekTotal / 7) * days; lResult.AbsenceTimes = string.Empty; if (lResult.RateFactor < 1) lResult.RateFactor = 1; if (customer.AbsenceTimes != null) { StringBuilder sb = new StringBuilder(); foreach (AbsenceTime atDb in customer.AbsenceTimes.OrderBy(a => a.Start)) { if (atDb.AbsenceSpan != null) { //Erzeuge neue Abwesenheiten, da die original Entities nicht geändert werden dürfen, falls eine nachfolgende Methode ein übergeordnetes Objekt speichert, werden die Änderungen hier sonst mitgespeichert AbsenceTime atTemp = new AbsenceTime(); AbsenceReason reasonTemp = new AbsenceReason(); reasonTemp.BillableMinutes = atDb.AbsenceReason.BillableMinutes; reasonTemp.Description = atDb.AbsenceReason.Description; atTemp.Start = atDb.Start; atTemp.End = atDb.End; atTemp.AbsenceReason = reasonTemp; atTemp.Oid = atDb.Oid; bool addToList = ( !atTemp.AbsenceReason.Description.ToLower().Contains("urlaub") && atTemp.AbsenceReason.BillableMinutes.HasValue && atTemp.AbsenceReason.BillableMinutes.Value > 0); if (atTemp.Start.HasValue) { atTemp.Start = atTemp.Start.Value.AddDays(1); } if (atTemp.End.HasValue) { atTemp.End = atTemp.End.Value.AddDays(-1); } // Prüfe ob Datum der Abwesenheit innerhalb des ausgewählten Belegzeitraums liegt if (addToList && ((atTemp.End.HasValue && atTemp.End < span.StartDateTime) || (atTemp.Start.HasValue && atTemp.Start > span.EndDateTime))) { addToList = false; } if (addToList) { if (atTemp.Start.HasValue && atTemp.End.HasValue) { var td = atTemp.End.Value.Subtract(atTemp.Start.Value).TotalDays; if (td < 0) { addToList = false; } } } if (addToList) { lResult.Abwesenheiten.Add(atTemp); if (sb.Length > 0) { sb.Append("; "); } sb.Append(atTemp.AbsenceReason.Description); sb.Append(": "); if (atTemp.Start.HasValue) { sb.Append(string.Format("{0:00}", atTemp.Start.Value.Day)); sb.Append("."); sb.Append(string.Format("{0:00}", atTemp.Start.Value.Month)); sb.Append("."); sb.Append(atTemp.Start.Value.Year.ToString().Substring(2)); sb.Append(" - "); if (atTemp.End.HasValue) { sb.Append(string.Format("{0:00}", atTemp.End.Value.Day)); sb.Append("."); sb.Append(string.Format("{0:00}", atTemp.End.Value.Month)); sb.Append("."); sb.Append(atTemp.End.Value.Year.ToString().Substring(2)); } else { sb.Append("..."); } } } } } if (sb.Length > 0) { lResult.AbsenceTimes = sb.ToString(); } } lResult.TotalFLSPerCostBearer = string.Empty; lResult.TotalFLMPerCostBearer = string.Empty; foreach (string cb in flmBillablePerCostBearer.Keys) { if (lResult.TotalFLSPerCostBearer.Length > 0) { lResult.TotalFLSPerCostBearer += ", "; } lResult.TotalFLSPerCostBearer += cb + ": " + String.Format("{0:0.##}", flmBillablePerCostBearer[cb] / 60).Replace(".", ",") + " FLS"; if (lResult.TotalFLMPerCostBearer.Length > 0) { lResult.TotalFLMPerCostBearer += ", "; } lResult.TotalFLMPerCostBearer += cb + ": " + String.Format("{0:0.##}", flmBillablePerCostBearer[cb]).Replace(".", ",") + " FLM"; } foreach (string abbr in flmNotBillableServiceDescAbbr.Keys) { if (lResult.TotalFLSPerCostBearer.Length > 0) { lResult.TotalFLSPerCostBearer += ", "; } lResult.TotalFLSPerCostBearer += abbr + ": " + String.Format("{0:0.##}", flmNotBillableServiceDescAbbr[abbr] / 60).Replace(".", ",") + " FLS"; if (lResult.TotalFLMPerCostBearer.Length > 0) { lResult.TotalFLMPerCostBearer += ", "; } lResult.TotalFLMPerCostBearer += abbr + ": " + String.Format("{0:0.##}", flmNotBillableServiceDescAbbr[abbr]).Replace(".", ",") + " FLM"; } lResult.TotalFLSPerCostBearer = "Gesamt: " + lResult.TotalFLSPerCostBearer; lResult.TotalFLMPerCostBearer = "Gesamt: " + lResult.TotalFLMPerCostBearer; foreach (Person p in flmPerEmployee.Keys) { EmployeeDetail detail = new EmployeeDetail(); detail.EmployeeName = p.FirstName.Substring(0, 1) + ". " + p.LastName; detail.TotalFLM = flmPerEmployee[p]; detail.TotalFLS = detail.TotalFLM / 60; detail.TotalFLSString = String.Format("{0:0.##}", detail.TotalFLS).Replace(".", ","); if (personPerEmployee.ContainsKey(p)) { detail.Employee = personPerEmployee[p]; } lResult.AllEmployees.Add(detail); } allServices.Sort((x, y) => { var c = x.StartDate.CompareTo(y.StartDate); if (c != 0) { return c; } return x.ServiceRecordOid.CompareTo(y.ServiceRecordOid); }); int i = 0; foreach (var iSD in allServices) { lResult._Services.Add(iSD); ServiceDoubleDetail sdd = new ServiceDoubleDetail(); sdd.CostBearer = iSD.CostBearer; sdd.EmployeeName = iSD.EmployeeAbbr; sdd.Minutes = iSD.MinutesQualified + iSD.MinutesUnqualified; sdd.CustomerCount = iSD.CustomerCount; sdd.FLS = sdd.Minutes / 60; sdd.FLSString = String.Format("{0:0.##}", sdd.FLS); sdd.FLSString = sdd.FLSString.Replace(".", ","); sdd.ServiceCategoryAbbr = iSD.ServiceCategoryAbbr; sdd.ServiceCategory = iSD.ServiceCategory; sdd.ServiceDescription = iSD.ServiceDescription; sdd.StartDate = iSD.StartDate; sdd.IsBillable = iSD.IsBillable; if (i < (allServices.Count / (float)2)) { lResult._ServicesDouble.Add(sdd); } else { sdd = lResult._ServicesDouble[i - lResult._ServicesDouble.Count]; sdd.CostBearer2 = iSD.CostBearer; sdd.EmployeeName2 = iSD.EmployeeAbbr; sdd.Minutes2 = iSD.MinutesQualified + iSD.MinutesUnqualified; sdd.CustomerCount2 = iSD.CustomerCount; sdd.FLS2 = sdd.Minutes2 / 60; sdd.FLSString2 = String.Format("{0:0.##}", sdd.FLS2); sdd.FLSString2 = sdd.FLSString2.Replace(".", ","); sdd.ServiceCategoryAbbr2 = iSD.ServiceCategoryAbbr; sdd.ServiceCategory2 = iSD.ServiceCategory; sdd.ServiceDescription2 = iSD.ServiceDescription; sdd.StartDate2 = iSD.StartDate; sdd.IsBillable2 = iSD.IsBillable; } i++; } lResult.TotalFLMQualified = flmQualified; lResult.TotalFLMUnqualified = flmUnqualified; lResult.TotalFLSQualified = flmQualified / 60; lResult.TotalFLSUnqualified = flmUnqualified / 60; lResult.TotalFLM = flmQualified + flmUnqualified; lResult.TotalFLS = lResult.TotalFLM / 60; lResult.TotalFLSFehlkontakte = lResult.TotalFLMFehlkontakte / 60; lResult.TotalFLSoFehlkontakte = lResult.TotalFLMoFehlkontakte / 60; lResult.TotalFLMBillable = flmBillable; DateTime dt = DateTime.Now.Date.AddMinutes(lResult.TotalFLMBillable); TimeSpan tspan = dt.Subtract(DateTime.Now.Date); double d = tspan.TotalHours; d = Math.Floor(d); lResult.TotalFLHoursMinutesString = String.Format("{0}:{1:00}", d, tspan.Minutes); lResult.TotalFLMQualifiedString = String.Format("{0:0.##}", flmQualified).Replace(".", ","); lResult.TotalFLMUnqualifiedString = String.Format("{0:0.##}", flmUnqualified).Replace(".", ","); lResult.TotalFLSQualifiedString = String.Format("{0:0.##}", lResult.TotalFLSQualified).Replace(".", ","); lResult.TotalFLSUnqualifiedString = String.Format("{0:0.##}", lResult.TotalFLSUnqualified).Replace(".", ","); lResult.TotalFLMString = String.Format("{0:0.##}", lResult.TotalFLM).Replace(".", ","); lResult.TotalFLSString = String.Format("{0:0.##}", lResult.TotalFLS).Replace(".", ","); lResult.TotalGefahreneKilometerString = String.Format("{0:0.##}", lResult.TotalGefahreneKilometer); lResult.Mandator = MapperFactory.MandatorDC_Mandator.MapToNewDC(AppSettings.GetMandatorEntity()); // if (cb2scOid2Data.Count == 1) // { // lResult.CostBearer2SupportConceptData = cb2scOid2Data.Values.First(); // } if (cb2scs.Count == 1) { lResult.SupportConceptCostBearer = cb2scs.Values.First(); } var mandatorSettings = lResult.Mandator?.Settings; var serviceRecordOids = lResult.Services.Where(service => service.IsBillable).Select(service => service.ServiceRecordOid).ToList(); var employeeSignature = DAOFactory.SearchDAO.GetConfirmationReceiptSignatureForServiceRecords(serviceRecordOids, SignatureType.Employee); if(employeeSignature?.SignatureImage != null) { lResult.EmployeeSignature = ImageUtils.ConvertBase64StringToBitmap(employeeSignature?.SignatureImage); lResult.EmployeeSignatureDate = employeeSignature?.InsTs; } var customerSignature = DAOFactory.SearchDAO.GetConfirmationReceiptSignatureForServiceRecords(serviceRecordOids, SignatureType.Customer); if(customerSignature?.SignatureImage != null) { lResult.CustomerSignature = ImageUtils.ConvertBase64StringToBitmap(customerSignature.SignatureImage); lResult.CustomerSignatureDate = customerSignature.InsTs; } return lResult; } public static void CreateGoalList(ServiceDetail sd) { var serviceRecord = DAOFactory.GenericDAO.LoadByID(sd.ServiceRecordOid); var srDc = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDC(serviceRecord); sd.GoalList = String.Empty; if (srDc.Goals != null && srDc.Goals.Count > 0) { foreach (var goal in srDc.Goals) { // Ohne diese Abfrage wird das selbe Ziel so oft eingefügt wie die Anzahl der Gruppenmitglieder ist if (sd.CustomerCount > 1 && !string.IsNullOrEmpty(goal.TypeDescription) && sd.GoalList.Contains(goal.TypeDescription)) continue; if (sd.GoalList.Length > 0) { sd.GoalList += ", "; } if (!string.IsNullOrEmpty(goal.TypeDescription)) { sd.GoalList += goal.TypeDescription; } else { sd.GoalList += goal.Abbreviation; } } } } public static void CreateSignatureString(ServiceDetail sd) { if (sd.SignatureOid.HasValue && String.IsNullOrEmpty(sd.Signature)) { var sig = DAOFactory.GenericDAO.GetByID(sd.SignatureOid.Value); if (sig != null) { sd.Signature = sig.DataBild; if (sig.Zeitstempel > DateTime.MinValue) { sd.SignatureDate = sig.Zeitstempel; } } } } public void CreateDummyEntries(bool summarizeDays) { var dayDict = new Dictionary(); var newList = new List(); if (this.Services != null) { foreach (var sd in this.Services) { if (!dayDict.ContainsKey(sd.StartDate.Day)) { dayDict.Add(sd.StartDate.Day, sd); newList.Add(sd); } else { if (summarizeDays) { var sumRecord = dayDict[sd.StartDate.Day]; sumRecord.Minutes += sd.Minutes; } else { newList.Add(sd); } } } for (int i = 1; i <= this.EndDate.Day; i++) { if (!dayDict.ContainsKey(i)) { //Erstelle Dummy Records für fehlende Tage var newSr = new ServiceDetail(); newSr.StartDate = new DateTime(this.StartDate.Year, this.StartDate.Month, i); newList.Add(newSr); } } this.Services = newList.OrderBy(s => s.StartDate).ToList(); } } private static int GetKW(DateTime actualDate) { Calendar objCal = CultureInfo.CurrentCulture.Calendar; int weekofyear = objCal.GetWeekOfYear(actualDate, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday); return weekofyear; } public static ServicesOverviewRO CopyFromRO(ServicesOverviewRO ro) { ServicesOverviewRO newRo = new ServicesOverviewRO(); newRo.StartDate = ro.StartDate; newRo.Abwesenheiten = ro.Abwesenheiten; newRo.AbsenceTimes = ro.AbsenceTimes; newRo.ApprovedEndDate = ro.ApprovedEndDate; newRo.ApprovedFLSPerMonth = ro.ApprovedFLSPerMonth; newRo.ApprovedFLSPerMonthTotal = ro.ApprovedFLSPerMonthTotal; newRo.ApprovedFLSPerWeek = ro.ApprovedFLSPerWeek; newRo.ApprovedFLSPerWeekTotal = ro.ApprovedFLSPerWeekTotal; newRo.ApprovedFLSTotal = ro.ApprovedFLSTotal; newRo.ApprovedStartDate = ro.ApprovedStartDate; newRo.ContactEmployee = ro.ContactEmployee; newRo.CostBearer2SupportConceptList = ro.CostBearer2SupportConceptList; newRo.Costbearer = ro.Costbearer; newRo.CustomerBirthday = ro.CustomerBirthday; newRo.CustomerLastName = ro.CustomerLastName; newRo.CustomerCity = ro.CustomerCity; newRo.CustomerFirstName = ro.CustomerFirstName; newRo.CustomerName = ro.CustomerName; newRo.CustomerPostalCode = ro.CustomerPostalCode; newRo.CustomerStreet = ro.CustomerStreet; newRo.CustomerInsuranceNumber = ro.CustomerInsuranceNumber; newRo.EndDate = ro.EndDate; newRo.FreeMinutesThisMonth = ro.FreeMinutesThisMonth; newRo.Month = ro.Month; newRo.Year = ro.Year; newRo.MainAttendant = ro.MainAttendant; newRo.MainAttendantCommaSeperated = ro.MainAttendantCommaSeperated; newRo.ReferenceNumber = ro.ReferenceNumber; newRo.TotalFLMBillable = ro.TotalFLMBillable; newRo.TotalFLM = ro.TotalFLM; newRo.TotalFLMFehlkontakte = ro.TotalFLMFehlkontakte; newRo.TotalFLMoFehlkontakte = ro.TotalFLMoFehlkontakte; newRo.TotalFLMQualified = ro.TotalFLMQualified; newRo.TotalFLMUnqualified = ro.TotalFLMUnqualified; newRo.TotalFLMQualifiedString = ro.TotalFLMQualifiedString; newRo.TotalFLMUnqualifiedString = ro.TotalFLMUnqualifiedString; newRo.TotalFLS = ro.TotalFLS; newRo.TotalFLSFehlkontakte = ro.TotalFLSFehlkontakte; newRo.TotalFLSoFehlkontakte = ro.TotalFLSoFehlkontakte; newRo.TotalFLSQualified = ro.TotalFLSQualified; newRo.TotalFLSUnqualified = ro.TotalFLSUnqualified; newRo.TotalFLSPerCostBearer = ro.TotalFLSPerCostBearer; newRo.TotalFLMPerCostBearer = ro.TotalFLMPerCostBearer; newRo.TotalGefahreneKilometer = ro.TotalGefahreneKilometer; newRo.SupportConceptCostBearer = ro.SupportConceptCostBearer; newRo.Mandator = ro.Mandator; newRo.CustomerOid = ro.CustomerOid; newRo.AllEmployees = ro.AllEmployees; newRo.EmployeeSignature = ro.EmployeeSignature; newRo.EmployeeSignatureDate = ro.EmployeeSignatureDate; newRo.CustomerSignature = ro.CustomerSignature; newRo.CustomerSignatureDate = ro.CustomerSignatureDate; return newRo; } [DebuggerDisplay("{EmployeeName}")] public class EmployeeDetail { public string EmployeeName { get; set; } public double TotalFLM { get; set; } public double TotalFLS { get; set; } public string TotalFLSString { get; set; } public Employee Employee { get; set; } // Unterschriftenobjekt hinzufügen // Nur, wenn die Unterschrift mit allen Einträgen im RO verknüpft ist? // Was ist mit Einträgen von anderen Mitarbeitern im Quittierungsbeleg? // Wer ist der verantwortliche Mitarbeiter? } [DebuggerDisplay("{StartDateString}: {Minutes}min {ServiceCategory}/{ServiceDescription}")] public class ServiceDetail { public long ServiceRecordOid { get; set; } public string CostBearer { get; set; } public int CustomerCount { get; set; } public string EmployeeAbbr { get; set; } public long EmployeeOid { get; set; } public int EmployeeCount { get; set; } public string EmployeeFullname { get; set; } public string EmployeeNameCommaSeparated { get; set; } public DateTime EndDate { get; set; } public DateTime? EndDateMinutes { get; set; } public double FLSQualified { get; set; } public string FLSQualifiedString { get; set; } public double FLSUnqualified { get; set; } public string FLSUnqualifiedString { get; set; } public double GroupMinutes { get; set; } public decimal? GroupRoundedDuration { get; set; } public bool IsBillable { get; set; } public bool IsGroup { get; set; } public int KW { get; set; } public double Minutes { get; set; } public DateTime MinutesDateTime { get; set; } public double MinutesQualified { get; set; } public double MinutesUnqualified { get; set; } public decimal ProzentAbrechenbar { get; set; } public string Notice { get; set; } public string Notice2 { get; set; } public string Notice3 { get; set; } public string Notice4 { get; set; } public string Notice5 { get; set; } public string ServiceCategory { get; set; } public string ServiceCategoryAbbr { get; set; } public string ServiceDescription { get; set; } public DateTime StartDate { get; set; } public DateTime? StartDateMinutes { get; set; } public string StartDateString { get; set; } public string TimeRangeString { get; set; } public DateTime EndDateNotRounded { get; set; } public string GefahreneKilometer { get; set; } //Wird aus Performancegründen nicht automatisch gesetzt. Kann bei Bedarf in den Kundenreports erstellt werden public string GoalList { get; set; } public bool IstFeiertag { get; set; } public bool IstFerien { get; set; } public bool IstSamstag { get; set; } public bool IstSonntag { get; set; } public long? SignatureOid { get; set; } public String Signature { get; set; } public DateTime? SignatureDate { get; set; } public string EmployeeFirstName { get; set; } public string EmployeeLastName { get; set; } public Bitmap SignatureImage { get; set; } public bool DurationInStunden { get; set; } } public class ServiceDoubleDetail { public string CostBearer { get; set; } public string CostBearer2 { get; set; } public string EmployeeName { get; set; } public string EmployeeName2 { get; set; } public double FLS { get; set; } public double FLS2 { get; set; } public string FLSString { get; set; } public string FLSString2 { get; set; } public bool IsBillable { get; set; } public bool IsBillable2 { get; set; } public double Minutes { get; set; } public double Minutes2 { get; set; } public string ServiceCategory { get; set; } public string ServiceCategory2 { get; set; } public string ServiceCategoryAbbr { get; set; } public string ServiceCategoryAbbr2 { get; set; } public string ServiceDescription { get; set; } public string ServiceDescription2 { get; set; } public DateTime StartDate { get; set; } public DateTime StartDate2 { get; set; } public int CustomerCount { get; set; } public int CustomerCount2 { get; set; } } public class ApprovalDetail { public DateTime TimeSpanStartDate { get; set; } public DateTime TimeSpanEndDate { get; set; } public DateTime? TotalStartDate { get; set; } public DateTime? TotalEndDate { get; set; } public int DaysInTimeSpan { get { return (int)TimeSpanEndDate.Subtract(TimeSpanStartDate).TotalDays + 1; } } public int DaysTotal { get { if (!TotalStartDate.HasValue || !TotalEndDate.HasValue) return 0; return (int)TotalEndDate.Value.Subtract(TotalStartDate.Value).TotalDays + 1; } } public decimal ApprovedHoursPerWeek { get; set; } public decimal ApprovedHoursInTimeSpan { get; set; } public decimal ApprovedHoursTotal { get; set; } public decimal UsedHoursInTimeSpan { get; set; } public decimal UsedHoursPreviousMonths { get; set; } public decimal RemainingHoursInTimeSpan { get { return ApprovedHoursInTimeSpan - UsedHoursInTimeSpan; } } public decimal RemainingHoursTotal { get { return ApprovedHoursTotal - UsedHoursPreviousMonths; } } } } }