diff --git a/Data/Data.csproj b/Data/Data.csproj
index 414469d07..f3d64fb46 100644
--- a/Data/Data.csproj
+++ b/Data/Data.csproj
@@ -199,6 +199,7 @@
+
@@ -709,6 +710,9 @@
+
+ Designer
+
Designer
diff --git a/Data/Entities/Address.cs b/Data/Entities/Address.cs
index fd156065c..0c679db82 100644
--- a/Data/Entities/Address.cs
+++ b/Data/Entities/Address.cs
@@ -161,5 +161,10 @@ namespace BeWo.Data.Entities
Town = this.Town
};
}
+
+ public string ToGoogle()
+ {
+ return $"{Street}, {PostalCode}, {Town}, {State}, {Country}";
+ }
}
}
\ No newline at end of file
diff --git a/Data/Entities/AddressRoute.cs b/Data/Entities/AddressRoute.cs
new file mode 100644
index 000000000..c45763447
--- /dev/null
+++ b/Data/Entities/AddressRoute.cs
@@ -0,0 +1,115 @@
+using BS.Shared;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BeWo.Data.Entities
+{
+ public class AddressRoute : BeWoEntityBase
+ {
+ private long address1_oid;
+ private long address1_version;
+ private long address2_oid;
+ private long address2_version;
+
+ private int distance_in_meter;
+ private int time_in_seconds;
+
+ public AddressRoute()
+ {
+ _Tid = TableID.AddressRoute;
+ }
+
+ public virtual long Address1_Oid
+ {
+ get
+ {
+ return address1_oid;
+ }
+ set
+ {
+ if (AreDifferent(address1_oid, value))
+ {
+ address1_oid = value;
+ }
+ }
+ }
+
+ public virtual long Address1_Version
+ {
+ get
+ {
+ return address1_version;
+ }
+ set
+ {
+ if (AreDifferent(address1_version, value))
+ {
+ address1_version = value;
+ }
+ }
+ }
+
+ public virtual long Address2_Oid
+ {
+ get
+ {
+ return address2_oid;
+ }
+ set
+ {
+ if (AreDifferent(address2_oid, value))
+ {
+ address2_oid = value;
+ }
+ }
+ }
+
+ public virtual long Address2_Version
+ {
+ get
+ {
+ return address2_version;
+ }
+ set
+ {
+ if (AreDifferent(address2_version, value))
+ {
+ address2_version = value;
+ }
+ }
+ }
+
+ public virtual int Distance_in_meter
+ {
+ get
+ {
+ return distance_in_meter;
+ }
+ set
+ {
+ if (AreDifferent(distance_in_meter, value))
+ {
+ distance_in_meter = value;
+ }
+ }
+ }
+
+ public virtual int Time_in_seconds
+ {
+ get
+ {
+ return time_in_seconds;
+ }
+ set
+ {
+ if (AreDifferent(time_in_seconds, value))
+ {
+ time_in_seconds = value;
+ }
+ }
+ }
+ }
+}
diff --git a/Data/Mappings/AddressRoute.hbm.xml b/Data/Mappings/AddressRoute.hbm.xml
new file mode 100644
index 000000000..cf0a9649b
--- /dev/null
+++ b/Data/Mappings/AddressRoute.hbm.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Host/Web.config b/Host/Web.config
index 0ec77dd6d..8b98d17ec 100644
--- a/Host/Web.config
+++ b/Host/Web.config
@@ -219,6 +219,8 @@
+
+
diff --git a/Model/Changes_2023_03_09_AddressRoute.txt b/Model/Changes_2023_03_09_AddressRoute.txt
new file mode 100644
index 000000000..ce4c5aae7
--- /dev/null
+++ b/Model/Changes_2023_03_09_AddressRoute.txt
@@ -0,0 +1,18 @@
+CREATE TABLE `AddressRoute` (
+ `Oid` bigint NOT NULL AUTO_INCREMENT,
+ `Tid` int DEFAULT NULL,
+ `IsActive` tinyint DEFAULT NULL,
+ `Notice` varchar(1024) DEFAULT NULL,
+ `InsTs` datetime DEFAULT NULL,
+ `InsUser` varchar(256) DEFAULT NULL,
+ `Version` bigint DEFAULT NULL,
+ `UdpUser` varchar(256) DEFAULT NULL,
+ `SystemEntryID` int DEFAULT NULL,
+ `Address1Oid` bigint DEFAULT NULL,
+ `Address1Version` bigint DEFAULT NULL,
+ `Address2Oid` bigint DEFAULT NULL,
+ `Address2Version` bigint DEFAULT NULL,
+ `DistanceMeter` int DEFAULT NULL,
+ `TimeSec` int DEFAULT NULL,
+ PRIMARY KEY (`Oid`)
+) ENGINE=InnoDB DEFAULT CHARSET=latin1;
\ No newline at end of file
diff --git a/Service/DCEntityMapper/AddressRouteDC_AddressRoute.cs b/Service/DCEntityMapper/AddressRouteDC_AddressRoute.cs
new file mode 100644
index 000000000..5e98dfe15
--- /dev/null
+++ b/Service/DCEntityMapper/AddressRouteDC_AddressRoute.cs
@@ -0,0 +1,64 @@
+using BeWo.Data.Entities;
+using BS.Shared.DataContracts;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BeWo.Service.DCEntityMapper
+{
+ public class AddressRouteDC_AddressRoute : AbstractIDCEntityMapper
+ {
+ public override AddressRouteDC MergeWithDC(AddressRoute pEntity, AddressRouteDC pDataContract)
+ {
+ pDataContract.Oid = pEntity.Oid;
+ pDataContract.IsActive = pEntity.IsActive;
+ pDataContract.Notice = pEntity.Notice;
+ pDataContract.InsTs = pEntity.InsTs;
+ pDataContract.InsUser = pEntity.InsUser;
+ pDataContract.Version = pEntity.Version;
+ pDataContract.UdpUser = pEntity.UdpUser;
+ pDataContract.SystemEntryID = pEntity.SystemEntryID;
+
+ pDataContract.Address1_Oid = pEntity.Address1_Oid;
+ pDataContract.Address1_Version = pEntity.Address1_Version;
+ pDataContract.Address2_Oid = pEntity.Address2_Oid;
+ pDataContract.Address2_Version = pEntity.Address2_Version;
+
+ pDataContract.Distance_in_meter = pEntity.Distance_in_meter;
+ pDataContract.Time_in_sec = pEntity.Time_in_seconds;
+
+ return pDataContract;
+ }
+
+ public override AddressRoute MergeWithEntity(AddressRouteDC pDataContract, AddressRoute pEntity)
+ {
+ this.ConcurrencyCheck(pDataContract.Version, pEntity);
+
+ pEntity.Oid = pDataContract.Oid;
+ pEntity.Notice = pDataContract.Notice;
+ pEntity.SystemEntryID = pDataContract.SystemEntryID;
+
+ pEntity.Address1_Oid = pDataContract.Address1_Oid;
+ pEntity.Address1_Version = pDataContract.Address1_Version;
+ pEntity.Address2_Oid = pDataContract.Address2_Oid;
+ pEntity.Address2_Version = pDataContract.Address2_Version;
+
+ pEntity.Distance_in_meter = pDataContract.Distance_in_meter;
+ pEntity.Time_in_seconds = pDataContract.Time_in_sec;
+
+ return pEntity;
+ }
+
+ protected override bool AreDCAndEntityEqual(AddressRouteDC pDC, AddressRoute pEntity)
+ {
+ if (pDC.Oid == null)
+ {
+ return false;
+ }
+
+ return pDC.Oid == pEntity.Oid;
+ }
+ }
+}
diff --git a/Service/DCEntityMapper/MapperFactory.cs b/Service/DCEntityMapper/MapperFactory.cs
index 76b3a0425..a34c246a7 100644
--- a/Service/DCEntityMapper/MapperFactory.cs
+++ b/Service/DCEntityMapper/MapperFactory.cs
@@ -288,6 +288,8 @@ namespace BeWo.Service.DCEntityMapper
private static AbwesenheitsInformationPrintDC_AbwesenheitsInformationPrint _AbwesenheitsInformationPrintDC_AbwesenheitsInformationPrint;
+ private static AddressRouteDC_AddressRoute _AddressRouteDC_AddressRoute;
+
public static MedRecordDC_MedRecord MedRecordDC_MedRecord =>
_MedRecordDC_MedRecord ?? (_MedRecordDC_MedRecord = new MedRecordDC_MedRecord());
@@ -723,5 +725,8 @@ namespace BeWo.Service.DCEntityMapper
public static AbwesenheitsInformationPrintDC_AbwesenheitsInformationPrint AbwesenheitsInformationPrintDC_AbwesenheitsInformationPrint =>
_AbwesenheitsInformationPrintDC_AbwesenheitsInformationPrint ?? (_AbwesenheitsInformationPrintDC_AbwesenheitsInformationPrint = new AbwesenheitsInformationPrintDC_AbwesenheitsInformationPrint());
+
+ public static AddressRouteDC_AddressRoute AddressRouteDC_AddressRoute =>
+ _AddressRouteDC_AddressRoute ?? (_AddressRouteDC_AddressRoute = new AddressRouteDC_AddressRoute());
}
}
\ No newline at end of file
diff --git a/Service/Service.csproj b/Service/Service.csproj
index 9b3c3d27a..c96a08dc6 100644
--- a/Service/Service.csproj
+++ b/Service/Service.csproj
@@ -169,6 +169,7 @@
..\packages\System.Memory.4.5.4\lib\net461\System.Memory.dll
+
..\packages\System.Numerics.Vectors.4.5.0\lib\net46\System.Numerics.Vectors.dll
@@ -218,6 +219,7 @@
+
@@ -481,6 +483,8 @@
+
+
@@ -527,7 +531,6 @@
-
diff --git a/Service/ServiceImplementations/OperationsServiceImp.cs b/Service/ServiceImplementations/OperationsServiceImp.cs
index ac383f2dc..d797b1a38 100644
--- a/Service/ServiceImplementations/OperationsServiceImp.cs
+++ b/Service/ServiceImplementations/OperationsServiceImp.cs
@@ -15,6 +15,7 @@ using BeWo.Service.Plugins;
using BeWo.Service.SBD;
using BeWo.Service.Security;
using BeWo.Service.ServiceContracts;
+using BeWo.Service.ServiceUtils.Generell;
using BeWo.Service.Vorlagen;
using BS.Shared;
using BS.Shared.Core;
@@ -7265,5 +7266,23 @@ namespace BeWo.Service.ServiceImplementations
DAOFactory.GenericDAO.Delete(signatures2Delete);
}
}
+
+ public AddressRouteDC GetAddressRouteInfo(long adr1_oid, long adr1_ver, long adr2_oid, long adr2_ver)
+ {
+ try
+ {
+ var address1 = DAOFactory.GenericDAO.LoadByID(adr1_oid);
+ var address2 = DAOFactory.GenericDAO.LoadByID(adr2_oid);
+
+ var res = AddressRouteManager.GetAddressRoute(address1, address2);
+
+ return MapperFactory.AddressRouteDC_AddressRoute.MapToNewDC(res);
+ }
+ catch (Exception exception)
+ {
+ throw Utils.CreateBeWoFaultException(exception);
+ }
+ }
+
}
}
diff --git a/Service/ServiceUtils/API/GoogleDistanceMatrixAPI.cs b/Service/ServiceUtils/API/GoogleDistanceMatrixAPI.cs
new file mode 100644
index 000000000..6b822ae80
--- /dev/null
+++ b/Service/ServiceUtils/API/GoogleDistanceMatrixAPI.cs
@@ -0,0 +1,106 @@
+using BeWo.Data.Entities;
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Configuration;
+using System.Linq;
+using System.Net.Http;
+using System.Text;
+using System.Threading.Tasks;
+using System.Web;
+
+namespace BeWo.Service.ServiceUtils.API
+{
+ public class GoogleDistanceMatrixApi
+ {
+ public class Response
+ {
+ public string Status { get; set; }
+
+ [JsonProperty(PropertyName = "origin_addresses")]
+ public string[] OriginAddresses { get; set; }
+
+ [JsonProperty(PropertyName = "destination_addresses")]
+ public string[] DestinationAddresses { get; set; }
+
+ public Row[] Rows { get; set; }
+
+ public class Data
+ {
+ public int Value { get; set; }
+ public string Text { get; set; }
+ }
+
+ public class Element
+ {
+ public string Status { get; set; }
+ public Data Duration { get; set; }
+ public Data Distance { get; set; }
+ }
+
+ public class Row
+ {
+ public Element[] Elements { get; set; }
+ }
+ }
+
+ private string Key { get; set; }
+ private string Url { get; set; }
+
+ private string[] OriginAddresses { get; set; }
+ private string[] DestinationAddresses { get; set; }
+
+ public GoogleDistanceMatrixApi(Address originAddress, Address destinationAddress) : this(new string[] { originAddress.ToGoogle() }, new string[] { destinationAddress.ToGoogle() })
+ {
+
+ }
+
+ public GoogleDistanceMatrixApi(string[] originAddresses, string[] destinationAddresses)
+ {
+ OriginAddresses = originAddresses;
+ DestinationAddresses = destinationAddresses;
+
+ var appSettings = ConfigurationManager.AppSettings;
+
+ if (string.IsNullOrEmpty(appSettings["GoogleDistanceMatrixApiUrl"]))
+ {
+ throw new Exception("GoogleDistanceMatrixApiUrl is not set in AppSettings.");
+ }
+ Url = appSettings["GoogleDistanceMatrixApiUrl"];
+
+ if (string.IsNullOrEmpty(appSettings["GoogleDistanceMatrixApiKey"]))
+ {
+ throw new Exception("GoogleDistanceMatrixApiKey is not set in AppSettings.");
+ }
+ Key = appSettings["GoogleDistanceMatrixApiKey"];
+ }
+
+ public async Task GetResponse()
+ {
+ using (var client = new HttpClient())
+ {
+ var uri = new Uri(GetRequestUrl());
+
+ HttpResponseMessage response = await client.GetAsync(uri);
+ if (!response.IsSuccessStatusCode)
+ {
+ throw new Exception("GoogleDistanceMatrixApi failed with status code: " + response.StatusCode);
+ }
+ else
+ {
+ var content = await response.Content.ReadAsStringAsync();
+ return JsonConvert.DeserializeObject(content);
+ }
+ }
+ }
+
+ private string GetRequestUrl()
+ {
+ OriginAddresses = OriginAddresses.Select(HttpUtility.UrlEncode).ToArray();
+ var origins = string.Join("|", OriginAddresses);
+ DestinationAddresses = DestinationAddresses.Select(HttpUtility.UrlEncode).ToArray();
+ var destinations = string.Join("|", DestinationAddresses);
+ return $"{Url}?origins={origins}&destinations={destinations}&key={Key}";
+ }
+ }
+}
diff --git a/Service/ServiceUtils/Generell/AddressRouteManager.cs b/Service/ServiceUtils/Generell/AddressRouteManager.cs
new file mode 100644
index 000000000..91f3ceaa3
--- /dev/null
+++ b/Service/ServiceUtils/Generell/AddressRouteManager.cs
@@ -0,0 +1,95 @@
+using BeWo.Data.Access;
+using BeWo.Data.Entities;
+using BeWo.Service.DCEntityMapper;
+using BeWo.Service.ServiceUtils.API;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BeWo.Service.ServiceUtils.Generell
+{
+ public static class AddressRouteManager
+ {
+ public static AddressRoute GetAddressRoute(Address address1, Address address2)
+ {
+ var routes = DAOFactory.GenericDAO.GetAll();
+
+ foreach (var route in routes)
+ {
+ if (route.Address1_Oid == address1.Oid && route.Address2_Oid == address2.Oid)
+ {
+ if (route.Address1_Version == address1.Version && route.Address2_Version == address2.Version)
+ {
+ // Route korrekt vorhanden
+ return route;
+ }
+ else
+ {
+ // Route vorhanden, aber Addresse hat update
+ return UpdateAddressRoute(route, address1, address2);
+ }
+ }
+ }
+
+ // Route nicht vorhanden
+ return InsertNewAddressRoute(address1, address2);
+ }
+
+ public static void DeleteAddressRoute(long oid) => DeleteAddressRoute(DAOFactory.GenericDAO.LoadByID(oid));
+
+ public static void DeleteAddressRoute(AddressRoute route)
+ {
+ if (route is object)
+ DAOFactory.GenericDAO.Delete(route);
+ }
+
+ public static AddressRoute InsertNewAddressRoute(Address address1, Address address2)
+ {
+ var newRoute = new AddressRoute
+ {
+ Address1_Oid = address1.Oid.Value,
+ Address2_Oid = address2.Oid.Value
+ };
+
+ RequestAddressRoute(ref newRoute, address1, address2);
+
+ DAOFactory.GenericDAO.Insert(newRoute);
+
+ return newRoute;
+ }
+
+ public static AddressRoute UpdateAddressRoute(AddressRoute route, Address address1, Address address2)
+ {
+ RequestAddressRoute(ref route, address1, address2);
+
+ DAOFactory.GenericDAO.Update(route);
+
+ return route;
+ }
+
+ public static AddressRoute RequestAddressRoute(ref AddressRoute route, Address address1, Address address2)
+ {
+ route.Address1_Version = address1.Version.Value;
+ route.Address2_Version = address2.Version.Value;
+
+ // Calculate Distance
+
+ var api = new GoogleDistanceMatrixApi(address1, address2);
+ var task = api.GetResponse();
+
+ task.Wait();
+
+ if(task.Exception is object)
+ {
+ throw task.Exception;
+ }
+
+ route.Distance_in_meter = task.Result.Rows[0].Elements[0].Distance.Value;
+ route.Time_in_seconds = task.Result.Rows[0].Elements[0].Duration.Value;
+
+ return route;
+ }
+ }
+}
diff --git a/Shared/BeWoEntityEnums.cs b/Shared/BeWoEntityEnums.cs
index 5de0154e2..24b9bdc03 100644
--- a/Shared/BeWoEntityEnums.cs
+++ b/Shared/BeWoEntityEnums.cs
@@ -160,7 +160,8 @@ namespace BS.Shared
RegelmaessigerDienst = 153,
GeschenkterUrlaubstag = 154,
Preis = 155,
- AbwesenheitsInformationPrint = 156
+ AbwesenheitsInformationPrint = 156,
+ AddressRoute = 160
}
public enum SystemEntryID
diff --git a/Shared/DataContracts/AddressRouteDC.cs b/Shared/DataContracts/AddressRouteDC.cs
new file mode 100644
index 000000000..602ae8b20
--- /dev/null
+++ b/Shared/DataContracts/AddressRouteDC.cs
@@ -0,0 +1,55 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Runtime.Serialization;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace BS.Shared.DataContracts
+{
+ public class AddressRouteDC : IDataContract
+ {
+ [DataMember]
+ public long? Oid { get; set; }
+
+ [DataMember]
+ public ActivationTypeId IsActive { get; set; }
+
+ [DataMember]
+ public string Notice { get; set; }
+
+ [DataMember]
+ public DateTime? InsTs { get; set; }
+
+ [DataMember]
+ public string InsUser { get; set; }
+
+ [DataMember]
+ public long? Version { get; set; }
+
+ [DataMember]
+ public string UdpUser { get; set; }
+
+ [DataMember]
+ public SystemEntryID? SystemEntryID { get; set; }
+
+ [DataMember]
+ public long Address1_Oid { get; set; }
+
+ [DataMember]
+ public long Address1_Version { get; set; }
+
+ [DataMember]
+ public long Address2_Oid { get; set; }
+
+ [DataMember]
+ public long Address2_Version { get; set; }
+
+ [DataMember]
+ public int Distance_in_meter { get; set; }
+
+ [DataMember]
+ public int Time_in_sec { get; set; }
+
+ }
+}
diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj
index d0b386020..fdf8aaea0 100644
--- a/Shared/Shared.csproj
+++ b/Shared/Shared.csproj
@@ -154,6 +154,7 @@
+