using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Web.Mvc; using BeWo.Report; using BeWo.Service.Plugins; using BeWo.View.Navigation.Filter; using BeWoPlanerMobil.Models; using BeWoPlanerMobil.Service; using BeWoPlanerMobil.Util; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using DevExpress.XtraEditors.Filtering.Templates; namespace BeWoPlanerMobil.Controllers { public class ReportViewerController : ReportBaseController { private ReportViewerModel _Model; public ReportViewerModel Model { get { if(!MobileSessionFacade.IsUserLoggedIn()) { RedirectToActionPermanent("Index", "Login"); return null; } if(((ReportViewerModel)Session[ModelSessionConstants.ReportViewerModelKey])?.Employee is null) { _Model = new ReportViewerModel { Employee = MobileSessionFacade.LoggedInEmployee, ReportCreator = GetReportCreator() }; Session[ModelSessionConstants.ReportViewerModelKey] = _Model; } else { _Model = (ReportViewerModel)Session[ModelSessionConstants.ReportViewerModelKey]; } return _Model; } } [Authorize] public ActionResult ReportViewer() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return Logout(); } Model.Report = null; var month = DateTime.Today.Month; var year = DateTime.Today.Year; var first = new DateTime(year, month, 1).AddMonths(-1); Model.SelectedYear = Model.SelectedYear ?? first.Year; Model.SelectedMonth = Model.SelectedMonth ?? first.Month; Model.AllEmployees = AbstractModel.HasRightMitarbeiterstundenkontoViewAll ? EmployeeService.GetAllActiveEmployeesCompact() : new List { MobileSessionFacade.LoggedInCompactEmployee }; // Alle Teams darf man nur sehen, wenn man das Recht "HasRightMitarbeiterstundenkontoViewAll" hat. // Hat man weder das Recht "HasRightMitarbeiterstundenkontoViewAll" noch "HasRightMitarbeiterstundenkontoViewTeams", sieht man die Teams gar nicht. // Hat man das Recht "HasRightMitarbeiterstundenkontoViewTeams", aber nicht das Recht "HasRightMitarbeiterstundenkontoViewAll", sieht man nur die Teams, deren Teamleiter man ist. Model.AllTeams = AbstractModel.HasRightMitarbeiterstundenkontoViewAll ? EmployeeService.GetAllActiveCompactTeamsForEmployee(MobileSessionFacade.LoggedInEmployee.EmployeeOid) : EmployeeService.FindLeadingCompactTeamsOfEmployee(MobileSessionFacade.LoggedInCompactEmployee.EmployeeOid); if(!AbstractModel.HasRightMitarbeiterstundenkontoViewAll) { Model.SelectedEmployeeOid = MobileSessionFacade.LoggedInCompactEmployee.EmployeeOid; } Model.ReportTypes = new List(); #if DEBUG if(AbstractModel.HasRightToViewReports) { Model.ReportTypes.Add(new SelectListItem { Text = "Berichte", Value = "0" }); Model.AllEmployeesForQueries = EmployeeService.GetAllActiveEmployeesCompact(); Model.AllCustomersForQueries = EmployeeService.GetActiveCompactCustomersForEmployee(null); Model.Queries = QueryService.GetAllQueriesOfType(QueryType.Public); var names2ValueListEntryTypes = new Dictionary(); foreach(var query in Model.Queries.Where(q => q.Parameter?.Any() ?? false)) { foreach(var parameter in query.Parameter.Where(p => p.ParamType == QueryParameterType.ValueListEntryType)) { var parameterName = parameter.Name; if(!(parameterName?.Contains("_") ?? false)) { continue; } var name2Type = parameterName.Split('_'); var name = name2Type[0]; var type = name2Type[1]; if(!int.TryParse(type, out var typeEnumInt)) { continue; } var valueListEntryType = (ValueListEntryType) typeEnumInt; names2ValueListEntryTypes.AddIfNotIn(new KeyValuePair(name, valueListEntryType)); } } Model.AllValueListEntriesForQuery = ValueListService.GetAllValueListEntrysByTypes(names2ValueListEntryTypes.Values.ToList()).ToList(); Model.AllValueListEntriesForQuery.DoForEach(valueListEntry => { Model.ValueListEntryTypes2ValueListEntries.AddOrUpdateValueInDictionary(valueListEntry.Type, valueListEntry); }); if(Model.Employee?.EmployeeOid.HasValue ?? false) { Model.SupportConcepts = EmployeeService.GetActiveSupportConceptsForEmployee(Model.Employee.EmployeeOid, CustomerFilterEnum.All); } else { Model.SupportConcepts = new List(); } Model.SupportConcepts.DoForEach(sc => Model.CostBearer2SupportConceptRels.AddRangeIfElementsNotIn(sc.CostBearerRelations)); if(Model.SelectedCostBearer2SupportConceptRelListObject is null) { Model.SelectedCostBearer2SupportConceptRelListObject = Model.CostBearer2SupportConceptRelListObjects.FirstOrDefault(f => f.CostBearer2SupportConceptOid == "-1") ?? Model.CostBearer2SupportConceptRelListObjects.First(); } Model.AllOrganisationForQuery = CustomerService.GetAllActiveOrganisationsCompact(); Model.AllTeamsForQueries = EmployeeService.GetAllActiveCompactTeamsForEmployee(null); Model.AllServiceCategoriesForQueries = OperationsService.GetAllServiceCategories(); } #endif if(AbstractModel.HasRightToViewMitarbeiterstundenkonto) { Model.ReportTypes.Add(new SelectListItem { Text = "Mitarbeiterstundenkonto", Value = "1" }); } #if !DEBUG Model.SelectedReportType = ReportType.Mitarbeiterstundenkonto; #endif #if DEBUG //Model.SelectedReportType = ReportType.Berichte; #endif return View(Model); } [Authorize] public ActionResult DocumentWebViewerPartial() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; } return PartialView("BeWoReportPartial", Model); } [Authorize] public ActionResult LoadCustomReport(long? reportOid) { try { if(Model?.Employee?.EmployeeOid is null || reportOid is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BeWoReportPartial"); } var selectedQuery = Model.Queries.FirstOrDefault(query => query.Oid.Equals(reportOid.Value)); if(selectedQuery is null) { Model.Report = null; return PartialView("BeWoReportPartial", Model); } Model.SelectedCustomReport = Model.CustomReports.FirstOrDefault(cr => cr.QueryOid == selectedQuery.Oid); Model.SelectedQuery = selectedQuery; var dcid = $"{MobileSessionFacade.Tenant}queryeoid{Model.Employee.EmployeeOid.Value}"; var queryResult = QueryService.ExecuteQuery(selectedQuery.Oid, null); if(queryResult is null) { return PartialView("BeWoReportPartial", Model); } QueryService.PrepareQueryReport(queryResult, dcid); var queryReport = Model.ReportCreator.CreateQueryReport(selectedQuery.Oid, dcid); Model.Report = queryReport; Model.ReportName = selectedQuery.Title; } catch(Exception e) { Log.Error(e); if(Model != null) { Model.ReportName = "Fehler"; } TempData[TempDataConstants.ReportErrorMessageKey] = e.Message; } return PartialView("BeWoReportPartial", Model); } [Authorize] public ActionResult LoadBerichteForm(long? reportOid) { try { if(Model?.Employee?.EmployeeOid is null || reportOid is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BerichteFormPartialView"); } var selectedQuery = Model.Queries.FirstOrDefault(query => query.Oid.Equals(reportOid.Value)); if(selectedQuery is null) { return PartialView("BerichteFormPartialView", Model); } Model.SelectedCustomReport = Model.CustomReports.FirstOrDefault(cr => cr.QueryOid == selectedQuery.Oid); Model.SelectedQuery = selectedQuery; foreach(var parameter in selectedQuery?.Parameter ?? new List()) { if(parameter.QueryParameterOid is null) { continue; } if(parameter.ParamType == QueryParameterType.Year) { Model.SelectedValues.AddOrUpdate(parameter.QueryParameterOid.Value, new SelectedValue(QueryParameterType.Year, DateTime.Today.Year)); } if(parameter.ParamType == QueryParameterType.Month) { Model.SelectedValues.AddOrUpdate(parameter.QueryParameterOid.Value, new SelectedValue(QueryParameterType.Month, DateTime.Today.AddMonths(-1))); } } return PartialView("BerichteFormPartialView", Model); } catch(Exception exception) { Log.Error(exception); TempData[TempDataConstants.ReportErrorMessageKey] = exception.Message; } return PartialView("BerichteFormPartialView", Model); } //[Authorize] //private string GetQueryReportUrl(QueryDC query) //{ // var url = Request?.Url; // if(Model?.Employee?.EmployeeOid is null || url is null || query is null) // { // return null; // } // //DEBUG: http://localhost:3777/service // //RELEASE: https://app4.bewoplaner.de/service // // http://localhost:3777/Host/ReportView.aspx?dcid=demoqueryeoid372&qoid=1304&type=QueryReport // var urlSuffix = $"/ReportView.aspx?dcid={MobileSessionFacade.Tenant}queryeoid{Model.Employee.EmployeeOid.Value}&qoid={query.Oid}&type={Utils.EnumName(ReportTypes.QueryReport)}"; // return GetSiteOfOrigin() + urlSuffix; //} private string GetSiteOfOrigin() { if(Model?.Employee?.EmployeeOid is null) { return null; } var url = Request?.Url; #if DEBUG return "http://localhost:3777/Host"; #endif return $"{url.Scheme}://{url.Host}/service"; } [Authorize] public ActionResult LoadViewerForm(string reportType) { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("ReportViewerFormPartial"); } Model.SelectedReportType = reportType == "0" ? ReportType.Berichte : ReportType.Mitarbeiterstundenkonto; return PartialView("ReportViewerFormPartial", Model); } [Authorize] public ActionResult LoadMitarbeiterstundenkonto(string parameters) { if(Model?.Employee?.EmployeeOid is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BeWoReportPartial"); } if(!string.IsNullOrWhiteSpace(parameters)) { var splitParameters = parameters.Split(';'); if(splitParameters.Length == 6) { var month = int.Parse(splitParameters[0]); var year = int.Parse(splitParameters[1]); var isEmployee = bool.Parse(splitParameters[2]); var all = bool.Parse(splitParameters[3]); long? employeeOid = null; List teamOids = null; long? oid = null; if(long.TryParse(splitParameters[4], out var oOid)) { oid = oOid; } var ansicht = int.Parse(splitParameters[5]); if(isEmployee) { employeeOid = oid; if(all || !AbstractModel.HasRightMitarbeiterstundenkontoViewAll) { employeeOid = null; } if(!(employeeOid is null)) { employeeOid = oid; } if(!AbstractModel.HasRightMitarbeiterstundenkontoViewAll) { employeeOid = Model.Employee.EmployeeOid; } } else { teamOids = new List(); var teamOid = oid; if(all || (!AbstractModel.HasRightMitarbeiterstundenkontoViewAll && !AbstractModel.HasRightMitarbeiterstundenkontoViewTeams)) { teamOid = null; } if(!(teamOid is null)) { teamOid = oid; } if(teamOid > 0 && !all) { teamOids.Add(teamOid.Value); } else if(all) { teamOids.AddRange(Model.AllTeams.Select(team => team.TeamOid)); } } var start = new DateTime(year, month, 1); var end = start.AddMonths(1); var report = Model.ReportCreator.CreateEmployeeHourReport(employeeOid, teamOids, start, end, ansicht); Model.Report = report; } } return PartialView("BeWoReportPartial", Model); } private static AbstractReportCreator GetReportCreator() { AbstractReportCreator creator = PluginLoader.FindClass() ?? new DefaultReportCreator(); var mobileBaseDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"..\Host\"); #if DEBUG creator.TempPath = BS.Shared.Core.Utils.CreateSavePath(mobileBaseDirectory, @"demo\temp"); #else creator.TempPath = BS.Shared.Core.Utils.CreateSavePath(mobileBaseDirectory, PluginLoader.Tenant + @"\temp"); #endif return creator; } [Authorize] public override string ResetReport() { if(Model is null) { TempData[TempDataConstants.DoLogoutKey] = true; return LeerzeichenFuerGetMethoden; } Model.Report = null; Model.ReportName = null; return LeerzeichenFuerGetMethoden; } // ToDo: Parameter hinzufügen [Authorize] public ActionResult CreateBerichtWithParameters() { if(Model?.SelectedQuery is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BeWoReportPartial"); } return PartialView("BeWoReportPartial", Model); } [Authorize] public ActionResult SelectCostBearer2SupportConceptRel(long? relOid) { if(Model?.SelectedQuery is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BerichteFormPartialView", Model); } if(relOid != null) { Model.SelectedCostBearer2SupportConceptRelListObject = Model.CostBearer2SupportConceptRelListObjects.FirstOrDefault(f => f.CostBearer2SupportConceptOid != null && f.CostBearer2SupportConceptOid.Equals(relOid.Value.ToString())); } return PartialView("BerichteFormPartialView", Model); } [Authorize] public ActionResult SelectQueryCustomValue(string customValue, long? paramOid) { if(Model?.SelectedQuery is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BerichteFormPartialView"); } return PartialView("BerichteFormPartialView", Model); } [Authorize] public ActionResult SelectValueListEntry(long? valueListEntryOid, int paramType, int index) { if(Model?.SelectedQuery is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BerichteFormPartialView"); } if(valueListEntryOid.HasValue) { var type = (QueryParameterType)paramType; var valueListEntry = Model.AllValueListEntriesForQuery.FirstOrDefault(vle => vle.ValueListEntryOid.HasValue && vle.ValueListEntryOid.Value.Equals(valueListEntryOid)); if(valueListEntry != null) { var selectedValue = new SelectedValue(type, valueListEntry); Model.SelectedValues.AddOrUpdate(index, selectedValue); } } return PartialView("BerichteFormPartialView", Model); } [Authorize] public ActionResult SelectQueryParameter(long? objectOid, int parameterType, long? parameterOid, string textValue) { if(Model?.SelectedQuery is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BerichteFormPartialView"); } if((objectOid.HasValue || textValue != null) && parameterOid.HasValue) { var queryParameterType = (QueryParameterType)parameterType; switch(queryParameterType) { case QueryParameterType.Custom: throw new NotImplementedException("Dieser Parametertyp wird noch nicht unterstützt!"); break; case QueryParameterType.Customer: if(objectOid is null || objectOid.Value.Equals(0)) { Model.SelectedValues.Remove(parameterOid.Value); break; } var selectedCustomer = Model.AllCustomersForQueries.FirstOrDefault(customer => customer.CustomerOid.Equals(objectOid.Value)); Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, selectedCustomer)); break; case QueryParameterType.Employee: if(objectOid is null || objectOid.Value.Equals(0)) { Model.SelectedValues.Remove(parameterOid.Value); break; } var selectedEmployee = Model.AllEmployeesForQueries.FirstOrDefault(employee => employee.EmployeeOid.Equals(objectOid.Value)); if(selectedEmployee != null) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, selectedEmployee)); } break; case QueryParameterType.Organisation: if(objectOid is null || objectOid.Value.Equals(0)) { Model.SelectedValues.Remove(parameterOid.Value); break; } var selectedOrganisation = Model.AllOrganisationForQuery.FirstOrDefault(organisation => organisation.OrganisationOid.Equals(objectOid.Value)); if(selectedOrganisation != null) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, selectedOrganisation)); } break; case QueryParameterType.Text: if(false == string.IsNullOrEmpty(textValue)) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, textValue)); } else { Model.SelectedValues.Remove(parameterOid.Value); } break; case QueryParameterType.Date: if(textValue != null && DateTime.TryParse(textValue, out var selectedDate)) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, selectedDate)); } else { Model.SelectedValues.Remove(parameterOid.Value); } break; case QueryParameterType.DateRange: if(textValue != null && textValue.Length == 21 &&textValue.Contains("_")) { var split = textValue.Split('_'); if(DateTime.TryParse(split[0], out var start) && DateTime.TryParse(split[1], out var end)) { var dateRange = new DateTimeSpan(start, end); Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, dateRange)); } } else { Model.SelectedValues.Remove(parameterOid.Value); } break; case QueryParameterType.Month: if(!textValue.Contains("_")) { break; } var month2Year = textValue.Split('_'); var monthAsString = month2Year[0]; var yearAsString = month2Year[1]; if(int.TryParse(monthAsString, out var month) && month > 0 && month < 13 && int.TryParse(yearAsString, out var year) && Model.Years.Any(listItem => listItem.Value.Equals(yearAsString))) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, new DateTime(year, month, 1))); } break; case QueryParameterType.ServiceCategory: if(objectOid is null || objectOid.Value.Equals(0)) { Model.SelectedValues.Remove(parameterOid.Value); break; } var selectedServiceCategory = Model.AllServiceCategoriesForQueries.FirstOrDefault(serviceCategory => serviceCategory.ServiceCategoryOid.HasValue && serviceCategory.ServiceCategoryOid.Value.Equals(objectOid)); if(selectedServiceCategory != null) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, selectedServiceCategory)); } break; case QueryParameterType.SupportConcept: var costBearer2SupportConceptRelListObj = Model.CostBearer2SupportConceptRelListObjects.FirstOrDefault(costBearer2SupportConceptRelListObject => costBearer2SupportConceptRelListObject.CostBearer2SupportConceptOid.Equals(objectOid.ToString())); Model.SelectedCostBearer2SupportConceptRelListObject = costBearer2SupportConceptRelListObj; if(objectOid is null || objectOid.Value.Equals(0)) { Model.SelectedValues.Remove(parameterOid.Value); break; } if(costBearer2SupportConceptRelListObj != null) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, costBearer2SupportConceptRelListObj)); } break; case QueryParameterType.Team: if(objectOid is null || objectOid.Value.Equals(0)) { Model.SelectedValues.Remove(parameterOid.Value); break; } var selectedTeam = Model.AllTeamsForQueries.FirstOrDefault(team => team.TeamOid.Equals(objectOid.Value)); if(selectedTeam != null) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, selectedTeam)); } break; case QueryParameterType.ValueListEntryType: if(objectOid is null || objectOid.Value.Equals(0)) { Model.SelectedValues.Remove(parameterOid.Value); break; } var selectedValueListEntry = Model.AllValueListEntriesForQuery.FirstOrDefault(valueListEntry => valueListEntry.ValueListEntryOid?.Equals(objectOid.Value) ?? false); if(selectedValueListEntry != null) { Model.SelectedValues.AddOrUpdate(parameterOid.Value, new SelectedValue(queryParameterType, selectedValueListEntry)); } break; case QueryParameterType.Year: break; } } return PartialView("BerichteFormPartialView", Model); } [Authorize] public ActionResult ExecuteQuery() { if(Model?.Employee?.EmployeeOid is null) { TempData[TempDataConstants.DoLogoutKey] = true; return PartialView("BeWoReportPartial"); } var query = Model.SelectedQuery; var paramList = new List(); foreach(var item in query.Parameter) { var param = new QueryParamDC(); paramList.Add(param); param.Name = item.Name; param.ParamType = item.ParamType; if(item.QueryParameterOid.HasValue && Model.SelectedValues.ContainsKey(item.QueryParameterOid.Value)) { param.Value = Model.SelectedValues[item.QueryParameterOid.Value].Parameter; } } var dcid = $"{MobileSessionFacade.Tenant}queryeoid{Model.Employee.EmployeeOid.Value}"; var queryResult = QueryService.ExecuteQuery(query.Oid, paramList); if(queryResult is null) { return PartialView("BeWoReportPartial", Model); } QueryService.PrepareQueryReport(queryResult, dcid); var queryReport = Model.ReportCreator.CreateQueryReport(query.Oid, dcid); Model.Report = queryReport; Model.ReportName = query.Title; return PartialView("BeWoReportPartial", Model); } } }