2025-06-05 14:03:55 +02:00
|
|
|
|
using BeWo.Data.Entities;
|
|
|
|
|
|
using BS.Shared;
|
|
|
|
|
|
using BS.Shared.Core;
|
|
|
|
|
|
using BS.Shared.Exceptions;
|
|
|
|
|
|
using BS.Shared.Interface;
|
2025-06-10 14:29:34 +02:00
|
|
|
|
using DevExpress.DataAccess.Native.Web;
|
2025-06-05 14:03:55 +02:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.IO;
|
|
|
|
|
|
using System.Linq;
|
|
|
|
|
|
using System.Runtime.Remoting.Messaging;
|
|
|
|
|
|
using System.Security.Cryptography;
|
|
|
|
|
|
using System.Text;
|
|
|
|
|
|
using System.Threading;
|
|
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
|
using System.Web.UI.WebControls;
|
|
|
|
|
|
using Task = System.Threading.Tasks.Task;
|
|
|
|
|
|
|
|
|
|
|
|
namespace BeWo.Data.Access
|
|
|
|
|
|
{
|
|
|
|
|
|
public class LocalTenantFileStorageDAO
|
|
|
|
|
|
{
|
2025-06-10 14:29:34 +02:00
|
|
|
|
public string Tenant => MultitenancyOperationContextExt.Current?.Tenant ?? throw new BeWoInvalidOperationException(AppError.MultitenancyOperationTenantUnknown);
|
|
|
|
|
|
|
2025-06-05 14:03:55 +02:00
|
|
|
|
private readonly string _rootPath;
|
|
|
|
|
|
|
|
|
|
|
|
public LocalTenantFileStorageDAO(string rootPath)
|
|
|
|
|
|
{
|
|
|
|
|
|
_rootPath = rootPath;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
public string GetXRechnungFileName(long invoicebase_oid)
|
2025-06-05 14:03:55 +02:00
|
|
|
|
{
|
2025-06-10 14:29:34 +02:00
|
|
|
|
return $"invoicebase_{invoicebase_oid}_xrechnung.pdf";
|
2025-06-05 14:03:55 +02:00
|
|
|
|
}
|
2025-06-10 14:29:34 +02:00
|
|
|
|
private string GetFilePath(string filePath)
|
2025-06-05 14:03:55 +02:00
|
|
|
|
{
|
2025-06-10 14:29:34 +02:00
|
|
|
|
return Path.Combine(_rootPath, Tenant, filePath);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
public StoredFile SaveHybridFile(BWPFeature feature, string pFileName, string pContentType, Stream content,
|
|
|
|
|
|
int? pBeWoObjectTid = null, long? pBeWoObjectOid = null, CancellationToken cancellationToken = default)
|
2025-06-05 14:03:55 +02:00
|
|
|
|
{
|
2025-06-10 14:29:34 +02:00
|
|
|
|
// Prüfe Namen
|
|
|
|
|
|
if (SecurityUtils.ContainsInvalidFilenameChars(pFileName))
|
|
|
|
|
|
throw new BeWoInvalidOperationException(AppError.FileNameInvalidChar);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
var lFilePath = Path.Combine(feature.ToString(), pFileName);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
// Prüfe Path
|
|
|
|
|
|
if (Path.GetFileName(lFilePath) != pFileName)
|
|
|
|
|
|
throw new BeWoInvalidOperationException(AppError.FileNameNotEqFilePath);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
// Prüfe Doppelte Belegung
|
|
|
|
|
|
if (DAOFactory.GenericDAO.Exists<StoredFile>(nameof(StoredFile.FilePath), lFilePath))
|
|
|
|
|
|
throw new BeWoInvalidOperationException(AppError.StoredFileAlreadyExists);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
|
|
|
|
|
|
// Erstelle DB Eintrag
|
|
|
|
|
|
var storedfile = new StoredFile();
|
|
|
|
|
|
|
|
|
|
|
|
storedfile.FileName = pFileName;
|
2025-06-10 14:29:34 +02:00
|
|
|
|
storedfile.FilePath = lFilePath;
|
2025-06-05 14:03:55 +02:00
|
|
|
|
storedfile.ContentType = pContentType;
|
|
|
|
|
|
storedfile.BeWoObjectTid = pBeWoObjectTid;
|
|
|
|
|
|
storedfile.BeWoObjectOid = pBeWoObjectOid;
|
|
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
// Speichere FileAsync
|
|
|
|
|
|
storedfile = SaveFileAsync(storedfile, content, cancellationToken).GetAwaiter().GetResult();
|
|
|
|
|
|
|
|
|
|
|
|
// Speichere DB Eintrag
|
|
|
|
|
|
DAOFactory.GenericDAO.Insert(storedfile);
|
|
|
|
|
|
|
|
|
|
|
|
return storedfile;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async Task<StoredFile> SaveFileAsync(StoredFile storedFile, Stream content, CancellationToken cancellationToken = default)
|
|
|
|
|
|
{
|
2025-06-05 14:03:55 +02:00
|
|
|
|
// Erstelle File Ordner
|
2025-06-10 14:29:34 +02:00
|
|
|
|
var path = GetFilePath(storedFile.FilePath);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
var directory = Path.GetDirectoryName(path);
|
|
|
|
|
|
Directory.CreateDirectory(directory);
|
|
|
|
|
|
|
|
|
|
|
|
// Speichere Datei
|
|
|
|
|
|
using (var stream = File.Create(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
await content.CopyToAsync(stream, bufferSize: 81920, cancellationToken).ConfigureAwait(true);
|
2025-06-10 14:29:34 +02:00
|
|
|
|
storedFile.Size = content.Position;
|
|
|
|
|
|
storedFile.Checksum = SecurityUtils.GetChecksumBuffered(content);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
return storedFile;
|
2025-06-05 14:03:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
public IStoredFile GetFileInfo(BWPFeature feature, string pFileName)
|
2025-06-05 14:03:55 +02:00
|
|
|
|
{
|
2025-06-10 14:29:34 +02:00
|
|
|
|
var lFilePath = Path.Combine(feature.ToString(), pFileName);
|
|
|
|
|
|
|
|
|
|
|
|
return GetFileInfo(lFilePath);
|
|
|
|
|
|
}
|
|
|
|
|
|
public IStoredFile GetFileInfo(string filePath)
|
|
|
|
|
|
{
|
|
|
|
|
|
var file = DAOFactory.GenericDAO.GetByProperty<StoredFile>(nameof(StoredFile.FilePath), filePath);
|
|
|
|
|
|
|
|
|
|
|
|
return file;
|
2025-06-05 14:03:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
public Stream GetFileContent(IStoredFile storedFile, CancellationToken cancellationToken = default)
|
2025-06-05 14:03:55 +02:00
|
|
|
|
{
|
2025-06-10 14:29:34 +02:00
|
|
|
|
var path = GetFilePath(storedFile.FilePath);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
if (!File.Exists(path))
|
2025-06-10 14:29:34 +02:00
|
|
|
|
return null;
|
2025-06-05 14:03:55 +02:00
|
|
|
|
|
|
|
|
|
|
Stream stream = File.OpenRead(path);
|
2025-06-10 14:29:34 +02:00
|
|
|
|
return stream;
|
2025-06-05 14:03:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
public bool DeleteFile(IStoredFile storedFile, CancellationToken cancellationToken = default)
|
2025-06-05 14:03:55 +02:00
|
|
|
|
{
|
2025-06-10 14:29:34 +02:00
|
|
|
|
var path = GetFilePath(storedFile.FilePath);
|
2025-06-05 14:03:55 +02:00
|
|
|
|
if (File.Exists(path))
|
|
|
|
|
|
{
|
|
|
|
|
|
File.Delete(path);
|
2025-06-10 14:29:34 +02:00
|
|
|
|
return true;
|
2025-06-05 14:03:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-06-10 14:29:34 +02:00
|
|
|
|
return false;
|
2025-06-05 14:03:55 +02:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|