MH: Lebenswert Rechnung + QB

This commit is contained in:
2023-07-03 16:44:26 +02:00
parent a9537cacd2
commit 24c304c2f9
9 changed files with 255 additions and 38 deletions

View File

@@ -29,9 +29,6 @@ namespace LebensWert.Invoicing
}
private const decimal AMOUNT_PER_KM_DEFAULT = 0.3m;
private const decimal AMOUNT_BEFORE_2023 = 15.28m;
private const decimal AMOUNT_SINCE_2023 = 16.24m;
//private ServiceCategory fahrtkostenServiceCategory = null;
private DateTime? accountingPeriodStart = null;
@@ -108,9 +105,9 @@ namespace LebensWert.Invoicing
UnitCount = unitCount,
ItemDescription = "Kontaktpauschale",
UnitDescription = "Pauschale pro direktem Kontakt",
AmountPerUnit = itemPeriodStart.Value.Year < 2023 ? AMOUNT_BEFORE_2023 : AMOUNT_SINCE_2023,
AmountTotal = itemPeriodStart.Value.Year < 2023 ? AMOUNT_BEFORE_2023 * unitCount : AMOUNT_SINCE_2023 * unitCount,
GrossAmountTotal = itemPeriodStart.Value.Year < 2023 ? AMOUNT_BEFORE_2023 * unitCount : AMOUNT_SINCE_2023 * unitCount,
AmountPerUnit = itemPeriodStart.Value.Year < 2023 ? PauschalenHelper.HANNOVER_AMOUNT_BEFORE_2023 : PauschalenHelper.HANNOVER_AMOUNT_SINCE_2023,
AmountTotal = itemPeriodStart.Value.Year < 2023 ? PauschalenHelper.HANNOVER_AMOUNT_BEFORE_2023 * unitCount : PauschalenHelper.HANNOVER_AMOUNT_SINCE_2023 * unitCount,
GrossAmountTotal = itemPeriodStart.Value.Year < 2023 ? PauschalenHelper.HANNOVER_AMOUNT_BEFORE_2023 * unitCount : PauschalenHelper.HANNOVER_AMOUNT_SINCE_2023 * unitCount,
ItemPeriodStart = itemPeriodStart,
ItemPeriodEnd = itemPeriodEnd
};

View File

@@ -70,8 +70,31 @@ namespace LebensWert.Invoicing
public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod,
SupportConceptApprovalPeriod scap, BS.Shared.Services.Calculations calc)
{
var list = base.CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, scap, calc);
var fitem = CreateFahrtkostenZoneItem(serviceRecordsInPeriod, invoicePeriod, scap);
var list = base.CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, scap, calc);
var crp = scap.CostBearer2SupportConcept.CostBearer.CostRatePeriods;
decimal minsProFLS = 60;
if (crp != null && crp.Count > 0)
{
var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit);
minsProFLS = minutesPerServiceUnit.CostRateValue.Value;
}
if (scap.CostBearer2SupportConcept.CostBearer.Organisation.Name.ToLower().Contains("neu"))
{
List<InvoiceItem> toAdd = new List<InvoiceItem>();
foreach (var item in list)
{
if (item.ItemDescription.ToLower() == "face-to-face" || item.ItemDescription.ToLower() == "face to face" || item.ItemDescription.ToLower() == "begleitende maßnahmen" || item.ItemDescription.ToLower() == "arztbesuch")
{
toAdd.Add(CreateKontaktpauschalenItem(serviceRecordsInPeriod.Count, item.ItemPeriodStart, item.ItemPeriodEnd));
}
}
if (toAdd.Count > 0)
list.AddRange(toAdd);
}
var fitem = CreateFahrtkostenZoneItem(serviceRecordsInPeriod, invoicePeriod, scap);
if (fitem != null)
list.Add(fitem);
@@ -123,7 +146,19 @@ namespace LebensWert.Invoicing
public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc)
{
var invoiceItem = base.CreateInvoiceItem(iServiceRecord, scap, calc);
if (iServiceRecord != null)
var crp = scap.CostBearer2SupportConcept.CostBearer.CostRatePeriods;
if (crp != null && crp.Count > 0)
{
var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit);
var minsProFLS = minutesPerServiceUnit != null ? minutesPerServiceUnit.CostRateValue : 60;
invoiceItem.UnitCount = invoiceItem.UnitCount * 60 / minsProFLS;
invoiceItem.GrossAmountTotal = invoiceItem.GrossAmountTotal * 60 / minsProFLS;
invoiceItem.AmountTotal = invoiceItem.AmountTotal * 60 / minsProFLS;
}
if (iServiceRecord != null)
{
var cat = iServiceRecord.ServiceDescription.CategoryName;
var desc = iServiceRecord.ServiceDescription.Name;
@@ -191,8 +226,23 @@ namespace LebensWert.Invoicing
return ii;
}
private InvoiceItem CreateKontaktpauschalenItem(decimal? unitCount, DateTime? itemPeriodStart, DateTime? itemPeriodEnd)
{
var ii = new InvoiceItem()
{
UnitCount = unitCount,
ItemDescription = "Kontaktpauschale",
UnitDescription = "Pauschale pro direktem Kontakt",
AmountPerUnit = PauschalenHelper.NIENBURG_AMOUNT_SINCE_2023,
AmountTotal = PauschalenHelper.NIENBURG_AMOUNT_SINCE_2023 * unitCount,
GrossAmountTotal = PauschalenHelper.NIENBURG_AMOUNT_SINCE_2023 * unitCount,
ItemPeriodStart = itemPeriodStart,
ItemPeriodEnd = itemPeriodEnd
};
public override string GetSummaryItemKey(SupportConceptApprovalPeriod scap, InvoiceItem iitem, bool summaryPerMonth)
return ii;
}
public override string GetSummaryItemKey(SupportConceptApprovalPeriod scap, InvoiceItem iitem, bool summaryPerMonth)
{
return String.Format("{0}_{1}_{2:yyyyMM}_{3}", iitem.AmountPerUnit, iitem.RateFactor, iitem.ItemPeriodStart, iitem.ItemDescription);
}

View File

@@ -1,5 +1,13 @@
using BeWo.Data.Entities;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Invoicing;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using BS.Shared.Services;
using System;
using System.Collections.Generic;
using System.Linq;
namespace LebensWert.Invoicing
{
@@ -10,5 +18,127 @@ namespace LebensWert.Invoicing
{
invoice.InvoiceBase.InvoiceId = "NI";
}
}
public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc)
{
var invoiceItem = base.CreateInvoiceItem(iServiceRecord, scap, calc);
var crp = scap.CostBearer2SupportConcept.CostBearer.CostRatePeriods;
if (crp != null && crp.Count > 0)
{
var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit);
var minsProFLS = minutesPerServiceUnit != null ? minutesPerServiceUnit.CostRateValue : 60;
//invoiceItem.UnitCount = invoiceItem.UnitCount * 60 / minsProFLS;
invoiceItem.GrossAmountTotal = invoiceItem.GrossAmountTotal * 60 / minsProFLS;
invoiceItem.AmountTotal = invoiceItem.AmountTotal * 60 / minsProFLS;
}
return invoiceItem;
}
public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod,
SupportConceptApprovalPeriod scap, BS.Shared.Services.Calculations calc)
{
var list = base.CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, scap, calc);
var crp = scap.CostBearer2SupportConcept.CostBearer.CostRatePeriods;
decimal minsProFLS = 60;
if (crp != null && crp.Count > 0)
{
var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit);
minsProFLS = minutesPerServiceUnit.CostRateValue.Value;
}
if (scap.CostBearer2SupportConcept.CostBearer.Organisation.Name.ToLower().Contains("neu"))
{
List<InvoiceItem> toAdd = new List<InvoiceItem>();
foreach (var item in list)
{
if (item.ItemDescription.ToLower() == "face-to-face" || item.ItemDescription.ToLower() == "face to face" || item.ItemDescription.ToLower() == "begleitende maßnahmen" || item.ItemDescription.ToLower() == "arztbesuch")
{
toAdd.Add(CreateKontaktpauschalenItem(serviceRecordsInPeriod.Count, item.ItemPeriodStart, item.ItemPeriodEnd));
}
}
if (toAdd.Count > 0)
list.AddRange(toAdd);
}
return list;
}
public override void BerechneSummaryItemsSummen(List<InvoiceItem> newlist, bool addRateFactorToUnitCount)
{
// Rausfinden, ob FLS 50 statt 60 Minuten gehen
//
var oid = newlist.FirstOrDefault(i => i.SupportConceptApprovalPeriodOid != null).SupportConceptApprovalPeriodOid;
SupportConceptApprovalPeriod ap = new SupportConceptApprovalPeriod();
if (oid != null)
ap = DAOFactory.GenericDAO.GetByID<SupportConceptApprovalPeriod>(oid.Value);
List<CostRatePeriod> crp = null;
if (ap != null)
crp = ap.CostBearer2SupportConcept.CostBearer.CostRatePeriods.ToList();
if (crp != null && crp.Count > 0)
{
var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit);
var minsProFLS = minutesPerServiceUnit != null ? minutesPerServiceUnit.CostRateValue : 60;
foreach (InvoiceItem invoiceItem in newlist)
{
if (!invoiceItem.AmountPerUnit.HasValue)
{
invoiceItem.AmountPerUnit = 0;
}
invoiceItem.AmountPerUnit = Math.Round(invoiceItem.AmountPerUnit.Value, 2, MidpointRounding.AwayFromZero);
if (!invoiceItem.UnitCount.HasValue)
{
invoiceItem.UnitCount = 0;
}
if (addRateFactorToUnitCount && invoiceItem.RateFactor.HasValue)
{
invoiceItem.UnitCount = (invoiceItem.UnitCount ?? 0) * ((invoiceItem.RateFactor + 100) / 100);
}
invoiceItem.UnitCount = Math.Round(invoiceItem.UnitCount.Value, 2, MidpointRounding.AwayFromZero);
// Änderung: Eine FLS hat 50 statt 60 Minuten
invoiceItem.AmountTotal = invoiceItem.AmountPerUnit * (invoiceItem.UnitCount * 60 / minsProFLS);
invoiceItem.AmountTotal = Math.Round(invoiceItem.AmountTotal.Value, 2, MidpointRounding.AwayFromZero);
invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
if (!addRateFactorToUnitCount && invoiceItem.RateFactor.HasValue)
{
invoiceItem.GrossAmountTotal *= ((invoiceItem.RateFactor + 100) / 100);
}
}
}
}
private InvoiceItem CreateKontaktpauschalenItem(decimal? unitCount, DateTime? itemPeriodStart, DateTime? itemPeriodEnd)
{
var ii = new InvoiceItem()
{
UnitCount = unitCount,
ItemDescription = "Kontaktpauschale",
UnitDescription = "Pauschale pro direktem Kontakt",
AmountPerUnit = PauschalenHelper.NIENBURG_AMOUNT_SINCE_2023,
AmountTotal = PauschalenHelper.NIENBURG_AMOUNT_SINCE_2023 * unitCount,
GrossAmountTotal = PauschalenHelper.NIENBURG_AMOUNT_SINCE_2023 * unitCount,
ItemPeriodStart = itemPeriodStart,
ItemPeriodEnd = itemPeriodEnd
};
return ii;
}
}
}

View File

@@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LebensWert.Invoicing
{
public class PauschalenHelper
{
public const decimal HANNOVER_AMOUNT_BEFORE_2023 = 15.28m;
public const decimal HANNOVER_AMOUNT_SINCE_2023 = 16.14m;
public const decimal NIENBURG_AMOUNT_SINCE_2023 = 15.56m;
}
}

View File

@@ -59,6 +59,7 @@
<Compile Include="Invoicing\CustomInvoiceCreationHI.cs" />
<Compile Include="Invoicing\CustomInvoiceFactory.cs" />
<Compile Include="Invoicing\CustomInvoiceCreationNI.cs" />
<Compile Include="Invoicing\PauschalenHelper.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Quittierungsbeleg.cs">
<SubType>Component</SubType>

View File

@@ -62,6 +62,7 @@ namespace LebensWert
this.xrTableCell7 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableCell43 = new DevExpress.XtraReports.UI.XRTableCell();
this.xrTableCell49 = new DevExpress.XtraReports.UI.XRTableCell();
this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
this.formattingRuleStartDate = new DevExpress.XtraReports.UI.FormattingRule();
this.ReportHeader = new DevExpress.XtraReports.UI.ReportHeaderBand();
this.xrLabel14 = new DevExpress.XtraReports.UI.XRLabel();
@@ -77,6 +78,7 @@ namespace LebensWert
this.formattingRuleCostBearer = new DevExpress.XtraReports.UI.FormattingRule();
this.formattingRuleEmployeeName = new DevExpress.XtraReports.UI.FormattingRule();
this.topMarginBand1 = new DevExpress.XtraReports.UI.TopMarginBand();
this.xrRichText5 = new DevExpress.XtraReports.UI.XRRichText();
this.bottomMarginBand1 = new DevExpress.XtraReports.UI.BottomMarginBand();
this.GroupFooter1 = new DevExpress.XtraReports.UI.GroupFooterBand();
this.xrLabel13 = new DevExpress.XtraReports.UI.XRLabel();
@@ -85,12 +87,10 @@ namespace LebensWert
this.xrLabel9 = new DevExpress.XtraReports.UI.XRLabel();
this.xrLabel1 = new DevExpress.XtraReports.UI.XRLabel();
this.fieldKontaktArt = new DevExpress.XtraReports.UI.CalculatedField();
this.xrRichText5 = new DevExpress.XtraReports.UI.XRRichText();
this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
((System.ComponentModel.ISupportInitialize)(this.xrTable3)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrTableServiceRecords1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText5)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText5)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this)).BeginInit();
//
// Detail
@@ -472,7 +472,7 @@ namespace LebensWert
this.xrTableCell7.StylePriority.UseBorders = false;
this.xrTableCell7.StylePriority.UseFont = false;
this.xrTableCell7.StylePriority.UseTextAlignment = false;
this.xrTableCell7.Text = "Minuten";
this.xrTableCell7.Text = "Zeitstunden";
this.xrTableCell7.TextAlignment = DevExpress.XtraPrinting.TextAlignment.TopCenter;
this.xrTableCell7.Weight = 0.23743016759776536D;
//
@@ -500,6 +500,10 @@ namespace LebensWert
this.xrTableCell49.TextAlignment = DevExpress.XtraPrinting.TextAlignment.TopCenter;
this.xrTableCell49.Weight = 0.44692737430167606D;
//
// bindingSource1
//
this.bindingSource1.DataSource = typeof(BeWo.Report.ReportObjects.ServicesOverviewRO);
//
// formattingRuleStartDate
//
this.formattingRuleStartDate.Condition = "[StartDate2] < [StartDate]";
@@ -706,6 +710,16 @@ namespace LebensWert
this.topMarginBand1.HeightF = 119.7917F;
this.topMarginBand1.Name = "topMarginBand1";
//
// xrRichText5
//
this.xrRichText5.Font = new System.Drawing.Font("Calibri", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.xrRichText5.LocationFloat = new DevExpress.Utils.PointFloat(34.99994F, 14.55589F);
this.xrRichText5.Name = "xrRichText5";
this.xrRichText5.SerializableRtfString = resources.GetString("xrRichText5.SerializableRtfString");
this.xrRichText5.SizeF = new System.Drawing.SizeF(677.0001F, 70.88823F);
this.xrRichText5.StylePriority.UseBackColor = false;
this.xrRichText5.StylePriority.UseFont = false;
//
// bottomMarginBand1
//
this.bottomMarginBand1.HeightF = 30F;
@@ -768,7 +782,7 @@ namespace LebensWert
this.xrLabel10.StylePriority.UseFont = false;
this.xrLabel10.StylePriority.UsePadding = false;
this.xrLabel10.StylePriority.UseTextAlignment = false;
this.xrLabel10.Text = "Fachleistungen in Minuten";
this.xrLabel10.Text = "Fachleistungen in Zeitstunden";
this.xrLabel10.TextAlignment = DevExpress.XtraPrinting.TextAlignment.MiddleLeft;
//
// xrLabel9
@@ -811,20 +825,6 @@ namespace LebensWert
this.fieldKontaktArt.FieldType = DevExpress.XtraReports.UI.FieldType.String;
this.fieldKontaktArt.Name = "fieldKontaktArt";
//
// xrRichText5
//
this.xrRichText5.Font = new System.Drawing.Font("Calibri", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.xrRichText5.LocationFloat = new DevExpress.Utils.PointFloat(34.99994F, 14.55589F);
this.xrRichText5.Name = "xrRichText5";
this.xrRichText5.SerializableRtfString = resources.GetString("xrRichText5.SerializableRtfString");
this.xrRichText5.SizeF = new System.Drawing.SizeF(677.0001F, 70.88823F);
this.xrRichText5.StylePriority.UseBackColor = false;
this.xrRichText5.StylePriority.UseFont = false;
//
// bindingSource1
//
this.bindingSource1.DataSource = typeof(BeWo.Report.ReportObjects.ServicesOverviewRO);
//
// Quittierungsbeleg
//
this.Bands.AddRange(new DevExpress.XtraReports.UI.Band[] {
@@ -850,8 +850,8 @@ namespace LebensWert
this.Version = "17.1";
((System.ComponentModel.ISupportInitialize)(this.xrTable3)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrTableServiceRecords1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText5)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.bindingSource1)).EndInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText5)).EndInit();
((System.ComponentModel.ISupportInitialize)(this)).EndInit();
}

View File

@@ -35,6 +35,7 @@ namespace LebensWert
{
if (sd.IsBillable && !sd.ServiceCategory.Contains("Fahrt")) // AB: ich bin mir nicht sicher ob die "Fahrt" hier noch maßgeblich ist...
{
sd.Minutes /= 60;
minuten += sd.Minutes;
ServicesOverviewRO.CreateSignatureString(sd);
if (sd.IsGroup)

View File

@@ -78,8 +78,8 @@ namespace LebensWert
this.xrLabel5 = new DevExpress.XtraReports.UI.XRLabel();
this.xrLabel1 = new DevExpress.XtraReports.UI.XRLabel();
this.xrLabel9 = new DevExpress.XtraReports.UI.XRLabel();
this.Minutes = new DevExpress.XtraReports.UI.CalculatedField();
this.bindingSource1 = new System.Windows.Forms.BindingSource(this.components);
this.Minutes = new DevExpress.XtraReports.UI.CalculatedField();
((System.ComponentModel.ISupportInitialize)(this.xrRichText5)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrRichText4)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.xrTable5)).BeginInit();
@@ -465,7 +465,7 @@ namespace LebensWert
this.xrTableCell43.Borders = ((DevExpress.XtraPrinting.BorderSide)(((DevExpress.XtraPrinting.BorderSide.Left | DevExpress.XtraPrinting.BorderSide.Top)
| DevExpress.XtraPrinting.BorderSide.Bottom)));
this.xrTableCell43.DataBindings.AddRange(new DevExpress.XtraReports.UI.XRBinding[] {
new DevExpress.XtraReports.UI.XRBinding("Text", null, "ServiceInvoicePeriods.ServiceInvoiceItems.Minutes", "{0:0}")});
new DevExpress.XtraReports.UI.XRBinding("Text", null, "ServiceInvoicePeriods.ServiceInvoiceItems.Hours", "{0:0}")});
this.xrTableCell43.Font = new System.Drawing.Font("Times New Roman", 11.25F);
this.xrTableCell43.Name = "xrTableCell43";
this.xrTableCell43.Padding = new DevExpress.XtraPrinting.PaddingInfo(2, 2, 2, 2, 100F);
@@ -706,16 +706,16 @@ namespace LebensWert
this.xrLabel9.StylePriority.UseFont = false;
this.xrLabel9.Text = "Mit freundlichen Grüßen";
//
// bindingSource1
//
this.bindingSource1.DataSource = typeof(BeWo.Report.ReportObjects.ServiceInvoiceRO);
//
// Minutes
//
this.Minutes.DataMember = "ServiceInvoicePeriods.ServiceInvoiceItems";
this.Minutes.Expression = "[UnitCount]*60";
this.Minutes.Name = "Minutes";
//
// bindingSource1
//
this.bindingSource1.DataSource = typeof(BeWo.Report.ReportObjects.ServiceInvoiceRO);
//
// RechnungNI
//
this.Bands.AddRange(new DevExpress.XtraReports.UI.Band[] {

View File

@@ -1,4 +1,5 @@
using System;
using System.Linq;
using BeWo.Data.Entities;
using BeWo.Report;
using BeWo.Report.ReportObjects;
@@ -38,6 +39,26 @@ namespace LebensWert
SetAnrede(pRO);
foreach (var sip in pRO.ServiceInvoicePeriods)
{
var crp = sip.CostBearer2SupportConcept.CostBearer.CostRatePeriods;
decimal minsProFLS = 60;
if (crp != null && crp.Count > 0)
{
var minutesPerServiceUnit = crp.FirstOrDefault(c => c.CostRateType == BS.Shared.CostRatePeriodType.MinutesPerServiceUnit);
minsProFLS = minutesPerServiceUnit.CostRateValue.Value;
}
foreach (var item in sip.ServiceInvoiceItems)
{
if (item.ServiceDescription == "Kontaktpauschale")
item.Hours *= minsProFLS;
else
item.Hours *= 60;
}
}
this.bindingSource1.DataSource = pRO;
}