Files
BeWoPlaner/ReportImp/AsbRheinErftDuerenSBD/Invoicing/CustomInvoiceCreationAldenhoven.cs

213 lines
9.6 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.Invoicing;
using BeWo.Service.Plugins;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using BS.Shared.Services;
using DevExpress.Data.Helpers;
using Service.Invoicing;
namespace AsbRheinErftDuerenSBD.Invoicing
{
public class CustomInvoiceCreationAldenhoven : InvoiceCreation
{
public override void SetInvoiceId(ServiceInvoice invoice)
{
invoice.InvoiceBase.InvoiceId = "SBD Aldenhoven";
invoice.InvoiceBase.InvoiceTypeText = "Abrechnung Aldenhoven";
}
public override void CreateFixedAmounts(ServiceInvoicePeriod serviceInvoicePeriod, SupportConceptApprovalPeriodDC supportConceptApprovalPeriod, CostBearer2SupportConcept cb2sc)
{
var calc = PluginLoader.FindClass<Calculations>(_SpecificID) ?? Calculations.GetInstance(_SpecificID);
var data = calc.GetFixedBillingData(supportConceptApprovalPeriod, serviceInvoicePeriod.Start, serviceInvoicePeriod.End);
string bezeichnung;
if (!supportConceptApprovalPeriod.Notice.IsNullOrEmpty() && supportConceptApprovalPeriod.Notice.ToLower().Trim() == "fahrtkosten")
bezeichnung = "Fahrtkostenpauschale";
else if (supportConceptApprovalPeriod.ServiceCategory.Name.Contains("HK"))
{
bezeichnung = "Integrationshilfe HK ";
}
else if (supportConceptApprovalPeriod.ServiceCategory.Name.Contains("FK"))
{
bezeichnung = "Integrationshilfe FK ";
}
else
{
bezeichnung = "Integrationshilfe";
}
if (supportConceptApprovalPeriod.ApprovedBEPerInterval != null)
{
bezeichnung = String.Format("{0}{1:0.00}", bezeichnung, supportConceptApprovalPeriod.ApprovedBEPerInterval);
}
foreach (var billingData in data)
{
serviceInvoicePeriod.InvoiceItemList.Add(new InvoiceItem
{
AmountTotal = billingData.AmountTotal,
GrossAmountTotal = billingData.GrossAmountTotal,
ItemPeriodStart = billingData.BillingPeriodStart,
ItemPeriodEnd = billingData.BillingPeriodEnd,
AccountingInterval = billingData.AccountingInterval,
AmountPerUnit = billingData.AmountPerUnit,
UnitCount = billingData.UnitCount,
ItemDescription = bezeichnung
}); ;
}
}
public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap, Calculations calc)
{
IList<InvoiceItem> result = new List<InvoiceItem>();
var list = new List<InvoiceItem>();
foreach (ServiceRecordDC iServiceRecord in serviceRecordsInPeriod)
{
if (iServiceRecord.ServiceDescription.Category.IsBillable)
{
if (!iServiceRecord.AlreadyAccounted)
{
InvoiceItem invoiceItem = CreateInvoiceItem(iServiceRecord, scap, calc);
if (invoiceItem != null)
{
invoiceItem.ItemDescription = String.Format("{0} {1}", iServiceRecord.Employee.FirstName, iServiceRecord.Employee.LastName);
if (iServiceRecord.ServiceDescription.Category.Name.Contains("Sonstige"))
{
invoiceItem.ItemDescription += "\n" + iServiceRecord.ServiceDescription.Name;
}
list.Add(invoiceItem);
}
iServiceRecord.AlreadyAccounted = true;
}
}
}
Dictionary<String, bool> dayDict = new Dictionary<String, bool>();
foreach (var item in list)
{
String key = String.Format("{0:dd.MM.yyyy}", item.ItemPeriodStart);
if (!dayDict.ContainsKey(key))
{
dayDict.Add(key, true);
}
result.Add(item);
}
var newList = result.Where(i => i.UnitCount.HasValue && i.UnitCount.Value > 0).OrderBy(i => i.ItemPeriodStart).ToList();
return CreateSummaryInvoiceItems(newList, invoicePeriod, scap, calc);
}
// Claude: Der Stundensatz richtet sich nach der Qualifikation des dokumentierenden Mitarbeiters.
// Vorbild: TeamPfeil/Invoicing/CustomInvoiceCreation.cs (ohne Korridor-Logik).
public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc)
{
var invoiceItem = new InvoiceItem();
// Standardabrechnungsdaten des ServiceRecords. Diese berücksichtigen bereits die normale
// CostRatePeriod des Kostenträgers, ggf. überschrieben durch die CostRatePeriods der
// ServiceDescription bzw. ServiceCategory. Sie dienen als Fallback, wenn keine
// (passende) Mitarbeiterqualifikation gefunden wird.
BillingData bd = calc.GetBillingData(iServiceRecord);
decimal stundensatz = 0;
// Claude: Qualifikation des Mitarbeiters ermitteln.
var qualifikation = iServiceRecord.Employee.ValueListEntries
.FirstOrDefault(v => v.Value == ValueListEntryType.StaffQualificationsType);
long qualiOid = qualifikation.Key;
// Claude: Für diese Qualifikationen (OID 70/71) gibt es eigene Stundensätze im Kostenträger.
if (qualiOid == 70) // Fachkraft
{
stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, qualiOid, iServiceRecord.Start);
invoiceItem.ItemDescription = "Fachkraft";
}
else if (qualiOid == 71) // Hilfskraft
{
stundensatz = GetStundensatz(scap.CostBearer2SupportConcept, qualiOid, iServiceRecord.Start);
invoiceItem.ItemDescription = "Hilfskraft";
}
// Gibt es Stundensätze für Leistung oder Leistungskategorie, müssen die natürlich überschreiben
if (iServiceRecord.ServiceDescription.CostRatePeriods != null && iServiceRecord.ServiceDescription.CostRatePeriods.Count > 0)
{
var crp = iServiceRecord.ServiceDescription.CostRatePeriods.GetCostRatePeriodForDate(CostRatePeriodType.AmountOfMoney, iServiceRecord.Start.Value);
if (crp != null && crp.CostRateValue != null && crp.CostRateValue > 0)
{
stundensatz = crp.CostRateValue.Value;
}
}
else if (iServiceRecord.ServiceDescription.Category.CostRatePeriods != null && iServiceRecord.ServiceDescription.Category.CostRatePeriods.Count > 0)
{
var crp = iServiceRecord.ServiceDescription.Category.CostRatePeriods.GetCostRatePeriodForDate(CostRatePeriodType.AmountOfMoney, iServiceRecord.Start.Value);
if (crp != null && crp.CostRateValue != null && crp.CostRateValue > 0)
{
stundensatz = crp.CostRateValue.Value;
}
}
if (stundensatz != 0)
{
// Claude: Qualifikationsabhängiger Stundensatz gefunden -> diesen verwenden.
invoiceItem.AmountPerUnit = stundensatz;
invoiceItem.AmountTotal = stundensatz * bd.UnitCount;
invoiceItem.GrossAmountTotal = stundensatz * bd.UnitCount;
}
else
{
// Claude: Keine (passende) Qualifikation -> Standardabrechnung wie in InvoiceCreation.
invoiceItem.AmountPerUnit = bd.AmountPerUnit;
invoiceItem.AmountTotal = bd.AmountTotal;
invoiceItem.GrossAmountTotal = bd.GrossAmountTotal;
invoiceItem.ItemDescription = iServiceRecord.ServiceDescription.Name;
}
invoiceItem.UnitCount = bd.UnitCount;
invoiceItem.ItemPeriodStart = bd.BillingPeriodStart;
invoiceItem.ItemPeriodEnd = bd.BillingPeriodEnd;
invoiceItem.RateFactor = bd.RateFactor;
invoiceItem.AccountingInterval = bd.AccountingInterval;
invoiceItem.ServiceRecord = DAOFactory.GenericDAO.LoadByID<ServiceRecord>(iServiceRecord.ServiceRecordOid.Value);
if (scap != null)
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
return invoiceItem;
}
// Claude: Liefert den qualifikationsabhängigen Stundensatz (HourlyRate) des Kostenträgers, sonst 0.
private decimal GetStundensatz(CostBearer2SupportConcept c2s, long vleOid, DateTime? date)
{
if (c2s.CostBearer.CostRatePeriods != null)
{
// ValueListEntryOid:
// 70 Fachkraft
// 71 Hilfskraft
var crpList = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(c2s.CostBearer.CostRatePeriods);
var cp = crpList.GetCostRatePeriodForDate(CostRatePeriodType.HourlyRate, (DateTime)date, vleOid);
if (cp != null && cp.CostRateValue.HasValue)
{
return cp.CostRateValue.Value;
}
}
return 0;
}
}
}