Files
BeWoPlaner/Data/Access/GenericDAO.cs
Rene Evertz 71d1bfd2c2 Merge branch 'feature_rene_17_xrechnung'
# Conflicts:
#	Data/Data.csproj
#	Data/Entities/InvoiceBase.cs
#	Host/Web.Secrets.config.template
#	Host/Web.config
#	Service/ServiceBehavior/AdminServiceMessageInspector.cs
#	Service/ServiceContracts/IAdminService.cs
#	Shared/BeWoEntityEnums.cs
#	Shared/DataContracts/InvoiceBaseDC.cs
2025-09-27 19:41:52 +02:00

484 lines
14 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using BeWo.Data.Entities;
using BeWo.Data.Entities.Light;
using BS.Shared;
using BS.Shared.Extensions;
using NHibernate;
using NHibernate.Criterion;
using NHibernate.Proxy;
namespace BeWo.Data.Access
{
public class GenericDAO : AbstractBaseDAO
{
internal GenericDAO()
{
}
public virtual void Deactivate(BeWoEntityBase pEntity)
{
Debug.WriteLine($"---->DEACTIVATE von {pEntity.GetType().FullName}");
this.SetActivationType(pEntity, ActivationTypeId.Deleted);
}
public virtual void Deactivate<T>(IEnumerable<T> pEntitys) where T : BeWoEntityBase, new()
{
if (pEntitys?.FirstOrDefault() is object obj)
{
Debug.WriteLine($"---->DEACTIVATE von {obj.GetType().FullName}");
}
ITransaction lTransaction = this.Session.BeginTransaction();
try
{
foreach (BeWoEntityBase iEntity in pEntitys)
{
iEntity.IsActive = ActivationTypeId.Deleted;
if (iEntity.SystemEntryID == null)
{
this.Session.SaveOrUpdate(iEntity);
}
else
{
throw new InvalidOperationException("Can't delete System Entries");
}
}
lTransaction.Commit();
}
catch (Exception e)
{
lTransaction.Rollback();
throw e;
}
}
public virtual void Delete(BeWoEntityBase pEntity)
{
Debug.WriteLine($"---->DELETE von {pEntity.GetType().FullName}");
if (pEntity.SystemEntryID is null)
{
LogSignatureDeletion(pEntity);
var lTransaction = Session.BeginTransaction();
try
{
Session.Delete(pEntity);
lTransaction.Commit();
}
catch (Exception e)
{
lTransaction.Rollback();
throw e;
}
}
else
{
throw new InvalidOperationException("Can't delete System Entries");
}
}
public virtual void Delete<T>(IEnumerable<T> pEntitys) where T : BeWoEntityBase, new()
{
if (pEntitys?.FirstOrDefault() is object obj)
{
Debug.WriteLine($"---->DELETE von {obj.GetType().FullName}");
}
var entities = pEntitys.ToList();
foreach (var entity in entities)
{
LogSignatureDeletion(entity);
}
var lTransaction = Session.BeginTransaction();
try
{
foreach (var iEntity in entities)
{
if (iEntity.SystemEntryID is null || iEntity.SystemEntryID.Value == SystemEntryID.AdditionalServiceAssessmentSheet)
{
Session.Delete(iEntity);
}
else
{
throw new InvalidOperationException("Can't delete System Entries");
}
}
lTransaction.Commit();
}
catch (Exception e)
{
lTransaction.Rollback();
throw e;
}
}
public virtual IList<T> GetAll<T>() where T : BeWoEntityBase
{
return this.CreateCriteria<T>().List<T>();
}
public virtual IList<T> GetAllActive<T>() where T : BeWoEntityBase
{
return this.GetAllWithActivationType<T>(ActivationTypeId.Active);
}
public virtual IList<T> GetAllActiveAndArchived<T>() where T : BeWoEntityBase
{
return this.CreateCriteria<T>().Add(Restrictions.Or(Restrictions.Eq(BeWoEntityBase.PropertyName_IsActive, ActivationTypeId.Active), Restrictions.Eq(BeWoEntityBase.PropertyName_IsActive, ActivationTypeId.Archived))).List<T>();
}
public virtual IList<T> GetAllWithActivationType<T>(ActivationTypeId activationType) where T : BeWoEntityBase
{
return this.CreateCriteria<T>().Add(Restrictions.Eq(BeWoEntityBase.PropertyName_IsActive, activationType)).List<T>();
}
public virtual T GetByID<T>(long pOid) where T : BeWoEntityBase, new()
{
return this.Session.Get<T>(pOid);
}
public virtual List<T> GetByIDs<T>(IEnumerable<long> pOids) where T : BeWoEntityBase, new()
{
return pOids.Select(oid => this.GetByID<T>(oid)).ToList();
}
public virtual IList<T> GetActiveByIDs<T>(IEnumerable<long> pOids) where T : BeWoEntityBase, new()
{
return CreateCriteria<T>().Add(Restrictions.Eq(BeWoEntityBase.PropertyName_IsActive, ActivationTypeId.Active)).Add(Restrictions.In(BeWoEntityBase.PropertyName_Oid, pOids.ToArray())).List<T>();
}
public virtual void Insert(BeWoEntityBase pEntity)
{
var entityType = pEntity.GetType();
Debug.WriteLine($"++++>INSERT von {entityType.FullName}");
if (pEntity is LightEntity)
throw new InvalidOperationException("Cannot insert LightEntity, only update! str:" + pEntity.ToString());
var session = Session;
if (session is null)
{
throw new InvalidOperationException("GenericDAO.Insert(): Session is null");
}
var lTransaction = session.BeginTransaction();
try
{
pEntity.IsActive = ActivationTypeId.Active;
session.Save(pEntity);
lTransaction.Commit();
if (pEntity is Signature signature)
{
LogSignatureInsert(signature);
}
}
catch (Exception e)
{
lTransaction.Rollback();
throw e;
}
}
public virtual void Insert<T>(IEnumerable<T> pEntitys) where T : BeWoEntityBase, new()
{
if (pEntitys?.FirstOrDefault() is object obj)
{
Debug.WriteLine($"++++>INSERT von {obj.GetType().FullName}");
}
ITransaction lTransaction = this.Session.BeginTransaction();
try
{
foreach (BeWoEntityBase iEntity in pEntitys)
{
if (iEntity is LightEntity)
throw new InvalidOperationException("Cannot insert LightEntity, only update! str:" + iEntity.ToString());
this.Session.Save(iEntity);
}
lTransaction.Commit();
}
catch (Exception e)
{
lTransaction.Rollback();
throw e;
}
}
public virtual T LoadByID<T>(long pOid) where T : BeWoEntityBase, new()
{
return this.Session.Load<T>(pOid);
}
public virtual List<T> LoadByIDs<T>(IEnumerable<long> pOids) where T : BeWoEntityBase, new()
{
return pOids.Select(oid => this.LoadByID<T>(oid)).ToList();
}
public virtual T LoadSystemEntry<T>(SystemEntryID pId) where T : BeWoEntityBase, new()
{
return this.CreateCriteria<T>().Add(Restrictions.Eq(BeWoEntityBase.PropertyName_SystemEntryID, pId)).UniqueResult<T>();
}
public void Reattach<T>(T entity) where T : BeWoEntityBase, new()
{
this.Session.Lock(entity, LockMode.None);
}
public virtual void SetActivationType(BeWoEntityBase pEntity, ActivationTypeId activationType)
{
if (pEntity.SystemEntryID == null)
{
ITransaction lTransaction = this.Session.BeginTransaction();
try
{
pEntity.IsActive = activationType;
this.Session.SaveOrUpdate(pEntity);
lTransaction.Commit();
}
catch (Exception e)
{
lTransaction.Rollback();
throw e;
}
}
else
{
throw new InvalidOperationException("Can't delete System Entries");
}
}
public virtual void Update(BeWoEntityBase pEntity)
{
Debug.WriteLine($"####>UPDATE von {pEntity.GetType().FullName}");
if (pEntity is ServiceRecord serviceRecord && serviceRecord.Oid.HasValue)
{
var hasPreviouslyExistingSignature = DAOFactory.SearchDAO.CheckForExistingServiceRecordSignature(serviceRecord.Oid.Value);
if (hasPreviouslyExistingSignature && serviceRecord.SignatureOid is null)
{
LogSignatureDeletion(serviceRecord);
}
}
if (pEntity is Bargeldkasse bargeldkasse && bargeldkasse.Oid.HasValue)
{
var oldTransactions = DAOFactory.SearchDAO.LoadBargeldTransaktionenNonLazy(bargeldkasse.Oid.Value);
var deletedTransactions = oldTransactions.Where(oldTransaction => false == bargeldkasse.Bargeldtransaktionen.Any(x => x.Oid.HasValue && x.Oid.Equals(oldTransaction.Oid))).ToList();
var deletedTransactionsWithSignature = deletedTransactions.Where(oldTransaction => oldTransaction.SignatureOid.HasValue).ToList();
foreach (var deletedTransactionWithSignature in deletedTransactionsWithSignature)
{
LogSignatureDeletion(deletedTransactionWithSignature);
}
}
ITransaction lTransaction = this.Session.BeginTransaction();
try
{
this.Session.SaveOrUpdate(pEntity);
lTransaction.Commit();
}
catch (Exception e)
{
lTransaction.Rollback();
throw e;
}
}
public virtual void Update<T>(IEnumerable<T> pEntities) where T : BeWoEntityBase, new()
{
if (pEntities?.FirstOrDefault() is object obj)
{
Debug.WriteLine($"####>UPDATE von {obj.GetType().FullName}");
}
ITransaction lTransaction = this.Session.BeginTransaction();
try
{
if (pEntities is IEnumerable<ServiceRecord> serviceRecords)
{
foreach (var serviceRecord in serviceRecords)
{
if (serviceRecord.Oid is null)
{
continue;
}
var hasPreviouslyExistingSignature = DAOFactory.SearchDAO.CheckForExistingServiceRecordSignature(serviceRecord.Oid.Value);
if (hasPreviouslyExistingSignature && serviceRecord.SignatureOid is null)
{
LogSignatureDeletion(serviceRecord);
}
}
}
if (pEntities is IEnumerable<Bargeldkasse> bargeldkassen)
{
foreach (var bargeldkasse in bargeldkassen)
{
if (bargeldkasse.Oid is null)
{
continue;
}
var oldTransactions = DAOFactory.SearchDAO.LoadBargeldTransaktionenNonLazy(bargeldkasse.Oid.Value);
var deletedTransactions = oldTransactions.Where(oldTransaction => bargeldkasse.Bargeldtransaktionen.Any(x => x.Oid.HasValue && x.Oid.Equals(oldTransaction.Oid))).ToList();
var deletedTransactionsWithSignature = deletedTransactions.Where(oldTransaction => oldTransaction.SignatureOid.HasValue).ToList();
foreach (var deletedTransactionWithSignature in deletedTransactionsWithSignature)
{
LogSignatureDeletion(deletedTransactionWithSignature);
}
}
}
foreach (BeWoEntityBase iEntity in pEntities)
{
this.Session.SaveOrUpdate(iEntity);
}
lTransaction.Commit();
}
catch (Exception e)
{
lTransaction.Rollback();
throw e;
}
}
public virtual T Unproxy<T>(T obj)
{
if (!NHibernateUtil.IsInitialized(obj))
{
NHibernateUtil.Initialize(obj);
}
if (obj is INHibernateProxy)
{
return (T)this.Session.GetSessionImplementation().PersistenceContext.Unproxy(obj);
}
return obj;
}
public virtual int GetRowCount<T>() where T : BeWoEntityBase
{
return Session.QueryOver<T>().RowCount();
}
public virtual int GetRowCount<T>(string pPropertyName, object value) where T : BeWoEntityBase
{
var count = CreateCriteria<T>()
.Add(Restrictions.Eq(pPropertyName, value))
.SetProjection(Projections.RowCount())
.UniqueResult<int>();
return count;
}
public virtual bool Any<T>() where T : BeWoEntityBase
{
return GetRowCount<T>() > 0;
}
public virtual bool Any<T>(string pPropertyName, object value) where T : BeWoEntityBase
{
return GetRowCount<T>(pPropertyName, value) > 0;
}
public virtual bool Exists<T>(string pPropertyName, object value) where T : BeWoEntityBase
{
return GetRowCount<T>(pPropertyName, value) > 0;
}
public T GetByProperty<T>(string pPropertyName, object value) where T : BeWoEntityBase
{
return CreateCriteria<T>().Add(Restrictions.Eq(pPropertyName, value)).UniqueResult<T>();
}
private static void LogSignatureDeletion(BeWoEntityBase entity)
{
var signatureHistoryEntries = new List<SignatureHistory>();
switch (entity)
{
case Signature signature:
signatureHistoryEntries.AddIfNotNull(DAOFactory.SearchDAO.CreateSignatureHistoryEntry(signature, SignatureEventType.Delete));
break;
case ConfirmationReceiptSignature confirmationReceiptSignature:
signatureHistoryEntries.AddIfNotNull(DAOFactory.SearchDAO.CreateMonthlySignatureHistoryEntry(confirmationReceiptSignature, SignatureEventType.Delete));
break;
case ServiceRecord serviceRecord when serviceRecord.Oid.HasValue:
{
var s = DAOFactory.SearchDAO.LoadJustDeletedSignature(serviceRecord.Oid.Value, true);
var signatureHistoryEntry = DAOFactory.SearchDAO.CreateSignatureHistoryEntry(s, SignatureEventType.CascadingDelete);
signatureHistoryEntries.AddIfNotNull(signatureHistoryEntry);
break;
}
case Bargeldkasse bargeldkasse when bargeldkasse.Bargeldtransaktionen.Any(bargeldtransaktion => bargeldtransaktion.SignatureOid.HasValue):
signatureHistoryEntries.AddRangeIfNotNull(DAOFactory.SearchDAO.CreateSignatureHistoryEntryForBargeldkasse(bargeldkasse));
break;
case Bargeldtransaktion bargeldtransaktion when bargeldtransaktion.SignatureOid.HasValue:
signatureHistoryEntries.AddIfNotNull(DAOFactory.SearchDAO.CreateSignatureHistoryForBargeldtransaktion(bargeldtransaktion, SignatureEventType.CascadingDelete));
break;
}
if (signatureHistoryEntries.Any())
{
DAOFactory.GenericDAO.Insert(signatureHistoryEntries.Where(she => she is object));
}
}
private static void LogSignatureUpdateForServiceRecord(ServiceRecord serviceRecord)
{
/*
* Wird bei folgenden Szenarien ausgeführt:
*
* 1. Direkt nach dem Signature-Insert (Erst das Signature-Insert, dann das ServiceRecord-Update, um die SignatureOid in die ServiceRecord-Tabelle zu schreiben).
* 2. Beim Löschen der Signature
*/
var hasPreviouslyExistingSignature = DAOFactory.SearchDAO.CheckForExistingServiceRecordSignature(serviceRecord.Oid.Value);
// Prüfen, ob es sich um ein Update, ausgelöst durch das Insert der Unterschrift, handelt.
if (false == hasPreviouslyExistingSignature)
{
return;
}
var signatureHistory = DAOFactory.SearchDAO.CreateSignatureHistoryForServiceRecordUpdate(serviceRecord, SignatureEventType.CascadingDelete);
DAOFactory.GenericDAO.Insert(signatureHistory);
}
private static void LogSignatureInsert(Signature signature)
{
var signatureHistory = DAOFactory.SearchDAO.CreateSignatureHistoryEntry(signature, SignatureEventType.Insert);
DAOFactory.GenericDAO.Insert(signatureHistory);
}
}
}