using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Net;
using System.ServiceModel;
using System.Text;
using System.Threading;

using BeWo.Data;
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Data.ICD10;
using BeWo.Service.Configuration;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.Invoicing;
using BeWo.Service.Plugins;
using BeWo.Service.Security;
using BeWo.Service.ServiceContracts;

using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.Compact;
using BS.Shared.DataContracts.Reports;
using BS.Shared.Extensions;
using BS.Shared.Services;
using Utils = BeWo.Service.Core.Utils;

namespace BeWo.Service.ServiceImplementations
{
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
    public class OperationsServiceImp : IOperationsService
    {
        #region Public Methods

        public Mandator GetMandatorEntity()
        {
            return AppSettings.GetMandatorEntity();
        }

        #endregion

        #region Implemented Interfaces

        #region IOperationsService

        public void DeactivateInvoices(List<InvoiceDC> pInvoices)
        {
            try
            {
                ServiceLogic.SetActivationType<Invoice>(pInvoices.ToDictionary(i => i.InvoiceOid.Value, i => i.InvoiceVersion.Value), ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeactivateServiceCategories(Dictionary<long, long> pOid2Version)
        {
            try
            {
                ServiceLogic.SetActivationType<ServiceCategory>(pOid2Version, ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeactivateAdditionalServices(Dictionary<long, long> pOid2Version)
        {
            try
            {
                ServiceLogic.SetActivationType<AdditionalService>(pOid2Version, ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeactivateServiceCategory(long pOid, long pVersion)
        {
            try
            {
                ServiceLogic.SetActivationType<ServiceCategory>(new Dictionary<long, long>
                {
                    {
                        pOid, pVersion
                    }
                }, ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeactivateServiceDescription(long pOid, long pVersion)
        {
            try
            {
                ServiceLogic.SetActivationType<ServiceDescription>(new Dictionary<long, long>
                {
                    {
                        pOid, pVersion
                    }
                }, ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeactivateServiceDescriptions(Dictionary<long, long> pOid2Version)
        {
            try
            {
                ServiceLogic.SetActivationType<ServiceDescription>(pOid2Version, ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeactivateAdditionalServiceRegions(Dictionary<long, long> pOid2Version)
        {
            try
            {
                ServiceLogic.SetActivationType<AdditionalServiceRegion>(pOid2Version, ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteAccountingTransaction(long pOid, long pVersion)
        {
            try
            {
                DeleteAccountingTransactions(new Dictionary<long, long>
                {
                    {
                        pOid, pVersion
                    }
                });
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteAccountingTransactions(Dictionary<long, long> pOid2Version)
        {
            try
            {
                List<AccountingTransaction> lOriginals = DAOFactory.GenericDAO.LoadByIDs<AccountingTransaction>(pOid2Version.Select(e => e.Key));
                lOriginals.DoForEach(or => MapperFactory.AccountingTransactionDC_AccountingTransaction.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

                // DAOFactory.GenericDAO.Deactivate<AccountingTransaction>(lOriginals);
                DAOFactory.GenericDAO.Delete(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteFileAttachment(long pOid, long pVersion)
        {
            try
            {
                DeleteFileAttachments(new Dictionary<long, long>
                {
                    {
                        pOid, pVersion
                    }
                });
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteFileAttachments(Dictionary<long, long> pOid2Version)
        {
            try
            {
                List<FileAttachment> lOriginals = DAOFactory.GenericDAO.LoadByIDs<FileAttachment>(pOid2Version.Select(e => e.Key));
                lOriginals.DoForEach(or => MapperFactory.FileAttachmentDC_FileAttachment.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

                DAOFactory.GenericDAO.Delete(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteServiceCategories(Dictionary<long, long> pOid2Version)
        {
            try
            {
                List<ServiceCategory> lOriginals = DAOFactory.GenericDAO.LoadByIDs<ServiceCategory>(pOid2Version.Select(e => e.Key));
                lOriginals.DoForEach(or => MapperFactory.ServiceCategoryDC_ServiceCategory.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

                DAOFactory.GenericDAO.Delete(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteServiceCategory(long pOid, long pVersion)
        {
            try
            {
                DeleteServiceCategories(new Dictionary<long, long>
                {
                    {
                        pOid, pVersion
                    }
                });
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteServiceDescription(long pOid, long pVersion)
        {
            try
            {
                DeleteServiceDescriptions(new Dictionary<long, long>
                {
                    {
                        pOid, pVersion
                    }
                });
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteServiceDescriptions(Dictionary<long, long> pOid2Version)
        {
            try
            {
                List<ServiceDescription> lOriginals = DAOFactory.GenericDAO.LoadByIDs<ServiceDescription>(pOid2Version.Select(e => e.Key));
                lOriginals.DoForEach(or => MapperFactory.ServiceDescriptionDC_ServiceDescription.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

                DAOFactory.GenericDAO.Delete(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteServiceRecord(long pOid, long pVersion)
        {
            try
            {
                DeleteServiceRecords(new Dictionary<long, long>
                {
                    {
                        pOid, pVersion
                    }
                });
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteServiceRecords(Dictionary<long, long> pOid2Version)
        {
            InternalDeleteServicerecords(pOid2Version);
        }

        public static void InternalDeleteServicerecords(IDictionary<long, long> pOid2Version)
        {
            try
            {
                var lOriginals = DAOFactory.GenericDAO.LoadByIDs<ServiceRecord>(pOid2Version.Select(e => e.Key));

                lOriginals.DoForEach(or => MapperFactory.ServiceRecordDC_ServiceRecord.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

                var srListToDelete = new List<ServiceRecord>();


                foreach (var item in lOriginals)
                {
                    if (item.Group != null)
                    {
                        MakeServiceRecordHistoryEntry(item.Group.ServiceRecordList, null, StatementType.Delete);

                        DAOFactory.GenericDAO.Delete(item.Group);
                    }
                    else
                    {
                        srListToDelete.Add(item);
                    }
                }

                if (srListToDelete.Count > 0)
                {
                    MakeServiceRecordHistoryEntry(srListToDelete, null, StatementType.Delete);
                    DAOFactory.GenericDAO.Delete(srListToDelete);
                }
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public Settlement2DC GenerateInitialSettlementDC(long pCostBearer2SupportConceptOid)
        {
            return GenerateInitialSettlementDCForPeriod(pCostBearer2SupportConceptOid, null, null);
        }

        public Settlement2DC GenerateInitialSettlementDCForPeriod(long pCostBearer2SupportConceptOid, DateTime? periodStart, DateTime? periodEnd)
        {
            try
            {
                var lCb2Sc = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(pCostBearer2SupportConceptOid);

                var costBearer = lCb2Sc.CostBearer;
                string tenant = null;

                if (MultitenancyOperationContextExt.Current != null)
                {
                    tenant = MultitenancyOperationContextExt.Current.Tenant;
                }

                var creator = PluginLoader.FindClass<SettlementInvoiceCreation>(costBearer.ID) ?? SettlementInvoiceCreation.GetInstance(costBearer.ID, tenant);
                var lResult = creator.GenerateSettlementInvoice(lCb2Sc, periodStart, periodEnd);

                return lResult;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<Settlement2DC> GenerateInitialSettlementDCsForPeriod(long pCostBearer, DateTime periodStart, DateTime periodEnd)
        {
            return new CustomerServiceImp()
                .GetAllActiveSupportConceptsCompact()
                .Where(i => i.IsApproved && i.CostBearerOids2CostBearerRelOids.ContainsKey(pCostBearer))
                .Select(i => GenerateInitialSettlementDCForPeriod(i.CostBearerOids2CostBearerRelOids[pCostBearer], periodStart, periodEnd))
                .ToList();
        }

        public List<AccountingTransactionDC> GetAccountingTransactions(DateTimeSpan pSpan, long? pSupportConceptOid, long? pSupportConceptCostBearerRelOid)
        {
            try
            {
                return MapperFactory.AccountingTransactionDC_AccountingTransaction.MapToNewDCs(DAOFactory.SearchDAO.FindAccoutingTransactions(pSpan, pSupportConceptOid, pSupportConceptCostBearerRelOid));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<InvoiceDC> GetAllActiveInvoices()
        {
            try
            {
                return MapperFactory.InvoiceDC_Invoice.MapToNewDCs(DAOFactory.GenericDAO.GetAllActive<Invoice>());
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<CompactSupportConceptDC> GetAllActiveSupportConceptCostbearer(bool onlyApproved, bool onlyWithAssignedCostbearer, long employeeOid)
        {
            try
            {
                IList<SupportConcept> list;
                if (onlyApproved)
                {
                    list = DAOFactory.SearchDAO.FindAllActiveApprovedSupportConcepts();
                }
                else
                {
                    list = DAOFactory.GenericDAO.GetAllActive<SupportConcept>();
                }

                List<CompactSupportConceptDC> result = CreateFlatSupportConceptCostBearerDCList(list, onlyWithAssignedCostbearer, employeeOid);

                if (onlyApproved)
                {
                    return result.Where(i => i.IsApproved).ToList();
                }

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<AdditionalServiceDC> GetAllAdditionalService()
        {
            try
            {
                IList<AdditionalService> list = DAOFactory.GenericDAO.GetAllActive<AdditionalService>();
                return MapperFactory.AdditionalServiceDC_AdditionalService.MapToNewDCs(list);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<AdditionalServiceRegionDC> GetAllAdditionalServiceRegion()
        {
            try
            {
                var result = new List<AdditionalServiceRegionDC>();

                result =
                    MapperFactory.AdditionalServiceRegionDC_AdditionalServiceRegion.MapToNewDCs(
                        DAOFactory.GenericDAO.GetAllActive<AdditionalServiceRegion>());

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceCategoryDC> GetAllServiceCategories()
        {
            try
            {
                IList<ServiceCategory> list = DAOFactory.GenericDAO.GetAllActive<ServiceCategory>();
                return MapperFactory.ServiceCategoryDC_ServiceCategory.MapToNewDCs(list);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceDescriptionDC> GetAllServiceDescriptions()
        {
            try
            {
                IList<ServiceDescription> list = DAOFactory.GenericDAO.GetAllActive<ServiceDescription>();
                AppSettings settings = AppSettings.CreateSettings();
                if (settings.SortServiceDescriptionAlphabetically)
                {
                    list = list.OrderBy(sd => sd.Name).ToList();
                }
                return MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewDCs(list);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceDescriptionDC> FindServiceDescriptionsForCategory(long pCategoryOid)
        {
            try
            {
                return MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewDCs(DAOFactory.SearchDAO.FindServiceDescriptionForCategory(pCategoryOid));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public ServiceDescriptionDC GetServiceDescription(long pServiceDescriptionOid)
        {
            try
            {
                return MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewDC(DAOFactory.GenericDAO.GetByID<ServiceDescription>(pServiceDescriptionOid));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string GetCompressedICD10Diagnosis()
        {
            try
            {
                return ICD10DAO.GetCompressedString();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public CustomerInfoDC GetCustomerInfosForCustomerOid(long customerOid)
        {
            try
            {
                var result = new CustomerInfoDC();
                var customer = DAOFactory.GenericDAO.LoadByID<Customer>(customerOid);

                if (customer.SupportConcepts == null || !customer.SupportConcepts.Exists(sc => sc.IsActive == ActivationTypeId.Active))
                {
                    result.CurrentSupportConcept = "Kein aktueller Hilfeplan";
                }
                else
                {
                    SupportConcept currentSC = customer.SupportConcepts.Where(sc => sc.IsActive == ActivationTypeId.Active).OrderByDescending(sc => sc.StartDate).First();

                    result.CurrentSupportConcept = "Akt. HP: ";
                    if (currentSC.StartDate.HasValue)
                    {
                        result.CurrentSupportConcept += currentSC.StartDate.Value.ToShortDateString().Remove(6, 2);
                    }

                    if (currentSC.EndDate.HasValue)
                    {
                        result.CurrentSupportConcept += " - " + currentSC.EndDate.Value.ToShortDateString().Remove(6, 2);
                    }

                    result.SupportConceptInfos = GetSupportConceptInfosForSupportConceptOid(currentSC.Oid.Value);
                }

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceRecordDC> GetCustomerServiceRecordsCompact(long pCustomerOid, long costbearer2SupportConceptOid, long? days)
        {
            try
            {
                var result = new List<ServiceRecordDC>();
                var srList = DAOFactory.SearchDAO.FindServiceRecordsDetailsForLastDays(costbearer2SupportConceptOid, days);

                if (srList != null)
                {
                    var serviceRecordsProcessed = new Dictionary<long, bool>();
                    foreach (var item in srList)
                    {
                        if (!serviceRecordsProcessed.ContainsKey(item.Oid.Value))
                        {
                            //ServiceRecordDC dc = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDC(item);
                            //result.Add(dc);
                            var dc = CreateServiceRecordDCCompact(item);
                            if (dc != null)
                            {
                                result.Add(dc);
                            }

                            serviceRecordsProcessed.Add(item.Oid.Value, true);
                        }
                    }
                }

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceRecordDC> GetCustomerServiceRecords(long pCustomerOid, bool fetchArchivedSupportConcepts)
        {
            try
            {
                var result = new List<ServiceRecordDC>();

                var lCustomer = DAOFactory.SearchDAO.FindCustomerWithServiceRecordsWithDetail(pCustomerOid);
                if (lCustomer != null)
                {
                    var srList = lCustomer.ServiceRecordList;

                    if (srList != null)
                    {
                        var serviceRecordsProcessed = new Dictionary<long, bool>();
                        foreach (var item in srList)
                        {
                            if (!serviceRecordsProcessed.ContainsKey(item.Oid.Value))
                            {
                                var dc = CreateServiceRecordDCIfSupportConceptIsActive(item, lCustomer, !fetchArchivedSupportConcepts);
                                if (dc != null)
                                {
                                    result.Add(dc);
                                }

                                serviceRecordsProcessed.Add(item.Oid.Value, true);
                            }
                        }
                    }
                }

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceRecordDC> GetCustomerServiceRecordsInMonth(long pCustomerOid, DateTime pMonth)
        {
            try
            {
                var list = GetCustomerServiceRecords(pCustomerOid, false);

                return list.Where(i => i.Start.HasValue && i.Start.Value.Year.Equals(pMonth.Year) && i.Start.Value.Month.Equals(pMonth.Month)).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceRecordDC> GetEmployeesServiceRecords(long pEmployeeOid)
        {
            try
            {
                IEnumerable<ServiceRecord> list = DAOFactory.SearchDAO.FindEmployeeServiceRecordsWithoutCustomer(pEmployeeOid, null);

                return MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs(list);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

		public List<ServiceRecordDC> GetEmployeesServiceRecords2(long pEmployeeOid, long? days)
		{
			try
			{
				IEnumerable<ServiceRecord> list = DAOFactory.SearchDAO.FindEmployeeServiceRecordsWithoutCustomer(pEmployeeOid, days);

				return MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs(list);
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

		public List<ServiceRecordDC> GetEmployeesServiceRecordsInSpan(long pEmployeeOid, DateTimeSpan limitinDateTimeSpan)
		{
			try
			{
				IEnumerable<ServiceRecord> list = DAOFactory.SearchDAO.FindEmployeeServiceRecordsWithoutCustomerInSpan(pEmployeeOid, limitinDateTimeSpan);

				return MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs(list);
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
		}

        public List<FileAttachmentDC> GetFileAttachments(TableID pObjectTid, long pObjectOid)
        {
            try
            {
                IEnumerable<FileAttachmentInfo> files = DAOFactory.SearchDAO.FindFileAttachmentInfos(pObjectTid, pObjectOid);

                return files.Select(item => MapperFactory.FileAttachmentDC_FileAttachmentInfo.MapToNewDC(item)).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<BeWoFolderDC> GetFolderTree(TableID pObjectTid, long pObjectOid)
        {
            try
            {
                IList<BeWoFolder> folder = DAOFactory.SearchDAO.FindBeWoFolders(pObjectTid, pObjectOid);
                bool templateFolder = folder.Any(f => f.SystemEntryID.Equals(SystemEntryID.TemplateDirectory));
                var folderDCList = new List<BeWoFolderDC>();

                foreach (BeWoFolder item in folder)
                {
                    folderDCList.Add(MapperFactory.BeWoFolderDC_BeWoFolder.MapToNewDC(item));
                }

                IEnumerable<FileAttachmentInfo> files = DAOFactory.SearchDAO.FindFileAttachmentInfos(pObjectTid, pObjectOid);
                var fileDCList = new List<FileAttachmentDC>();

                foreach (FileAttachmentInfo item in files)
                {
                    fileDCList.Add(MapperFactory.FileAttachmentDC_FileAttachmentInfo.MapToNewDC(item));
                }

                Thread.Sleep(500);

                return CreateFolderTree(folderDCList, fileDCList, pObjectTid, pObjectOid, templateFolder);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteFolder(long pBeWoFolderOid, long pVersion)
        {
            try
            {
                var origFolder = DAOFactory.GenericDAO.LoadByID<BeWoFolder>(pBeWoFolderOid);
                MapperFactory.BeWoFolderDC_BeWoFolder.ConcurrencyCheck(pVersion, origFolder);

                DAOFactory.GenericDAO.Delete(origFolder);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public long InsertNewFolder(BeWoFolderDC folder)
        {
            try
            {
                BeWoFolder newFolder = MapperFactory.BeWoFolderDC_BeWoFolder.MapToNewEntity(folder);

                DAOFactory.GenericDAO.Insert(newFolder);

                BeWoFolderDC newFolderDC = MapperFactory.BeWoFolderDC_BeWoFolder.MapToNewDC(newFolder);
                return newFolderDC.BeWoFolderOid.Value;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public BeWoFolderDC UpdateFolder(BeWoFolderDC folder)
        {
            try
            {
                //Root Folder kann nicht umbenannt werden
                var origFolder = DAOFactory.GenericDAO.LoadByID<BeWoFolder>(folder.BeWoFolderOid.Value);

                MapperFactory.BeWoFolderDC_BeWoFolder.MergeWithEntity(folder, origFolder);


                DAOFactory.GenericDAO.Update(origFolder);

                BeWoFolderDC updatedFolderDC = MapperFactory.BeWoFolderDC_BeWoFolder.MapToNewDC(origFolder);
                return updatedFolderDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public FileAttachmentDC UpdateFileAttachment(FileAttachmentDC file)
        {
            try
            {
                var origFile = DAOFactory.GenericDAO.LoadByID<FileAttachmentInfo>(file.FileAttachmentOid.Value);
                MapperFactory.FileAttachmentDC_FileAttachmentInfo.MergeWithEntity(file, origFile);

                DAOFactory.GenericDAO.Update(origFile);

                FileAttachmentDC updatedFileDC = MapperFactory.FileAttachmentDC_FileAttachmentInfo.MapToNewDC(origFile);
                return updatedFileDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public FileAttachmentDC DoTheRealFileUpdate(FileAttachmentDC file)
        {
            try
            {
                var origFile = DAOFactory.GenericDAO.LoadByID<FileAttachment>(file.FileAttachmentOid.Value);
                if (!origFile.Data.Equals(file.BinaryData))
                {
                }
                MapperFactory.FileAttachmentDC_FileAttachment.MergeWithEntity(file, origFile);

                DAOFactory.GenericDAO.Update(origFile);

                FileAttachmentDC updatedFileDC = MapperFactory.FileAttachmentDC_FileAttachment.MapToNewDC(origFile);
                return updatedFileDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public MandatorDC GetMandator()
        {
            try
            {
                Mandator man = GetMandatorEntity();
                MandatorDC manDc = MapperFactory.MandatorDC_Mandator.MapToNewDC(man);

                Dictionary<string, string> settingValueDict = GetSettingsValueDict(manDc.Settings);


                string contractState = GetContractState();
                Dictionary<string, string> contractStateDict = GetSettingsValueDict(contractState);

                foreach (var kv in contractStateDict)
                {
                    if (settingValueDict.ContainsKey(kv.Key))
                    {
                        settingValueDict.Remove(kv.Key);
                    }
                    settingValueDict.Add(kv.Key, kv.Value);
                }
                if (!settingValueDict.ContainsKey("ShowScheduler") && man.IsSchedulerAllowed)
                {
                    settingValueDict.Add("ShowScheduler", "1");
                }
                if (!settingValueDict.ContainsKey("ShowMedication") && man.IsMedicationAllowed)
                {
                    settingValueDict.Add("ShowMedication", "1");
                }
                manDc.Settings = "";
                foreach (var kv in settingValueDict)
                {
                    if (manDc.Settings.Length > 0)
                    {
                        manDc.Settings += ";";
                    }
                    manDc.Settings += String.Format("{0}={1}", kv.Key, kv.Value);
                }

                return manDc;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceRecordHistoryDC> GetServiceRecordHistory(long serviceRecordOid)
        {
            try
            {
                IEnumerable<ServiceRecordHistory> historyList = DAOFactory.SearchDAO.FindServiceRecordHistory(serviceRecordOid);

                List<ServiceRecordHistoryDC> result = MapperFactory.ServiceRecordHistoryDC_ServiceRecordHistory.MapToNewDCs(historyList);

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public ServiceRecordGroupDC GetServiceRecordGroup(long pGroupOid)
        {
            try
            {
                ServiceRecordGroup group = DAOFactory.SearchDAO.FindServiceRecordGroup(pGroupOid);

                ServiceRecordGroupDC groupDC = MapperFactory.ServiceRecordGroupDC_ServiceRecordGroup.MapToNewDC(group);

                var result = new List<ServiceRecordDC>();

                var serviceRecordsProcessed = new Dictionary<long, bool>();
                foreach (ServiceRecord item in group.ServiceRecordList)
                {
                    if (!serviceRecordsProcessed.ContainsKey(item.Oid.Value))
                    {
                        var dc = new ServiceRecordDC();

                        dc.ServiceRecordOid = item.Oid;
                        dc.ServiceRecordVersion = item.Version;
                        dc.Start = item.Start;
                        dc.End = item.End;
                        dc.Notice = item.Notice;
                        dc.Notice2 = item.Notice2;
                        dc.Notice3 = item.Notice3;
                        dc.Notice4 = item.Notice4;
                        dc.Notice5 = item.Notice5;
                        dc.RoundedDuration = item.RoundedDuration;
                        dc.InsertedOn = item.InsTs;
                        dc.InsUser = item.InsUser;

                        CompactCustomerDC customerDC = null;
                        if (item.Customer != null)
                        {
                            customerDC = new CompactCustomerDC();

                            customerDC.CustomerOid = item.Customer.Oid.Value;
                            customerDC.CustomerVersion = item.Customer.Version.Value;
                            customerDC.FirstName = item.Customer.Person.FirstName;
                            customerDC.LastName = item.Customer.Person.LastName;
                            customerDC.DateOfBirth = item.Customer.Person.DateOfBirth;
                            customerDC.Sex = item.Customer.Person.Sex;
                            customerDC.ActivationType = item.Customer.IsActive;
                            customerDC.TerminationDate = item.Customer.TerminationDate;
                            customerDC.EquityContribution = item.Customer.EquityContribution;
                        }

                        dc.Customer = customerDC;
                        if (item.Employee != null)
                        {
                            var employeeDC = new CompactEmployeeDC();

                            employeeDC.EmployeeOid = item.Employee.Oid.Value;
                            employeeDC.EmployeeVersion = item.Employee.Version.Value;
                            employeeDC.FirstName = item.Employee.Person.FirstName;
                            employeeDC.LastName = item.Employee.Person.LastName;
                            employeeDC.PersonnelNumber = item.Employee.PersonnelNumber;
                            //employeeDC.FLSPerWeek = item.Employee.WeeklyFLS;

                            dc.Employee = employeeDC;
                        }

                        CompactSupportConceptDC scDC = null;
                        if (item.SupportConcept != null)
                        {
                            scDC = new CompactSupportConceptDC();

                            scDC.SupportConceptOid = item.SupportConcept.Oid.Value;
                            scDC.SupportConceptVersion = item.SupportConcept.Version.Value;
                            scDC.Customer = customerDC;
                            scDC.ActivationType = item.SupportConcept.IsActive;
                            scDC.ConferenceDate = item.SupportConcept.ConferenceDate;
                        }

                        dc.SupportConcept = scDC;

                        CostBearer2SupportConcept cb2sc = item.CostBearer2SupportConcept;
                        if (cb2sc != null)
                        {
                            dc.CostBearer2SupportConceptOid = cb2sc.Oid.Value;

                            if (scDC != null)
                            {
                                var costBearer = new CompactCostBearerDC();

                                costBearer.IsCalculatingWithFactor = cb2sc.CostBearer.IsCalculatingWithFactor;
                                costBearer.CostBearerID = cb2sc.CostBearer.ID;
                                costBearer.CostBearerOid = cb2sc.CostBearer.Oid.Value;
                                costBearer.CostBearer2SupportConceptOid = cb2sc.Oid.Value;
                                costBearer.SupportConceptStatus = cb2sc.Status;
                                costBearer.RequestedStartDate = cb2sc.RequestedStartDate;
                                costBearer.RequestedEndDate = cb2sc.RequestedEndDate;
                                costBearer.ApprovedStartDate = cb2sc.ApprovedStartDate;
                                costBearer.ApprovedEndDate = cb2sc.ApprovedEndDate;

                                // costBearer.ApprovedFLS = cb2sc.ApprovedFLS;
                                // costBearer.ApprovedFLSTotal = cb2sc.ApprovedFLSTotal;
                                costBearer.CustomerReferenceNumber = cb2sc.CustomerReferenceNumber;

                                if (cb2sc.CostBearer.Organisation != null)
                                {
                                    CompactOrganisationDC orgDC = MapperFactory.CompactOrganisationDC_Organisation.MapToNewDC(cb2sc.CostBearer.Organisation);

                                    costBearer.Organisation = orgDC;

                                    dc.CostBearer = orgDC;
                                }

                                scDC.CostBearerList.Add(costBearer);
                                scDC.CustomerReferenceNumbers.Add(cb2sc.CustomerReferenceNumber);
                                scDC.CostBearerRelOids.Add(cb2sc.Oid.Value);
                            }
                        }

                        dc.GroupEmployeeCount = item.GroupEmployeeCount;
                        dc.GroupPersonCount = item.GroupPersonCount;
                        dc.GroupRoundedDuration = item.GroupRoundedDuration;
                        dc.GroupOid = item.GroupOid;

                        result.Add(dc);

                        serviceRecordsProcessed.Add(item.Oid.Value, true);
                    }
                }

                groupDC.ServiceRecordList = result;

                return groupDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<SupportConcetInfoDC> GetSupportConceptInfosForSupportConceptOid(long supportConceptOid)
        {
            try
            {
                var sc = DAOFactory.GenericDAO.LoadByID<SupportConcept>(supportConceptOid);
                return sc.CostBearer2SupportConceptList.Select(
                    cb2sc =>
                    {
                        Calculations calc = PluginLoader.FindClass<Calculations>(cb2sc.CostBearer.ID) ?? Calculations.GetInstance(cb2sc.CostBearer.ID);
                        var res = new SupportConcetInfoDC
                        {
                            CostBearer = cb2sc.CostBearer.Organisation.Name,
                            ApprovedHours = calc.GetApprovedHoursTotal(cb2sc.MapToNewDC(), true) ?? 0m,
                            RecordedHours = calc.GetBillableDurationInMinutes(cb2sc.ServiceRecords.MapToNewDCsCompact())/60
                        };

                        // if (cb2sc.ApprovedStartDate.HasValue && cb2sc.ApprovedEndDate.HasValue)
                        // {
                        // decimal lDurationInWeeks = Convert.ToDecimal((cb2sc.ApprovedEndDate.Value - cb2sc.ApprovedStartDate.Value).Days + 1) / 7;

                        // if (cb2sc.ApprovedFLSTotal == null)
                        // {
                        // if (cb2sc.ApprovedFLS.HasValue)
                        // {
                        // res.ApprovedHours = cb2sc.ApprovedFLS.Value * lDurationInWeeks;
                        // }
                        // }
                        // else
                        // {
                        // res.ApprovedHours = cb2sc.ApprovedFLSTotal.Value;
                        // }
                        // }

                        // res.RecordedHours = 0;
                        // if (cb2sc.ServiceRecords != null)
                        // {
                        // foreach (var sr in cb2sc.ServiceRecords)
                        // {
                        // if (sr.ServiceDescription != null && sr.ServiceDescription.ServiceCategory != null && sr.ServiceDescription.ServiceCategory.IsBillable)
                        // {
                        // decimal rd = sr.RoundedDuration;

                        // if (sr.ServiceDescription.ServiceCategory.Percentage != 100)
                        // {
                        // rd = (rd * sr.ServiceDescription.ServiceCategory.Percentage) / 100;
                        // }

                        // res.RecordedHours += rd;
                        // }
                        // }
                        // }

                        // res.RecordedHours /= 60;
                        return res;
                    }).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<SupportConceptTreeNodeDC> GetSupportConceptTreeAllActive()
        {
            try
            {
                return BuildTree(DAOFactory.GenericDAO.GetAllActiveAndArchived<SupportConcept>());
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<SupportConceptTreeNodeDC> GetSupportConceptTreeAllActiveWithCostbearer()
        {
            try
            {
                return BuildTree(DAOFactory.GenericDAO.GetAllActive<SupportConcept>().Where(sc => sc.CostBearer2SupportConceptList.Count > 0));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<SupportConceptTreeNodeDC> GetSupportConceptTreeAllCurrent()
        {
            try
            {
                return BuildTree(DAOFactory.SearchDAO.FindCurrentSupportConcepts());
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<SupportConceptTreeNodeDC> GetSupportConceptTreeByEmployee(long pEmployeeOid)
        {
            try
            {
                long starttime = DateTime.Now.Ticks;

                var lResult = new List<SupportConceptTreeNodeDC>();

                var lEmployee = DAOFactory.GenericDAO.LoadByID<Employee>(pEmployeeOid);

                IList<Person> persons = DAOFactory.SearchDAO.GetActivePersonsWithType(PersonType.Customer);

                IEnumerable<Customer> customers = DAOFactory.SearchDAO.GetAllActiveCustomersWithSupportConceptData();

                // int test = customers.Count;
                // customers = customers.Distinct().ToList();
                // test = customers.Count;
                IList<Employee2Customer> list = lEmployee.Employee2CustomerList;

                var customerOIDs = new Dictionary<long, long>();
                foreach (Employee2Customer item in list)
                {
                    if (!customerOIDs.ContainsKey(item.Customer.Oid.Value))
                    {
                        customerOIDs.Add(item.Customer.Oid.Value, item.Customer.Oid.Value);
                    }
                }

                // IList<Address> Addresses = DAOFactory.GenericDAO.GetAll<Address>();

                // IList<CostBearer2SupportConcept> costbearer2supportconcept = DAOFactory.GenericDAO.GetAll<CostBearer2SupportConcept>();
                // IList<SupportConcept> supportConcepts = DAOFactory.GenericDAO.GetAll<SupportConcept>();
                // IList<Organisation> Organisations = DAOFactory.GenericDAO.GetAll<Organisation>();
                // IList<CostBearer> Costbearer = DAOFactory.GenericDAO.GetAll<CostBearer>();

                // IList<AbsenceReason> AbsenceReasons = DAOFactory.GenericDAO.GetAll<AbsenceReason>();
                // IList<AbsenceTime> AbsenceTimes = DAOFactory.GenericDAO.GetAll<AbsenceTime>();

                // IList<Customer2CostBearer> Customer2CostBearers = DAOFactory.GenericDAO.GetAll<Customer2CostBearer>();

                // IList<CostRatePeriod> CostRatePeriods = DAOFactory.GenericDAO.GetAll<CostRatePeriod>();

                // IList<ServiceRecord> ServiceRecords = DAOFactory.GenericDAO.GetAll<ServiceRecord>();

                // foreach (var iCustomer in lEmployee.Employee2CustomerList
                // .Where(e2c => (e2c.IsActive == ActivationTypeId.Active || e2c.IsActive == ActivationTypeId.Archived) && (e2c.Customer.IsActive == ActivationTypeId.Active || e2c.Customer.IsActive == ActivationTypeId.Archived))
                // .Select(e2c => e2c.Customer).Distinct())
                var customerProcessed = new Dictionary<long, bool>();
                var supportConceptProcessed = new Dictionary<long, bool>();

                foreach (Customer iCustomer in customers)
                {
	                if (iCustomer.Oid.Value == 53)
	                {
		                int test = 0;
	                }
                    if (!customerProcessed.ContainsKey(iCustomer.Oid.Value))
                    {
                        var lCustomerNode = new SupportConceptTreeNodeDC
                        {
                            NodeType = iCustomer.Person.Sex == Sex.Male
                                ? NodeType.Customer_Male
                                : NodeType.Customer_Female,
                            Employee = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(lEmployee),
                            Customer = CreateCustomerForSupportConceptTree(iCustomer)



                            // MapperFactory.CompactCustomerDC_Customer.MapToNewDC(iCustomer)
                        };
                        if (customerOIDs.ContainsKey(iCustomer.Oid.Value))
                        {
                            lCustomerNode.IsRelatedToEmployee = true;
                        }

                        lResult.Add(lCustomerNode);

                        foreach (SupportConcept iSupportConcept in
                            iCustomer.SupportConcepts.Where(e2c => (e2c.IsActive == ActivationTypeId.Active || e2c.IsActive == ActivationTypeId.Archived)))
                        {
                            if (!supportConceptProcessed.ContainsKey(iSupportConcept.Oid.Value))
                            {
                                var lSupportConceptNode = new SupportConceptTreeNodeDC
                                {
                                    NodeType = NodeType.SupportConcept,
                                    Employee = lCustomerNode.Employee,
                                    Customer = lCustomerNode.Customer,
                                    SupportConcept = CreateSCForSupportConceptTree(iSupportConcept)



                                    // MapperFactory.CompactSupportConceptDC_SupportConcept.MapToNewDC(iSupportConcept)
                                };
                                lSupportConceptNode.SupportConcept.Customer = lCustomerNode.Customer;

                                // if (getSupportConceptGoals)
                                // {
                                // lSupportConceptNode.SupportConcept.Goals = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDCs(
                                // iSupportConcept.ValueList.FindByType(ValueListEntryType.CustomerCareType).Select(e2o => e2o.Entry));
                                // }
                                lSupportConceptNode.IsRelatedToEmployee = lCustomerNode.IsRelatedToEmployee;
                                lCustomerNode.ChildNodes.Add(lSupportConceptNode);

                                foreach (CostBearer2SupportConcept iSC2Cb in
                                    iSupportConcept.CostBearer2SupportConceptList.Where(e2c => (e2c.IsActive == ActivationTypeId.Active || e2c.IsActive == ActivationTypeId.Archived)))
                                {
                                    var lSC2CbNode = new SupportConceptTreeNodeDC
                                    {
                                        NodeType = NodeType.CostBearer,
                                        Employee = lSupportConceptNode.Employee,
                                        Customer = lSupportConceptNode.Customer,
                                        SupportConcept = lSupportConceptNode.SupportConcept,
                                        SupportConceptCostBearerRelDC = CreateSCCostBearerRelForSupportConceptTree(iSC2Cb)


                                        // ??? warum nicht mapper?
                                        // MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(iSC2Cb)
                                    };
                                    lSC2CbNode.SupportConceptCostBearerRelDC.SupportConcept = lSupportConceptNode.SupportConcept;

                                    lSC2CbNode.IsRelatedToEmployee = lCustomerNode.IsRelatedToEmployee;

                                    if (iSC2Cb.CostBearer.Organisation != null)
                                    {
                                        lSC2CbNode.CostBearer = MapperFactory.CompactOrganisationDC_Organisation.MapToNewDC(iSC2Cb.CostBearer.Organisation);
                                    }

                                    lSupportConceptNode.ChildNodes.Add(lSC2CbNode);
                                }

                                supportConceptProcessed.Add(iSupportConcept.Oid.Value, true);
                            }
                        }

                        customerProcessed.Add(iCustomer.Oid.Value, true);
                    }
                }

                long endtime = DateTime.Now.Ticks;

                long diff = endtime - starttime;
                double secs = diff/(double) 10000000;

                // 10 Mio Ticks = 1Sec.
                return lResult;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<SupportConceptTreeNodeDC> GetSupportConceptTreeInSpan(DateTimeSpan pSpan)
        {
            try
            {
                return BuildTree(DAOFactory.SearchDAO.FindSupportConceptsInSpan(pSpan));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public SupportConceptTreeNodeDetailInfoDC GetSupportConceptTreeNodeDetailInfo(long pCustomerOid, long? pSupportConceptOid, long? pCostbearer2SupportConceptOid)
        {
            try
            {
                var dc = new SupportConceptTreeNodeDetailInfoDC();

                var customer = DAOFactory.GenericDAO.LoadByID<Customer>(pCustomerOid);

                dc.CustomerAbsenceTimes = MapperFactory.AbsenceTimeDC_AbsenceTime.MapToNewDCs(customer.AbsenceTimes);

                if (pSupportConceptOid != null)
                {
                    var sc = DAOFactory.GenericDAO.LoadByID<SupportConcept>(pSupportConceptOid.Value);

                    var list = new List<ValueListEntryType>();
                    list.Add(ValueListEntryType.SupportConceptGoalType);
					list.Add(ValueListEntryType.SupportConceptGoalCategoryType);
                    list.Add(ValueListEntryType.SupportConceptIndividualGoalCategoryType);
					list.Add(ValueListEntryType.SupportConceptIndividualGoalType);

	                dc.SupportConceptGoals =
		                MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDCs(
			                sc.ValueList.FindByTypes(list)
				                .Select(e2o => e2o.Entry)
				                .Where(e => e.IsActive == ActivationTypeId.Active));

                    dc.ServiceAccountings = MapperFactory.ServiceAccountingDC_ServiceAccounting.MapToNewDCs(sc.ServiceAccountings);
                }

                if (pCostbearer2SupportConceptOid != null)
                {
                    var c2s = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(pCostbearer2SupportConceptOid.Value);
                    dc.ApprovalPeriods = MapperFactory.SupportConceptApprovalPeriodDC_SupportConceptApprovalPeriod.MapToNewDCs(c2s.ApprovalPeriodList);
                    if (dc.ApprovalPeriods != null)
                    {
                        foreach (SupportConceptApprovalPeriodDC item in dc.ApprovalPeriods)
                        {
                            if (!item.StartDate.HasValue)
                            {
                                item.StartDate = c2s.ApprovedStartDate.HasValue ? c2s.ApprovedStartDate : c2s.RequestedStartDate;
                            }
                            if (!item.EndDate.HasValue)
                            {
                                item.EndDate = c2s.ApprovedEndDate.HasValue ? c2s.ApprovedEndDate : c2s.RequestedEndDate;
                            }
                        }
                    }
                }
                return dc;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public CompactOrganisationDC FillCostbearerDetails(CompactOrganisationDC dc)
        {
            try
            {
                if (dc.CostRatePeriods == null || dc.CostRatePeriods.Count == 0)
                {
                    var org = DAOFactory.GenericDAO.LoadByID<Organisation>(dc.OrganisationOid);
                    if (org != null)
                    {
                        MapperFactory.CompactOrganisationDC_Organisation.MergeWithDC(org, dc);
                    }
                }
                return dc;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<AccountingTransactionDC> GetUnassignedAccountingTransactions()
        {
            try
            {
                IEnumerable<AccountingTransaction> list = DAOFactory.SearchDAO.FindUnassignedAccountingTransactions();

                return MapperFactory.AccountingTransactionDC_AccountingTransaction.MapToNewDCs(list);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<VarFieldDC> GetVarFieldDefs(TableID tid)
        {
            try
            {
                return MapperFactory.VarFieldDC_VarField.VarFieldMapToDCs(DAOFactory.SearchDAO.GetVarFieldDefs(tid), null);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewAccountingTransactions(List<AccountingTransactionDC> pAccountingTransactions)
        {
            try
            {
                foreach (var at in pAccountingTransactions)
                {
                    if (at.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid.HasValue && !at.SupportConceptCostBearerRelDC.CostBearer2SupportConceptVersion.HasValue)
                    {
                        var c2s = DAOFactory.GenericDAO.LoadByID<CostBearer2SupportConcept>(at.SupportConceptCostBearerRelDC.CostBearer2SupportConceptOid.Value);
                        var c2sDc = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(c2s);
                        at.SupportConceptCostBearerRelDC = c2sDc;
                    }

                }
                List<AccountingTransaction> lEntities = MapperFactory.AccountingTransactionDC_AccountingTransaction.MapToNewEntities(pAccountingTransactions);
                DAOFactory.GenericDAO.Insert(lEntities);
                return lEntities.Select(e => e.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void InsertNewInvoices(List<InvoiceDC> pInvoices)
        {
            try
            {
                DAOFactory.GenericDAO.Insert(MapperFactory.InvoiceDC_Invoice.MapToNewEntities(pInvoices));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewServiceCategories(List<ServiceCategoryDC> pServiceCategories)
        {
            try
            {
                List<ServiceCategory> lServiceCategories = MapperFactory.ServiceCategoryDC_ServiceCategory.MapToNewEntities(pServiceCategories);
                DAOFactory.GenericDAO.Insert(lServiceCategories);
                return lServiceCategories.Select(sc => sc.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewAdditionalServices(IEnumerable<AdditionalServiceDC> pAdditionalServiceDcs)
        {
            try
            {
                List<AdditionalService> lAdditionalServices = MapperFactory.AdditionalServiceDC_AdditionalService.MapToNewEntities(pAdditionalServiceDcs);
                DAOFactory.GenericDAO.Insert(lAdditionalServices);
                return lAdditionalServices.Select(ads => ads.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewServiceDescriptions(List<ServiceDescriptionDC> pServiceDescriptions)
        {
            try
            {
                List<ServiceDescription> lServiceDescriptions = MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewEntities(pServiceDescriptions);
                DAOFactory.GenericDAO.Insert(lServiceDescriptions);
                IList<SupportConcept> scToSave = new List<SupportConcept>();
                //Prüfe ob es HPs gibt wo die Leistung hinterlegt werden muss

                IList<long> newServiceDescriptionOids = new List<long>();
                foreach (ServiceDescription newSd in lServiceDescriptions)
                {
                    newServiceDescriptionOids.Add(newSd.Oid.Value);
                }
                foreach (ServiceDescription newSd in lServiceDescriptions)
                {
                    ServiceCategory cat = newSd.ServiceCategory;

                    IEnumerable<ServiceDescription> descList = DAOFactory.SearchDAO.FindServiceDescriptionForCategory(cat.Oid.Value);

                    IList<long> oids = new List<long>();
                    foreach (ServiceDescription oldSd in descList)
                    {
                        if (!newServiceDescriptionOids.Contains(oldSd.Oid.Value))
                        {
                            oids.Add(oldSd.Oid.Value);
                        }
                    }

                    //Prüfe für alle Leistungen dieser Kategorie, ob sie im Hilfeplan angehakt wurden
                    IEnumerable<ServiceAccounting> accountingList = DAOFactory.SearchDAO.FindServiceAccountingsForServiceDescriptions(oids);

                    var supportConceptCountDict = new Dictionary<long, int>();
                    foreach (ServiceAccounting acc in accountingList)
                    {
                        if (acc.SupportConceptOid.HasValue)
                        {
                            if (supportConceptCountDict.ContainsKey(acc.SupportConceptOid.Value))
                            {
                                supportConceptCountDict[acc.SupportConceptOid.Value]++;
                            }
                            else
                            {
                                supportConceptCountDict.Add(acc.SupportConceptOid.Value, 1);
                            }
                        }
                    }

                    IList<long> supportConceptToUpdateOids = new List<long>();
                    foreach (var pair in supportConceptCountDict)
                    {
                        if (pair.Value == oids.Count)
                        {
                            //Wenn es für alle alten Leistungen eine ServiceAccounting gibt, füge die neue Leistung auch hinzu
                            supportConceptToUpdateOids.Add(pair.Key);
                        }
                    }

                    foreach (long scOid in supportConceptToUpdateOids)
                    {
                        var sc = DAOFactory.GenericDAO.LoadByID<SupportConcept>(scOid);
                        var newSa = new ServiceAccounting();
                        newSa.ServiceDescription = newSd;

                        sc.ServiceAccountings.Add(newSa);

                        scToSave.Add(sc);
                    }
                }

                if (scToSave.Count > 0)
                {
                    DAOFactory.GenericDAO.Insert(scToSave);
                }


                return lServiceDescriptions.Select(sd => sd.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewAdditionalServiceRegions(List<AdditionalServiceRegionDC> pAdditionalServiceRegions)
        {
            try
            {
                List<AdditionalServiceRegion> lAdditionalServiceRegions = MapperFactory.AdditionalServiceRegionDC_AdditionalServiceRegion.MapToNewEntities(pAdditionalServiceRegions);
                DAOFactory.GenericDAO.Insert(lAdditionalServiceRegions);
                return lAdditionalServiceRegions.Select(asr => asr.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public long InsertNewAdditionalServiceRegion(AdditionalServiceRegionDC pAdditionalServiceRegionDC)
        {
            try
            {
                AdditionalServiceRegion lAdditionalServiceRegion = MapperFactory.AdditionalServiceRegionDC_AdditionalServiceRegion.MapToNewEntity(pAdditionalServiceRegionDC);
                DAOFactory.GenericDAO.Insert(lAdditionalServiceRegion);
                return lAdditionalServiceRegion.Oid.Value;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public AdditionalServiceRegionDC GetAdditionalServiceRegion(long pRegionOid)
        {
            try
            {
                return MapperFactory.AdditionalServiceRegionDC_AdditionalServiceRegion.MapToNewDC(DAOFactory.GenericDAO.GetByID<AdditionalServiceRegion>(pRegionOid));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public ServiceRecordGroupDC InsertNewServiceRecordGroup(ServiceRecordGroupDC pServiceRecordGroup)
        {
            try
            {
                ServiceRecordGroup group = MapperFactory.ServiceRecordGroupDC_ServiceRecordGroup.MapToNewEntity(pServiceRecordGroup);

                var lServiceRecords = new List<ServiceRecord>();

                if (pServiceRecordGroup.ServiceRecordList != null && pServiceRecordGroup.ServiceRecordList.Count > 0)
                {
                    lServiceRecords = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewEntities(pServiceRecordGroup.ServiceRecordList);

                    foreach (ServiceRecord iServiceRecord in lServiceRecords)
                    {
                        iServiceRecord.IP = Utils.GetClientIP();

                        // iServiceRecord.Group = group;
                    }

                    group.ServiceRecordList = lServiceRecords;
                }

                DAOFactory.GenericDAO.Insert(group);

                if (lServiceRecords.Count > 0)
                    MakeServiceRecordHistoryEntry(lServiceRecords, lServiceRecords.Select(sr => sr.Oid.Value).ToList(), StatementType.Insert);

                ServiceRecordGroupDC newGroupDC = MapperFactory.ServiceRecordGroupDC_ServiceRecordGroup.MapToNewDC(group);

                newGroupDC.ServiceRecordList = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs(group.ServiceRecordList);

                return newGroupDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteAdditionalServiceGroupOfPeopleRelation(long pOid, long pVersion)
        {
            try
            {
                DeleteAdditionalServiceGroupOfPeopleRelations(new Dictionary<long, long> {{pOid, pVersion}});
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteAdditionalServiceBookings(Dictionary<long, long> pOid2Version)
        {
            try
            {
                List<AdditionalServiceBooking> lOriginals =
                    DAOFactory.GenericDAO.LoadByIDs<AdditionalServiceBooking>(pOid2Version.Select(e => e.Key));
                lOriginals.DoForEach(or => MapperFactory.AdditionalServiceBookingDC_AdditionalServiceBooking.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

                List<AdditionalServiceBooking> asbListToDelete = lOriginals.ToList();
                if (asbListToDelete.Count <= 0)
                    return;

                DAOFactory.GenericDAO.Delete(asbListToDelete);

                IList<AssessmentSheetEntry> allEntries = DAOFactory.GenericDAO.GetAll<AssessmentSheetEntry>();
                var entries2Delete = new List<AssessmentSheetEntry>();

                foreach (AdditionalServiceBooking item in lOriginals)
                {
                    entries2Delete.AddRange(allEntries.Where(e => pOid2Version.ContainsKey(e.Customer.Oid.Value) &&
                                                                  e.Day.Equals(item.Datum.Value) &&
                                                                  e.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet)).ToList());
                }

                DAOFactory.GenericDAO.Delete(entries2Delete);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateAdditionalServiceGroupOfPeopleRelations(List<AdditionalServiceGroupOfPeopleRelationDC> pAdditionalServiceGroupOfPeopleRelations)
        {
            try
            {
                List<AdditionalService2GroupOfPeople> lOriginals = DAOFactory.GenericDAO.LoadByIDs<AdditionalService2GroupOfPeople>(pAdditionalServiceGroupOfPeopleRelations.Select(dc => dc.AdditionalService2GroupOfPeopleOid.Value));
                MapperFactory.AdditionalServiceGroupOfPeopleRelationDC_AdditionalService2GroupOfPeople.MergeWithEntitys(pAdditionalServiceGroupOfPeopleRelations, lOriginals);
                DAOFactory.GenericDAO.Update(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateAdditionalServiceBookings(List<AdditionalServiceBookingDC> pAdditionalServiceBookings)
        {
            try
            {
                List<AdditionalServiceBooking> lOriginals = DAOFactory.GenericDAO.LoadByIDs<AdditionalServiceBooking>(pAdditionalServiceBookings.Select(dc => dc.AdditionalServiceBookingOid.Value));
                MapperFactory.AdditionalServiceBookingDC_AdditionalServiceBooking.MergeWithEntitys(pAdditionalServiceBookings, lOriginals);
                DAOFactory.GenericDAO.Update(lOriginals);

                var entries2Update = new List<AssessmentSheetEntry>();
                var entries2Delete = new List<AssessmentSheetEntry>();
                var newEntries = new List<AssessmentSheetEntry>();

                IList<AssessmentSheetValue> avList = DAOFactory.GenericDAO.GetAll<AssessmentSheetValue>();

                AssessmentSheetValue yes = avList.First(v => !String.IsNullOrEmpty(v.Description) && v.Description.Equals("Ja") &&
                                                             v.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet));

                //var no = avList.First(v => !String.IsNullOrEmpty(v.Description) && v.Description.Equals("Nein") &&
                //                                                                    v.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet));

                foreach (AdditionalServiceBooking item in lOriginals)
                {
                    IEnumerable<AssessmentSheetEntry> list = DAOFactory.SearchDAO.GetAdditionalAssessmentSheetEntries(item.Datum.Value);

                    IEnumerable<AssessmentSheetEntry> list2 = list.Where(e => !String.IsNullOrEmpty(e.AssessmentSheetCategory.Description) &&
                                                                              e.AssessmentSheetCategory.Description.Equals(item.AdditionalServiceRegion.AdditionalService.Name) &&
                                                                              item.Customer2AddServiceBookings.Exists(c2a => c2a.CustomerOid == e.Customer.Oid));

                    entries2Update.AddRange(list2);

                    foreach (Customer2AddServiceBooking c2a in item.Customer2AddServiceBookings)
                    {
                        bool containsEntry = false;

                        foreach (AssessmentSheetEntry entry in entries2Update)
                        {
                            if (entry.Customer.Oid == null) continue;
                            if (entry.Customer.Oid.Value.Equals(c2a.CustomerOid))
                            {
                                containsEntry = true;
                                if (c2a.Participated)
                                    entry.AssessmentSheetValue = yes;
                                else
                                    entries2Delete.Add(entry);
                            }
                        }
                        if (c2a.Participated && !containsEntry)
                        {
                            AssessmentSheetCategory cat =
                                DAOFactory.SearchDAO.GetAddServiceAssessmentSheetCategoryWithName(
                                    item.AdditionalServiceRegion.AdditionalService.Name);
                            if (cat != null)
                            {
                                newEntries.Add(new AssessmentSheetEntry
                                {
                                    Customer = DAOFactory.GenericDAO.GetByID<Customer>(c2a.CustomerOid),
                                    AssessmentSheetCategory = cat,
                                    AssessmentSheetValue = yes,
                                    SystemEntryID = SystemEntryID.AdditionalServiceAssessmentSheet,
                                    Day = item.Datum.Value
                                });
                            }
                        }
                    }
                }

                entries2Update.RemoveRange(entries2Delete);

                DAOFactory.GenericDAO.Update(entries2Update);
                DAOFactory.GenericDAO.Delete(entries2Delete);
                DAOFactory.GenericDAO.Insert(newEntries);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public bool AssessmentSheetEntryBelongsToAddServices(long assessmentSheetCategoryOid)
        {
            var lOriginal = DAOFactory.GenericDAO.GetByID<AssessmentSheetCategory>(assessmentSheetCategoryOid);
            IList<AdditionalService> services = DAOFactory.GenericDAO.GetAll<AdditionalService>();

            bool result = lOriginal.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet) && services.Count(e => e.Name.Equals(lOriginal.Description)) > 0;

            return result;
        }

        public AdditionalServiceGroupOfPeopleDC UpdateAdditionalServiceGroupOfPeople(AdditionalServiceGroupOfPeopleDC pAdditionalServiceGroupOfPeople)
        {
            try
            {
                var lOriginal =
                    DAOFactory.GenericDAO.LoadByID<AdditionalServiceGroupOfPeople>(
                        pAdditionalServiceGroupOfPeople.AdditionalServiceGroupOfPeopleOid.Value);

                MapperFactory.AdditionalServiceGroupOfPeopleCD_AdditionalServiceGroupOfPeople.MergeWithEntity(
                    pAdditionalServiceGroupOfPeople, lOriginal);

                MapperFactory.CompactCustomerDC_Customer.MergeWithEntitys(
                    pAdditionalServiceGroupOfPeople.CustomerList, lOriginal.CustomerList);

                DAOFactory.GenericDAO.Update(lOriginal);

                AdditionalServiceGroupOfPeopleDC newGroupDC =
                    MapperFactory.AdditionalServiceGroupOfPeopleCD_AdditionalServiceGroupOfPeople.MapToNewDC(
                        lOriginal);

                newGroupDC.CustomerList =
                    MapperFactory.CompactCustomerDC_Customer.MapToNewDCs(lOriginal.CustomerList);

                return newGroupDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewAdditionalServiceGroupOfPeopleRelations(List<AdditionalServiceGroupOfPeopleRelationDC> pAdditionalServiceGroupOfPeopleRelations)
        {
            try
            {
                List<AdditionalService2GroupOfPeople> lAdditionalServiceGroupOfPeopleRelations =
                    MapperFactory.AdditionalServiceGroupOfPeopleRelationDC_AdditionalService2GroupOfPeople.
                        MapToNewEntities(pAdditionalServiceGroupOfPeopleRelations);

                DAOFactory.GenericDAO.Insert(lAdditionalServiceGroupOfPeopleRelations);

                return lAdditionalServiceGroupOfPeopleRelations.Select(asgopr => asgopr.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewAdditionalServiceGroupsOfPeople(List<AdditionalServiceGroupOfPeopleDC> pGroups)
        {
            try
            {
                List<AdditionalServiceGroupOfPeople> lGroups =
                    MapperFactory.AdditionalServiceGroupOfPeopleCD_AdditionalServiceGroupOfPeople.MapToNewEntities(
                        pGroups);

                DAOFactory.GenericDAO.Insert(lGroups);

                return lGroups.Select(asgop => asgop.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewServiceRecords(List<ServiceRecordDC> pServiceRecords)
        {
            return InternalInsertNewServiceRecords(MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewEntities(pServiceRecords));
        }

        public static List<long> InternalInsertNewServiceRecords(IEnumerable<ServiceRecord> lServiceRecords)
        {
            try
            {
                ServiceRecordGroup group = null;

                foreach (var iServiceRecord in lServiceRecords)
                {
                    if (string.IsNullOrEmpty(iServiceRecord.IP))
                    {
                        iServiceRecord.IP = OperationContext.Current != null ? Utils.GetClientIP() : "::1";
                    }

                    if (iServiceRecord.InsTs == null)
                    {
                        iServiceRecord.InsTs = DateTime.Now;
                    }

                    if (iServiceRecord.GroupEmployeeCount != null && iServiceRecord.GroupPersonCount != null &&
                        (iServiceRecord.GroupEmployeeCount.Value + iServiceRecord.GroupPersonCount.Value > 2))
                    {
                        if (group == null)
                        {
                            group = new ServiceRecordGroup
                            {
                                CustomerCount = iServiceRecord.GroupPersonCount.Value,
                                EmployeeCount = iServiceRecord.GroupEmployeeCount.Value,
                                RoundedDuration = iServiceRecord.GroupRoundedDuration.Value,
                                StartDate = iServiceRecord.Start,
                                EndDate = iServiceRecord.End
                            };
                        }

                        iServiceRecord.Group = group;
                    }
                    else
                    {
                        var bsi = PluginLoader.FindClass<SaveInterceptor>();
                        if (bsi != null)
                        {
                            bsi.BeforeSaveServiceRecord(iServiceRecord);
                        }
                    }
                }

                DAOFactory.GenericDAO.Insert(lServiceRecords);

                MakeServiceRecordHistoryEntry(lServiceRecords, lServiceRecords.Select(sr => sr.Oid.Value).ToList(), StatementType.Insert);

                return lServiceRecords.Select(sr => sr.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<long> InsertNewAdditionalServiceBookings(List<AdditionalServiceBookingDC> pAdditionalServiceBookings)
        {
            try
            {
                List<AdditionalServiceBooking> lAdditionalServiceBookings = MapperFactory.AdditionalServiceBookingDC_AdditionalServiceBooking.MapToNewEntities(pAdditionalServiceBookings);
                DAOFactory.GenericDAO.Insert(lAdditionalServiceBookings);

                foreach (AdditionalServiceBooking booking in lAdditionalServiceBookings)
                {
                    AttachAddServiceToAssessment(booking);
                }

                return lAdditionalServiceBookings.Select(asb => asb.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public bool IsAlive()
        {
            return true;
        }

        public string PrepareFLSReport(FLSAnalysisDataReportDC pReportDC, string id)
        {
            try
            {
                string lResult = id + ".xml";

                string lDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, MultitenancyOperationContextExt.Current.Tenant + @"\temp");
                string lPath = Path.Combine(lDir, lResult);

                BS.Shared.Core.Utils.XMLSerialize(lPath, pReportDC);

                return lResult;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string PrepareSettlementReport(Settlement2DC pSettlementDC)
        {
            try
            {
                string lResult = Guid.NewGuid() + ".xml";

                string lDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, MultitenancyOperationContextExt.Current.Tenant + @"\temp");
                string lPath = Path.Combine(lDir, lResult);

                BS.Shared.Core.Utils.XMLSerialize(lPath, pSettlementDC);

                return lResult;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateAccountingTransactions(List<AccountingTransactionDC> pAccountingTransactions)
        {
            try
            {
                List<AccountingTransaction> lOriginals = DAOFactory.GenericDAO.LoadByIDs<AccountingTransaction>(pAccountingTransactions.Select(dc => dc.AccountingTransactionOid.Value));
                MapperFactory.AccountingTransactionDC_AccountingTransaction.MergeWithEntitys(pAccountingTransactions, lOriginals);
                DAOFactory.GenericDAO.Update(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateInvoices(List<InvoiceDC> invoices)
        {
            try
            {
                List<Invoice> lOriginals = DAOFactory.GenericDAO.LoadByIDs<Invoice>(invoices.Select(dc => dc.InvoiceOid.Value));
                MapperFactory.InvoiceDC_Invoice.MergeWithEntitys(invoices, lOriginals);
                DAOFactory.GenericDAO.Update(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public MandatorDC UpdateMandator(MandatorDC mandator)
        {
            try
            {
                Mandator lOriginal = GetMandatorEntity();
                MapperFactory.MandatorDC_Mandator.MergeWithEntity(mandator, lOriginal);
                DAOFactory.GenericDAO.Update(lOriginal);
                return MapperFactory.MandatorDC_Mandator.MapToNewDC(lOriginal);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateServiceCategories(List<ServiceCategoryDC> pServiceCategories)
        {
            try
            {
                List<ServiceCategory> lOriginals = DAOFactory.GenericDAO.LoadByIDs<ServiceCategory>(pServiceCategories.Select(sc => sc.ServiceCategoryOid.Value));

                MapperFactory.ServiceCategoryDC_ServiceCategory.MergeWithEntitys(pServiceCategories, lOriginals);

                DAOFactory.GenericDAO.Update(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateAdditionalServices(List<AdditionalServiceDC> pAdditionalServices)
        {
            try
            {
                List<AdditionalService> lOriginals = DAOFactory.GenericDAO.LoadByIDs<AdditionalService>(pAdditionalServices.Select(sc => sc.AdditionalServiceOid.Value));

                MapperFactory.AdditionalServiceDC_AdditionalService.MergeWithEntitys(pAdditionalServices, lOriginals);

                DAOFactory.GenericDAO.Update(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateServiceDescriptions(List<ServiceDescriptionDC> pServiceDescriptions)
        {
            try
            {
                List<ServiceDescription> lOriginals = DAOFactory.GenericDAO.LoadByIDs<ServiceDescription>(pServiceDescriptions.Select(sc => sc.ServiceDescriptionOid.Value));

                MapperFactory.ServiceDescriptionDC_ServiceDescription.MergeWithEntitys(pServiceDescriptions, lOriginals);

                DAOFactory.GenericDAO.Update(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateAdditionalServiceRegions(List<AdditionalServiceRegionDC> pAdditionalServiceRegions)
        {
            try
            {
                List<AdditionalServiceRegion> lOriginals = DAOFactory.GenericDAO.LoadByIDs<AdditionalServiceRegion>(pAdditionalServiceRegions.Select(sc => sc.AdditionalServiceRegionOid.Value));

                MapperFactory.AdditionalServiceRegionDC_AdditionalServiceRegion.MergeWithEntitys(pAdditionalServiceRegions, lOriginals);

                DAOFactory.GenericDAO.Update(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public ServiceRecordGroupDC UpdateServiceRecordGroup(ServiceRecordGroupDC pServiceRecordGroup)
        {
            try
            {
                var lOriginal = DAOFactory.GenericDAO.LoadByID<ServiceRecordGroup>(pServiceRecordGroup.ServiceRecordGroupOid.Value);

                MapperFactory.ServiceRecordGroupDC_ServiceRecordGroup.MergeWithEntity(pServiceRecordGroup, lOriginal);

                var lServiceRecords = new List<ServiceRecord>();

                // update servicerecords
                MapperFactory.ServiceRecordDC_ServiceRecord.MergeWithEntitys(pServiceRecordGroup.ServiceRecordList, lOriginal.ServiceRecordList);
                foreach (ServiceRecord iServiceRecord in lOriginal.ServiceRecordList)
                {
                    if (String.IsNullOrEmpty(iServiceRecord.IP))
                        iServiceRecord.IP = Utils.GetClientIP();

                    iServiceRecord.GroupOid = lOriginal.Oid;
                    lServiceRecords.Add(iServiceRecord);
                }

                DAOFactory.GenericDAO.Update(lOriginal);
                MakeServiceRecordHistoryEntry(lServiceRecords, null, StatementType.Update);


                ServiceRecordGroupDC newGroupDC = MapperFactory.ServiceRecordGroupDC_ServiceRecordGroup.MapToNewDC(lOriginal);

                newGroupDC.ServiceRecordList = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs(lOriginal.ServiceRecordList);

                return newGroupDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateServiceRecords(List<ServiceRecordDC> pServiceRecords)
        {
            try
            {
                List<ServiceRecord> lOriginals =
                    DAOFactory.GenericDAO.LoadByIDs<ServiceRecord>(
                        pServiceRecords.Select(sr => sr.ServiceRecordOid.Value));

                MapperFactory.ServiceRecordDC_ServiceRecord.MergeWithEntitys(pServiceRecords, lOriginals);

	            var si = PluginLoader.FindClass<SaveInterceptor>();
	            if (si != null)
	            {
		            foreach (var serviceRecord in lOriginals)
		            {
						si.BeforeSaveServiceRecord(serviceRecord);
		            }
	            }
	            DAOFactory.GenericDAO.Update(lOriginals);


                lOriginals =
                    DAOFactory.GenericDAO.LoadByIDs<ServiceRecord>(
                        pServiceRecords.Select(sr => sr.ServiceRecordOid.Value));

                MakeServiceRecordHistoryEntry(lOriginals, null, StatementType.Update);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public bool DoesNotOverlapWithOtherServiceRecord(ServiceRecordDC pServiceRecord, long customerOid, long? employeeOid)
        {
			//obsolete
	        return false;
			//if (pServiceRecord.ServiceDescription.DoNotCheckOverlapping)
			//{
			//	return false;
			//}
			//var span = new DateTimeSpan
			//{StartDate = pServiceRecord.Start.Value, EndDate = pServiceRecord.End.Value.AddDays(1).AddTicks(-1)};

			//List<ServiceRecord> records = DAOFactory.SearchDAO.FindCustomerServiceRecords(customerOid, span, employeeOid, null).ToList();

			//return records.Count <= 0 || records.Where(record => record.CostBearer2SupportConcept.CostBearer.Oid == pServiceRecord.CostBearer.OrganisationOid).Select(record => TimeSpanOverlapsWithOtherTimeSpan(pServiceRecord.Start, record.Start, pServiceRecord.RoundedDuration, record.RoundedDuration)).All(timeCheck => !timeCheck);
        }

        public bool OverlapsWithAnotherAdditionalServiceBooking(long additionalServiceRegionOid, List<long> customerOids, DateTime pDatum)
        {
            List<AdditionalServiceBooking> bookings = DAOFactory.GenericDAO.GetAll<AdditionalServiceBooking>().Where(b => b.Datum.Equals(pDatum) && b.AdditionalServiceRegion.Oid.Value.Equals(additionalServiceRegionOid)).ToList();

            return bookings.Any(booking => booking.Customer2AddServiceBookings.Any(customer => customerOids.Contains(customer.CustomerOid)));
        }

        public List<AdditionalServiceGroupOfPeopleRelationDC> GetAllAdditionalServiceGroupOfPeopleRelation()
        {
            try
            {
                IList<AdditionalService2GroupOfPeople> as2gop = DAOFactory.GenericDAO.GetAll<AdditionalService2GroupOfPeople>();
                return as2gop.Select(item => MapperFactory.AdditionalServiceGroupOfPeopleRelationDC_AdditionalService2GroupOfPeople.MergeWithDC(item, new AdditionalServiceGroupOfPeopleRelationDC())).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<AdditionalServiceGroupOfPeopleDC> GetAllAdditionalServiceGroupOfPeople()
        {
            try
            {
                List<AdditionalServiceGroupOfPeopleDC> result =
                    MapperFactory.AdditionalServiceGroupOfPeopleCD_AdditionalServiceGroupOfPeople.MapToNewDCs(
                        DAOFactory.GenericDAO.GetAll<AdditionalServiceGroupOfPeople>()).ToList();

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<AdditionalServiceBookingDC> GetAllAdditionalServiceBookings(long? regionOid, DateTime start, DateTime end)
        {
            try
            {
                List<AdditionalServiceBookingDC> result =
                    MapperFactory.AdditionalServiceBookingDC_AdditionalServiceBooking.MapToNewDCs(
                        DAOFactory.SearchDAO.GetAdditionalServiceBookings(regionOid, start, end)).ToList();

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public Dictionary<ServiceRecordDC, List<ServiceRecordValidationResult>> ValidateGroupServiceRecordEntry(ServiceRecordDC pServiceRecord, List<ServiceRecordDC> groupServiceRecords, List<CompactEmployeeDC> employees, DateTime? date, int maxDaysEditServiceRecordsAllowed, decimal flsTotalRounded, out Dictionary<long, string> overlappingRecords, out Dictionary<long, string> overlappingEmployees)
        {
			var validator = PluginLoader.FindClass<ServiceRecordValidator>();
	        return validator.ValidateGroupServiceRecordEntry(pServiceRecord, groupServiceRecords, employees, date,
		        maxDaysEditServiceRecordsAllowed, flsTotalRounded, out overlappingRecords, out overlappingEmployees);

        }

        public List<ServiceRecordValidationResultDC> ValidateServiceRecordEntry(ServiceRecordDC newServiceRecord,
            SupportConceptStatisticsDC statistics, int maxDaysEditServiceRecordsAllowed, bool isGroupRecord,
            IList<long> employeeOids)
        {
            return ValidateServiceRecord(newServiceRecord, statistics, maxDaysEditServiceRecordsAllowed, employeeOids,
                null);
        }

        public List<ServiceRecordValidationResultDC> ValidateServiceRecord(ServiceRecordDC newServiceRecord,
            SupportConceptStatisticsDC statistics, int maxDaysEditServiceRecordsAllowed,
            IList<long> employeeOids, IList<long> cb2scOids)
        {
			var validator = PluginLoader.FindClass<ServiceRecordValidator>();
	        return validator.ValidateServiceRecord(newServiceRecord, statistics, maxDaysEditServiceRecordsAllowed, employeeOids, cb2scOids);
			
        }

        public List<ServiceRecordValidationResult> CheckExistingSettlementInvoices(ServiceRecordDC pServiceRecord)
        {
            var result = new List<ServiceRecordValidationResult>();
            // 6. SettlementInvoiceAlreadyExisting
            try
            {
                IList<SettlementInvoice> allSettlementInvoices = DAOFactory.GenericDAO.GetAll<SettlementInvoice>();

                foreach (SettlementInvoice rechnung in allSettlementInvoices)
                {
                    if (rechnung.InvoiceBase.CostBearer2SupportConcept.Oid.HasValue)
                        if (rechnung.InvoiceBase.CostBearer2SupportConcept.Oid.Value.Equals(pServiceRecord.CostBearer2SupportConceptOid.Value) && rechnung.IsActive.Equals(ActivationTypeId.Active))
                        {
                            result.Add(ServiceRecordValidationResult.SettlementInvoiceAlreadyExisting);
                            break;
                        }
                }
            }
            catch (Exception)
            {
                result.Add(ServiceRecordValidationResult.Error);
            }

            return result;
        }

        public List<AdditionalServiceBookingDC> GetAllAdditionalServiceBookingsForCustomer(long customerOid, DateTime start, DateTime end)
        {
            try
            {
                ;
                List<AdditionalServiceBookingDC> result =
                    MapperFactory.AdditionalServiceBookingDC_AdditionalServiceBooking.MapToNewDCs(
                        DAOFactory.SearchDAO.GetAdditionalServiceBookingsForCustomer(customerOid, start, end));
                //var result =
                //	MapperFactory.AdditionalServiceBookingDC_AdditionalServiceBooking.MapToNewDCs(
                //		DAOFactory.GenericDAO.GetAll<AdditionalServiceBooking>()).ToList().Where(b => b.CustomerOidDict.Any(c => c.Key.Equals(customerOid))).ToList();

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public ServiceRecordDC GetServiceRecordById(long pId)
        {
            try
            {
                var sr = DAOFactory.GenericDAO.GetByID<ServiceRecord>(pId);

                if (sr == null)
                    return null;

                ServiceRecordDC result = MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDC(sr);
                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<FileAttachmentDC> GetFileAttachmentInfoByType(FileAttachmentType fileAttachmentType)
        {
            try
            {
                return MapperFactory.FileAttachmentDC_FileAttachmentInfo.MapToNewDCs(DAOFactory.SearchDAO.FindFileAttachmentInfoByType(fileAttachmentType));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<ServiceRecordDC> GetActiveServiceRecordsBySupportConcept(long pSupportConceptOid)
        {
            try
            {
                return MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs(DAOFactory.SearchDAO.FindServiceRecordsForSupportConcept(pSupportConceptOid));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void InsertBeWoMobilBrowserInfo(BeWoMobilBrowserInfoDC browserInfo)
        {
            try
            {
                BeWoMobilBrowserInfo info = MapperFactory.BeWoMobilBrowserInfoDC_BeWoMobilBrowserInfo.MapToNewEntity(browserInfo);
                DAOFactory.GenericDAO.Insert(info);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public IList<ServiceRecordDC> FindServiceRecordsForLastDays(long? costbearer2SupportConceptOid, int days, long? employeeOid)
        {
            try
            {
                return MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs(DAOFactory.SearchDAO.FindServiceRecordsForDays(costbearer2SupportConceptOid, days, employeeOid));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public IEnumerable<CompactSupportConceptDC> GetCompactSupportConcepts(long supportConceptOid, long? employeeOid)
        {
            try
            {
                var list = new List<SupportConcept>();
                list.Add(DAOFactory.GenericDAO.GetByID<SupportConcept>(supportConceptOid));


                List<CompactSupportConceptDC> result = CreateFlatSupportConceptCostBearerDCList(list, true, employeeOid);

                return result;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        private ServiceRecordDC CreateServiceRecordDCCompact(ServiceRecord sr)
        {
            var dc = new ServiceRecordDC();

            dc.ServiceRecordOid = sr.Oid;
            dc.ServiceRecordVersion = sr.Version;
            dc.Start = sr.Start;
            dc.End = sr.End;
            dc.Notice = sr.Notice;
            dc.Notice2 = sr.Notice2;
            dc.Notice3 = sr.Notice3;
            dc.Notice4 = sr.Notice4;
            dc.Notice5 = sr.Notice5;
            if (sr.ServiceDescription != null)
                dc.ServiceDescription = MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewDC(sr.ServiceDescription);
            dc.RoundedDuration = sr.RoundedDuration;
	        dc.DistanceInMeter = sr.DistanceInMeter;
            dc.InsertedOn = sr.InsTs;
            dc.InsUser = sr.InsUser;
            dc.GroupEmployeeCount = sr.GroupEmployeeCount;
            dc.GroupPersonCount = sr.GroupPersonCount;
            dc.GroupRoundedDuration = sr.GroupRoundedDuration;
            dc.ServiceRecordType = sr.ServiceRecordType ?? ServiceRecordTypeId.DefaultActivity;
            dc.GroupOid = sr.GroupOid;

            if (sr.Employee != null)
            {
                //dc.Employee = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(sr.Employee);
                dc.Employee = new CompactEmployeeDC();
                dc.Employee.EmployeeOid = sr.Employee.Oid.Value;
                dc.Employee.EmployeeVersion = sr.Employee.Version.Value;
                dc.Employee.FirstName = sr.Employee.Person.FirstName;
                dc.Employee.LastName = sr.Employee.Person.LastName;
                dc.Employee.PersonnelNumber = sr.Employee.PersonnelNumber;
                //pDataContract.FLSPerWeek = pEntity.WeeklyFLS;
                dc.Employee.ActivationType = sr.Employee.IsActive;
            }


            //Goals -------------------------
            var list = new List<ValueListEntryType>();
            list.Add(ValueListEntryType.SupportConceptGoalType);
			list.Add(ValueListEntryType.SupportConceptGoalCategoryType);
			list.Add(ValueListEntryType.SupportConceptIndividualGoalCategoryType);
            list.Add(ValueListEntryType.SupportConceptIndividualGoalType);
            dc.Goals = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDCs(
                sr.ValueList.FindByTypes(list).Select(e2o => e2o.Entry));


            return dc;
        }

        private ServiceRecordDC CreateServiceRecordDCIfSupportConceptIsActive(ServiceRecord sr, Customer cust, bool checkArchivedSupportConcepts)
        {
            ServiceRecordDC dc = null;
            if (!checkArchivedSupportConcepts || (sr.SupportConcept != null && sr.SupportConcept.IsActive == ActivationTypeId.Active))
            {
                dc = new ServiceRecordDC();

                dc.ServiceRecordOid = sr.Oid;
                dc.ServiceRecordVersion = sr.Version;
                dc.Start = sr.Start;
                dc.End = sr.End;
                dc.Notice = sr.Notice;
                dc.Notice2 = sr.Notice2;
                dc.Notice3 = sr.Notice3;
                dc.Notice4 = sr.Notice4;
                dc.Notice5 = sr.Notice5;
                if (sr.ServiceDescription != null)
                    dc.ServiceDescription = MapperFactory.ServiceDescriptionDC_ServiceDescription.MapToNewDC(sr.ServiceDescription);
                dc.RoundedDuration = sr.RoundedDuration;
                dc.InsertedOn = sr.InsTs;
                dc.InsUser = sr.InsUser;

                //Customer -----------------
                dc.Customer = new CompactCustomerDC();


                dc.Customer.CustomerOid = cust.Oid.Value;
                dc.Customer.CustomerVersion = cust.Version.Value;
                dc.Customer.FirstName = cust.Person.FirstName;
                dc.Customer.LastName = cust.Person.LastName;
                dc.Customer.Sex = cust.Person.Sex;
                //dc.Customer.DateOfBirth = cust.Person.DateOfBirth;
                //dc.Customer.ActivationType = cust.IsActive;
                //dc.Customer.TerminationDate = cust.TerminationDate;
                //dc.Customer.EquityContribution = cust.EquityContribution;

                //pDataContract.AbsenceTimes = MapperFactory.AbsenceTimeDC_AbsenceTime.MapToNewDCs(pEntity.AbsenceTimes);


                //Employee -----------------


                if (sr.Employee != null)
                {
                    //dc.Employee = MapperFactory.CompactEmployeeDC_Employee.MapToNewDC(sr.Employee);
                    dc.Employee = new CompactEmployeeDC();
                    dc.Employee.EmployeeOid = sr.Employee.Oid.Value;
                    dc.Employee.EmployeeVersion = sr.Employee.Version.Value;
                    dc.Employee.FirstName = sr.Employee.Person.FirstName;
                    dc.Employee.LastName = sr.Employee.Person.LastName;
                    dc.Employee.PersonnelNumber = sr.Employee.PersonnelNumber;
                    //pDataContract.FLSPerWeek = pEntity.WeeklyFLS;
                    dc.Employee.ActivationType = sr.Employee.IsActive;
                }


                //SupportConcept -----------------
                if (sr.SupportConcept != null)
                {
                    dc.SupportConcept = new CompactSupportConceptDC();

                    dc.SupportConcept.SupportConceptOid = sr.SupportConcept.Oid.Value;
                    dc.SupportConcept.SupportConceptVersion = sr.SupportConcept.Version.Value;
                    dc.SupportConcept.Customer = dc.Customer;
                    //pDataContract.Customer = MapperFactory.CompactCustomerDC_Customer.MapToNewDC(pEntity.Customer);
                    dc.SupportConcept.ActivationType = sr.SupportConcept.IsActive;
                    dc.SupportConcept.ConferenceDate = sr.SupportConcept.ConferenceDate;

                    //foreach (var iCBRel in pEntity.CostBearer2SupportConceptList)
                    //{
                    //    CompactCostBearerDC costBearer = new CompactCostBearerDC();

                    //    if (iCBRel.CostBearer.Organisation != null)
                    //    {
                    //        CompactOrganisationDC orgDC = new CompactOrganisationDC();
                    //        orgDC.Name = iCBRel.CostBearer.Organisation.Name;
                    //        orgDC.OrganisationOid = iCBRel.CostBearer.Organisation.Oid.Value;

                    //        if (iCBRel.CostBearer.Organisation.Address != null)
                    //        {
                    //            orgDC.Street = iCBRel.CostBearer.Organisation.Address.Street;
                    //            orgDC.PostalCode = iCBRel.CostBearer.Organisation.Address.PostalCode;
                    //            orgDC.Town = iCBRel.CostBearer.Organisation.Address.Town;
                    //        }
                    //        costBearer.Organisation = orgDC;
                    //    }
                    //    costBearer.CostBearerOid = iCBRel.CostBearer.Oid.Value;
                    //    costBearer.CostBearer2SupportConceptOid = iCBRel.Oid.Value;
                    //    costBearer.SupportConceptStatus = iCBRel.Status;
                    //    costBearer.RequestedStartDate = iCBRel.RequestedStartDate;
                    //    costBearer.RequestedEndDate = iCBRel.RequestedEndDate;
                    //    costBearer.ApprovedStartDate = iCBRel.ApprovedStartDate;
                    //    costBearer.ApprovedEndDate = iCBRel.ApprovedEndDate;
                    //    costBearer.ApprovedFLS = iCBRel.ApprovedFLS;
                    //    costBearer.ApprovedFLSTotal = iCBRel.ApprovedFLSTotal;
                    //    costBearer.CustomerReferenceNumber = iCBRel.CustomerReferenceNumber;
                    //    costBearer.IsCalculatingWithFactor = iCBRel.CostBearer.IsCalculatingWithFactor;

                    //    pDataContract.CostBearerList.Add(costBearer);
                    //    pDataContract.CustomerReferenceNumbers.Add(iCBRel.CustomerReferenceNumber);
                    //    pDataContract.CostBearerRelOids.Add(iCBRel.Oid.Value);
                    //}

                    //dc.SupportConcept = MapperFactory.CompactSupportConceptDC_SupportConcept.MapToNewDC(sr.SupportConcept);
                }

                //Costbearer -----------------
                if (sr.CostBearer2SupportConcept != null)
                {
                    dc.CostBearer2SupportConceptOid = sr.CostBearer2SupportConcept.Oid.Value;

                    if (dc.SupportConcept != null)
                    {
                        var costBearer = new CompactCostBearerDC();

                        if (sr.CostBearer2SupportConcept.CostBearer.Organisation != null)
                        {
                            var orgDC = new CompactOrganisationDC();
                            orgDC.Name = sr.CostBearer2SupportConcept.CostBearer.Organisation.Name;
                            orgDC.OrganisationOid = sr.CostBearer2SupportConcept.CostBearer.Organisation.Oid.Value;
                            orgDC.CostBearerOid = sr.CostBearer2SupportConcept.CostBearer.Oid;
                            dc.CostBearer = orgDC;
                            costBearer.Organisation = orgDC;
                        }
                        costBearer.CostBearerID = sr.CostBearer2SupportConcept.CostBearer.ID;
                        costBearer.CostBearerOid = sr.CostBearer2SupportConcept.CostBearer.Oid.Value;
                        costBearer.CostBearer2SupportConceptOid = sr.CostBearer2SupportConcept.Oid.Value;
                        costBearer.SupportConceptStatus = sr.CostBearer2SupportConcept.Status;
                        costBearer.RequestedStartDate = sr.CostBearer2SupportConcept.RequestedStartDate;
                        costBearer.RequestedEndDate = sr.CostBearer2SupportConcept.RequestedEndDate;
                        costBearer.ApprovedStartDate = sr.CostBearer2SupportConcept.ApprovedStartDate;
                        costBearer.ApprovedEndDate = sr.CostBearer2SupportConcept.ApprovedEndDate;
                        costBearer.CustomerReferenceNumber = sr.CostBearer2SupportConcept.CustomerReferenceNumber;
                        costBearer.IsCalculatingWithFactor = sr.CostBearer2SupportConcept.CostBearer.IsCalculatingWithFactor;

                        dc.SupportConcept.CostBearerList.Add(costBearer);
                        dc.SupportConcept.CustomerReferenceNumbers.Add(sr.CostBearer2SupportConcept.CustomerReferenceNumber);
                        dc.SupportConcept.CostBearerRelOids.Add(sr.CostBearer2SupportConcept.Oid.Value);
                    }

                    if (dc.CostBearer == null)
                    {
                        if (sr.CostBearer2SupportConcept.CostBearer.Organisation != null)
                            dc.CostBearer = MapperFactory.CompactOrganisationDC_Organisation.MapToNewDC(sr.CostBearer2SupportConcept.CostBearer.Organisation);
                    }
                }

                //Goals -------------------------
                var list = new List<ValueListEntryType>();
				list.Add(ValueListEntryType.SupportConceptGoalType);
				list.Add(ValueListEntryType.SupportConceptGoalCategoryType);
				list.Add(ValueListEntryType.SupportConceptIndividualGoalCategoryType);
				list.Add(ValueListEntryType.SupportConceptIndividualGoalType);
                dc.Goals = MapperFactory.ValueListEntryDC_ValueListEntry.MapToNewDCs(
                    sr.ValueList.FindByTypes(list).Select(e2o => e2o.Entry));

                dc.GroupEmployeeCount = sr.GroupEmployeeCount;
                dc.GroupPersonCount = sr.GroupPersonCount;
                dc.GroupRoundedDuration = sr.GroupRoundedDuration;
                dc.GroupOid = sr.GroupOid;
                dc.ServiceRecordType = sr.ServiceRecordType ?? ServiceRecordTypeId.DefaultActivity;
            }
            return dc;
        }

        private List<BeWoFolderDC> CreateFolderTree(List<BeWoFolderDC> folderDCList, List<FileAttachmentDC> fileDCList, TableID pObjectTid, long pObjectOid, bool templateFolder = false)
        {
            Dictionary<long, BeWoFolderDC> folderDict = folderDCList.ToDictionary(fo => fo.BeWoFolderOid.Value);
            Dictionary<long, FileAttachmentDC> fileDict = fileDCList.ToDictionary(fi => fi.FileAttachmentOid.Value);

            var resultList = new List<BeWoFolderDC>();

            var root = new BeWoFolderDC
            {
                ObjectTid = pObjectTid,
                ObjectOid = pObjectOid,
                Name = "Alle Ordner",
                SubFolders = new List<BeWoFolderDC>(),
                Files = new List<FileAttachmentDC>()
            };

            if (templateFolder)
                root = folderDCList.First(f => f.Name.Equals("Vorlagen"));

            resultList.Add(root);

            foreach (BeWoFolderDC cfo in folderDCList)
            {
                if (root.Equals(cfo)) continue;

                if (cfo.ParentBeWoFolderOid.HasValue)
                {
                    if (folderDict.ContainsKey(cfo.ParentBeWoFolderOid.Value))
                    {
                        BeWoFolderDC parent = folderDict[cfo.ParentBeWoFolderOid.Value];
                        parent.SubFolders.Add(cfo);
                    }
                    else
                    {
                        root.SubFolders.Add(cfo);
                    }
                }
                else
                {
                    root.SubFolders.Add(cfo);
                }
            }

            foreach (FileAttachmentDC fi in fileDCList)
            {
                if (fi.BeWoFolderOid.HasValue)
                {
                    if (folderDict.ContainsKey(fi.BeWoFolderOid.Value))
                    {
                        BeWoFolderDC parent = folderDict[fi.BeWoFolderOid.Value];
                        parent.Files.Add(fi);
                    }
                    else
                    {
                        root.Files.Add(fi);
                    }
                }
                else
                {
                    root.Files.Add(fi);
                }
            }

            return resultList;
        }

        public static Dictionary<String, String> GetSettingsValueDict(string settings)
        {
            var dict = new Dictionary<String, String>();
            if (!String.IsNullOrEmpty(settings))
            {
                string[] keyValuePairs = settings.Split(';');

                foreach (string pair in keyValuePairs)
                {
                    string[] keyValuePair = pair.Split('=');
                    if (keyValuePair.Length == 2)
                    {
                        dict.Add(keyValuePair[0], keyValuePair[1]);
                    }
                }
            }

            return dict;
        }

        private static String GetContractState()
        {
//#if DEBUG

//			info.MaxLicenseCount = 9999;
//			info.PercentFreeEmployee = 100;

//			info.LicenseInUseCount = DAOFactory.GenericDAO.GetAllActive<ApplicationUser>().Count;
//			info.EmployeeCount = DAOFactory.GenericDAO.GetAllActive<Employee>().Count;

//			info.MaxEmployeeCount = (int)Math.Ceiling(1000000 * ((100 + 100m) / 100));
//			return info;
//#endif
            try
            {
                string url = ConfigurationManager.AppSettings.Get("ContractStateUrl");

                url = url.Replace("[TENANT]", MultitenancyOperationContextExt.Current.Tenant);

                using (var client = new WebClient())
                {
                    //MessageBox.Show(hostAddress);
                    byte[] response = client.DownloadData(url);

                    return Encoding.ASCII.GetString(response);
                }
            }
            catch (Exception)
            {
            }

            return String.Empty;
        }

        public static void DeleteAdditionalServiceGroupOfPeopleRelations(Dictionary<long, long> pOid2Version)
        {
            try
            {
                List<AdditionalService2GroupOfPeople> lOriginals = DAOFactory.GenericDAO.LoadByIDs<AdditionalService2GroupOfPeople>(pOid2Version.Select(e => e.Key));

                lOriginals.DoForEach(or => MapperFactory.AdditionalServiceGroupOfPeopleRelationDC_AdditionalService2GroupOfPeople.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

                List<AdditionalService2GroupOfPeople> srListToDelete = lOriginals.ToList();

                if (srListToDelete.Count > 0)
                    DAOFactory.GenericDAO.Delete(srListToDelete);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        private static void AttachAddServiceToAssessment(AdditionalServiceBooking pAdditionalServiceBookingDC)
        {
            try
            {
                var newCategoryDC = new AssessmentSheetCategoryDC {Description = pAdditionalServiceBookingDC.AdditionalServiceRegion.AdditionalService.Name};
                AssessmentSheetCategory lCategory = MapperFactory.AssessmentSheetCategoryDC_AssessmentSheetCategory.MapToNewEntity(newCategoryDC);
                lCategory.SystemEntryID = SystemEntryID.AdditionalServiceAssessmentSheet;

                AssessmentSheetCategory cat = DAOFactory.SearchDAO.GetAddServiceAssessmentSheetCategoryWithName(lCategory.Description);


                if (cat == null)
                {
                    DAOFactory.GenericDAO.Insert(lCategory);
                }
                else
                {
                    lCategory = cat;
                }

                IList<AssessmentSheetValue> values = DAOFactory.GenericDAO.GetAll<AssessmentSheetValue>();
                bool yesExists =
                    values.Count(
                        v =>
                            v.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet) &&
                            v.Description.Equals("Ja")) == 1;

                bool noExists =
                    values.Count(
                        v =>
                            v.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet) &&
                            v.Description.Equals("Nein")) == 1;

                var lYes = new AssessmentSheetValue
                {
                    Color = "#FF7FFF00",
                    Description = "Ja",
                    Position = 0,
                    Sign = "",
                    SystemEntryID = SystemEntryID.AdditionalServiceAssessmentSheet
                };

                var lNo = new AssessmentSheetValue
                {
                    Color = "#FFFF0000",
                    Description = "Nein",
                    Position = 0,
                    Sign = "x",
                    SystemEntryID = SystemEntryID.AdditionalServiceAssessmentSheet
                };

                if (!yesExists)
                {
                    DAOFactory.GenericDAO.Insert(lYes);
                }
                else
                {
                    lYes = values.First(
                        c =>
                            c.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet) &&
                            c.Description.Equals(lYes.Description));
                }

                if (!noExists)
                {
                    DAOFactory.GenericDAO.Insert(lNo);
                }
                else
                {
                    lNo = values.First(
                        c =>
                            c.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet) &&
                            c.Description.Equals(lNo.Description));
                }

                if (!lCategory.PossibleValues.Contains(lYes))
                    DAOFactory.AdoDAO.ExecuteQuery(string.Format("INSERT INTO assessmentsheetcategory2assessmentsheetvalue(assessmentsheetcategoryoid, assessmentsheetvalueoid) VALUES({0}, {1})", lCategory.Oid.Value, lYes.Oid.Value));

                if (!lCategory.PossibleValues.Contains(lNo))
                    DAOFactory.AdoDAO.ExecuteQuery(string.Format("INSERT INTO assessmentsheetcategory2assessmentsheetvalue(assessmentsheetcategoryoid, assessmentsheetvalueoid) VALUES({0}, {1})", lCategory.Oid.Value, lNo.Oid.Value));

                var entryList = new List<AssessmentSheetEntry>();
                string sqlString = string.Empty;

                foreach (Customer2AddServiceBooking customerParticipated in pAdditionalServiceBookingDC.Customer2AddServiceBookings)
                {
                    var customer = DAOFactory.GenericDAO.GetByID<Customer>(customerParticipated.CustomerOid);
                    entryList.Add(new AssessmentSheetEntry
                    {
                        Customer = customer,
                        AssessmentSheetCategory = lCategory,
                        AssessmentSheetValue = (customerParticipated.Participated ? lYes : lNo),
                        SystemEntryID = SystemEntryID.AdditionalServiceAssessmentSheet,
                        Day = pAdditionalServiceBookingDC.Datum
                    });
                    IList<AssessmentSheetCategory> customer2Category = DAOFactory.GenericDAO.GetAll<AssessmentSheetCategory>();
                    AssessmentSheetCategory f = customer2Category.First(
                        abc =>
                            abc.SystemEntryID.Equals(SystemEntryID.AdditionalServiceAssessmentSheet) &&
                            abc.Description.Equals(lCategory.Description));

                    if (f.Customers == null || !f.Customers.Contains(customer))
                        sqlString += string.Format("INSERT INTO customer2assessmentsheetcategory(customeroid, assessmentsheetoid) VALUES({0}, {1});", customer.Oid.Value, lCategory.Oid.Value);
                }

                DAOFactory.GenericDAO.Insert(entryList);
                DAOFactory.AdoDAO.ExecuteQuery(sqlString);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        private static void MakeServiceRecordHistoryEntry(IEnumerable<ServiceRecord> lOriginals, IEnumerable<long> serviceRecordOidList, StatementType statementType)
        {
            var hServiceRecords = new List<ServiceRecordHistory>();

            if (statementType.Equals(StatementType.Insert) && serviceRecordOidList != null)
            {
                int iterator = 0;
                foreach (ServiceRecordHistory history in lOriginals.Select(ServiceRecordOriginal => new ServiceRecordHistory
                {
                    TimeStamp = DateTime.Now,
                    ChangeType = statementType,
                    CostBearer2SupportConcept = ServiceRecordOriginal.CostBearer2SupportConcept,
                    CostBearer2SupportConceptOid = ServiceRecordOriginal.CostBearer2SupportConceptOid,
                    Customer = ServiceRecordOriginal.Customer,
                    CustomerOid = ServiceRecordOriginal.CustomerOid,
                    Employee = ServiceRecordOriginal.Employee,
                    EmployeeOid = ServiceRecordOriginal.EmployeeOid,
                    End = ServiceRecordOriginal.End,
                    Group = ServiceRecordOriginal.Group,
                    GroupEmployeeCount = ServiceRecordOriginal.GroupEmployeeCount,
                    GroupOid = ServiceRecordOriginal.GroupOid,
                    GroupPersonCount = ServiceRecordOriginal.GroupPersonCount,
                    GroupRoundedDuration = ServiceRecordOriginal.GroupRoundedDuration,
                    IP = ServiceRecordOriginal.IP,
                    IsActive = ServiceRecordOriginal.IsActive,
                    Notice = ServiceRecordOriginal.Notice,
                    ServiceRecordOid = serviceRecordOidList.ElementAt(iterator),
                    RoundedDuration = ServiceRecordOriginal.RoundedDuration,
                    ServiceDescription = ServiceRecordOriginal.ServiceDescription,
                    ServiceRecordType = ServiceRecordOriginal.ServiceRecordType,
                    ServiceRecordInsTs = ServiceRecordOriginal.InsTs,
                    ServiceRecordVersion = ServiceRecordOriginal.Version.Value,
                    ServiceRecordInsUser = ServiceRecordOriginal.InsUser,
                    ServiceRecordUdpUser = ServiceRecordOriginal.UdpUser,
                    Start = ServiceRecordOriginal.Start,
                    SupportConcept = ServiceRecordOriginal.SupportConcept,
                    SystemEntryID = ServiceRecordOriginal.SystemEntryID,
                    DistanceInMeter = ServiceRecordOriginal.DistanceInMeter,
                    IsCreatedInMobileClient = ServiceRecordOriginal.IsCreatedInMobileClient
                }))
                {
                    iterator++;
                    hServiceRecords.Add(history);
                }
            }
            else
            {
                hServiceRecords.AddRange(lOriginals.Select(ServiceRecordOriginal => new ServiceRecordHistory
                {
                    TimeStamp = DateTime.Now,
                    ChangeType = statementType,
                    CostBearer2SupportConcept = ServiceRecordOriginal.CostBearer2SupportConcept,
                    CostBearer2SupportConceptOid = ServiceRecordOriginal.CostBearer2SupportConceptOid,
                    Customer = ServiceRecordOriginal.Customer,
                    CustomerOid = ServiceRecordOriginal.CustomerOid,
                    Employee = ServiceRecordOriginal.Employee,
                    EmployeeOid = ServiceRecordOriginal.EmployeeOid,
                    End = ServiceRecordOriginal.End,
                    Group = ServiceRecordOriginal.Group,
                    GroupEmployeeCount = ServiceRecordOriginal.GroupEmployeeCount,
                    GroupOid = ServiceRecordOriginal.GroupOid,
                    GroupPersonCount = ServiceRecordOriginal.GroupPersonCount,
                    GroupRoundedDuration = ServiceRecordOriginal.GroupRoundedDuration,
                    IP = ServiceRecordOriginal.IP,
                    IsActive = ServiceRecordOriginal.IsActive,
                    Notice = ServiceRecordOriginal.Notice,
                    ServiceRecordOid = ServiceRecordOriginal.Oid,
                    RoundedDuration = ServiceRecordOriginal.RoundedDuration,
                    ServiceDescription = ServiceRecordOriginal.ServiceDescription,
                    ServiceRecordType = ServiceRecordOriginal.ServiceRecordType,
                    ServiceRecordInsTs = ServiceRecordOriginal.InsTs,
                    ServiceRecordVersion = ServiceRecordOriginal.Version.Value,
                    ServiceRecordInsUser = ServiceRecordOriginal.InsUser,
                    ServiceRecordUdpUser = ServiceRecordOriginal.UdpUser,
                    Start = ServiceRecordOriginal.Start,
                    SupportConcept = ServiceRecordOriginal.SupportConcept,
                    SystemEntryID = ServiceRecordOriginal.SystemEntryID,
                    DistanceInMeter = ServiceRecordOriginal.DistanceInMeter,
                    IsCreatedInMobileClient = ServiceRecordOriginal.IsCreatedInMobileClient
                }));
            }

            DAOFactory.GenericDAO.Insert(hServiceRecords);
        }
		
        public IList<TextbausteinDC> GetAllTextbausteine()
        {
            try
            {
                return MapperFactory.TextbausteinDC_Textbaustein.MapToNewDCs(DAOFactory.GenericDAO.GetAllActive<Textbaustein>());
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public IList<TextbausteinDC> GetTextbausteineByServiceCategory(long pServiceCategoryOid)
        {
            try
            {
                return MapperFactory.TextbausteinDC_Textbaustein.MapToNewDCs(DAOFactory.SearchDAO.GetActiveTextbausteineByServiceCategory(pServiceCategoryOid));
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public IList<long> InsertNewTextbausteine(IEnumerable<TextbausteinDC> pTextbausteine)
        {
            try
            {
                var lTextbausteine = MapperFactory.TextbausteinDC_Textbaustein.MapToNewEntities(pTextbausteine);
                DAOFactory.GenericDAO.Insert(lTextbausteine);

                return lTextbausteine.Select(asb => asb.Oid.Value).ToList();
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void UpdateTextbausteine(List<TextbausteinDC> pTextbausteine)
        {
            try
            {
                var lOriginals = DAOFactory.GenericDAO.LoadByIDs<Textbaustein>(pTextbausteine.Select(sc => sc.TextbausteinOid.Value));

                MapperFactory.TextbausteinDC_Textbaustein.MergeWithEntitys(pTextbausteine, lOriginals);

                DAOFactory.GenericDAO.Update(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeleteTextbausteine(Dictionary<long, long> pOid2Version)
        {
            try
            {
                List<Textbaustein> lOriginals = DAOFactory.GenericDAO.LoadByIDs<Textbaustein>(pOid2Version.Select(e => e.Key));
                lOriginals.DoForEach(or => MapperFactory.TextbausteinDC_Textbaustein.ConcurrencyCheck(pOid2Version[or.Oid.Value], or));

                DAOFactory.GenericDAO.Delete(lOriginals);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

	    public IList<ServiceRecordDC> FindServiceRecordsInSpan(long pCostBearer2SupportConceptOid, DateTimeSpan period)
	    {
			try
			{
				var records = DAOFactory.SearchDAO.FindServiceRecordsInSpan(pCostBearer2SupportConceptOid, period);
				return MapperFactory.ServiceRecordDC_ServiceRecord.MapToNewDCs(records);
			}
			catch (Exception e)
			{
				throw Utils.CreateBeWoFaultException(e);
			}
	    }

        public SignatureDC InsertSignature(SignatureDC s)
        {
            try
            {
                var lSignature = MapperFactory.SignatureDC_Signature.MapToNewEntity(s);
                DAOFactory.GenericDAO.Insert(lSignature);
                SignatureDC updatedSignatureDC = MapperFactory.SignatureDC_Signature.MapToNewDC(lSignature);

                if (s.ServiceRecordOid.HasValue)
                {
                    var sr = DAOFactory.GenericDAO.LoadByID<ServiceRecord>(s.ServiceRecordOid.Value);

                    sr.SignatureOid = lSignature.Oid;

                    DAOFactory.GenericDAO.Update(sr);
                }

                return updatedSignatureDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public EmployeeAPPCodeDC CreateNewEmployeeAPPCodeDC(long employeeOid)
        {
            try
            {
                EmployeeAPPCode newCode = new EmployeeAPPCode();
                newCode.EmployeeCode = ErzeugeZufallsCode();
                newCode.EmployeeOid = employeeOid;
                newCode.EmployeeCodeGenDate = DateTime.Now;

                DAOFactory.GenericDAO.Insert(newCode);

                var employeeAPPCodeDC = MapperFactory.EmployeeAPPCodeDC_EmployeeAPPCode.MapToNewDC(newCode);

                return employeeAPPCodeDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }


        public EmployeeAPPCodeDC CreateNewIsChatActiveEmployeeAPPCodeDC(long employeeOid, int activeType)
        {
            try
            {          
                EmployeeAPPCode newCode = new EmployeeAPPCode();             
                newCode.EmployeeOid = employeeOid;
                
                if(activeType == 1)
                    newCode.IsChatAktiv = activeType;
                else
                    newCode.IsChatAktiv = 0;

                DAOFactory.GenericDAO.Insert(newCode);

                var employeeAPPCodeDC = MapperFactory.EmployeeAPPCodeDC_EmployeeAPPCode.MapToNewDC(newCode);

                return employeeAPPCodeDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public EmployeeAPPCodeDC CreateNewNotfallNacrichtEmployeeAPPCodeDC(long employeeOid, String notfallstate)
        {
            try
            {
                EmployeeAPPCode newCode = new EmployeeAPPCode();
                newCode.EmployeeOid = employeeOid;

                newCode.NotfallStatement = notfallstate;            

                DAOFactory.GenericDAO.Insert(newCode);

                var employeeAPPCodeDC = MapperFactory.EmployeeAPPCodeDC_EmployeeAPPCode.MapToNewDC(newCode);

                return employeeAPPCodeDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }



        public CustomerAPPCodeDC CreateNewCustomerAPPCodeDC(long customerOid)
        {
            try
            {
                CustomerAPPCode newCode = new CustomerAPPCode();
                newCode.CustomerCode = ErzeugeZufallsCode();
                newCode.CustomerOid = customerOid;
                newCode.CustomerCodeGenDate = DateTime.Now;

                DAOFactory.GenericDAO.Insert(newCode);
                
                var customerAPPCodeDC = MapperFactory.CustomerAPPCodeDC_CustomerAPPCode.MapToNewDC(newCode);
                
                return customerAPPCodeDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public ChatMessageDC CreateNewChatMessagesDC(long senderOid, long empfängerOid, string message)
        {
            try
            {
                ChatMessage newCode = new ChatMessage();
                newCode.EmpfängerPersonOid = empfängerOid;
                newCode.SenderPersonOid = senderOid;
                newCode.Uhrzeit = DateTime.Now;
                newCode.ChatText = message;

                DAOFactory.GenericDAO.Insert(newCode);

                var ChatMEssagesDC = MapperFactory.ChatMessagesDC_ChatMessages.MapToNewDC(newCode);

                return ChatMEssagesDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public CustomerAPPCodeDC CreateNewIsChatActiveCustomerAPPCodeDC(long customerOid,int activeType)
        {
            try
            {
                CustomerAPPCode newCode = new CustomerAPPCode();             
                newCode.CustomerOid = customerOid;
                
                if(activeType == 1)
                    newCode.IsChatAktiv = activeType;
                else
                    newCode.IsChatAktiv = 0;

                DAOFactory.GenericDAO.Insert(newCode);

                var customerAPPCodeDC = MapperFactory.CustomerAPPCodeDC_CustomerAPPCode.MapToNewDC(newCode);

                return customerAPPCodeDC;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public string ErzeugeZufallsCode()
        {
            int lenght = 12;
            const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" +
                                 "abcdefghijklmnopqrstuvwxyz" +
                                 "0123456789";
            var random = new Random();
            String Code = new string(Enumerable.Repeat(chars, lenght)
            .Select(s => s[random.Next(s.Length)]).ToArray());


            return Code;
        }

        public long InsertNewServiceRecordAndSignature(ServiceRecordDC sr, SignatureDC sig) {

            try
            {
                var dcList = new List<ServiceRecordDC>();
                dcList.Add(sr);

                var oidList = InsertNewServiceRecords(dcList);
                var serviceRecordOid = oidList[0];


                if (!String.IsNullOrEmpty(sig.DataBild))
                {
                    var lSignature = MapperFactory.SignatureDC_Signature.MapToNewEntity(sig);
                 //   lSignature.ServiceRecordOid = serviceRecordOid;

                    DAOFactory.GenericDAO.Insert(lSignature);
                }
                return serviceRecordOid;

            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<OrganisationPersonRelationDC> LoadOrganisationPersonRelationsByOid(IEnumerable<long> pOids)
        {
            try
            {
                var customerPersonRels = DAOFactory.GenericDAO.LoadByIDs<Organisation2Person>(pOids);

                return MapperFactory.OrganisationPersonRelDC_Organisation2PersonMapper.MapToNewDCs(customerPersonRels);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public List<BargeldkassenDC> LoadBargeldkassenForObject(TableID objectTid, long objectOid)
        {
            try
            {
                var bargeldkassen = DAOFactory.SearchDAO.FindBargeldkasse(objectTid, objectOid);

                return MapperFactory.BargeldkassenDCBargeldkasseDC_BargeldkassenDCBargeldkasse.MapToNewDCs(bargeldkassen);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public long InsertNewBargeldkasse(BargeldkassenDC pBargeldkasse)
        {
            try
            {
                var lBargeldkasse = MapperFactory.BargeldkassenDCBargeldkasseDC_BargeldkassenDCBargeldkasse.MapToNewEntity(pBargeldkasse);
                DAOFactory.GenericDAO.Insert(lBargeldkasse);

                return lBargeldkasse.Oid.Value;
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public BargeldkassenDC UpdateBargeldkasse(BargeldkassenDC pBargeldkasse)
        {
            try
            {
                var lOriginal = DAOFactory.GenericDAO.LoadByID<Bargeldkasse>(pBargeldkasse.BargeldkassenOid.Value);

                MapperFactory.BargeldkassenDCBargeldkasseDC_BargeldkassenDCBargeldkasse.MergeWithEntity(pBargeldkasse, lOriginal);
                DAOFactory.GenericDAO.Update(lOriginal);

                return MapperFactory.BargeldkassenDCBargeldkasseDC_BargeldkassenDCBargeldkasse.MapToNewDC(lOriginal);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        public void DeactivateBargeldkasse(long pOid, long pVersion)
        {
            try
            {
                ServiceLogic.SetActivationType<Bargeldkasse>(new Dictionary<long, long>{{pOid, pVersion}}, ActivationTypeId.Deleted);
            }
            catch (Exception e)
            {
                throw Utils.CreateBeWoFaultException(e);
            }
        }

        #endregion

        #endregion

        #region Methods

        public string PrepareAuslastungReport(AuslastungAnalysisRootDC pReport, string id)
        {
            try
            {
                string lResult = id + ".xml";

                string lDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, MultitenancyOperationContextExt.Current.Tenant + @"\temp");
                string lPath = Path.Combine(lDir, lResult);

                BS.Shared.Core.Utils.XMLSerialize(lPath, pReport);

                return lResult;
            }
            catch (Exception e)
            {
                throw (Utils.CreateBeWoFaultException(e));
            }
        }

        public ServiceRecordStatisticsInfoDC GetServiceRecordStatisticInfo(long costBearer2SupportConceptOid, DateTime statisticsDate)
        {
            var factory = PluginLoader.FindClass<ServiceRecordStatisticFactory>();

            if (factory != null)
            {
                return factory.GetServiceRecordStatisticInfo(costBearer2SupportConceptOid, statisticsDate);
            }
            return null;
        }

        public SupportConceptStatisticsDC CreateSupportConceptStatistics(long costBearer2SupportConceptOid, DateTime statisticsDate)
        {
            var factory = PluginLoader.FindClass<ServiceRecordStatisticFactory>();


            if (factory == null)
            {
                factory = new ServiceRecordStatisticFactory();
            }
            return factory.CreateSupportConceptStatistics(costBearer2SupportConceptOid, statisticsDate);
        }


        public void ResetTenant(String tenant)
        {
            WCFHibernateSessionManager.ResetSessionFactory(tenant);
        }

        public void ResetAllTenants()
        {
            WCFHibernateSessionManager.ResetAllSessionFactories();
        }

        public String GetLicenseOrderUrl()
        {
            string url = ConfigurationManager.AppSettings.Get("LicenseOrderUrl");
            url = url.Replace("[TENANT]", MultitenancyOperationContextExt.Current.Tenant);

            return url;
        }

        public LicenseInfoDC GetLicenseInfo()
        {
            return SecurityUtils.GetLicenseInfo();
        }

        public GroupDurationDC CalculateGroupDuration(int personCount, int employeeCount, decimal totalDuration)
        {
            var calc = PluginLoader.FindClass<GroupDurationCalculator>();

            if (calc != null)
            {
                return calc.CalculateGroupDuration(personCount, employeeCount, totalDuration);
            }
            return null;
        }

	    public GroupDurationDC CalculateGroupDuration2(int personCount, int employeeCount, decimal totalDuration, long[] costBearer2SupportConceptArray)
	    {
			var calc = PluginLoader.FindClass<GroupDurationCalculator>();

			if (calc != null)
			{
				return calc.CalculateGroupDuration(personCount, employeeCount, totalDuration, costBearer2SupportConceptArray);
			}
			return null;
	    }

        public IList<UiElementDC> GetUiElements(UiElementType? uiType, long? employeeOid, long? teamOid, long[] oidArray)
        {
            var factory = PluginLoader.FindClass<UiElementFactory>();

            if (factory == null)
            {
                factory = new UiElementFactory();
            }

            return factory.GetUiElements(uiType, employeeOid, teamOid);
        }

        private static List<SupportConceptTreeNodeDC> BuildTree(IEnumerable<SupportConcept> pSupportConcepts)
        {
            var lResult = new List<SupportConceptTreeNodeDC>();
            foreach (SupportConcept iSC in pSupportConcepts)
            {
                var lScNode = new SupportConceptTreeNodeDC
                {
                    NodeType = NodeType.SupportConcept,
                    SupportConcept = MapperFactory.CompactSupportConceptDC_SupportConcept.MapToNewDC(iSC),
                };
                lScNode.Description = String.Format("{0}, {1}", iSC.Customer.Person.LastName, iSC.Customer.Person.FirstName);

                foreach (CostBearer2SupportConcept iSC2Cb in iSC.CostBearer2SupportConceptList)
                {
                    var tnode = new SupportConceptTreeNodeDC();

                    tnode.NodeType = NodeType.SupportConceptCostBearerRelDC;
                    tnode.SupportConcept = lScNode.SupportConcept;
                    tnode.SupportConceptCostBearerRelDC = MapperFactory.SupportConceptCostBearerRelDC_CostBearer2SupportConcept.MapToNewDC(iSC2Cb);
                    if (iSC2Cb.CostBearer.Organisation != null)
                    {
                        tnode.Description = iSC2Cb.CostBearer.Organisation.Name;
                    }

                    lScNode.ChildNodes.Add(tnode);
                }

                lResult.Add(lScNode);
            }

            return lResult.OrderBy(s => s.Description).ToList();
        }

        private static CompactCustomerDC CreateCustomerForSupportConceptTree(Customer pEntity)
        {
            var dc = new CompactCustomerDC();
            dc.CustomerOid = pEntity.Oid.Value;
            dc.CustomerVersion = pEntity.Version.Value;
            dc.FirstName = pEntity.Person.FirstName;
            dc.LastName = pEntity.Person.LastName;
            dc.DateOfBirth = pEntity.Person.DateOfBirth;
            dc.ActivationType = pEntity.IsActive;
            dc.TerminationDate = pEntity.TerminationDate;
            dc.Sex = pEntity.Person.Sex;

            return dc;
        }

        private List<CompactSupportConceptDC> CreateFlatSupportConceptCostBearerDCList(IEnumerable<SupportConcept> pEntityList, bool onlyWithAssignedCostbearer, long? employeeOid)
        {
            var list = new List<CompactSupportConceptDC>();
            var customerOIDs = new Dictionary<long, long>();

            if (employeeOid.HasValue)
            {
                var lEmployee = DAOFactory.GenericDAO.LoadByID<Employee>(employeeOid.Value);
                IList<Employee2Customer> e2cList = lEmployee.Employee2CustomerList;


                foreach (Employee2Customer item in e2cList)
                {
                    if (!customerOIDs.ContainsKey(item.Customer.Oid.Value))
                    {
                        customerOIDs.Add(item.Customer.Oid.Value, item.Customer.Oid.Value);
                    }
                }
            }
            //var t = new List<long>();
            var c2sOids = new Dictionary<long, bool>();
            foreach (SupportConcept sc in pEntityList)
            {
                if (sc.CostBearer2SupportConceptList != null && sc.CostBearer2SupportConceptList.Count > 0)
                {
                    foreach (CostBearer2SupportConcept cb2sc in sc.CostBearer2SupportConceptList)
                    {
                        //t.Add(cb2sc.Oid.Value);
                        if (!c2sOids.ContainsKey(cb2sc.Oid.Value))
                        {
                            CompactSupportConceptDC dc = CreateFlatSupportConcept(sc, cb2sc);
                            if (customerOIDs.ContainsKey(sc.Customer.Oid.Value))
                            {
                                dc.IsRelatedToEmployee = true;
                                dc.Customer.IsRelatedToEmployee = true;
                            }
                            list.Add(dc);
                            c2sOids.Add(cb2sc.Oid.Value, true);
                        }
                    }
                }
                else
                {
                    if (!onlyWithAssignedCostbearer)
                    {
                        list.Add(MapperFactory.CompactSupportConceptDC_SupportConcept.MergeWithDC(sc, new CompactSupportConceptDC()));
                    }
                }
            }

            return list;
        }

        public static CompactSupportConceptDC CreateFlatSupportConcept(SupportConcept sc, CostBearer2SupportConcept cb2sc)
        {
            var dc = new CompactSupportConceptDC();

            dc.SupportConceptOid = sc.Oid.Value;
            dc.SupportConceptVersion = sc.Version.Value;
            dc.Customer = CreateCustomerForSupportConceptTree(sc.Customer);
            dc.ActivationType = sc.IsActive;
            dc.ConferenceDate = sc.ConferenceDate;
            dc.IsApproved = cb2sc.Status == CostBearer2SupportConceptStatus.Approved;


            var costBearer = new CompactCostBearerDC();

            if (cb2sc.CostBearer.Organisation != null)
            {
                costBearer.Organisation = MapperFactory.CompactOrganisationDC_Organisation.MapToNewDC(cb2sc.CostBearer.Organisation);
            }

            costBearer.CostBearerID = cb2sc.CostBearer.ID;
            costBearer.CostBearerOid = cb2sc.CostBearer.Oid.Value;
            costBearer.CostBearer2SupportConceptOid = cb2sc.Oid.Value;
            costBearer.SupportConceptStatus = cb2sc.Status;
            costBearer.RequestedStartDate = cb2sc.RequestedStartDate;
            costBearer.RequestedEndDate = cb2sc.RequestedEndDate;
            costBearer.ApprovedStartDate = cb2sc.ApprovedStartDate;
            costBearer.ApprovedEndDate = cb2sc.ApprovedEndDate;

            // costBearer.ApprovedFLS = cb2sc.ApprovedFLS;
            // costBearer.ApprovedFLSTotal = cb2sc.ApprovedFLSTotal;
            costBearer.CustomerReferenceNumber = cb2sc.CustomerReferenceNumber;
            costBearer.IsCalculatingWithFactor = cb2sc.CostBearer.IsCalculatingWithFactor;

            dc.CostBearerList.Add(costBearer);
            dc.CustomerReferenceNumbers.Add(cb2sc.CustomerReferenceNumber);
            dc.CostBearerRelOids.Add(cb2sc.Oid.Value);
            dc.CostBearerOids2CostBearerRelOids.Add(costBearer.CostBearerOid, cb2sc.Oid.Value);

            return dc;
        }

        private static SupportConceptCostBearerRelDC CreateSCCostBearerRelForSupportConceptTree(CostBearer2SupportConcept pEntity)
        {
            var dc = new SupportConceptCostBearerRelDC();

            // dc.ApprovedFLS = pEntity.ApprovedFLS;
            // dc.ApprovedFLSTotal = pEntity.ApprovedFLSTotal;
            dc.CostBearer2SupportConceptOid = pEntity.Oid;
            dc.CostBearer2SupportConceptVersion = pEntity.Version;
            dc.Notice = pEntity.Notice;
            dc.Status = pEntity.Status;
            dc.RequestedStartDate = pEntity.RequestedStartDate;
            dc.RequestedEndDate = pEntity.RequestedEndDate;
            dc.ApprovedStartDate = pEntity.ApprovedStartDate;
            dc.ApprovedEndDate = pEntity.ApprovedEndDate;
            dc.CustomerReferenceNumber = pEntity.CustomerReferenceNumber;
            dc.MonthlyPayment = pEntity.MonthlyPayment;

            // dc.NoRelationExists = pEntity.ServiceRecords.Count == 0;
            if (pEntity.CostBearer.Organisation != null)
            {
                dc.CostBearer = MapperFactory.CompactOrganisationDC_Organisation.MapToNewDC(pEntity.CostBearer.Organisation);
            }

            // pDataContract.SupportConcept = MapperFactory.CompactSupportConceptDC_SupportConcept.MapToNewDC(pEntity.SupportConcept);
            return dc;
        }

        private static CompactSupportConceptDC CreateSCForSupportConceptTree(SupportConcept pEntity)
        {
            var dc = new CompactSupportConceptDC();

            dc.SupportConceptOid = pEntity.Oid.Value;
            dc.SupportConceptVersion = pEntity.Version.Value;

            // dc.Customer = MapperFactory.CompactCustomerDC_Customer.MapToNewDC(pEntity.Customer);
            dc.ActivationType = pEntity.IsActive;
            dc.ConferenceDate = pEntity.ConferenceDate;

            // foreach (var iCBRel in pEntity.CostBearer2SupportConceptList)
            // {
            // CompactCostBearerDC costBearer = new CompactCostBearerDC();

            // if (iCBRel.CostBearer.Organisation != null)
            // costBearer.OrganisationName = iCBRel.CostBearer.Organisation.Name;

            // costBearer.SupportConceptStatus = iCBRel.Status;
            // costBearer.RequestedStartDate = iCBRel.RequestedStartDate;
            // costBearer.RequestedEndDate = iCBRel.RequestedEndDate;
            // costBearer.ApprovedStartDate = iCBRel.ApprovedStartDate;
            // costBearer.ApprovedEndDate = iCBRel.ApprovedEndDate;
            // costBearer.ApprovedFLS = iCBRel.ApprovedFLS;
            // costBearer.CustomerReferenceNumber = iCBRel.CustomerReferenceNumber;

            // pDataContract.CostBearerList.Add(costBearer);
            // pDataContract.CustomerReferenceNumbers.Add(iCBRel.CustomerReferenceNumber);
            // pDataContract.CostBearerRelOids.Add(iCBRel.Oid.Value);
            // }
            return dc;
        }

        #endregion
    }
}