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

578 lines
21 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
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 LebenshilfeFrankfurtOder.Utils;
namespace LebenshilfeFrankfurtOder.Invoicing
{
public class HortInvoiceCreation : InvoiceCreation
{
private Dictionary<String, decimal> category2Tagessatz = null;
private Dictionary<String, String> category2ServiceDescription = null;
private List<ServiceInvoice> privatRechnungen = null;
private String alleKlienten = "";
private bool additionalItemsCreated = false;
public override void SetInvoiceId(ServiceInvoice invoice)
{
invoice.InvoiceBase.InvoiceId = "RechnungHort";
invoice.InvoiceBase.InvoiceTypeText = "Hortangebot";
}
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 => (s.Customer != null && !String.IsNullOrEmpty(s.Customer.DebitorNumber)) ? s.Customer.DebitorNumber : "zzzzz").ToList();
privatRechnungen = null;
foreach (var sc in sortedScs)
{
var serviceRecords = supportConcepts2ServiceRecords[sc];
if (sc.CostBearerList.Count > 0)
{
var costBearer = DAOFactory.GenericDAO.LoadByID<CostBearer>(sc.CostBearerList[0].CostBearerOid);
privatRechnungen = CreatePrivatRechnungen(invoiceCounter, costBearer, invoicePeriod, sc, serviceRecords);
if (privatRechnungen != null)
{
foreach (var si in privatRechnungen)
{
invoiceList.Add(si);
invoiceCounter++;
}
}
additionalItemsCreated = false;
var invoice = CreateSingleInvoice(invoiceCounter, costBearer, invoicePeriod, sc, serviceRecords);
if (invoice != null)
{
invoiceList.Add(invoice);
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 List<ServiceInvoice> CreatePrivatRechnungen(int invoiceCounter, CostBearer costBearer, DateTimeSpan invoicePeriod, CompactSupportConceptDC sc, List<ServiceRecordDC> serviceRecords)
{
IList<VarFieldDef> defs = DAOFactory.SearchDAO.GetVarFieldDefs(TableID.Customer);
List<ServiceInvoice> list = new List<ServiceInvoice>();
Dictionary<long, bool> customerOids = new Dictionary<long, bool>();
var bookings = DAOFactory.SearchDAO.GetAdditionalServiceBookings(22, invoicePeriod.StartDate, invoicePeriod.EndDate);
foreach (var ab in bookings)
{
foreach (var c2a in ab.Customer2AddServiceBookings)
{
if (c2a.Participated)
{
if (!customerOids.ContainsKey(c2a.CustomerOid))
{
customerOids.Add(c2a.CustomerOid, true);
}
}
}
}
foreach (var sr in serviceRecords)
{
if (sr.Customer != null)
{
if (!customerOids.ContainsKey(sr.Customer.Oid.Value))
{
customerOids.Add(sr.Customer.Oid.Value, true);
}
}
}
foreach (var coid in customerOids.Keys)
{
var c = DAOFactory.GenericDAO.LoadByID<Customer>(coid);
var vv = c.VarFieldValueList.FirstOrDefault(v => v.VarFieldDefOid.Value == 6);
if (vv != null)
{
var varFieldValue = BS.Shared.Core.Utils.XMLDeserializeFromString(vv.SerializedValue, Type.GetType(vv.TypeName));
decimal eigenanteil = 0;
if (varFieldValue != null && Decimal.TryParse(varFieldValue.ToString(), out eigenanteil))
{
if (eigenanteil > 0)
{
ServiceInvoice invoice = CreatePrivatRechnung(invoiceCounter, costBearer, invoicePeriod, sc, c, eigenanteil);
if (invoice != null)
{
list.Add(invoice);
}
}
}
}
}
return list;
}
private ServiceInvoice CreatePrivatRechnung(int invoiceCounter, CostBearer costBearer, DateTimeSpan invoicePeriod, CompactSupportConceptDC sc, Customer customer, decimal eigenanteil)
{
var invoice = base.CreateSingleInvoice(invoiceCounter, costBearer, invoicePeriod, sc, new List<ServiceRecordDC>());
invoice.InvoiceBase.InvoiceId = "RechnungHortPrivat";
if (customer.Person.InvoiceAddress != null)
{
invoice.InvoiceBase.RecipientAddress = customer.Person.InvoiceAddress.CopyToNew();
invoice.InvoiceBase.RecipientOrganisation = "";
invoice.InvoiceBase.RecipientCostBearerOid = null;
}
else if (customer.Person.Address != null)
{
invoice.InvoiceBase.RecipientAddress = customer.Person.Address.CopyToNew();
invoice.InvoiceBase.RecipientOrganisation = "";
invoice.InvoiceBase.RecipientCostBearerOid = null;
}
invoice.InvoiceBase.RecipientPersonFirstName = customer.Person.FirstName;
invoice.InvoiceBase.RecipientPersonLastName = customer.Person.LastName;
invoice.ServiceInvoicePeriodList = new List<ServiceInvoicePeriod>();
var sip = new ServiceInvoicePeriod
{
Start = invoicePeriod.StartDateTime,
End = invoicePeriod.EndDateTime
};
sip.Notice = customer.Person.LastNameFirstName;
var ii = new InvoiceItem();
ii.AmountPerUnit = eigenanteil;
ii.UnitCount = 1;
ii.AmountTotal = ii.AmountPerUnit * ii.UnitCount;
ii.ItemPeriodStart = invoicePeriod.StartDateTime;
ii.ItemPeriodEnd = invoicePeriod.EndDateTime;
ii.RateFactor = null;
ii.GrossAmountTotal = ii.AmountTotal;
ii.UnitDescription = String.Format("{0}", customer.Oid);
ii.ItemDescription = "Eigenanteil";
ii.Notice = customer.Person.FirstNameLastName;
sip.InvoiceItemList.Add(ii);
invoice.ServiceInvoicePeriodList.Add(sip);
SetServiceInvoicePeriodAmounts(invoice);
return invoice;
}
public override void SetSingleInvoiceBaseData(int invoiceCounter, ServiceInvoice invoice, CostBearer costBearer, DateTimeSpan invoicePeriod, CompactSupportConceptDC supportConcept)
{
if (supportConcept.SupportConceptOid > 0 && supportConcept.CostBearerRelOids.Count > 0)
{
base.SetSingleInvoiceBaseData(invoiceCounter, invoice, costBearer, invoicePeriod, supportConcept);
}
}
public override void SetRecipientInformation(ServiceInvoice serviceInvoice, CostBearer costBearer)
{
base.SetRecipientInformation(serviceInvoice, costBearer);
serviceInvoice.InvoiceBase.RecipientOrganisation = costBearer.Organisation.Name.Replace("Hort", "").Trim();
}
public override void SetServiceInvoicePeriods(ServiceInvoice invoice, CostBearer2SupportConcept costBearer2SupportConcept, DateTimeSpan invoicePeriod, List<ServiceRecordDC> serviceRecords)
{
if (costBearer2SupportConcept != null)
{
base.SetServiceInvoicePeriods(invoice, costBearer2SupportConcept, invoicePeriod, serviceRecords);
}
var invoiceAccountingPeriodSpan = new DateTimeSpan
{
StartDateTime = invoice.InvoiceBase.AccountingPeriodStart.Value,
EndDateTime = invoice.InvoiceBase.AccountingPeriodEnd.Value
};
ServiceInvoicePeriod serviceInvoicePeriod = new ServiceInvoicePeriod
{
Start = invoiceAccountingPeriodSpan.StartDateTime,
End = invoiceAccountingPeriodSpan.EndDateTime
};
Calculations calc = PluginLoader.FindClass<Calculations>(_SpecificID) ?? Calculations.GetInstance(_SpecificID);
SetInvoiceItems(invoice, serviceInvoicePeriod, null, costBearer2SupportConcept, invoicePeriod, serviceRecords);
if (serviceInvoicePeriod.InvoiceItemList.Count > 0)
invoice.ServiceInvoicePeriodList.Add(serviceInvoicePeriod);
}
public override void SetInvoiceItems(ServiceInvoice invoice, ServiceInvoicePeriod serviceInvoicePeriod,
SupportConceptApprovalPeriodDC supportConceptApprovalPeriod, CostBearer2SupportConcept cb2sc,
DateTimeSpan invoicePeriod, List<ServiceRecordDC> serviceRecords)
{
List<ServiceRecordDC> serviceRecordsInPeriod = serviceRecords.Where(
i =>
{
bool valid = i.Start.Value.InBetween(serviceInvoicePeriod.Start.Value,
serviceInvoicePeriod.End.Value, true);
if (valid && serviceInvoicePeriod.SupportConceptApprovalPeriod != null && serviceInvoicePeriod.SupportConceptApprovalPeriod.ServiceCategory != null)
valid = serviceInvoicePeriod.SupportConceptApprovalPeriod.ServiceCategory.Oid ==
i.ServiceDescription.Category.ServiceCategoryOid;
return valid;
}).ToList();
Calculations calc = PluginLoader.FindClass<Calculations>(_SpecificID) ?? Calculations.GetInstance(_SpecificID);
var itemList = CreateInvoiceItems(serviceRecordsInPeriod, invoicePeriod, serviceInvoicePeriod.SupportConceptApprovalPeriod, calc);
serviceInvoicePeriod.InvoiceItemList.AddRange(itemList);
serviceInvoicePeriod.Notice = alleKlienten;
}
public override IList<InvoiceItem> CreateInvoiceItems(List<ServiceRecordDC> serviceRecordsInPeriod, DateTimeSpan invoicePeriod, SupportConceptApprovalPeriod scap,
Calculations calc)
{
alleKlienten = "";
var list = new List<InvoiceItem>();
foreach (ServiceRecordDC iServiceRecord in serviceRecordsInPeriod)
{
if (!iServiceRecord.ServiceDescription.Name.Contains("Ferien") && !iServiceRecord.AlreadyAccounted)
{
iServiceRecord.AlreadyAccounted = true;
InvoiceItem invoiceItem = CreateInvoiceItem(iServiceRecord, scap, calc);
if (invoiceItem != null)
{
invoiceItem.Notice = iServiceRecord.ServiceDescription.Name;
list.Add(invoiceItem);
if (iServiceRecord.Customer != null && !String.IsNullOrEmpty(iServiceRecord.Customer.Name))
{
String ersterBuchstabe = "";
if (!String.IsNullOrEmpty(iServiceRecord.Customer.FirstName) &&
iServiceRecord.Customer.FirstName.Length > 0)
{
ersterBuchstabe = iServiceRecord.Customer.FirstName.Substring(0, 1);
}
String name = String.Format("{0}. {1}", ersterBuchstabe, iServiceRecord.Customer.LastName);
if (!alleKlienten.Contains(name))
{
if (alleKlienten.Length > 0)
{
alleKlienten += ", ";
}
alleKlienten += name;
}
}
//if (alleKlienten.Contains())
}
}
}
var hortItems = ErstelleHortItems(list, invoicePeriod.StartDate, invoicePeriod.EndDate);
if (!additionalItemsCreated)
{
var ferienItem = ErstelleFerienItem(invoicePeriod.StartDate, invoicePeriod.EndDate);
if (ferienItem != null)
{
hortItems.Add(ferienItem);
}
if (privatRechnungen != null)
{
var ii = CreateEigenanteilsItem(privatRechnungen);
if (ii != null)
{
hortItems.Add(ii);
}
}
additionalItemsCreated = true;
}
return hortItems;
}
private InvoiceItem ErstelleFerienItem(DateTime start, DateTime end)
{
var bookings = DAOFactory.SearchDAO.GetAdditionalServiceBookings(22, start, end);
Dictionary<int, int> dayCount = new Dictionary<int, int>();
int teilnameCount = 0;
foreach (var ab in bookings)
{
bool nimmtTeil = false;
foreach (var c2a in ab.Customer2AddServiceBookings)
{
if (c2a.Participated)
{
if (!dayCount.ContainsKey(ab.StartDate.Value.Day))
{
dayCount.Add(ab.StartDate.Value.Day, 0);
}
dayCount[ab.StartDate.Value.Day]++;
teilnameCount++;
}
}
//if (nimmtTeil)
//{
// if (!dayCount.ContainsKey(ab.StartDate.Value.Day))
// {
// dayCount.Add(ab.StartDate.Value.Day, 0);
// }
// dayCount[ab.StartDate.Value.Day]++;
//}
}
if (dayCount.Count > 0)
{
var ii = new InvoiceItem();
ii.AmountPerUnit = FrankfurtOderHelper.GetPreisFerienbetreuung(start);
ii.UnitCount = teilnameCount;
ii.AmountTotal = ii.AmountPerUnit * ii.UnitCount;
ii.ItemPeriodStart = start;
ii.ItemPeriodEnd = end;
ii.RateFactor = null;
ii.GrossAmountTotal = ii.AmountTotal;
ii.UnitDescription = "Tage";
ii.ItemDescription = "Ferien";
ii.Notice = "Ferien";
return ii;
}
return null;
}
private InvoiceItem CreateEigenanteilsItem(List<ServiceInvoice> serviceInvoices)
{
DateTime start = DateTime.MinValue;
DateTime ende = DateTime.MaxValue;
decimal amount = 0;
InvoiceItem ii = null;
foreach (var si in serviceInvoices)
{
amount += si.GetTotalClaim() ?? 0;
start = si.InvoiceBase.AccountingPeriodStart.Value;
ende = si.InvoiceBase.AccountingPeriodEnd.Value;
}
if (amount > 0)
{
amount *= -1;
ii = new InvoiceItem();
ii.AmountPerUnit = amount;
ii.UnitCount = 1;
ii.AmountTotal = ii.AmountPerUnit * ii.UnitCount;
ii.ItemPeriodStart = start;
ii.ItemPeriodEnd = ende;
ii.RateFactor = null;
ii.GrossAmountTotal = ii.AmountTotal;
ii.UnitDescription = "Eigenanteil";
ii.ItemDescription = "Eigenanteil";
}
return ii;
}
private IList<InvoiceItem> ErstelleHortItems(IList<InvoiceItem> items, DateTime start, DateTime end)
{
var hortItems = new List<InvoiceItem>();
Dictionary<String, int> countPerDayHort = new Dictionary<String, int>();
Dictionary<String, int> countPerDayFerien = new Dictionary<String, int>();
foreach (var ii in items)
{
String key = String.Format("{0:dd.MM.yyyy}", ii.ItemPeriodStart);
Dictionary<String, int> countPerDay = countPerDayHort;
if (!String.IsNullOrEmpty(ii.Notice) && ii.Notice.Contains("Ferien"))
{
countPerDay = countPerDayFerien;
}
if (!countPerDay.ContainsKey(key))
{
countPerDay.Add(key, 0);
}
countPerDay[key] += 1;
}
int anzahlBis3 = 0;
int anzahlAb4 = 0;
int anzahlAb6 = 0;
int anzahlFerien = countPerDayFerien.Count;
foreach (var dayKey in countPerDayHort.Keys)
{
var anzahlKinderAmTag = countPerDayHort[dayKey];
if (anzahlKinderAmTag > 0)
{
if (anzahlKinderAmTag < 4)
{
anzahlBis3 ++;
}
else if (anzahlKinderAmTag >= 4 && anzahlKinderAmTag < 6)
{
anzahlAb4 ++;
}
else
{
anzahlAb6 ++;
}
}
}
if (anzahlBis3 > 0)
{
var ii = new InvoiceItem();
ii.AmountPerUnit = FrankfurtOderHelper.PREIS_HORT_BIS_3_KINDER;
ii.UnitCount = anzahlBis3;
ii.AmountTotal = ii.AmountPerUnit * ii.UnitCount;
ii.ItemPeriodStart = start;
ii.ItemPeriodEnd = end;
ii.RateFactor = null;
ii.GrossAmountTotal = ii.AmountTotal;
ii.UnitDescription = "Tage";
ii.ItemDescription = "bis 3 Kinder";
ii.Notice = "Hortbetreuung bis 3 Kinder";
hortItems.Add(ii);
}
if (anzahlAb4 > 0)
{
var ii = new InvoiceItem();
ii.AmountPerUnit = FrankfurtOderHelper.PREIS_HORT_AB_4_KINDER;
ii.UnitCount = anzahlAb4;
ii.AmountTotal = ii.AmountPerUnit * ii.UnitCount;
ii.ItemPeriodStart = start;
ii.ItemPeriodEnd = end;
ii.RateFactor = null;
ii.GrossAmountTotal = ii.AmountTotal;
ii.UnitDescription = "Tage";
ii.ItemDescription = "ab 4 Kinder";
ii.Notice = "Hortbetreuung ab 4 Kinder";
hortItems.Add(ii);
}
if (anzahlAb6 > 0)
{
var ii = new InvoiceItem();
ii.AmountPerUnit = FrankfurtOderHelper.PREIS_HORT_AB_6_KINDER;
ii.UnitCount = anzahlAb6;
ii.AmountTotal = ii.AmountPerUnit * ii.UnitCount;
ii.ItemPeriodStart = start;
ii.ItemPeriodEnd = end;
ii.RateFactor = null;
ii.GrossAmountTotal = ii.AmountTotal;
ii.UnitDescription = "Tage";
ii.ItemDescription = "ab 6 Kinder";
ii.Notice = "Hortbetreuung ab 6 Kinder";
hortItems.Add(ii);
}
if (anzahlFerien > 0)
{
var ii = new InvoiceItem();
ii.AmountPerUnit = FrankfurtOderHelper.GetPreisFerienbetreuung(start);
ii.UnitCount = anzahlFerien;
ii.AmountTotal = ii.AmountPerUnit * ii.UnitCount;
ii.ItemPeriodStart = start;
ii.ItemPeriodEnd = end;
ii.RateFactor = null;
ii.GrossAmountTotal = ii.AmountTotal;
ii.UnitDescription = "Tage";
ii.ItemDescription = "Ferien";
ii.Notice = "Ferien";
hortItems.Add(ii);
}
return hortItems;
}
}
}