using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.IO; using System.Linq; using System.Text; using System.Web.Mvc; using System.Windows.Forms; using BeWo.Service.ServiceImplementations; using BeWoPlanerMobil.Models; using BeWoPlanerMobil.Service; using BeWoPlanerMobil.Util; using static BeWoPlanerMobil.Util.MobileUtils; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.Extensions; using BS.Shared.Services; using Newtonsoft.Json; using static BS.Shared.ServiceRecordValidationResult; using FormCollection = System.Web.Mvc.FormCollection; using ServiceRecordDC = BS.Shared.DataContracts.ServiceRecordDC; namespace BeWoPlanerMobil.Controllers { public class MainController : AbstractBaseController { private MainModel _Model; public MainModel Model { get { if(!MobileSessionFacade.IsUserLoggedIn()) { RedirectToActionPermanent("Index", "Login"); return null; } if(((MainModel) Session[MainModelSessionKey])?.Employee == null) { _Model = new MainModel { Employee = MobileSessionFacade.LoggedInEmployee }; Session[MainModelSessionKey] = _Model; } else { _Model = (MainModel) Session[MainModelSessionKey]; } return _Model; } } private const string MainModelSessionKey = "MainModel"; private Dictionary _ParentGoals; private static readonly List _Zieltypen = new List { ValueListEntryType.SupportConceptGoalCategoryType, ValueListEntryType.SupportConceptIndividualGoalCategoryType }; private static readonly List _Massnahmentypen = new List { ValueListEntryType.SupportConceptGoalType, ValueListEntryType.SupportConceptIndividualGoalType }; private MandatorDC GetMandator() { var mandator = (MandatorDC)HttpContext.Session["mandator"]; if(mandator == null) { mandator = OperationsService.GetMandator(); HttpContext.Session["mandator"] = mandator; } return mandator; } [Authorize] public ActionResult Main() { try { if(!MobileSessionFacade.IsUserLoggedIn() || Request.Browser.Browser.Equals("InternetExplorer") || !AbstractModel.HasRightToSeeServiceRecords) { var isNewSession = Session.IsNewSession; if(isNewSession) { TempData["ein_schluessel"] = "Sie wurden automatisch abgemeldet, da Ihre Session abgelaufen ist."; } return Logout(); } Model.ShowExpiredSupportConcepts = GetUserSettingValue("ShowExpiredSupportConcepts") == "1"; Model.ShowOnlyOwnSupportConcepts = GetUserSettingValue("ShowOnlyMySupportConcepts") == "1"; var mandator = GetMandator(); var supportConceptExpirationLimitInMonths = GetSettingValue(mandator.Settings, "HilfeplanAuslaufAuswahl"); var anzTageZeiterfassErfolgt = GetSettingValue(mandator.Settings, "AnzTageZeiterfassErfolgt"); var maxDaysEditServiceRecordsAllowed = GetSettingValue(mandator.Settings, "MaxDaysEditServiceRecordsAllowed"); BS.Shared.Settings.ApplicationSettings.SupportConceptExpirationLimitInMonths = supportConceptExpirationLimitInMonths == null ? 3 : int.Parse(supportConceptExpirationLimitInMonths); BS.Shared.Settings.ApplicationSettings.AnzTageZeiterfassErfolgt = anzTageZeiterfassErfolgt == null ? 0 : int.Parse(anzTageZeiterfassErfolgt); BS.Shared.Settings.ApplicationSettings.MaxDaysEditServiceRecordsAllowed = maxDaysEditServiceRecordsAllowed == null ? 0 : int.Parse(maxDaysEditServiceRecordsAllowed); var timeUntilUILock = GetSettingValue(mandator.Settings, "TimeUntilUILock"); BS.Shared.Settings.ApplicationSettings.TimeUntilUILock = timeUntilUILock == null ? 0 : int.Parse(timeUntilUILock); var unter = GetSettingValue(mandator.Settings, "ShowSignature"); Model.ShowSignature = unter == "1"; #if DEBUG Model.ShowSignature = true; #endif Model.GroupsOfPeople = EmployeeService.GetAllGroups(GetUser().Employee.EmployeeOid); if (!Model.IsInEditingMode) { Model.SelectedGoals.Clear(); } Model.ShowDistanceField = "1" == GetSettingValue(mandator.Settings, "ShowDistanceFields"); Model.Dokutypes = ValueListService.GetAllValueListEntrysByType(ValueListEntryType.DocumentType); if (Model.Dokutypes != null) { Model.Dokutypes = Model.Dokutypes.OrderBy(s => s.ValueListEntryOid).ToArray(); } if(MainModel.AllEmployees == null) { MainModel.AllEmployees = EmployeeService.GetAllActiveEmployeesCompact().OrderBy(e => e.LastName).ToList(); } var myRelatedCustomers = Model.Employee == null ? new List() : Model.Employee.RelatedCustomers; var relatedCustomerOids = myRelatedCustomers.Select(employee2customer => employee2customer.Customer.CustomerOid).ToList(); if (MobileSessionFacade.CheckForUserRight(UserRightType.ServiceRecord_AllowCreationForOtherEmployees)) { Model.Employees = EmployeeService.GetAllActiveEmployeesCompact(); } else if(MobileSessionFacade.CheckForUserRight(UserRightType.ServiceRecord_AllowCreationForOtherTeamMember) && Model.Employee?.EmployeeOid != null) { Model.Employees = EmployeeService.GetAllTeamMember(MobileSessionFacade.LoggedInCompactEmployee); } else { Model.Employees = new List { MobileSessionFacade.LoggedInCompactEmployee }; } if(Model.ShowOnlyOwnSupportConcepts == false && MobileSessionFacade.CheckForUserRight(UserRightType.SupportConcept_ViewAllSupportConcepts)) { Model.SupportConcepts = CustomerService.GetAllActiveSupportConcepts(); } else { Model.SupportConcepts = CustomerService.GetAllActiveSupportConceptsByCustomers(relatedCustomerOids); } if(!Model.ShowExpiredSupportConcepts) { Model.SupportConcepts = Model.SupportConcepts.Where(supportConcept => { var endDate = MainModel.GetEndDateOfSupportConcept(supportConcept); return endDate == null || endDate.Value >= DateTime.Now; }).ToList(); } if(Model.ServiceCategories == null) { Model.ServiceCategories = new List(); } if(Model.SelectedConceptCostBearerRelations == null) { Model.SelectedConceptCostBearerRelations = new List(); } if (Model.SelectedEmployee == null) { Model.SelectedEmployee = MobileSessionFacade.LoggedInCompactEmployee; } var isServiceRecordNoticeMandatorySetting = GetSettingValue(mandator.Settings, "IsServiceRecordNoticeMandatory"); if (isServiceRecordNoticeMandatorySetting != null && isServiceRecordNoticeMandatorySetting == "0") { Model.IsServiceRecordNoticeMandatory = false; } else { Model.IsServiceRecordNoticeMandatory = true; } var isInList = Model.SelectedSupportConceptListObject != null && Model.SupportConceptListObjects.Contains(Model.SelectedSupportConceptListObject); if(Model.SelectedSupportConceptListObject == null || !isInList) { Model.SelectedSupportConceptListObject = Model.SupportConceptListObjects.FirstOrDefault(f => f.CostBearer2SupportConceptOid == "-1") ?? Model.SupportConceptListObjects.First(); Model.CostBearer2SupportConceptOid = -1; } if(Model.CostBearer2SupportConceptOid != null) { LoadRecordsToModel(); } var endtime = GetSettingValue(mandator.Settings, "IsEndDateVisible"); Model.IsEndDateVisible = Equals(endtime, "1"); var isDurationMinHoursSwitchableSetting = GetSettingValue(mandator.Settings, "IsZeiterfassungInStdMin"); Model.IsZeiterfassungInStdMin = Equals(isDurationMinHoursSwitchableSetting, "1"); } catch (Exception e) { Log.Error(e.Message, e); } return View(Model); } [HttpPost] [Authorize] public ActionResult SetShowOnlyOwnSupportConcepts(FormCollection collection) { if (Model == null) { return RedirectToActionPermanent("Index", "Login"); } var newValue = "true,false" == collection["ShowOnlyOwnSupportConcepts"]; Model.ShowOnlyOwnSupportConcepts = newValue; return UpdateSettings("ShowOnlyMySupportConcepts", newValue ? "1" : "0"); ; } [HttpPost] [Authorize] public ActionResult SetShowExpiredSupportConcepts(FormCollection pCollection) { if (Model == null) { return RedirectToActionPermanent("Index", "Login"); } var newValue = "true,false" == pCollection["ShowExpiredSupportConcepts"]; Model.ShowExpiredSupportConcepts = newValue; return UpdateSettings("ShowExpiredSupportConcepts", newValue ? "1" : "0"); } [Authorize] public ActionResult UpdateSettings(string pKey, string pValue) { if (Model == null) { return RedirectToActionPermanent("Index", "Login"); } var userSettings = GetUser().Settings; UserSettingsUtils.SetSettingValue(SettingsType.ApplicationSettings, pKey, pValue, userSettings); UserService.UpdateUserSettings(GetUser().UserOid.Value, userSettings); return RedirectToAction("Main"); } [HttpPost] public new ActionResult Logout() { return base.Logout(); } [Authorize] public string LoadGoalTreeItems() { if (!Model.CostBearer2SupportConceptOid.HasValue || Model.CostBearer2SupportConceptOid.Value > 0 || Model.SelectedSupportConcept == null) { return null; } var goals = Model.SelectedSupportConcept.Goals; var missingParentElements = goals.Where(w => w.ParentOid.HasValue && !goals.Any(a => a.ValueListEntryOid.Equals(w.ParentOid))).Select(s => s.ParentOid).ToList(); _ParentGoals = new Dictionary(); foreach (var oid in missingParentElements) { LoadMissingParents(oid.Value); } goals.AddRangeIfElementsNotIn(_ParentGoals.Values); var ziele = goals.Where(w => _Zieltypen.Contains(w.Type)).OrderBy(s => s.TypeDescription).ToList(); var massnahmen = goals.Where(w => _Massnahmentypen.Contains(w.Type)).OrderBy(s => s.TypeDescription).ToList(); var parentItems = goals.Where(w => w.ValueListEntryOid.HasValue && goals.Any(a => a.ParentOid.HasValue && a.ParentOid.Equals(w.ValueListEntryOid))).ToList(); var goalTree = new List(); var goalTreeDic = new Dictionary(); foreach (var ziel in ziele.Where(ziel => ziel.ValueListEntryOid.HasValue)) { var treeItem = new BootstrapTreeViewItem(ziel.TypeDescription, ziel.ParentOid, ziel.ValueListEntryOid.Value, parentItems.Contains(ziel)); goalTreeDic.Add(ziel.ValueListEntryOid.Value, treeItem); if (ziel.ParentOid == null) { goalTree.Add(treeItem); } } foreach (var zielMitEltern in goalTreeDic.Values.Where(w => w.ParentOid != null)) { goalTreeDic[zielMitEltern.ParentOid.Value].Nodes.Add(zielMitEltern); } foreach (var ziel in massnahmen) { var node = new BootstrapTreeViewItem(ziel.TypeDescription, ziel.ParentOid, ziel.ValueListEntryOid.Value, parentItems.Contains(ziel)); if (ziel.ParentOid != null && goalTreeDic.ContainsKey(ziel.ParentOid.Value)) { node.ParentOid = goalTreeDic[ziel.ParentOid.Value].ParentOid; goalTreeDic[ziel.ParentOid.Value].Nodes.Add(node); } } return JsonConvert.SerializeObject(goalTree, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } [Authorize] public string LoadGoals() { if((!Model.CostBearer2SupportConceptOid.HasValue || Model.CostBearer2SupportConceptOid.Value > 0) && Model.SelectedSupportConcept == null) { RedirectToActionPermanent("Index", "Login"); return null; } var supportConcept = Model.SupportConcepts.FirstOrDefault(sc => sc.CostBearerRelations.Any(sc2Cb => sc2Cb.CostBearer2SupportConceptOid.HasValue && sc2Cb.CostBearer2SupportConceptOid.Value.Equals(Model.CostBearer2SupportConceptOid.Value))); if (supportConcept == null) { return null; } Model.SelectedSupportConcept = supportConcept; var selectedGoals = supportConcept.Goals; var missingParents = selectedGoals.Where(w => w.ParentOid != null && false == selectedGoals.Any(a => a.ValueListEntryOid.Equals(w.ParentOid))).Select(s => s.ParentOid).ToList(); _ParentGoals = new Dictionary(); foreach (var oid in missingParents) { LoadMissingParents(oid.Value); } var goalTree = BuildGoalTree(selectedGoals.Union(_ParentGoals.Values).ToList()); return SerializeObject(goalTree); } private static List BuildGoalTree(IReadOnlyCollection goals) { var ziele = goals.Where(w => _Zieltypen.Contains(w.Type)).OrderBy(s => s.TypeDescription).ToList(); var massnahmen = goals.Where(w => _Massnahmentypen.Contains(w.Type)).OrderBy(s => s.TypeDescription).ToList(); var goalTree = new List(); var goalTreeDic = new Dictionary(); foreach(var ziel in ziele) { var treeItem = new GoalTreeItem { Children = new List(), Header = ziel.TypeDescription, ParentOid = ziel.ParentOid, ValueListEntryOid = ziel.ValueListEntryOid }; goalTreeDic.Add(ziel.ValueListEntryOid.Value, treeItem); if(ziel.ParentOid == null) { goalTree.Add(treeItem); } } foreach(var zielMitEltern in goalTreeDic.Values.Where(w => w.ParentOid != null)) { goalTreeDic[zielMitEltern.ParentOid.Value].Children.Add(zielMitEltern); } foreach(var ziel in massnahmen) { var kind = new GoalTreeItem { Children = new List(), Header = ziel.TypeDescription, IsLeaf = true, ValueListEntryOid = ziel.ValueListEntryOid }; if(ziel.ParentOid != null && goalTreeDic.ContainsKey(ziel.ParentOid.Value)) { kind.ParentOid = goalTreeDic[ziel.ParentOid.Value].ParentOid; goalTreeDic[ziel.ParentOid.Value].Children.Add(kind); } } foreach(var item in goalTreeDic.Values) { if(item.Children.Count == 0) { item.IsLeaf = true; } } return goalTree; } private void LoadMissingParents(long pParentOid) { while(true) { var parentDC = ValueListService.GetValueListEntryByOid(pParentOid); if(!_ParentGoals.ContainsKey(parentDC.ValueListEntryOid.Value)) { _ParentGoals.Add(parentDC.ValueListEntryOid.Value, parentDC); if(parentDC.ParentOid != null) { pParentOid = parentDC.ParentOid.Value; continue; } } break; } } private static string GetUserSettingValue(string key) { var user = MobileSessionFacade.LoggedInUser; var settings = user?.SettingList.FirstOrDefault(f => f.Type.Equals(SettingsType.ApplicationSettings)); return settings != null ? MobileUtils.GetSettingValue(settings.Value, key) : null; } [Authorize] public string LoadStatistics(long oid) { try { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } var supportConceptStatistics = OperationsService.CreateSupportConceptStatistics(oid, DateTime.Now); if (supportConceptStatistics.PeriodStatistics != null && supportConceptStatistics.PeriodStatistics.Count == 1) { } return SerializeObject(supportConceptStatistics); } catch (Exception e) { Log.Error(e.Message, e); return SerializeObject("Fehler 560"); } } [Authorize] public string SaveUnterschrift(string blob, string timeStamp, long? serviceRecordOid) { try { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } using (var signatureBitmap = SignatureUtils.Base64StringToBitmap(blob.Split(',')[1])) { var isValid = SignatureUtils.ValidateSignature(signatureBitmap); if(!isValid) { return SerializeObject("Das Unterschriftenfeld darf nicht leer sein."); } var date = DateTime.Parse(timeStamp); OperationsService.InsertSignature(new SignatureDC { DataBild = blob, Zeitstempel = date, ServiceRecordOid = serviceRecordOid }); } return _LeerzeichenFuerGetMethoden; } catch (Exception e) { Log.Error(e.Message, e); return SerializeObject("Fehler 540"); } } private void ApplyWatermark() { if (Model == null || string.IsNullOrWhiteSpace(Model.SignatureImage)) { return; } var watermarkImage = Image.FromFile(Server.MapPath("../Content/images/bewoplaner_logo_big.png")); var signatureImage = SignatureUtils.Base64StringToBitmap(Model.SignatureImage); var hasTransparentBackground = SignatureUtils.HasTransparentBackground(Model.SignatureImage); if (hasTransparentBackground) { signatureImage = SignatureUtils.AddBackgroundToBitmap(signatureImage, Color.White); } var watermarker = new Watermarker(signatureImage); for(var y = 0; y < signatureImage.Height; y++) { for (var x = 0; x < signatureImage.Width; x++) { watermarker.Position = WatermarkPosition.Absolute; watermarker.PositionX = x; watermarker.PositionY = y; watermarker.Margin = new Padding(20); watermarker.Opacity = .1f; watermarker.TransparentColor = Color.White; watermarker.DrawImage(watermarkImage); x += watermarkImage.Width; } y += watermarkImage.Height; } Model.SignatureImage = "data:image/png;base64," + SignatureUtils.ConvertImageToBase64String(watermarker.Image); } [Authorize] public string LoadServiceCategories(long pServiceCategoryOid) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } try { var scm = Model?.ServiceCategories.FirstOrDefault(s => s.ServiceCategoryOid.Value == pServiceCategoryOid); if (scm != null) { Model.SelectedServiceCategoryOid = scm.ServiceCategoryOid; } return SerializeObject(scm != null ? scm.ServiceDescriptions.OrderBy(serviceDescription => serviceDescription.Position).ToList() : new List()); } catch(Exception exception) { Debug.WriteLine(exception); throw; } } [Authorize] public string LoadTextbausteineForServiceCategory(long pServiceCategoryOid) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } try { if (!MobileSessionFacade.CheckForUserRight(UserRightType.TextbausteineNurEigeneAnsehen) && !MobileSessionFacade.CheckForUserRight(UserRightType.TextbausteineAlleAnsehen)) { return _LeerzeichenFuerGetMethoden; } var textbausteine = OperationsService.GetAllTextModules(); foreach (var tm in textbausteine) { if (tm.Text == null) { tm.Text = string.Empty; } } if(!MobileSessionFacade.CheckForUserRight(UserRightType.TextbausteineAlleAnsehen)) { textbausteine = textbausteine.Where(w => w.Employee.EmployeeOid == Model.Employee.EmployeeOid && w.IsOnlyForEmployee).ToList(); } Model.Textbausteine = textbausteine.Where(w => w.ServiceCategory == null || w.ServiceCategory.ServiceCategoryOid == pServiceCategoryOid).ToList(); Model.Textbausteine.AddRangeIfElementsNotIn(Utils.GetParentTextModules(Model.Textbausteine)); var displayItems = Model.Textbausteine.Select(s => new TextbausteinDisplayItem(s.Name, new List {s.TextModuleOid.Value.ToString()}, s.Parent?.TextModuleOid, s.TextModuleOid.Value, s.IsParent)).ToList(); foreach(var item in displayItems) { if(item.ParentOid != null) { var parent = displayItems.FirstOrDefault(f => f.Oid == item.ParentOid); if (parent != null) { if (parent.nodes == null) { parent.nodes = new List(); } parent.nodes.AddIfNotIn(item); } } } displayItems = displayItems.Where(w => w.ParentOid == null).ToList(); return JsonConvert.SerializeObject(displayItems, Formatting.None, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } catch(Exception exception) { Debug.WriteLine(exception); throw; } } [Authorize] public string LoadCompleteTextbausteinByOid(long pTextbausteinOid) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } var textModule = Model.Textbausteine.FirstOrDefault(f => f.TextModuleOid.HasValue && f.TextModuleOid.Value == pTextbausteinOid); return textModule == null ? null : string.IsNullOrWhiteSpace(textModule.Text) ? textModule.Name : textModule.Text; } [HttpPost] [Authorize] public ActionResult CreateServiceRecord(FormCollection collection) { try { if(Model == null) { return RedirectToActionPermanent("Index", "Login"); } if (string.IsNullOrEmpty(collection["Datum"]) || Model.NewServiceRecord == null) { return View("Main", Model); } string doku1; var distanceInMeters = 0; var dauer = 0; var serviceDescOid = 0L; if(Model.Dokutypes != null && Model.Dokutypes.Length > 0) { doku1 = collection["Dokumentation1"]; } else { doku1 = collection["Dokumentation6"]; } var doku2 = collection["Dokumentation2"]; var doku3 = collection["Dokumentation3"]; var doku4 = collection["Dokumentation4"]; var doku5 = collection["Dokumentation5"]; var distanz = collection["Distanz"]; var start = collection["Start"]; var ende = collection["Ende"]; var endDateString = collection["Enddatum"]; var selectedCostbearerScRelOid = Model.CostBearer2SupportConceptOid < 1 ? null : Model.CostBearer2SupportConceptOid; var datum = Convert.ToDateTime(collection["Datum"]); if(!string.IsNullOrEmpty(distanz)) { if(int.TryParse(distanz, out var parsedDistance)) { distanceInMeters = parsedDistance; } } Log.Info($"CreateServiceRecord: datum:{collection["Datum"]}; start:{collection["Start"]}; ende:{collection["Ende"]}; dauer:{collection["Dauer"]}; doku:{doku1}; aktion:{collection["versteckt"]}"); var enddatum = datum; if(endDateString != null) { enddatum = Convert.ToDateTime(endDateString); } if(datum > enddatum) { enddatum = datum; } if(!string.IsNullOrEmpty(collection["Dauer"])) { int.TryParse(collection["Dauer"], out dauer); } var zeitenFeld = new DateTime[2]; if(start == string.Empty && ende == string.Empty) { zeitenFeld[0] = new DateTime(datum.Year, datum.Month, datum.Day, 0, 0, 1); if(enddatum == datum) { zeitenFeld[1] = new DateTime(datum.Year, datum.Month, datum.Day, 0, 0, 1).AddMinutes(dauer); } else { zeitenFeld[1] = new DateTime(enddatum.Year, enddatum.Month, enddatum.Day, 0, 0, 1).AddMinutes(dauer); } } else { zeitenFeld = enddatum == datum ? ConvertRecordTimes(start, ende, datum, dauer) : ConvertRecordTimesWithEndDate(start, ende, datum, enddatum, dauer); } if(dauer == 0 || zeitenFeld[1] != zeitenFeld[0]) { dauer = (int) (zeitenFeld[1] - zeitenFeld[0]).TotalMinutes; } Model.NewServiceRecord.IP = Request.UserHostAddress; Model.NewServiceRecord.Goals = Model.SelectedGoals; Model.NewServiceRecord.Start = zeitenFeld[0]; Model.NewServiceRecord.End = zeitenFeld[1]; Model.NewServiceRecord.DistanceInMeter = distanceInMeters; if(Model.Employee.EmployeeOid != null) { Model.NewServiceRecord.Employee = Model.SelectedEmployee ?? MobileSessionFacade.LoggedInCompactEmployee; var sc = Model.SupportConcepts.FirstOrDefault(fod => fod.CostBearerRelations.Any(a => a.CostBearer2SupportConceptOid.HasValue && a.CostBearer2SupportConceptOid.Value.Equals(selectedCostbearerScRelOid))); if(sc != null) { if(sc.SupportConceptOid != null) { Model.NewServiceRecord.SupportConcept = CustomerService.LoadCompactSupportConceptDC(sc.SupportConceptOid.Value, Model.Employee.EmployeeOid); } Model.NewServiceRecord.Customer = sc.Customer; var cb2ScRel = sc.CostBearerRelations.First(f => f.CostBearer2SupportConceptOid.HasValue && f.CostBearer2SupportConceptOid.Equals(selectedCostbearerScRelOid)); Model.NewServiceRecord.CostBearer = cb2ScRel.CostBearer; var intervall = Model.NewServiceRecord.CostBearer.ActualMinuteIntervall; if(intervall > 0) { Model.NewServiceRecord.RoundedDuration = dauer % intervall != 0 ? dauer + (intervall - dauer % intervall) : dauer; } else { Model.NewServiceRecord.RoundedDuration = dauer; } Model.NewServiceRecord.CostBearer2SupportConceptOid = selectedCostbearerScRelOid; } else { Model.NewServiceRecord.RoundedDuration = dauer; } } Model.NewServiceRecord.DurationInStunden = ZeiterfassungsDauer.Minuten; Model.NewServiceRecord.ServiceRecordFormat = ServiceRecordFormate.OriginaleZeiterfassung; Model.NewServiceRecord.Notice = string.IsNullOrEmpty(doku1) ? null : doku1; Model.NewServiceRecord.Notice2 = string.IsNullOrEmpty(doku2) ? null : doku2; Model.NewServiceRecord.Notice3 = string.IsNullOrEmpty(doku3) ? null : doku3; Model.NewServiceRecord.Notice4 = string.IsNullOrEmpty(doku4) ? null : doku4; Model.NewServiceRecord.Notice5 = string.IsNullOrEmpty(doku5) ? null : doku5; if(!string.IsNullOrEmpty(collection["ServiceDescription"])) { serviceDescOid = Convert.ToInt64(collection["ServiceDescription"]); } else if(Model.SelectedServiceDescriptionOid.HasValue) { serviceDescOid = Model.SelectedServiceDescriptionOid.Value; } if (serviceDescOid > 0) { Model.NewServiceRecord.ServiceDescription = OperationsService.GetServiceDescription(serviceDescOid); } if (Model.NewServiceRecord.RoundedDuration == 0) { Model.NewServiceRecord.RoundedDuration = dauer; } Model.NewServiceRecord.IP = Request.UserHostAddress; Model.NewServiceRecord.InsertedOn = DateTime.Now; Model.NewServiceRecord.InsUser = $"{MobileSessionFacade.LoggedInEmployee.FirstName} {MobileSessionFacade.LoggedInEmployee.LastName}"; Model.NewServiceRecord.IsCreatedInMobileClient = true; Model.NewServiceRecord.Goals = Model.SelectedGoals; var oidList = OperationsService.InsertNewServiceRecords(new List { Model.NewServiceRecord }); Model.ServiceRecordOid = oidList[0]; Model.NewServiceRecord = new ServiceRecordDC(); if(selectedCostbearerScRelOid.HasValue) { Model.ServiceRecords = OperationsService.FindServiceRecordsForLastDays(selectedCostbearerScRelOid, Model.Zeitraum, Model.Employee.EmployeeOid).ToList(); } } catch (Exception e) { Log.Error(e.Message, e); } Model.SaveSignature = Model.ShowSignature && Model.SelectedSupportConcept != null; return RedirectToActionPermanent("Main"); } [HttpPost] [Authorize] public ActionResult CreateOrUpdateServiceRecord(FormCollection collection) { try { if(Model == null) { return RedirectToActionPermanent("Index", "Login"); } string doku1; if(Model.Dokutypes != null && Model.Dokutypes.Length > 1) { doku1 = collection["Dokumentation1"]; } else { doku1 = collection["Dokumentation6"]; } Log.Info($"CreateServiceRecord: datum:{collection["Datum"]}; start:{collection["Start"]}; ende:{collection["Ende"]}; dauer:{collection["Dauer"]}; doku:{doku1}; aktion:{(Model.IsInEditingMode ? "Speichern" : "Anlegen")}"); if(string.IsNullOrEmpty(collection["Datum"])) { return View("Main", Model); } var distanz = collection["Distanz"]; var distanceInMeters = 0; if(!string.IsNullOrEmpty(distanz)) { if(int.TryParse(distanz, out var parsedDistance)) { distanceInMeters = parsedDistance; } } var selectedCostbearerSCRelOid = Model.CostBearer2SupportConceptOid < 1 ? null : Model.CostBearer2SupportConceptOid; var datum = Convert.ToDateTime(collection["Datum"]); var enddatum = datum; var start = collection["Start"]; var ende = collection["Ende"]; var dauer = 0; if(datum > enddatum) { enddatum = datum; } if(!string.IsNullOrEmpty(collection["Dauer"])) { int.TryParse(collection["Dauer"], out dauer); } var doku2 = collection["Dokumentation2"]; var doku3 = collection["Dokumentation3"]; var doku4 = collection["Dokumentation4"]; var doku5 = collection["Dokumentation5"]; var zeitenFeld = new DateTime[2]; if(start == string.Empty && ende == string.Empty) { zeitenFeld[0] = new DateTime(datum.Year, datum.Month, datum.Day, 0, 0, 1); if(enddatum == datum) { zeitenFeld[1] = new DateTime(datum.Year, datum.Month, datum.Day, 0, 0, 1).AddMinutes(dauer); } else { zeitenFeld[1] = new DateTime(enddatum.Year, enddatum.Month, enddatum.Day, 0, 0, 1).AddMinutes(dauer); } } else { zeitenFeld = enddatum == datum ? ConvertRecordTimes(start, ende, datum, dauer) : ConvertRecordTimesWithEndDate(start, ende, datum, enddatum, dauer); } if(dauer == 0 || zeitenFeld[1] != zeitenFeld[0]) { dauer = (int)(zeitenFeld[1] - zeitenFeld[0]).TotalMinutes; } if(Model.IsInEditingMode) { var selectedRecordOid = Model.SelectedServiceRecordOid ?? Model.SelectedServiceRecord.ServiceRecordOid; Model.NewServiceRecord = OperationsService.GetServiceRecordById(selectedRecordOid.Value); } if(Model.NewServiceRecord == null) { return RedirectToActionPermanent("Main"); } Model.NewServiceRecord.IP = Request.UserHostAddress; Model.NewServiceRecord.Goals = Model.SelectedGoals; Model.NewServiceRecord.Start = zeitenFeld[0]; Model.NewServiceRecord.End = zeitenFeld[1]; Model.NewServiceRecord.DistanceInMeter = distanceInMeters; if(Model.Employee.EmployeeOid != null) { if(!Model.IsInEditingMode) { Model.NewServiceRecord.Employee = Model.SelectedEmployee ?? MobileSessionFacade.LoggedInCompactEmployee; } else { if(Model.SelectedEmployee != null) { Model.NewServiceRecord.Employee = Model.SelectedEmployee; } } var sc = Model.SupportConcepts.FirstOrDefault(fod => fod.CostBearerRelations.Any(a => a.CostBearer2SupportConceptOid.HasValue && a.CostBearer2SupportConceptOid.Value.Equals(selectedCostbearerSCRelOid))); if(sc != null) { if(sc.SupportConceptOid != null) { Model.NewServiceRecord.SupportConcept = CustomerService.LoadCompactSupportConceptDC(sc.SupportConceptOid.Value, Model.Employee.EmployeeOid); } Model.NewServiceRecord.Customer = sc.Customer; var cb2ScRel = sc.CostBearerRelations.First(f => f.CostBearer2SupportConceptOid.HasValue && f.CostBearer2SupportConceptOid.Equals(selectedCostbearerSCRelOid)); Model.NewServiceRecord.CostBearer = cb2ScRel.CostBearer; var intervall = Model.NewServiceRecord.CostBearer.ActualMinuteIntervall; if(intervall > 0) { Model.NewServiceRecord.RoundedDuration = dauer % intervall != 0 ? dauer + (intervall - dauer % intervall) : dauer; } else { Model.NewServiceRecord.RoundedDuration = dauer; } Model.NewServiceRecord.CostBearer2SupportConceptOid = selectedCostbearerSCRelOid; } else { Model.NewServiceRecord.RoundedDuration = dauer; } } Model.NewServiceRecord.DurationInStunden = ZeiterfassungsDauer.Minuten; Model.NewServiceRecord.ServiceRecordFormat = ServiceRecordFormate.OriginaleZeiterfassung; Model.NewServiceRecord.Notice = string.IsNullOrEmpty(doku1) ? null : doku1; Model.NewServiceRecord.Notice2 = string.IsNullOrEmpty(doku2) ? null : doku2; Model.NewServiceRecord.Notice3 = string.IsNullOrEmpty(doku3) ? null : doku3; Model.NewServiceRecord.Notice4 = string.IsNullOrEmpty(doku4) ? null : doku4; Model.NewServiceRecord.Notice5 = string.IsNullOrEmpty(doku5) ? null : doku5; var serviceDescOid = 0L; if(!string.IsNullOrEmpty(collection["ServiceDescription"])) { serviceDescOid = Convert.ToInt64(collection["ServiceDescription"]); } else if(Model.SelectedServiceDescriptionOid.HasValue) { serviceDescOid = Model.SelectedServiceDescriptionOid.Value; } if(serviceDescOid > 0) { Model.NewServiceRecord.ServiceDescription = OperationsService.GetServiceDescription(serviceDescOid); } if(Model.NewServiceRecord.RoundedDuration == 0) { Model.NewServiceRecord.RoundedDuration = dauer; } Model.NewServiceRecord.IP = Request.UserHostAddress; Model.NewServiceRecord.InsertedOn = DateTime.Now; Model.NewServiceRecord.InsUser = $"{MobileSessionFacade.LoggedInEmployee.FirstName} {MobileSessionFacade.LoggedInEmployee.LastName}"; Model.NewServiceRecord.IsCreatedInMobileClient = true; if(Model.IsInGroupBookingMode && Model.SelectedSupportConcepts.Count > 1) { return Model.NewServiceRecord.ServiceRecordOid.HasValue ? SaveGroupBooking() : UpdateGroupBooking(); } if(!Model.IsInEditingMode) { var oidList = OperationsService.InsertNewServiceRecords(new List { Model.NewServiceRecord }); Model.ServiceRecordOid = oidList[0]; } else { OperationsService.UpdateServiceRecords(new List { Model.NewServiceRecord }); } Model.NewServiceRecord = new ServiceRecordDC(); if(selectedCostbearerSCRelOid.HasValue) { Model.ServiceRecords = OperationsService.FindServiceRecordsForLastDays(selectedCostbearerSCRelOid, Model.Zeitraum, Model.Employee.EmployeeOid).ToList(); } } catch (Exception e) { Log.Error(e.Message, e); } return ResetEditingMode(null); } private ActionResult SaveGroupBooking() { var employeeCount = Model.SelectedEmployees.Count; var personCount = Model.SelectedSupportConcepts.Count; var cb2ScOids = (from scDc in Model.SelectedSupportConcepts where scDc.CostBearerRelations != null && scDc.CostBearerRelations.Count > 0 let costBearer2SupportConceptOid = scDc.CostBearerRelations[0].CostBearer2SupportConceptOid where costBearer2SupportConceptOid != null select costBearer2SupportConceptOid.Value).ToList(); var list = CalculateGroupBookingDuration(employeeCount, personCount, cb2ScOids); var newDCList = new List(); foreach(var dc in list) { foreach(var emp in Model.SelectedEmployees) { var newDC = CloneServiceRecordForGroupBooking(dc); newDC.Employee = emp; newDC.InsertedOn = DateTime.Now; newDCList.Add(newDC); } } if(newDCList.Count > 0) { if(newDCList.Count == 1) { OperationsService.InsertNewServiceRecords(newDCList); } else { var groupDC = new ServiceRecordGroupDC { EmployeeCount = employeeCount, CustomerCount = personCount, StartDate = Model.NewServiceRecord.Start, EndDate = Model.NewServiceRecord.End, Notice = Model.NewServiceRecord.Notice, Notice2 = Model.NewServiceRecord.Notice2, Notice3 = Model.NewServiceRecord.Notice3, Notice4 = Model.NewServiceRecord.Notice4, Notice5 = Model.NewServiceRecord.Notice5, ServiceRecordList = newDCList }; if(Model.NewServiceRecord.GroupRoundedDuration != null) { groupDC.RoundedDuration = Model.NewServiceRecord.GroupRoundedDuration.Value; } OperationsService.InsertNewServiceRecordGroup(groupDC); } } return ResetEditingMode(null); } private ActionResult UpdateGroupBooking() { var dc = Model.SelectedServiceRecord; var group = OperationsService.GetServiceRecordGroup(dc.GroupOid.Value); UpdateServiceRecordGroup(group); var employeeCount = Model.SelectedEmployees.Count; var customerCount = Model.SelectedSupportConcepts.Count; group.EmployeeCount = employeeCount; group.CustomerCount = customerCount; var roundDuration = true; var minuteInterval = 0; CompactOrganisationDC org = null; var cb2ScOids = new List(); foreach(var scdc in Model.SelectedSupportConcepts) { if(scdc.CostBearerRelations.Count > 0) { cb2ScOids.Add(scdc.CostBearerRelations.ElementAt(0).CostBearer2SupportConceptOid.Value); if(org == null) { org = scdc.CostBearerRelations.ElementAt(0).CostBearer; if(org != null) { minuteInterval = org.ActualMinuteIntervall; } } else { if(scdc.CostBearerRelations.ElementAt(0).CostBearer == null || !org.Equals(scdc.CostBearerRelations.ElementAt(0).CostBearer)) { roundDuration = false; } } } } var duration = (decimal) (Model.NewServiceRecord.End.Value - Model.NewServiceRecord.Start.Value).TotalMinutes; var lRoundedDuration = duration; decimal groupDuration; decimal roundedDuration; var gd = OperationsService.CalculateGroupDuration2(customerCount, employeeCount, duration, cb2ScOids.ToArray()); if(gd != null) { groupDuration = gd.TotalDuration; roundedDuration = gd.SingleDuration; } else { if(minuteInterval > 0 && roundDuration) { lRoundedDuration = duration % minuteInterval != 0 ? duration + (minuteInterval - duration % minuteInterval) : duration; } groupDuration = lRoundedDuration; roundedDuration = Math.Round(groupDuration / Model.SelectedSupportConcepts.Count, 0 , MidpointRounding.AwayFromZero); } Model.NewServiceRecord.RoundedDuration = roundedDuration; Model.NewServiceRecord.GroupRoundedDuration = groupDuration; group.Notice = Model.NewServiceRecord.Notice; group.Notice2 = Model.NewServiceRecord.Notice2; group.Notice3 = Model.NewServiceRecord.Notice3; group.Notice4 = Model.NewServiceRecord.Notice4; group.Notice5 = Model.NewServiceRecord.Notice5; group.RoundedDuration = groupDuration; group.StartDate = Model.NewServiceRecord.Start; group.EndDate = Model.NewServiceRecord.End; foreach(var item in group.ServiceRecordList) { item.Notice = Model.NewServiceRecord.Notice; item.Notice2 = Model.NewServiceRecord.Notice2; item.Notice3 = Model.NewServiceRecord.Notice3; item.Notice4 = Model.NewServiceRecord.Notice4; item.Notice5 = Model.NewServiceRecord.Notice5; item.End = Model.NewServiceRecord.End; item.Start = Model.NewServiceRecord.Start; item.RoundedDuration = roundedDuration; item.DistanceInMeter = Model.NewServiceRecord.DistanceInMeter; item.ServiceDescription = Model.NewServiceRecord.ServiceDescription; item.ServiceRecordFormat = Model.NewServiceRecord.ServiceRecordFormat; item.DurationInStunden = Model.NewServiceRecord.DurationInStunden; item.ServiceDescription = item.ServiceDescription ?? Model.NewServiceRecord.ServiceDescription; item.GroupEmployeeCount = group.EmployeeCount; item.GroupPersonCount = group.CustomerCount; item.GroupOid = Model.NewServiceRecord.GroupOid; item.GroupRoundedDuration = groupDuration; if(item.CostBearer != null && item.CostBearer.CostBearerOid == null && item.SupportConcept != null && item.SupportConcept.CostBearerList.Count > 0) { item.CostBearer.CostBearerOid = item.SupportConcept.CostBearerList[0].CostBearerOid; } } if(Model.NewServiceRecord.GroupOid.HasValue) { OperationsService.UpdateServiceRecordGroup(group); } Model.NewServiceRecord = null; Model.SelectedServiceRecord = null; Model.SelectedSupportConcepts = new List(); Model.SelectedEmployees = new List(); ResetGroupBookingMode(false); Model.IsInEditingMode = false; return ResetEditingMode(null); } private IEnumerable CalculateGroupBookingDuration(int pEmployeeCount, int pCustomerCount, ICollection cb2ScOids) { var compactSupportConcepts = CustomerServiceImp.GetCompactSupportConcepts((from sc in Model.SelectedSupportConcepts where sc.SupportConceptOid != null select sc.SupportConceptOid.Value).ToList(), GetUser().Employee.EmployeeOid); var nodes = (from supportConcept in Model.SelectedSupportConcepts let cb = supportConcept.CostBearerRelations.FirstOrDefault(f => cb2ScOids.Contains(f.CostBearer2SupportConceptOid.Value)) let sc = compactSupportConcepts.FirstOrDefault(f => f.SupportConceptOid == supportConcept.SupportConceptOid) where cb != null && sc != null select SupportConceptService.CreateFlatSupportConceptItem(sc, CustomerService.LoadOrganisationCompact(cb.CostBearer.OrganisationOid))).ToList(); var list = new List(); foreach(var node in nodes) { var sc = CloneServiceRecordForGroupBooking(Model.NewServiceRecord); if(Model.NewServiceRecord.RoundedDuration == 0) { if(Model.NewServiceRecord.Start.HasValue && Model.NewServiceRecord.End.HasValue) { var minutes = Model.NewServiceRecord.End.Value.Subtract(Model.NewServiceRecord.Start.Value).TotalMinutes; Model.NewServiceRecord.RoundedDuration = (decimal)minutes; } } sc.GroupRoundedDuration = Model.NewServiceRecord.RoundedDuration; sc.CostBearer2SupportConceptOid = node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid; sc.SupportConcept = node.SupportConceptTreeNodeDC.SupportConcept; sc.CostBearer = node.SupportConceptTreeNodeDC.CostBearer; sc.Customer = node.SupportConceptTreeNodeDC.Customer; sc.GroupEmployeeCount = pEmployeeCount; sc.GroupPersonCount = pCustomerCount; list.Add(sc); } var roundDuration = false; var minuteInterval = 0; string calcdId = null; var lastMinuteInterval = -1; if(Model.SelectedServiceDescriptionOid.HasValue && IsBillable(Model.SelectedServiceDescriptionOid.Value, Model.GetServiceDesctiptions())) { roundDuration = true; foreach(var org in from dc in Model.SelectedSupportConcepts where dc.CostBearerRelations.Count > 0 select dc.CostBearerRelations.First().CostBearer) { if(org != null) { minuteInterval = org.ActualMinuteIntervall; if(lastMinuteInterval == -1) { lastMinuteInterval = minuteInterval; calcdId = org.CostBearerID; } else if(lastMinuteInterval != minuteInterval) { roundDuration = false; } } else if(minuteInterval >= 0) { roundDuration = false; } else { minuteInterval = 0; } } } var duration = Model.NewServiceRecord.RoundedDuration; var totalDuration = duration; var groupDuration = OperationsService.CalculateGroupDuration2(pCustomerCount, pEmployeeCount, Model.NewServiceRecord.RoundedDuration, nodes.Select(s => s.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid.Value).ToArray()); if(groupDuration != null) { Model.NewServiceRecord.GroupRoundedDuration = groupDuration.TotalDuration; Model.NewServiceRecord.RoundedDuration = groupDuration.SingleDuration; } else { if(minuteInterval > 0 && roundDuration) { var calc = Calculations.GetInstance(calcdId); totalDuration = calc.GetRoundedDuration(minuteInterval, duration); } Model.NewServiceRecord.RoundedDuration = Math.Round(totalDuration / pCustomerCount, 0, MidpointRounding.AwayFromZero); Model.NewServiceRecord.GroupRoundedDuration = totalDuration; } return list; } private void UpdateServiceRecordGroup(ServiceRecordGroupDC pGroupDC) { var newCount = 0; foreach(var serviceRecord in pGroupDC.ServiceRecordList) { if(!serviceRecord.ServiceRecordOid.HasValue) { newCount++; } } if(newCount == pGroupDC.ServiceRecordList.Count) { return; } var dcsToChange = new List(); var oldSCs = new Dictionary(); var oldEmps = new Dictionary(); var newKeys = new Dictionary(); foreach(var sc in Model.SelectedSupportConcepts) { foreach(var emp in Model.SelectedEmployees) { var key = emp.EmployeeOid + "_" + sc.SupportConceptOid; if(sc.CostBearerRelations != null && sc.CostBearerRelations.Count > 0) { var costBearer2SupportConceptOid = sc.CostBearerRelations.ElementAt(0).CostBearer2SupportConceptOid; if(costBearer2SupportConceptOid != null) { key += "_" + costBearer2SupportConceptOid.Value; } newKeys.Add(key, key); } } } foreach(var item in pGroupDC.ServiceRecordList) { var key = item.Employee.EmployeeOid + "_" + item.SupportConcept.SupportConceptOid; if(item.CostBearer2SupportConceptOid.HasValue) { key += "_" + item.CostBearer2SupportConceptOid.Value; } if(newKeys.ContainsKey(key)) { newKeys.Remove(key); } else { dcsToChange.Add(item); } if(!oldEmps.ContainsKey(item.Employee.EmployeeOid)) { oldEmps.Add(item.Employee.EmployeeOid, item.Employee); } if(!oldSCs.ContainsKey(item.SupportConcept.SupportConceptOid)) { oldSCs.Add(item.SupportConcept.SupportConceptOid, item.SupportConcept); } } if(newKeys.Count != 0 || dcsToChange.Count != 0) { if(newKeys.Count > 0) { foreach(var sc in Model.SelectedSupportConcepts) { foreach(var emp in Model.SelectedEmployees) { var key = emp.EmployeeOid + "_" + sc.SupportConceptOid; if(sc.CostBearerRelations != null && sc.CostBearerRelations.Count > 0) { key += "_" + sc.CostBearerRelations.ElementAt(0).CostBearer2SupportConceptOid; } if(!newKeys.ContainsKey(key)) { continue; } ServiceRecordDC newServiceRecord; if(dcsToChange.Count > 0) { newServiceRecord = dcsToChange[0]; dcsToChange.Remove(newServiceRecord); } else { newServiceRecord = CloneServiceRecordForGroupBooking(Model.NewServiceRecord); pGroupDC.ServiceRecordList.Add(newServiceRecord); } newServiceRecord.Employee = emp; newServiceRecord.SupportConcept = CustomerService.LoadCompactSupportConceptDC(sc.SupportConceptOid.Value, null); newServiceRecord.CostBearer = sc.CostBearerRelations.ElementAt(0).CostBearer; newServiceRecord.Customer = sc.Customer; newServiceRecord.CostBearer2SupportConceptOid = sc.CostBearerRelations.ElementAt(0).CostBearer2SupportConceptOid; } } } foreach(var item in dcsToChange) { pGroupDC.ServiceRecordList.Remove(item); } } } [HttpPost] [Authorize] public ActionResult SelectSupportConcept(FormCollection formCollection) { if(Model == null) { return RedirectToActionPermanent("Index", "Login"); } long? cb2ScOid = Convert.ToInt64(formCollection["CostBearer2SupportConceptOid"]); LoadServiceCategoriesToModel(cb2ScOid); Model.Zeitraum = 7; LoadRecordsToModel(); LoadGoalTreeItems(); return ResetEditingMode(null); } private void LoadServiceCategoriesToModel(long? cb2ScOid) { if(cb2ScOid == null && Model.IsInGroupBookingMode) { Model.ServiceCategories = CreateServiceCategoryModels(OperationsService.GetAllServiceDescriptions()); return; } Model.CostBearer2SupportConceptOid = cb2ScOid; Model.SelectedSupportConcept = Model.SupportConcepts.FirstOrDefault( f => f.CostBearerRelations.Any( a => a.CostBearer2SupportConceptOid.HasValue && a.CostBearer2SupportConceptOid.Value.Equals(Model.CostBearer2SupportConceptOid))); if(Model.SelectedSupportConcept != null) { Model.SelectedSupportConceptListObject = Model.SupportConceptListObjects.First(f => long.Parse(f.CostBearer2SupportConceptOid) == cb2ScOid); var details = OperationsService.GetSupportConceptTreeNodeDetailInfo(Model.SelectedSupportConcept.Customer.CustomerOid, Model.SelectedSupportConcept.SupportConceptOid, Model.CostBearer2SupportConceptOid); Model.ServiceCategories = details.ServiceAccountings.Count > 0 ? CreateServiceCategoryModels(details.ServiceAccountings.Select(sa => sa.ServiceDescription).ToList()) : CreateServiceCategoryModels(OperationsService.GetAllServiceDescriptions()); Model.ServiceCategories = Model.ServiceCategories.Where(c => !c.OhneHilfeplan.HasValue || c.OhneHilfeplan.Value == AccountingvisibilityType.Beides || c.OhneHilfeplan.Value == AccountingvisibilityType.NurKlientenbezogen).ToList(); } else if(cb2ScOid == -2) { Model.SelectedSupportConceptListObject = Model.SupportConceptListObjects.First(f => f.CostBearer2SupportConceptOid.Equals(cb2ScOid.ToString())); Model.ServiceCategories = CreateServiceCategoryModels(OperationsService.GetAllServiceDescriptions()); Model.ServiceCategories = Model.ServiceCategories.Where(c => !c.OhneHilfeplan.HasValue || c.OhneHilfeplan.Value == AccountingvisibilityType.Beides || c.OhneHilfeplan.Value == AccountingvisibilityType.NichtKlientenbezogen).ToList(); } else if(cb2ScOid == -1) { Model.SelectedSupportConceptListObject = Model.SupportConceptListObjects.First(f => f.CostBearer2SupportConceptOid.Equals(cb2ScOid.ToString())); Model.ServiceCategories.Clear(); } if(Model.ServiceCategories != null) { Model.ServiceCategories = Model.ServiceCategories.OrderBy(serviceCategory => serviceCategory.Position).ToList(); } } [HttpPost] [Authorize] public ActionResult DeleteServiceRecord(FormCollection formCollection) { if (Model == null) { return RedirectToActionPermanent("Index", "Login"); } Model.ServiceRecordOidToDelete = long.Parse(formCollection["serviceRecordOidHolder"]); if (Model.ServiceRecordOidToDelete != null && Model.ServiceRecordOidToDelete > 0 && MobileSessionFacade.LoggedInUser.UserGroups.Any(a => a.Rights.Any(f => f.RightType.Equals(UserRightType.ServiceRecordView_Delete)))) { var serviceRecordDC = Model.ServiceRecords.FirstOrDefault(f => f.ServiceRecordOid != null && f.ServiceRecordOid.Value.Equals(Model.ServiceRecordOidToDelete)); var version = serviceRecordDC?.ServiceRecordVersion; if (version != null) { OperationsService.DeleteServiceRecord(Model.ServiceRecordOidToDelete.Value, version.Value); Model.ServiceRecords = Model.ServiceRecords.Where(sr => sr.ServiceRecordOid != null && !sr.ServiceRecordOid.Value.Equals(serviceRecordDC.ServiceRecordOid)).ToList(); } } ResetGroupBookingMode(false); return RedirectToActionPermanent("Main"); } public string UpdateGoals(string pGoalOids) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } var sc = Model.SelectedSupportConcept; if (sc == null) { return _LeerzeichenFuerGetMethoden; } if(string.IsNullOrEmpty(pGoalOids)) { Model.SelectedGoals.Clear(); return _LeerzeichenFuerGetMethoden; } var splitOids = pGoalOids.Trim(';').Split(';'); var selectedGoalOids = splitOids.Select(long.Parse).ToList(); var goals = sc.Goals.Where(w => w.ValueListEntryOid.HasValue && selectedGoalOids.Contains(w.ValueListEntryOid.Value)).ToList(); Model.SelectedGoals = goals; return _LeerzeichenFuerGetMethoden; } public string SetServiceDescription(long pServiceDescriptionOid) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } Model.SelectedServiceDescriptionOid = pServiceDescriptionOid; return _LeerzeichenFuerGetMethoden; } [HttpPost] [Authorize] public ActionResult LoadServiceRecords(FormCollection formCollection) { if (Model == null) { return RedirectToActionPermanent("Index", "Login"); } var zeitraum = int.Parse(formCollection["Records"]); if (zeitraum < 0) { zeitraum = 7; } Model.Zeitraum = zeitraum; LoadRecordsToModel(); return RedirectToActionPermanent("Main"); } private void LoadRecordsToModel() { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return; } if (Model.Zeitraum < 0 || Model.CostBearer2SupportConceptOid.HasValue && Model.CostBearer2SupportConceptOid.Value == -1) { Model.ServiceRecords = new List(); return; } var records = OperationsService.FindServiceRecordsForLastDays(Model.CostBearer2SupportConceptOid < 1 ? null : Model.CostBearer2SupportConceptOid, Model.Zeitraum, Model.Employee.EmployeeOid); var recordsOhneDuplikate = new List(); foreach(var r in records.Where(r => !recordsOhneDuplikate.Any(a => a.GroupOid.HasValue && a.GroupOid.Value.Equals(r.GroupOid)))) { recordsOhneDuplikate.Add(r); } Model.ServiceRecords = recordsOhneDuplikate.Where(serviceRecord => serviceRecord.Start.HasValue && serviceRecord.End.HasValue) .OrderBy(serviceRecord => serviceRecord.Start.Value.Date) .ThenBy(serviceRecord => serviceRecord.Start.Value.Hour) .ThenBy(serviceRecord => serviceRecord.Start.Value.Minute) .ThenBy(serviceRecord => serviceRecord.End.Value.Date) .ThenBy(serviceRecord => serviceRecord.End.Value.Hour) .ThenBy(serviceRecord => serviceRecord.End.Value.Minute).ToList(); } [HttpPost] [Authorize] public ActionResult SelectRecordToEdit(FormCollection formCollection) { if(Model == null) { return RedirectToActionPermanent("Index", "Login"); } var oidString = formCollection["service-record-oid-holder"]; var wasSuccessful = long.TryParse(oidString, out var serviceRecordOid); if (!wasSuccessful) { RedirectToActionPermanent("Main"); } Model.SelectedServiceRecordOid = serviceRecordOid; var selectedServiceRecord = OperationsService.GetServiceRecordById(serviceRecordOid); Model.SelectedServiceRecord = selectedServiceRecord; Model.SelectedGoals = selectedServiceRecord.Goals; Model.SelectedServiceDescriptionOid = selectedServiceRecord.ServiceDescription.ServiceDescriptionOid; Model.SelectedServiceCategoryOid = selectedServiceRecord.ServiceDescription.Category.ServiceCategoryOid; Model.SelectedEmployee = selectedServiceRecord.Employee; Model.IsInEditingMode = true; if (selectedServiceRecord.GroupOid.HasValue) { Model.IsInGroupBookingMode = true; Model.SelectedSupportConcept = null; Model.SelectedEmployee = null; Model.ServiceCategories = CreateServiceCategoryModels(OperationsService.GetAllServiceDescriptions()); var group = OperationsService.GetServiceRecordGroup(selectedServiceRecord.GroupOid.Value); Model.SelectedEmployees.AddRangeIfElementsNotIn(group.ServiceRecordList.Select(serviceRecord => serviceRecord.Employee).ToList()); var cb2ScOids = group.ServiceRecordList.Where(w => w.CostBearer2SupportConceptOid.HasValue).Select(s => s.CostBearer2SupportConceptOid.Value).ToList(); Model.SelectedConceptCostBearerRelations.AddRangeIfElementsNotIn(OperationsService.GetSupportConceptCostBearerRelDCsByOids(cb2ScOids)); } return RedirectToActionPermanent("Main"); } public string GetSelectedRecordInformation() { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } var result = _LeerzeichenFuerGetMethoden; if (Model.SelectedServiceRecordOid.HasValue) { result = SerializeObject(Model.ServiceRecords.First(f => f.ServiceRecordOid == Model.SelectedServiceRecordOid)); } return result; } public string GetSelectedRecordInformationWithOid(long oid) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } LoadRecordsToModel(); return SerializeObject(Model.ServiceRecords.First(f => f.ServiceRecordOid == oid)); } [Authorize] public string CheckRights(string von, string bis, bool inEditMode, string dateString, string startString, string endString) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } Log.Info($"CheckRights: von:{von};bis:{bis};inEditMode:{inEditMode};dateString:{dateString};startString:{startString};endString:{endString}"); var startHoursDt = ConvertTimeStringToDateTime(startString); var endHoursDt = ConvertTimeStringToDateTime(endString); if (!DateTime.TryParse(dateString, out var date)) { date = DateTime.Now.Date; } var startDt = date.AddHours(startHoursDt.Hour).AddMinutes(startHoursDt.Minute); var endDt = date.AddHours(endHoursDt.Hour).AddMinutes(endHoursDt.Minute); if (startDt > endDt) { return "StartGreaterEnd"; } var dauer = (int)(endDt - startDt).TotalMinutes; if (dauer == 0) { startDt = startDt.AddSeconds(1); endDt = endDt.AddSeconds(1); } var checkServiceRecord = new ServiceRecordDC(); if (inEditMode) { checkServiceRecord = Model.ServiceRecords.FirstOrDefault(f => f.ServiceRecordOid.HasValue && f.ServiceRecordOid.Value.Equals(Model.SelectedServiceRecordOid)); } if (checkServiceRecord == null) { checkServiceRecord = new ServiceRecordDC(); } checkServiceRecord.Goals = Model.SelectedGoals; checkServiceRecord.Start = startDt; checkServiceRecord.End = endDt; checkServiceRecord.IP = Request.UserHostAddress; checkServiceRecord.ServiceDescription = OperationsService.GetServiceDescription(Model.SelectedServiceDescriptionOid.Value); checkServiceRecord.Employee = Model.SelectedEmployee ?? MobileSessionFacade.LoggedInCompactEmployee; if (Model.SelectedEmployee != null && !Model.IsInGroupBookingMode) { var sc = Model.SupportConcepts.FirstOrDefault(fod => fod.CostBearerRelations.Any(a => a.CostBearer2SupportConceptOid.HasValue && a.CostBearer2SupportConceptOid.Value.Equals(Model.CostBearer2SupportConceptOid))); if (sc != null) { if (sc.SupportConceptOid != null) { checkServiceRecord.SupportConcept = CustomerService.LoadCompactSupportConceptDC(sc.SupportConceptOid.Value, Model.Employee.EmployeeOid); } checkServiceRecord.Customer = sc.Customer; var cb2ScRel = sc.CostBearerRelations.First(f => f.CostBearer2SupportConceptOid.HasValue && f.CostBearer2SupportConceptOid.Equals(Model.CostBearer2SupportConceptOid)); checkServiceRecord.CostBearer = cb2ScRel.CostBearer; var intervall = checkServiceRecord.CostBearer.ActualMinuteIntervall; if (intervall > 0) { checkServiceRecord.RoundedDuration = dauer % intervall != 0 ? dauer + (intervall - dauer % intervall) : dauer; } checkServiceRecord.CostBearer2SupportConceptOid = Model.CostBearer2SupportConceptOid; } } var mandator = GetMandator(); var maxDaysEditSRsAllowedString = GetSettingValue(mandator.Settings, "MaxDaysEditServiceRecordsAllowed"); var limitFuerZeiterfassungString = GetSettingValue(mandator.Settings, "AnzTageZeiterfassErfolgt"); var isSuccessful1 = int.TryParse(maxDaysEditSRsAllowedString, out var maxDaysEditSRsAllowed); if (!isSuccessful1) { maxDaysEditSRsAllowed = 0; } var isSuccessful2 = int.TryParse(limitFuerZeiterfassungString, out var limitFuerZeiterfassung); if(!isSuccessful2) { limitFuerZeiterfassung = 0; } if (MobileSessionFacade.CheckForUserRight(UserRightType.ServiceRecord_AllowEditAfterMaxDaysInNextMonth)) { maxDaysEditSRsAllowed = -1; } SupportConceptStatisticsDC stats = null; if (Model.CostBearer2SupportConceptOid != null && Model.CostBearer2SupportConceptOid > 0) { stats = OperationsService.CreateSupportConceptStatistics(Model.CostBearer2SupportConceptOid.Value, DateTime.Now); } var employees = new List {checkServiceRecord.Employee.EmployeeOid}; var validationResults = new List(); checkServiceRecord.ServiceRecordFormat = ServiceRecordFormate.OriginaleZeiterfassung; checkServiceRecord.DurationInStunden = ZeiterfassungsDauer.Minuten; string dateRangeString = null; if(Model.IsInGroupBookingMode) { if (checkServiceRecord.GroupOid.HasValue) { var serviceRecordGroup = OperationsService.GetServiceRecordGroup(checkServiceRecord.GroupOid.Value); serviceRecordGroup.ServiceRecordList.DoForEach(sr => employees.AddIfNotIn(sr.Employee.EmployeeOid)); } else { Model.SelectedEmployees.DoForEach(e => employees.AddIfNotIn(e.EmployeeOid)); } var cb2ScOids = (from scDc in Model.SelectedSupportConcepts where scDc.CostBearerRelations != null && scDc.CostBearerRelations.Count > 0 select scDc.CostBearerRelations[0].CostBearer2SupportConceptOid.Value).ToList(); var relations = CustomerService.GetSupportConceptCostBearerRelationsById(cb2ScOids); foreach (var rel in relations) { var sr = CloneServiceRecordForGroupBooking(checkServiceRecord); sr.SupportConcept = rel.SupportConcept; sr.CostBearer = rel.CostBearer; sr.CostBearer2SupportConceptOid = rel.CostBearer2SupportConceptOid; var result = OperationsService.ValidateServiceRecord(sr, null, maxDaysEditSRsAllowed, employees, cb2ScOids); dateRangeString = rel.DateRangeString; validationResults.Add(new ServiceRecord2Validation(sr, result, dateRangeString)); } } else { if (Model.SelectedSupportConcept != null) { var node = CreateFlatSupportConceptItem(CustomerService.LoadCompactSupportConceptDC(Model.SelectedSupportConcept.SupportConceptOid.Value, Model.SelectedEmployee.EmployeeOid), null); dateRangeString = node?.SupportConceptTreeNodeDC != null ? node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.DateRangeString : ""; } var result = OperationsService.ValidateServiceRecordEntry(checkServiceRecord, stats, maxDaysEditSRsAllowed, checkServiceRecord.GroupOid.HasValue, employees); validationResults.Add(new ServiceRecord2Validation(checkServiceRecord, result, dateRangeString ?? "")); } var allowOverlappingFLS = MobileSessionFacade.CheckForUserRight(UserRightType.ServiceRecord_AllowCreateOverlappingFLS); var allowOverlappingFLSForEmployee = MobileSessionFacade.CheckForUserRight(UserRightType.ServiceRecord_AllowCreateOverlappingFLSForEmployee); var allowMoreFLSThanApproved = MobileSessionFacade.CheckForUserRight(UserRightType.ServiceRecord_AllowCreateMoreFLSThanApproved); var bookAfterSettlementInvoice = MobileSessionFacade.CheckForUserRight(UserRightType.BookServiceRecordAfterSettlementInvoice); var bookServiceRecordOutOfSupportConcept = MobileSessionFacade.CheckForUserRight(UserRightType.BookServiceRecordOutOfSupportConcept); var newResult = new ValidationResult(); var exitLoop = false; foreach (var sr2V in validationResults) { if(exitLoop) { break; } foreach (var vr in sr2V.ValidationResults) { if (exitLoop) { break; } switch(vr.ResultType) { case ServiceRecordOverlapping: newResult.Message += "An dem gewählten Datum '" + von + "' existiert bereits ein Eintrag (" + vr.Message + " bei Klient/in " + vr.CustomerName + ").

"; newResult.KannTrotzdemGespeichertWerden = allowOverlappingFLS; exitLoop = !allowOverlappingFLS; break; case EmployeeOverlapping: newResult.Message += "An dem gewählten Datum " + von + " existiert bereits ein Eintrag von " + vr.EmployeeName + " (" + vr.Message + ").

"; newResult.KannTrotzdemGespeichertWerden = allowOverlappingFLSForEmployee; exitLoop = !allowOverlappingFLSForEmployee; break; case OutsideOfSupportConcept: newResult.Message += "Das gewählte Datum " + von.Substring(0, 10) + " liegt außerhalb des Zeitraumes des gewählten Hilfeplans (" + sr2V.HilfePlanZeitraum + ").

"; newResult.KannTrotzdemGespeichertWerden = bookServiceRecordOutOfSupportConcept; exitLoop = !bookServiceRecordOutOfSupportConcept; break; case ApprovedFLSOverspending: var klient = "diesen Hilfeplan"; if (!string.IsNullOrEmpty(vr.CustomerName)) { klient = "Klient/in " + vr.CustomerName; } var msg = "Die für " + klient + " genehmigten FLS (" + vr.ApprovedHours + ") werden mit diesem Eintrag überschritten. (" + vr.HoursNew + ")."; newResult.Message += msg + "

"; newResult.KannTrotzdemGespeichertWerden = allowMoreFLSThanApproved; exitLoop = !allowMoreFLSThanApproved; break; case OutOfEditLimit: newResult.Message += "Sie können keine neuen Leistungen für den " + von + " dokumentieren, da bereits der " + maxDaysEditSRsAllowed + ". des nachfolgenden Monats überschritten ist.

"; exitLoop = true; newResult.KannTrotzdemGespeichertWerden = false; break; case Error: newResult.Message += "Beim Speichern ist ein Fehler aufgetreten.

"; exitLoop = true; newResult.KannTrotzdemGespeichertWerden = false; break; case SettlementInvoiceAlreadyExisting: var klient2 = "diesen Hilfeplan"; if(!string.IsNullOrEmpty(vr.CustomerName)) { klient2 = "Klient/in " + vr.CustomerName; } newResult.KannTrotzdemGespeichertWerden = bookAfterSettlementInvoice; exitLoop = !bookAfterSettlementInvoice; if (bookAfterSettlementInvoice) { newResult.Message += "Es existiert bereits eine Spitzabrechnung für " + klient2 + ". Um diesen Eintrag zu berücksichtigen, muss eventuell eine neue Spitzabrechnung erstellt werden.

"; } else { newResult.Message += "Sie können den Eintrag nicht bearbeiten, da bereits eine Spitzabrechnung für " + klient2 + "

"; } break; case FristAbgelaufen: var intervall = "einem Tag"; if (limitFuerZeiterfassung != 1) { intervall = "" + limitFuerZeiterfassung + " Tagen"; } newResult.Message += "Sie können keine neuen Leistungen für den " + von + " dokumentieren, da die Zeiterfassung innerhalb von " + intervall + " erfolgen muss.

"; exitLoop = true; newResult.KannTrotzdemGespeichertWerden = false; break; case Custom: newResult.Message += vr.Message + "

"; exitLoop = true; newResult.KannTrotzdemGespeichertWerden = false; break; } } } if (!string.IsNullOrEmpty(newResult.Message)) { newResult.Message += newResult.KannTrotzdemGespeichertWerden ? "
Möchten Sie trotzdem speichern?

" : "
Speichern nicht möglich.

"; } Model.NewServiceRecord = new ServiceRecordDC(); return SerializeObject(newResult); } public string SetServiceRecordEmployee(long employeeOid) { try { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } Model.SelectedEmployee = MainModel.AllEmployees.First(f => f.EmployeeOid.Equals(employeeOid)); return _LeerzeichenFuerGetMethoden; } catch (Exception e) { Log.Info("Error in SetServiceRecordEmployee:"); Log.Error(e.Message, e); if (MainModel.AllEmployees == null) { Log.Info("Weitere Infos: AllEmployees = null!"); } else { Log.Info($"Weitere Infos: AllEmployees enthält {MainModel.AllEmployees.Count} Elemente: "); var stringBuilder = new StringBuilder(); foreach (var ce in MainModel.AllEmployees) { if (stringBuilder.Length > 0) { stringBuilder.Append(","); } stringBuilder.Append(ce.EmployeeOid); } Log.Info(stringBuilder.ToString()); } throw e; } } public string CheckToken(string token) { if(token != null && token.Equals("abcd")) { return SerializeObject("localhost;demo"); } return _LeerzeichenFuerGetMethoden; } // Menünavigation public ActionResult RedirectToScheduler() { return RedirectToActionPermanent("Scheduler", "Scheduler"); } public ActionResult RedirectToCustomer() { if(Model?.SelectedSupportConcept?.Customer?.Oid.HasValue ?? false) { return RedirectToActionPermanent("PreselectCustomer", "Customer", new {Model.SelectedSupportConcept.Customer.CustomerOid}); } if(Model?.SelectedSupportConcept == null && (CustomerModel)Session[CustomerController.CustomerModelModelSessionKey] != null) { var customerModel = (CustomerModel) Session[CustomerController.CustomerModelModelSessionKey]; customerModel.SelectedCustomerOid = null; customerModel.SelectedCustomer = null; } return RedirectToActionPermanent("Customer", "Customer"); } public ActionResult RedirectToMain() { return RedirectToActionPermanent("Main", "Main"); } // Gruppenbuchungen [HttpPost] [Authorize] public ActionResult SetGroupBookingMode(FormCollection pFormCollection) { if (Model == null) { return RedirectToActionPermanent("Index", "Login"); } var isInGroupBookingMode = "true,false" == pFormCollection["IsInGroupBookingMode"]; ResetGroupBookingMode(isInGroupBookingMode); return RedirectToAction("Main"); } /// /// Setzt die getroffenen Auswahlen zurück /// /// /// Wenn true, wird davon ausgegangen, dass man von der Einzelbuchung in eine Gruppenbuchung wechselt und es wird sich der vorher ausgewählte Mitarbeiter und Hilfeplan gemerkt. /// Bei false wird davon ausgegangen, dass man von der Gruppenbuchung in eine Einzelbuchung wechselt und der vorher ausgewählte Mitarbeiter und Hilfeplan wird automatisch ausgewählt. private void ResetGroupBookingMode(bool pIsInGroupBookingMode) { if (Model == null) { RedirectToActionPermanent("Index", "Login"); return; } Model.IsInGroupBookingMode = pIsInGroupBookingMode; if (pIsInGroupBookingMode) { Model.PreviouslySelectedEmployee = Model.SelectedEmployee; Model.PreviouslySelectedSupportConcept = Model.SelectedSupportConcept; Model.SelectedSupportConcept = null; Model.SelectedEmployee = null; Model.ServiceCategories = CreateServiceCategoryModels(OperationsService.GetAllServiceDescriptions()); Model.SelectedEmployees.Add(MobileSessionFacade.LoggedInCompactEmployee); Model.IsInEditingMode = false; Model.SelectedServiceRecord = null; } else { Model.SelectedEmployee = Model.PreviouslySelectedEmployee; Model.SelectedSupportConcept = Model.PreviouslySelectedSupportConcept; Model.ServiceCategories.Clear(); Model.SelectedCostbearerRelOids.Clear(); Model.SelectedEmployees.Clear(); Model.SelectedSupportConcepts.Clear(); Model.SelectedConceptCostBearerRelations.Clear(); Model.SelectedEmployee = MobileSessionFacade.LoggedInCompactEmployee; if (Model.SelectedSupportConcept != null) { var details = OperationsService.GetSupportConceptTreeNodeDetailInfo(Model.SelectedSupportConcept.Customer.CustomerOid, Model.SelectedSupportConcept.SupportConceptOid, Model.CostBearer2SupportConceptOid); Model.ServiceCategories = details.ServiceAccountings.Count > 0 ? CreateServiceCategoryModels(details.ServiceAccountings.Select(sa => sa.ServiceDescription).ToList()) : CreateServiceCategoryModels(OperationsService.GetAllServiceDescriptions()); Model.ServiceCategories = Model.ServiceCategories.Where(c => !c.OhneHilfeplan.HasValue || c.OhneHilfeplan.Value == AccountingvisibilityType.Beides || c.OhneHilfeplan.Value == AccountingvisibilityType.NurKlientenbezogen).ToList(); } else if (Model.CostBearer2SupportConceptOid == -2) { Model.ServiceCategories = CreateServiceCategoryModels(OperationsService.GetAllServiceDescriptions()); Model.ServiceCategories = Model.ServiceCategories.Where(c => !c.OhneHilfeplan.HasValue || c.OhneHilfeplan.Value == AccountingvisibilityType.Beides || c.OhneHilfeplan.Value == AccountingvisibilityType.NichtKlientenbezogen).ToList(); } } } [HttpPost] [Authorize] public ActionResult ResetEditingMode(FormCollection pFormCollection) { if (Model == null) { return RedirectToActionPermanent("Index", "Login"); } Model.NewServiceRecord = new ServiceRecordDC(); Model.SelectedServiceRecord = null; //Model.SelectedEmployees.Clear(); Model.IsInEditingMode = false; Model.SelectedSupportConcepts.Clear(); Model.SelectedConceptCostBearerRelations.Clear(); Model.SelectedCostbearerRelOids.Clear(); Model.SelectedGroupOfPeopleOids.Clear(); Model.SelectedEmployees = new List { MobileSessionFacade.LoggedInCompactEmployee }; Model.SelectedEmployee = MobileSessionFacade.LoggedInCompactEmployee; Model.ServiceCategories = CreateServiceCategoryModels(OperationsService.GetAllServiceDescriptions()); //LoadServiceCategoriesToModel(Model.CostBearer2SupportConceptOid); var serviceDescriptions = Model.GetServiceDesctiptions(); if (Model.ServiceCategories.Any() && serviceDescriptions.Any()) { var firstServiceDescription = serviceDescriptions.First(); Model.SelectedServiceDescriptionOid = firstServiceDescription.ServiceDescriptionOid; Model.SelectedServiceCategoryOid = firstServiceDescription.Category.ServiceCategoryOid; } return RedirectToActionPermanent("Main"); } [Authorize] public string AddSupportConceptCostBearerRelationsToGroupBooking(string pRelOids, string pGroupOids) { if(Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } var rawRelOids = string.IsNullOrEmpty(pRelOids) ? new string[0] : pRelOids.Split(','); var rawGroupOids = string.IsNullOrEmpty(pGroupOids) ? new string[0] : pGroupOids.Split(','); var relOids = new List(); var groups = new List(); rawRelOids.DoForEach(s => relOids.AddIfNotIn(long.Parse(s))); Model.SelectedGroupOfPeopleOids.Clear(); rawGroupOids.DoForEach(s => { var group = Model.GroupsOfPeople.FirstOrDefault(f => f.GroupOfPeopleOid.HasValue && f.GroupOfPeopleOid.Value.Equals(long.Parse(s))); if(group == null) { return; } groups.AddIfNotIn(group); group.SupportConceptList.DoForEach(f => relOids.AddRangeIfElementsNotIn(f.CostBearerRelOids)); }); Model.SelectedSupportConcepts.Clear(); Model.SelectedCostbearerRelOids.Clear(); Model.SelectedCostbearerRelOids.AddRangeIfElementsNotIn(relOids); var selectedSupportConcepts = Model.SupportConcepts.Where(w => w != null && w.CostBearerRelations.Any(a => a.CostBearer2SupportConceptOid.HasValue && relOids.Contains(a.CostBearer2SupportConceptOid.Value))).ToList(); var groupCostBearerRelations = CustomerService.GetSupportConceptCostBearerRelationsById(relOids); Model.SelectedConceptCostBearerRelations.Clear(); Model.SelectedConceptCostBearerRelations.AddRangeIfElementsNotIn(groupCostBearerRelations); Model.SelectedSupportConcepts.AddRangeIfElementsNotIn(selectedSupportConcepts); foreach (var gruppe in groups.Where(g => g.GroupOfPeopleOid.HasValue)) { var groupRelOids = new List(); gruppe.SupportConceptList.ForEach(f => groupRelOids.AddRange(f.CostBearerRelOids)); if (!gruppe.GroupOfPeopleOid.HasValue) { continue; } var groupOid = gruppe.GroupOfPeopleOid.Value; if (relOids.ContainsItems(groupRelOids)) { Model.SelectedGroupOfPeopleOids.AddIfNotIn(groupOid); } else if (Model.SelectedGroupOfPeopleOids.Contains(groupOid)) { Model.SelectedGroupOfPeopleOids.Remove(groupOid); } } return SerializeObject(Model.GroupBookingSelectionObject); } [Authorize] public string RemoveSupportConceptCostBearerRelationFromGroupBooking(string pRelOid) { if(Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } long.TryParse(pRelOid, out var supportConceptCostBearerRelationOid); var supportConcept = Model.SelectedSupportConcepts.FirstOrDefault(f => f.CostBearerRelations.Any(a => a.CostBearer2SupportConceptOid == supportConceptCostBearerRelationOid)); var relation = Model.SelectedConceptCostBearerRelations.FirstOrDefault(f => f.CostBearer2SupportConceptOid == supportConceptCostBearerRelationOid); Model.SelectedSupportConcepts.Remove(supportConcept); Model.SelectedConceptCostBearerRelations.Remove(relation); var selectedGroups = Model.GroupsOfPeople.Where(group => group.GroupOfPeopleOid.HasValue && Model.SelectedGroupOfPeopleOids.Contains(group.GroupOfPeopleOid.Value)).ToList(); var groups = selectedGroups.Where(group => group.SupportConceptList.All(a => Model.SelectedSupportConcepts.Where(w => w.SupportConceptOid.HasValue).Select(s => s.SupportConceptOid.Value).Contains(a.SupportConceptOid))); Model.SelectedGroupOfPeopleOids = groups.Where(group => group.GroupOfPeopleOid.HasValue).Select(group => group.GroupOfPeopleOid.Value).ToList(); return SerializeObject(Model.GroupBookingSelectionObject); } [Authorize] public string AddEmployeesToGroupBooking(string pEmployeeOids) { if(Model == null) { RedirectToActionPermanent("Index", "Login"); return _LeerzeichenFuerGetMethoden; } if(string.IsNullOrEmpty(pEmployeeOids)) { Model.SelectedEmployees.Clear(); return JsonConvert.SerializeObject(Model.SelectedEmployees.Count); } var rawEmployeeOids = pEmployeeOids.Split(','); var oids = new List(); rawEmployeeOids.DoForEach(s => oids.AddIfNotIn(long.Parse(s))); var employees = Model.Employees.Where(w => oids.Contains(w.EmployeeOid)); Model.SelectedEmployees.Clear(); Model.SelectedEmployees.AddRangeIfElementsNotIn(employees); return JsonConvert.SerializeObject(Model.SelectedEmployees.Count); } [HttpPost] [Authorize] public ActionResult LoadSignatureImage(FormCollection pFormCollection) { if(Model == null) { return RedirectToActionPermanent("Index", "Login"); } var isParsingSuccessful2 = long.TryParse(pFormCollection["service-record-oid-holder"], out var serviceRecordOid); var isParsingSuccessful = long.TryParse(pFormCollection["signatureOidHolder"], out var signatureOid); if(isParsingSuccessful && isParsingSuccessful2) { var signatureServiceRecord = Model.ServiceRecords.FirstOrDefault(serviceRecord => serviceRecord.ServiceRecordOid.Equals(serviceRecordOid)); Model.SignatureServiceRecordHeader = MainModel.GetServiceRecordTimeHeader(signatureServiceRecord, false); Model.SignatureImage = OperationsService.GetSignature(signatureOid).DataBild; ApplyWatermark(); } return RedirectToActionPermanent("Main"); } [Authorize] public string ResetSignatureImage() { if(Model == null) { return _LeerzeichenFuerGetMethoden; } Model.SignatureImage = null; Model.SignatureServiceRecordHeader = null; return _LeerzeichenFuerGetMethoden; } [HttpPost] [Authorize] public ActionResult CreateGroupBooking(FormCollection formCollection) { try { if(Model == null) { return RedirectToActionPermanent("Index", "Login"); } if(Model.SelectedConceptCostBearerRelations.Count == 1) { var cb2ScOids = (from scDc in Model.SelectedSupportConcepts where scDc.CostBearerRelations != null && scDc.CostBearerRelations.Count > 0 let costBearer2SupportConceptOid = scDc.CostBearerRelations[0].CostBearer2SupportConceptOid where costBearer2SupportConceptOid != null select costBearer2SupportConceptOid.Value).ToList(); var cb2ScOidsCount = cb2ScOids.Count; if (cb2ScOidsCount == 1) { Model.CostBearer2SupportConceptOid = cb2ScOids[0]; } else { return RedirectToActionPermanent("Main"); } } string doku1; if(Model.Dokutypes != null && Model.Dokutypes.Length > 0) { doku1 = formCollection["Dokumentation1"]; } else { doku1 = formCollection["Dokumentation6"]; } Log.Info($"CreateServiceRecord: datum:{formCollection["Datum"]}; start:{formCollection["Start"]}; ende:{formCollection["Ende"]}; dauer:{formCollection["Dauer"]}; doku:{doku1}; aktion:{formCollection["versteckt"]}"); if(string.IsNullOrEmpty(formCollection["Datum"])) { return View("Main", Model); } var distanz = formCollection["Distanz"]; var distanceInMeters = 0; if(!string.IsNullOrEmpty(distanz)) { if(int.TryParse(distanz, out var parsedDistance)) { distanceInMeters = parsedDistance; } } var selectedCostbearerScRelOid = Model.CostBearer2SupportConceptOid < 1 ? null : Model.CostBearer2SupportConceptOid; var datum = Convert.ToDateTime(formCollection["Datum"]); var enddatum = datum; var endDateString = formCollection["Enddatum"]; if(endDateString != null) { enddatum = Convert.ToDateTime(endDateString); } var start = formCollection["Start"]; var ende = formCollection["Ende"]; var dauer = 0; if(datum > enddatum) { enddatum = datum; } if(!string.IsNullOrEmpty(formCollection["Dauer"])) { int.TryParse(formCollection["Dauer"], out dauer); } var doku2 = formCollection["Dokumentation2"]; var doku3 = formCollection["Dokumentation3"]; var doku4 = formCollection["Dokumentation4"]; var doku5 = formCollection["Dokumentation5"]; var zeitenFeld = new DateTime[2]; if(start == string.Empty && ende == string.Empty) { zeitenFeld[0] = new DateTime(datum.Year, datum.Month, datum.Day, 0, 0, 1); if(enddatum == datum) { zeitenFeld[1] = new DateTime(datum.Year, datum.Month, datum.Day, 0, 0, 1).AddMinutes(dauer); } else { zeitenFeld[1] = new DateTime(enddatum.Year, enddatum.Month, enddatum.Day, 0, 0, 1).AddMinutes(dauer); } } else { zeitenFeld = enddatum == datum ? ConvertRecordTimes(start, ende, datum, dauer) : ConvertRecordTimesWithEndDate(start, ende, datum, enddatum, dauer); } if(dauer == 0 || zeitenFeld[1] != zeitenFeld[0]) { dauer = (int)(zeitenFeld[1] - zeitenFeld[0]).TotalMinutes; } if(Model.NewServiceRecord == null) { return RedirectToActionPermanent("Main"); } Model.NewServiceRecord.IP = Request.UserHostAddress; Model.NewServiceRecord.Goals = Model.SelectedGoals; Model.NewServiceRecord.Start = zeitenFeld[0]; Model.NewServiceRecord.End = zeitenFeld[1]; Model.NewServiceRecord.DistanceInMeter = distanceInMeters; if(Model.Employee.EmployeeOid != null) { if(Model.SelectedEmployee != null) { Model.NewServiceRecord.Employee = Model.SelectedEmployee; } var sc = Model.SupportConcepts.FirstOrDefault(fod => fod.CostBearerRelations.Any(a => a.CostBearer2SupportConceptOid.HasValue && a.CostBearer2SupportConceptOid.Value.Equals(selectedCostbearerScRelOid))); if(sc != null) { if(sc.SupportConceptOid != null) { Model.NewServiceRecord.SupportConcept = CustomerService.LoadCompactSupportConceptDC(sc.SupportConceptOid.Value, Model.Employee.EmployeeOid); } Model.NewServiceRecord.Customer = sc.Customer; var cb2ScRel = sc.CostBearerRelations.First(f => f.CostBearer2SupportConceptOid.HasValue && f.CostBearer2SupportConceptOid.Equals(selectedCostbearerScRelOid)); Model.NewServiceRecord.CostBearer = cb2ScRel.CostBearer; var intervall = Model.NewServiceRecord.CostBearer.ActualMinuteIntervall; if(intervall > 0) { Model.NewServiceRecord.RoundedDuration = dauer % intervall != 0 ? dauer + (intervall - dauer % intervall) : dauer; } else { Model.NewServiceRecord.RoundedDuration = dauer; } Model.NewServiceRecord.CostBearer2SupportConceptOid = selectedCostbearerScRelOid; } else { Model.NewServiceRecord.RoundedDuration = dauer; } } Model.NewServiceRecord.DurationInStunden = ZeiterfassungsDauer.Minuten; Model.NewServiceRecord.ServiceRecordFormat = ServiceRecordFormate.OriginaleZeiterfassung; Model.NewServiceRecord.Notice = string.IsNullOrEmpty(doku1) ? null : doku1; Model.NewServiceRecord.Notice2 = string.IsNullOrEmpty(doku2) ? null : doku2; Model.NewServiceRecord.Notice3 = string.IsNullOrEmpty(doku3) ? null : doku3; Model.NewServiceRecord.Notice4 = string.IsNullOrEmpty(doku4) ? null : doku4; Model.NewServiceRecord.Notice5 = string.IsNullOrEmpty(doku5) ? null : doku5; var serviceDescOid = 0L; if(!string.IsNullOrEmpty(formCollection["ServiceDescription"])) { serviceDescOid = Convert.ToInt64(formCollection["ServiceDescription"]); } else if(Model.SelectedServiceDescriptionOid.HasValue) { serviceDescOid = Model.SelectedServiceDescriptionOid.Value; } if(serviceDescOid > 0) { Model.NewServiceRecord.ServiceDescription = OperationsService.GetServiceDescription(serviceDescOid); } if(Model.NewServiceRecord.RoundedDuration == 0) { Model.NewServiceRecord.RoundedDuration = dauer; } Model.NewServiceRecord.IP = Request.UserHostAddress; Model.NewServiceRecord.InsertedOn = DateTime.Now; Model.NewServiceRecord.InsUser = $"{MobileSessionFacade.LoggedInEmployee.FirstName} {MobileSessionFacade.LoggedInEmployee.LastName}"; Model.NewServiceRecord.IsCreatedInMobileClient = true; if(Model.IsInGroupBookingMode && Model.SelectedSupportConcepts.Count > 1) { ResetGroupBookingMode(true); return SaveGroupBooking(); } var oidList = OperationsService.InsertNewServiceRecords(new List { Model.NewServiceRecord }); Model.ServiceRecordOid = oidList[0]; Model.NewServiceRecord = new ServiceRecordDC(); } catch(Exception e) { Log.Error(e.Message, e); } return ResetEditingMode(null); } [HttpPost] [Authorize] public ActionResult EditServiceRecord(FormCollection formCollection) { if(Model == null) { return RedirectToActionPermanent("Index", "Login"); } try { string doku1; if(Model.Dokutypes != null && Model.Dokutypes.Length > 0) { doku1 = formCollection["Dokumentation1"]; } else { doku1 = formCollection["Dokumentation6"]; } Log.Info($"EditServiceRecord: datum:{formCollection["Datum"]}; start:{formCollection["Start"]}; ende:{formCollection["Ende"]}; dauer:{formCollection["Dauer"]}; doku:{doku1}; aktion:Speichern"); if(string.IsNullOrEmpty(formCollection["Datum"])) { return View("Main", Model); } var distanz = formCollection["Distanz"]; var distanceInMeters = 0; if(!string.IsNullOrEmpty(distanz)) { if(int.TryParse(distanz, out var parsedDistance)) { distanceInMeters = parsedDistance; } } var selectedCostbearer2SupportConceptRelOid = Model.CostBearer2SupportConceptOid < 1 ? null : Model.CostBearer2SupportConceptOid; var datum = Convert.ToDateTime(formCollection["Datum"]); var enddatum = datum; var endDateString = formCollection["Enddatum"]; if(endDateString != null) { enddatum = Convert.ToDateTime(endDateString); } var start = formCollection["Start"]; var ende = formCollection["Ende"]; var dauer = 0; if(datum > enddatum) { enddatum = datum; } if(!string.IsNullOrEmpty(formCollection["Dauer"])) { int.TryParse(formCollection["Dauer"], out dauer); } var doku2 = formCollection["Dokumentation2"]; var doku3 = formCollection["Dokumentation3"]; var doku4 = formCollection["Dokumentation4"]; var doku5 = formCollection["Dokumentation5"]; var zeitenFeld = new DateTime[2]; if(start == string.Empty && ende == string.Empty) { zeitenFeld[0] = new DateTime(datum.Year, datum.Month, datum.Day, 0, 0, 1); if(enddatum == datum) { zeitenFeld[1] = new DateTime(datum.Year, datum.Month, datum.Day, 0, 0, 1).AddMinutes(dauer); } else { zeitenFeld[1] = new DateTime(enddatum.Year, enddatum.Month, enddatum.Day, 0, 0, 1).AddMinutes(dauer); } } else { zeitenFeld = enddatum == datum ? ConvertRecordTimes(start, ende, datum, dauer) : ConvertRecordTimesWithEndDate(start, ende, datum, enddatum, dauer); } if(dauer == 0 || zeitenFeld[1] != zeitenFeld[0]) { dauer = (int)(zeitenFeld[1] - zeitenFeld[0]).TotalMinutes; } var selectedRecordOid = Model.SelectedServiceRecordOid ?? Model.SelectedServiceRecord.ServiceRecordOid; Model.NewServiceRecord = OperationsService.GetServiceRecordById(selectedRecordOid.Value); if(Model.NewServiceRecord == null) { return RedirectToActionPermanent("Main"); } Model.NewServiceRecord.IP = Request.UserHostAddress; Model.NewServiceRecord.Goals = Model.SelectedGoals; Model.NewServiceRecord.Start = zeitenFeld[0]; Model.NewServiceRecord.End = zeitenFeld[1]; Model.NewServiceRecord.DistanceInMeter = distanceInMeters; if(Model.Employee.EmployeeOid != null) { if(Model.SelectedEmployee != null) { Model.NewServiceRecord.Employee = Model.SelectedEmployee; } var sc = Model.SupportConcepts.FirstOrDefault(fod => fod.CostBearerRelations.Any(a => a.CostBearer2SupportConceptOid.HasValue && a.CostBearer2SupportConceptOid.Value.Equals(selectedCostbearer2SupportConceptRelOid))); if(sc != null) { if(sc.SupportConceptOid != null) { Model.NewServiceRecord.SupportConcept = CustomerService.LoadCompactSupportConceptDC(sc.SupportConceptOid.Value, Model.Employee.EmployeeOid); } Model.NewServiceRecord.Customer = sc.Customer; var cb2ScRel = sc.CostBearerRelations.First(f => f.CostBearer2SupportConceptOid.HasValue && f.CostBearer2SupportConceptOid.Equals(selectedCostbearer2SupportConceptRelOid)); Model.NewServiceRecord.CostBearer = cb2ScRel.CostBearer; var intervall = Model.NewServiceRecord.CostBearer.ActualMinuteIntervall; if(intervall > 0) { Model.NewServiceRecord.RoundedDuration = dauer % intervall != 0 ? dauer + (intervall - dauer % intervall) : dauer; } else { Model.NewServiceRecord.RoundedDuration = dauer; } Model.NewServiceRecord.CostBearer2SupportConceptOid = selectedCostbearer2SupportConceptRelOid; } else { Model.NewServiceRecord.RoundedDuration = dauer; } } Model.NewServiceRecord.DurationInStunden = ZeiterfassungsDauer.Minuten; Model.NewServiceRecord.ServiceRecordFormat = ServiceRecordFormate.OriginaleZeiterfassung; Model.NewServiceRecord.Notice = string.IsNullOrEmpty(doku1) ? null : doku1; Model.NewServiceRecord.Notice2 = string.IsNullOrEmpty(doku2) ? null : doku2; Model.NewServiceRecord.Notice3 = string.IsNullOrEmpty(doku3) ? null : doku3; Model.NewServiceRecord.Notice4 = string.IsNullOrEmpty(doku4) ? null : doku4; Model.NewServiceRecord.Notice5 = string.IsNullOrEmpty(doku5) ? null : doku5; var serviceDescOid = 0L; if(!string.IsNullOrEmpty(formCollection["ServiceDescription"])) { serviceDescOid = Convert.ToInt64(formCollection["ServiceDescription"]); } else if(Model.SelectedServiceDescriptionOid.HasValue) { serviceDescOid = Model.SelectedServiceDescriptionOid.Value; } if(serviceDescOid > 0) { Model.NewServiceRecord.ServiceDescription = OperationsService.GetServiceDescription(serviceDescOid); } if(Model.NewServiceRecord.RoundedDuration == 0) { Model.NewServiceRecord.RoundedDuration = dauer; } Model.NewServiceRecord.IP = Request.UserHostAddress; Model.NewServiceRecord.InsertedOn = DateTime.Now; Model.NewServiceRecord.InsUser = $"{MobileSessionFacade.LoggedInEmployee.FirstName} {MobileSessionFacade.LoggedInEmployee.LastName}"; Model.NewServiceRecord.IsCreatedInMobileClient = true; if(Model.IsInGroupBookingMode && Model.SelectedSupportConcepts.Count > 1) { return UpdateGroupBooking(); } OperationsService.UpdateServiceRecords(new List { Model.NewServiceRecord }); Model.NewServiceRecord = new ServiceRecordDC(); if(selectedCostbearer2SupportConceptRelOid.HasValue) { Model.ServiceRecords = OperationsService.FindServiceRecordsForLastDays(selectedCostbearer2SupportConceptRelOid, Model.Zeitraum, Model.Employee.EmployeeOid).ToList(); } } catch(Exception e) { Log.Error(e.Message, e); } return ResetEditingMode(null); } [HttpPost] public ActionResult LogOutAfterSessionTimeout() { Logout(); return RedirectToActionPermanent("Index", "Login", new { isSessionTimedOut = true}); } } }