Files
BeWoPlaner/ReportImp/LebenshilfeFrankfurtOder/Invoicing/FudInvoiceCreation.cs

649 lines
25 KiB
C#

using BeWo.Data;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.Invoicing;
using BeWo.Service.Plugins;
using BeWo.Service.ServiceImplementations;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.Extensions;
using BS.Shared.Services;
using DevExpress.Office.Drawing;
using System;
using System.Collections.Generic;
using System.Linq;
namespace LebenshilfeFrankfurtOder.Invoicing
{
public class FudInvoiceCreation : InvoiceCreation
{
private const decimal AMOUNT_PER_KM = 0.4m;
private DateTime? accountingPeriodStart = null;
private DateTime? accountingPeriodEnd = null;
private bool istSelbstzahler = false;
private bool istPrivatrechnung = false;
private bool createTestInvoice = false;
private InvoiceItem mehrAlsMaxBetragVomKlientenZuZahlen = null;
public override void SetInvoiceId(ServiceInvoice invoice)
{
invoice.InvoiceBase.InvoiceId = "RechnungFud";
invoice.InvoiceBase.InvoiceTypeText = "FED";
}
public override List<ServiceInvoiceDC> GenerateServiceInvoices(long costBearerOid, DateTimeSpan invoicePeriod, Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>> supportConcepts2ServiceRecords)
{
var invoiceList = new List<ServiceInvoice>();
var invoiceCounter = 0;
//var sortedScs = supportConcepts2ServiceRecords.Keys.OrderBy(s => !String.IsNullOrEmpty(s.Customer.DebitorNumber) ? s.Customer.DebitorNumber : "zzzzz").ToList();
var sortedScs = supportConcepts2ServiceRecords.Keys.OrderBy(s =>
{
String name = s.Customer.LastNameFirstName;
if (s.CostBearerList.Count > 0)
{
name = String.Format("{0} {1}", s.CostBearerList[0].OrganisationName, name);
}
return name;
}).ToList();
foreach (var sc in sortedScs)
{
var serviceRecords = supportConcepts2ServiceRecords[sc];
if (sc.CostBearerList.Count > 0)
{
istSelbstzahler = false;
istPrivatrechnung = false;
var costBearer = DAOFactory.GenericDAO.LoadByID<CostBearer>(sc.CostBearerList[0].CostBearerOid);
if (costBearer.Organisation.Name.Contains("Selbstzahler"))
{
istSelbstzahler = true;
}
if (sc.Customer.VarFieldValues != null)
{
foreach (var vv in sc.Customer.VarFieldValues)
{
}
}
bool isPara45 = false;
foreach (var sr in serviceRecords)
{
if (sr.ServiceDescription.CategoryName.Replace(" ", "").Contains("§45"))
{
isPara45 = true;
}
}
mehrAlsMaxBetragVomKlientenZuZahlen = null;
if (isPara45)
{
createTestInvoice = true;
var testinvoice = CreateSingleInvoice(0, costBearer, invoicePeriod, sc, serviceRecords);
createTestInvoice = false;
foreach (var sr in serviceRecords)
{
sr.AlreadyAccounted = false;
}
if (testinvoice != null)
{
mehrAlsMaxBetragVomKlientenZuZahlen = GetMaxBetragItem(testinvoice);
}
}
if (istSelbstzahler || MussPrivatRechnungErstelltWerden(serviceRecords) || mehrAlsMaxBetragVomKlientenZuZahlen != null)
{
istPrivatrechnung = true;
var privateInvoice = CreateSingleInvoice(invoiceCounter, costBearer, invoicePeriod, sc, serviceRecords);
if (privateInvoice != null)
{
privateInvoice.InvoiceBase.InvoiceId = "RechnungFudPrivat";
SetzeCategory(privateInvoice, serviceRecords);
invoiceList.Add(privateInvoice);
invoiceCounter++;
}
}
if (!istSelbstzahler && MussKTRechnungErstelltWerden(serviceRecords))
{
istPrivatrechnung = false;
var invoice = CreateSingleInvoice(invoiceCounter, costBearer, invoicePeriod, sc, serviceRecords);
if (invoice != null)
{
SetzeCategory(invoice, serviceRecords);
invoiceList.Add(invoice);
//var maxBetrag = GetMaxBetrag(invoice);
//if (maxBetrag.HasValue && maxBetrag.Value > 0)
//{
// if (privateInvoice == null)
// {
// }
// SetzeMaxBetragAufPrivat(invoice, maxBetrag);
//}
invoiceCounter++;
}
}
}
}
var result = invoiceList.Select(item => MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(item)).ToList();
//return result.Count > 1 ? result.OrderBy(i => i.InvoiceBase.CustomerLastName).ToList() : result;
return result;
}
public override void SetSenderInformation(ServiceInvoice serviceInvoice)
{
ApplicationUser user = null;
if (LoggedInUserOperationContextExt.Current != null)
{
user = LoggedInUserOperationContextExt.Current.User;
}
else
{
user = SessionFacade.LoggedInUser;
}
var mandator = new OperationsServiceImp().GetMandator2(false);
serviceInvoice.InvoiceBase.SenderAddress = new Address
{
Street = mandator.Street,
PostalCode = mandator.PostalCode,
Town = mandator.Town,
State = mandator.State
};
if (user != null)
{
serviceInvoice.InvoiceBase.CreatorFirstName = serviceInvoice.InvoiceBase.SenderFirstName = user.Employee.Person.FirstName;
serviceInvoice.InvoiceBase.CreatorLastName = serviceInvoice.InvoiceBase.SenderLastName = user.Employee.Person.LastName;
serviceInvoice.InvoiceBase.SenderContacts = user.Employee.Person.Contacts.Select(i => i.CopyToNew()).ToList();
}
}
private InvoiceItem GetMaxBetragItem(ServiceInvoice invoice)
{
decimal? maxBetrag = null;
foreach (var sip in invoice.ServiceInvoicePeriodList)
{
if (sip.SupportConceptApprovalPeriod != null &&
sip.SupportConceptApprovalPeriod.ServiceCategory != null && sip.SupportConceptApprovalPeriod
.ServiceCategory.Name.Replace(" ", "").Contains("§45"))
{
if (sip.SupportConceptApprovalPeriod.ApprovedFixedAmount.HasValue &&
sip.SupportConceptApprovalPeriod.ApprovedFixedAmount.Value > 0)
{
maxBetrag = sip.SupportConceptApprovalPeriod.ApprovedFixedAmount;
}
}
}
var rechnungsBetrag = invoice.GetTotalClaim();
decimal? hourlyRate = null;
String desc = "";
String unit = "";
foreach (var sip in invoice.ServiceInvoicePeriodList)
{
foreach (var invoiceItem in sip.InvoiceItemList)
{
if (!hourlyRate.HasValue)
{
hourlyRate = invoiceItem.AmountPerUnit;
desc = invoiceItem.ItemDescription;
unit = invoiceItem.UnitDescription;
}
}
}
if (maxBetrag < rechnungsBetrag && hourlyRate.HasValue)
{
var ii = new InvoiceItem();
ii.AmountPerUnit = hourlyRate;
ii.AmountTotal = invoice.GetTotalClaim() - maxBetrag;
ii.ItemDescription = desc;
ii.UnitDescription = unit;
return ii;
}
return null;
}
private void SetzeCategory(ServiceInvoice i, List<ServiceRecordDC> records)
{
foreach (var sr in records)
{
i.Notice = String.Format("{0}", sr.ServiceDescription.Category.ServiceCategoryOid);
}
}
private bool MussPrivatRechnungErstelltWerden(List<ServiceRecordDC> records)
{
foreach (var sr in records)
{
if (MussPrivatAbgerechnetWerden(sr.ServiceDescription.Name))
{
return true;
}
}
return false;
}
private bool MussKTRechnungErstelltWerden(List<ServiceRecordDC> records)
{
foreach (var sr in records)
{
if (!MussPrivatAbgerechnetWerden(sr.ServiceDescription.Name))
{
return true;
}
}
return false;
}
private bool MussPrivatAbgerechnetWerden(String nameDerLeistung)
{
if (nameDerLeistung.Contains("Kurskosten") || nameDerLeistung.Contains("Mittag") || "FED Disco Verpflegung".Equals(nameDerLeistung))
{
return true;
}
return false;
}
public override ServiceInvoice CreateSingleInvoice(int invoiceCounter, CostBearer costBearer, DateTimeSpan invoicePeriod, CompactSupportConceptDC supportConcept, List<ServiceRecordDC> serviceRecords)
{
var i = base.CreateSingleInvoice(invoiceCounter, costBearer, invoicePeriod, supportConcept, serviceRecords);
if (i != null)
{
var claim = i.GetTotalClaim();
if (!claim.HasValue || claim.Value == 0)
{
return null;
}
}
return i;
}
public override void SetRecipientInformation(ServiceInvoice serviceInvoice, CostBearer costBearer)
{
if (istSelbstzahler || istPrivatrechnung)
{
if (serviceInvoice.InvoiceBase.CostBearer2SupportConcept != null)
{
var cust = serviceInvoice.InvoiceBase.CostBearer2SupportConcept.SupportConcept.Customer;
if (cust.Person.InvoiceAddress != null)
{
serviceInvoice.InvoiceBase.RecipientAddress = cust.Person.InvoiceAddress.CopyToNew();
}
else if (cust.Person.Address != null)
{
serviceInvoice.InvoiceBase.RecipientAddress = cust.Person.Address.CopyToNew();
}
serviceInvoice.InvoiceBase.RecipientPersonFirstName = cust.Person.FirstName;
serviceInvoice.InvoiceBase.RecipientPersonLastName = cust.Person.LastName;
}
}
else
{
base.SetRecipientInformation(serviceInvoice, costBearer);
}
}
public override void SetInvoiceBaseData(int invoiceCounter, ServiceInvoice invoice, CostBearer costBearer, DateTimeSpan invoicePeriod,
IList<CompactSupportConceptDC> supportConceptList)
{
if (invoicePeriod != null)
{
accountingPeriodStart = invoicePeriod.StartDate;
accountingPeriodEnd = invoicePeriod.EndDate;
}
base.SetInvoiceBaseData(invoiceCounter, invoice, costBearer, invoicePeriod, supportConceptList);
}
public override void SetServiceInvoicePeriods(ServiceInvoice invoice, CostBearer2SupportConcept costBearer2SupportConcept,
DateTimeSpan invoicePeriod, List<ServiceRecordDC> serviceRecords)
{
var invoiceAccountingPeriodSpan = new DateTimeSpan
{
StartDateTime = invoice.InvoiceBase.AccountingPeriodStart.Value,
EndDateTime = invoice.InvoiceBase.AccountingPeriodEnd.Value
};
foreach (SupportConceptApprovalPeriod iPeriod in costBearer2SupportConcept.ApprovalPeriodList)
{
SupportConceptApprovalPeriodDC approvalPeriodDC = MapperFactory.SupportConceptApprovalPeriodDC_SupportConceptApprovalPeriod.MapToNewDC(iPeriod);
if (approvalPeriodDC.Span.EndDateTime < invoiceAccountingPeriodSpan.StartDateTime || approvalPeriodDC.Span.StartDateTime > invoiceAccountingPeriodSpan.EndDate)
{
continue;
}
ServiceInvoicePeriod serviceInvoicePeriod = CreateServiceInvoicePeriod(approvalPeriodDC, invoiceAccountingPeriodSpan);
serviceInvoicePeriod.SupportConceptApprovalPeriod = iPeriod;
serviceInvoicePeriod.Customer = costBearer2SupportConcept.SupportConcept.Customer;
CostBearer costBearer = costBearer2SupportConcept.CostBearer;
List<CostRatePeriodDC> costRates = MapperFactory.CostRatePeriodDC_CostRatePeriod.MapToNewDCs(costBearer.CostRatePeriods);
CostRatePeriodDC serviceUnit = costRates.GetCostRatePeriodForDate(CostRatePeriodType.MinutesPerServiceUnit, DateTime.Now);
serviceInvoicePeriod.ServiceUnitName = serviceUnit.UnitName;
SetInvoiceItems(invoice, serviceInvoicePeriod, approvalPeriodDC, costBearer2SupportConcept, invoicePeriod, serviceRecords);
if (serviceInvoicePeriod.InvoiceItemList.Count > 0)
invoice.ServiceInvoicePeriodList.Add(serviceInvoicePeriod);
}
}
public virtual void SetInvoiceItems(ServiceInvoice invoice,
ServiceInvoicePeriod serviceInvoicePeriod,
SupportConceptApprovalPeriodDC supportConceptApprovalPeriod,
CostBearer2SupportConcept cb2sc,
DateTimeSpan invoicePeriod,
List<ServiceRecordDC> serviceRecords)
{
Calculations calc = PluginLoader.FindClass<Calculations>(_SpecificID) ??
Calculations.GetInstance(_SpecificID);
List<ServiceRecordDC> serviceRecordsInPeriod = serviceRecords.Where(
i =>
{
bool valid = i.Start.Value.InBetween(serviceInvoicePeriod.Start.Value, serviceInvoicePeriod.End.Value, true);
if (valid)
{
String cat = i.ServiceDescription.CategoryName.ToLower().Trim().Replace(" ", "");
if (cat.Contains("§45") || cat.Contains("§42") || cat.Contains("§39"))
{
if (MussPrivatAbgerechnetWerden(i.ServiceDescription.Name))
{
valid = istPrivatrechnung;
}
else
{
valid = !istPrivatrechnung || istSelbstzahler;
}
}
else
{
valid = false;
}
}
return valid;
}).ToList();
//if (serviceRecordsInPeriod.Count > 0)
//{
var itemList = CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, serviceInvoicePeriod.SupportConceptApprovalPeriod, calc);
serviceInvoicePeriod.InvoiceItemList.AddRange(itemList);
//}
}
public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap,
Calculations calc)
{
var list = base.CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, scap, calc);
if (invoicePeriod.StartDate < new DateTime(2023, 2, 1))
{
InvoiceItem ttii = CreateFahrkostenInvoiceItem(serviceRecordsInPeriod, scap, calc);
if (ttii != null)
list.Add(ttii);
}
if (istPrivatrechnung && mehrAlsMaxBetragVomKlientenZuZahlen != null)
{
InvoiceItem ii = CreateMaxBetragInvoiceItem(mehrAlsMaxBetragVomKlientenZuZahlen, scap);
if (ii != null)
list.Add(ii);
}
return list;
}
public override InvoiceItem CreateInvoiceItem(ServiceRecordDC iServiceRecord, SupportConceptApprovalPeriod scap, Calculations calc)
{
var ii = base.CreateInvoiceItem(iServiceRecord, scap, calc);
ii.Notice = iServiceRecord.ServiceDescription.CategoryName;
if (ii.AccountingInterval.HasValue)
{
if (ii.AccountingInterval.Value == AccountingIntervalType.Daily)
{
ii.UnitDescription = "Tage";
}
else if (ii.AccountingInterval.Value == AccountingIntervalType.Hourly)
{
ii.UnitDescription = "h";
}
}
return ii;
}
private InvoiceItem CreateFahrkostenInvoiceItem(List<ServiceRecordDC> serviceRecordsInPeriod, SupportConceptApprovalPeriod scap, Calculations calc)
{
if (!accountingPeriodStart.HasValue)
accountingPeriodStart = scap.StartDate;
if (!accountingPeriodEnd.HasValue)
accountingPeriodEnd = scap.EndDate;
decimal km = 0;
foreach (var sr in serviceRecordsInPeriod)
{
if (scap.ServiceCategory == null ||
scap.ServiceCategory.Oid == sr.ServiceDescription.Category.ServiceCategoryOid)
{
if (sr.DistanceInMeter.HasValue)
{
km += sr.DistanceInMeter.Value;
if (!createTestInvoice)
{
//sr.DistanceInMeter = 0; // Verhindern, dass bei mehreren Bewilligungen doppelt abgerechnet wird
}
}
}
}
if (km > 0)
{
var invoiceItem = new InvoiceItem();
invoiceItem.AmountPerUnit = AMOUNT_PER_KM;
invoiceItem.UnitCount = km;
invoiceItem.UnitDescription = "km";
invoiceItem.AmountTotal = invoiceItem.UnitCount * invoiceItem.AmountPerUnit;
invoiceItem.RateFactor = null;
invoiceItem.ItemPeriodStart = accountingPeriodStart;
invoiceItem.ItemPeriodEnd = accountingPeriodEnd;
invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
invoiceItem.ItemDescription = "Fahrtkosten";
if (scap != null)
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
return invoiceItem;
}
return null;
}
private InvoiceItem CreateMaxBetragInvoiceItem(InvoiceItem ii, SupportConceptApprovalPeriod scap)
{
if (!accountingPeriodStart.HasValue)
accountingPeriodStart = scap.StartDate;
if (!accountingPeriodEnd.HasValue)
accountingPeriodEnd = scap.EndDate;
var invoiceItem = new InvoiceItem();
invoiceItem.AmountPerUnit = ii.AmountPerUnit;
invoiceItem.UnitCount = ii.AmountTotal / ii.AmountPerUnit;
invoiceItem.UnitDescription = ii.UnitDescription;
invoiceItem.AmountTotal = invoiceItem.UnitCount * invoiceItem.AmountPerUnit;
invoiceItem.RateFactor = null;
invoiceItem.ItemPeriodStart = accountingPeriodStart;
invoiceItem.ItemPeriodEnd = accountingPeriodEnd;
invoiceItem.GrossAmountTotal = invoiceItem.AmountTotal;
invoiceItem.ItemDescription = ii.ItemDescription;
if (scap != null)
invoiceItem.SupportConceptApprovalPeriodOid = scap.Oid;
return invoiceItem;
}
public override IList<InvoiceItem> CreateSummaryInvoiceItems(IList<InvoiceItem> itemList, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap, Calculations calc, bool summaryPerMonth, bool addRateFactorToUnitCount)
{
//Fasse InvoiceItems mit gleichem Stundensatz zusammen:
var newlist = new List<InvoiceItem>();
var rateToItem = new Dictionary<String, InvoiceItem>();
foreach (InvoiceItem iitem in itemList)
{
InvoiceItem item;
var key = GetSummaryItemKey(scap, iitem, summaryPerMonth);
if (rateToItem.ContainsKey(key))
{
item = rateToItem[key];
}
else
{
item = new InvoiceItem();
newlist.Add(item);
item.AmountPerUnit = iitem.AmountPerUnit;
if (invoicePeriod != null)
{
item.ItemPeriodStart = invoicePeriod.StartDate;
item.ItemPeriodEnd = invoicePeriod.EndDate;
}
else
{
item.ItemPeriodStart = scap.StartDate;
item.ItemPeriodEnd = scap.EndDate;
}
if (summaryPerMonth && iitem.ItemPeriodStart.HasValue)
{
DateTime start = new DateTime(iitem.ItemPeriodStart.Value.Year, iitem.ItemPeriodStart.Value.Month, 1);
DateTime end = start.AddMonths(1).AddDays(-1);
if (item.ItemPeriodStart < start)
{
item.ItemPeriodStart = start;
}
if (item.ItemPeriodEnd > end)
{
item.ItemPeriodEnd = end;
}
}
item.RateFactor = iitem.RateFactor;
item.AccountingInterval = iitem.AccountingInterval;
item.ItemDescription = iitem.ItemDescription;
item.UnitDescription = iitem.UnitDescription;
item.SupportConceptApprovalPeriodOid = scap.Oid;
item.Notice = iitem.Notice;
rateToItem[key] = item;
}
if (!item.UnitCount.HasValue)
{
item.UnitCount = 0;
}
item.UnitCount += iitem.UnitCount ?? 0;
}
BerechneSummaryItemsSummen(newlist, addRateFactorToUnitCount);
return newlist;
}
public override void BerechneSummaryItemsSummen(List<InvoiceItem> newlist, bool addRateFactorToUnitCount)
{
base.BerechneSummaryItemsSummen(newlist, addRateFactorToUnitCount);
if (!istPrivatrechnung && mehrAlsMaxBetragVomKlientenZuZahlen != null)
{
if (newlist.Count > 0)
{
decimal neuerBetrag = (newlist[0].AmountTotal ?? 0) - (mehrAlsMaxBetragVomKlientenZuZahlen.AmountTotal ?? 0);
if (neuerBetrag > 0)
{
if (newlist[0].AmountPerUnit.HasValue && newlist[0].AmountPerUnit.Value > 0)
{
newlist[0].UnitCount = neuerBetrag / newlist[0].AmountPerUnit.Value;
}
newlist[0].AmountTotal = neuerBetrag;
newlist[0].GrossAmountTotal = neuerBetrag;
}
}
}
}
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);
}
}
}