2024-04-30 12:18:38 +02:00
using System ;
using System.Configuration ;
using System.IO ;
using System.Linq ;
using System.ServiceModel ;
using System.Text.RegularExpressions ;
using System.Threading ;
using System.Web.Mvc ;
using BeWo.Data.Entities ;
using BeWo.Data.Utils ;
using BeWo.Service.DCEntityMapper ;
using BeWo.Service.Security ;
using BeWoPlanerMobil.Models ;
using BeWoPlanerMobil.Service ;
using BeWoPlanerMobil.Util ;
using BS.Shared ;
using NHibernate ;
using NHibernate.Criterion ;
2024-04-18 16:14:20 +02:00
namespace BeWoPlanerMobil.Controllers
{
public class ExternalSignatureController : Controller
{
2024-04-30 12:18:38 +02:00
private static readonly object Lock = string . Empty ;
protected static readonly log4net . ILog Log = log4net . LogManager . GetLogger ( System . Reflection . MethodBase . GetCurrentMethod ( ) . DeclaringType ) ;
private ExternalSignatureModel _Model ;
public ExternalSignatureModel Model
{
get
{
2025-06-11 22:56:25 +02:00
if ( _Model = = null )
2024-04-30 12:18:38 +02:00
{
_Model = new ExternalSignatureModel ( ) ;
}
2025-06-11 22:56:25 +02:00
//if((ExternalSignatureModel) Session["ExternalSignatureModel"] is null)
//{
// _Model = new ExternalSignatureModel();
// Session["ExternalSignatureModel"] = _Model;
//}
//else
//{
// _Model = (ExternalSignatureModel) Session["ExternalSignatureModel"];
//}
2024-04-30 12:18:38 +02:00
return _Model ? ? new ExternalSignatureModel ( ) ;
}
}
private bool IsTokenExpired ( )
{
if ( Model ? . Token is null )
{
2024-05-03 14:35:33 +02:00
return true ;
2024-04-30 12:18:38 +02:00
}
try
{
var info = SecurityUtils . SliceOneTimeLinkToken ( Model . Token ) ;
if ( info . ContainsKey ( "expirationDate" ) & & DateTime . TryParse ( info [ "expirationDate" ] ? . ToString ( ) , out var expirationDate ) )
{
return expirationDate < DateTime . Now ;
}
2024-05-03 14:35:33 +02:00
return true ;
2024-04-30 12:18:38 +02:00
}
catch ( Exception exception )
{
Log . Error ( exception . Message , exception ) ;
2024-05-03 14:35:33 +02:00
return true ;
2024-04-30 12:18:38 +02:00
}
}
private bool CheckCredentials ( )
{
if ( Model ? . Token is null )
{
return false ;
}
var info = SecurityUtils . SliceOneTimeLinkToken ( Model . Token ) ;
var username = info [ "user" ] . ToString ( ) ;
var password = info [ "password" ] . ToString ( ) ;
var session = CreateSessionFromTokenInfo ( ) ;
if ( session is null )
{
return false ;
}
try
{
var user = session . CreateCriteria < ApplicationUser > ( )
. Add ( Restrictions . Eq ( nameof ( ApplicationUser . LoginName ) , username ) )
. Add ( Restrictions . Eq ( nameof ( BeWoEntityBase . IsActive ) , BS . Shared . ActivationTypeId . Active ) )
. UniqueResult < ApplicationUser > ( ) ;
if ( ! ( user is null ) & & user . CheckRC2Password ( password ) )
{
return user . CheckRC2Password ( password ) ;
}
Model . ErrorMessage = "Es ist ein Fehler aufgetreten.<br />Bitte wenden Sie sich an Ihren Administrator" ;
#if DEBUG
2024-05-03 14:35:33 +02:00
//Model.ErrorMessage = $"Es wurde kein Benutzer mit dem Loginnamen {username} gefunden oder das Passwort stimmt nicht überein!";
2024-04-30 12:18:38 +02:00
#endif
return false ;
}
catch ( Exception exception )
{
throw exception ;
}
finally
{
session . Close ( ) ;
}
}
private ISession CreateSessionFromTokenInfo ( )
{
try
{
Monitor . Enter ( Lock ) ;
var test = System . Web . HttpContext . Current . Server . MapPath ( "" ) ;
var dotDotCount = Regex . Matches ( test , "ExternalSignature" ) . Count ;
var mapPathParameter = "" ;
for ( var i = 0 ; i < dotDotCount ; i + + )
{
mapPathParameter + = "..\\" ;
}
var serverPath = System . Web . HttpContext . Current . Server . MapPath ( mapPathParameter ) ;
serverPath = Path . Combine ( serverPath , ConfigurationManager . AppSettings . Get ( "MultitenancyPath" ) ) ;
serverPath = Path . Combine ( serverPath , $"{Model.Tenant}.config" ) ;
if ( ! System . IO . File . Exists ( serverPath ) )
{
Model . ErrorMessage = "Es ist ein Fehler aufgetreten.<br />Bitte wenden Sie sich an Ihren Administrator" ;
#if DEBUG
2024-05-03 14:35:33 +02:00
//Model.ErrorMessage = "Die .config-Datei wurde nicht gefunden!";
2024-04-30 12:18:38 +02:00
#endif
return null ;
}
var config = new NHibernate . Cfg . Configuration ( ) . Configure ( serverPath ) . SetInterceptor ( new MobileUpdInsInterceptor ( ) ) . BuildSessionFactory ( ) ;
return config . OpenSession ( ) ;
}
catch ( Exception exception )
{
throw new FaultException ( exception . StackTrace + ( exception . InnerException ? . Message ? ? string . Empty ) ) ;
}
finally
{
Monitor . Exit ( Lock ) ;
}
}
private ServiceRecord LoadServiceRecord ( )
{
try
{
if ( false = = CheckCredentials ( ) | | IsTokenExpired ( ) )
{
return null ;
}
var session = CreateSessionFromTokenInfo ( ) ;
try
{
if ( Model . ServiceRecordOid is null )
{
return null ;
}
return session . CreateCriteria < ServiceRecord > ( )
. Add ( Restrictions . Eq ( nameof ( BeWoEntityBase . Oid ) , Model . ServiceRecordOid ) )
. Add ( Restrictions . Eq ( nameof ( BeWoEntityBase . IsActive ) , ActivationTypeId . Active ) )
. UniqueResult < ServiceRecord > ( ) ;
}
catch ( Exception exception )
{
throw exception ;
}
finally
{
session . Close ( ) ;
}
}
catch ( Exception exception )
{
Log . Error ( exception . Message , exception ) ;
return null ;
}
}
2024-04-18 16:14:20 +02:00
public ActionResult ExternalSignature ( string token )
{
2024-04-30 12:18:38 +02:00
if ( token is null )
{
Model . ErrorMessage = "Es ist ein Fehler aufgetreten.<br />Bitte wenden Sie sich an Ihren Administrator" ;
#if DEBUG
Model . ErrorMessage = "Token ist null!" ;
#endif
return View ( Model ) ;
}
try
{
Model . Token = token ;
var info = SecurityUtils . SliceOneTimeLinkToken ( token ) ;
if ( IsTokenExpired ( ) )
{
Model . ErrorMessage = "Der Link ist abgelaufen!" ;
return View ( Model ) ;
}
Model . Tenant = info [ "tenant" ] . ToString ( ) ;
var username = info [ "user" ] . ToString ( ) ;
var serviceRecordOid = long . Parse ( info [ "serviceRecordOid" ] . ToString ( ) ) ;
var session = CreateSessionFromTokenInfo ( ) ;
if ( session is null )
{
return View ( Model ) ;
}
if ( false = = CheckCredentials ( ) )
{
2024-05-03 14:35:33 +02:00
Model . ErrorMessage = "Es ist ein Fehler aufgetreten.<br />Bitte wenden Sie sich an Ihren Administrator." ;
2024-04-30 12:18:38 +02:00
#if DEBUG
2024-05-03 14:35:33 +02:00
//Model.ErrorMessage = $"Es wurde kein Benutzer mit dem Loginnamen {username} gefunden oder das Passwort stimmt nicht überein!";
2024-04-30 12:18:38 +02:00
#endif
return View ( Model ) ;
}
try
{
var serviceRecord = session . CreateCriteria < ServiceRecord > ( )
. Add ( Restrictions . Eq ( nameof ( BeWoEntityBase . Oid ) , serviceRecordOid ) )
. Add ( Restrictions . Eq ( nameof ( BeWoEntityBase . IsActive ) , BS . Shared . ActivationTypeId . Active ) )
. UniqueResult < ServiceRecord > ( ) ;
if ( serviceRecord is null )
{
2024-05-03 14:35:33 +02:00
Model . ErrorMessage = "Es ist ein Fehler aufgetreten.<br />Bitte wenden Sie sich an Ihren Administrator." ;
2024-04-30 12:18:38 +02:00
#if DEBUG
2024-05-03 14:35:33 +02:00
//Model.TestInfo = $"Es wurde kein ServiceRecord mit der Oid {serviceRecordOid} gefunden!";
2024-04-30 12:18:38 +02:00
#endif
return View ( Model ) ;
}
if ( serviceRecord . SignatureOid . HasValue )
{
Model . HasSignatureAlready = true ;
return View ( Model ) ;
}
var auswahlBezeichnung = serviceRecord . CostBearer2SupportConcept . AuswahlBezeichnung ;
var cb2ScStart = serviceRecord . CostBearer2SupportConcept . StartDate ? . ToShortDateString ( ) . Remove ( 6 , 2 ) ? ? string . Empty ;
var cb2ScEnd = serviceRecord . CostBearer2SupportConcept . EndDate ? . ToShortDateString ( ) . Remove ( 6 , 2 ) ? ? string . Empty ;
var costBearerName = serviceRecord . CostBearer2SupportConcept . CostBearer . Organisation . Name ;
var approvalInfo = GetIsNotApproved ( serviceRecord . CostBearer2SupportConcept ) ;
var customerDC = MapperFactory . CompactCustomerDC_Customer . MapToNewDC ( serviceRecord . Customer ) ;
Model . SupportConceptInfo = $"{customerDC.SimpleDescription} {customerDC.DateOfBirthString ?? string.Empty} | {auswahlBezeichnung} {cb2ScStart}-{cb2ScEnd} {costBearerName}{approvalInfo}" ;
Model . ServiceDescriptionInfo = serviceRecord . ServiceDescription . Name ;
Model . CategoryInfo = serviceRecord . ServiceDescription . ServiceCategory . Name ;
Model . EmployeeInfo = serviceRecord . Employee . Person . LastNameFirstName ;
Model . ServiceRecordDateTime = MainModel . GetServiceRecordTimeString ( MapperFactory . ServiceRecordDC_ServiceRecord . MapToNewDC ( serviceRecord ) ) ;
Model . ServiceRecordOid = serviceRecord . Oid ;
Model . CustomerName = customerDC . Name ;
}
catch ( Exception exception )
{
throw exception ;
}
finally
{
session . Close ( ) ;
}
}
catch ( Exception exception )
{
Log . Error ( exception . Message , exception ) ;
Model . ErrorMessage = exception . Message + "<br/><br/>" + exception . StackTrace ;
}
return View ( Model ) ;
}
public string SaveSignature ( string base64Image , DateTime creationDate )
{
try
{
long? oid ;
using ( var signatureBitmap = SignatureUtils . Base64StringToBitmap ( base64Image . Split ( ',' ) [ 1 ] ) )
{
var isValid = SignatureUtils . ValidateSignature ( signatureBitmap ) ;
if ( ! isValid )
{
return "Das Unterschriftenfeld darf nicht leer sein." ;
}
var signature = new Signature
{
DataBild = base64Image ,
IsActive = ActivationTypeId . Active ,
ServiceRecordOid = Model . ServiceRecordOid ,
Zeitstempel = creationDate
} ;
Insert ( signature ) ;
oid = signature . Oid ;
var serviceRecord = LoadServiceRecord ( ) ;
serviceRecord . SignatureOid = signature . Oid ;
var session = CreateSessionFromTokenInfo ( ) ;
if ( session is null )
{
throw new InvalidOperationException ( "Database session is null!" ) ;
}
var transaction = session . BeginTransaction ( ) ;
try
{
BeWo . Service . Core . ServiceLogic . ConcurrencyCheck ( serviceRecord . Version , LoadServiceRecord ( ) ) ;
session . Update ( serviceRecord ) ;
transaction . Commit ( ) ;
transaction = session . BeginTransaction ( ) ;
var previousRecordHistorySignatureInfo = FindMostRecentSignatureStatusInfo ( ) ;
var seviceRecordHistoryEntry = new ServiceRecordHistory
{
TimeStamp = DateTime . Now ,
ChangeType = StatementType . Signature ,
CostBearer2SupportConcept = serviceRecord . CostBearer2SupportConcept ,
CostBearer2SupportConceptOid = serviceRecord . CostBearer2SupportConceptOid ,
Customer = serviceRecord . Customer ,
CustomerOid = serviceRecord . CustomerOid ,
Employee = serviceRecord . Employee ,
EmployeeOid = serviceRecord . EmployeeOid ,
End = serviceRecord . End ,
Group = serviceRecord . Group ,
GroupEmployeeCount = serviceRecord . GroupEmployeeCount ,
GroupOid = serviceRecord . GroupOid ,
GroupPersonCount = serviceRecord . GroupPersonCount ,
GroupRoundedDuration = serviceRecord . GroupRoundedDuration ,
IP = serviceRecord . IP ,
IsActive = serviceRecord . IsActive ,
Notice = serviceRecord . Notice ,
ServiceRecordOid = serviceRecord . Oid ,
RoundedDuration = serviceRecord . RoundedDuration ,
ServiceDescription = serviceRecord . ServiceDescription ,
ServiceRecordType = serviceRecord . ServiceRecordType ,
ServiceRecordInsTs = serviceRecord . InsTs ,
ServiceRecordVersion = serviceRecord . Version . Value ,
ServiceRecordInsUser = serviceRecord . InsUser ,
ServiceRecordUdpUser = serviceRecord . UdpUser ,
Start = serviceRecord . Start ,
SupportConcept = serviceRecord . SupportConcept ,
SystemEntryID = serviceRecord . SystemEntryID ,
DistanceInMeter = serviceRecord . DistanceInMeter ,
IsCreatedInMobileClient = serviceRecord . IsCreatedInMobileClient ,
CustomerConfirmationReceiptSignatureStateType = SignatureStateType . Valid ,
EmployeeConfirmationReceiptSignatureStateType = previousRecordHistorySignatureInfo ? . EmployeeConfirmationReceiptSignatureStateType ? ? SignatureStateType . None ,
ServiceRecordSignatureStateType = previousRecordHistorySignatureInfo ? . ServiceRecordSignatureStateType ? ? SignatureStateType . None ,
CustomerConfirmationReceiptSignatureOid = previousRecordHistorySignatureInfo ? . CustomerConfirmationReceiptSignatureOid ,
EmployeeConfirmationReceiptSignatureOid = previousRecordHistorySignatureInfo ? . EmployeeConfirmationReceiptSignatureOid
} ;
session . Save ( seviceRecordHistoryEntry ) ;
transaction . Commit ( ) ;
}
catch ( Exception exception )
{
transaction . Rollback ( ) ;
throw exception ;
}
finally
{
session . Close ( ) ;
}
}
return oid . HasValue ? "1" : "0" ;
}
catch ( Exception outerException )
{
Log . Error ( outerException . Message , outerException ) ;
return "0" ;
}
}
private void Insert ( BeWoEntityBase entity )
{
try
{
var session = CreateSessionFromTokenInfo ( ) ;
if ( session is null | | false = = CheckCredentials ( ) )
{
throw new InvalidOperationException ( "Database session is null!" ) ;
}
var transaction = session . BeginTransaction ( ) ;
try
{
session . Save ( entity ) ;
transaction . Commit ( ) ;
}
catch ( Exception exception )
{
transaction . Rollback ( ) ;
throw exception ;
}
finally
{
session . Close ( ) ;
}
}
catch ( Exception exception )
{
Log . Error ( exception . Message , exception ) ;
}
}
private SignatureStateInfoFromServiceRecordHistoryEntry FindMostRecentSignatureStatusInfo ( )
{
var session = CreateSessionFromTokenInfo ( ) ;
var sqlQuery = session . CreateSQLQuery ( $"SELECT * FROM ServiceRecordHistory WHERE ServiceRecordOid = {Model.ServiceRecordOid} ORDER BY InsTs DESC LIMIT 1" )
. AddScalar ( "CustomerConfirmationReceiptSignatureStateType" , NHibernateUtil . Int32 )
. AddScalar ( "EmployeeConfirmationReceiptSignatureStateType" , NHibernateUtil . Int32 )
. AddScalar ( "ServiceRecordSignatureStateType" , NHibernateUtil . Int32 )
. AddScalar ( "CustomerConfirmationReceiptSignatureOid" , NHibernateUtil . Int64 )
. AddScalar ( "EmployeeConfirmationReceiptSignatureOid" , NHibernateUtil . Int64 ) ;
var objectsList = sqlQuery . List < object [ ] > ( ) . ToList ( ) ;
var row = objectsList . FirstOrDefault ( ) ;
if ( row is null | | row . Length ! = 5 )
{
return null ;
}
var customerConfirmationReceiptSignatureState = ( SignatureStateType ) row [ 0 ] ;
var employeeConfirmationReceiptSignatureState = ( SignatureStateType ) row [ 1 ] ;
var serviceRecordSignatureStateType = ( SignatureStateType ) row [ 2 ] ;
var customerConfirmationReceiptSignatureOid = ( long? ) row [ 3 ] ;
var employeeConfirmationReceiptSignatureOid = ( long? ) row [ 4 ] ;
return new SignatureStateInfoFromServiceRecordHistoryEntry ( customerConfirmationReceiptSignatureState , employeeConfirmationReceiptSignatureState , serviceRecordSignatureStateType , customerConfirmationReceiptSignatureOid , employeeConfirmationReceiptSignatureOid ) ;
}
private static string GetIsNotApproved ( CostBearer2SupportConcept costBearer2SupportConcept )
{
var result = string . Empty ;
var customer = costBearer2SupportConcept ? . SupportConcept ? . Customer ;
if ( customer ? . TerminationDate . HasValue ? ? false )
{
var terminationReason = string . Empty ;
if ( ! string . IsNullOrEmpty ( customer . TerminationReason . Value ) )
{
terminationReason + = $", Begründung: {customer.TerminationReason}" ;
}
result + = $" (Betreuung beendet am: {customer.TerminationDate:dd.MM.yyyy}{terminationReason})" ;
}
if ( costBearer2SupportConcept ? . ApprovedStartDate is null | | costBearer2SupportConcept . ApprovedEndDate is null )
{
result + = " nicht bewilligt!" ;
}
2024-04-23 17:24:14 +02:00
2024-04-30 12:18:38 +02:00
return result ;
2024-04-18 16:14:20 +02:00
}
}
}