Merge branch 'master' of ssh://float.ownsoft.de/git/beyondSoft/BeWo

This commit is contained in:
2026-05-19 15:54:25 +02:00
8 changed files with 154 additions and 82 deletions

View File

@@ -55,7 +55,7 @@ sr.ServiceDescriptionOid,
(select CONCAT(emp1p.`FirstName`, ' ', emp1p.`LastName`) from employee emp1 join `person` emp1p on emp1p.`Oid` = emp1.`PersonOid` where emp1.`Oid` in (select employeeoid from `employee2customer` e2c1 join `valuelistentry2object` vl2o on e2c1.`Oid` = vl2o.`ObjectOid` join `valuelistentry` vle on vl2o.`ValueListEntryOid` = vle.`Oid` where e2c1.`CustomerOid` = sc.CustomerOid and vle.`SystemEntryID` = 3) LIMIT 1) as 'Bezugsbetreuung',
(select name from ServiceDescription sd where sd.Oid = sr.ServiceDescriptionOid),
(select distinct zeitstempel from signature sig where sig.ServiceRecordOid = sr.Oid AND sig.IsActive = 1 order by zeitstempel desc limit 1),
(select emp2p.Abbreviation from employee emp2 join `person` emp2p on emp2p.`Oid` = emp2.`PersonOid` where emp2.`Oid` = sr.EmployeeOid),
(select COALESCE(NULLIF(emp2p.Abbreviation, ''), CONCAT(LEFT(emp2p.LastName, 4), LEFT(emp2p.FirstName, 1))) from employee emp2 join `person` emp2p on emp2p.`Oid` = emp2.`PersonOid` where emp2.`Oid` = sr.EmployeeOid),
(select cs.InsTs from confirmationreceiptsignature2servicerecord cs2s join confirmationreceiptsignature cs where cs.Oid = cs2s.ConfirmationReceiptSignatureOid and cs.IsActive = 1 and cs.EmployeeOid Is not null and cs2s.ServiceRecordOid = sr.oid LIMIT 1),
(select cs.InsTs from confirmationreceiptsignature2servicerecord cs2s join confirmationreceiptsignature cs where cs.Oid = cs2s.ConfirmationReceiptSignatureOid and cs.IsActive = 1 and cs.CustomerOid = c.Oid and cs2s.ServiceRecordOid = sr.oid LIMIT 1)
FROM servicerecord sr

View File

@@ -130,7 +130,7 @@ namespace FeidPartnerReports
bool vorhandeneEintraege = false;
if (serviceRecords != null && serviceRecords.Count > 0)
{
vorhandeneEintraege = serviceRecords.Any(s => s.Start.Value.Date >= start.Date && s.Start.Value.Date <= end.Date && s.RoundedDuration > 0 && s.ServiceDescription.Category.IsBillable);
vorhandeneEintraege = serviceRecords.Any(s => s.Start.Value.Date >= start.Date && s.Start.Value.Date < end.Date && s.RoundedDuration > 0 && s.ServiceDescription.Category.IsBillable);
}
return vorhandeneEintraege;
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using BeWo.Data.Access;
@@ -21,7 +21,7 @@ namespace FeidPartnerReports.Statistics
try
{
// Fahrtzeiten nicht in Ministatistik nur für Abrechnung
// Fahrtzeiten nicht in Ministatistik nur für Abrechnung
stat.PeriodStatistics = stat.PeriodStatistics.Where(p => p.SupportConceptApprovalPeriod.ServiceCategory == null || String.IsNullOrEmpty(p.SupportConceptApprovalPeriod.ServiceCategory.Abbreviation) ||
!p.SupportConceptApprovalPeriod.ServiceCategory.Abbreviation.Contains("FZQA")).ToList();
@@ -135,7 +135,7 @@ namespace FeidPartnerReports.Statistics
catch (Exception)
{
//Mach nichts. Das ist für den alten Mok bei dem die Felder MinutesFreePerWeekStatisticDate noch nicht in der alten Shared.dll existieren
//Mach nichts. Das ist für den alten Mok bei dem die Felder MinutesFreePerWeekStatisticDate noch nicht in der alten Shared.dll existieren
}
}
@@ -156,7 +156,7 @@ namespace FeidPartnerReports.Statistics
bool vorhandeneEintraege = false;
if (serviceRecords != null && serviceRecords.Count > 0)
{
vorhandeneEintraege = serviceRecords.Any(s => s.Start.Value.Date >= start.Date && s.Start.Value.Date <= end.Date && s.RoundedDuration > 0 && s.ServiceDescription.Category.IsBillable);
vorhandeneEintraege = serviceRecords.Any(s => s.Start.Value.Date >= start.Date && s.Start.Value.Date < end.Date && s.RoundedDuration > 0 && s.ServiceDescription.Category.IsBillable);
}
return vorhandeneEintraege;
}

View File

@@ -241,62 +241,87 @@ namespace LebenshilfeBadKreuznach.Invoicing
var preise = DAOFactory.GenericDAO.GetAllActive<Preis>();
int countWegeBG1 = 0;
int countWegeBG2 = 0;
if (invoicePeriod.StartDate < new DateTime(2025, 03, 01)) // alter Weg - Anzahl aller Zeiterfassungseinträge
if (invoicePeriod.StartDate > new DateTime(2025, 12, 31)) // neue Berechnung hat für alle Entfernungen einen Preis, die glauben aber noch nicht, dass das so bleibt
{
foreach (var sr in serviceRecordsInPeriod)
countWegeBG1 = serviceRecordsInPeriod.GroupBy(r => r.Start.Value.Date).Count(); // es darf für jeden Tag maximal einmal abgerechnet werden
if (countWegeBG1 > 0)
{
if (sr.ServiceDescription.CategoryName.ToLower().StartsWith("bg1"))
wegepauschale = GetPreis(preise, "Wegevergütung BG1", km, invoicePeriod.StartDate);
decimal anzahlWege = countWegeBG1;
var invoiceItem = new InvoiceItem();
invoiceItem.AmountPerUnit = wegepauschale;
invoiceItem.UnitCount = anzahlWege;
invoiceItem.AmountTotal = anzahlWege * wegepauschale;
invoiceItem.ItemPeriodStart = invoicePeriod.StartDate;
invoiceItem.ItemPeriodEnd = invoicePeriod.EndDate;
invoiceItem.RateFactor = null;
invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
invoiceItem.ItemDescription = "Wegevergütung";
if (scap != null)
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
items.Add(invoiceItem);
}
}
else
{
if (invoicePeriod.StartDate < new DateTime(2025, 03, 01)) // alter Weg - Anzahl aller Zeiterfassungseinträge
{
foreach (var sr in serviceRecordsInPeriod)
{
countWegeBG1++;
}
if (sr.ServiceDescription.CategoryName.ToLower().StartsWith("bg2"))
{
countWegeBG2++;
if (sr.ServiceDescription.CategoryName.ToLower().StartsWith("bg1"))
{
countWegeBG1++;
}
if (sr.ServiceDescription.CategoryName.ToLower().StartsWith("bg2"))
{
countWegeBG2++;
}
}
}
}
else // neuer Weg - Anzahl der Tage wo die Zeiterfassungseinträge vorkommen (max. 1 pro Tag)
{
countWegeBG1 = serviceRecordsInPeriod.Where(r => r.ServiceDescription.CategoryName.ToLower().StartsWith("bg1")).GroupBy(r => r.Start.Value.Date).Count();
countWegeBG2 = serviceRecordsInPeriod.Where(r => r.ServiceDescription.CategoryName.ToLower().StartsWith("bg2")).GroupBy(r => r.Start.Value.Date).Count();
}
else // neuer Weg - Anzahl der Tage wo die Zeiterfassungseinträge vorkommen (max. 1 pro Tag)
{
countWegeBG1 = serviceRecordsInPeriod.Where(r => r.ServiceDescription.CategoryName.ToLower().StartsWith("bg1")).GroupBy(r => r.Start.Value.Date).Count();
countWegeBG2 = serviceRecordsInPeriod.Where(r => r.ServiceDescription.CategoryName.ToLower().StartsWith("bg2")).GroupBy(r => r.Start.Value.Date).Count();
}
if (countWegeBG1 > 0)
{
wegepauschale = GetPreis(preise, "Wegevergütung BG1", km, invoicePeriod.StartDate);
decimal anzahlWege = countWegeBG1;
var invoiceItem = new InvoiceItem();
invoiceItem.AmountPerUnit = wegepauschale;
invoiceItem.UnitCount = anzahlWege;
invoiceItem.AmountTotal = anzahlWege * wegepauschale;
invoiceItem.ItemPeriodStart = invoicePeriod.StartDate;
invoiceItem.ItemPeriodEnd = invoicePeriod.EndDate;
invoiceItem.RateFactor = null;
invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
invoiceItem.ItemDescription = "Wegevergütung BG1";
if (scap != null)
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
if (countWegeBG1 > 0)
{
wegepauschale = GetPreis(preise, "Wegevergütung BG1", km, invoicePeriod.StartDate);
decimal anzahlWege = countWegeBG1;
var invoiceItem = new InvoiceItem();
invoiceItem.AmountPerUnit = wegepauschale;
invoiceItem.UnitCount = anzahlWege;
invoiceItem.AmountTotal = anzahlWege * wegepauschale;
invoiceItem.ItemPeriodStart = invoicePeriod.StartDate;
invoiceItem.ItemPeriodEnd = invoicePeriod.EndDate;
invoiceItem.RateFactor = null;
invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
invoiceItem.ItemDescription = "Wegevergütung BG1";
if (scap != null)
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
items.Add(invoiceItem);
}
if (countWegeBG2 > 0)
{
wegepauschale = GetPreis(preise, "Wegevergütung BG2", km, invoicePeriod.StartDate);
decimal anzahlWege = countWegeBG2;
var invoiceItem = new InvoiceItem();
invoiceItem.AmountPerUnit = wegepauschale;
invoiceItem.UnitCount = anzahlWege;
invoiceItem.AmountTotal = anzahlWege * wegepauschale;
invoiceItem.ItemPeriodStart = invoicePeriod.StartDate;
invoiceItem.ItemPeriodEnd = invoicePeriod.EndDate;
invoiceItem.RateFactor = null;
invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
invoiceItem.ItemDescription = "Wegevergütung BG2";
if (scap != null)
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
items.Add(invoiceItem);
}
if (countWegeBG2 > 0)
{
wegepauschale = GetPreis(preise, "Wegevergütung BG2", km, invoicePeriod.StartDate);
decimal anzahlWege = countWegeBG2;
var invoiceItem = new InvoiceItem();
invoiceItem.AmountPerUnit = wegepauschale;
invoiceItem.UnitCount = anzahlWege;
invoiceItem.AmountTotal = anzahlWege * wegepauschale;
invoiceItem.ItemPeriodStart = invoicePeriod.StartDate;
invoiceItem.ItemPeriodEnd = invoicePeriod.EndDate;
invoiceItem.RateFactor = null;
invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
invoiceItem.ItemDescription = "Wegevergütung BG2";
if (scap != null)
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
items.Add(invoiceItem);
items.Add(invoiceItem);
}
}
return items;
}

View File

@@ -180,7 +180,9 @@ namespace PerspektivenEV.Export
12 ii.Notice,
13 ii.AmountPerUnit,
14 ii.UnitCount,
15 ii.AmountTotal
15 ii.AmountTotal,
16 ib.CustomerOid,
17 ib.CostbearerOid
*/
//Kontonummer; Umsatz; Gegenkonto; Belegdatum; Kost 1; Belegfeld 1; Buchungstext; Festschreibung
@@ -193,6 +195,8 @@ namespace PerspektivenEV.Export
String itemDescription = "";
String unitDescription = "";
String isApproved = "";
long? cOid = null;
if (row[8] != null)
orgaName = row[8].ToString();
@@ -206,14 +210,35 @@ namespace PerspektivenEV.Export
if (row[12] != null)
isApproved = row[12].ToString();
if (row[16] != null)
cOid = long.Parse(row[16].ToString());
if (sb.Length > 0)
sb.AppendLine();
DateTime lastDate = new DateTime(date.Year, date.Month, 1);
lastDate = lastDate.AddMonths(1).AddDays(-1);
var debitor = "999998";
if (cOid != null)
{
var scs = DAOFactory.SearchDAO.GetAllActiveSupportConceptsByCustomers(new List<long>() { cOid.Value }, false).ToList();
if (scs != null && scs.Count != 0 && scs[0].CostBearer2SupportConceptList != null)
{
var sc = scs[0];
if (scs.Count > 1)
{
sc = scs.Where(p => p.StartDate < lastDate && p.EndDate > new DateTime(date.Year, date.Month, 1)).FirstOrDefault();
}
var cb2sc = sc.CostBearer2SupportConceptList.Where(sc => sc.CostBearer.Organisation.Name != "EIGENANTEIL" && sc.CostBearer.Organisation.Name != "SELBSTZAHLER").FirstOrDefault();
if (cb2sc != null && cb2sc.KontoHilfeplan != null && cb2sc.KontoHilfeplan.Length > 0)
{
debitor = cb2sc.KontoHilfeplan;
}
}
}
//sb.Append(String.Format("{0}", row[1])); //Debitornr. als Kontonummer
sb.Append("999998;");
sb.Append(debitor + ";");
sb.Append(String.Format("{0:0.00}", row[15])); //Umsatz - der Rechnungsposition
sb.Append(";");
//var gegenkto = GetErloeskonto(itemDescription, unitDescription, orgaName, isApproved);
@@ -573,7 +598,9 @@ namespace PerspektivenEV.Export
ii.Notice,
ii.AmountPerUnit,
ii.UnitCount,
ii.AmountTotal
ii.AmountTotal,
ib.RecipientCustomerOid,
ib.RecipientCostbearerOid
from
invoicebase ib
inner join invoiceitem ii on ii.InvoiceBaseOid = ib.Oid

View File

@@ -1,12 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Invoicing;
using BeWo.Service.Plugins;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using static BeWo.Report.ReportObjects.SettlementRO;
namespace VSDHammReports
{
@@ -27,15 +29,16 @@ namespace VSDHammReports
public override List<InvoiceItemDC> CreateInvoiceItems(Settlement2DC si, IList<ApprovalPeriod> apList, bool schneideBeiMaxAb)
{
//var items = base.CreateInvoiceItems(si, apList, true);
//var items = base.CreateInvoiceItems(si, apList, true);
//return items;
//return items;
//Übergangslösung um Fehlkontakte auch bei JA mit 0 % Ratefaktor zu identifzieren. Nur ii.ItemDesc = "Fehlkontakte" weicht vom Standard ab...
schneideBeiMaxAb = true;
// Übergangslösung um Fehlkontakte auch bei JA mit 0 % Ratefaktor zu identifzieren.
// AB, 19.05.2026: Anders als im Standard kann bei JA ein Fehlkontakt auch mit 100 % abgerechnet werden.
// Erkennung Abrechenbarkeit nachträglich eingeführt: if (!String.IsNullOrEmpty(approvalPeriod.Notice) && approvalPeriod.Notice == "Fehlkontakte") ff.
schneideBeiMaxAb = true;
List<InvoiceItemDC> iiList = new List<InvoiceItemDC>();
var apsByHourlyRate = new Dictionary<String, IList<ApprovalPeriod>>();
foreach (var ap in apList)
{
IList<ApprovalPeriod> list = null;
@@ -84,8 +87,18 @@ namespace VSDHammReports
rf = approvalPeriod.RateFactor.Value;
}
if (!String.IsNullOrEmpty(approvalPeriod.Notice) && approvalPeriod.Notice == "Fehlkontakte")
{
hr *= 0.8m;
{
var c2s = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(si.CostBearer2SupportConceptOid.Value);
var records = c2s.ServiceRecords;
if (records.Any(s => s.ServiceDescription.Name.Contains("Fehlkontakt")))
{
var fk = records.Where(s => s.ServiceDescription.Name.Contains("Fehlkontakt")).FirstOrDefault();
if (fk.ServiceDescription.ProzentAbrechnung.HasValue && fk.ServiceDescription.ProzentAbrechnung != 100)
{
var anteil = fk.ServiceDescription.ProzentAbrechnung.Value / 100;
hr *= anteil;
}
}
ii.ItemDescription = "Fehlkontakte";
}
}

View File

@@ -39,9 +39,12 @@ namespace VSDHammReports.Alt
hasFehlkontakte = true;
ii.ItemDescription = String.Format("{0:dd.MM.yyyy} bis {1:dd.MM.yyyy}", ii.ItemPeriodStart, ii.ItemPeriodEnd);
ii.ItemDescription += String.Format(": {0:0.##} Std. x {1:c}", ii.UnitCount, ii.AmountPerUnit);
ii.Notice = "Fehlkontakte - 80 % abrechenbar";
}
ii.Notice = "Fehlkontakte";
if (String.IsNullOrEmpty(pRO.RecipientOrganisation) || pRO.RecipientOrganisation.ToLower().StartsWith("lwl"))
{
ii.Notice += " - 80 % abrechenbar";
}
}
else
{
ii.ItemDescription = String.Format("{0:dd.MM.yyyy} bis {1:dd.MM.yyyy}", ii.ItemPeriodStart, ii.ItemPeriodEnd);

View File

@@ -112,18 +112,22 @@ namespace VSDHammReports
{
report = new VSDHammReports.QuittierungsbelegJA();
}
else if (kt.Contains("Jugendamt") || kt.Contains("jugendamt") || kt.Contains("Jugendamt der Stadt Hamm") || kt == "Jugendamt der Stadt Aachen"
|| kt == "Stadt Hamm Jugendamt Clearing" || kt == "Jugendamt Ahlen Wohnprojekt" || kt.Contains("Wohnprojekt")
else if (function == "LWL")
{
report = new VSDHammReports.Stundenzettel();
}
else if (kt.Contains("Jugendamt") || kt.Contains("jugendamt") || kt.Contains("Jugendamt der Stadt Hamm") || kt == "Jugendamt der Stadt Aachen"
|| kt == "Stadt Hamm Jugendamt Clearing" || kt == "Jugendamt Ahlen Wohnprojekt" || kt.Contains("Wohnprojekt")
|| function == "Jugendamt")
{
if (ro.StartDate < new DateTime(2016, 7, 1))
{
report = new VSDHammReports.QuittierungsbelegJA();
}
else
{
report = new VSDHammReports.LeistungsnachweisJA();
}
if (ro.StartDate < new DateTime(2016, 7, 1))
{
report = new VSDHammReports.QuittierungsbelegJA();
}
else
{
report = new VSDHammReports.LeistungsnachweisJA();
}
}
if (report == null)