using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Text; using System.Windows.Input; using System.Windows.Media; using System.Windows.Threading; using BeWo.Core; using BeWo.Core.Service; using BeWo.ServiceProxy; using BeWo.View.Controls.AI; using BeWo.ViewModel.View.AI; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.DataContracts.Feature.AI.Functions.ServiceRecords; using BS.Shared.Extensions; using BS.Shared.Services; using DevExpress.Mvvm; using DevExpress.Xpf.Editors.ExpressionEditor; using Microsoft.VisualBasic; using Newtonsoft.Json; using DispatcherObject = System.Windows.Threading.DispatcherObject; namespace BeWo.ViewModel.ListViewModel { public class ServiceRecordListVM : AbstractDCListMapperVM { public static string PropertyName_CustomerNodes = "CustomerNodes"; public static string PropertyName_Information = "Information"; public static string PropertyName_PrototypeVM = "PrototypeVM"; public static string PropertyName_RecordCountInformationString = "RecordCountInformationString"; public static string PropertyName_RecordingDays = "RecordingDays"; public static string PropertyName_ServiceRecordsForSelectedCustomer = "ServiceRecordsForSelectedCustomer"; public static string PropertyName_IsCustomerWarningActive = "IsCustomerWarningActive"; public static string PropertyName_CustomerWarning = "CustomerWarning"; public static string PropertyName_Statistics = "Statistics"; public static string PropertyName_ServiceRecordTimeInterval = "ServiceRecordTimeInterval"; public static string PropertyName_Wohnheimbuchungen = "Wohnheimbuchungen"; public static string PropertyName_SelectedWohnheimbuchung = "SelectedWohnheimbuchung"; public static string PropertyName_BedarfsMedViewModel = "BedarfsMedViewModel"; public static string PropertyName_MedRecordCreationEnabled = "MedRecordCreationEnabled"; public event EventHandler StatisticInfosLoaded; private readonly List _AllGoalCategories; private readonly Dictionary> _Category2Services; private readonly Dictionary _CostBearer2SupportConceptOid2BookingInfoDict = new Dictionary(); //private readonly Dictionary _ServiceRecordsLoaded = new Dictionary(); //private readonly Dictionary _EmployeeServiceRecordsLoaded = new Dictionary(); private readonly BindingList _ServiceRecordsForSelectedCustomer; private List _AllGoals; private ObservableSortCollection _CustomerNodes; private ServiceRecordVM _PrototypeVM; private string _RecordCountInformationString; private ObservableCollection _RecordingDays; private FlatSupportConceptTreeNodeDC _SelectedCustomerNode; private CompactEmployeeDC mSelectedEmployee; private bool _IsCustomerWarningActive; private string _CustomerWarning; private ServiceRecordTimeInterval _ServiceRecordTimeInterval = ServiceRecordTimeInterval.LastWeek; private bool _ShowOnlyContentServiceRecords; private List _Statistics; //meins private DateTime? _XTageVon; private DateTime? _XTageBis; private int _XTage; private int _SelectedMonthIndex; private int _SelectedYear; //private WohnheimbuchungsVM selectedWohnheimbuchung; //private static List _AllDosageForms; private List _AiActionHistory; private int _AiActionHistoryIndex; private AiConversationButtonState _AiConversationButtonState; public ICommand OpenAiPromptSelectionCommand { get; set; } public ICommand UndoAiActionCommand { get; set; } public ICommand RedoAiActionCommand { get; set; } private List _EditAiActionHistory; private int _EditAiActionHistoryIndex; public ICommand OpenEditAiPromptSelectionCommand { get; set; } public ICommand UndoEditAiActionCommand { get; set; } public ICommand RedoEditAiActionCommand { get; set; } public ServiceRecordListVM( Dictionary> pCategory2Services, IEnumerable pAllGoalCategories, IEnumerable pAllIndGoalCategories, List pAllGoals, List pAlleWohnheime, List allDocTypes, List pAllDosageForms) { _ServiceRecordTimeInterval = BeWoApp.AppSettings.LastSelectedServiceRecordTimeInterval; _XTage = BeWoApp.AppSettings.LastSelectedServiceRecordTimeIntervalDays; if (pCategory2Services != null) { Dictionary> globalCats = pCategory2Services.Keys.Where(cat => cat.ScopeType == ScopeTypeId.Global) .ToDictionary(cat => cat, cat => pCategory2Services[cat]); _Category2Services = globalCats; } _ServiceRecordsForSelectedCustomer = new BindingList(); _SelectedMonthIndex = BeWoApp.AppSettings.LastSelectedServiceRecordMonth.Month - 1; _SelectedYear = BeWoApp.AppSettings.LastSelectedServiceRecordMonth.Year; //if (DateTime.Now.Day < 15) //{ //CB EINKOMMENTIEREN //var wdc = new WohnheimbuchungDC(); //wdc.Buchungsdatum = DateTime.Now; //var gefilterteWohnheime = // pAlleWohnheime.Where(wh => wh.EmployeeOids.Contains(BeWoApp.LoggedOnEmployee.EmployeeOid.Value)).ToList(); //if (gefilterteWohnheime.Count == 1) //{ // wdc.Wohnheim = gefilterteWohnheime[0]; //} //selectedWohnheimbuchung = new WohnheimbuchungsVM(wdc, pCategory2Services); //AlleWohnheime = gefilterteWohnheime; //AllDosageForms = pAllDosageForms; _AllGoalCategories = new List(); if (pAllGoalCategories != null) { _AllGoalCategories.AddRange(pAllGoalCategories); } if (pAllIndGoalCategories != null) { _AllGoalCategories.AddRange(pAllIndGoalCategories); } _AllGoals = pAllGoals; AllDocTypes = allDocTypes; AllGoalCategories = _AllGoalCategories; if (AllDocTypes != null) { AllDocTypes.Sort((a, b) => a.ValueListEntryOid.Value.CompareTo(b.ValueListEntryOid.Value)); } VMList.ListChanged += (s, e) => CheckCustomerAbsenceTimes(); InitAiStuff(); } private void InitAiStuff() { var vm_doku = new AiPromptbausteinSelectionComplexViewModel(AiActionType.ServiceRecordDocumentation); vm_doku.PromptAccepted += PromptAccepted; OpenAiPromptSelectionCommand = new DelegateCommand(() => { BeWoApp.MainControl.WindowService.Show(vm_doku); }, () => !string.IsNullOrWhiteSpace(AktuellerDokutext)); UndoAiActionCommand = new DelegateCommand(UndoAiAction); RedoAiActionCommand = new DelegateCommand(RedoAiAction); var vm_edit_doku = new AiPromptbausteinSelectionComplexViewModel(AiActionType.ServiceRecordDocumentation); vm_edit_doku.PromptAccepted += EditPromptAccepted; OpenEditAiPromptSelectionCommand = new DelegateCommand(() => { _EditAiActionHistory = new List(); _EditAiActionHistory.Add(AktuellerEditDokutext); _EditAiActionHistoryIndex = 0; BeWoApp.MainControl.WindowService.Show(vm_edit_doku); }, () => !string.IsNullOrWhiteSpace(AktuellerEditDokutext)); UndoEditAiActionCommand = new DelegateCommand(UndoEditAiAction); RedoEditAiActionCommand = new DelegateCommand(RedoEditAiAction); _AiActionHistory = new List(); _AiActionHistory.Add(AktuellerDokutext); _AiActionHistoryIndex = 0; } public AiConversationButtonState AiConversationButtonState { get => _AiConversationButtonState; set => SetProperty(ref _AiConversationButtonState, value, nameof(AiConversationButtonState)); } public IEnumerable CurrentVisibleVMs { get; set; } public string AktuellerDokutext { get => PrototypeVM.Notice; set { PrototypeVM.Notice = value; FirePropertyChanged(nameof(IsRedoButtonVisible)); FirePropertyChanged(nameof(IsUndoButtonVisible)); } } public string AktuellerEditDokutext { get => EditVM?.Notice; set { EditVM.Notice = value; FirePropertyChanged(nameof(IsEditUndoButtonVisible)); FirePropertyChanged(nameof(IsEditRedoButtonVisible)); } } public bool IsAiButtonVisible => SelectedCustomerNode is object && (BeWoApp.AppSettings.ShowAI || BeWoApp.AppSettings.ShowAIVoice); public bool IsUndoButtonVisible => _AiActionHistoryIndex > 0; public bool IsRedoButtonVisible => _AiActionHistoryIndex < _AiActionHistory.Count - 1; public bool IsEditUndoButtonVisible => _EditAiActionHistoryIndex > 0; public bool IsEditRedoButtonVisible => _EditAiActionHistoryIndex < (_EditAiActionHistory?.Count ?? 0) - 1; private void PromptAccepted(object sender, AiPromptbausteinPromptVM prompt) { if (prompt is null) throw new NotImplementedException(); // 1. Information aufbereiten // 1.1 Prompt var prompt_oid = prompt.DataContract.Oid.Value; var prompt_version = prompt.DataContract.Version; // 1.2 Hilfeplan var support_concept = SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConcept; var support_concept_oid = support_concept.SupportConceptOid; var support_concept_version = support_concept.SupportConceptVersion; // 1.3 Aktuelles Doku Feld var doku_feld = AktuellerDokutext; // 1.4 Sichtbaren Zeiterfassungseinträge var service_records = CurrentVisibleVMs; var sr_refs = service_records.Select(x => new BeWoRefDC(x.DataContract.ServiceRecordOid.Value, x.DataContract.ServiceRecordVersion)); // 1.5 Costbearer var costbearer = SelectedCustomerNode.SupportConceptTreeNodeDC.CostBearer; var cb_oid = costbearer.CostBearerOid.Value; var cb_ver = costbearer.CostBearerVersion; // Service Aufruf var req = new AiFunctionDocRequest() { AiPromptbausteinPrompt = new BeWoRefDC(prompt_oid, prompt_version), SupportConcept = new BeWoRefDC(support_concept_oid, support_concept_version), ServiceRecords = sr_refs, CostBearer = new BeWoRefDC(cb_oid, cb_ver), Dokumentation = doku_feld, }; ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.ExecuteAiFunctionServiceRecordDocumentation(req), callback => { var viewModel = new AiPromptbausteinActionResultViewModel(); viewModel.Result = callback.Result; viewModel.Accept_Button_Clicked += (s, e) => { var sb = new StringBuilder(); sb.AppendLine("AI Antwort:"); sb.AppendLine(viewModel.Result); sb.AppendLine(); sb.AppendLine("Original:"); sb.AppendLine(AktuellerDokutext); var str = sb.ToString(); var idx = _AiActionHistoryIndex; var count = _AiActionHistory.Count; if (count - 1 > idx) { _AiActionHistory.RemoveRange(idx + 1, count - idx - 1); } if (AktuellerDokutext != _AiActionHistory[_AiActionHistoryIndex]) { _AiActionHistory.Add(AktuellerDokutext); _AiActionHistoryIndex++; } _AiActionHistory.Add(str); _AiActionHistoryIndex++; AktuellerDokutext = str; }; viewModel.Replace_Button_Clicked += (s, e) => { var str = viewModel.Result; var idx = _AiActionHistoryIndex; var count = _AiActionHistory.Count; if (count - 1 > idx) { _AiActionHistory.RemoveRange(idx + 1, count - idx - 1); } if (AktuellerDokutext != _AiActionHistory[_AiActionHistoryIndex]) { _AiActionHistory.Add(AktuellerDokutext); _AiActionHistoryIndex++; } _AiActionHistory.Add(str); _AiActionHistoryIndex++; AktuellerDokutext = str; }; viewModel.Retry_Button_Clicked += (s, e) => { PromptAccepted(sender, prompt); }; BeWoApp.MainControl.WindowService.Show(viewModel); } ); } private void EditPromptAccepted(object sender, AiPromptbausteinPromptVM prompt) { if (prompt is null) throw new NotImplementedException(); // 1. Information aufbereiten // 1.1 Prompt var prompt_oid = prompt.DataContract.Oid.Value; var prompt_version = prompt.DataContract.Version; // 1.2 Hilfeplan var support_concept = SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConcept; var support_concept_oid = support_concept.SupportConceptOid; var support_concept_version = support_concept.SupportConceptVersion; // 1.3 Aktuelles Doku Feld var doku_feld = AktuellerEditDokutext; // 1.4 Sichtbaren Zeiterfassungseinträge var service_records = CurrentVisibleVMs; var sr_refs = service_records.Select(x => new BeWoRefDC(x.DataContract.ServiceRecordOid.Value, x.DataContract.ServiceRecordVersion)); // 1.5 Costbearer var costbearer = SelectedCustomerNode.SupportConceptTreeNodeDC.CostBearer; var cb_oid = costbearer.CostBearerOid.Value; var cb_ver = costbearer.CostBearerVersion; // Service Aufruf var req = new AiFunctionDocRequest() { AiPromptbausteinPrompt = new BeWoRefDC(prompt_oid, prompt_version), SupportConcept = new BeWoRefDC(support_concept_oid, support_concept_version), ServiceRecords = sr_refs, CostBearer = new BeWoRefDC(cb_oid, cb_ver), Dokumentation = doku_feld, }; ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.ExecuteAiFunctionServiceRecordDocumentation(req), callback => { var viewModel = new AiPromptbausteinActionResultViewModel(); viewModel.Result = callback.Result; viewModel.Accept_Button_Clicked += (s, e) => { var sb = new StringBuilder(); sb.AppendLine("AI Antwort:"); sb.AppendLine(viewModel.Result); sb.AppendLine(); sb.AppendLine("Original:"); sb.AppendLine(AktuellerEditDokutext); var str = sb.ToString(); var idx = _EditAiActionHistoryIndex; var count = _EditAiActionHistory.Count; if (count - 1 > idx) { _EditAiActionHistory.RemoveRange(idx + 1, count - idx - 1); } if (AktuellerEditDokutext != _EditAiActionHistory[_EditAiActionHistoryIndex]) { _EditAiActionHistory.Add(AktuellerEditDokutext); _EditAiActionHistoryIndex++; } _EditAiActionHistory.Add(str); _EditAiActionHistoryIndex++; AktuellerEditDokutext = str; }; viewModel.Replace_Button_Clicked += (s, e) => { var str = viewModel.Result; var idx = _EditAiActionHistoryIndex; var count = _EditAiActionHistory.Count; if (count - 1 > idx) { _EditAiActionHistory.RemoveRange(idx + 1, count - idx - 1); } if (AktuellerEditDokutext != _EditAiActionHistory[_EditAiActionHistoryIndex]) { _EditAiActionHistory.Add(AktuellerEditDokutext); _EditAiActionHistoryIndex++; } _EditAiActionHistory.Add(str); _EditAiActionHistoryIndex++; AktuellerEditDokutext = str; }; viewModel.Retry_Button_Clicked += (s, e) => { PromptAccepted(sender, prompt); }; BeWoApp.MainControl.WindowService.Show(viewModel); } ); } public void UpdateViewYearFilter(IEnumerable enumerable) { if (BeWoApp.AppSettings.ShowAI) { AiConversationButtonState = AiConversationButtonState.Loading; var context = GetVisibleInformationReferences(enumerable); if (context != null) { var context2 = context.ToDictionary(kv => kv.Key, kv => kv.Value.ToList()); ServiceFacade.DoAiEnhancedServiceAsnyc(x => x.CheckContextSize(AiContextType.ServiceRecord, context2, null), isValid => { if (isValid) AiConversationButtonState = AiConversationButtonState.Normal; else AiConversationButtonState = AiConversationButtonState.Warning; }, (exp) => AiConversationButtonState = AiConversationButtonState.Disabled); } } else { AiConversationButtonState = AiConversationButtonState.Hidden; } } public Dictionary GetVisibleInformationReferences(IEnumerable selected_records) { var current = SelectedCustomerNode; var hello = current?.SupportConceptTreeNodeDC; var sr = ServiceRecordsForSelectedCustomer; if (current is null || hello is null) return null; var oids = new List(); foreach (var record in selected_records) { oids.Add(record.DataContract.ServiceRecordOid ?? -1); } var rtn = new Dictionary() { {TableID.Customer, new long[]{ hello.Customer.CustomerOid } }, {TableID.SupportConcept, new long[]{ hello.SupportConcept.SupportConceptOid } }, {TableID.CostBearer, new long[]{ hello.CostBearer.CostBearerOid ?? -1 } }, {TableID.ServiceRecord, oids.ToArray() } }; return rtn; } //CB EINKOMMENTIEREN //public bool MedRecordCreationEnabled //{ // get { return (BeWoApp.LoggedOnUser.HasRight(UserRightType.MedRecordsAnlegen) || BeWoApp.LoggedOnUser.HasRight(UserRightType.CreateAll)) && BedarfsMedViewModel != null; } //} public List AllDocTypes { get; set; } public List AllGoalCategories { get; set; } //CB EINKOMMENTIEREN //public void LoadExistingWohnheimbuchung(CompactWohnheimDC pWohnheim, DateTime pBuchungsdatum, Action callback) //{ // ServiceFacade.DoCustomerServiceAsync(s => s.GetWohnheimbuchungByWohnheimAndBuchungsdatum(pWohnheim.WohnheimOid, pBuchungsdatum), r => // { // SelectedWohnheimbuchung = new WohnheimbuchungsVM(r ?? new WohnheimbuchungDC { Buchungsdatum = pBuchungsdatum, Wohnheim = pWohnheim }, PrototypeVM.Category2Services) { Category = selectedWohnheimbuchung.Category, ServiceDescription = selectedWohnheimbuchung.ServiceDescription }; // if (r == null) // { // SelectedWohnheimbuchung.Wohnheimbuchung2Costbearer2SupportConceptList = new Wohnheimbuchung2Costbearer2SupportConceptRelListVM(SelectedWohnheimbuchung.DataContract.Costbearer2SupportConceptList); // SelectedWohnheimbuchung.EmployeeList = new WohnheimbuchungEmployeeRelListVM(SelectedWohnheimbuchung.DataContract.EmployeeList); // SelectedWohnheimbuchung.Buchungsdatum = pBuchungsdatum; // SelectedWohnheimbuchung.Wohnheim = pWohnheim; // selectedWohnheimbuchung.Category = selectedWohnheimbuchung.Category; // selectedWohnheimbuchung.ServiceDescription = selectedWohnheimbuchung.ServiceDescription; // } // else // { // var serviceDescription = ServiceFacade.DoCustomerServiceSync(s => s.FindServiceDescriptionForWohnheimbuchungsServiceRecord(r.WohnheimbuchungOid.Value)) ?? selectedWohnheimbuchung.ServiceDescription; // selectedWohnheimbuchung.ServiceDescription = serviceDescription; // selectedWohnheimbuchung.Category = serviceDescription.Category; // } // callback(r != null); // }); //} private MedRecordListVM _BedarfsMedViewModel; public MedRecordListVM BedarfsMedViewModel { get { return _BedarfsMedViewModel; } set { _BedarfsMedViewModel = value; FirePropertyChanged(PropertyName_BedarfsMedViewModel); FirePropertyChanged(PropertyName_MedRecordCreationEnabled); } } public static List AllDosageForms { get; private set; } internal void FetchStatistics(long costBearer2SupportConceptOid) { DateTime stichtag = DateTime.Now; var recordStats = ServiceFacade.DoOperationsServiceSync(s => s.GetServiceRecordStatisticInfo(costBearer2SupportConceptOid, stichtag)); var scStats = ServiceFacade.DoOperationsServiceSync(s => s.CreateSupportConceptStatistics(costBearer2SupportConceptOid, stichtag)); RecordStatisticsDC = recordStats; StatisticsDC = scStats; Statistics = CreateStatisticVMList(scStats); } //CB EINKOMMENTIEREN //public WohnheimbuchungsVM SelectedWohnheimbuchung //{ // get { return selectedWohnheimbuchung; } // set // { // selectedWohnheimbuchung = value; // FirePropertyChanged(PropertyName_SelectedWohnheimbuchung); // } //} public List AlleWohnheime { get; private set; } public int XTage { get { return _XTage; } set { if (AreDifferent(_XTage, value)) { _XTage = value; ServiceRecordTimeInterval = ServiceRecordTimeInterval.XTage; BeWoApp.AppSettings.LastSelectedServiceRecordTimeIntervalDays = value; BeWoApp.SaveAppSettings(); BuildServiceRecordsForSelectedTreeNode(true, false); } } } public DateTime? XTageBis { get { return _XTageBis ?? (_XTageBis = DateTime.Now); } set { if (AreDifferent(_XTageBis, value)) { _XTageBis = value; ServiceRecordTimeInterval = ServiceRecordTimeInterval.ZeitraumWaehlen; if (XTageVon == null) { XTageVon = DateTime.Now; } BuildServiceRecordsForSelectedTreeNode(true, false); } } } public DateTime? XTageVon { get { return _XTageVon ?? (_XTageVon = new DateTime(DateTime.Now.Year, DateTime.Now.Month, 1, 0, 0, 0)); } set { if (AreDifferent(_XTageVon, value)) { _XTageVon = value; ServiceRecordTimeInterval = ServiceRecordTimeInterval.ZeitraumWaehlen; BuildServiceRecordsForSelectedTreeNode(true, false); } } } public int SelectedMonthIndex { get { return _SelectedMonthIndex; } set { if (AreDifferent(_SelectedMonthIndex, value)) { _SelectedMonthIndex = value; ServiceRecordTimeInterval = ServiceRecordTimeInterval.Monatsauswahl; BeWoApp.AppSettings.LastSelectedServiceRecordMonth = new DateTime(_SelectedYear, _SelectedMonthIndex + 1, 1); BeWoApp.SaveAppSettings(); BuildServiceRecordsForSelectedTreeNode(true, false); } } } public int SelectedYear { get { return _SelectedYear; } set { if (AreDifferent(_SelectedYear, value)) { _SelectedYear = value; ServiceRecordTimeInterval = ServiceRecordTimeInterval.Monatsauswahl; BeWoApp.AppSettings.LastSelectedServiceRecordMonth = new DateTime(_SelectedYear, _SelectedMonthIndex + 1, 1); BeWoApp.SaveAppSettings(); BuildServiceRecordsForSelectedTreeNode(true, false); } } } public List Statistics { get { return _Statistics; } set { _Statistics = value; FirePropertyChanged(PropertyName_Statistics); FirePropertyChanged("HasStatistics"); FirePropertyChanged("StatisticsButtonVisible"); FirePropertyChanged("OpenAiChatButtonVisible"); } } public bool HasStatistics { get { return _Statistics != null && _Statistics.Count > 0; } } public bool StatisticsButtonVisible { get { return BeWoApp.AppSettings.ShowHilfeplanStatistikReport && SelectedCustomerNode != null && SelectedCustomerNode.SupportConceptTreeNodeDC != null; } } public ServiceRecordTimeInterval ServiceRecordTimeInterval { get { return _ServiceRecordTimeInterval; } set { if (_ServiceRecordTimeInterval != value) { _ServiceRecordTimeInterval = value; BuildServiceRecordsForSelectedTreeNode(true, false); if (value != ServiceRecordTimeInterval.ZeitraumWaehlen) { BeWoApp.AppSettings.LastSelectedServiceRecordTimeInterval = value; BeWoApp.SaveAppSettings(); } FirePropertyChanged(PropertyName_ServiceRecordTimeInterval); } } } public ServiceRecordTypeId? OnlyWithThisType { get; set; } private bool _ShowOnlyAdditionalServiceRecords; public bool ShowOnlyAdditionalServiceRecords { get { return _ShowOnlyAdditionalServiceRecords; } set { if (_ShowOnlyAdditionalServiceRecords == value) return; _ShowOnlyAdditionalServiceRecords = value; if (_ShowOnlyAdditionalServiceRecords) { FilterServiceRecordsByType(ServiceRecordTypeId.AdditionalService); OnlyWithThisType = ServiceRecordTypeId.AdditionalService; } else { FilterServiceRecordsByType(null); OnlyWithThisType = null; } } } public bool ShowOnlyContentServiceRecords { get { return _ShowOnlyContentServiceRecords; } set { if (_ShowOnlyContentServiceRecords != value) { _ShowOnlyContentServiceRecords = value; if (_ShowOnlyContentServiceRecords) FilterServiceRecordsByType(ServiceRecordTypeId.Content); else FilterServiceRecordsByType(null); } } } private void FilterServiceRecordsByType(ServiceRecordTypeId? serviceRecordTypeId) { // Wird nur beim Klick auf Ergänzende Dienste ausgeführt. BuildServiceRecordsForTreeNode(_SelectedCustomerNode, false, serviceRecordTypeId); } public FlatSupportConceptTreeNodeDC SelectedCustomerNode { get { return _SelectedCustomerNode; } } public event EventHandler ServiceRecordListChanged; public ObservableSortCollection CustomerNodes { get { if (_CustomerNodes == null) { _CustomerNodes = new ObservableSortCollection(); _CustomerNodes.CollectionChanged += (s, e) => { if (e.OldItems != null && e.OldItems.Count > 0) { foreach (FlatSupportConceptTreeNodeDC iNode in e.OldItems) { iNode.IsCustomerWarningActive = false; iNode.CustomerWarning = null; } } FirePropertyChanged(PropertyName_Information); //this.CheckCustomerAbsenceTimes(); CheckEmployeeLabourTime(); }; } return _CustomerNodes; } set { if (AreDifferent(_CustomerNodes, value)) { _CustomerNodes = value; FirePropertyChanged(PropertyName_CustomerNodes); } } } public DispatcherObject DispatcherObject { get; set; } public bool IsCustomerWarningActive { get { return _IsCustomerWarningActive; } set { _IsCustomerWarningActive = value; FirePropertyChanged(PropertyName_IsCustomerWarningActive); } } public string CustomerWarning { get { return _CustomerWarning; } set { _CustomerWarning = value; FirePropertyChanged(PropertyName_CustomerWarning); } } public string Information { get { return string.Empty; } } public ServiceRecordVM PrototypeVM { get { if (_PrototypeVM == null) { _PrototypeVM = NewVM; _PrototypeVM.DauerEinheit = BeWoApp.AppSettings.LetzteZeiterfassungsDauer; _PrototypeVM.PropertyChanged += (s, e) => { if (e.PropertyName.Equals(ServiceRecordVM.PropertyName_Duration)) { FirePropertyChanged(PropertyName_Information); } CheckCustomerAbsenceTimes(); CheckEmployeeLabourTime(); }; } return _PrototypeVM; } } public string RecordCountInformationString { get { return _RecordCountInformationString; } } public ObservableCollection RecordingDays { get { if (_RecordingDays == null) { _RecordingDays = new ObservableCollection(); //this._RecordingDays.CollectionChanged += (s, e) => // { // this.CheckCustomerAbsenceTimes(); // this.CheckEmployeeLabourTime(); // }; } return _RecordingDays; } set { if (AreDifferent(_RecordingDays, value)) { _RecordingDays = value; FirePropertyChanged(PropertyName_RecordingDays); } } } public CompactEmployeeDC SelectedEmployee { get { return mSelectedEmployee; } set { mSelectedEmployee = value; } } //public ServiceRecordVM SelectedVMForEditing { get; set; } public BindingList ServiceRecordsForSelectedCustomer { get { return _ServiceRecordsForSelectedCustomer; } } //public List Tree { get; private set; } public bool WithoutClient { get; set; } protected override Comparison Comparison { get { return (x, y) => y.StartDate.CompareTo(x.StartDate); } } private DateTime? enddate; public void UndoAiAction() { if (_AiActionHistoryIndex <= 0) return; _AiActionHistoryIndex--; AktuellerDokutext = _AiActionHistory[_AiActionHistoryIndex]; } public void RedoAiAction() { if (_AiActionHistoryIndex >= _AiActionHistory.Count - 1) return; _AiActionHistoryIndex++; AktuellerDokutext = _AiActionHistory[_AiActionHistoryIndex]; } public void UndoEditAiAction() { if (_EditAiActionHistoryIndex <= 0) return; _EditAiActionHistoryIndex--; AktuellerEditDokutext = _EditAiActionHistory[_EditAiActionHistoryIndex]; } public void RedoEditAiAction() { if (_EditAiActionHistoryIndex >= _EditAiActionHistory.Count - 1) return; _EditAiActionHistoryIndex++; AktuellerEditDokutext = _EditAiActionHistory[_EditAiActionHistoryIndex]; } public List CreateFromPrototype() { var lResult = new List(); if (WithoutClient) { ServiceRecordVM lNewRecord = CreateNewVM(); lNewRecord.Employee = BeWoApp.LoggedOnUser.Employee; lNewRecord.Customer = null; lResult.Add(lNewRecord); } else { foreach (FlatSupportConceptTreeNodeDC iCustomerNode in _CustomerNodes) { ServiceRecordVM lNewRecord = CreateNewVM(); enddate = lNewRecord.EndDate; lNewRecord.ChoosenNode = iCustomerNode; //if (_PrototypeVM.Duration == 0) //{ // var minutes = enddate.Value.Subtract(_PrototypeVM.StartDate).TotalMinutes; // _PrototypeVM.Duration = (decimal)minutes; //} //lNewRecord.Duration = _PrototypeVM.Duration / _CustomerNodes.Count; //if(lNewRecord.Duration.HasValue) //{ // lNewRecord.RoundedDuration = lNewRecord.Duration.Value; //} lResult.Add(lNewRecord); } } // NewVM = null; // _PrototypeVM = null; FirePropertyChanged(PropertyName_PrototypeVM); return lResult; } public ServiceRecordVM CreateNewVM(ServiceRecordDC pDC) { ServiceRecordVM lNewRecord = CreateVM(pDC); return lNewRecord; } public List GetAbsencesTimeForDate(SupportConceptCostBearerRelDC relDc, DateTime dt) { if (_CostBearer2SupportConceptOid2BookingInfoDict.ContainsKey(relDc.CostBearer2SupportConceptOid.Value)) { SupportConceptTreeNodeDetailInfoDC info = _CostBearer2SupportConceptOid2BookingInfoDict[relDc.CostBearer2SupportConceptOid.Value]; if (info != null && info.CustomerAbsenceTimes != null) { return info.CustomerAbsenceTimes.Where( at => at.AbsenceSpan.ContainsDate(dt)).ToList(); } } return null; } //public List GetSupportConceptGoals(SupportConceptCostBearerRelDC relDc) //{ // List list = new List(); // if (this._CostBearer2SupportConceptOid2BookingInfoDict.ContainsKey(relDc.CostBearer2SupportConceptOid.Value)) // { // SupportConceptTreeNodeDetailInfoDC info = this._CostBearer2SupportConceptOid2BookingInfoDict[relDc.CostBearer2SupportConceptOid.Value]; // list = info.SupportConceptGoals; // } // return list; //} public void RefreshServiceRecordsForSelectedTreeNode(bool refreshGoalTree) { BuildServiceRecordsForSelectedTreeNode(false, refreshGoalTree); } internal void ChangeTreeItemSelection(FlatSupportConceptTreeNodeDC lClickedNode) { if (WithoutClient || _SelectedCustomerNode == null || lClickedNode.SupportConceptTreeNodeDC == null || _SelectedCustomerNode.SupportConceptTreeNodeDC == null || !_SelectedCustomerNode.SupportConceptTreeNodeDC.Customer.EqualsNullCheck( lClickedNode.SupportConceptTreeNodeDC.Customer) || !_SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConcept.EqualsNullCheck( lClickedNode.SupportConceptTreeNodeDC.SupportConcept) || !_SelectedCustomerNode.SupportConceptTreeNodeDC.CostBearer.EqualsNullCheck( lClickedNode.SupportConceptTreeNodeDC.CostBearer)) { _SelectedCustomerNode = lClickedNode; FirePropertyChanged(nameof(IsAiButtonVisible)); CustomerNodes.Clear(); if (lClickedNode != null) { CustomerNodes.Add(lClickedNode); } BuildServiceRecordsForSelectedTreeNode(false, true); } } protected override ServiceRecordVM CreateVM(ServiceRecordDC pDC) { return new ServiceRecordVM(pDC, _Category2Services, null, null); } private void AddServiceRecordToList(ServiceRecordDC dc, List goalCats, List goals, FlatSupportConceptTreeNodeDC selectedCustomerNode) { bool contained = false; InitNewDC(dc, selectedCustomerNode); // List contained = new List(); var groupVMs = new Dictionary(); foreach (ServiceRecordVM vm in VMList) { if (vm.GroupOid != null && vm.Customer != null) { string key = String.Format("{0}_{1}", vm.GroupOid.Value, vm.Customer.Oid.Value); if (!groupVMs.ContainsKey(key)) { groupVMs.Add(key, vm); } } } foreach (ServiceRecordVM vm in VMList) { if (vm.DataContract.ServiceRecordOid == dc.ServiceRecordOid) { contained = true; break; } if (dc.GroupOid != null && dc.Customer != null) { contained = true; string key = String.Format("{0}_{1}", dc.GroupOid.Value, dc.Customer.Oid.Value); if (groupVMs.ContainsKey(key)) { ServiceRecordVM groupVM = groupVMs[key]; // groupVM.RoundedDuration = groupVM.GroupRoundedDuration.Value; } else { var newVM = new ServiceRecordVM(dc, _Category2Services, goalCats, goals); SetDocTypes(newVM); // newVM.RoundedDuration = newVM.GroupRoundedDuration.Value; groupVMs.Add(key, newVM); // ###AddServiceRecord VMList.Add(newVM); } break; } } if (!contained) { // ###AddServiceRecord var newVM = new ServiceRecordVM(dc, _Category2Services, goalCats, goals); SetDocTypes(newVM); if (dc.GroupOid != null) { // newVM.RoundedDuration = newVM.GroupRoundedDuration.Value; } VMList.Add(newVM); } } private void SetDocTypes(ServiceRecordVM newVM) { if (AllDocTypes != null) { if (AllDocTypes.Count > 0) { newVM.DocField1 = AllDocTypes[0].TypeDescription; } if (AllDocTypes.Count > 1) { newVM.DocField2 = AllDocTypes[1].TypeDescription; } if (AllDocTypes.Count > 2) { newVM.DocField3 = AllDocTypes[2].TypeDescription; } if (AllDocTypes.Count > 3) { newVM.DocField4 = AllDocTypes[3].TypeDescription; } if (AllDocTypes.Count > 4) { newVM.DocField5 = AllDocTypes[4].TypeDescription; } } } private static void InitNewDC(ServiceRecordDC newDc, FlatSupportConceptTreeNodeDC selectedCustomerNode) { if (selectedCustomerNode != null && selectedCustomerNode.SupportConceptTreeNodeDC != null) { newDc.Customer = selectedCustomerNode.SupportConceptTreeNodeDC.Customer; //dc.Customer = new CompactCustomerDC(); //dc.Customer.CustomerOid = cust.Oid.Value; //dc.Customer.CustomerVersion = cust.Version.Value; //dc.Customer.FirstName = cust.Person.FirstName; //dc.Customer.LastName = cust.Person.LastName; newDc.SupportConcept = selectedCustomerNode.SupportConceptTreeNodeDC.SupportConcept; if (selectedCustomerNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC != null) { newDc.CostBearer2SupportConceptOid = selectedCustomerNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC. CostBearer2SupportConceptOid; newDc.CostBearer = selectedCustomerNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.CostBearer; } //if (sr.SupportConcept != null) //{ // dc.SupportConcept = new CompactSupportConceptDC(); // dc.SupportConcept.SupportConceptOid = sr.SupportConcept.Oid.Value; // dc.SupportConcept.SupportConceptVersion = sr.SupportConcept.Version.Value; // dc.SupportConcept.Customer = dc.Customer; // dc.SupportConcept.ActivationType = sr.SupportConcept.IsActive; // dc.SupportConcept.ConferenceDate = sr.SupportConcept.ConferenceDate; //} //Costbearer ----------------- //if (sr.CostBearer2SupportConcept != null) //{ // dc.CostBearer2SupportConceptOid = sr.CostBearer2SupportConcept.Oid.Value; // if (dc.SupportConcept != null) // { // CompactCostBearerDC costBearer = new CompactCostBearerDC(); // if (sr.CostBearer2SupportConcept.CostBearer.Organisation != null) // { // CompactOrganisationDC orgDC = new CompactOrganisationDC(); // orgDC.Name = sr.CostBearer2SupportConcept.CostBearer.Organisation.Name; // orgDC.OrganisationOid = sr.CostBearer2SupportConcept.CostBearer.Organisation.Oid.Value; // orgDC.CostBearerOid = sr.CostBearer2SupportConcept.CostBearer.Oid; // dc.CostBearer = orgDC; // costBearer.Organisation = orgDC; // } // costBearer.CostBearerOid = sr.CostBearer2SupportConcept.CostBearer.Oid.Value; // costBearer.CostBearer2SupportConceptOid = sr.CostBearer2SupportConcept.Oid.Value; // costBearer.SupportConceptStatus = sr.CostBearer2SupportConcept.Status; // costBearer.RequestedStartDate = sr.CostBearer2SupportConcept.RequestedStartDate; // costBearer.RequestedEndDate = sr.CostBearer2SupportConcept.RequestedEndDate; // costBearer.ApprovedStartDate = sr.CostBearer2SupportConcept.ApprovedStartDate; // costBearer.ApprovedEndDate = sr.CostBearer2SupportConcept.ApprovedEndDate; // costBearer.CustomerReferenceNumber = sr.CostBearer2SupportConcept.CustomerReferenceNumber; // costBearer.IsCalculatingWithFactor = sr.CostBearer2SupportConcept.CostBearer.IsCalculatingWithFactor; // dc.SupportConcept.CostBearerList.Add(costBearer); // dc.SupportConcept.CustomerReferenceNumbers.Add(sr.CostBearer2SupportConcept.CustomerReferenceNumber); // dc.SupportConcept.CostBearerRelOids.Add(sr.CostBearer2SupportConcept.Oid.Value); // } // if (dc.CostBearer == null) // { // if (sr.CostBearer2SupportConcept.CostBearer.Organisation != null) // dc.CostBearer = MapperFactory.CompactOrganisationDC_Organisation.MapToNewDC(sr.CostBearer2SupportConcept.CostBearer.Organisation); // } //} } } public void BuildServiceRecordsForSelectedTreeNode(bool forceRefreshServiceRecords, bool changeGoalTree) { BuildServiceRecordsForSelectedTreeNode(forceRefreshServiceRecords, changeGoalTree, null); } public void BuildServiceRecordsForSelectedTreeNode(bool forceRefreshServiceRecords, bool changeGoalTree, Action refreshFinishedCallback) { long? days = 0; DateTime start = DateTime.MinValue; DateTime end = DateTime.MaxValue; switch (ServiceRecordTimeInterval) { case ServiceRecordTimeInterval.All: days = null; break; case ServiceRecordTimeInterval.LastWeek: days = 7; break; case ServiceRecordTimeInterval.LastMonth: days = 30; break; case ServiceRecordTimeInterval.Last3Month: days = 90; break; case ServiceRecordTimeInterval.XTage: days = _XTage; break; case ServiceRecordTimeInterval.ZeitraumWaehlen: start = XTageVon.Value; end = XTageBis.Value; break; case ServiceRecordTimeInterval.Monatsauswahl: if (SelectedYear > 0) { start = new DateTime(SelectedYear, SelectedMonthIndex + 1, 1); end = start.AddMonths(1).AddDays(-1); } break; } if (WithoutClient) { var emp = mSelectedEmployee ?? BeWoApp.LoggedOnUser.Employee; PrototypeVM.UpdateServiceAccountings(null, _Category2Services, false); if (DispatcherObject != null && (!days.HasValue || days.Value > 0)) { ServiceFacade.DoOperationsServiceAsync(s => s.GetEmployeesServiceRecords2(emp.EmployeeOid, days), r => DispatcherObject.Dispatch(delegate { PrepareListVM(r, null, null, null, null, true, null); })); } else if (DispatcherObject != null) { ServiceFacade.DoOperationsServiceAsync(s => s.GetEmployeesServiceRecordsWithStartEndDate(emp.EmployeeOid, start, end), r => DispatcherObject.Dispatch(delegate { PrepareListVM(r, null, null, null, null, true, null); })); } else { BuildServiceRecordsForTreeNode(null, true, null); } PrototypeVM.ChangeGoalTree(null, null); } else { if (_SelectedCustomerNode != null) { if (_SelectedCustomerNode.SupportConceptTreeNodeDC == null) { //Gruppen- oder Mehrfachbuchung PrototypeVM.UpdateServiceAccountings(null, _Category2Services, true); BuildServiceRecordsForTreeNode(_SelectedCustomerNode, true, OnlyWithThisType); } else { var customer = _SelectedCustomerNode.SupportConceptTreeNodeDC.Customer; if (customer != null) { var scDC = _SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConcept; List goalCats = null; List goals = null; var cb2scOid = _SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid.Value; if (_CostBearer2SupportConceptOid2BookingInfoDict.ContainsKey(cb2scOid)) { _CostBearer2SupportConceptOid2BookingInfoDict.Remove(cb2scOid); } long? scOidForGoals = scDC.SupportConceptOid; var infoDC = ServiceFacade.DoOperationsServiceSync(s => s.GetSupportConceptTreeNodeDetailInfo(customer.CustomerOid, scOidForGoals, cb2scOid)); _CostBearer2SupportConceptOid2BookingInfoDict.Add(cb2scOid, infoDC); if (infoDC != null && infoDC.SupportConceptGoals != null && infoDC.SupportConceptGoals.Count > 0) { goalCats = new List(); goals = new List(); var goalCategoryDict = _AllGoalCategories.ToDictionary(goalCat => goalCat.ValueListEntryOid.Value); foreach (var goal in infoDC.SupportConceptGoals) { if (goal.ParentOid != null && goalCategoryDict.ContainsKey(goal.ParentOid.Value)) { var path = GetAllParentGoalCategoies(goalCategoryDict, goal); foreach (var goalCat in path) { goalCats.Add(goalCat); goalCategoryDict.Remove(goalCat.ValueListEntryOid.Value); } } goals.Add(goal); } } if (infoDC != null) { _SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.ApprovalPeriodList = infoDC.ApprovalPeriods; if (!IsGroupBooking && !IsMultiBooking) { PrototypeVM.UpdateServiceAccountings(infoDC.ServiceAccountings, _Category2Services, true); } } if (DispatcherObject != null && (!days.HasValue || days.Value > 0)) { ServiceFacade.DoOperationsServiceAsync( s => s.GetCustomerServiceRecordsCompact(customer.CustomerOid, cb2scOid, days), r => DispatcherObject.Dispatch(delegate { PrepareListVM(r, goalCats, goals, _SelectedCustomerNode, refreshFinishedCallback, true, OnlyWithThisType); })); } else if (DispatcherObject != null) { ServiceFacade.DoOperationsServiceAsync( s => s.GetCustomerServiceRecordsCompactWithStartEndDate(customer.CustomerOid, cb2scOid, start, end), r => DispatcherObject.Dispatch(delegate { PrepareListVM(r, goalCats, goals, _SelectedCustomerNode, refreshFinishedCallback, true, OnlyWithThisType); })); } if (changeGoalTree) { var copyGoalCats = GoalService.CopyGoals(goalCats, false); var copyGoals = GoalService.CopyGoals(goals, false); PrototypeVM.ChangeGoalTree(copyGoalCats, copyGoals); } } } } } } private void PrepareListVM(IEnumerable pServiceRecords, List pGoalCats, List pGoals, FlatSupportConceptTreeNodeDC pSelectedCustomerNode, Action pRefreshFinishedCallback, bool pShouldFetchStatistics, ServiceRecordTypeId? pOnlyWithThisType) { VMList.Clear(); foreach (var dc in pServiceRecords) { AddServiceRecordToList(dc, pGoalCats, pGoals, pSelectedCustomerNode); } BuildServiceRecordsForTreeNode(pSelectedCustomerNode, pShouldFetchStatistics, pOnlyWithThisType); if (pRefreshFinishedCallback != null) { pRefreshFinishedCallback(); } } public static IEnumerable GetAllParentGoalCategoies(Dictionary goalCategoryDict, ValueListEntryDC goal) { IList path = new List(); if (goal.ParentOid.HasValue && goalCategoryDict.ContainsKey(goal.ParentOid.Value)) { ValueListEntryDC parentCat = goalCategoryDict[goal.ParentOid.Value]; while (parentCat != null) { path.Add(parentCat); if (parentCat.ParentOid.HasValue && goalCategoryDict.ContainsKey(parentCat.ParentOid.Value)) { parentCat = goalCategoryDict[parentCat.ParentOid.Value]; } else { parentCat = null; } } } return path; } private List Parents; public void GetGoalParents(ValueListEntryDC child, Dictionary possibleParents) { while (true) { if (child.ParentOid != null && possibleParents.ContainsKey(child.ParentOid.Value) && !Parents.Contains(possibleParents[child.ParentOid.Value])) { Parents.Add(possibleParents[child.ParentOid.Value]); child = possibleParents[child.ParentOid.Value]; continue; } break; } } private void BuildServiceRecordsForTreeNode(FlatSupportConceptTreeNodeDC treeNode, bool fetchStatistics, ServiceRecordTypeId? onlyWithThisType) { _ServiceRecordsForSelectedCustomer.Clear(); if (fetchStatistics) Statistics = null; bool isTypeZeitraumWaehlen = false; if (WithoutClient || (treeNode != null && treeNode.SupportConceptTreeNodeDC != null)) { SupportConceptCostBearerRelDC relDC = null; if (!WithoutClient) { relDC = treeNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC; } Func f; if (WithoutClient) { CompactEmployeeDC emp = SelectedEmployee ?? BeWoApp.LoggedOnUser.Employee; f = vm => (vm.Customer == null || vm.SupportConcept == null || vm.CostBearer == null) && emp.Equals(vm.Employee) && (!onlyWithThisType.HasValue || onlyWithThisType.HasValue && vm.ServiceRecordType == onlyWithThisType.Value); } else { if (treeNode.SupportConceptTreeNodeDC.CostBearer != null) { f = vm => treeNode.SupportConceptTreeNodeDC.Customer.Equals(vm.Customer) && treeNode.SupportConceptTreeNodeDC.SupportConcept.Equals(vm.SupportConcept) && treeNode.SupportConceptTreeNodeDC.CostBearer.Equals(vm.CostBearer) && (!onlyWithThisType.HasValue /*&& vm.ServiceRecordType != ServiceRecordTypeId.AdditionalService*/|| onlyWithThisType.HasValue && vm.ServiceRecordType == onlyWithThisType.Value); } else if (treeNode.SupportConceptTreeNodeDC.SupportConcept != null) { f = vm => treeNode.SupportConceptTreeNodeDC.Customer.Equals(vm.Customer) && treeNode.SupportConceptTreeNodeDC.SupportConcept.Equals(vm.SupportConcept) && (!onlyWithThisType.HasValue /* && vm.ServiceRecordType != ServiceRecordTypeId.AdditionalService */|| onlyWithThisType.HasValue && vm.ServiceRecordType == onlyWithThisType.Value); } else { f = vm => treeNode.SupportConceptTreeNodeDC.Customer.Equals(vm.Customer) && (!onlyWithThisType.HasValue /* && vm.ServiceRecordType != ServiceRecordTypeId.AdditionalService */|| onlyWithThisType.HasValue && vm.ServiceRecordType == onlyWithThisType.Value); } } //var recordsUpToDate = ServiceFacade.DoOperationsServiceSync(s => s.GetCustomerServiceRecords(treeNode.SupportConceptTreeNodeDC.Customer.Oid.Value, false)); //VMList.Clear(); //foreach (var record in recordsUpToDate.Where(r => // r.SupportConcept.SupportConceptOid.Equals(treeNode.SupportConceptTreeNodeDC.SupportConcept.SupportConceptOid) && // r.CostBearer2SupportConceptOid.Value.Equals(treeNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid.Value))) //{ // if (record.GroupOid.HasValue && VMList.Any(x => x.GroupOid.HasValue && x.GroupOid.Equals(record.GroupOid))) // continue; // VMList.Add(CreateVM(record)); //} foreach (ServiceRecordVM vm in VMList.Where(f)) { long? days = null; switch (ServiceRecordTimeInterval) { case ServiceRecordTimeInterval.LastWeek: days = 7; break; case ServiceRecordTimeInterval.LastMonth: days = 30; break; case ServiceRecordTimeInterval.Last3Month: days = 90; break; case ServiceRecordTimeInterval.XTage: days = _XTage; break; //case ServiceRecordTimeInterval.ZeitraumWaehlen: // //zu test zwecken // var x = XTageBis.Value.Date - XTageVon.Value.Date; // days = (long)x.TotalDays; // isTypeZeitraumWaehlen = true; // break; } DateTime minDate = DateTime.MinValue; if (days.HasValue) { minDate = DateTime.Now.Date.AddDays(-1 * days.Value); } if (vm.StartDate >= minDate) _ServiceRecordsForSelectedCustomer.Add(vm); } if (!WithoutClient && relDC != null && isTypeZeitraumWaehlen == false) { if (fetchStatistics) { //DateTime stichtag = new DateTime(2021, 8, 15); DateTime stichtag = DateTime.Now; ServiceFacade.DoOperationsServiceAsync( s1 => s1.GetServiceRecordStatisticInfo(relDC.CostBearer2SupportConceptOid.Value, stichtag), stinf => ServiceFacade.DoOperationsServiceAsync( s => s.CreateSupportConceptStatistics(relDC.CostBearer2SupportConceptOid.Value, stichtag), r => DispatcherObject.Dispatch(delegate { StatisticsDC = r; RecordStatisticsDC = stinf; if (stinf != null && StatisticInfosLoaded != null) { StatisticInfosLoaded(stinf, new EventArgs()); } else { Statistics = CreateStatisticVMList(r); } }), false)); } } } //ErstelleRecordInformationString(_ServiceRecordsForSelectedCustomer); FirePropertyChanged(PropertyName_ServiceRecordsForSelectedCustomer); if (ServiceRecordListChanged != null) { ServiceRecordListChanged(this, new EventArgs()); } } public void ErstelleRecordInformationString(IList records) { if (records == null) { _RecordCountInformationString = null; } else { decimal minuten = 0; foreach (var sr in records) { minuten += sr.RoundedDuration; } _RecordCountInformationString = String.Format("Anzahl Einträge: {0}, Summe Minuten: {1:0.##} entspricht {2:0.00} Stunden", records.Count, minuten, minuten / 60); } FirePropertyChanged(PropertyName_RecordCountInformationString); } private static List CreateStatisticVMList(SupportConceptStatisticsDC statisticsDc) { var stats = new List(); if (statisticsDc != null) { if (statisticsDc.PeriodStatistics.Count > 1 && !TimeSpanIsEqual(statisticsDc)) stats.Add(CreateTotalStatisticsVM(statisticsDc)); foreach (SupportConceptPeriodStatisticsDC dc in statisticsDc.PeriodStatistics) { bool showOutOfPeriod = statisticsDc.PeriodStatistics.Count == 1; stats.Add(CreateStatisticsVM(statisticsDc, dc, showOutOfPeriod)); } } return stats; } public static SupportConceptPeriodStatisticsVM CreateTotalStatisticsVM(SupportConceptStatisticsDC dc) { int unitDividend = 60; var vm = new SupportConceptPeriodStatisticsVM(); vm.Header = "Gesamt"; String tenant = BeWoApp.Tenant; #if DEBUG //tenant = "3057313346"; #endif if (tenant == "3057313346" || tenant == "2918696314") { unitDividend = 1; vm.StatisticInfo1Left = String.Format("{0:0.00}", dc.MinutesProvidedThisWeek / unitDividend); vm.StatisticInfo1Right = String.Format("{0:0.00}", dc.MinutesProvidedTotalRounded / unitDividend); vm.StatisticInfo2Left = String.Format("{0:0.00}", dc.MinutesApprovedPerWeek / unitDividend); vm.StatisticInfo2Right = String.Format("{0:0.00}", dc.MinutesApprovedTotal / unitDividend); vm.StatisticInfo3Left = String.Format("{0:0.00}", dc.MinutesFreePerWeekAverage / unitDividend); vm.StatisticInfo3Right = String.Format("{0:0.00}", (dc.MinutesApprovedTotal - dc.MinutesProvidedTotalRounded) / unitDividend); vm.StatisticInfo4Left = String.Format("{0:0.00}", dc.MinutesProvidedThisMonth / unitDividend); vm.StatisticInfo4Right = String.Format("{0:0.00}", dc.MinutesApprovedPerMonth / unitDividend); vm.StatisticInfo5Left = String.Format("{0:0.00}", dc.SollTotalUntilThisMonth / unitDividend); vm.StatisticInfo5Right = String.Format("{0:0.00}", dc.IstTotalUntilThisMonth / unitDividend); } else { vm.StatisticInfo1Left = String.Format("{0:0.00}", dc.MinutesProvidedThisWeek / unitDividend); vm.StatisticInfo1Right = String.Format("{0:0.00}", dc.MinutesProvidedTotalRounded / unitDividend); vm.StatisticInfo2Left = String.Format("{0:0.00}", dc.MinutesApprovedPerWeek / unitDividend); vm.StatisticInfo2Right = String.Format("{0:0.00}", dc.MinutesApprovedTotal / unitDividend); vm.StatisticInfo3Left = String.Format("{0:0.00}", dc.MinutesFreePerWeekAverage / unitDividend); vm.StatisticInfo3Right = String.Format("{0:0.00}", (dc.MinutesApprovedTotal - dc.MinutesProvidedTotalRounded) / unitDividend); decimal schwellwert = dc.MinutesApprovedTotal * (BeWoApp.AppSettings.ZeiterfassungsSchwellwert / 100m); decimal free = dc.MinutesApprovedTotal - dc.MinutesProvidedTotalRounded; decimal prozent = 0; if (dc.MinutesApprovedTotal != 0) { prozent = (free / dc.MinutesApprovedTotal) * 100; } if (dc.MinutesProvidedTotalRounded > schwellwert) { vm.StatisticInfo3ForegroundColor = Brushes.Red; if (free >= 0) { vm.StatisticInfo3Tooltip = String.Format( "Es stehen nur noch {0:0.##} % der bewilligten Gesamtstunden zur Verfügung.\nSie können den Schwellwert für diese Anzeige in der Verwaltung ändern.", prozent); } else { vm.StatisticInfo3Tooltip = String.Format( "Die bewilligten Gesamtstunden wurden um {0:0.##} % überschritten.\nSie können den Schwellwert für diese Anzeige in der Verwaltung ändern.", prozent * -1m); } } else { vm.StatisticInfo3ForegroundColor = Brushes.Green; vm.StatisticInfo3Tooltip = String.Format( "Es stehen noch {0:0.##} % der bewilligten Gesamtstunden zur Verfügung.\nSie können den Schwellwert für diese Anzeige in der Verwaltung ändern.", prozent); } } vm.MinutesProvidedTotalRounded = dc.MinutesProvidedTotalRounded; return vm; } public static SupportConceptPeriodStatisticsVM CreateStatisticsVM(SupportConceptStatisticsDC stats, SupportConceptPeriodStatisticsDC periodStats, bool showOutOfPeriod) { int unitDividend = 60; var vm = new SupportConceptPeriodStatisticsVM(); if (periodStats.SupportConceptApprovalPeriod != null) { if (periodStats.SupportConceptApprovalPeriod.ServiceCategory != null) { if (periodStats.SupportConceptApprovalPeriod.StartDate.HasValue && periodStats.SupportConceptApprovalPeriod.EndDate.HasValue && periodStats.SupportConceptApprovalPeriod.StartDate.Value.Date == stats.StatisticsStartDate.Date && periodStats.SupportConceptApprovalPeriod.EndDate.Value.Date == stats.StatisticsEndDate.Date && !showOutOfPeriod) { vm.Header = periodStats.SupportConceptApprovalPeriod.ServiceCategory.Name; } else { vm.Header = String.Format("{0}: {1:dd.MM.yy} - {2:dd.MM.yy}", periodStats.SupportConceptApprovalPeriod.ServiceCategory.Name, periodStats.SupportConceptApprovalPeriod.StartDate, periodStats.SupportConceptApprovalPeriod.EndDate); } } else { vm.Header = String.Format("{0:dd.MM.yy} - {1:dd.MM.yy}", periodStats.SupportConceptApprovalPeriod.StartDate, periodStats.SupportConceptApprovalPeriod.EndDate); } } String tenant = BeWoApp.Tenant; #if DEBUG //tenant = "3057313346"; #endif if (tenant == "3057313346" || tenant == "2918696314") { unitDividend = 1; vm.StatisticInfo1Left = String.Format("{0:0.00}", periodStats.MinutesProvidedTotalRounded / unitDividend); vm.StatisticInfo1Right = String.Format("{0:0.00}", periodStats.MinutesApprovedTotal / unitDividend); vm.StatisticInfo2Left = String.Format("{0:0.00}", periodStats.MinutesProvidedThisWeek / unitDividend); vm.StatisticInfo2Right = String.Format("{0:0.00}", periodStats.MinutesApprovedPerWeek / unitDividend); vm.StatisticInfo3Left = String.Format("{0:0.00}", periodStats.MinutesProvidedThisMonth / unitDividend); vm.StatisticInfo3Right = String.Format("{0:0.00}", periodStats.MinutesApprovedPerMonth / unitDividend); vm.StatisticInfo4Left = String.Format("{0:0.00}", (periodStats.SollTotalUntilThisMonth - periodStats.IstTotalUntilThisMonth) / unitDividend); } else { vm.StatisticInfo1Left = String.Format("{0:0.00}", periodStats.MinutesProvidedThisWeek / unitDividend); vm.StatisticInfo1Right = String.Format("{0:0.00}", periodStats.MinutesProvidedTotalRounded / unitDividend); vm.StatisticInfo2Left = String.Format("{0:0.00}", periodStats.MinutesApprovedPerWeek / unitDividend); vm.StatisticInfo2Right = String.Format("{0:0.00}", periodStats.MinutesApprovedTotal / unitDividend); vm.StatisticInfo3Left = String.Format("{0:0.00}", periodStats.MinutesFreePerWeek / unitDividend); vm.StatisticInfo3Right = String.Format("{0:0.00}", (periodStats.MinutesApprovedTotal - periodStats.MinutesProvidedTotalRounded) / unitDividend); decimal schwellwert = periodStats.MinutesApprovedTotal * (BeWoApp.AppSettings.ZeiterfassungsSchwellwert / 100m); decimal free = periodStats.MinutesApprovedTotal - periodStats.MinutesProvidedTotalRounded; decimal prozent = 0; if (periodStats.MinutesApprovedTotal != 0) { prozent = (free / periodStats.MinutesApprovedTotal) * 100; } if (periodStats.MinutesProvidedTotalRounded > schwellwert) { vm.StatisticInfo3ForegroundColor = Brushes.Red; if (free >= 0) { vm.StatisticInfo3Tooltip = String.Format( "Es stehen nur noch {0:0.##} % der bewilligten Gesamtstunden zur Verfügung.\nSie können den Schwellwert für diese Anzeige in der Verwaltung ändern.", prozent); } else { vm.StatisticInfo3Tooltip = String.Format( "Die bewilligten Gesamtstunden wurden um {0:0.##} % überschritten.\nSie können den Schwellwert für diese Anzeige in der Verwaltung ändern.", prozent * -1m); } } else { vm.StatisticInfo3ForegroundColor = Brushes.Green; vm.StatisticInfo3Tooltip = String.Format( "Es stehen noch {0:0.##} % der bewilligten Gesamtstunden zur Verfügung.\nSie können den Schwellwert für diese Anzeige in der Verwaltung ändern.", prozent); } } if (showOutOfPeriod && stats.MinutesOutOfApprovedPeriod > 0) vm.StatisticInfo1Error = String.Format(" {0:0.00}", stats.MinutesOutOfApprovedPeriod / 60); vm.MinutesProvidedTotalRounded = periodStats.MinutesProvidedTotalRounded; return vm; } private static bool TimeSpanIsEqual(SupportConceptStatisticsDC r) { if (r.PeriodStatistics != null && r.PeriodStatistics.Count > 1) { for (int i = 0; i < r.PeriodStatistics.Count - 1; i++) { SupportConceptPeriodStatisticsDC p1 = r.PeriodStatistics[i]; if (p1.SupportConceptApprovalPeriod.StartDate.HasValue && p1.SupportConceptApprovalPeriod.EndDate.HasValue) { for (int j = i + 1; j < r.PeriodStatistics.Count; j++) { SupportConceptPeriodStatisticsDC p2 = r.PeriodStatistics[j]; if (p2.SupportConceptApprovalPeriod.StartDate.HasValue && p2.SupportConceptApprovalPeriod.EndDate.HasValue) { if ((p1.SupportConceptApprovalPeriod.StartDate.Value.Date != p2.SupportConceptApprovalPeriod.StartDate.Value.Date) || (p1.SupportConceptApprovalPeriod.EndDate.Value.Date != p2.SupportConceptApprovalPeriod.EndDate.Value.Date)) return false; } } } } } return true; } private decimal CalculateDurationSum(FlatSupportConceptTreeNodeDC pCustomerNode) { decimal lResult = 0m; if (_PrototypeVM.Duration > 0) { lResult = Convert.ToDecimal(_PrototypeVM.RoundedDuration) / _CustomerNodes.Count; if (_PrototypeVM.ServiceDescription != null && _PrototypeVM.ServiceDescription.Category != null && _PrototypeVM.ServiceDescription.Category.IsBillable && pCustomerNode.SupportConceptTreeNodeDC.CostBearer != null) { int mi = pCustomerNode.SupportConceptTreeNodeDC.CostBearer.ActualMinuteIntervall; if (mi > 0) { lResult = lResult % mi != 0 ? lResult + (mi - (lResult % mi)) : lResult; } } } return lResult; // *this.GetBookingDates().Count(); } private void CheckCustomerAbsenceTimes() { IsCustomerWarningActive = false; if (!WithoutClient) { if (CustomerNodes != null) { foreach (FlatSupportConceptTreeNodeDC iCustomerNode in CustomerNodes) { if (iCustomerNode.SupportConceptTreeNodeDC != null && iCustomerNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC != null) { List atList = GetAbsencesTimeForDate( iCustomerNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC, PrototypeVM.StartDate); if (atList != null && atList.Count > 0) { IsCustomerWarningActive = true; CustomerWarning = ""; AbsenceTimeDC atCurrent = null; foreach (AbsenceTimeDC at in atList) { if (CustomerWarning.Length > 0) CustomerWarning += "\n"; CustomerWarning += String.Format("{0} von {1:d} bis {2}", at.Reason.Description, at.Start, at.End.HasValue ? String.Format("{0:d}", at.End) : "unbekannt"); if (at.Reason.BillableMinutes.HasValue && at.Reason.BillableMinutes.Value > 0) atCurrent = at; } if (atCurrent != null) { DateTimeSpan week = null; decimal maxBillableMinutes = atCurrent.Reason.BillableMinutes.Value; IEnumerable lAbsenceWeeks = atCurrent.AbsenceSpan.GetWholeWeeks(); foreach (DateTimeSpan lAbsenceWeek in lAbsenceWeeks) { if (PrototypeVM.StartDate.InBetween(lAbsenceWeek, true)) { week = lAbsenceWeek; } } //iCustomerNode.IsCustomerWarningActive = false; //iCustomerNode.CustomerWarning = null; DateTime start = atCurrent.Start.Value.Date; DateTime end = atCurrent.End.HasValue ? atCurrent.End.Value.Date : DateTime.MaxValue; if (week != null) { decimal lExisitingFLMInAbsenceWeek = VMList.Where( sr => sr.Customer != null && sr.Customer.Equals(iCustomerNode.SupportConceptTreeNodeDC.Customer) && sr.ServiceDescription != null && sr.ServiceDescription.Category.IsBillable && sr.StartDate.InBetween(week, true) && sr.StartDate.Date != start && sr.StartDate.Date != end) .Sum(sr => sr.RoundedDuration); //decimal lNewFLMInAbsenceWeek = CalculateDurationSum(iCustomerNode); //if (lExisitingFLMInAbsenceWeek + lNewFLMInAbsenceWeek > lAbsenceWeek.Value) //{ //iCustomerNode.IsCustomerWarningActive = true; CustomerWarning += "\nAbrechenbar in dieser Woche: " + maxBillableMinutes + " Minuten\nBereits geleistet: " + BeWoWpfUtils.GetDecimalValueWithMaxDecimal(lExisitingFLMInAbsenceWeek, 2) + " Minuten"; //" Minuten\nNeue Buchung(en) in der Maske: " + BeWoWpfUtils.GetDecimalValueWithMaxDecimal(lNewFLMInAbsenceWeek, 2) + " Minuten" + decimal notBillableMinutes = BeWoWpfUtils.GetDecimalValueWithMaxDecimal( -(maxBillableMinutes - (lExisitingFLMInAbsenceWeek)), 2) ?? 0; if (notBillableMinutes > 0) { CustomerWarning += "\nEs werden " + notBillableMinutes + " Minuten verfallen"; } } } } } } } } } private static void CheckEmployeeLabourTime() { } private ServiceRecordVM CreateNewVM() { ServiceRecordVM lNewRecord = _PrototypeVM.Clone(); //lNewRecord.Date = _PrototypeVM.Date; //lNewRecord.Duration = _PrototypeVM.Duration; //if (_PrototypeVM.Duration.HasValue) //lNewRecord.RoundedDuration = _PrototypeVM.Duration.Value; lNewRecord.SetInsertedOn(DateTime.Now); lNewRecord.InsUser = BeWoApp.LoggedOnUser.Employee.FirstName + " " + BeWoApp.LoggedOnUser.Employee.LastName; //lNewRecord.ServiceRecordType = this._PrototypeVM.ServiceRecordType; return lNewRecord; } //private List GetBookingDates() //{ // if (this._PrototypeVM != null && this._PrototypeVM.Date != null && this._RecordingDays != null) // { // return this._RecordingDays.Select(d => this._PrototypeVM.Date.Value.GetInSameCalendarWeek(d)).ToList(); // } // return new List(); //} public bool IsGroupBooking { get; set; } public bool IsMultiBooking { get; set; } internal decimal GetFLSTotal(ServiceRecordVM vm) { if (Statistics != null && Statistics.Count > 0) { return Statistics[0].MinutesProvidedTotalRounded / 60; } return 0; } public ServiceRecordStatisticsInfoDC RecordStatisticsDC { get; set; } public SupportConceptStatisticsDC StatisticsDC { get; set; } internal static GroupDurationDC CalculateGroupDuration(int personCount, int employeeCount, decimal totalDuration, List costBearer2SupportConceptList) { return ServiceFacade.DoOperationsServiceSync(s => s.CalculateGroupDuration2(personCount, employeeCount, totalDuration, costBearer2SupportConceptList)); } public void InitPrototypeVM(long customerOid, long? supportConceptOid, long? cb2scOid) { var infoDC = ServiceFacade.DoOperationsServiceSync(s => s.GetSupportConceptTreeNodeDetailInfo(customerOid, supportConceptOid, cb2scOid)); if (infoDC != null && infoDC.SupportConceptGoals != null && infoDC.SupportConceptGoals.Count > 0) { var goalCats = new List(); var goals = new List(); var goalCategoryDict = _AllGoalCategories.ToDictionary(goalCat => goalCat.ValueListEntryOid.Value); foreach (var goal in infoDC.SupportConceptGoals) { if (goal.ParentOid != null && goalCategoryDict.ContainsKey(goal.ParentOid.Value)) { var path = GetAllParentGoalCategoies(goalCategoryDict, goal); foreach (var goalCat in path) { goalCats.Add(goalCat); goalCategoryDict.Remove(goalCat.ValueListEntryOid.Value); } } goals.Add(goal); } PrototypeVM.ChangeGoalTree(goalCats, goals); } if (infoDC != null) { //_SelectedCustomerNode.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.ApprovalPeriodList = infoDC.ApprovalPeriods; if (!IsGroupBooking && !IsMultiBooking) { PrototypeVM.UpdateServiceAccountings(infoDC.ServiceAccountings, _Category2Services, true); } } } internal void UpdateGroupServiceAccountings(IList data) { if (data != null) { var oids = new List(); foreach (var item in data) { oids.Add(item.SupportConceptOid); } var allInfos = ServiceFacade.DoOperationsServiceSync(s => s.GetSupportConceptTreeNodeDetailInfos(oids)); UpdateGruppenZiele(allInfos); if (BeWoApp.AppSettings.FilterGroupServiceCategories) { var serviceAccountings = ErstelleServiceCategorySchnittmenge(allInfos); PrototypeVM.UpdateServiceAccountings(serviceAccountings, _Category2Services, true); } } } private void UpdateGruppenZiele(List allInfos) { if (allInfos != null && _AllGoalCategories != null) { var goalCats = new List(); var goals = new List(); var goalCategoryDict = _AllGoalCategories.ToDictionary(goalCat => goalCat.ValueListEntryOid.Value); foreach (var info in allInfos) { foreach (var goal in info.SupportConceptGoals) { goal.Prefix = info.CustomerName; if (goal.ParentOid != null && goalCategoryDict.ContainsKey(goal.ParentOid.Value)) { var path = GetAllParentGoalCategoies(goalCategoryDict, goal); foreach (var goalCat in path) { goalCats.Add(goalCat); goalCategoryDict.Remove(goalCat.ValueListEntryOid.Value); } } goals.Add(goal); } } PrototypeVM.ChangeGoalTree(goalCats, goals); } } private List ErstelleServiceCategorySchnittmenge(List allInfos) { if (allInfos.Count == 0) { return null; } else if (allInfos.Count == 1) { return allInfos[0].ServiceAccountings; } var schnittmenge = new List(); foreach (var info in allInfos) { if (info.ServiceAccountings != null && info.ServiceAccountings.Count == 0 && _Category2Services != null) { foreach (var cat in _Category2Services.Keys) { if (!cat.OhneHilfeplan.HasValue || (cat.OhneHilfeplan.Value != AccountingvisibilityType.NichtKlientenbezogen && cat.OhneHilfeplan.Value != AccountingvisibilityType.Never)) { var descList = _Category2Services[cat]; foreach (var desc in descList) { info.ServiceAccountings.Add(new ServiceAccountingDC { ServiceDescription = desc }); } } } } } var erster = allInfos[0]; foreach (var sa in erster.ServiceAccountings) { //Prüfe für jeden des ersten ob er auch in allen anderen enthalten ist bool istDrin = true; for (int i = 1; i < allInfos.Count; i++) { var info2 = allInfos[i]; if (!info2.ServiceAccountings.Exists(sa2 => sa2.ServiceDescription.ServiceDescriptionOid == sa.ServiceDescription.ServiceDescriptionOid)) { istDrin = false; } } if (istDrin) { schnittmenge.Add(sa); } } return schnittmenge; } public string GetVisibleInformationString(IEnumerable selected_records) { var current = SelectedCustomerNode; var hello = current?.SupportConceptTreeNodeDC; var sr = ServiceRecordsForSelectedCustomer; if (current is null) return null; var selected = new Dictionary { { "CostBearerName", current.CostBearerName }, { "CustomerName", current.CustomerName }, { "SupportConceptDuration", current.SupportConceptName } }; var records = new List>(); foreach (var record in selected_records) { var record_dict = new Dictionary { { "StartDate", record.StartDate }, { "EndDate", record.EndDate }, { "Duration (Min)", record.Duration }, { "Category", record.CategoryString }, { "ServiceDescription", record.ServiceDescriptionString }, { "Documentation", record.AllNotices }, { "Goals", record.GoalString }, { "Distance (Meter)", record.DistanceInMeter ?? 0 }, { "InsertedOn", record.InsertedOn }, { "Betrag", record.Betrag }, { "InsertUser", record.InsUser }, { "Employee", record.Employee } }; records.Add(record_dict); } var dict = new Dictionary { { "Aktuelle Ansicht", "Zeiterfassung" }, { "Selected", selected }, { "Zeiterfassungen", records } }; var json = JsonConvert.SerializeObject(dict); //var // var node = ViewModel.SelectedCustomerNode; //long c2sOid = 0; //if (node != null && node.SupportConceptTreeNodeDC != null && node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC != null) //{ // c2sOid = node.SupportConceptTreeNodeDC.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid.Value; //} //var sr = ViewModel.ServiceRecordsForSelectedCustomer; //var earliestStartDate = sr.Any() ? sr.OrderBy(o => o.StartDate).First().StartDate : DateTime.Now; //var latestEndDate = sr.Any() // ? sr.OrderByDescending(o => o.EndDate).First().EndDate // : DateTime.Now.AddSeconds(1); //if (latestEndDate.Hour == 0 && latestEndDate.Minute == 0 && latestEndDate.Second == 1) //{ // latestEndDate = latestEndDate.AddHours(23); // latestEndDate = latestEndDate.AddMinutes(59); //} //AiChatController.ShowAiChatViewForServiceRecords(c2sOid, earliestStartDate, latestEndDate, Math.Min(800, this.ActualHeight), Math.Min(1200, this.ActualWidth)); return json; } } }