XRechung StoredFileVM + StoredFileVM.Data

XRechnung wird nach dem Runterladen im Arbeitsspeicher gespiechert
This commit is contained in:
2025-06-25 11:49:36 +02:00
parent fb3303163d
commit bb812665db
9 changed files with 211 additions and 117 deletions

View File

@@ -19,7 +19,7 @@ namespace BeWo.ServiceProxy
[System.ServiceModel.OperationContractAttribute(Action="http://tempuri.org/IAccountingEnhancedService/GetXRechnung", ReplyAction="http://tempuri.org/IAccountingEnhancedService/GetXRechnungResponse")]
[System.ServiceModel.FaultContractAttribute(typeof(BS.Shared.Core.BeWoFault), Action="http://tempuri.org/IAccountingEnhancedService/GetXRechnungBeWoFaultFault", Name="BeWoFault", Namespace="http://schemas.datacontract.org/2004/07/BS.Shared.Core")]
BS.Shared.DataContracts.MikePHPContracts.ApiResponse<byte[]> GetXRechnung(long invoice_base_oid, int report_type, string report_url);
BS.Shared.DataContracts.MikePHPContracts.ApiResponse<System.Tuple<BS.Shared.DataContracts.StoredFileDC, byte[]>> GetXRechnung(long invoice_base_oid, int report_type, string report_url);
}
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
@@ -56,7 +56,7 @@ namespace BeWo.ServiceProxy
{
}
public BS.Shared.DataContracts.MikePHPContracts.ApiResponse<byte[]> GetXRechnung(long invoice_base_oid, int report_type, string report_url)
public BS.Shared.DataContracts.MikePHPContracts.ApiResponse<System.Tuple<BS.Shared.DataContracts.StoredFileDC, byte[]>> GetXRechnung(long invoice_base_oid, int report_type, string report_url)
{
return base.Channel.GetXRechnung(invoice_base_oid, report_type, report_url);
}

View File

@@ -94,12 +94,28 @@ namespace BeWo.ViewModel
if (originalValueProvider != null)
{
bool isDirty = !EqualityComparer<T>.Default.Equals(originalValueProvider(), value);
var isDirty = true;
if(DataContract != null)
{
isDirty = !EqualityComparer<T>.Default.Equals(getSafe(originalValueProvider), value);
}
StoreDirtyInformation(isDirty, propertyName);
}
FirePropertyChanged(propertyName);
return true;
}
private T getSafe<T>(Func<T> originalValueProvider)
{
try
{
return originalValueProvider();
}
catch (Exception e)
{
return default(T);
}
}
}
}

View File

@@ -917,11 +917,12 @@ namespace BeWo.ViewModel
get; set;
}
public StoredFileVM XRechnungStoredFileVM { get; set; }
public long? Oid => DataContract.InvoiceBaseOid;
public string SenderStreet => DataContract.SenderStreet;
public string SenderTown => DataContract.SenderTown;
public string SenderPostCode => DataContract.SenderPostCode;
public StoredFileDC XRechnungStoredFile => DataContract.XRechnungStoredFile;
public IList<IInvoiceItem> IInvoiceItems => throw new NotImplementedException();
@@ -991,6 +992,8 @@ namespace BeWo.ViewModel
IsGkvValid = pDataContract.IsGkvValid;
IsGkvValidError = pDataContract.IsGkvValidError;
IsAlreadyInActiveGkvAbrechnung = pDataContract.IsAlreadyInActiveGkvAbrechnung;
XRechnungStoredFileVM = new StoredFileVM(pDataContract.XRechnungStoredFile);
}
protected override InvoiceBaseDC MapToDataContract(InvoiceBaseDC pDataContract, bool doCommit)

View File

@@ -7,23 +7,25 @@ using BeWo.ServiceProxy;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.Extensions;
using DevExpress.DataAccess.Native.Web;
using DevExpress.Mvvm;
using DevExpress.Xpf.Editors;
using DevExpress.Xpf.Layout.Core;
namespace BeWo.ViewModel.ListViewModel
{
public class InvoiceBaseListVM : AbstractDCListMapperVM<InvoiceBaseDC, InvoiceBaseVM>
{
public static string PropertyName_DateTimeSpanFilter = "DateTimeSpanFilter";
public class InvoiceBaseListVM : AbstractDCListMapperVM<InvoiceBaseDC, InvoiceBaseVM>
{
public static string PropertyName_DateTimeSpanFilter = "DateTimeSpanFilter";
public static string PropertyName_FilterResultAmountSum = "FilterResultAmountSum";
public static string PropertyName_FilterResultAmountNotPaidSum = "FilterResultAmountNotPaidSum";
private DateTimeSpan _DateTimeSpanFilter;
private BindingList<InvoiceBaseVM> _FilteredInvoices;
public static string PropertyName_FilterResultAmountSum = "FilterResultAmountSum";
public static string PropertyName_FilterResultAmountNotPaidSum = "FilterResultAmountNotPaidSum";
public InvoiceBaseListVM(List<InvoiceBaseDC> pDCs) : base(pDCs)
{
private DateTimeSpan _DateTimeSpanFilter;
private BindingList<InvoiceBaseVM> _FilteredInvoices;
public InvoiceBaseListVM(List<InvoiceBaseDC> pDCs) : base(pDCs)
{
VMList.ListChanged += (s, e) => FirePropertyChanged(PropertyName_FilterResultAmountSum);
VMList.ListChanged += (s, e) => FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
@@ -31,64 +33,83 @@ namespace BeWo.ViewModel.ListViewModel
ShowXRechnungCommand = new DelegateCommand(ShowXRechnung, canExecute);
}
public DelegateCommand ShowXRechnungCommand { get; set; }
public DelegateCommand ShowXRechnungCommand { get; set; }
public DateTimeSpan DateTimeSpanFilter
{
get
{
return _DateTimeSpanFilter;
}
set
{
if (AreDifferent(_DateTimeSpanFilter, value))
{
_DateTimeSpanFilter = value;
FirePropertyChanged(PropertyName_DateTimeSpanFilter);
}
}
}
public decimal? FilterResultAmountSum
{
get
{
return VMList.Sum(e => e.TotalAmount);
}
}
public decimal? FilterResultAmountNotPaidSum
{
get
{
decimal? sum = 0.0m;
foreach (var item in VMList)
sum += item.IsPaid ? item.TotalAmount : 0;
return FilterResultAmountSum - sum;
}
}
public void ShowXRechnung()
{
var invoice_base_oid = SelectedVM.DataContract.InvoiceBaseOid ?? -1;
var invoice_type = (int)SelectedVM.DataContract.Type;
var report_link = SelectedVM.ReportLink;
ServiceFacade.DoAccountingEnhancedServiceAsnyc(
x => x.GetXRechnung(invoice_base_oid, invoice_type, report_link),
response =>
{
get
{
if (response.Success)
return _DateTimeSpanFilter;
}
set
{
if (AreDifferent(_DateTimeSpanFilter, value))
{
BeWoApp.MainControl.WindowService.ShowERechnungWindow(new MemoryStream(response.Data));
}
else
{
MessageBox.Show(response.ToErrorString());
_DateTimeSpanFilter = value;
FirePropertyChanged(PropertyName_DateTimeSpanFilter);
}
}
}
public decimal? FilterResultAmountSum
{
get
{
return VMList.Sum(e => e.TotalAmount);
}
}
public decimal? FilterResultAmountNotPaidSum
{
get
{
decimal? sum = 0.0m;
foreach (var item in VMList)
sum += item.IsPaid ? item.TotalAmount : 0;
return FilterResultAmountSum - sum;
}
}
public void ShowXRechnung()
{
var invoice_base = SelectedVM;
// Holt bereits geladene
if (invoice_base.XRechnungStoredFileVM is StoredFileVM vm && vm.Data is byte[] bytes)
{
BeWoApp.MainControl.WindowService.ShowERechnungWindow(new MemoryStream(bytes));
return;
}
// Noch nicht geladen
var invoice_base_dc = invoice_base.DataContract;
var invoice_base_oid = invoice_base_dc.InvoiceBaseOid ?? -1;
var invoice_type = (int)invoice_base_dc.Type;
var report_link = invoice_base.ReportLink;
ServiceFacade.DoAccountingEnhancedServiceAsnyc(
x => x.GetXRechnung(invoice_base_oid, invoice_type, report_link),
response =>
{
if (response.Success)
{
if (response.Data.Item1 is StoredFileDC dc)
{
invoice_base.XRechnungStoredFileVM.UpdateByDataContract(dc);
}
bytes = response.Data.Item2;
invoice_base.XRechnungStoredFileVM.Data = bytes;
BeWoApp.MainControl.WindowService.ShowERechnungWindow(new MemoryStream(bytes));
}
else
{
MessageBox.Show(response.ToErrorString());
}
}
);
}
@@ -101,13 +122,13 @@ namespace BeWo.ViewModel.ListViewModel
FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
}
internal void UpdateList(IList<InvoiceBaseVM> vmList)
{
VMList.Clear();
VMList.AddRange(vmList);
internal void UpdateList(IList<InvoiceBaseVM> vmList)
{
VMList.Clear();
VMList.AddRange(vmList);
FirePropertyChanged(PropertyName_FilterResultAmountSum);
FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
}
}
FirePropertyChanged(PropertyName_FilterResultAmountSum);
FirePropertyChanged(PropertyName_FilterResultAmountNotPaidSum);
}
}
}

View File

@@ -14,8 +14,9 @@ namespace BeWo.ViewModel
private string _Checksum;
private int? _BeWoObjectTid;
private long? _BeWoObjectOid;
private byte[] _Data;
public StoredFileVM(StoredFileDC dc) : base(dc, dc.Oid)
public StoredFileVM(StoredFileDC dc) : base(dc, dc?.Oid)
{
}
@@ -62,8 +63,17 @@ namespace BeWo.ViewModel
set => SetProperty(ref _BeWoObjectOid, value, nameof(BeWoObjectOid), () => DataContract.BeWoObjectOid);
}
public byte[] Data
{
get => _Data;
set => SetProperty(ref _Data, value, nameof(Data));
}
protected override void InitByDataContract(StoredFileDC pDataContract)
{
if (pDataContract is null)
return;
_FileName = pDataContract.FileName;
_FilePath = pDataContract.FilePath;
_ContentType = pDataContract.ContentType;
@@ -85,5 +95,19 @@ namespace BeWo.ViewModel
return pDataContract;
}
public override void UpdateByDataContract(StoredFileDC pDataContract)
{
if (pDataContract is null)
return;
FileName = pDataContract.FileName;
FilePath = pDataContract.FilePath;
ContentType = pDataContract.ContentType;
Size = pDataContract.Size;
Checksum = pDataContract.Checksum;
BeWoObjectTid = pDataContract.BeWoObjectTid;
BeWoObjectOid = pDataContract.BeWoObjectOid;
}
}
}

View File

@@ -1,12 +1,15 @@
using BeWo.Data.Access;
using BeWo.Data.Entities;
using BeWo.Service.Core;
using BeWo.Service.DCEntityMapper;
using BeWo.Service.ServiceImplementations;
using BeWo.Service.ServiceProxy;
using BeWo.Service.ServiceUtils;
using BS.Shared;
using BS.Shared.Core;
using BS.Shared.DataContracts;
using BS.Shared.DataContracts.MikePHPContracts;
using BS.Shared.Interface;
using DevExpress.Export;
using DevExpress.Utils.Filtering.Internal;
using System;
@@ -21,17 +24,21 @@ namespace BeWo.Service.Plugins
{
public class XRechnungService : AbstractIDSpecificDefaultClass<XRechnungService>
{
public ApiResponse<byte[]> GetXRechnung(long invoice_base_oid, int report_type, string report_url)
public ApiResponse<Tuple<StoredFileDC, byte[]>> GetXRechnung(long invoice_base_oid, int report_type, string report_url)
{
// Hole Parameter
var lStoragePath = MergedConfig.GetSetting(WebConfigSetting.StoredTenantFilesFolderPath);
var lStorage = DAOFactory.GetLocalTenantFileStorage(lStoragePath);
var invoice_base = DAOFactory.GenericDAO.LoadByID<InvoiceBase>(invoice_base_oid);
var stored_file = invoice_base.XRechnungStoredFile;
// Falls Lokal vorhanden, gebe lokale Version zurück
if(invoice_base.XRechnungStoredFile?.FileName is string lFileName && tryGetXRechnungLocal(lStorage, lFileName, out var bytes))
return ApiResponse<byte[]>.SuccessResponse(bytes);
if (stored_file?.FileName is string lFileName && tryGetXRechnungLocal(lStorage, lFileName, out var bytes))
{
var stored_file_dc = MapperFactory.StoredFile.MapToNewDC(stored_file);
return ApiResponse<Tuple<StoredFileDC, byte[]>>.SuccessResponse(new Tuple<StoredFileDC, byte[]>(stored_file_dc, bytes));
}
// Lokal nicht vorhanden, berechne XRechnung
var str = ServiceConfigReader.GetInvoiceTestJsonString();
@@ -42,6 +49,50 @@ namespace BeWo.Service.Plugins
return requestXRechnung(lStorage, invoice_base, str, token_url);
}
private ApiResponse<Tuple<StoredFileDC, byte[]>> requestXRechnung(LocalTenantFileStorageDAO pStorage, InvoiceBase invoice_base, object obj, string token_url)
{
var response = ServiceFacade.XRechnung.Create(obj, token_url);
var final_response = new ApiResponse<Tuple<StoredFileDC, byte[]>>();
ApiResponse<byte[]>.CopyTo(response, final_response);
var lFileName = pStorage.GetXRechnungFileName(invoice_base.Oid.Value);
if (response.Success)
{
try
{
var bytes = response.Data;
StoredFile stored_file = null;
using (MemoryStream ms = new MemoryStream(bytes))
{
stored_file = pStorage.SaveHybridFile(BWPFeature.XRechnung, lFileName, "application/pdf", ms, TableID.InvoiceBase, invoice_base.Oid.Value);
invoice_base.XRechnungStoredFile = stored_file;
DAOFactory.GenericDAO.Update(invoice_base);
}
var stored_file_dc = MapperFactory.StoredFile.MapToNewDC(stored_file);
final_response.Data = new Tuple<StoredFileDC, byte[]>(stored_file_dc, bytes);
}
catch (Exception ex)
{
try
{
ServiceHelper.CoreLogger.LogError(ex, nameof(GetXRechnung));
}
catch (Exception ex2)
{
response.ErrorStrings.Add("AccountingEnhancedServiceImp: " + ex2.ToString());
}
response.ErrorStrings.Add("AccountingEnhancedServiceImp: " + ex.ToString());
}
}
return final_response;
}
private string GetTokenUrl(string report_url)
{
string download_url;
@@ -56,43 +107,6 @@ namespace BeWo.Service.Plugins
return token_url;
}
private ApiResponse<byte[]> requestXRechnung(LocalTenantFileStorageDAO pStorage, InvoiceBase invoice_base, object obj, string token_url)
{
// Request
var response = ServiceFacade.XRechnung.Create(obj, token_url);
var lFileName = pStorage.GetXRechnungFileName(invoice_base.Oid.Value);
if (response.Success)
{
try
{
var bytes = response.Data;
using (MemoryStream ms = new MemoryStream(bytes))
{
var file = pStorage.SaveHybridFile(BWPFeature.XRechnung, lFileName, "application/pdf", ms, TableID.InvoiceBase, invoice_base.Oid.Value);
invoice_base.XRechnungStoredFile = file;
DAOFactory.GenericDAO.Update(invoice_base);
}
}
catch (Exception ex)
{
try
{
ServiceHelper.CoreLogger.LogError(ex, nameof(GetXRechnung));
}
catch (Exception ex2)
{
response.ErrorStrings.Add("AccountingEnhancedServiceImp: " + ex2.ToString());
}
response.ErrorStrings.Add("AccountingEnhancedServiceImp: " + ex.ToString());
}
}
return response;
}
private bool tryGetXRechnungLocal(LocalTenantFileStorageDAO pStorage, string pFileName, out byte[] bytes)
{

View File

@@ -19,6 +19,6 @@ namespace BeWo.Service.ServiceContracts.Enhanced
{
[FaultContract(typeof(BeWoFault))]
[OperationContract]
ApiResponse<byte[]> GetXRechnung(long invoice_base_oid, int report_type, string report_url);
ApiResponse<Tuple<StoredFileDC, byte[]>> GetXRechnung(long invoice_base_oid, int report_type, string report_url);
}
}

View File

@@ -33,7 +33,7 @@ namespace BeWo.Service.ServiceImplementations.Enhanced
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Single)]
public class AccountingEnhancedServiceImp : IAccountingEnhancedService
{
public ApiResponse<byte[]> GetXRechnung(long invoice_base_oid, int report_type, string report_url)
public ApiResponse<Tuple<StoredFileDC, byte[]>> GetXRechnung(long invoice_base_oid, int report_type, string report_url)
{
var service = PluginLoader.FindClass<XRechnungService>();
return service.GetXRechnung(invoice_base_oid, report_type, report_url);

View File

@@ -28,6 +28,22 @@ namespace BS.Shared.DataContracts.MikePHPContracts
public bool Success => (Errors?.Count ?? 0) == 0 && (ErrorStrings?.Count ?? 0) == 0;
public ApiResponse()
{
}
public static void CopyTo<Tnew>(ApiResponse<T> from, ApiResponse<Tnew> to)
{
to.Errors = from.Errors;
to.ErrorStrings = from.ErrorStrings;
to.Messages = from.Messages;
to.Meta = from.Meta;
to.TraceId = from.TraceId;
to.Timestamp = from.Timestamp;
to.StatusCode = from.StatusCode;
}
//Factory Methods
public static ApiResponse<T> SuccessResponse(T data, List<string> messages = null, Dictionary<string, object> meta = null)
{