using BeWo.Report; using BeWo.Report.ReportObjects; using BeWoPlanerMobil.Models; using BeWoPlanerMobil.Service; using BeWoPlanerMobil.Util; using BeWoPlanerMobil.Util.ReportUtils; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.Extensions; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Web.Mvc; using BeWo.Service.Plugins; using DevExpress.XtraReports.UI; // Controller des Quittierungsbelegsmoduls namespace BeWoPlanerMobil.Controllers { public class ReportController : AbstractBaseController { private ReportModel _Model; public ReportModel Model { get { if(!MobileSessionFacade.IsUserLoggedIn()) { RedirectToActionPermanent("Index", "Login"); return null; } if (_Model == null) { _Model = new ReportModel { ReportCreator = GetReportCreator() }; InitModel(_Model); InitViewModel(); } //if (((ReportModel) Session[ModelSessionConstants.ReportModelKey])?.LoggedInEmployee is null) //{ // _Model = new ReportModel {ReportCreator = GetReportCreator()}; // InitModel(_Model); // Session[ModelSessionConstants.ReportModelKey] = _Model; //} //else //{ // _Model = (ReportModel) Session[ModelSessionConstants.ReportModelKey]; //} return _Model; } } private void InitViewModel() { var month = DateTime.Today.Month; var year = DateTime.Today.Year; var first = new DateTime(year, month, 1).AddMonths(-1); var last = first.AddMonths(1).AddDays(-1); Model.SelectedYear = Model.SelectedYear ?? first.Year; Model.SelectedMonth = Model.SelectedMonth ?? first.Month; Model.SelectedStartDay = Model.SelectedStartDay ?? first.Day; Model.SelectedEndDay = Model.SelectedEndDay ?? last.Day; InitFilterCombo(); Model.Customers.Clear(); Model.Customers = CustomerService.GetAllActiveCustomersForEmployee(); Model.Employees = EmployeeService.GetActiveCompactEmployeesForEmployee(LoggedInEmployee.EmployeeOid.Value); Model.ServiceCategories = OperationsService.GetAllServiceCategories(); Model.Organisations = CustomerService.GetAllCostBearerCompact(); Model.Organisations.Sort((x, y) => string.Compare(x.Name, y.Name, StringComparison.CurrentCulture)); Model.AllTeams = EmployeeService.GetAllActiveCompactTeamsForEmployee(LoggedInEmployee.EmployeeOid.Value); Model.Dokutypes = ValueListService.GetAllValueListEntrysByType(ValueListEntryType.DocumentType); if (Model.Dokutypes != null) { Model.Dokutypes = Model.Dokutypes.OrderBy(s => s.ValueListEntryOid).ToArray(); } if (Model.SelectedCustomerOid.HasValue) { Model.SelectedCustomer = Model.Customers.FirstOrDefault(customer => customer.CustomerOid == Model.SelectedCustomerOid.Value); } if (Model.SelectedEmployeeOid.HasValue) { Model.SelectedEmployee = Model.Employees.FirstOrDefault(employee => employee.EmployeeOid.Equals(Model.SelectedEmployeeOid.Value)); } if (Model.SelectedTeamOid.HasValue) { Model.SelectedTeam = Model.AllTeams.FirstOrDefault(team => team.TeamOid == Model.SelectedTeamOid.Value); } if (Model.SelectedOrganisationOid.HasValue) { Model.SelectedOrganisation= Model.Organisations.FirstOrDefault(organisation => organisation.OrganisationOid.Equals(Model.SelectedOrganisationOid.Value)); } if (Model.SelectedServiceCategoryOid.HasValue) { Model.SelectedServiceCategory = Model.ServiceCategories.FirstOrDefault(serviceCategory => serviceCategory.ServiceCategoryOid == Model.SelectedServiceCategoryOid.Value); } } private static AbstractReportCreator GetReportCreator() { var creator = PluginLoader.FindClass(); #if DEBUG creator.TempPath = BS.Shared.Core.Utils.CreateSavePath(AppDomain.CurrentDomain.BaseDirectory, @"demo\temp"); #else creator.TempPath = BS.Shared.Core.Utils.CreateSavePath(AppDomain.CurrentDomain.BaseDirectory, PluginLoader.Tenant + @"\temp"); #endif return creator; } // Veraltet, wird nicht mehr benutzt. [Authorize] public ActionResult Report() { if(!MobileSessionFacade.IsUserLoggedIn() || Request.Browser.Browser.Equals("InternetExplorer")) { return Logout(); } if(!_Model.HasRightToViewQuittierungsbelege) { return RedirectToActionPermanent("Main", "Main"); } return View(Model); } [Authorize] public ActionResult InitReports() { try { if(!MobileSessionFacade.IsUserLoggedIn() || Request.Browser.Browser.Equals("InternetExplorer") || Model?.LoggedInEmployee?.EmployeeOid is null) { return Logout(); } if(!Model.HasRightToViewQuittierungsbelege) { return RedirectToActionPermanent("Main", "Main"); } if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } } catch(Exception e) { Log.Error(e.Message, e); } return View("Report", Model); } private void InitFilterCombo() { Model.QbFilters.Clear(); var filterList = new List(); var hasRightToViewCustomers = Model.CheckForAtLeastOneRight(new[] { UserRightType.CustomerView_View, UserRightType.ViewAll }); var hasRightToViewMyTeams = Model.CheckForAtLeastOneRight(new[] { UserRightType.Customer_ViewMyTeams, UserRightType.ViewAll }); if(hasRightToViewCustomers) { filterList.Add(new QbFilterItem(QBFilterEnum.AlleKlienten)); } if(hasRightToViewMyTeams) { filterList.Add(new QbFilterItem(QBFilterEnum.NurKlientenMeinesTeams)); } filterList.Add(new QbFilterItem(QBFilterEnum.MeineKlienten)); filterList.Add(new QbFilterItem(QBFilterEnum.KlientenAuswahl)); if(Model.CheckRight(UserRightType.TeamView_ViewMyTeams) && false == Model.CheckRight(UserRightType.TeamView_ViewAll)) { if(hasRightToViewMyTeams) { filterList.Add(new QbFilterItem(QBFilterEnum.TeamAuswahl)); } } else if(Model.CheckRight(UserRightType.TeamView_ViewAll)) { if(hasRightToViewCustomers) { filterList.Add(new QbFilterItem(QBFilterEnum.TeamAuswahl)); } } Model.QbFilters = filterList; } /// /// Ermittelt den Unterschriftenstatus, der besagt, ob für alle ausgewählten Zeiterfassungseinträge eine Unterschrift existiert. /// /// Oids der ausgewählten Zeiterfassungseinträge /// Oids der ausgewählten Zeiterfassungseinträge mit Unterschrift /// Typ der Unterschrift; entweder von Mitarbeitern oder von Klienten /// private static SignatureState GetSignatureState(List oids, Dictionary> serviceRecordOidsWithSignature, SignatureType signatureType) { var hasSignatures = oids.All(signatureOid => serviceRecordOidsWithSignature.ContainsValueAtKey(signatureType, signatureOid)); var hasSomeSignatures = oids.Any(signatureOid => serviceRecordOidsWithSignature.ContainsValueAtKey(signatureType, signatureOid)); if(hasSignatures) { return SignatureState.All; } return hasSomeSignatures ? SignatureState.Some : SignatureState.None; } /// /// Erzeugt den String, der in der Filterauswahl angezeigt wird. /// /// Ob es sich um ein Dativ-Objekt handelt /// Grammatikalisch korrekten Satz für die Filterauswahl private string BuildInformationString(bool isDativ = false) { var stringBuilder = new StringBuilder(isDativ ? string.Empty : "Einträge für "); // Einträge für [alle Klienten/die Klienten meines Teams/meine Klienten/[CustomerName]/[TeamName]] [von [Mitarbeiter] [bei [Kostenträger]] und [Leistungskategorie]] vom 01.10. bis 31.10.2020 // Einträge für Grube, Clair von Fisher, George bei LWL und face-to-face vom 01.10. bis 31.10.2020 // Unterschrift für x erbrachte Leistungen von switch(Model.SelectedFilterItem?.FilterEnum) { case QBFilterEnum.KlientenAuswahl: stringBuilder.Append(Model.SelectedCustomer); break; case QBFilterEnum.MeineKlienten: stringBuilder.Append(isDativ ? "meinen" : "meine"); stringBuilder.Append(" Klienten"); break; case QBFilterEnum.NurKlientenMeinesTeams: stringBuilder.Append(isDativ ? "den" : "die"); stringBuilder.Append(" Klienten meines Teams"); break; case QBFilterEnum.TeamAuswahl: stringBuilder.Append(Model.SelectedTeam); break; default: stringBuilder.Append(isDativ ? "allen" : "alle"); stringBuilder.Append(" Klienten"); break; } stringBuilder.Append(" "); if(Model.SelectedEmployee != null) { stringBuilder.Append($"von {Model.SelectedEmployee} "); } if(Model.SelectedOrganisation != null) { stringBuilder.Append($"bei {Model.SelectedOrganisation} "); } if(Model.SelectedServiceCategory != null) { if(Model.SelectedEmployee != null || Model.SelectedOrganisation != null) { stringBuilder.Append("und "); } stringBuilder.Append(Model.SelectedServiceCategory.Name); } stringBuilder.Append(GetTimeSpanString()); return stringBuilder.ToString(); } private string GetTimeSpanString() { var month = Model.SelectedMonth < 10 ? $"0{Model.SelectedMonth}" : Model.SelectedMonth.ToString(); var year = Model.SelectedYear; var vom = Model.SelectedStartDay < 10 ? $"0{Model.SelectedStartDay}" : Model.SelectedStartDay.ToString(); var bis = Model.SelectedEndDay < 10 ? $"0{Model.SelectedEndDay}" : Model.SelectedEndDay.ToString(); return $"vom {vom}.{month}. bis {bis}.{month}.{year}"; } [Authorize] public string CheckForSelectedOrganization() { return Model?.SelectedOrganisation != null ? $"{Model.SelectedOrganisation.DetailDescription}_{Model.SelectedOrganisation.OrganisationOid}" : LeerzeichenFuerGetMethoden; } [Authorize] public string CheckForSelectedEmployee() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return LeerzeichenFuerGetMethoden; } if(Model.SelectedEmployee is null && (Model.LoggedInEmployee?.EmployeeOid.HasValue ?? false)) { return $"{Model.LoggedInEmployee.LastNameFirstName}_{Model.LoggedInEmployee.EmployeeOid.Value}"; } return $"{Model.SelectedEmployee.DetailDescription}_{Model.SelectedEmployee.EmployeeOid}"; } [Authorize] public string SetCustomer(long customerOid) { if(Model is null) { return LeerzeichenFuerGetMethoden; } Model.SelectedCustomer = Model.Customers.FirstOrDefault(customer => customer.CustomerOid == customerOid); Model.SelectedCustomerOid = customerOid; return Model.SelectedCustomer?.DetailDescription ?? LeerzeichenFuerGetMethoden; } [Authorize] public string SetTeam(long teamOid) { if(Model is null) { return LeerzeichenFuerGetMethoden; } Model.SelectedTeam = Model.AllTeams.FirstOrDefault(team => team.TeamOid == teamOid); Model.SelectedTeamOid = teamOid; return Model.SelectedTeam?.DetailDescription ?? string.Empty; } [Authorize] public string ChangeDateSelection(string startDayString, string endDayString, string monthString, string yearString) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var isParsingSuccessful1 = int.TryParse(startDayString, out var startDay); var isParsingSuccessful2 = int.TryParse(endDayString, out var endDay); var isParsingSuccessful3 = int.TryParse(monthString, out var month); var isParsingSuccessful4 = int.TryParse(yearString, out var year); if(isParsingSuccessful1 && isParsingSuccessful2 && isParsingSuccessful3 && isParsingSuccessful4) { var start = new DateTime(year, month, startDay); var end = new DateTime(year, month, endDay); Model.SelectedEndDay = end.Day; Model.SelectedStartDay = start.Day; Model.SelectedMonth = month; Model.SelectedYear = year; } return LeerzeichenFuerGetMethoden; } [Authorize] public string ChangeIntervalSelection(int selectedInterval, int month, int year) { Model.SelectedIntervalSelection = (QbSignatureIntervalSelection) selectedInterval; Model.SelectedMonth = month; Model.SelectedYear = year; var lastDayOfMonth = new DateTime(year, month, 1).GetLastOfMonth(); switch(Model.SelectedIntervalSelection) { case QbSignatureIntervalSelection.FirstHalf: Model.SelectedStartDay = 1; Model.SelectedEndDay = 15; break; case QbSignatureIntervalSelection.SecondHalf: Model.SelectedStartDay = 16; Model.SelectedEndDay = lastDayOfMonth.Day; break; default: Model.SelectedStartDay = 1; Model.SelectedEndDay = lastDayOfMonth.Day; break; } return LeerzeichenFuerGetMethoden; } [Authorize] public string ChangeFilters(string organisationOidStr, string categoryOidStr) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } Model.SelectedOrganisationOid = null; Model.SelectedServiceCategoryOid = null; if (long.TryParse(organisationOidStr, out var organisationOid)) { Model.SelectedOrganisationOid = organisationOid; } if (long.TryParse(categoryOidStr, out var categoryOid)) { Model.SelectedServiceCategoryOid = categoryOid; } //Model.SelectedOrganisation = isParsingSuccessful2 ? Model.Organisations.FirstOrDefault(organisation => organisation.OrganisationOid.Equals(organisationOid)) : null; //Model.SelectedServiceCategory = isParsingSuccessful3 ? OperationsService.LoadServiceCategory(categoryOid) : null; return LeerzeichenFuerGetMethoden; } [Authorize] public string ChangeIsForSelectedEmployeesOnly(bool? isForSelectedEmployeeOnly, long? employeeOid) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } Model.IsForSelectedEmployeesOnly = isForSelectedEmployeeOnly ?? false; Model.SelectedEmployee = employeeOid.HasValue ? Model.Employees.FirstOrDefault(employee => employee.EmployeeOid.Equals(employeeOid.Value)) : null; Model.SelectedEmployeeOid = employeeOid; return LeerzeichenFuerGetMethoden; } [Authorize] public string SetEmployeeOid(long? employeeOid) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } Model.SelectedEmployee = employeeOid.HasValue ? Model.Employees.FirstOrDefault(employee => employee.EmployeeOid.Equals(employeeOid)) : null; Model.SelectedEmployeeOid = employeeOid; return Model.SelectedEmployee?.DetailDescription ?? LeerzeichenFuerGetMethoden; } [Authorize] public string ChangeIsForSelectedOrganisationOnly(bool? isForSelectedOrganisationOnly, long? organisationOid) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } Model.IsForSelectedCostbearersOnly = isForSelectedOrganisationOnly ?? false; Model.SelectedOrganisation = organisationOid.HasValue && Model.IsForSelectedCostbearersOnly ? Model.Organisations.FirstOrDefault(organisation => organisation.OrganisationOid.Equals(organisationOid)) : null; Model.SelectedOrganisationOid = organisationOid; return LeerzeichenFuerGetMethoden; } [Authorize] public string SetOrganisationOid(long? organisationOid) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } Model.SelectedOrganisation = organisationOid.HasValue ? Model.Organisations.FirstOrDefault(organisation => organisation.OrganisationOid.Equals(organisationOid)) : null; Model.SelectedOrganisationOid = organisationOid; return Model.SelectedOrganisation?.DetailDescription ?? LeerzeichenFuerGetMethoden; } [Authorize] public string ChangeIsForSelectedServiceCategoryOnly(bool? isForSelectedServiceCategoryOnly, long? serviceCategoryOid) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } Model.IsForSelectedCategoryOnly = isForSelectedServiceCategoryOnly ?? false; Model.SelectedServiceCategory = serviceCategoryOid.HasValue && Model.IsForSelectedCategoryOnly ? Model.ServiceCategories.FirstOrDefault(serviceCategory => serviceCategory.ServiceCategoryOid == serviceCategoryOid) : null; Model.SelectedServiceCategoryOid = serviceCategoryOid; return LeerzeichenFuerGetMethoden; } [Authorize] public string SetServiceCategoryOid(long? serviceCategoryOid) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } if(serviceCategoryOid.HasValue) { Model.SelectedServiceCategory = Model.ServiceCategories.FirstOrDefault(serviceCategory => serviceCategory.ServiceCategoryOid == serviceCategoryOid); } Model.SelectedServiceCategoryOid = serviceCategoryOid; return LeerzeichenFuerGetMethoden; } /// /// Setzt den Quittierungsbelegsfilter; alle Klienten, nur Klienten meines Teams, Meine Klienten, Klient auswählen, oder Team auswählen /// /// Der Enum, der dem ausgewählten Quittierungsbelegsfilter entspricht /// Das Leerzeichen für Get-Methoden. Ansonsten kann es zu Fehlern im JavaScript kommen. [Authorize] public string SetQbFilterEnum(string filterEnumString) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var isParsingSuccessful = int.TryParse(filterEnumString, out var filterEnumValue); if(!isParsingSuccessful) { return LeerzeichenFuerGetMethoden; } var selectedFilterEnum = (QBFilterEnum) filterEnumValue; Model.SelectedFilterItemId = selectedFilterEnum; if(selectedFilterEnum != QBFilterEnum.KlientenAuswahl || Model.SelectedCustomer != null) { return LeerzeichenFuerGetMethoden; } var customer = Model.Customers.FirstOrDefault(); if(!(customer is null)) { Model.SelectedCustomerOid = customer.CustomerOid; } return LeerzeichenFuerGetMethoden; } [Authorize] [HttpPost] public string CreateSignatureForServiceOverview(string base64SignatureString, string customerOidString, bool? isCustomerSignature, bool? overwrite) { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } var shouldOverwrite = overwrite.HasValue && overwrite.Value; var isCustomerSig = isCustomerSignature.HasValue && isCustomerSignature.Value; var isSuccessful = long.TryParse(customerOidString, out var customerOid); if(!isSuccessful || customerOid == 0) { return MobileUtils.SerializeObject("Es ist ein unbekannter Fehler aufgetreten. Bitte wenden Sie sich an den Administrator."); } var signatureType = isCustomerSig ? SignatureType.Customer : SignatureType.Employee; var serviceRecordOids = new List(); var resultList = Model.ConfirmationReceiptObject.ConfirmationReceiptResultList; if(customerOid > 0L) { resultList = resultList.Where(item => item.CustomerOid == customerOid).ToList(); } resultList.DoForEach(result => result.Items.DoForEach(item => serviceRecordOids.AddIfNotIn(item.ServiceRecordOid))); var existingServiceRecordSignatures = OperationsService.LoadConfirmationReceiptSignaturesByServiceRecordOids(serviceRecordOids, signatureType, out var serviceRecordOidsWithSignature); var serviceRecords = OperationsService.GetServiceRecordsByIds(serviceRecordOids); using(var signatureBitmap = SignatureUtils.Base64StringToBitmap(base64SignatureString.Split(',')[1])) { var isValid = SignatureUtils.ValidateSignature(signatureBitmap); if(!isValid) { return MobileUtils.SerializeObject("Das Unterschriftenfeld darf nicht leer sein."); } if(shouldOverwrite) { foreach(var csr in existingServiceRecordSignatures) { var temp = csr.ServiceRecords.Where(sr => sr.ServiceRecordOid.HasValue && !serviceRecordOidsWithSignature.Contains(sr.ServiceRecordOid.Value)); if(!Model.HasRightToProvideEmployeeSignatureForOthers) { temp = temp.Where(sr => sr.Employee.Equals(LoggedInUser.Employee)); } csr.ServiceRecords.Clear(); csr.ServiceRecords.AddRangeIfElementsNotIn(temp); if(csr.ServiceRecords.Count == 0 && csr.ConfirmationReceiptSignatureOid.HasValue) { OperationsService.DeleteConfirmationReceiptSignature(csr.ConfirmationReceiptSignatureOid.Value); } else { OperationsService.UpdateConfirmationReceiptSignature(csr); } } } else { serviceRecords = serviceRecords.Where(sr => sr.ServiceRecordOid.HasValue && !serviceRecordOidsWithSignature.Contains(sr.ServiceRecordOid.Value)).ToList(); } var timeSpanString = GetTimeSpanString(); if(timeSpanString.Contains("vom")) { timeSpanString = timeSpanString.Substring(4); } var filteredServiceRecords = new List(); if(!isCustomerSig && !Model.HasRightToProvideEmployeeSignatureForOthers) { filteredServiceRecords = serviceRecords.Where(sr => sr.Employee.Equals(LoggedInUser.Employee)).ToList(); } else { filteredServiceRecords = serviceRecords; } var confirmationReceiptSignature = new ConfirmationReceiptSignatureDC { ServiceRecords = filteredServiceRecords, CustomerOid = isCustomerSig ? (long?) customerOid : null, Employee = isCustomerSig ? null : LoggedInUser.Employee, SignatureImage = base64SignatureString, SignatureType = signatureType, TimeSpanString = timeSpanString }; OperationsService.InsertConfirmationReceiptSignature(confirmationReceiptSignature); } return LeerzeichenFuerGetMethoden; } [Authorize] public string LoadConfirmationReceiptSignatures(string oidsAsString) { try { if(Model is null) { Logout(); return LeerzeichenFuerGetMethoden; } if(!string.IsNullOrWhiteSpace(oidsAsString)) { var oidStrings = oidsAsString.Split(','); var oids = new List(); foreach(var oidString in oidStrings) { if(long.TryParse(oidString, out var oid)) { oids.AddIfNotIn(oid); } } var signatures = Model.GetConfirmationReceitSignaturesByOids(oids).Where(signature => signature.SignatureImage != null).ToList(); return MobileUtils.SerializeObject(ConvertSignatureDCsToSignatureObjects(signatures)); } return LeerzeichenFuerGetMethoden; } catch(Exception exception) { return MobileUtils.SerializeObject("Ein Fehler ist aufgetreten. Bitte wenden Sie sich an Ihren Administrator."); } } private List ConvertSignatureDCsToSignatureObjects(List dataContracts) { var result = new List(); if(dataContracts is null) { return result; } foreach(var signature in dataContracts.OrderBy(o => o.InsTs)) { var img = MainController.ApplyWatermark(signature.SignatureImage, Server.MapPath("../Content/images/bewoplaner_by_ownsoft_logo_mok.png")); var date = signature.InsTs?.ToString("dd.MM.yyyy HH:mm:ss") ?? "unbekannt"; var personName = signature.SignatureType == SignatureType.Customer ? (Model.Customers.FirstOrDefault(f => f.CustomerOid.Equals(signature.CustomerOid))?.LastNameFirstName ?? "unbekannt") : signature.Employee.SimpleDescription; result.AddIfNotIn(new ConfirmationReceiptSignatureObject(img, date, personName, signature.SignatureType == SignatureType.Employee, signature.ServiceRecords)); } return result; } /// /// Lädt die Übersicht über bereits geleistete oder fehlende Unterschriften für den ausgewählten Zeitraum /// /// Das QuittierungsbelegsResultPartial, das die Liste enthält [Authorize] public ActionResult LoadServiceOverview() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("QuittierungsbelegsResultPartial"); } if(Model.SelectedFilterItem is null) { // ToDo: Warnung einbauen? return RedirectToActionPermanent("Report"); } LoadPaginatedQbEntries(1); return PartialView("QuittierungsbelegsResultPartial", Model); } /// /// Erstellt den Zeitraum für die Auswahl /// /// private ReportTimeFrame GetReportTimeFrame() { var month = DateTime.Today.Month; var year = DateTime.Today.Year; var first = new DateTime(year, month, 1).AddMonths(-1); var last = first.AddMonths(1).AddDays(-1); return new ReportTimeFrame(Model.SelectedYear ?? year, Model.SelectedMonth ?? month, Model.SelectedStartDay ?? first.Day, Model.SelectedEndDay ?? last.Day); } [Authorize] [HttpPost] public ActionResult DeleteCustomerSignature(FormCollection formCollection) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var info = formCollection["deleteCustomerSignaturesInfo"]; if(Model.HasRightToDeleteReceiptSignatures) { DeleteSignatures(info, true); } LoadPaginatedQbEntries(Model.CurrentQbEntryPage); return RedirectToAction("InitReports"); } [Authorize] [HttpPost] public ActionResult DeleteEmployeeSignature(FormCollection formCollection) { if(Model?.ConfirmationReceiptObject is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var info = formCollection["deleteEmployeeSignatureInfo"]; if(Model.HasRightToDeleteReceiptSignatures) { DeleteSignatures(info, false); } LoadPaginatedQbEntries(Model.CurrentQbEntryPage); return RedirectToAction("InitReports"); } [Authorize] private void DeleteSignatures(string guid, bool isCustomerSignature) { if(Model is null || !Model.HasRightToDeleteReceiptSignatures) { return; } if(!Guid.TryParse(guid, out var identifier)) { return; } var list = Model.ConfirmationReceiptObject.ConfirmationReceiptResultList; var confirmationReceiptResult = list.FirstOrDefault(obj => obj.Identifier.Equals(identifier)); if(confirmationReceiptResult is null) { return; } var signatureOids = isCustomerSignature ? confirmationReceiptResult.CustomerSignatureOids : confirmationReceiptResult.EmployeeSignatureOids; var signatures = OperationsService.GetConfirmationReceiptSignatures(signatureOids); OperationsService.DeleteConfirmationReceiptSignatures(signatures.ToDictionary(s => s.ConfirmationReceiptSignatureOid.Value, s => s.ConfirmationReceiptSignatureVersion.Value)); } [Authorize] public ActionResult FetchConfirmationReceiptSignatures(string identifier, bool isEmployee) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; PartialView("ConfirmationReceiptSignaturePartial"); } if(!Guid.TryParse(identifier, out var resultIdentifier)) { return PartialView("ConfirmationReceiptSignaturePartial", Model); } var obj = Model.ConfirmationReceiptObject.ConfirmationReceiptResultList.FirstOrDefault(f => f.Identifier.Equals(resultIdentifier)); if(obj is null) { return PartialView("ConfirmationReceiptSignaturePartial", Model); } var oids = isEmployee ? obj.EmployeeSignatureOids : obj.CustomerSignatureOids; var signatures = Model.GetConfirmationReceitSignaturesByOids(oids); Model.SelectedConfirmationReceiptSignatures = ConvertSignatureDCsToSignatureObjects(signatures); var customerName = obj.CustomerName; var employeeName = LoggedInUser.Employee.SimpleDescription; var serviceRecordCount = 0; if(isEmployee) { serviceRecordCount = Model.HasRightToProvideEmployeeSignatureForOthers ? obj.Items.Count : obj.Items.Count(x => x.EmployeeOid.Equals(LoggedInEmployee.EmployeeOid)); } else { serviceRecordCount = obj.Items.Count(); } var personName = isEmployee ? employeeName : customerName; Model.Quittierungsbelegsunterschriftenobjekt = new Quittierungsbelegsunterschriftenobjekt(isEmployee, personName, Model.ConfirmationReceiptObject.TimeSpanString, customerName, serviceRecordCount, obj.CustomerOid); return PartialView("ConfirmationReceiptSignaturePartial", Model); } //[Authorize] //public ActionResult LoadReportToModel() //{ // if(Model is null) // { // TempData[TempDataConstants.DoLogoutKey] = true; // return PartialView("QuittierungsbelegsPreviewPartial"); // } // var month = Model.SelectedMonth ?? DateTime.Now.AddMonths(-1).Month; // var year = Model.SelectedYear ?? DateTime.Now.Year; // var customerOid = Model.SelectedCustomerOid; // var teamOid = Model.SelectedTeamOid; // var employeeOid = Model.SelectedEmployeeOid; // var organisationOid = Model.SelectedOrganisationOid; // var serviceCategoryOid = Model.SelectedServiceCategoryOid; // var startDate = Model.SelectedStartDay ?? 1; // var date = new DateTime(year, month, startDate); // var endDate = Model.SelectedEndDay ?? date.GetLastOfMonth().Day; // var filterType = Model.SelectedFilterItem; // Model.QuittierungsbelegsReportObject = Model.ReportCreator.CreateServiceOverviewReportNew(month, year, filterType.FilterEnum, customerOid, teamOid, employeeOid, organisationOid, serviceCategoryOid, startDate, endDate, false); // return PartialView("QuittierungsbelegsPreviewPartial", Model); //} [Authorize] public string ResetQuittierungsbeleg() { Model.QuittierungsbelegsReportSettings = null; Model.QuittierungsbelegsReport = null; return LeerzeichenFuerGetMethoden; } [Authorize] [HttpPost] public ActionResult LoadQuittierungsbeleg() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } var reportSettings = new QuittierungsbelegsReportSettings(); reportSettings.Month = Model.SelectedMonth ?? DateTime.Now.AddMonths(-1).Month; reportSettings.Year = Model.SelectedYear ?? DateTime.Now.Year; reportSettings.CustomerOid = Model.SelectedCustomerOid; reportSettings.TeamOid = Model.SelectedTeamOid; reportSettings.EmployeeOid = Model.SelectedEmployeeOid; reportSettings.OrganisationOid = Model.SelectedOrganisationOid; reportSettings.ServiceCategoryOid = Model.SelectedServiceCategoryOid; reportSettings.StartDay = Model.SelectedStartDay ?? 1; var date = new DateTime(reportSettings.Year, reportSettings.Month, reportSettings.StartDay); reportSettings.EndDay = Model.SelectedEndDay ?? date.GetLastOfMonth().Day; reportSettings.FilterEnum = Model.SelectedFilterItem.FilterEnum; Model.QuittierungsbelegsReportSettings = reportSettings; //var report = Model.ReportCreator.CreateServiceOverviewReportNew(month, year, filterType.FilterEnum, customerOid, teamOid, employeeOid, organisationOid, serviceCategoryOid, startDate, endDate, false); //report.ExportOptions.PrintPreview.DefaultFileName = CreateFileName(); //report.DisplayName = CreateFileName(); return RedirectToAction("InitReports"); } [Authorize] public ActionResult CreateQuittierungsbelegsReport() { if (Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("QuittierungsbelegsPreviewPartial"); } Model.QuittierungsbelegsReport = CreateQuittierungsbelegsReportFromSettings(); return PartialView("QuittierungsbelegsPreviewPartial", Model); } private XtraReport CreateQuittierungsbelegsReportFromSettings() { if (Model.QuittierungsbelegsReportSettings == null) { return null; } var s = Model.QuittierungsbelegsReportSettings; var report = Model.ReportCreator.CreateServiceOverviewReportNew(s.Month, s.Year, s.FilterEnum, s.CustomerOid, s.TeamOid, s.EmployeeOid, s.OrganisationOid, s.ServiceCategoryOid, s.StartDay, s.EndDay, false); report.ExportOptions.PrintPreview.DefaultFileName = CreateFileName(); report.DisplayName = CreateFileName(); return report; } private string CreateFileName() { var fileName = "Quittierungsbeleg_"; var selectedFilter = Model.SelectedFilterItem.FilterEnum; var filterText = string.Empty; switch(selectedFilter) { case QBFilterEnum.AlleKlienten: filterText = "AlleKlienten"; break; case QBFilterEnum.NurKlientenMeinesTeams: filterText = "KlientenMeinerTeams"; break; case QBFilterEnum.MeineKlienten: filterText = "MeineKlienten"; break; case QBFilterEnum.KlientenAuswahl: filterText = "KlientenAuswahl"; break; case QBFilterEnum.TeamAuswahl: filterText = "TeamAuswahl"; break; } fileName += $"{filterText}_"; if(Model.IsForSelectedEmployeesOnly) { var selectedEmployee = Model.SelectedEmployee; var employeeName = $"{selectedEmployee.LastName}-{selectedEmployee.FirstName}_"; fileName += $"{employeeName}_"; } if(Model.IsForSelectedCostbearersOnly) { var selectedCostbearer = Model.SelectedOrganisation; fileName += $"{selectedCostbearer.Name}_"; } if(Model.IsForSelectedCategoryOnly) { var selectedServiceCategory = Model.SelectedServiceCategory; fileName += $"{selectedServiceCategory.Name}_"; } if(!Model.SelectedMonth.HasValue || !Model.SelectedYear.HasValue || !Model.SelectedStartDay.HasValue || !Model.SelectedEndDay.HasValue) { return fileName; } var start = new DateTime(Model.SelectedYear.Value, Model.SelectedMonth.Value, Model.SelectedStartDay.Value); var end = new DateTime(Model.SelectedYear.Value, Model.SelectedMonth.Value, Model.SelectedEndDay.Value); fileName += $"{start:MMMM}-{start:dd}-{end:dd}-{start:yyyy}"; return fileName; } [Authorize] public ActionResult GoToFirstServiceOverviewPage() { LoadPaginatedQbEntries(1); return PartialView("QuittierungsbelegsResultPartial", Model); } [Authorize] public ActionResult GoToLastServiceOverviewPage() { LoadPaginatedQbEntries(Model.QbEntryPageCount); return PartialView("QuittierungsbelegsResultPartial", Model); } [Authorize] public ActionResult LoadServiceOverviewPage(int selectedPage) { LoadPaginatedQbEntries(selectedPage); return PartialView("QuittierungsbelegsResultPartial", Model); } private void LoadPaginatedQbEntries(int selectedPage) { if(selectedPage < 1) { selectedPage = 1; } if(Model.SelectedFilterItem.FilterEnum == QBFilterEnum.KlientenAuswahl) { var customerOidString = Model.SelectedCustomerOid.ToString(); var isCustomerOidSuccessful = long.TryParse(customerOidString, out var selectedCustomerOid); if(isCustomerOidSuccessful) { var selectedCustomer = Model.Customers.FirstOrDefault(customer => customer.CustomerOid == selectedCustomerOid); Model.SelectedCustomer = selectedCustomer; } } else { Model.SelectedCustomer = null; Model.SelectedCustomerOid = null; } if(Model.SelectedFilterItem.FilterEnum == QBFilterEnum.TeamAuswahl) { var teamOidString = Model.SelectedTeamOid.ToString(); var isTeamOidSuccessful = long.TryParse(teamOidString, out var selectedTeamOid); if(isTeamOidSuccessful) { var selectedTeam = Model.AllTeams.FirstOrDefault(team => team.TeamOid == selectedTeamOid); Model.SelectedTeam = selectedTeam; } } else { Model.SelectedTeam = null; Model.SelectedTeamOid = null; } var reportTimeFrame = GetReportTimeFrame(); var reportObjects = new List(); var organisationOid = Model.SelectedOrganisationOid ?? 0; var employeeOid = Model.SelectedEmployeeOid ?? 0; var serviceCategoryOid = Model.SelectedServiceCategoryOid; var teamOid = Model.SelectedTeamOid; var customerOid = Model.SelectedCustomerOid ?? 0; var creator = PluginLoader.FindClass() ?? new DefaultReportCreator(); Model.CurrentQbEntryPage = selectedPage; var firstResult = (selectedPage - 1) * Model.MaxResults; var rowCount = 1; switch(Model.SelectedFilterItem.FilterEnum) { case QBFilterEnum.AlleKlienten: reportObjects = ServicesOverviewRO.CreatePaginated(firstResult, Model.MaxResults, reportTimeFrame.Month, reportTimeFrame.Year, organisationOid, employeeOid, reportTimeFrame.StartDay, reportTimeFrame.EndDay, out rowCount, serviceCategoryOid); break; case QBFilterEnum.NurKlientenMeinesTeams: var teamRelatedCustomerOids = creator.GetKlientenOidsMeinesTeams(null); var rOs = ServicesOverviewRO.CreatePaginated(firstResult, Model.MaxResults, teamRelatedCustomerOids.ToArray(), reportTimeFrame.Month, reportTimeFrame.Year, true, organisationOid, employeeOid, reportTimeFrame.StartDay, reportTimeFrame.EndDay, out rowCount, serviceCategoryOid); reportObjects.AddRange(rOs); break; case QBFilterEnum.MeineKlienten: var myRelatedCustomerOids = creator.GetMeineKlientenOids(); var myCustomersReportObject = ServicesOverviewRO.CreatePaginated(firstResult, Model.MaxResults, myRelatedCustomerOids.ToArray(), reportTimeFrame.Month, reportTimeFrame.Year, true, organisationOid, employeeOid, reportTimeFrame.StartDay, reportTimeFrame.EndDay, out rowCount, serviceCategoryOid); reportObjects.AddRange(myCustomersReportObject); break; case QBFilterEnum.KlientenAuswahl: reportObjects = new List { ServicesOverviewRO.Create(customerOid, reportTimeFrame.Month, reportTimeFrame.Year, false, organisationOid, employeeOid, reportTimeFrame.StartDay, reportTimeFrame.EndDay, serviceCategoryOid) }; break; case QBFilterEnum.TeamAuswahl: var customerOids = creator.GetKlientenOidsMeinesTeams(teamOid); var teamCustomersReportObjects = ServicesOverviewRO.CreatePaginated(firstResult, Model.MaxResults, customerOids.ToArray(), reportTimeFrame.Month, reportTimeFrame.Year, true, organisationOid, employeeOid, reportTimeFrame.StartDay, reportTimeFrame.EndDay, out rowCount, serviceCategoryOid); reportObjects.AddRange(teamCustomersReportObjects); break; default: reportObjects = ServicesOverviewRO.CreatePaginated(firstResult, Model.MaxResults, reportTimeFrame.Month, reportTimeFrame.Year, organisationOid, employeeOid, reportTimeFrame.StartDay, reportTimeFrame.EndDay, out rowCount, serviceCategoryOid); break; } var pageCount = Math.DivRem(rowCount, Model.MaxResults, out var remainder); if(remainder > 0) { pageCount++; } Model.QbEntryPageCount = pageCount; Model.QbEntryCount = rowCount; reportObjects = reportObjects.Where(x => x != null).ToList(); var srOids = new List(); reportObjects.DoForEach(x => x.Services.DoForEach(s => srOids.AddIfNotIn(s.ServiceRecordOid))); Model.ConfirmationReceiptSignatures = OperationsService.LoadAllConfirmationReceiptSignaturesByServiceRecordOids(srOids, out var serviceRecordOidsWithSignature); var customerSignatures = Model.ConfirmationReceiptSignatures.Where(crs => crs.SignatureType == SignatureType.Customer).ToList(); var employeeSignatures = Model.ConfirmationReceiptSignatures.Where(crs => crs.SignatureType == SignatureType.Employee).ToList(); Model.ReportServiceRecordOids = new List(); reportObjects.DoForEach(ro => ro.Services.DoForEach(s => { Model.ReportServiceRecordOids.AddIfNotIn(s.ServiceRecordOid); })); var hasEmployeeSignature = srOids.All(a => serviceRecordOidsWithSignature.ContainsValueAtKey(SignatureType.Employee, a)); var anyEmployeeSignatures = srOids.Any(a => serviceRecordOidsWithSignature.ContainsValueAtKey(SignatureType.Employee, a)); var employeeSignatureState = SignatureState.None; if(anyEmployeeSignatures) { employeeSignatureState = SignatureState.Some; } if(hasEmployeeSignature) { employeeSignatureState = SignatureState.All; } if(!Model.HasRightToProvideEmployeeSignatureForOthers) { // Prüfen, ob alle eigenen ServiceRecords unterschrieben sind var ownServiceRecordOids = new List(); reportObjects.DoForEach(reportObject => ownServiceRecordOids.AddRangeIfElementsNotIn(reportObject.Services.Where(serviceDetail => serviceDetail.EmployeeOid.Equals(LoggedInEmployee.EmployeeOid)).Select(serviceDetail => serviceDetail.ServiceRecordOid))); // Prüfen, ob Einträge von anderen Mitarbeitern existieren var serviceRecordOidsFromOtherEmployees = new List(); reportObjects.DoForEach(reportObject => serviceRecordOidsFromOtherEmployees.AddRangeIfElementsNotIn(reportObject.Services.Where(serviceDetail => !serviceDetail.EmployeeOid.Equals(LoggedInEmployee.EmployeeOid)).Select(serviceDetail => serviceDetail.ServiceRecordOid))); var areAllForeignEntriesSigned = serviceRecordOidsFromOtherEmployees.All(srOid => serviceRecordOidsWithSignature.ContainsValueAtKey(SignatureType.Employee, srOid)); var areAllOwnEntriesSigned = ownServiceRecordOids.All(srOid => serviceRecordOidsWithSignature.ContainsValueAtKey(SignatureType.Employee, srOid)); employeeSignatureState = !areAllForeignEntriesSigned && areAllOwnEntriesSigned ? SignatureState.AllOwnServiceRecords : employeeSignatureState; } Model.ConfirmationReceiptObject = null; Model.ConfirmationReceiptObject = new ConfirmationReceiptObject( BuildInformationString(), new List(), BuildInformationString(true), GetTimeSpanString(), hasEmployeeSignature, employeeSignatures.ToList(), employeeSignatureState); var confirmationReceiptResults = new List(); reportObjects.DoForEach(reportObject => { var quittierungsbelegItems = new List(); reportObject.Services.DoForEach(serviceDetail => { quittierungsbelegItems.Add(new QuittierungsbelegItem(serviceDetail)); }); if(quittierungsbelegItems.Count == 0) { return; } var oids = quittierungsbelegItems.Select(s => s.ServiceRecordOid).ToList(); var hasCustomerSignature = oids.All(a => serviceRecordOidsWithSignature.ContainsValueAtKey(SignatureType.Customer, a)); var employeeSignatureState2 = GetSignatureState(oids, serviceRecordOidsWithSignature, SignatureType.Employee); var customerSignatureState = GetSignatureState(oids, serviceRecordOidsWithSignature, SignatureType.Customer); var customerSignatureOid = hasCustomerSignature ? customerSignatures.FirstOrDefault(cs => cs.ServiceRecords.All(a => a.Customer.CustomerOid.Equals(reportObject.CustomerOid) && a.ServiceRecordOid.HasValue && serviceRecordOidsWithSignature[SignatureType.Customer].Contains(a.ServiceRecordOid.Value)))?.ConfirmationReceiptSignatureOid : null; var sigs = customerSignatures.Where(cs => cs.ServiceRecords.All(a => a.Customer.CustomerOid.Equals(reportObject.CustomerOid) && a.ServiceRecordOid.HasValue && serviceRecordOidsWithSignature[SignatureType.Customer].Contains(a.ServiceRecordOid.Value))).ToList(); var customerSignatureOids = sigs.Where(signature => signature.ConfirmationReceiptSignatureOid.HasValue).Select(signature => signature.ConfirmationReceiptSignatureOid.Value).ToList(); var employeeSignatureOids = new List(); if(serviceRecordOidsWithSignature.ContainsKey(SignatureType.Employee)) { foreach(var signature in employeeSignatures.Where(s => s.ConfirmationReceiptSignatureOid.HasValue)) { foreach(var serviceRecord in signature.ServiceRecords) { var oid = serviceRecord.ServiceRecordOid; if(oid.HasValue && oids.Contains(oid.Value)) { employeeSignatureOids.AddIfNotIn(signature.ConfirmationReceiptSignatureOid.Value); } } } } var customerSignatureServiceRecordOids = new List(); var employeeSignatureServiceRecordOids = new List(); if(serviceRecordOidsWithSignature.ContainsKey(SignatureType.Customer)) { customerSignatureServiceRecordOids = serviceRecordOidsWithSignature[SignatureType.Customer]; } if(serviceRecordOidsWithSignature.ContainsKey(SignatureType.Employee)) { employeeSignatureServiceRecordOids = serviceRecordOidsWithSignature[SignatureType.Employee]; } foreach(var quittierungsbelegItem in quittierungsbelegItems) { var serviceRecordOid = quittierungsbelegItem.ServiceRecordOid; quittierungsbelegItem.HasCustomerSignature = customerSignatureServiceRecordOids.Contains(serviceRecordOid); quittierungsbelegItem.HasEmployeeSignature = employeeSignatureServiceRecordOids.Contains(serviceRecordOid); } var employeeOids = new List(); foreach(var serviceDetail in reportObject.Services) { employeeOids.AddIfNotIn(serviceDetail.EmployeeOid); } if(!Model.HasRightToProvideEmployeeSignatureForOthers) { var serviceRecordOidsFromOtherEmployees = reportObject.Services.Where(serviceDetail => !serviceDetail.EmployeeOid.Equals(LoggedInEmployee.EmployeeOid)).Select(serviceDetail => serviceDetail.ServiceRecordOid).ToList(); var ownServiceRecordOids = reportObject.Services.Where(serviceDetail => serviceDetail.EmployeeOid.Equals(LoggedInEmployee.EmployeeOid)).Select(serviceDetail => serviceDetail.ServiceRecordOid).ToList(); var areAllForeignEntriesSigned = serviceRecordOidsFromOtherEmployees.All(srOid => serviceRecordOidsWithSignature.ContainsValueAtKey(SignatureType.Employee, srOid)); var areAllOwnEntriesSigned = ownServiceRecordOids.All(srOid => serviceRecordOidsWithSignature.ContainsValueAtKey(SignatureType.Employee, srOid)); employeeSignatureState2 = !areAllForeignEntriesSigned && areAllOwnEntriesSigned ? SignatureState.AllOwnServiceRecords : employeeSignatureState2; } confirmationReceiptResults.Add( item: new QuittierungsbelegResult ( $"{reportObject.CustomerLastName}, {reportObject.CustomerFirstName}", quittierungsbelegItems, reportObject.CustomerOid, hasCustomerSignature, customerSignatureOid, customerSignatureState, customerSignatureOids, employeeSignatureState2, employeeSignatureOids, employeeOids.Count ) ); }); Model.ConfirmationReceiptObject.ConfirmationReceiptResultList.AddRangeIfElementsNotIn(confirmationReceiptResults.OrderBy(o => o.CustomerName)); if(Model.ConfirmationReceiptObject.ConfirmationReceiptResultList.Any()) { Model.GoalRatingTypes = OperationsService.GetAllRatingTypes().OrderBy(o => o.Position).ToList(); } if(Model.ConfirmationReceiptObject.ConfirmationReceiptResultList.All(qbItem => qbItem.Items.Count == 0)) { TempData[TempDataConstants.HasWarningMessageKey] = true; } } [Authorize] public override string SaveCollapsibleStatus(bool isOpen, string identifier) { Model.Collapsibles2IsShown[identifier] = isOpen; return LeerzeichenFuerGetMethoden; } } public class ConfirmationReceiptSignatureObject { public Guid Identifier { get; } public string ImageStr { get; } public string InsTsStr { get; } public string PersonName { get; } public bool IsEmployeeSignature { get; } public int NumberOfServiceRecords { get; } public List ServiceRecords { get; } public ConfirmationReceiptSignatureObject(string imageStr, string insTsStr, string personName, bool isEmployeeSignature, List serviceRecords) { Identifier = Guid.NewGuid(); ImageStr = imageStr; InsTsStr = insTsStr; PersonName = personName; IsEmployeeSignature = isEmployeeSignature; NumberOfServiceRecords = serviceRecords.Count; ServiceRecords = serviceRecords; } } }