From 9c3bd3f752d99d0e69e9da001f5059a6ce4609d0 Mon Sep 17 00:00:00 2001 From: HirschleM Date: Thu, 26 Feb 2026 15:00:24 +0100 Subject: [PATCH] MH: PZD Differenzrechnung --- .../Invoicing/CustomAccountingService.cs | 99 +++++++++++++++++++ .../RechnungAssistenz.Designer.cs | 17 +--- ReportImp/PZDDuesseldorf/RechnungAssistenz.cs | 39 +++++++- 3 files changed, 137 insertions(+), 18 deletions(-) diff --git a/ReportImp/PZDDuesseldorf/Invoicing/CustomAccountingService.cs b/ReportImp/PZDDuesseldorf/Invoicing/CustomAccountingService.cs index a0df0dbb1..d4b822d4d 100644 --- a/ReportImp/PZDDuesseldorf/Invoicing/CustomAccountingService.cs +++ b/ReportImp/PZDDuesseldorf/Invoicing/CustomAccountingService.cs @@ -77,7 +77,106 @@ namespace PZDDuesseldorf.Service neu.InvoiceDate = DateTime.Now; } + // Zusätzlich zur CustomerOID wird hier noch nach dem Abrechnungszeitraum gesucht, den die neue Rechnung hat. Die haben da bisschen Schmarn gemacht, durch den die + // Differenzrechnung sonst nicht funktioniert. + protected override ServiceInvoiceDC ErstelleDifferenzRechnung(DifferenzRechnungCheck item) + { + ServiceInvoiceDC diffRechnung = null; + var letzteRg = item.VorhandeneRechungen.OrderByDescending(r => r.ServiceInvoiceOid).FirstOrDefault(); + + letzteRg = item.VorhandeneRechungen.FirstOrDefault(r => item.NeueRechnung.InvoiceBase.CustomerOid == r.InvoiceBase.CustomerOid && item.NeueRechnung.InvoiceBase.PeriodString == r.InvoiceBase.PeriodString); + #region Standard + if (letzteRg != null) + { + if (item.NeueRechnung.ClaimSum == letzteRg.ClaimSum) + { + diffRechnung = item.NeueRechnung; + diffRechnung.InvoiceBase.NeuErstellen = false; + diffRechnung.InvoiceBase.Hinweise = String.Format("Rechnung wurde bereits erstellt"); + } + else + { + diffRechnung = new ServiceInvoiceDC(); + diffRechnung.OriginalZurDifferenz = item.NeueRechnung; + diffRechnung.InvoiceBase = new InvoiceBaseDC(); + CopyInvoiceBaseDC(item.NeueRechnung.InvoiceBase, diffRechnung); + + ServiceInvoice counterInvoice = new ServiceInvoice(); + var serviceInvoice = DAOFactory.SearchDAO.GetServiceInvoiceByInvoiceBaseOid(letzteRg.InvoiceBase.InvoiceBaseOid.Value); + + CopyServiceInvoice(serviceInvoice, counterInvoice); + SetzeStornoInfos(counterInvoice); + SetzeRechnungspositionenServiceInvoice(diffRechnung, counterInvoice, item); + + diffRechnung.InvoiceBase.NeuErstellen = true; + diffRechnung.InvoiceBase.Hinweise = String.Format("Rechnungsdifferenz zu Rechnung {0} in Höhe von {1:c}", letzteRg.InvoiceBase.InvoiceNumber, letzteRg.InvoiceBase.TotalAmount.Value); + } + } + + return diffRechnung; + #endregion; + } + // Nur überschrieben, da die für die Assistenzrechnung ein angepasstes Layout haben und der Text der Differenzpositionen im Standardformat nicht klappt + public override void SetzeRechnungspositionenServiceInvoice(ServiceInvoiceDC diffRechnung, ServiceInvoice counterInvoice, DifferenzRechnungCheck item) + { + #region Standard + var siDCAlt = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(counterInvoice); + if (siDCAlt.ServiceInvoicePeriods != null && siDCAlt.ServiceInvoicePeriods.Count > 0) + { + diffRechnung.ServiceInvoicePeriods = siDCAlt.ServiceInvoicePeriods; + } + + if (item.NeueRechnung.ServiceInvoicePeriods != null && item.NeueRechnung.ServiceInvoicePeriods.Count > 0) + { + if (diffRechnung.ServiceInvoicePeriods == null) + { + diffRechnung.ServiceInvoicePeriods = item.NeueRechnung.ServiceInvoicePeriods; + } + else + { + foreach (var NewSip in item.NeueRechnung.ServiceInvoicePeriods) + { + if (NewSip.InvoiceItems != null && NewSip.InvoiceItems.Count > 0) + { + if (NewSip.Customer != null && diffRechnung.ServiceInvoicePeriods.Any(s => s.Customer.CustomerOid == NewSip.Customer.CustomerOid) && + NewSip.SupportConceptApprovalPeriod != null && NewSip.SupportConceptApprovalPeriod.SupportConceptApprovalPeriodOid.HasValue + && diffRechnung.ServiceInvoicePeriods.Any(s => s.SupportConceptApprovalPeriod != null && s.SupportConceptApprovalPeriod.SupportConceptApprovalPeriodOid.HasValue + && s.SupportConceptApprovalPeriod.SupportConceptApprovalPeriodOid.Value == NewSip.SupportConceptApprovalPeriod.SupportConceptApprovalPeriodOid.Value)) + { + var ip = diffRechnung.ServiceInvoicePeriods.Where(s => s.SupportConceptApprovalPeriod != null && s.SupportConceptApprovalPeriod.SupportConceptApprovalPeriodOid.Value == NewSip.SupportConceptApprovalPeriod.SupportConceptApprovalPeriodOid.Value).First(); + if (ip.InvoiceItems != null && ip.InvoiceItems.Count > 0) + { + ip.Claim += NewSip.Claim; + foreach (var ii in NewSip.InvoiceItems) + { + ip.InvoiceItems.Add(ii); + } + + // Bei Rechnungspositionen mit negativem Betrag auf alte Rechnung verweisen + foreach (var iitem in ip.InvoiceItems) + { + if (iitem.AmountTotal < 0) + { + var vorhandeneRechnung = item.VorhandeneRechungen.FirstOrDefault(r => r.InvoiceBase != null && r.InvoiceBase.CustomerOid == ip.Customer.CustomerOid); + #endregion + if (vorhandeneRechnung != null) + iitem.ItemDescription = string.Format("{0} ({1:dd.MM.yyyy})", vorhandeneRechnung.InvoiceBase.InvoiceNumber, vorhandeneRechnung.InvoiceBase.InvoiceDate); + #region Standard + } + } + } + } + else + { + diffRechnung.ServiceInvoicePeriods.Add(NewSip); + } + } + } + } + } + #endregion + } public override List GetInvoiceBases(DateTime? startDate, DateTime? endDate, bool filterByInvoiceDate) { DateTime? end = endDate; diff --git a/ReportImp/PZDDuesseldorf/RechnungAssistenz.Designer.cs b/ReportImp/PZDDuesseldorf/RechnungAssistenz.Designer.cs index 255f4e482..ae963e53a 100644 --- a/ReportImp/PZDDuesseldorf/RechnungAssistenz.Designer.cs +++ b/ReportImp/PZDDuesseldorf/RechnungAssistenz.Designer.cs @@ -41,7 +41,6 @@ namespace PZDDuesseldorf this.xrLabel19 = new DevExpress.XtraReports.UI.XRLabel(); this.xrLabel9 = new DevExpress.XtraReports.UI.XRLabel(); this.lblAbrechnungstext = new DevExpress.XtraReports.UI.XRLabel(); - this.xrLabel1 = new DevExpress.XtraReports.UI.XRLabel(); this.xrLabel6 = new DevExpress.XtraReports.UI.XRLabel(); this.xrLabel8 = new DevExpress.XtraReports.UI.XRLabel(); this.xrTable1 = new DevExpress.XtraReports.UI.XRTable(); @@ -134,7 +133,6 @@ namespace PZDDuesseldorf this.xrLabel19, this.xrLabel9, this.lblAbrechnungstext, - this.xrLabel1, this.xrLabel6, this.xrLabel8, this.xrTable1, @@ -179,20 +177,10 @@ namespace PZDDuesseldorf this.lblAbrechnungstext.Multiline = true; this.lblAbrechnungstext.Name = "lblAbrechnungstext"; this.lblAbrechnungstext.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F); - this.lblAbrechnungstext.SizeF = new System.Drawing.SizeF(530.5417F, 17F); + this.lblAbrechnungstext.SizeF = new System.Drawing.SizeF(641.9999F, 17F); this.lblAbrechnungstext.StylePriority.UseFont = false; this.lblAbrechnungstext.Text = "1 Stunden * 20,20 € = 20,20 €"; // - // xrLabel1 - // - this.xrLabel1.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] { - new DevExpress.XtraReports.UI.XRBinding("Text", null, "InvoiceBase.InvoiceItems.GrossAmountTotal")}); - this.xrLabel1.LocationFloat = new DevExpress.Utils.PointFloat(568.0007F, 404.9133F); - this.xrLabel1.Name = "xrLabel1"; - this.xrLabel1.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 0, 0, 100F); - this.xrLabel1.SizeF = new System.Drawing.SizeF(100F, 23F); - this.xrLabel1.Text = "xrLabel1"; - // // xrLabel6 // this.xrLabel6.LocationFloat = new DevExpress.Utils.PointFloat(0.000890096F, 333.2883F); @@ -568,7 +556,7 @@ namespace PZDDuesseldorf this.lblAdresse.Text = "[RecipientOrganisation]\r\n[RecipientContactPerson]\r\n[RecipientDivision]\r\n[Recipien" + "tStreet]\r\n[RecipientPostCodeAndTown]"; // - // Rechnung + // RechnungAssistenz // this.Bands.AddRange(new DevExpress.XtraReports.UI.Band[] { this.Detail, @@ -635,7 +623,6 @@ namespace PZDDuesseldorf private DevExpress.XtraReports.UI.XRTableRow xrTableRow24; private DevExpress.XtraReports.UI.XRTableCell xrTableCell31; private DevExpress.XtraReports.UI.XRLabel xrLabel10; - private DevExpress.XtraReports.UI.XRLabel xrLabel1; private DevExpress.XtraReports.UI.XRLabel xrLabel18; private DevExpress.XtraReports.UI.XRLabel lblAbrechnungstext; private DevExpress.XtraReports.UI.XRLabel xrLabel9; diff --git a/ReportImp/PZDDuesseldorf/RechnungAssistenz.cs b/ReportImp/PZDDuesseldorf/RechnungAssistenz.cs index e46994dc0..4c80f6b06 100644 --- a/ReportImp/PZDDuesseldorf/RechnungAssistenz.cs +++ b/ReportImp/PZDDuesseldorf/RechnungAssistenz.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using System.Linq; using System.Text; using BeWo.Data.Access; using BeWo.Report; @@ -28,7 +30,11 @@ namespace PZDDuesseldorf decimal hourlyRateFk = 0; decimal hoursFk = 0; decimal amountFk = 0; + decimal hoursBereitsAbgerechnet = 0; + decimal amountBereitsAbgerechnet = 0; + List invoicenumbersBereitsAbgerechnet = new List(); bool fehlkontakt = false; + bool differenzrechnung = false; if (pRO.ServiceInvoicePeriods != null && pRO.ServiceInvoicePeriods.Count > 0) { @@ -38,7 +44,24 @@ namespace PZDDuesseldorf { foreach (var i in p.ServiceInvoiceItems) { - if (i.ServiceDescription.Contains("Fehlkontakt") && p.ServiceInvoiceItems.Count > 1) + if (i.NetAmount < 0) + { + differenzrechnung = true; + + if (i.Hours.HasValue) + { + hoursBereitsAbgerechnet += i.Hours.Value; + } + if (i.NetAmount.HasValue) + { + amountBereitsAbgerechnet += i.NetAmount.Value; + } + if (i.ServiceDescription != null) + { + invoicenumbersBereitsAbgerechnet.Add(i.ServiceDescription); + } + } + else if (i.ServiceDescription.Contains("Fehlkontakt") && p.ServiceInvoiceItems.Count > 1) { fehlkontakt = true; if (i.HourlyRate.HasValue) @@ -74,16 +97,26 @@ namespace PZDDuesseldorf } } + lblAbrechnungstext.Text = ""; + if (!String.IsNullOrEmpty(pRO.CustomerSalutation) && pRO.CustomerSalutation.ToLower() == "herr") pRO.CustomerSalutation = "Herrn"; + if (fehlkontakt) { - lblAbrechnungstext.Text = String.Format("{0:0.##} Stunden x {1:c} = {2:c}", hours, hourlyRate, amount); + lblAbrechnungstext.Text += String.Format("{0:0.##} Stunden x {1:c} = {2:c}", hours, hourlyRate, amount); lblAbrechnungstext.Text += String.Format("\n{0:0.##} Stunden Fehlkontakt x {1:c} = {2:c}", hoursFk, hourlyRateFk, amountFk); } else { - lblAbrechnungstext.Text = String.Format("{0:0.##} Stunden x {1:c} = {2}", hours, hourlyRate, pRO.NetClaim); + lblAbrechnungstext.Text += String.Format("{0:0.##} Stunden x {1:c} = {2:c}", hours, hourlyRate, amount); + } + if (differenzrechnung) + { + string rechnungsnummern = string.Join(", ", invoicenumbersBereitsAbgerechnet); + lblAbrechnungstext.Text += String.Format("\nAbzüglich bereits abgerechneter Stunden in Rechnung {0}: {1:c}\n", rechnungsnummern, amountBereitsAbgerechnet); + lblAbrechnungstext.Text += String.Format("\nRestbetrag: {0}", pRO.NetClaim); + } SetzeAdresse(pRO);