Merge branch 'master' into feature_rene_18_ai - kein kommentar...

# Conflicts:
#	BeWo/BeWo.csproj
#	BeWo/BeWoApp.xaml.cs
#	BeWo/ServiceProxy/GeneratedAiEnhancedService.cs
#	BeWo/Services/BeWoControlFactory.cs
#	BeWo/Services/BeWoWindowFactory.cs
#	BeWo/Services/BeWoWindowService.cs
#	BeWo/Services/IControlFactory.cs
#	BeWo/Services/IWindowFactory.cs
#	BeWo/Services/IWindowService.cs
#	BeWo/View/BeWoFileView.xaml
#	BeWo/View/Detail/Report/AbwesenheitsView.xaml
#	BeWo/View/Windows/AnimatedBeWoWindow.xaml.cs
#	BeWo/app.config
#	BeWoAllReports.sln
#	BeWoPlanerMobil.sln
#	BeWoPlanerMobil/.vs/BeWoPlanerMobil.csproj.dtbcache.json
#	BeWoTests.sln
#	Dakota/DakotaUtils.cs
#	Dakota/Logic/DakotaInfoCreator.cs
#	Dakota/Models/DakotaFile.cs
#	Data/Access/GenericDAO.cs
#	Data/Access/SearchDAO.cs
#	Data/Data.csproj
#	Host/Web.config
#	Server/Components/ServerUtils/ApiFacade/WebClientFacade.cs
#	Service/BeWoServiceEnums.cs
#	Service/Core/ServiceHelper.cs
#	Service/Core/ServiceValidator.cs
#	Service/Extensions/ServiceEnumExtension.cs
#	Service/Service.csproj
#	Service/ServiceContracts/Enhanced/IAiEnhancedService.cs
#	Service/ServiceContracts/Enhanced/IOperationsEnhancedService.cs
#	Service/ServiceImplementations/EmployeeServiceImp.cs
#	Service/ServiceImplementations/Enhanced/AiEnhancedServiceImp.cs
#	Service/ServiceImplementations/Enhanced/OperationsEnhancedServiceImp.cs
#	Service/ServiceProxy/OpenWebUIFacade.cs
#	Service/ServiceProxy/ServiceFacade.cs
#	Service/ServiceUtils/DistanceCalculator/GoogleDistanceMatrixAPI.cs
#	Shared/BeWoEntityEnums.cs
#	Shared/Core/AppError.cs
#	Shared/Core/Facade/WebClientFacade.cs
#	Shared/Core/WebClientFacade.cs
#	Shared/Shared.csproj
This commit is contained in:
2025-11-28 12:07:35 +01:00
1059 changed files with 112727 additions and 175550 deletions

View File

@@ -94,12 +94,28 @@ namespace BeWo.ViewModel
if (originalValueProvider != null)
{
bool isDirty = !EqualityComparer<T>.Default.Equals(originalValueProvider(), value);
var isDirty = true;
if(DataContract != null)
{
isDirty = !EqualityComparer<T>.Default.Equals(getSafe(originalValueProvider), value);
}
StoreDirtyInformation(isDirty, propertyName);
}
FirePropertyChanged(propertyName);
return true;
}
private T getSafe<T>(Func<T> originalValueProvider)
{
try
{
return originalValueProvider();
}
catch (Exception e)
{
return default(T);
}
}
}
}

View File

@@ -917,6 +917,10 @@ namespace BeWo.ViewModel
get; set;
}
public StoredFileVM XRechnungStoredFileVM { get; set; }
public long? Oid => DataContract.InvoiceBaseOid;
public string InvoiceId => DataContract.InvoiceId;
public string SenderStreet => DataContract.SenderStreet;
public string SenderTown => DataContract.SenderTown;
public string SenderPostCode => DataContract.SenderPostCode;
@@ -989,6 +993,8 @@ namespace BeWo.ViewModel
IsGkvValid = pDataContract.IsGkvValid;
IsGkvValidError = pDataContract.IsGkvValidError;
IsAlreadyInActiveGkvAbrechnung = pDataContract.IsAlreadyInActiveGkvAbrechnung;
XRechnungStoredFileVM = new StoredFileVM(pDataContract.XRechnungStoredFile);
}
protected override InvoiceBaseDC MapToDataContract(InvoiceBaseDC pDataContract, bool doCommit)

View File

@@ -1,98 +1,134 @@
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows;
using BeWo.ServiceProxy;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using DevExpress.DataAccess.Native.Web;
using DevExpress.Mvvm;
using DevExpress.Xpf.Editors;
using DevExpress.Xpf.Layout.Core;
namespace BeWo.ViewModel.ListViewModel
{
public class InvoiceBaseListVM : AbstractDCListMapperVM<InvoiceBaseDC, InvoiceBaseVM>
{
#region Constants and Fields
public class InvoiceBaseListVM : AbstractDCListMapperVM<InvoiceBaseDC, InvoiceBaseVM>
{
public static string PropertyName_DateTimeSpanFilter = "DateTimeSpanFilter";
public static string PropertyName_DateTimeSpanFilter = "DateTimeSpanFilter";
public static string PropertyName_FilterResultAmountSum = "FilterResultAmountSum";
public static string PropertyName_FilterResultAmountNotPaidSum = "FilterResultAmountNotPaidSum";
public static string PropertyName_FilterResultAmountSum = "FilterResultAmountSum";
public static string PropertyName_FilterResultAmountNotPaidSum = "FilterResultAmountNotPaidSum";
private DateTimeSpan _DateTimeSpanFilter;
private DateTimeSpan _DateTimeSpanFilter;
private BindingList<InvoiceBaseVM> _FilteredInvoices;
private BindingList<InvoiceBaseVM> _FilteredInvoices;
public InvoiceBaseListVM(List<InvoiceBaseDC> pDCs) : base(pDCs)
{
VMList.ListChanged += (s, e) => FirePropertyChanged(PropertyName_FilterResultAmountSum);
VMList.ListChanged += (s, e) => FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
#endregion
bool canExecute(InvoiceBaseVM invoice_vm) => invoice_vm is object && true;
ShowXRechnungCommand = new DelegateCommand<InvoiceBaseVM>(ShowXRechnung, canExecute);
}
#region Constructors and Destructors
public DelegateCommand<InvoiceBaseVM> ShowXRechnungCommand { get; set; }
public InvoiceBaseListVM(List<InvoiceBaseDC> pDCs) : base(pDCs)
{
this.VMList.ListChanged += (s, e) => this.FirePropertyChanged(PropertyName_FilterResultAmountSum);
this.VMList.ListChanged += (s, e) => this.FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
}
public DateTimeSpan DateTimeSpanFilter
{
get
{
return _DateTimeSpanFilter;
}
#endregion
set
{
if (AreDifferent(_DateTimeSpanFilter, value))
{
_DateTimeSpanFilter = value;
FirePropertyChanged(PropertyName_DateTimeSpanFilter);
#region Properties
}
}
}
public DateTimeSpan DateTimeSpanFilter
{
get
{
return this._DateTimeSpanFilter;
}
public decimal? FilterResultAmountSum
{
get
{
return VMList.Sum(e => e.TotalAmount);
}
}
public decimal? FilterResultAmountNotPaidSum
{
get
{
decimal? sum = 0.0m;
foreach (var item in VMList)
sum += item.IsPaid ? item.TotalAmount : 0;
set
{
if (this.AreDifferent(this._DateTimeSpanFilter, value))
{
this._DateTimeSpanFilter = value;
this.FirePropertyChanged(PropertyName_DateTimeSpanFilter);
return FilterResultAmountSum - sum;
}
}
}
}
}
public void ShowXRechnung(InvoiceBaseVM invoice_vm)
{
var invoice_base = invoice_vm;
public decimal? FilterResultAmountSum
{
get
{
return this.VMList.Sum(e => e.TotalAmount);
}
}
public decimal? FilterResultAmountNotPaidSum
{
get
{
decimal? sum = 0.0m;
foreach (var item in this.VMList)
sum += item.IsPaid ? item.TotalAmount : 0;
// Holt bereits geladene
if (invoice_base.XRechnungStoredFileVM is StoredFileVM vm && vm.Data is byte[] bytes)
{
BeWoApp.MainControl.WindowService.ShowERechnungWindow(new MemoryStream(bytes));
return;
}
return FilterResultAmountSum - sum;
}
}
// Noch nicht geladen
var invoice_base_dc = invoice_base.DataContract;
var invoice_base_oid = invoice_base_dc.InvoiceBaseOid ?? -1;
var invoice_type = (int)invoice_base_dc.Type;
var report_link = invoice_base.ReportLink;
ServiceFacade.DoAccountingEnhancedServiceAsnyc(
x => x.GetXRechnung(invoice_base_oid, invoice_type, report_link),
response =>
{
if (response.Success)
{
if (response.Data.Item1 is StoredFileDC dc)
{
invoice_base.XRechnungStoredFileVM.UpdateByDataContract(dc);
}
bytes = response.Data.Item2;
#endregion
invoice_base.XRechnungStoredFileVM.Data = bytes;
BeWoApp.MainControl.WindowService.ShowERechnungWindow(new MemoryStream(bytes));
}
else
{
MessageBox.Show(response.ToErrorString());
}
}
);
}
internal void UpdateList(IList<InvoiceBaseDC> dcList)
{
this.VMList.Clear();
this.VMList.AddRange(dcList.Select(CreateVM));
VMList.Clear();
VMList.AddRange(dcList.Select(CreateVM));
this.FirePropertyChanged(PropertyName_FilterResultAmountSum);
this.FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
FirePropertyChanged(PropertyName_FilterResultAmountSum);
FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
}
internal void UpdateList(IList<InvoiceBaseVM> vmList)
{
this.VMList.Clear();
this.VMList.AddRange(vmList);
internal void UpdateList(IList<InvoiceBaseVM> vmList)
{
VMList.Clear();
VMList.AddRange(vmList);
this.FirePropertyChanged(PropertyName_FilterResultAmountSum);
this.FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
}
}
FirePropertyChanged(PropertyName_FilterResultAmountSum);
FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
}
}
}

View File

@@ -319,6 +319,37 @@ namespace BeWo.ViewModel
}
}
}
public int AnzTageArbeitszeiterfassungErfolgt
{
get { return BeWoApp.AppSettings.AnzTageArbeitszeiterfassungErfolgt; }
set
{
if (this.AreDifferent(BeWoApp.AppSettings.AnzTageArbeitszeiterfassungErfolgt, value))
{
BeWoApp.AppSettings.AnzTageArbeitszeiterfassungErfolgt = value;
this.Settings = UserSettingsUtils.CreateNewSettingValue(this._Settings, SettingsKeys.AnzTageArbeitszeiterfassungErfolgt, value.ToString());
}
}
}
public DateTime? StartStundenkonto
{
get { return BeWoApp.AppSettings.StartStundenkonto; }
set
{
if (this.AreDifferent(BeWoApp.AppSettings.StartStundenkonto, value))
{
BeWoApp.AppSettings.StartStundenkonto = value;
this.Settings = UserSettingsUtils.CreateNewSettingValue(this._Settings, SettingsKeys.StartStundenkonto, value != null ? String.Format("{0:dd.MM.yyyy}", value) : "null");
}
}
}
public bool EnableRestTimeWarning
{
get { return BeWoApp.AppSettings.EnableRestTimeWarning; }

View File

@@ -713,8 +713,8 @@ namespace BeWo.ViewModel
}
public bool IsIKNumberValid
=> Validator.IsIKNumberValid(IKKrankenkasse)
&& Validator.IsLeistungserbringergruppeValid(Leistungserbringergruppe);
=> GkvValidator.IsIKNumberValid(IKKrankenkasse)
&& GkvValidator.IsLeistungserbringergruppeValid(Leistungserbringergruppe);
public string IKKrankenkasse
{

View File

@@ -972,7 +972,7 @@ namespace BeWo.ViewModel
}
}
if (allowed && BeWoApp.AppSettings.AnzTageZeiterfassErfolgt > 0)
if (allowed && BeWoApp.AppSettings.AnzTageZeiterfassErfolgt > 0 && this.SupportConcept != null)
{
if (!BeWoApp.LoggedOnUser.HasRight(UserRightType.ServiceRecordAllowEditAfterMindays))
{

View File

@@ -0,0 +1,113 @@
using System;
using BS.Shared;
using BS.Shared.DataContracts;
namespace BeWo.ViewModel
{
public class StoredFileVM : AbstractDCMapperVM<StoredFileDC>
{
private string _FileName;
private string _FilePath;
private string _ContentType;
private long _Size;
private string _Checksum;
private int? _BeWoObjectTid;
private long? _BeWoObjectOid;
private byte[] _Data;
public StoredFileVM(StoredFileDC dc) : base(dc, dc?.Oid)
{
}
public string FileName
{
get => _FileName;
set => SetProperty(ref _FileName, value, nameof(FileName), () => DataContract.FileName);
}
public string FilePath
{
get => _FilePath;
set => SetProperty(ref _FilePath, value, nameof(FilePath), () => DataContract.FilePath);
}
public string ContentType
{
get => _ContentType;
set => SetProperty(ref _ContentType, value, nameof(ContentType), () => DataContract.ContentType);
}
public long Size
{
get => _Size;
set => SetProperty(ref _Size, value, nameof(Size), () => DataContract.Size);
}
public string Checksum
{
get => _Checksum;
set => SetProperty(ref _Checksum, value, nameof(Checksum), () => DataContract.Checksum);
}
public int? BeWoObjectTid
{
get => _BeWoObjectTid;
set => SetProperty(ref _BeWoObjectTid, value, nameof(BeWoObjectTid), () => DataContract.BeWoObjectTid);
}
public long? BeWoObjectOid
{
get => _BeWoObjectOid;
set => SetProperty(ref _BeWoObjectOid, value, nameof(BeWoObjectOid), () => DataContract.BeWoObjectOid);
}
public byte[] Data
{
get => _Data;
set => SetProperty(ref _Data, value, nameof(Data));
}
protected override void InitByDataContract(StoredFileDC pDataContract)
{
if (pDataContract is null)
return;
_FileName = pDataContract.FileName;
_FilePath = pDataContract.FilePath;
_ContentType = pDataContract.ContentType;
_Size = pDataContract.Size;
_Checksum = pDataContract.Checksum;
_BeWoObjectTid = pDataContract.BeWoObjectTid;
_BeWoObjectOid = pDataContract.BeWoObjectOid;
}
protected override StoredFileDC MapToDataContract(StoredFileDC pDataContract, bool doCommit)
{
pDataContract.FileName = _FileName;
pDataContract.FilePath = _FilePath;
pDataContract.ContentType = _ContentType;
pDataContract.Size = _Size;
pDataContract.Checksum = _Checksum;
pDataContract.BeWoObjectTid = _BeWoObjectTid;
pDataContract.BeWoObjectOid = _BeWoObjectOid;
return pDataContract;
}
public override void UpdateByDataContract(StoredFileDC pDataContract)
{
if (pDataContract is null)
return;
FileName = pDataContract.FileName;
FilePath = pDataContract.FilePath;
ContentType = pDataContract.ContentType;
Size = pDataContract.Size;
Checksum = pDataContract.Checksum;
BeWoObjectTid = pDataContract.BeWoObjectTid;
BeWoObjectOid = pDataContract.BeWoObjectOid;
}
}
}

View File

@@ -27,6 +27,10 @@ namespace BeWo.ViewModel
private ObservableCollection<CompactEmployeeDC> _Member;
private ObservableCollection<Person2TeamDC> _OwnChatMember;
private bool _IsOwnChatTeam;
private string _Name;
private string _Notice;
@@ -45,6 +49,21 @@ namespace BeWo.ViewModel
}
}
public bool IsOwnChatTeam
{
get { return _IsOwnChatTeam; }
set
{
if (AreDifferent(_IsOwnChatTeam, value))
{
_IsOwnChatTeam = value;
StoreDirtyInformation(AreDifferent(DataContract.IsOwnChatTeam, value), nameof(IsOwnChatTeam));
FirePropertyChanged(nameof(IsOwnChatTeam));
}
}
}
public CompactEmployeeDC Leader
{
get { return this._Leader; }
@@ -63,7 +82,7 @@ namespace BeWo.ViewModel
}
}
[Validation(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
public string LeaderString
{
get { return this._Leader.ToStringNullCheck(); } // Validation Workaround
@@ -84,6 +103,25 @@ namespace BeWo.ViewModel
}
}
public ObservableCollection<Person2TeamDC> OwnChatMember
{
get { return this._OwnChatMember; }
set
{
if (this.AreDifferent(this._OwnChatMember, value))
{
this._OwnChatMember = value;
this.FirePropertyChanged(nameof(OwnChatMember));
}
}
}
public void OwnChatMemberRoleChanged(bool changed)
{
this.StoreDirtyInformation(changed, "OwnChatMemberRole");
}
[ValidationAttribute(ValidationRule = ValidationRules.NotNullOrStringEmpty)]
public string Name
{
@@ -132,9 +170,10 @@ namespace BeWo.ViewModel
protected override void InitByDataContract(TeamDC pDataContract)
{
this._Member = new ObservableCollection<CompactEmployeeDC>();
this._OwnChatMember = new ObservableCollection<Person2TeamDC>();
if (!this.IsNew)
{
this._IsOwnChatTeam = pDataContract.IsOwnChatTeam;
this._Name = pDataContract.Name;
this._Notice = pDataContract.Notice;
this._Leader = pDataContract.Leader;
@@ -143,19 +182,25 @@ namespace BeWo.ViewModel
{
this._Member.AddRange(pDataContract.Member.OrderBy(m => string.Format("{0},{1}", m.LastName, m.FirstName)));
}
if (pDataContract.OwnChatMember != null)
{
this._OwnChatMember.AddRange(pDataContract.OwnChatMember.OrderBy(m => string.Format("{0},{1}", m.Person.LastName, m.Person.FirstName)));
}
}
_VarFields = new VarFieldListVM(pDataContract.TeamVarFields);
this._Member.CollectionChanged += (s, e) => this.StoreDirtyInformation(!pDataContract.Member.ContainsSameItemsAs(this._Member), PropertyName_Member);
this._OwnChatMember.CollectionChanged += (s, e) => this.StoreDirtyInformation(!pDataContract.OwnChatMember.ContainsSameItemsAs(this._OwnChatMember), nameof(OwnChatMember));
}
protected override TeamDC MapToDataContract(TeamDC pDataContract, bool doCommit)
{
pDataContract.IsOwnChatTeam = this._IsOwnChatTeam;
pDataContract.Leader = this._Leader;
pDataContract.Name = this._Name;
pDataContract.Notice = this._Notice;
pDataContract.Member = this._Member.ToList();
pDataContract.OwnChatMember = this._OwnChatMember.ToList();
if (_VarFields != null)
{
pDataContract.TeamVarFields = _VarFields.CopyToDCList(doCommit);

View File

@@ -17,7 +17,7 @@ using BS.Shared.Extensions;
namespace BeWo.ViewModel.View.AI
{
public class AiConversationChatViewModel : DialogViewModel
public class AiConversationChatViewModel : BaseDialogViewModel
{
private bool _IsSettingsOpen;
private bool _IsCloneOpen;

View File

@@ -13,7 +13,7 @@ using System.Windows.Input;
namespace BeWo.ViewModel.View.AI
{
public class AiPromptbausteinSelectionViewModel : DialogViewModel
public class AiPromptbausteinSelectionViewModel : BaseDialogViewModel
{
public AiPromptbausteinSelectionViewModel()

View File

@@ -11,7 +11,7 @@ using System.Windows.Input;
namespace BeWo.ViewModel.View.Administration
{
public class AiPromptbausteinDetailViewModel : DialogViewModel
public class AiPromptbausteinDetailViewModel : BaseDialogViewModel
{
private AiPromptbausteinDetailViewModel(AiPromptbausteinTreeViewModel viewModel, AiPromptbausteinTreeVM node, bool isAdd, AiPromptbausteinTreeListVM parent = null)
{

View File

@@ -8,11 +8,11 @@ using System.Windows.Input;
namespace BeWo.ViewModel.View.Dialogs
{
public class DialogViewModel : WindowViewModel
public class BaseDialogViewModel : WindowViewModel
{
public event EventHandler RequestClose;
public DialogViewModel() : base()
public BaseDialogViewModel() : base()
{
CloseDialogCommand = new DelegateCommand(Close);
}

View File

@@ -0,0 +1,19 @@
using BeWo.ViewModel.Light;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BeWo.ViewModel.View.Dialogs
{
public class GkvAbrechnungDialogViewModel : BaseDialogViewModel
{
public GkvAbrechnungLightVM Abrechnung { get; set; }
public GkvAbrechnungDialogViewModel(GkvAbrechnungLightVM abrechnung)
{
Abrechnung = abrechnung;
}
}
}

View File

@@ -35,6 +35,8 @@ namespace BeWo.ViewModel
public static string PropertyName_StandardZeilenanzahl = "StandardZeilenanzahl";
public static string PropertyName_Sortierungsart = "Sortierungsart";
public static string PropertyName_AbsteigendeSortierung = "AbsteigendeSortierung";
public static string PropertyName_VarFields = "VarFields";
//##################################################################
#endregion
@@ -51,6 +53,7 @@ namespace BeWo.ViewModel
private int _Sortierungsart;
private int _AbsteigendeSortierung;
private bool _IsArchived;
private VarFieldListVM _VarFields;
//##################################################################
@@ -90,6 +93,7 @@ namespace BeWo.ViewModel
{
return base.IsDirty || WohnheimEmployeeRelations.IsDirty
|| WohnheimCustomerRelations.IsDirty
|| this._VarFields.IsDirty
|| WohneinheitListVM.IsDirty
|| WohneinheitBelegungListVM.IsDirty;
}
@@ -342,8 +346,20 @@ namespace BeWo.ViewModel
FirePropertyChanged(PropertyName_WohnheimTeamRelations);
}
}
public VarFieldListVM VarFields
{
get { return this._VarFields; }
set
{
if (this.AreDifferent(this._VarFields, value))
{
this._VarFields = value;
this.FirePropertyChanged(PropertyName_VarFields);
}
}
}
public bool AddBelegung(object wohneinheit_oid = null, DateTime? start = null)
{
@@ -389,6 +405,8 @@ namespace BeWo.ViewModel
protected override void InitByDataContract(WohnheimDC pDataContract)
{
this._VarFields = new VarFieldListVM(pDataContract.VarFields);
_WohnheimName = pDataContract.WohnheimName;
_Strasse = pDataContract.Strasse;
_PLZ = pDataContract.PLZ;
@@ -435,6 +453,11 @@ namespace BeWo.ViewModel
//pDataContract.Wohneinheiten = _WohneinheitListVM.CopyToDCList(doCommit);
if (this._VarFields != null)
{
pDataContract.VarFields = this._VarFields.CopyToDCList(doCommit);
}
pDataContract.Wohneinheiten = null;
var einheit_vm2dc = new Dictionary<WohneinheitVM, WohneinheitDC>();
foreach (var vm in _WohneinheitListVM.VMList)