517 lines
21 KiB
C#
517 lines
21 KiB
C#
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;
|
|
|
|
namespace BeWoPlanerMobil.Controllers
|
|
{
|
|
public class ExternalSignatureController : Controller
|
|
{
|
|
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
|
|
{
|
|
if (_Model == null)
|
|
{
|
|
_Model = new ExternalSignatureModel();
|
|
}
|
|
|
|
|
|
//if((ExternalSignatureModel) Session["ExternalSignatureModel"] is null)
|
|
//{
|
|
// _Model = new ExternalSignatureModel();
|
|
// Session["ExternalSignatureModel"] = _Model;
|
|
//}
|
|
//else
|
|
//{
|
|
// _Model = (ExternalSignatureModel) Session["ExternalSignatureModel"];
|
|
//}
|
|
|
|
return _Model ?? new ExternalSignatureModel();
|
|
}
|
|
}
|
|
|
|
private bool IsTokenExpired()
|
|
{
|
|
if(Model?.Token is null)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
try
|
|
{
|
|
var info = SecurityUtils.SliceOneTimeLinkToken(Model.Token);
|
|
|
|
if(info.ContainsKey("expirationDate") && DateTime.TryParse(info["expirationDate"]?.ToString(), out var expirationDate))
|
|
{
|
|
return expirationDate < DateTime.Now;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
catch(Exception exception)
|
|
{
|
|
Log.Error(exception.Message, exception);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
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
|
|
//Model.ErrorMessage = $"Es wurde kein Benutzer mit dem Loginnamen {username} gefunden oder das Passwort stimmt nicht überein!";
|
|
#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
|
|
//Model.ErrorMessage = "Die .config-Datei wurde nicht gefunden!";
|
|
#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;
|
|
}
|
|
}
|
|
|
|
public ActionResult ExternalSignature(string token)
|
|
{
|
|
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())
|
|
{
|
|
Model.ErrorMessage = "Es ist ein Fehler aufgetreten.<br />Bitte wenden Sie sich an Ihren Administrator.";
|
|
#if DEBUG
|
|
//Model.ErrorMessage = $"Es wurde kein Benutzer mit dem Loginnamen {username} gefunden oder das Passwort stimmt nicht überein!";
|
|
#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)
|
|
{
|
|
Model.ErrorMessage = "Es ist ein Fehler aufgetreten.<br />Bitte wenden Sie sich an Ihren Administrator.";
|
|
|
|
#if DEBUG
|
|
//Model.TestInfo = $"Es wurde kein ServiceRecord mit der Oid {serviceRecordOid} gefunden!";
|
|
#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!";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
} |