Files
BeWoPlaner/ReportImp/Wabe/Invoicing/CollectiveInvoiceCreation.cs

251 lines
11 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
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.DataContracts.Compact;
using BS.Shared.Extensions;
using BS.Shared.Services;
namespace Wabe.Invoicing
{
public class CollectiveInvoiceCreation : InvoiceCreation
{
private DateTime? accountingPeriodStart = null;
private DateTime? accountingPeriodEnd = null;
public override void SetInvoiceId(ServiceInvoice invoice)
{
invoice.InvoiceBase.InvoiceId = "RgBezirk";
invoice.InvoiceBase.InvoiceTypeText = "Sammelrechnung Bezirk";
}
public override List<ServiceInvoiceDC> GenerateServiceInvoices(long costBearerOid,
DateTimeSpan invoicePeriod,
Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>> supportConcepts2ServiceRecords)
{
var costBearer = DAOFactory.GenericDAO.LoadByID<CostBearer>(costBearerOid);
var invoiceList = new List<ServiceInvoice>();
ServiceInvoice invoice;
invoice = CreateCollectiveBilling2(costBearer, invoicePeriod, supportConcepts2ServiceRecords);
if (invoice != null)
invoiceList.Add(invoice);
var result = invoiceList.Select(item => MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(item)).ToList();
return result.Count > 1 ? result.OrderBy(i => i.InvoiceBase.CustomerLastName).ToList() : result;
}
private ServiceInvoice CreateCollectiveBilling2(CostBearer costBearer, DateTimeSpan invoicePeriod, Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>> supportConcepts2ServiceRecords)
{
var invoice = new ServiceInvoice();
var newDict = new Dictionary<CompactSupportConceptDC, List<ServiceRecordDC>>();
foreach (var sc2sr in supportConcepts2ServiceRecords)
{
if (sc2sr.Key.IsApproved)
newDict.Add(sc2sr.Key, sc2sr.Value);
}
SetRecipientInformation(invoice, costBearer);
SetSenderInformation(invoice);
SetInvoiceBaseData(0, invoice, costBearer, invoicePeriod, newDict.Keys.ToList());
SetCollectiveBillingBaseData(0, invoice, costBearer, invoicePeriod, newDict);
SetCollectiveBillingServiceInvoicePeriods(invoice, invoicePeriod, newDict);
SetServiceInvoicePeriodAmounts(invoice);
SetAmountAdvancePayments(invoice);
return invoice;
}
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 SetInvoiceItems(ServiceInvoice invoice,
ServiceInvoicePeriod serviceInvoicePeriod,
SupportConceptApprovalPeriodDC supportConceptApprovalPeriod,
CostBearer2SupportConcept cb2sc,
DateTimeSpan invoicePeriod,
List<ServiceRecordDC> serviceRecords)
{
CreateFixedAmounts(serviceInvoicePeriod, supportConceptApprovalPeriod, cb2sc);
}
public override void CreateFixedAmounts(ServiceInvoicePeriod serviceInvoicePeriod, SupportConceptApprovalPeriodDC supportConceptApprovalPeriod, CostBearer2SupportConcept cb2sc)
{
var calc = PluginLoader.FindClass<BS.Shared.Services.Calculations>(_SpecificID) ?? BS.Shared.Services.Calculations.GetInstance(_SpecificID);
var data = calc.GetFixedBillingData(supportConceptApprovalPeriod, serviceInvoicePeriod.Start, serviceInvoicePeriod.End);
var scap = supportConceptApprovalPeriod;
if (scap != null && scap.ServiceCategory != null && scap.ServiceCategory.Name.Contains("HEG"))
{
IList<InvoiceItem> ergebnis = new List<InvoiceItem>();
var customer = cb2sc.SupportConcept.Customer;
DateTime start;
DateTime ende;
if (scap.StartDate <= serviceInvoicePeriod.Start)
{
start = serviceInvoicePeriod.Start.Value;
}
else
{
start = (DateTime)scap.StartDate; //Einzugstag wird mit abgerechnet
}
if (cb2sc.SupportConcept.Customer.TerminationDate.HasValue &&
cb2sc.SupportConcept.Customer.TerminationDate.Value <= serviceInvoicePeriod.End.Value
&& cb2sc.SupportConcept.Customer.TerminationDate.Value <= scap.EndDate.Value
&& cb2sc.SupportConcept.Customer.TerminationDate.Value >= scap.StartDate.Value)
{
ende = cb2sc.SupportConcept.Customer.TerminationDate.Value.AddDays(-1); // finaler Auszugstag wird NICHT abgerechnet
}
else
{
if (scap.EndDate >= serviceInvoicePeriod.End)
{
ende = serviceInvoicePeriod.End.Value;
}
else
{
ende = (DateTime)scap.EndDate.Value;
}
}
decimal tagessatz = 0;
var crList = scap.ServiceCategory.CostRatePeriods;
var cr = crList.GetCostRatePeriodForDate(BS.Shared.CostRatePeriodType.AmountOfMoney, start);
if (cr != null && cr.CostRateValue.HasValue)
{
tagessatz = cr.CostRateValue.Value;
}
while (start <= ende)
{
DateTime monatStart = start; //new DateTime(start.Year, start.Month, 1);
DateTime monatEnde = monatStart.AddMonths(1); //new DateTime(start.Year, start.AddMonths(1).Month, 1); //ende.AddDays(1);
monatEnde = new DateTime(monatEnde.Year, monatEnde.Month, 1);
if (ende.AddDays(1) < monatStart.AddMonths(1))
{
monatEnde = ende.AddDays(1);
}
var tageMonat = monatEnde.Subtract(start).Days;
decimal? sumCustomerMonth = 0;
//Falls Platzfreihaltegebühr doch schlagend wird->siehe Domiziel Ansbach Invoice Helper!!!
int tageAbwesendImMonat = 0;
foreach (var at in customer.AbsenceTimes)
{
DateTime? startAbw = at.Start;
DateTime? endAbw = at.End;
if (at.Start.HasValue && at.End.HasValue && at.AbsenceReason.Description.Contains("unbezahlt"))
{
endAbw = at.End.Value.AddDays(-1);
if (startAbw.HasValue && startAbw.Value < monatEnde && (!endAbw.HasValue || endAbw.Value >= monatStart))
{
DateTime abwStart = at.Start.Value;
if (start > abwStart)
{
abwStart = start;
}
DateTime abwEnd = monatEnde.AddDays(-1);
if (endAbw.HasValue && endAbw < monatEnde)
{
abwEnd = endAbw.Value;
}
DateTime dt = abwStart;
while (dt <= abwEnd)
{
tageAbwesendImMonat++;
dt = dt.AddDays(1);
}
}
}
}
var ii = new InvoiceItem();
ii.UnitCount = tageMonat - tageAbwesendImMonat;
ii.AmountPerUnit = tagessatz;
ii.AmountTotal = ii.UnitCount * ii.AmountPerUnit;
ii.GrossAmountTotal = ii.AmountTotal;
sumCustomerMonth += ii.AmountTotal;
ii.MaxApprovedAmount = null;
ii.ItemDescription = "Klientenname";
ii.UnitDescription = scap.ServiceCategory.Name;
ii.ItemPeriodStart = monatStart;
ii.Notice = String.Format("{0:dd.MM.yyyy} - {1:dd.MM.yyyy}", monatStart, monatEnde.AddDays(-1));
ii.SupportConceptApprovalPeriodOid = scap.SupportConceptApprovalPeriodOid;
ii.ItemDescription = "";
serviceInvoicePeriod.InvoiceItemList.Add(ii);
start = start.AddMonths(1);
start = new DateTime(start.Year, start.Month, 1);
}
if (cb2sc.SupportConcept.Oid.HasValue)
{
var equity = GetAmountEquityContribution(cb2sc.SupportConcept.Oid.Value, serviceInvoicePeriod);
if (equity > 0)
{
var ii = new InvoiceItem();
ii.UnitCount = 1;
ii.AmountPerUnit = equity;
ii.AmountTotal = -equity * ii.UnitCount;
ii.GrossAmountTotal = -equity * ii.UnitCount;
ii.ItemPeriodStart = serviceInvoicePeriod.End.Value;
ii.Notice = "Eigenanteil";
ii.SupportConceptApprovalPeriodOid = scap.SupportConceptApprovalPeriodOid;
ii.ItemDescription = "";
serviceInvoicePeriod.InvoiceItemList.Add(ii);
}
}
}
}
private decimal GetAmountEquityContribution(long scOid, ServiceInvoicePeriod period)
{
decimal equity = 0;
IList<InvoiceBase> EquityInvoiceList =
DAOFactory.SearchDAO.GetInvoiceBaseByTypeAndSupportConceptOid(InvoiceType.CustomerEquity, scOid);
EquityInvoiceList = EquityInvoiceList.Where(i => i.AccountingPeriodStart.HasValue &&
i.AccountingPeriodStart.Value.InBetween(period.Start.Value, period.End.Value, true)).ToList();
foreach (InvoiceBase iEquityInvoice in EquityInvoiceList)
{
foreach (InvoiceItem item in iEquityInvoice.InvoiceItems)
{
if (item.AmountTotal != null)
{
equity += item.AmountTotal.Value;
}
}
}
return equity;
}
}
}