diff --git a/Data/Access/Criterias/GkvCriterias.cs b/Data/Access/Criterias/GkvCriterias.cs new file mode 100644 index 000000000..c5848b592 --- /dev/null +++ b/Data/Access/Criterias/GkvCriterias.cs @@ -0,0 +1,59 @@ +using BeWo.Data.Entities; +using BS.Shared; +using NHibernate; +using NHibernate.Criterion; +using NHibernate.SqlCommand; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Data.Access.Criterias +{ + public class GkvTransferprotokollCriteria + { + //public static ICriterion GetGkvTransferProtokollKostenpflichtigRestriction() + //{ + // var isEchtverfahren = Restrictions.Eq(Projections.Property(a => a.Verfahrensstufe), GkvVerfahrensstufe.Echt); + // var isErprobung = Restrictions.Eq(Projections.Property(a => a.Verfahrensstufe), GkvVerfahrensstufe.Erprobung); + // var isKnappschaft = Restrictions.Not(Restrictions.Like(Projections.Property(x => x.EmpfangerBezeichnung), "knappschaft")); + + // return Restrictions.Or(isEchtverfahren, Restrictions.And(isErprobung, isKnappschaft)); + //} + + //public static IQueryable GetGkvTransferProtokolle(ICriteria criteria) + //{ + + //} + + + + //public static IQueryable GetGkvTransferprotokoll(ICriteria criteria) + //{ + // var + + // var query = criteria + // .Join("gkvabrechnung", JoinType.InnerJoin) // a1.Oid = t1.GkvAbrechnungOid + // .Where(restriction => + // restriction.Ge("DATE(ErstelltAm)", new DateTime(2025, 1, 1)) // DATE(t1.ErstelltAm) >= '2025-01-01' + // .And(restriction.Le("DATE(ErstelltAm)", new DateTime(2025, 2, 28))) // DATE(t1.ErstelltAm) <= '2025-02-28' + // .And(restriction.Eq("Oid", GetMinOidSubquery(restriction))) // t1.Oid = (SELECT MIN(Oid)...) + // .And(restriction.Or( + // restriction.And(restriction.Eq("Verfahrensstufe", 1), restriction.NotLike("EmpfangerBezeichnung", "knappschaft%")), // a1.Verfahrensstufe = 1 AND t1.EmpfangerBezeichnung NOT LIKE 'knappschaft%' + // restriction.Eq("Verfahrensstufe", 2))) // OR a1.Verfahrensstufe = 2 + // ); + // return query; + //} + + //private static Subquery GetMinOidSubquery(ICriteriaBuilder criteriaBuilder) + //{ + // var subquery = criteriaBuilder.CreateSubquery() + // .Select(x => x.Oid) + // .Group(x => x.GkvAbrechnungOid) + // .Having(x => x.Min(t => t.Oid)); + + // return subquery; + //} + } +} diff --git a/Data/Access/DAOFactory.cs b/Data/Access/DAOFactory.cs index fb6c6e6cb..c93543798 100644 --- a/Data/Access/DAOFactory.cs +++ b/Data/Access/DAOFactory.cs @@ -10,6 +10,7 @@ namespace BeWo.Data.Access /// Kleiner Fix bzgl Threadsafe private static readonly Lazy _AdoDAO = new Lazy(() => new AdoDAO()); private static readonly Lazy _GenericDAO = new Lazy(() => new GenericDAO()); + private static readonly Lazy _GenericSearchDAO = new Lazy(() => new GenericSearchDAO()); private static readonly Lazy _FinanceDAO = new Lazy(() => new FinanceDAO()); private static readonly Lazy _OrganisationDAO = new Lazy(() => new OrganisationDAO()); private static readonly Lazy _ScriptDAO = new Lazy(() => new ScriptDAO()); @@ -18,6 +19,7 @@ namespace BeWo.Data.Access public static AdoDAO AdoDAO => _AdoDAO.Value; public static GenericDAO GenericDAO => _GenericDAO.Value; + public static GenericSearchDAO GenericSearchDAO => _GenericSearchDAO.Value; public static FinanceDAO FinanceDAO => _FinanceDAO.Value; public static OrganisationDAO OrganisationDAO => _OrganisationDAO.Value; public static ScriptDAO ScriptDAO => _ScriptDAO.Value; diff --git a/Data/Access/GenericSearchDAO.cs b/Data/Access/GenericSearchDAO.cs new file mode 100644 index 000000000..2b6b47874 --- /dev/null +++ b/Data/Access/GenericSearchDAO.cs @@ -0,0 +1,35 @@ +using BeWo.Data.Entities; +using BS.Shared; +using NHibernate.Criterion; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BeWo.Data.Access +{ + public class GenericSearchDAO : AbstractBaseDAO + { + internal GenericSearchDAO() { } + + public virtual T LoadEntityByProperty(Func propertyFunc, string propertyName = null) where T : BeWoEntityBase, new() + { + if (propertyName is null) + propertyName = nameof(propertyFunc); + + var criteria = CreateCriteria() + .Add(Restrictions.Eq(propertyName, propertyFunc)); + + var candidates = criteria.List(); + + if(candidates.Count == 1) + return candidates[0]; + + if (candidates.Count == 0) + throw new NotImplementedException("Count == 0"); + + throw new NotImplementedException("Count > 1"); + } + } +} diff --git a/Data/Access/ScriptDAO.cs b/Data/Access/ScriptDAO.cs index ce9268ace..b857adfe2 100644 --- a/Data/Access/ScriptDAO.cs +++ b/Data/Access/ScriptDAO.cs @@ -1,4 +1,5 @@ -using BS.Shared; +using BeWo.Data.Entities; +using BS.Shared; using DevExpress.XtraPrinting; using System; using System.Collections.Generic; @@ -41,5 +42,17 @@ namespace BeWo.Data.Access return rtn; } + + public IEnumerable GetGkvSumByDateRange2(DateTime? start, DateTime? end) + { + var sql = LoadSQLStatement("GetGkvSumByDateRange2.sql"); + + var rtn = Session.CreateSQLQuery(sql) + .SetParameter(0, start ?? DateTime.MinValue) + .SetParameter(1, end ?? DateTime.MaxValue) + .List(); + + return rtn; + } } } diff --git a/Data/Access/Scripts/GetGkvSumByDateRange.sql b/Data/Access/Scripts/GetGkvSumByDateRange.sql index 90c3fba73..d1522b13c 100644 --- a/Data/Access/Scripts/GetGkvSumByDateRange.sql +++ b/Data/Access/Scripts/GetGkvSumByDateRange.sql @@ -2,8 +2,8 @@ FROM gkvtransferprotokoll AS t1 JOIN gkvabrechnung a1 ON a1.Oid = t1.GkvAbrechnungOid -WHERE DATE(t1.ErstelltAm) >= ? -AND DATE(t1.ErstelltAm) <= ? +WHERE DATE(a1.ErstelltAm) >= ? +AND DATE(a1.ErstelltAm) <= ? AND t1.Oid = ( SELECT MIN(Oid) FROM gkvtransferprotokoll AS t2 diff --git a/Data/Access/Scripts/GetGkvSumByDateRange2.sql b/Data/Access/Scripts/GetGkvSumByDateRange2.sql new file mode 100644 index 000000000..981faf318 --- /dev/null +++ b/Data/Access/Scripts/GetGkvSumByDateRange2.sql @@ -0,0 +1,18 @@ +SELECT t1.Oid +FROM gkvtransferprotokoll AS t1 +JOIN gkvabrechnung a1 +ON a1.Oid = t1.GkvAbrechnungOid +WHERE DATE(a1.ErstelltAm) >= ? +AND DATE(a1.ErstelltAm) <= ? +AND t1.Oid = ( +SELECT MIN(Oid) +FROM gkvtransferprotokoll AS t2 +WHERE t1.GkvAbrechnungOid = t2.GkvAbrechnungOid +GROUP BY t2.GkvAbrechnungOid +) +AND +( +(a1.Verfahrensstufe = 1 AND t1.EmpfangerBezeichnung NOT LIKE 'knappschaft') +OR +a1.Verfahrensstufe = 2 +) \ No newline at end of file diff --git a/Data/Access/Scripts/GetGkvSumByDateRangeDebug.sql b/Data/Access/Scripts/GetGkvSumByDateRangeDebug.sql index b41ef5dcf..8a58a0e16 100644 --- a/Data/Access/Scripts/GetGkvSumByDateRangeDebug.sql +++ b/Data/Access/Scripts/GetGkvSumByDateRangeDebug.sql @@ -1,9 +1,9 @@ -SELECT * +SELECT a1.Oid as 'a1.oid', t1.Oid as 't1.oid', a1.ErstelltAm as 'a1.ErstelltAm', t1.EmpfangerBezeichnung, a1.AbrechnungsZeitraumStart, a1.AbrechnungsZeitraumEnde, a1.Verfahrensstufe, a1.UrbelegeGesendet, a1.Bezahlt, a1.Betrag FROM gkvtransferprotokoll AS t1 JOIN gkvabrechnung a1 ON a1.Oid = t1.GkvAbrechnungOid -WHERE DATE(t1.ErstelltAm) >= '2025-01-01' -AND DATE(t1.ErstelltAm) <= '2025-02-28' +WHERE DATE(a1.ErstelltAm) >= '2025-01-01' +AND DATE(a1.ErstelltAm) <= '2025-02-28' AND t1.Oid = ( SELECT MIN(Oid) FROM gkvtransferprotokoll AS t2 diff --git a/Data/Access/SearchDAO.cs b/Data/Access/SearchDAO.cs index d5d49294c..2b85c06d9 100644 --- a/Data/Access/SearchDAO.cs +++ b/Data/Access/SearchDAO.cs @@ -1812,7 +1812,7 @@ WHERE sc.Billable = 1 and sr.StartDate >= '{0:yyyy-MM-dd}' and sr.StartDate < '{ return lCriteria.List(); } - public IEnumerable GetInvoiceBases(DateTime? startDate, DateTime? endDate, long costBearerOid, String invoiceId) + public IEnumerable GetInvoiceBases(DateTime? startDate, DateTime? endDate, long costBearerOid, String invoiceId) { var lCriteria = CreateCriteriaIsActive(); diff --git a/Data/Data.csproj b/Data/Data.csproj index 544bfaef1..a7ff94fef 100644 --- a/Data/Data.csproj +++ b/Data/Data.csproj @@ -221,9 +221,11 @@ + + @@ -739,6 +741,7 @@ + PreserveNewest diff --git a/Host/Web.Secrets.config.template b/Host/Web.Secrets.config.template index 7af9b3a0e..ef52dc374 100644 --- a/Host/Web.Secrets.config.template +++ b/Host/Web.Secrets.config.template @@ -7,4 +7,10 @@ + + + + + + \ No newline at end of file diff --git a/Host/Web.config b/Host/Web.config index c25d5e19b..bf2cc4575 100644 --- a/Host/Web.config +++ b/Host/Web.config @@ -263,7 +263,7 @@ - + diff --git a/Service/ServiceBehavior/AdminServiceMessageInspector.cs b/Service/ServiceBehavior/AdminServiceMessageInspector.cs index c20d32981..62be5e1c8 100644 --- a/Service/ServiceBehavior/AdminServiceMessageInspector.cs +++ b/Service/ServiceBehavior/AdminServiceMessageInspector.cs @@ -8,6 +8,7 @@ using System.ServiceModel; using System.Text; using System.Threading.Tasks; using BeWo.Data; +using BeWo.Service.Core; namespace BeWo.Service.ServiceBehavior { @@ -34,7 +35,7 @@ namespace BeWo.Service.ServiceBehavior } // Hole erlaubten API Key aus den appSettings - string allowedApikey = ConfigurationManager.AppSettings["AdminServiceAPIKey"]; + string allowedApikey = MergedConfig.GetSetting("AdminServiceAPIKey"); // Extrahiert den API Key von Remote var prop = (HttpRequestMessageProperty)request.Properties[HttpRequestMessageProperty.Name]; diff --git a/Service/ServiceContracts/IAdminService.cs b/Service/ServiceContracts/IAdminService.cs index 89fe621ee..b823a5c7d 100644 --- a/Service/ServiceContracts/IAdminService.cs +++ b/Service/ServiceContracts/IAdminService.cs @@ -24,7 +24,7 @@ namespace BeWo.Service.ServiceContracts string Echo(string echo); [OperationContract] - [WebInvoke(UriTemplate = "/GetGkvSum", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] - object GetGkvAbrechnungSumme(AdminServiceSumReqDC request); + [WebInvoke(UriTemplate = "/GetGkvSum?detail={flag}", Method = "POST", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)] + AdminServiceSumResponseDC GetGkvAbrechnungSumme(AdminServiceSumReqDC request, string flag); } } diff --git a/Service/ServiceImplementations/AdminServiceImp.cs b/Service/ServiceImplementations/AdminServiceImp.cs index d5cc90488..cc30e8c81 100644 --- a/Service/ServiceImplementations/AdminServiceImp.cs +++ b/Service/ServiceImplementations/AdminServiceImp.cs @@ -1,11 +1,17 @@ using BeWo.Data.Access; +using BeWo.Data.Entities; +using BeWo.Data.Entities.Light; +using BeWo.Service.DCEntityMapper; using BeWo.Service.ServiceContracts; +using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts.AdminService; +using BS.Shared.Extensions; using DevExpress.Pdf.Native.BouncyCastle.Ocsp; using Newtonsoft.Json; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.ServiceModel; using System.Text; @@ -26,7 +32,7 @@ namespace BeWo.Service.ServiceImplementations return echo; } - public object GetGkvAbrechnungSumme(AdminServiceSumReqDC request) + public AdminServiceSumResponseDC GetGkvAbrechnungSumme(AdminServiceSumReqDC request, string detail) { if (request == null) { @@ -42,12 +48,54 @@ namespace BeWo.Service.ServiceImplementations { throw new ArgumentException("end entspricht nicht ISO8601 Norm."); } + + var res = new AdminServiceSumResponseDC(); + res.Sum = DAOFactory.ScriptDAO.GetGkvSumByDateRange(start, end); - var sum = DAOFactory.ScriptDAO.GetGkvSumByDateRange(start, end); + if (detail != "true") + { + return res; + } - var json = JsonUtils.ToSimpleJson("sum", sum); + string detail_res; - return json; + var protokolle_oids = DAOFactory.ScriptDAO.GetGkvSumByDateRange2(start, end); + if (protokolle_oids.HasContent()) + { + var protokolle = DAOFactory.GenericDAO.LoadByIDs(protokolle_oids); + var abrechnung_oids = protokolle.Select(x => x.GkvAbrechnungOid).Distinct(); + var abrechnung = DAOFactory.GenericDAO.LoadByIDs(abrechnung_oids); + var abrechnung_dc = MapperFactory.GkvAbrechnungLight.MapToNewDCs(abrechnung); + + res.Details = abrechnung_dc.Select(x => + { + var t = x.TransferProtokolle.First(); + var state = x.GetState(); + + return new AdminServiceSumResponseDetailDC() + { + Oid = x.Oid, + ProtokollOid = t.Oid.Value, + ErstelltAm = x.ErstelltAm.ToString("o", CultureInfo.InvariantCulture), + Empfanger = t.BezDatenannahmestelle, + AbrechnungsZeitraumStart = x.AbrechnungsZeitraumStart?.ToString("o", CultureInfo.InvariantCulture), + AbrechnungsZeitraumEnde = x.AbrechnungsZeitraumEnde?.ToString("o", CultureInfo.InvariantCulture), + VerfahrensstufeInt = x.Verfahrensstufe, + Verfahrensstufe = ((GkvVerfahrensstufe)x.Verfahrensstufe).ToString(), + StateInt = (int)state, + State = state.ToString(), + UrbelegeGesendet = x.UrbelegeGesendet, + Bezahlt = x.Bezahlt, + Betrag = x.Betrag + }; + }); + } + else + { + res.Details = new List(); + } + + return res; } } } diff --git a/Shared/Core/JsonUtils.cs b/Shared/Core/JsonUtils.cs index e5ffab409..7cb13ecfb 100644 --- a/Shared/Core/JsonUtils.cs +++ b/Shared/Core/JsonUtils.cs @@ -19,11 +19,18 @@ namespace BS.Shared.Core return JsonConvert.SerializeObject(dict); } - public static string ToJson(Dictionary dict) + public static string ConvertToJson(Dictionary dict) { var json = JsonConvert.SerializeObject(dict); return json; } + + public static string ConvertToJson(dynamic payload, Formatting formatting = Formatting.None) + { + var json = JsonConvert.SerializeObject((object)payload, formatting); + + return json; + } } } diff --git a/Shared/DataContracts/AdminService/AdminServiceSumResponseDC.cs b/Shared/DataContracts/AdminService/AdminServiceSumResponseDC.cs new file mode 100644 index 000000000..0ddb6c5fe --- /dev/null +++ b/Shared/DataContracts/AdminService/AdminServiceSumResponseDC.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace BS.Shared.DataContracts.AdminService +{ + [DataContract] + public class AdminServiceSumResponseDC : IAdminServiceDC + { + [DataMember(Name = "sum", Order = 1)] + public decimal? Sum { get; set; } + + [DataMember(Name = "details", EmitDefaultValue = false, Order = 2)] + public IEnumerable Details { get; set; } + } +} diff --git a/Shared/DataContracts/AdminService/AdminServiceSumResponseDetailDC.cs b/Shared/DataContracts/AdminService/AdminServiceSumResponseDetailDC.cs new file mode 100644 index 000000000..4cdd3909c --- /dev/null +++ b/Shared/DataContracts/AdminService/AdminServiceSumResponseDetailDC.cs @@ -0,0 +1,55 @@ +using BS.Shared.Interface; +using DevExpress.Mvvm.DataAnnotations; +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Runtime.Serialization; +using System.Text; +using System.Threading.Tasks; + +namespace BS.Shared.DataContracts.AdminService +{ + [DataContract] + public class AdminServiceSumResponseDetailDC : IAdminServiceDC + { + [DataMember(Name = "a.oid", Order = 1)] + public long Oid { get; set; } + + [DataMember(Name = "t.oid", Order = 2)] + public long ProtokollOid { get; set; } + + [DataMember(Name = "sum", Order = 3)] + public decimal Betrag { get; set; } + + [DataMember(Name = "paid", Order = 4)] + public bool Bezahlt { get; set; } + + [DataMember(Name = "urbelege_sent", Order = 5)] + public bool UrbelegeGesendet { get; set; } + + [DataMember(Name = "receiver", Order = 6)] + public string Empfanger { get; set; } + + [DataMember(Name = "create", Order = 7)] + public string ErstelltAm { get; set; } + + [DataMember(Name = "gkv_start", Order = 8)] + public string AbrechnungsZeitraumStart { get; set; } + + [DataMember(Name = "gkv_end", Order = 9)] + public string AbrechnungsZeitraumEnde { get; set; } + + [DataMember(Name = "level", Order = 10)] + public int VerfahrensstufeInt { get; set; } + + [DataMember(Name = "level_string", Order = 11)] + public string Verfahrensstufe { get; set; } + + [DataMember(Name = "state", Order = 20)] + public int StateInt { get; set; } + + [DataMember(Name = "state_string", Order = 21)] + public string State { get; set; } + } +} diff --git a/Shared/Extensions/IEnumerableTExtensions.cs b/Shared/Extensions/IEnumerableTExtensions.cs index e0e22de5b..cae14cf03 100644 --- a/Shared/Extensions/IEnumerableTExtensions.cs +++ b/Shared/Extensions/IEnumerableTExtensions.cs @@ -10,6 +10,12 @@ namespace BS.Shared.Extensions { public static class IEnumerableTExtensions { + public static bool HasNoContent(this IEnumerable values) + => !HasContent(values); + + public static bool HasContent(this IEnumerable values) + => values is IEnumerable && values.Any(); + public static bool ContainsSameItemsAs(this IEnumerable p1, IEnumerable pList) { if ((p1 == null || p1.Count() == 0) && (pList == null || pList.Count() == 0)) diff --git a/Shared/Shared.csproj b/Shared/Shared.csproj index c3e6108f1..37f92f697 100644 --- a/Shared/Shared.csproj +++ b/Shared/Shared.csproj @@ -178,6 +178,8 @@ + +