From 9da8c92ca7636c536cd08fed74fb1f96c1ef5545 Mon Sep 17 00:00:00 2001 From: Rene Evertz Date: Wed, 3 Sep 2025 13:40:35 +0200 Subject: [PATCH] =?UTF-8?q?Laden=20=C3=BCber=20DC=20Feature=20-=20Data=20g?= =?UTF-8?q?etrennt=20Feature=20<<<=20AICore=20AICore:=20Verbindung=20BeWoP?= =?UTF-8?q?laner=20->=20MikeAiService?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AICore/AICore.csproj | 4 - .../Context/Core/ContextEntryMapperFactory.cs | 4 +- AICore/Context/Core/ContextSummaryFactory.cs | 49 ++-- .../Detail/CustomerDetailContextEntry.cs | 4 +- .../Detail/EmployeeDetailContextEntry.cs | 4 +- .../Detail/OrganisationDetailContextEntry.cs | 4 +- .../Entry/Detail/PersonDetailContextEntry.cs | 4 +- .../SupportConceptDetailContextEntry.cs | 4 +- .../CustomerNavigationContextEntry.cs | 4 +- .../EmployeeNavigationContextEntry.cs | 4 +- .../OrganisationNavigationContextEntry.cs | 4 +- .../PersonNavigationContextEntry.cs | 4 +- .../Navigation/ServiceRecordContextEntry.cs | 4 +- .../SupportConceptNavigationContextEntry.cs | 4 +- .../Detail/CustomerContextEntryMapper.cs | 37 +-- .../Detail/EmployeeContextEntryMapper.cs | 6 +- .../Detail/OrganisationContextEntryMapper.cs | 6 +- .../Detail/PersonContextEntryMapper.cs | 6 +- .../Detail/ServiceRecordContextEntryMapper.cs | 28 +- .../SupportConceptContextEntryMapper.cs | 6 +- .../CustomerNavigationContextEntryMapper.cs | 13 +- .../EmployeeNavigationContextEntryMapper.cs | 70 +---- ...rganisationNavigationContextEntryMapper.cs | 13 +- .../PersonNavigationContextEntryMapper.cs | 22 +- ...portConceptNavigationContextEntryMapper.cs | 92 +----- AICore/Facade/LLM/BaseLLMApiClient.cs | 1 - AICore/Facade/LLM/OllamaApiClient.cs | 2 +- AICore/Prompt/Core/AiUtils.cs | 6 +- BeWo/ViewModel/Light/InvoiceBaseLightVM.cs | 1 - BeWoAI.sln | 15 - Data/Entities/Address.cs | 16 -- ...GkvAbrechnungLightDC_GkvAbrechnungLight.cs | 1 - Shared/ApiFacade/HttpClientFacade.cs | 231 +++++++++++++++ Shared/ApiFacade/JsonHttpClientFacade.cs | 48 ++++ Shared/ApiFacade/WebClientFacade.cs | 268 ++++++++++++++++++ Shared/Core/AppError.cs | 1 - Shared/DataContracts/ApiResponse.cs | 1 - .../Compact/CompactCustomerDC.cs | 20 +- .../Compact/CompactEmployeeDC.cs | 3 +- .../Compact/CompactOrganisationDC.cs | 12 +- .../DataContracts/Compact/CompactPersonDC.cs | 12 +- Shared/DataContracts/PersonDC.cs | 12 +- Shared/Extensions/AddressExtensions.cs | 34 +++ Shared/Extensions/PersonNameableExtensions.cs | 22 ++ Shared/Interface/Abstract/IAddressable.cs | 19 ++ Shared/Interface/Abstract/IPersonNameable.cs | 14 + Shared/Shared.csproj | 7 + 47 files changed, 830 insertions(+), 316 deletions(-) create mode 100644 Shared/ApiFacade/HttpClientFacade.cs create mode 100644 Shared/ApiFacade/JsonHttpClientFacade.cs create mode 100644 Shared/ApiFacade/WebClientFacade.cs create mode 100644 Shared/Extensions/AddressExtensions.cs create mode 100644 Shared/Extensions/PersonNameableExtensions.cs create mode 100644 Shared/Interface/Abstract/IAddressable.cs create mode 100644 Shared/Interface/Abstract/IPersonNameable.cs diff --git a/AICore/AICore.csproj b/AICore/AICore.csproj index 6d2ba4480..e2b820fdb 100644 --- a/AICore/AICore.csproj +++ b/AICore/AICore.csproj @@ -112,10 +112,6 @@ - - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7} - ApiFacade - {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57} ServiceUtils diff --git a/AICore/Context/Core/ContextEntryMapperFactory.cs b/AICore/Context/Core/ContextEntryMapperFactory.cs index 066a3ef75..0f5e25b8b 100644 --- a/AICore/Context/Core/ContextEntryMapperFactory.cs +++ b/AICore/Context/Core/ContextEntryMapperFactory.cs @@ -2,7 +2,7 @@ using AICore.Context.EntryMapper; using AICore.Context.EntryMapper.Detail; using AICore.Context.EntryMapper.Navigation; -using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; namespace AICore.Context.Core { @@ -21,6 +21,6 @@ namespace AICore.Context.Core public static SupportConceptNavigationContextEntryMapper SupportConceptNavigationMapper { get; } = new SupportConceptNavigationContextEntryMapper(); public static ServiceRecordContextEntryMapper ServiceRecordMapper { get; } = new ServiceRecordContextEntryMapper(); - public static BaseContextEntryMapper ServiceRecordCustomerMapper { get; } = new CustomerNavigationContextEntryMapper(); + public static BaseContextEntryMapper ServiceRecordCustomerMapper { get; } = new CustomerNavigationContextEntryMapper(); } } diff --git a/AICore/Context/Core/ContextSummaryFactory.cs b/AICore/Context/Core/ContextSummaryFactory.cs index 49f3186d1..f1f2cb470 100644 --- a/AICore/Context/Core/ContextSummaryFactory.cs +++ b/AICore/Context/Core/ContextSummaryFactory.cs @@ -2,7 +2,8 @@ using AICore.Context.Entry; using AICore.Context.Entry.Navigation; using AICore.Context.Summary; -using BeWo.Data.Entities; +using BS.Shared.DataContracts; +using BS.Shared.DataContracts.Compact; using BS.Shared.Exceptions; using System.Collections.Generic; @@ -12,19 +13,19 @@ namespace AICore.Context.SummaryMapper { public static DetailContextSummary CreateDetailContext(TEntity entity) where TEntry : DetailContextEntry - where TEntity : BeWoEntityBase, new() + where TEntity : IDataContract, new() { object obj = null; - if (entity is Customer customer) + if (entity is CustomerDC customer) obj = CreateCustomerDetailContextSummary(customer); - else if (entity is Employee employee) + else if (entity is EmployeeDC employee) obj = CreateEmployeeDetailContextSummary(employee); - else if (entity is Person person) + else if (entity is PersonDC person) obj = CreatePersonDetailContextSummary(person); - else if (entity is Organisation organisation) + else if (entity is OrganisationDC organisation) obj = CreateOrganisationDetailContextSummary(organisation); - else if (entity is SupportConcept support) + else if (entity is SupportConceptDC support) obj = CreateSupportConceptDetailContextSummary(support); if (obj == null) @@ -35,19 +36,19 @@ namespace AICore.Context.SummaryMapper public static NavigationContextSummary CreateNavigationContext(IEnumerable entities) where TEntry : NavigationContextEntry - where TEntity : BeWoEntityBase, new() + where TEntity : IDataContract, new() { object obj = null; - if (entities is IEnumerable customer) + if (entities is IEnumerable customer) obj = CreateCustomerNavigationContextSummary(customer); - else if (entities is IEnumerable employee) + else if (entities is IEnumerable employee) obj = CreateEmployeeNavigationContextSummary(employee); - else if (entities is IEnumerable person) + else if (entities is IEnumerable person) obj = CreatePersonNavigationContextSummary(person); - else if (entities is IEnumerable organisation) + else if (entities is IEnumerable organisation) obj = CreateOrganisationNavigationContextSummary(organisation); - else if (entities is IEnumerable support) + else if (entities is IEnumerable support) obj = CreateSupportConceptNavigationContextSummary(support); if (obj == null) @@ -56,7 +57,7 @@ namespace AICore.Context.SummaryMapper return obj as NavigationContextSummary; } - public static ServiceRecordNavigationContextSummary CreateServiceRecordNavigationContextSummary(IEnumerable serviceRecords, Customer customer, string costBearer, string supportConcept) + public static ServiceRecordNavigationContextSummary CreateServiceRecordNavigationContextSummary(IEnumerable serviceRecords, CompactCustomerDC customer, string costBearer, string supportConcept) { var entries = ContextEntryMapperFactory.ServiceRecordMapper.MapToNewContexts(serviceRecords); var customer_entry = ContextEntryMapperFactory.ServiceRecordCustomerMapper.MapToNewContext(customer); @@ -64,70 +65,70 @@ namespace AICore.Context.SummaryMapper return new ServiceRecordNavigationContextSummary(entries, customer_entry, costBearer, supportConcept); } - private static CustomerDetailContextSummary CreateCustomerDetailContextSummary(Customer customer) + private static CustomerDetailContextSummary CreateCustomerDetailContextSummary(CustomerDC customer) { var entry = ContextEntryMapperFactory.CustomerMapper.MapToNewContext(customer); return new CustomerDetailContextSummary(entry); } - private static EmployeeDetailContextSummary CreateEmployeeDetailContextSummary(Employee employee) + private static EmployeeDetailContextSummary CreateEmployeeDetailContextSummary(EmployeeDC employee) { var entry = ContextEntryMapperFactory.EmployeeMapper.MapToNewContext(employee); return new EmployeeDetailContextSummary(entry); } - private static PersonDetailContextSummary CreatePersonDetailContextSummary(Person person) + private static PersonDetailContextSummary CreatePersonDetailContextSummary(PersonDC person) { var entry = ContextEntryMapperFactory.PersonMapper.MapToNewContext(person); return new PersonDetailContextSummary(entry); } - private static OrganisationDetailContextSummary CreateOrganisationDetailContextSummary(Organisation organisation) + private static OrganisationDetailContextSummary CreateOrganisationDetailContextSummary(OrganisationDC organisation) { var entry = ContextEntryMapperFactory.OrganisationMapper.MapToNewContext(organisation); return new OrganisationDetailContextSummary(entry); } - private static SupportConceptDetailContextSummary CreateSupportConceptDetailContextSummary(SupportConcept supportConcept) + private static SupportConceptDetailContextSummary CreateSupportConceptDetailContextSummary(SupportConceptDC supportConcept) { var entry = ContextEntryMapperFactory.SupportConceptMapper.MapToNewContext(supportConcept); return new SupportConceptDetailContextSummary(entry); } - private static CustomerNavigationContextSummary CreateCustomerNavigationContextSummary(IEnumerable customer) + private static CustomerNavigationContextSummary CreateCustomerNavigationContextSummary(IEnumerable customer) { var entry = ContextEntryMapperFactory.CustomerNavigationMapper.MapToNewContexts(customer); return new CustomerNavigationContextSummary(entry); } - private static EmployeeNavigationContextSummary CreateEmployeeNavigationContextSummary(IEnumerable employee) + private static EmployeeNavigationContextSummary CreateEmployeeNavigationContextSummary(IEnumerable employee) { var entry = ContextEntryMapperFactory.EmployeeNavigationMapper.MapToNewContexts(employee); return new EmployeeNavigationContextSummary(entry); } - private static PersonNavigationContextSummary CreatePersonNavigationContextSummary(IEnumerable person) + private static PersonNavigationContextSummary CreatePersonNavigationContextSummary(IEnumerable person) { var entry = ContextEntryMapperFactory.PersonNavigationMapper.MapToNewContexts(person); return new PersonNavigationContextSummary(entry); } - private static OrganisationNavigationContextSummary CreateOrganisationNavigationContextSummary(IEnumerable organisation) + private static OrganisationNavigationContextSummary CreateOrganisationNavigationContextSummary(IEnumerable organisation) { var entry = ContextEntryMapperFactory.OrganisationNavigationMapper.MapToNewContexts(organisation); return new OrganisationNavigationContextSummary(entry); } - private static SupportConceptNavigationContextSummary CreateSupportConceptNavigationContextSummary(IEnumerable supportConcept) + private static SupportConceptNavigationContextSummary CreateSupportConceptNavigationContextSummary(IEnumerable supportConcept) { var entry = ContextEntryMapperFactory.SupportConceptNavigationMapper.MapToNewContexts(supportConcept); diff --git a/AICore/Context/Entry/Detail/CustomerDetailContextEntry.cs b/AICore/Context/Entry/Detail/CustomerDetailContextEntry.cs index 810a6815e..3e875012c 100644 --- a/AICore/Context/Entry/Detail/CustomerDetailContextEntry.cs +++ b/AICore/Context/Entry/Detail/CustomerDetailContextEntry.cs @@ -1,10 +1,10 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts; using System; using System.Text.Json.Serialization; namespace AICore.Context.Entry { - public class CustomerDetailContextEntry : DetailContextEntry + public class CustomerDetailContextEntry : DetailContextEntry { [JsonPropertyName("Klient-ID")] public long CustomerOid { get; set; } diff --git a/AICore/Context/Entry/Detail/EmployeeDetailContextEntry.cs b/AICore/Context/Entry/Detail/EmployeeDetailContextEntry.cs index 8d6845ed5..96ee657e9 100644 --- a/AICore/Context/Entry/Detail/EmployeeDetailContextEntry.cs +++ b/AICore/Context/Entry/Detail/EmployeeDetailContextEntry.cs @@ -1,8 +1,8 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.Entry { - public class EmployeeDetailContextEntry : DetailContextEntry + public class EmployeeDetailContextEntry : DetailContextEntry { } diff --git a/AICore/Context/Entry/Detail/OrganisationDetailContextEntry.cs b/AICore/Context/Entry/Detail/OrganisationDetailContextEntry.cs index 942494801..cbc48c842 100644 --- a/AICore/Context/Entry/Detail/OrganisationDetailContextEntry.cs +++ b/AICore/Context/Entry/Detail/OrganisationDetailContextEntry.cs @@ -1,8 +1,8 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.Entry { - public class OrganisationDetailContextEntry : DetailContextEntry + public class OrganisationDetailContextEntry : DetailContextEntry { } diff --git a/AICore/Context/Entry/Detail/PersonDetailContextEntry.cs b/AICore/Context/Entry/Detail/PersonDetailContextEntry.cs index 861a178da..3e79a6181 100644 --- a/AICore/Context/Entry/Detail/PersonDetailContextEntry.cs +++ b/AICore/Context/Entry/Detail/PersonDetailContextEntry.cs @@ -1,8 +1,8 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.Entry { - public class PersonDetailContextEntry : DetailContextEntry + public class PersonDetailContextEntry : DetailContextEntry { } diff --git a/AICore/Context/Entry/Detail/SupportConceptDetailContextEntry.cs b/AICore/Context/Entry/Detail/SupportConceptDetailContextEntry.cs index 6af458d01..ab9026d97 100644 --- a/AICore/Context/Entry/Detail/SupportConceptDetailContextEntry.cs +++ b/AICore/Context/Entry/Detail/SupportConceptDetailContextEntry.cs @@ -1,8 +1,8 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.Entry { - public class SupportConceptDetailContextEntry : DetailContextEntry + public class SupportConceptDetailContextEntry : DetailContextEntry { } diff --git a/AICore/Context/Entry/Navigation/CustomerNavigationContextEntry.cs b/AICore/Context/Entry/Navigation/CustomerNavigationContextEntry.cs index 8d864cf4b..c5a210f53 100644 --- a/AICore/Context/Entry/Navigation/CustomerNavigationContextEntry.cs +++ b/AICore/Context/Entry/Navigation/CustomerNavigationContextEntry.cs @@ -1,10 +1,10 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; using System; using System.Text.Json.Serialization; namespace AICore.Context.Entry.Navigation { - public class CustomerNavigationContextEntry : NavigationContextEntry + public class CustomerNavigationContextEntry : NavigationContextEntry { [JsonPropertyName("Adresse")] public string AddressString { get; set; } diff --git a/AICore/Context/Entry/Navigation/EmployeeNavigationContextEntry.cs b/AICore/Context/Entry/Navigation/EmployeeNavigationContextEntry.cs index ae21f9233..e913e6d27 100644 --- a/AICore/Context/Entry/Navigation/EmployeeNavigationContextEntry.cs +++ b/AICore/Context/Entry/Navigation/EmployeeNavigationContextEntry.cs @@ -1,9 +1,9 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; using System.Text.Json.Serialization; namespace AICore.Context.Entry.Navigation { - public class EmployeeNavigationContextEntry : NavigationContextEntry + public class EmployeeNavigationContextEntry : NavigationContextEntry { [JsonPropertyName("Mitarbeiter-ID")] public long EmployeeOid { get; set; } diff --git a/AICore/Context/Entry/Navigation/OrganisationNavigationContextEntry.cs b/AICore/Context/Entry/Navigation/OrganisationNavigationContextEntry.cs index b1fe15b29..36714b310 100644 --- a/AICore/Context/Entry/Navigation/OrganisationNavigationContextEntry.cs +++ b/AICore/Context/Entry/Navigation/OrganisationNavigationContextEntry.cs @@ -1,9 +1,9 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; using System.Text.Json.Serialization; namespace AICore.Context.Entry.Navigation { - public class OrganisationNavigationContextEntry : NavigationContextEntry + public class OrganisationNavigationContextEntry : NavigationContextEntry { [JsonPropertyName("Organisation-ID")] public long OrganisationOid { get; set; } diff --git a/AICore/Context/Entry/Navigation/PersonNavigationContextEntry.cs b/AICore/Context/Entry/Navigation/PersonNavigationContextEntry.cs index af9d28b63..7ec4eb25f 100644 --- a/AICore/Context/Entry/Navigation/PersonNavigationContextEntry.cs +++ b/AICore/Context/Entry/Navigation/PersonNavigationContextEntry.cs @@ -1,10 +1,10 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; using System; using System.Text.Json.Serialization; namespace AICore.Context.Entry.Navigation { - public class PersonNavigationContextEntry : NavigationContextEntry + public class PersonNavigationContextEntry : NavigationContextEntry { [JsonPropertyName("Adresse")] public string AddressString { get; set; } diff --git a/AICore/Context/Entry/Navigation/ServiceRecordContextEntry.cs b/AICore/Context/Entry/Navigation/ServiceRecordContextEntry.cs index a68ddab97..8f890b6c5 100644 --- a/AICore/Context/Entry/Navigation/ServiceRecordContextEntry.cs +++ b/AICore/Context/Entry/Navigation/ServiceRecordContextEntry.cs @@ -1,10 +1,10 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts; using System; using System.Text.Json.Serialization; namespace AICore.Context.Entry.Navigation { - public class ServiceRecordContextEntry : NavigationContextEntry + public class ServiceRecordContextEntry : NavigationContextEntry { [JsonPropertyName("Zeiteintrag-ID")] public long ServiceRecordOid { get; set; } diff --git a/AICore/Context/Entry/Navigation/SupportConceptNavigationContextEntry.cs b/AICore/Context/Entry/Navigation/SupportConceptNavigationContextEntry.cs index d22e794e2..8fc9cb7f1 100644 --- a/AICore/Context/Entry/Navigation/SupportConceptNavigationContextEntry.cs +++ b/AICore/Context/Entry/Navigation/SupportConceptNavigationContextEntry.cs @@ -1,10 +1,10 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; using System; using System.Text.Json.Serialization; namespace AICore.Context.Entry.Navigation { - public class SupportConceptNavigationContextEntry : NavigationContextEntry + public class SupportConceptNavigationContextEntry : NavigationContextEntry { [JsonPropertyName("Hilfeplan-ID")] public long SupportConceptOid { get; set; } diff --git a/AICore/Context/EntryMapper/Detail/CustomerContextEntryMapper.cs b/AICore/Context/EntryMapper/Detail/CustomerContextEntryMapper.cs index 49480c51e..32a324462 100644 --- a/AICore/Context/EntryMapper/Detail/CustomerContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Detail/CustomerContextEntryMapper.cs @@ -1,35 +1,36 @@ using AICore.Context.Entry; -using BeWo.Data.Entities; +using BS.Shared.DataContracts; +using BS.Shared.Extensions; namespace AICore.Context.EntryMapper.Detail { - public class CustomerContextEntryMapper : BaseContextEntryMapper + public class CustomerContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(Customer pObject, CustomerDetailContextEntry pContext) + public override void MergeWithObject(CustomerDC pObject, CustomerDetailContextEntry pContext) { - pContext.CustomerOid = pObject.Oid ?? 0; - pContext.FullName = pObject.Person.FirstNameLastName; + pContext.CustomerOid = pObject.CustomerOid ?? -2; + pContext.FullName = pObject.GetLastNameFirstName(); pContext.CustomerAlias = pObject.CustomerAlias; - pContext.DateOfBirth = pObject.Person.DateOfBirth; - pContext.Sex = pObject.Person.Sex?.ToString() ?? "null"; - pContext.NationalitaetDisplayName = pObject.Person.Nationalitaet.Value; - pContext.IsMigrant = pObject.Person.IsMigrant; - pContext.Migrationshintergrund = pObject.Person.Migrationshintergrund; - pContext.AufenthaltsStatusDisplayName = pObject.Person.AufenthaltsStatus?.Value ?? "null"; - pContext.FamilyStatus = pObject.Person.FamilyStatus?.ToString() ?? "null"; - pContext.Profession = pObject.Person.Profession; + pContext.DateOfBirth = pObject.DateOfBirth; + pContext.Sex = pObject.Sex?.ToString() ?? "null"; + pContext.NationalitaetDisplayName = pObject.Nationalitaet?.TypeDescription ?? "null"; + pContext.IsMigrant = pObject.IsMigrant; + pContext.Migrationshintergrund = pObject.Migrationshintergrund; + pContext.AufenthaltsStatusDisplayName = pObject.AufenthaltsStatus?.TypeDescription ?? "null"; + pContext.FamilyStatus = pObject.FamilyStatus?.ToString() ?? "null"; + pContext.Profession = pObject.Profession; pContext.Childs = pObject.Childs; pContext.EquityContribution = pObject.EquityContribution; pContext.HealthInsurance = pObject.HealthInsurance; pContext.InsuranceNumber = pObject.InsuranceNumber; pContext.VersichertenStatus = pObject.VersichertenStatus; pContext.Notice = pObject.Notice; - pContext.AddressLine1 = pObject.Person.Address.AddressLine1; - pContext.Street = pObject.Person.Address.Street; - pContext.PostalCode = pObject.Person.Address.PostalCode; - pContext.Town = pObject.Person.Address.Town; + pContext.AddressLine1 = pObject.AddressLine1; + pContext.Street = pObject.Street; + pContext.PostalCode = pObject.PostalCode; + pContext.Town = pObject.Town; pContext.DistanceInMeter = pObject.DistanceInMeter; - pContext.InvoiceAddress = pObject.Person.InvoiceAddress?.ToSingleLine() ?? "null"; + pContext.InvoiceAddress = pObject.GetInvoiceAddressSingleLine() ?? "null"; } } } diff --git a/AICore/Context/EntryMapper/Detail/EmployeeContextEntryMapper.cs b/AICore/Context/EntryMapper/Detail/EmployeeContextEntryMapper.cs index 937fd4cd3..1479a16ab 100644 --- a/AICore/Context/EntryMapper/Detail/EmployeeContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Detail/EmployeeContextEntryMapper.cs @@ -1,13 +1,13 @@ using System; using System.Linq; using AICore.Context.Entry; -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.EntryMapper.Detail { - public class EmployeeContextEntryMapper : BaseContextEntryMapper + public class EmployeeContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(Employee pObject, EmployeeDetailContextEntry pContext) + public override void MergeWithObject(EmployeeDC pObject, EmployeeDetailContextEntry pContext) { throw new NotImplementedException(); } diff --git a/AICore/Context/EntryMapper/Detail/OrganisationContextEntryMapper.cs b/AICore/Context/EntryMapper/Detail/OrganisationContextEntryMapper.cs index 548702bfc..d25a95a0e 100644 --- a/AICore/Context/EntryMapper/Detail/OrganisationContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Detail/OrganisationContextEntryMapper.cs @@ -1,13 +1,13 @@ using System; using System.Linq; using AICore.Context.Entry; -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.EntryMapper.Detail { - public class OrganisationContextEntryMapper : BaseContextEntryMapper + public class OrganisationContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(Organisation pObject, OrganisationDetailContextEntry pContext) + public override void MergeWithObject(OrganisationDC pObject, OrganisationDetailContextEntry pContext) { throw new NotImplementedException(); } diff --git a/AICore/Context/EntryMapper/Detail/PersonContextEntryMapper.cs b/AICore/Context/EntryMapper/Detail/PersonContextEntryMapper.cs index fb7c9a871..a447fa2db 100644 --- a/AICore/Context/EntryMapper/Detail/PersonContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Detail/PersonContextEntryMapper.cs @@ -1,13 +1,13 @@ using System; using System.Linq; using AICore.Context.Entry; -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.EntryMapper.Detail { - public class PersonContextEntryMapper : BaseContextEntryMapper + public class PersonContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(Person pObject, PersonDetailContextEntry pContext) + public override void MergeWithObject(PersonDC pObject, PersonDetailContextEntry pContext) { throw new NotImplementedException(); } diff --git a/AICore/Context/EntryMapper/Detail/ServiceRecordContextEntryMapper.cs b/AICore/Context/EntryMapper/Detail/ServiceRecordContextEntryMapper.cs index decaed1d1..fbd3b0219 100644 --- a/AICore/Context/EntryMapper/Detail/ServiceRecordContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Detail/ServiceRecordContextEntryMapper.cs @@ -1,19 +1,19 @@ using System; using System.Linq; using AICore.Context.Entry.Navigation; -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.EntryMapper.Detail { - public class ServiceRecordContextEntryMapper : BaseContextEntryMapper + public class ServiceRecordContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(ServiceRecord pObject, ServiceRecordContextEntry pContext) + public override void MergeWithObject(ServiceRecordDC pObject, ServiceRecordContextEntry pContext) { - pContext.ServiceRecordOid = pObject.Oid.Value; + pContext.ServiceRecordOid = pObject.ServiceRecordOid.Value; pContext.Start = pObject.Start; pContext.End = pObject.End; - pContext.DurationInMinuten = pObject.DurationMinutes; - pContext.CategoryName = pObject.ServiceDescription.ServiceCategory.Name; + pContext.DurationInMinuten = GetDurationMinutes(pObject); + pContext.CategoryName = pObject.ServiceDescription.CategoryName; pContext.DescriptionName = pObject.ServiceDescription.Name; pContext.Notice = pObject.Notice; pContext.Notice2 = pObject.Notice2; @@ -21,10 +21,22 @@ namespace AICore.Context.EntryMapper.Detail pContext.Notice4 = pObject.Notice4; pContext.Notice5 = pObject.Notice5; pContext.DistanceInMeter = pObject.DistanceInMeter; - pContext.InsertedOn = pObject.InsTs.Value; + pContext.InsertedOn = pObject.InsertedOn.Value; pContext.Betrag = pObject.Betrag; pContext.InsUser = pObject.InsUser; - pContext.Employee = pObject.Employee.Person.FirstNameLastName; + pContext.Employee = pObject.Employee.FirstNameLastName; + } + + public virtual double GetDurationMinutes(ServiceRecordDC pObject) + { + if (pObject.GroupOid.HasValue) + { + return (double)pObject.RoundedDuration; + } + else + { + return (pObject.End.Value - pObject.Start.Value).TotalMinutes; + } } } } diff --git a/AICore/Context/EntryMapper/Detail/SupportConceptContextEntryMapper.cs b/AICore/Context/EntryMapper/Detail/SupportConceptContextEntryMapper.cs index 185cd4cf7..44d22dda2 100644 --- a/AICore/Context/EntryMapper/Detail/SupportConceptContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Detail/SupportConceptContextEntryMapper.cs @@ -1,13 +1,13 @@ using System; using System.Linq; using AICore.Context.Entry; -using BeWo.Data.Entities; +using BS.Shared.DataContracts; namespace AICore.Context.EntryMapper.Detail { - public class SupportConceptContextEntryMapper : BaseContextEntryMapper + public class SupportConceptContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(SupportConcept pObject, SupportConceptDetailContextEntry pContext) + public override void MergeWithObject(SupportConceptDC pObject, SupportConceptDetailContextEntry pContext) { throw new NotImplementedException(); } diff --git a/AICore/Context/EntryMapper/Navigation/CustomerNavigationContextEntryMapper.cs b/AICore/Context/EntryMapper/Navigation/CustomerNavigationContextEntryMapper.cs index dcfbd6071..4d045eec0 100644 --- a/AICore/Context/EntryMapper/Navigation/CustomerNavigationContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Navigation/CustomerNavigationContextEntryMapper.cs @@ -1,19 +1,20 @@ using System; using System.Linq; using AICore.Context.Entry.Navigation; -using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; +using BS.Shared.Extensions; namespace AICore.Context.EntryMapper.Navigation { - public class CustomerNavigationContextEntryMapper : BaseContextEntryMapper + public class CustomerNavigationContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(Customer pObject, CustomerNavigationContextEntry pContext) + public override void MergeWithObject(CompactCustomerDC pObject, CustomerNavigationContextEntry pContext) { - pContext.AddressString = pObject.Person.Address?.ToSingleLine() ?? "null"; + pContext.AddressString = pObject.GetSingleAddressLine() ?? "null"; pContext.CustomerAlias = pObject.CustomerAlias; pContext.CustomerOid = pObject.Oid.Value; - pContext.DateOfBirth = pObject.Person.DateOfBirth; - pContext.FullName = pObject.Person.FirstNameLastName; + pContext.DateOfBirth = pObject.DateOfBirth; + pContext.FullName = pObject.GetLastNameFirstName(); pContext.Teams = "CustomerService"; pContext.Bezugspersonen = "CustomerService"; } diff --git a/AICore/Context/EntryMapper/Navigation/EmployeeNavigationContextEntryMapper.cs b/AICore/Context/EntryMapper/Navigation/EmployeeNavigationContextEntryMapper.cs index c5f8a0707..78ae10004 100644 --- a/AICore/Context/EntryMapper/Navigation/EmployeeNavigationContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Navigation/EmployeeNavigationContextEntryMapper.cs @@ -2,82 +2,20 @@ using System.Collections.Generic; using System.Linq; using AICore.Context.Entry.Navigation; -using BeWo.Data.Access; -using BeWo.Data.Entities; using BS.Shared.DataContracts.Compact; using BS.Shared.DataContracts; -using BeWo.Data.Security; using BS.Shared; using BS.Shared.Extensions; namespace AICore.Context.EntryMapper.Navigation { - public class EmployeeNavigationContextEntryMapper : BaseContextEntryMapper + public class EmployeeNavigationContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(Employee pObject, EmployeeNavigationContextEntry pContext) + public override void MergeWithObject(CompactEmployeeDC pObject, EmployeeNavigationContextEntry pContext) { - pContext.EmployeeOid = pObject.Oid.Value; + pContext.EmployeeOid = pObject.EmployeeOid; pContext.PersonnelNumber = pObject.PersonnelNumber; - pContext.FirstNameLastName = pObject.Person.FirstNameLastName; + pContext.FirstNameLastName = pObject.GetFirstNameLastName(); } - - //public virtual List GetAllCompactEmployees() - //{ - // var employees = DAOFactory.GenericDAO.GetAll(); - - // var teams = GetAllTeamsCompact(); - - // foreach (var employee in employees) - // { - // var team_oids = new List(); - - // foreach (var team in teams) - // { - // if (team.MemberList.Contains(employee)) - // { - // var team_oid = team.Oid.Value; - - // team_oids.Add(team_oid); - // } - // } - - // if (team_oids.Count > 0) - // { - // foreach (var oid in dc.TeamOids) - // { - // var team = teamDCs.FirstOrDefault(t => t.TeamOid == oid); - // if (team != null) - // { - - - // if (dc.RelatedTeams == null) - // dc.RelatedTeams = "Teams: " + team.Name + ", "; - // else - // dc.RelatedTeams += team.Name + ", "; - // } - // } - // } - // } - - // return dcs; - //} - - //public virtual IEnumerable GetAllTeamsCompact() - //{ - // var loggedInUser = UserRightHelper.GetLoggedInUser(); - - // if (UserRightHelper.UserHasRight(loggedInUser, UserRightType.TeamView_ViewAll)) - // { - // return DAOFactory.GenericDAO.GetAllActive(); - // } - - // if (UserRightHelper.UserHasRight(loggedInUser, UserRightType.TeamView_ViewMyTeams)) - // { - // var teams = DAOFactory.SearchDAO.FindAllActiveTeamsOfEmployee(loggedInUser.Employee.Oid.Value); - // return teams; - // } - - // return new List(); - //} } } diff --git a/AICore/Context/EntryMapper/Navigation/OrganisationNavigationContextEntryMapper.cs b/AICore/Context/EntryMapper/Navigation/OrganisationNavigationContextEntryMapper.cs index 24a398e32..d131a67d9 100644 --- a/AICore/Context/EntryMapper/Navigation/OrganisationNavigationContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Navigation/OrganisationNavigationContextEntryMapper.cs @@ -1,18 +1,19 @@ using System; using System.Linq; using AICore.Context.Entry.Navigation; -using BeWo.Data.Entities; +using BS.Shared.DataContracts.Compact; +using BS.Shared.Extensions; namespace AICore.Context.EntryMapper.Navigation { - public class OrganisationNavigationContextEntryMapper : BaseContextEntryMapper + public class OrganisationNavigationContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(Organisation pObject, OrganisationNavigationContextEntry pContext) + public override void MergeWithObject(CompactOrganisationDC pObject, OrganisationNavigationContextEntry pContext) { - pContext.OrganisationOid = pObject.Oid.Value; + pContext.OrganisationOid = pObject.OrganisationOid; pContext.Name = pObject.Name; - pContext.Funktion = pObject.Function?.Value; - pContext.AddressString = pObject.Address?.ToSingleLine() ?? "null"; + pContext.Funktion = pObject.Function; + pContext.AddressString = pObject.GetSingleAddressLine(); pContext.IKDatenannahmestelle = pObject.IKDatenannahmestelle; pContext.IKKostentrager = pObject.IKKostentrager; pContext.IKKrankenkasse = pObject.IKKrankenkasse; diff --git a/AICore/Context/EntryMapper/Navigation/PersonNavigationContextEntryMapper.cs b/AICore/Context/EntryMapper/Navigation/PersonNavigationContextEntryMapper.cs index 20a6dab12..acb671c2c 100644 --- a/AICore/Context/EntryMapper/Navigation/PersonNavigationContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Navigation/PersonNavigationContextEntryMapper.cs @@ -1,28 +1,28 @@ using System; using System.Linq; using AICore.Context.Entry.Navigation; -using BeWo.Data.Entities; using BS.Shared.DataContracts; using BS.Shared; using BS.Shared.Extensions; +using BS.Shared.DataContracts.Compact; namespace AICore.Context.EntryMapper.Navigation { - public class PersonNavigationContextEntryMapper : BaseContextEntryMapper + public class PersonNavigationContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(Person pObject, PersonNavigationContextEntry pContext) + public override void MergeWithObject(CompactPersonDC pObject, PersonNavigationContextEntry pContext) { - pContext.AddressString = pObject.Address?.ToSingleLine() ?? "null"; + pContext.AddressString = pObject.GetSingleAddressLine() ?? "null"; //pContext.DateOfBirth = pObject.DateOfBirth; - pContext.FullName = pObject.LastNameFirstName; - pContext.Title = pObject.Title?.Value; + pContext.FullName = pObject.GetLastNameFirstName(); + pContext.Title = pObject.Title; //pContext.Geschlecht = pObject.Sex?.ToString(); - pContext.Function = pObject.Function?.Value; + pContext.Function = pObject.Function; - pContext.Tel = pObject.Contacts.GetPrivatePhoneNumber(); - pContext.Fax = pObject.Contacts.GetPrivateFaxNumber(); - pContext.Mobil = pObject.Contacts.GetPrivateMobilePhoneNumber(); - pContext.Email = pObject.Contacts.GetPrivateMailNumber(); + pContext.Tel = pObject.Communication1; + pContext.Mobil = pObject.Communication2; + pContext.Email = pObject.Communication3; + pContext.Fax = pObject.Communication4; } } } diff --git a/AICore/Context/EntryMapper/Navigation/SupportConceptNavigationContextEntryMapper.cs b/AICore/Context/EntryMapper/Navigation/SupportConceptNavigationContextEntryMapper.cs index d815071de..37ffce623 100644 --- a/AICore/Context/EntryMapper/Navigation/SupportConceptNavigationContextEntryMapper.cs +++ b/AICore/Context/EntryMapper/Navigation/SupportConceptNavigationContextEntryMapper.cs @@ -4,96 +4,22 @@ using System.Linq; using System.Text; using AICore.Context.Core; using AICore.Context.Entry.Navigation; -using BeWo.Data.Entities; using BS.Shared.DataContracts.Compact; +using BS.Shared.Extensions; namespace AICore.Context.EntryMapper.Navigation { - public class SupportConceptNavigationContextEntryMapper : BaseContextEntryMapper + public class SupportConceptNavigationContextEntryMapper : BaseContextEntryMapper { - public override void MergeWithObject(SupportConcept pObject, SupportConceptNavigationContextEntry pContext) + public override void MergeWithObject(CompactSupportConceptDC pObject, SupportConceptNavigationContextEntry pContext) { - pContext.SupportConceptOid = pObject.Oid.Value; - pContext.AddressString = pObject.Customer.Person.Address.ToSingleLine(); - pContext.CostBearerDetailStrings = CreateCostBearerDetailStrings(pObject).ToArray(); - pContext.CustomerName = pObject.Customer.Person.LastNameFirstName; + pContext.SupportConceptOid = pObject.SupportConceptOid; + pContext.AddressString = pObject.Customer.GetSingleAddressLine(); + pContext.CostBearerDetailStrings = pObject.CostBearerDetailStrings?.ToArray(); + pContext.CustomerName = pObject.Customer.GetFirstNameLastName(); pContext.CustomerAlias = pObject.Customer.CustomerAlias; - pContext.CustomerDateOfBirth = pObject.Customer.Person.DateOfBirth; - pContext.CustomerPostcode = pObject.Customer.Person.Address.PostalCode; - } - - private List CreateCostBearerDetailStrings(SupportConcept pObject) - { - var rtn = new List(); - foreach (var cb2sc in pObject.CostBearer2SupportConceptList) - { - DateTime? from = null; - DateTime? to = null; - - from = cb2sc.ApprovedStartDate; - to = cb2sc.ApprovedEndDate; - - if (from == null) - { - from = cb2sc.RequestedStartDate; - } - - if (to == null) - { - to = cb2sc.RequestedEndDate; - } - - StringBuilder cbstr = new StringBuilder(); - - - if (from != null && to != null) - { - cbstr.Append(from.Value.ToShortDateString()); - cbstr.Append(" - "); - cbstr.Append(to.Value.ToShortDateString()); - } - - if (pObject.Customer.TerminationDate.HasValue) - { - String grund = ""; - if (!String.IsNullOrEmpty(pObject.Customer.TerminationReason?.Value)) - { - grund = ", Begründung: " + pObject.Customer.TerminationReason.Value; - } - cbstr.Append(String.Format(" (Betreuung beendet am: {0:dd.MM.yyyy}{1})", pObject.Customer.TerminationDate, grund)); - } - - if (cbstr.Length > 0) - { - cbstr.Append(" "); - } - - if (cb2sc.CostBearer.Organisation != null) - { - cbstr.Append(cb2sc.CostBearer.Organisation.Name); - } - - if (cb2sc.ApprovedStartDate == null) - { - cbstr.Append(" nicht bewilligt!"); - } - - String str = cbstr.ToString(); - - if (!String.IsNullOrEmpty(cb2sc.CustomerReferenceNumber)) - { - str = String.Format("{0}, {1}", str, cb2sc.CustomerReferenceNumber); - } - - if (!String.IsNullOrEmpty(cb2sc.AuswahlBezeichnung)) - { - str = String.Format("{0} {1}", cb2sc.AuswahlBezeichnung, str); - } - - rtn.Add(str); - } - - return rtn; + pContext.CustomerDateOfBirth = pObject.Customer.DateOfBirth; + pContext.CustomerPostcode = pObject.Customer.PostalCode; } } } diff --git a/AICore/Facade/LLM/BaseLLMApiClient.cs b/AICore/Facade/LLM/BaseLLMApiClient.cs index ecbaaf743..19daaded8 100644 --- a/AICore/Facade/LLM/BaseLLMApiClient.cs +++ b/AICore/Facade/LLM/BaseLLMApiClient.cs @@ -1,7 +1,6 @@ using BeWo.ServiceUtils.Core; using BS.Shared.DataContracts.Feature.AI; using BS.Shared.DataContracts; -using BS.Shared.Interface; using System; using System.Collections.Generic; using System.IO; diff --git a/AICore/Facade/LLM/OllamaApiClient.cs b/AICore/Facade/LLM/OllamaApiClient.cs index df768c8f3..d7299f913 100644 --- a/AICore/Facade/LLM/OllamaApiClient.cs +++ b/AICore/Facade/LLM/OllamaApiClient.cs @@ -7,7 +7,7 @@ using System; using System.Linq; using System.Net.Sockets; using System.Net; -using BeWo.Server.ApiFacade.Core; +using BS.Shared.ApiFacade; namespace AICore.Facade.LLM { diff --git a/AICore/Prompt/Core/AiUtils.cs b/AICore/Prompt/Core/AiUtils.cs index 7c949fccf..98e469601 100644 --- a/AICore/Prompt/Core/AiUtils.cs +++ b/AICore/Prompt/Core/AiUtils.cs @@ -1,4 +1,4 @@ -using BeWo.Data.Entities; +using BS.Shared.DataContracts; using BS.Shared.Exceptions; using System.Collections.Generic; @@ -6,7 +6,7 @@ namespace AICore.Prompt.Core { public static class AiUtils { - public static void CheckTokenSize(IList messages, string modelName, int max_context_size) + public static void CheckTokenSize(IList messages, string modelName, int max_context_size) { var buffer = 500; @@ -28,7 +28,7 @@ namespace AICore.Prompt.Core } } - private static int CalculateTokensByModel(IList messages, string modelName) + private static int CalculateTokensByModel(IList messages, string modelName) { var count = 0; diff --git a/BeWo/ViewModel/Light/InvoiceBaseLightVM.cs b/BeWo/ViewModel/Light/InvoiceBaseLightVM.cs index 27b487a74..23e7fbc91 100644 --- a/BeWo/ViewModel/Light/InvoiceBaseLightVM.cs +++ b/BeWo/ViewModel/Light/InvoiceBaseLightVM.cs @@ -3,7 +3,6 @@ using BeWo.ViewModel.ListViewModel; using BS.Shared.DataContracts; using BS.Shared; using BS.Shared.DataContracts.Light; -using BS.Shared.Interface; using BS.Shared.Translation; using System; using System.Collections.Generic; diff --git a/BeWoAI.sln b/BeWoAI.sln index f56b55032..3d0c7a261 100644 --- a/BeWoAI.sln +++ b/BeWoAI.sln @@ -53,8 +53,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AI", "AI", "{084C391D-FCE1- EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AiCoreUnitTest", "AiCoreUnitTest\AiCoreUnitTest.csproj", "{68C1F8EA-7828-4E46-8F04-91105C55860E}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ApiFacade", "Server\ApiFacade\ApiFacade.csproj", "{4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|.NET = Debug|.NET @@ -237,18 +235,6 @@ Global {68C1F8EA-7828-4E46-8F04-91105C55860E}.Release|Any CPU.Build.0 = Release|Any CPU {68C1F8EA-7828-4E46-8F04-91105C55860E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU {68C1F8EA-7828-4E46-8F04-91105C55860E}.Release|Mixed Platforms.Build.0 = Release|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Debug|.NET.ActiveCfg = Debug|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Debug|.NET.Build.0 = Debug|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Release|.NET.ActiveCfg = Release|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Release|.NET.Build.0 = Release|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Release|Any CPU.Build.0 = Release|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7}.Release|Mixed Platforms.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -272,7 +258,6 @@ Global {EC2349FB-7FE0-4AD1-B28B-A7A27AF80A57} = {FEB0336B-F053-40B6-92DD-7DE56AB9408A} {084C391D-FCE1-4984-87FA-F8F9CFCC6A4F} = {CCD6B644-49E7-4A11-BD8F-607088A4AC83} {68C1F8EA-7828-4E46-8F04-91105C55860E} = {084C391D-FCE1-4984-87FA-F8F9CFCC6A4F} - {4B2F3959-3CDA-4514-83A2-FA3C24E57BB7} = {FEB0336B-F053-40B6-92DD-7DE56AB9408A} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {5352BE53-F2FD-442F-85A8-4157599AA153} diff --git a/Data/Entities/Address.cs b/Data/Entities/Address.cs index f564fd113..ec47f079c 100644 --- a/Data/Entities/Address.cs +++ b/Data/Entities/Address.cs @@ -58,21 +58,5 @@ namespace BeWo.Data.Entities { return string.IsNullOrWhiteSpace(Street + Town + PostalCode); } - - public virtual string ToSingleLine() - { - var parts = new List - { - AddressLine1, - AddressLine2, - Street, - PostalCode, - Town, - State, - Country - }; - - return string.Join(", ", parts.Where(p => !string.IsNullOrWhiteSpace(p))); - } } } \ No newline at end of file diff --git a/Service/DCEntityMapper/Light/GkvAbrechnungLightDC_GkvAbrechnungLight.cs b/Service/DCEntityMapper/Light/GkvAbrechnungLightDC_GkvAbrechnungLight.cs index 03eb4e936..c22aa778e 100644 --- a/Service/DCEntityMapper/Light/GkvAbrechnungLightDC_GkvAbrechnungLight.cs +++ b/Service/DCEntityMapper/Light/GkvAbrechnungLightDC_GkvAbrechnungLight.cs @@ -5,7 +5,6 @@ using BS.Shared.DataContracts; using BS.Shared.DataContracts.Compact; using BS.Shared.DataContracts.Light; using BS.Shared.Extensions; -using BS.Shared.Interface; using System; using System.Collections.Generic; using System.Linq; diff --git a/Shared/ApiFacade/HttpClientFacade.cs b/Shared/ApiFacade/HttpClientFacade.cs new file mode 100644 index 000000000..73d94aea5 --- /dev/null +++ b/Shared/ApiFacade/HttpClientFacade.cs @@ -0,0 +1,231 @@ +using BS.Shared.Core; +using BS.Shared.DataContracts; +using BS.Shared.Exceptions; +using BS.Shared.Interface; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Diagnostics.Eventing.Reader; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Net.Security; +using System.Net.Sockets; +using System.Runtime.CompilerServices; +using System.Security.Authentication; +using System.Security.Cryptography.X509Certificates; +using System.Text; +using System.Threading.Tasks; + +namespace BS.Shared.ApiFacade +{ + public class HttpClientFacade + { + public HttpClientFacade(string base_url, string api_key, bool directConntect = true) + { + if (string.IsNullOrEmpty(base_url)) + throw new ArgumentNullException("HttpClient: base_url is missing"); + + if (string.IsNullOrWhiteSpace(api_key)) + throw new ArgumentNullException("HttpClient: token is missing"); + + Base_Url = base_url; + SetToken(api_key); + DirectConnect = directConntect; + } + + public bool DirectConnect { get; private set; } + public string Base_Url { get; private set; } + + public HttpMethod Method { get; set; } = HttpMethod.Get; + public Dictionary Headers { get; set; } = new Dictionary(); + public Dictionary Parameters { get; set; } = new Dictionary(); + public string ContentType { get; set; } = "application/x-www-form-urlencoded"; + public Encoding Encoding { get; set; } = Encoding.UTF8; + public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(30); + + /// + /// Führt einen Request aus, erwartet einen komplexen Datentyp: Schaue Verweise für Beispiele. + /// + /// + /// + /// + /// + /// + public virtual async Task> GetAnonymousTypeAsync(string method, T anonymousType, IApiErrorExtractor extractor) + { + var http_response = await getResponseAsync(method).ConfigureAwait(false); + + if (!http_response.IsSuccessStatusCode) + { + return ApiResponse.FailureResponse(AppError.ApiResponseFailed, http_response.ReasonPhrase, (int)http_response.StatusCode); + } + + var json = await http_response.Content.ReadAsStringAsync().ConfigureAwait(false); + + return parse(() => JsonConvert.DeserializeAnonymousType(json, anonymousType), json, extractor); + } + + /// + /// Führt einen Request aus, erwartet einen einfachen Datentyp wie: string, int, decimal, byte[] - + /// Liste kann gerne erweitert werden + /// + /// + /// + /// + /// + /// + public virtual async Task> GetAsync(string method, IApiErrorExtractor extractor) + { + var http_response = await getResponseAsync(method).ConfigureAwait(false); + + if (!http_response.IsSuccessStatusCode) + { + return ApiResponse.FailureResponse(AppError.ApiResponseFailed, http_response.ReasonPhrase, (int)http_response.StatusCode); + } + + var content = await http_response.Content.ReadAsStringAsync().ConfigureAwait(false); + object result; + + var type = typeof(T); + if (type == typeof(string)) + { + result = content; + } + else if (type == typeof(int)) + { + result = int.Parse(content); + } + else if (type == typeof(decimal)) + { + result = decimal.Parse(content); + } + else if (type == typeof(byte[])) + { + result = await http_response.Content.ReadAsByteArrayAsync().ConfigureAwait(false); + } + else + { + throw new BeWoInvalidOperationException(AppError.UnsupportedType(typeof(T))); + } + + return parse(() => (T)result, content, extractor); + } + + private static bool ServerCertificateCustomValidation(HttpRequestMessage requestMessage, X509Certificate2 certificate, X509Chain chain, SslPolicyErrors sslErrors) + { + // It is possible to inspect the certificate provided by the server. + Console.WriteLine($"Requested URI: {requestMessage.RequestUri}"); + Console.WriteLine($"Effective date: {certificate?.GetEffectiveDateString()}"); + Console.WriteLine($"Exp date: {certificate?.GetExpirationDateString()}"); + Console.WriteLine($"Issuer: {certificate?.Issuer}"); + Console.WriteLine($"Subject: {certificate?.Subject}"); + + // Based on the custom logic it is possible to decide whether the client considers certificate valid or not + Console.WriteLine($"Errors: {sslErrors}"); + return sslErrors == SslPolicyErrors.None; + } + + private protected virtual async Task getResponseAsync(string method) + { + var handler = new HttpClientHandler + { + ServerCertificateCustomValidationCallback = ServerCertificateCustomValidation, + SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls, + }; + + using (var client = new HttpClient(handler) { Timeout = Timeout }) + { + var requestUri = BS.Shared.Core.Utilities.WebUtils.CombineUrl(Base_Url, method); + + if (Method == HttpMethod.Get && Parameters.Count > 0) + { + var query = string.Join("&", Parameters.Select(p => $"{Uri.EscapeDataString(p.Key)}={Uri.EscapeDataString(p.Value)}")); + requestUri += (Base_Url.Contains("?") ? "&" : "?") + query; + } + + using (var request = new HttpRequestMessage(Method, requestUri)) + { + await checkForDirect(request).ConfigureAwait(false); + + // Add headers + foreach (var header in Headers) + request.Headers.TryAddWithoutValidation(header.Key, header.Value); + + // Add body if POST or PUT + if (Method == HttpMethod.Post || Method == HttpMethod.Put) + { + var content = new FormUrlEncodedContent(Parameters); + var bytes = await content.ReadAsByteArrayAsync().ConfigureAwait(false); + request.Content = new ByteArrayContent(bytes); + request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(ContentType); + } + + return await client.SendAsync(request).ConfigureAwait(false); + } + } + } + + private protected async Task checkForDirect(HttpRequestMessage request) + { + if (!DirectConnect || request.RequestUri is null) + return; + + var host = request.RequestUri.DnsSafeHost; + var isSslSession = request.RequestUri.ToString().StartsWith("https://"); + + try + { + // DNS-Auflösung für den Hostnamen durchführen + var ipAddresses = await Dns.GetHostAddressesAsync(host).ConfigureAwait(false); + + // Erste verfügbare IP-Adresse verwenden (IPv4 bevorzugen) + var targetIp = ipAddresses.FirstOrDefault(ip => ip.AddressFamily == AddressFamily.InterNetwork) + ?? ipAddresses.FirstOrDefault(); + + if (targetIp != null) + { + request.RequestUri = new Uri($"{(isSslSession ? "https://" : "http://")}{targetIp}{request.RequestUri.PathAndQuery}"); + request.Headers.Host = host; + } + } + catch (Exception ex) + { + // Fallback: Original URI beibehalten bei DNS-Fehlern + // Optional: Logging des Fehlers + Console.WriteLine($"DNS resolution failed for {host}: {ex.Message}"); + } + } + + private void SetToken(string api_key) + { + var key = nameof(HttpRequestHeader.Authorization); + var token = $"Bearer {api_key}"; + + if (Headers.ContainsKey(key)) + { + Headers[key] = token; + } + else + { + Headers.Add(key, token); + } + } + + private ApiResponse parse(Func func, string json, IApiErrorExtractor errorExtractor) + { + try + { + // Versuch, die erwartete Struktur zu deserialisieren + var data = func(); + + return ApiResponse.SuccessResponse(data); + } + catch (JsonException) + { + // Falls normale Deserialisierung fehlschlägt, versuche Fehler zu extrahieren + return ApiResponse.FailureResponse(AppError.JsonParsingError, errorExtractor.ExtractError(json).ToList()); + } + } + } +} diff --git a/Shared/ApiFacade/JsonHttpClientFacade.cs b/Shared/ApiFacade/JsonHttpClientFacade.cs new file mode 100644 index 000000000..13fbff7a5 --- /dev/null +++ b/Shared/ApiFacade/JsonHttpClientFacade.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using Newtonsoft.Json; + +namespace BS.Shared.ApiFacade +{ + public class JsonHttpClientFacade : HttpClientFacade + { + public object JsonObject { get; set; } + + public JsonHttpClientFacade(string base_url, string api_key, bool directConnect = true) : base(base_url, api_key, directConnect) + { + ContentType = "application/json"; + Method = HttpMethod.Post; + } + + private protected override async Task getResponseAsync(string method) + { + using (var client = new HttpClient { Timeout = Timeout }) + { + var requestUri = BS.Shared.Core.Utilities.WebUtils.CombineUrl(Base_Url, method); + + using (var request = new HttpRequestMessage(Method, requestUri)) + { + await checkForDirect(request).ConfigureAwait(false); + + // Add headers + foreach (var header in Headers) + request.Headers.TryAddWithoutValidation(header.Key, header.Value); + + // Add body if POST or PUT + if (Method == HttpMethod.Post || Method == HttpMethod.Put) + { + var json = JsonConvert.SerializeObject(JsonObject); + request.Content = new StringContent(json, Encoding, "application/json"); + } + + return await client.SendAsync(request).ConfigureAwait(false); + } + } + } + } +} diff --git a/Shared/ApiFacade/WebClientFacade.cs b/Shared/ApiFacade/WebClientFacade.cs new file mode 100644 index 000000000..1fd2bb2ab --- /dev/null +++ b/Shared/ApiFacade/WebClientFacade.cs @@ -0,0 +1,268 @@ +using BS.Shared.Extensions; +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Net; +using System.Security.Policy; +using System.Text; +using System.Threading.Tasks; + +namespace BS.Shared.ApiFacade +{ + public class WebClientFacade + { + // + // GET + // + protected TRes SendGet(string sub_url, string token = null) + => Get(sub_url, token); + protected Task SendGetAsync(string sub_url, string token = null) + => GetAsync(sub_url, token); + + // + // POST + // + protected TRes SendPostUploadString(string sub_url, TReq req, string token = null) + => SendUploadString(sub_url, "POST", req, token); + protected TRes SendPostUploadValues(string sub_url, TReq req, string token = null) + => SendUploadValues(sub_url, "POST", req, token); + protected byte[] SendPostUploadValuesRaw(string sub_url, TReq req, string token = null) + => SendUploadValuesRaw(sub_url, "POST", req, token); + protected Task SendPostUploadStringAsync(string sub_url, TReq req, string token = null) + => SendUploadStringAsync(sub_url, "POST", req, token); + protected Task SendPostUploadValuesAsync(string sub_url, TReq req, string token = null) + => SendUploadValuesAsync(sub_url, "POST", req, token); + protected Task SendPostUploadValuesAsyncRaw(string sub_url, TReq req, string token = null) + => SendUploadValuesRawAsync(sub_url, "POST", req, token); + + #region private + // + // Requests + // + private TRes Get(string sub_url, string token = null) + { + var url = getUrl(sub_url); + + string response = Get(url, token); + + return deserialize(response); + } + private TRes SendUploadString(string sub_url, string method, TReq req, string token = null) + { + var data = serializeJson(req); + var url = getUrl(sub_url); + + string response = SendUploadString(url, method, data, token); + + return deserialize(response); + } + private TRes SendUploadValues(string sub_url, string method, TReq req, string token = null) + { + var data = serialize(req); + var url = getUrl(sub_url); + + string response = SendUploadValues(url, method, data, token); + + return deserialize(response); + } + private byte[] SendUploadValuesRaw(string sub_url, string method, TReq req, string token = null) + { + var data = serialize(req); + var url = getUrl(sub_url); + + var response = SendUploadValuesRaww(url, method, data, token); + + return response; + } + private async Task GetAsync(string sub_url, string token = null) + { + var url = getUrl(sub_url); + + string response = await GetAsync(url, token); + + return deserialize(response); + } + private async Task SendUploadStringAsync(string sub_url, string method, TReq req, string token = null) + { + var data = serializeJson(req); + var url = getUrl(sub_url); + + string response = await SendUploadStringAsync(url, method, data, token); + + return deserialize(response); + } + private async Task SendUploadValuesAsync(string sub_url, string method, TReq req, string token = null) + { + var data = serialize(req); + var url = getUrl(sub_url); + + string response = await SendUploadValuesAsync(url, method, data, token); + + return deserialize(response); + } + private async Task SendUploadValuesRawAsync(string sub_url, string method, TReq req, string token = null) + { + var data = serialize(req); + var url = getUrl(sub_url); + + var response = await SendUploadValuesRawAsync(url, method, data, token); + + return response; + } + + // + // String + // + private string Get(string url, string token = null) + => exec(true, client => client.DownloadString(url), token); + private string SendUploadString(string url, string method, string request, string token = null) + => exec(false, client => client.UploadString(url, method, request), token); + private string SendUploadValues(string url, string method, T request, string token = null) + => exec(false, client => Encoding.UTF8.GetString(client.UploadValues(url, method, request?.ToNameValueCollection())), token); + private byte[] SendUploadValuesRaww(string url, string method, T request, string token = null) + => execraw(false, client => client.UploadValues(url, method, request?.ToNameValueCollection()), token); + private Task GetAsync(string url, string token = null) + => execasync(true, client => client.DownloadStringTaskAsync(url), token); + private Task SendUploadStringAsync(string url, string method, string request, string token = null) + => execasync(false, client => client.UploadStringTaskAsync(url, method, request), token); + private Task SendUploadValuesAsync(string url, string method, T request, string token = null) + => execasync(false, async client => Encoding.UTF8.GetString(await client.UploadValuesTaskAsync(url, method, request?.ToNameValueCollection()).ConfigureAwait(false)), token); + private Task SendUploadValuesRawAsync(string url, string method, T request, string token = null) + => execasyncraw(false, async client => await client.UploadValuesTaskAsync(url, method, request?.ToNameValueCollection()).ConfigureAwait(false), token); + + // + // Base + // + private string exec(bool override_header, Func action, string token = null) + { + string response; + + using (WebClient client = new WebClient()) + { + //client.Encoding = Encoding.Default; + client.Encoding = Encoding.UTF8; + + if (override_header) + client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); + + if (token != null) + client.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + token); + + response = action(client); + } + + return response; + } + private byte[] execraw(bool override_header, Func action, string token = null) + { + byte[] response; + + using (WebClient client = new WebClient()) + { + //client.Encoding = Encoding.Default; + client.Encoding = Encoding.UTF8; + + if (override_header) + client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); + + if (token != null) + client.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + token); + + response = action(client); + } + + return response; + } + private async Task execasync(bool override_header, Func> action, string token = null) + { + string response; + + using (WebClient client = new WebClient()) + { + //client.Encoding = Encoding.Default; + client.Encoding = Encoding.UTF8; + + if (override_header) + client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); + + if (token != null) + client.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + token); + + response = await action(client); + } + + return response; + } + private async Task execasyncraw(bool override_header, Func> action, string token = null) + { + byte[] response; + + using (WebClient client = new WebClient()) + { + //client.Encoding = Encoding.Default; + client.Encoding = Encoding.UTF8; + + if (override_header) + client.Headers.Add(HttpRequestHeader.ContentType, "application/json"); + + if (token != null) + client.Headers.Set(HttpRequestHeader.Authorization, "Bearer " + token); + + response = await action(client); + } + + return response; + } + + private T deserialize(string input) + { + if (string.IsNullOrEmpty(input)) + return default; + + if (typeof(T) == typeof(string)) + return (T)(object)input; + + if (typeof(T) == typeof(byte[])) + return (T)(object)Encoding.UTF8.GetBytes(input); + + var t = JsonConvert.DeserializeObject(input); + + return t; + } + private IDictionary serialize(T input) + { + return input?.ToKeyValue(); + } + private string serializeJson(T input) + { + if (typeof(T) == typeof(string)) + return input as string; + + var t = JsonConvert.SerializeObject(input); + + return t; + } + #endregion + + protected virtual string getKey() + { + return null; + } + + protected virtual string getUrl() + { + return null; + } + + private string getUrl(string sub_url) + { + var root = getUrl(); + var baseUri = new Uri(root); + var uri = new Uri(baseUri, sub_url); + var url = uri.ToString(); + return url; + } + } +} diff --git a/Shared/Core/AppError.cs b/Shared/Core/AppError.cs index 2d0f763dd..ef327d8eb 100644 --- a/Shared/Core/AppError.cs +++ b/Shared/Core/AppError.cs @@ -1,5 +1,4 @@ using BS.Shared.DataContracts; -using BS.Shared.Interface; using System; using System.Collections.Generic; using System.Linq; diff --git a/Shared/DataContracts/ApiResponse.cs b/Shared/DataContracts/ApiResponse.cs index 4fa3322b3..60af7c13b 100644 --- a/Shared/DataContracts/ApiResponse.cs +++ b/Shared/DataContracts/ApiResponse.cs @@ -1,5 +1,4 @@ using BS.Shared.Core; -using BS.Shared.Interface; using DevExpress.XtraRichEdit.Import.Html; using Newtonsoft.Json; using System; diff --git a/Shared/DataContracts/Compact/CompactCustomerDC.cs b/Shared/DataContracts/Compact/CompactCustomerDC.cs index e56363cbb..327398aa9 100644 --- a/Shared/DataContracts/Compact/CompactCustomerDC.cs +++ b/Shared/DataContracts/Compact/CompactCustomerDC.cs @@ -1,4 +1,6 @@ -using System; +using BS.Shared.Extensions; +using BS.Shared.Interface.Abstract; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Runtime.Serialization; @@ -8,8 +10,8 @@ namespace BS.Shared.DataContracts.Compact [DataContract, Serializable] [DebuggerDisplay("{LastName}, {FirstName}")] - public partial class CompactCustomerDC : IDataContract - { + public partial class CompactCustomerDC : IDataContract, IPersonNameable, IAddressable + { private Dictionary _CostBearerReferenceNumbers; private Dictionary _VarFieldValues; private Dictionary _VarFieldDefs; @@ -67,7 +69,9 @@ namespace BS.Shared.DataContracts.Compact [DataMember] public string PostalCode { get; set; } - [DataMember] + public string Postalcode => throw new NotImplementedException(); + + [DataMember] public Sex? Sex { get; set; } [DataMember] @@ -155,6 +159,10 @@ namespace BS.Shared.DataContracts.Compact [DataMember] public bool IsSubstitutionNeeded { get; set; } - //public List VarFields { get; set; } - } + + public string AddressLine1 => null; + public string AddressLine2 => null; + public string State => null; + public string Country => null; + } } \ No newline at end of file diff --git a/Shared/DataContracts/Compact/CompactEmployeeDC.cs b/Shared/DataContracts/Compact/CompactEmployeeDC.cs index 6a6680d15..eb0a5d1e1 100644 --- a/Shared/DataContracts/Compact/CompactEmployeeDC.cs +++ b/Shared/DataContracts/Compact/CompactEmployeeDC.cs @@ -2,12 +2,13 @@ using System.Collections.Generic; using System.Diagnostics; using System.Runtime.Serialization; +using BS.Shared.Interface.Abstract; namespace BS.Shared.DataContracts.Compact { [DataContract, Serializable] [DebuggerDisplay("{EmployeeOid}: {LastName}, {FirstName}")] - public partial class CompactEmployeeDC : IDataContract + public partial class CompactEmployeeDC : IDataContract, IPersonNameable { private List _RelatedCustomerOIDList; diff --git a/Shared/DataContracts/Compact/CompactOrganisationDC.cs b/Shared/DataContracts/Compact/CompactOrganisationDC.cs index 8ee9677c4..a18825092 100644 --- a/Shared/DataContracts/Compact/CompactOrganisationDC.cs +++ b/Shared/DataContracts/Compact/CompactOrganisationDC.cs @@ -1,4 +1,5 @@ -using System.Collections.Generic; +using BS.Shared.Interface.Abstract; +using System.Collections.Generic; using System.Diagnostics; using System.Runtime.Serialization; @@ -7,7 +8,7 @@ namespace BS.Shared.DataContracts.Compact [DataContract] [DebuggerDisplay("{Name}")] - public partial class CompactOrganisationDC : IDataContract + public partial class CompactOrganisationDC : IDataContract, IAddressable { private List _CostRatePeriods; @@ -105,5 +106,10 @@ namespace BS.Shared.DataContracts.Compact [DataMember] public string BusinessPartnerId { get; set; } - } + + + public string AddressLine2 => null; + public string State => null; + public string Country => null; + } } \ No newline at end of file diff --git a/Shared/DataContracts/Compact/CompactPersonDC.cs b/Shared/DataContracts/Compact/CompactPersonDC.cs index 4867f8ace..b81499a0b 100644 --- a/Shared/DataContracts/Compact/CompactPersonDC.cs +++ b/Shared/DataContracts/Compact/CompactPersonDC.cs @@ -1,12 +1,13 @@ using System; using System.Collections.Generic; using System.Runtime.Serialization; +using BS.Shared.Interface.Abstract; namespace BS.Shared.DataContracts.Compact { [DataContract] - public partial class CompactPersonDC : IDataContract - { + public partial class CompactPersonDC : IDataContract, IPersonNameable, IAddressable + { [DataMember] public ActivationTypeId ActivationType { get; set; } @@ -75,5 +76,10 @@ namespace BS.Shared.DataContracts.Compact [DataMember] public Sex? Geschlecht { get; set; } - } + + public string AddressLine1 => null; + public string AddressLine2 => null; + public string State => null; + public string Country => null; + } } \ No newline at end of file diff --git a/Shared/DataContracts/PersonDC.cs b/Shared/DataContracts/PersonDC.cs index 3ceefab1c..6ba968889 100644 --- a/Shared/DataContracts/PersonDC.cs +++ b/Shared/DataContracts/PersonDC.cs @@ -3,11 +3,13 @@ using System.Collections.Generic; using System.Runtime.Serialization; using BS.Shared.Core; +using BS.Shared.Extensions; +using BS.Shared.Interface.Abstract; namespace BS.Shared.DataContracts { [DataContract] - public class PersonDC : IDataContract + public class PersonDC : IDataContract, IPersonNameable, IAddressable { private List _ContactInformations; @@ -73,6 +75,10 @@ namespace BS.Shared.DataContracts } } + public string AddressLine2 => null; + public string State => null; + public string Country => null; + public bool ContainsAddressData() { return !Utils.AreAllNullOrEmpty(this.AddressLine1, this.Street, this.PostalCode, this.Town); @@ -93,5 +99,9 @@ namespace BS.Shared.DataContracts return !Utils.AreAllNullOrEmpty(this.FirstName, this.LastName, this.DateOfBirth, this.Sex, this.Profession, this.Abbreviation); } + public string GetInvoiceAddressSingleLine() + { + return AddressExtensions.ToSingleAddressLine(InvoiceAddressLine1, InvoiceAddressLine2, InvoiceAddressStreet, InvoiceAddressPostalCode, InvoiceAddressTown); + } } } \ No newline at end of file diff --git a/Shared/Extensions/AddressExtensions.cs b/Shared/Extensions/AddressExtensions.cs new file mode 100644 index 000000000..c20d5359d --- /dev/null +++ b/Shared/Extensions/AddressExtensions.cs @@ -0,0 +1,34 @@ +using BS.Shared.Interface.Abstract; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BS.Shared.Extensions +{ + public static class AddressExtensions + { + public static string ToSingleAddressLine(string addressline1, string addressline2, string street, string postalcode, string town, string state = null, string country = null) + { + var parts = new List + { + addressline1, + addressline2, + street, + postalcode, + town, + state, + country + }; + + return string.Join(", ", parts.Where(p => !string.IsNullOrWhiteSpace(p))); + } + + + public static string GetSingleAddressLine(this IAddressable addressable) + { + return ToSingleAddressLine(addressable.AddressLine1, addressable.AddressLine2, addressable.Street, addressable.PostalCode, addressable.Town, addressable.State, addressable.Country); + } + } +} diff --git a/Shared/Extensions/PersonNameableExtensions.cs b/Shared/Extensions/PersonNameableExtensions.cs new file mode 100644 index 000000000..7b19d5f03 --- /dev/null +++ b/Shared/Extensions/PersonNameableExtensions.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using BS.Shared.Interface.Abstract; + +namespace BS.Shared.Extensions +{ + public static class PersonNameableExtensions + { + public static string GetFirstNameLastName(this IPersonNameable personNameable, bool withcomma = false) + { + return $"{personNameable.FirstName}{(withcomma ? "," : null)} {personNameable.LastName}"; + } + + public static string GetLastNameFirstName(this IPersonNameable personNameable, bool withcomma = true) + { + return $"{personNameable.LastName}{(withcomma ? "," : null)} {personNameable.FirstName}"; + } + } +} diff --git a/Shared/Interface/Abstract/IAddressable.cs b/Shared/Interface/Abstract/IAddressable.cs new file mode 100644 index 000000000..e6f9acd34 --- /dev/null +++ b/Shared/Interface/Abstract/IAddressable.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BS.Shared.Interface.Abstract +{ + public interface IAddressable + { + string AddressLine1 { get; } + string AddressLine2 { get; } + string Street { get; } + string PostalCode { get; } + string Town { get; } + string State { get; } + string Country { get; } + } +} diff --git a/Shared/Interface/Abstract/IPersonNameable.cs b/Shared/Interface/Abstract/IPersonNameable.cs new file mode 100644 index 000000000..0c83126e0 --- /dev/null +++ b/Shared/Interface/Abstract/IPersonNameable.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BS.Shared.Interface.Abstract +{ + public interface IPersonNameable + { + string FirstName { get; } + string LastName { get; } + } +} diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index 6ee1fd046..6a003c129 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -134,6 +134,9 @@ + + + @@ -391,14 +394,18 @@ + + + +