using System; using System.Collections.Generic; using System.Linq; using System.ServiceModel; using BeWo.Data; using BeWo.Service.Plugins; using BS.Shared.DataContracts.Compact; using BeWo.Data.Access; using BeWo.Data.Entities; using BeWo.Service.Core; using BeWo.Service.DCEntityMapper; using BeWo.Service.ServiceContracts; using BS.Shared; using BS.Shared.Core; using BS.Shared.DataContracts; using Utils = BeWo.Service.Core.Utils; using BeWo.Service.Invoicing; namespace BeWo.Service.ServiceImplementations { [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)] public class AccountingServiceImp : IAccountingService { public void DeactivateInvoiceBases(List invoices) { try { var s = PluginLoader.FindClass(); s.DeactivateInvoiceBases(invoices); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void StorniereInvoiceBases(List invoices) { try { var s = PluginLoader.FindClass(); s.StorniereInvoiceBases(invoices); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeactivateServiceInvoices(List invoices) { try { var s = PluginLoader.FindClass(); s.DeactivateServiceInvoices(invoices); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void DeactivateSettlementInvoice(List invoices) { try { ServiceLogic.SetActivationType(invoices.ToDictionary(i => i.SettlementIvoiceOid.Value, i => i.SettlementInvoiceVersion.Value), ActivationTypeId.Deleted); ServiceLogic.SetActivationType(invoices.ToDictionary(i => i.InvoiceBaseOid.Value, i => i.InvoiceBaseVersion.Value), ActivationTypeId.Deleted); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GenerateInitialServiceInvoices( long costBearerOid, long? supportConceptOid, DateTimeSpan invoicePeriod) { try { var operationService = new OperationsServiceImp(); IEnumerable supportConcepts; // GetAllActiveSupportConceptCostbearer returns a "Flat" SupportConcept List, one for each CostBearer2SupportConcept! if (!supportConceptOid.HasValue) { supportConcepts = operationService.GetAllActiveSupportConceptCostbearer(false, true, 0) .Where(i => i.CostBearerOids2CostBearerRelOids.ContainsKey(costBearerOid)); } else { supportConcepts = operationService.GetCompactSupportConcepts(supportConceptOid.Value, null) .Where(i => i.CostBearerOids2CostBearerRelOids.ContainsKey(costBearerOid)); } DateTimeSpan newSpan = null; if (invoicePeriod != null) { //invoicePeriod.StartDateTime = invoicePeriod.StartDateTime.Date; //invoicePeriod.EndDateTime = invoicePeriod.EndDateTime.Date; newSpan = new DateTimeSpan(); newSpan.StartDateTime = invoicePeriod.StartDateTime.Date; newSpan.EndDateTime = invoicePeriod.EndDateTime.Date.AddDays(1).AddTicks(-1); if (!supportConceptOid.HasValue) { supportConcepts = supportConcepts.Where(sc => sc.StartDate < newSpan.EndDate && sc.EndDate >= newSpan.StartDate); } } var supportConcepts2ServiceRecords = supportConcepts.ToDictionary( i => i, i => MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs( DAOFactory.SearchDAO.FindServiceRecordsInSpan(i.CostBearerRelOids[0], newSpan))); var cb = DAOFactory.GenericDAO.LoadByID(costBearerOid); String tenant = null; if (MultitenancyOperationContextExt.Current != null) tenant = MultitenancyOperationContextExt.Current.Tenant; var factory = PluginLoader.FindClass(cb.ID); if (factory == null) { factory = InvoiceFactory.GetInstance(cb.ID, tenant); } var creator = factory.CreateInvoiceCreator(cb.ID, tenant, supportConcepts2ServiceRecords); //String text = String.Format("Tenant={0}, Context=Null? {1}, Factory = {2}", tenant, // MultitenancyOperationContextExt.Current == null, factory); //Utils.SendErrorMail("CB DEBUG", text); return creator.GenerateServiceInvoices(costBearerOid, invoicePeriod, supportConcepts2ServiceRecords); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetAllActiveInvoiceBases() { try { return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.GenericDAO.GetAllActive()); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetInvoiceBases(DateTime? startDate, DateTime? endDate) { try { var s = PluginLoader.FindClass(); return s.GetInvoiceBases(startDate, endDate); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetGeneralInvoiceBasesForCustomer(long customerOid) { try { return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.SearchDAO.GetInvoiceBaseByCustomerOid(InvoiceType.General, customerOid)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetGeneralInvoiceBasesForOrganisation(long organisationOid) { try { return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.SearchDAO.GetInvoiceBaseByOrganisationOid(InvoiceType.General, organisationOid)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetGeneralInvoiceBasesForPerson(long personOid) { try { return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.SearchDAO.GetInvoiceBaseByPersonOid(InvoiceType.General, personOid)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetInvoiceBasesForSupportConcept(InvoiceType type, long supportConceptOid) { try { return MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDCs(DAOFactory.SearchDAO.GetInvoiceBaseByTypeAndSupportConceptOid(type, supportConceptOid)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public ServiceInvoiceDC GetServiceInvoiceByInvoiceBaseOid(long invoiceBaseOid) { try { var dc = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(DAOFactory.SearchDAO.GetServiceInvoiceByInvoiceBaseOid(invoiceBaseOid)); SortServiceInvoicePeriods(dc); return dc; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetServiceInvoices(long costBearerOid, long? supportConceptOid, DateTimeSpan period) { try { List entities = DAOFactory.SearchDAO.GetServiceInvoices(costBearerOid, supportConceptOid, period); entities.Sort((x, y) => { if (y.InvoiceBase.InvoiceDate.Value.Date.Equals(x.InvoiceBase.InvoiceDate.Value.Date)) { return y.InvoiceBase.InvoiceNumber.CompareTo(x.InvoiceBase.InvoiceNumber); } return y.InvoiceBase.InvoiceDate.Value.Date.CompareTo(x.InvoiceBase.InvoiceDate.Value.Date); }); var dcList = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDCs(entities); foreach (var serviceInvoice in dcList) { SortServiceInvoicePeriods(serviceInvoice); } return dcList; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } private void SortServiceInvoicePeriods(ServiceInvoiceDC serviceInvoice) { if (serviceInvoice.ServiceInvoicePeriods != null) { serviceInvoice.ServiceInvoicePeriods.Sort((x, y) => { if (x.Customer != null && y.Customer != null) return x.Customer.ToString().CompareTo(y.Customer.ToString()); else if (x.Start != null && y.Start != null) { x.Start.Value.CompareTo(y.Start.Value); } return 0; }); } } public Settlement2DC GetSettlementByInvoiceBaseOid(long invoiceBaseOid) { try { return MapperFactory.SettlementDC_SettlementInvoice.MapToNewDC(DAOFactory.SearchDAO.GetSettlementInvoiceByInvoiceBaseOid(invoiceBaseOid)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetSettlementInvoicesForCostBearerAndPeriod(long costBearerOid, DateTime periodStart, DateTime periodEnd) { try { return MapperFactory.SettlementDC_SettlementInvoice.MapToNewDCs(DAOFactory.SearchDAO.GetSettlementInvoicesForCostBearerAndPeriod(costBearerOid, periodStart, periodEnd)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List GetSettlementInvoicesForSupportConcept(long supportConceptOid) { try { return MapperFactory.SettlementDC_SettlementInvoice.MapToNewDCs(DAOFactory.SearchDAO.GetSettlementInvoiceBySupportConceptOid(supportConceptOid)); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List InsertNewInvoiceBases(List invoices) { try { if (invoices != null && LoggedInUserOperationContextExt.Current != null && LoggedInUserOperationContextExt.Current.User != null) { var loggedInUser = LoggedInUserOperationContextExt.Current.User; foreach (var ib in invoices) { ib.SenderContactInformations = new List(); foreach (var contact in loggedInUser.Employee.Person.Contacts) { var newContact = new ContactDC(); newContact.ContactType = contact.Type; newContact.ContactValue = contact.Value; ib.SenderContactInformations.Add(newContact); } } } var newInvoices = MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewEntities(invoices); int count = 0; var inc = PluginLoader.FindClass(); foreach (var ib in newInvoices) { if (ib.Type == InvoiceType.General) { foreach (var item in ib.InvoiceItems) { item.AmountTotal = Math.Round(item.AmountTotal ?? 0, 2, MidpointRounding.AwayFromZero); } } var nextNumber = inc.GetNextInvoiceNumber(count, ib); if (!String.IsNullOrEmpty(nextNumber)) { if (!String.IsNullOrEmpty(ib.InvoiceNumber)) // Rechnungsnummer schon vorher erzeugt oder per Hand vergeben. { if (ib.InvoiceNumber == nextNumber) //Die per Hand vergebene Rechnungsnummer ist gleich der nächsten berechneten Rechnungsnummer, daher Rechnungsnummerzähler erhöhen { count++; } } else { ib.InvoiceNumber = nextNumber; count++; } } } var factory = PluginLoader.FindClass(); if (factory != null) { foreach (var ib in newInvoices) { if (ib.Type == InvoiceType.CustomerEquity) { var creator = factory.CreateEquityInvoiceCreator(ib); creator.InitEquityInvoice(ib); } else if (ib.Type == InvoiceType.General) { var creator = factory.CreateGeneralInvoiceCreator(ib); creator.InitInvoice(ib); } } } DAOFactory.GenericDAO.Insert(newInvoices); inc.IncreaseInvoiceNumber(count, newInvoices); return newInvoices.Select(i => i.Oid.Value).ToList(); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List InsertNewServiceInvoices(List invoices) { try { var newInvoices = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewEntities(invoices); if (newInvoices.Count > 0) { int count = 0; var inc = PluginLoader.FindClass(); foreach (var i in newInvoices) { var nextNumber = inc.GetNextInvoiceNumber(count, i.InvoiceBase); if (!String.IsNullOrEmpty(nextNumber)) { //if (!String.IsNullOrEmpty(i.InvoiceBase.InvoiceNumber) && newInvoices.Count == 1) // // Rechnungsnummer schon vorher erzeugt oder per Hand vergeben. //{ // if (i.InvoiceBase.InvoiceNumber == nextNumber || newInvoices.Count > 1) // //Die per Hand vergebene Rechnungsnummer ist gleich der nächsten berechneten Rechnungsnummer, daher Rechnungsnummerzähler erhöhen // { // count++; // } //} //else //{ i.InvoiceBase.InvoiceNumber = nextNumber; count++; //} } } DAOFactory.GenericDAO.Insert(newInvoices); inc.IncreaseInvoiceNumber(count, newInvoices); } return newInvoices.Select(i => i.Oid.Value).ToList(); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List InsertNewSettlementInvoice(List invoices) { try { var newInvoices = MapperFactory.SettlementDC_SettlementInvoice.MapToNewEntities(invoices); int count = 0; var inc = PluginLoader.FindClass(); foreach (var i in newInvoices) { var nextNumber = inc.GetNextInvoiceNumber(count, i.InvoiceBase); if (!String.IsNullOrEmpty(nextNumber)) { if (!String.IsNullOrEmpty(i.InvoiceBase.InvoiceNumber)) // Rechnungsnummer schon vorher erzeugt oder per Hand vergeben. { if (i.InvoiceBase.InvoiceNumber == nextNumber) //Die per Hand vergebene Rechnungsnummer ist gleich der nächsten berechneten Rechnungsnummer, daher Rechnungsnummerzähler erhöhen { count++; } } else { i.InvoiceBase.InvoiceNumber = nextNumber; count++; } } } DAOFactory.GenericDAO.Insert(newInvoices); inc.IncreaseInvoiceNumber(count, newInvoices); return newInvoices.Select(i => i.Oid.Value).ToList(); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public InvoiceBaseDC LoadInvoiceBaseByOid(long invoiceBaseOid) { try { var r = MapperFactory.InvoiceBaseDC_InvoiceBase.MapToNewDC( DAOFactory.GenericDAO.LoadByID(invoiceBaseOid)); if (r.Type == InvoiceType.Settlement && r.SupportConceptOid != null) { SupportConcept sc = DAOFactory.GenericDAO.LoadByID(r.SupportConceptOid.Value); r.CustomerFirstName = sc.Customer.Person.FirstName; r.CustomerLastName = sc.Customer.Person.LastName; } return r; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public InvoiceNumberDC LoadInvoiceNumber() { try { var inr = DAOFactory.GenericDAO.LoadByID(1); if (inr != null) return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDC(inr); return null; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public ServiceInvoiceDC LoadServiceInvoiceByOid(long serviceInvoiceOid) { try { var r = MapperFactory.ServiceInvoiceDC_ServiceInvoice.MapToNewDC(DAOFactory.GenericDAO.LoadByID(serviceInvoiceOid)); return r; } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List UpdateInvoiceBases(List invoices) { try { var originals = DAOFactory.GenericDAO.LoadByIDs(invoices.Select(i => i.InvoiceBaseOid.Value)); MapperFactory.InvoiceBaseDC_InvoiceBase.MergeWithEntitys(invoices, originals); DAOFactory.GenericDAO.Update(originals); return originals.Select(e => e.Version.Value).ToList(); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List SetInvoicePaid(List invoices, bool isPaid) { try { var originals = DAOFactory.GenericDAO.LoadByIDs(invoices.Select(i => i.InvoiceBaseOid.Value)); foreach (var invoiceBase in originals) { invoiceBase.IsPaid = isPaid; } DAOFactory.GenericDAO.Update(originals); return originals.Select(e => e.Version.Value).ToList(); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public InvoiceNumberDC UpdateInvoiceNumber(InvoiceNumberDC dc) { try { var old = DAOFactory.GenericDAO.LoadByID(1); MapperFactory.InvoiceNumberDC_InvoiceNumber.MergeWithEntity(dc, old); DAOFactory.GenericDAO.Update(old); return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDC(old); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List UpdateServiceInvoices(List invoices) { try { var originals = DAOFactory.GenericDAO.LoadByIDs(invoices.Select(i => i.ServiceInvoiceOid.Value)); MapperFactory.ServiceInvoiceDC_ServiceInvoice.MergeWithEntitys(invoices, originals); DAOFactory.GenericDAO.Update(originals); return originals.Select(e => e.Version.Value).ToList(); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public void UpdateSettlementInvoice(List invoices) { try { var originals = DAOFactory.GenericDAO.LoadByIDs(invoices.Select(i => i.SettlementIvoiceOid.Value)); MapperFactory.SettlementDC_SettlementInvoice.MergeWithEntitys(invoices, originals); //originals.ForEach( // i => // { //i.InvoiceBase.Type = InvoiceType.Settlement; // We´ll add an invoiceitem, so we can treat a settlement like any other invoice //i.InvoiceBase.InvoiceItems.Clear(); //i.InvoiceBase.InvoiceItems.Add( // new InvoiceItem // { // AmountTotal = i.Claim, // ItemPeriodStart = i.InvoiceBase.AccountingPeriodStart, // ItemPeriodEnd = i.InvoiceBase.AccountingPeriodEnd, // ItemDescription = "Spitzabrechung" // }); //}); DAOFactory.GenericDAO.Update(originals); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List LoadInvoiceNumberList() { try { var numbers = DAOFactory.GenericDAO.GetAllActive(); return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDCs(numbers); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } public List UpdateInvoiceNumberList(List dclist) { try { var numbers = DAOFactory.GenericDAO.GetAllActive(); MapperFactory.InvoiceNumberDC_InvoiceNumber.MergeWithEntitys(dclist, numbers); DAOFactory.GenericDAO.Update(numbers); return MapperFactory.InvoiceNumberDC_InvoiceNumber.MapToNewDCs(numbers); } catch (Exception e) { throw Utils.CreateBeWoFaultException(e); } } } }