Refactor EKÁER: support multi-doc declarations
Refactored EKÁER declaration logic to allow one EkaerHistory to reference multiple source documents via a new EkaerHistoryMapping junction table. Removed ForeignKey from EkaerHistory and updated all usages to use the Mappings collection. Updated service, controller, SignalR, and client interfaces to operate by EkaerHistoryId. Adjusted grid UI to display all mapped source IDs. Added EkaerHistoryMapping entity and updated documentation, constants, and ToonDescription attributes accordingly.
This commit is contained in:
parent
2221d4a68e
commit
973c8030d2
|
|
@ -74,7 +74,8 @@
|
||||||
"WebFetch(domain:net.jogtar.hu)",
|
"WebFetch(domain:net.jogtar.hu)",
|
||||||
"WebFetch(domain:www.itrack.hu)",
|
"WebFetch(domain:www.itrack.hu)",
|
||||||
"WebFetch(domain:docplayer.hu)",
|
"WebFetch(domain:docplayer.hu)",
|
||||||
"WebFetch(domain:supportcenter.devexpress.com)"
|
"WebFetch(domain:supportcenter.devexpress.com)",
|
||||||
|
"PowerShell($c = Get-Command claude -ErrorAction SilentlyContinue; if \\($c\\) { $c.Source; & claude --help 2>&1 | Select-Object -First 90 } else { \"claude not on PATH\" })"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -37,19 +37,23 @@ public sealed class FruitBankEkaerService : IFruitBankEkaerService
|
||||||
return _submitService.SubmitAsync(operations, cancellationToken);
|
return _submitService.SubmitAsync(operations, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EkaerHistory GenerateEkaerXmlDocument(ShippingDocument document, EkaerHistory? ekaerHistory = null)
|
public EkaerHistory GenerateEkaerXmlDocument(IReadOnlyCollection<ShippingDocument> documents, EkaerHistory? ekaerHistory = null)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(document);
|
ArgumentNullException.ThrowIfNull(documents);
|
||||||
ekaerHistory ??= new EkaerHistory { ForeignKey = document.Id, IsOutgoing = false };
|
if (documents.Count == 0) throw new ArgumentException("documents is empty", nameof(documents));
|
||||||
|
ekaerHistory ??= new EkaerHistory { IsOutgoing = false };
|
||||||
|
|
||||||
var currency = document.Partner?.Currency;
|
// A csoport azonos Partneré (a kapu így csoportosít) → az első dokumentum pénzneme a mérvadó.
|
||||||
return TryConfigError(ekaerHistory, currency) ?? Finalize(ekaerHistory, _mapper.MapDocument(document, _settings.Company), currency);
|
var currency = documents.First().Partner?.Currency;
|
||||||
|
// A csoport ÖSSZES dokumentuma EGY tradeCard-dá (összevont tömeg/érték): ToConsignment → BuildTradeCard.
|
||||||
|
var tradeCard = _mapper.BuildTradeCard(_mapper.ToConsignment(documents, _settings.Company));
|
||||||
|
return TryConfigError(ekaerHistory, currency) ?? Finalize(ekaerHistory, tradeCard, currency);
|
||||||
}
|
}
|
||||||
|
|
||||||
public EkaerHistory GenerateEkaerXmlDocument(OrderDto order, EkaerHistory? ekaerHistory = null)
|
public EkaerHistory GenerateEkaerXmlDocument(OrderDto order, EkaerHistory? ekaerHistory = null)
|
||||||
{
|
{
|
||||||
ArgumentNullException.ThrowIfNull(order);
|
ArgumentNullException.ThrowIfNull(order);
|
||||||
ekaerHistory ??= new EkaerHistory { ForeignKey = order.Id, IsOutgoing = true };
|
ekaerHistory ??= new EkaerHistory { IsOutgoing = true };
|
||||||
|
|
||||||
// Kimenő pénznem: jelenleg minden HUF (a deviza az OrderDto-ba kerül, amint bekötik) → ConversionRate = 1.
|
// Kimenő pénznem: jelenleg minden HUF (a deviza az OrderDto-ba kerül, amint bekötik) → ConversionRate = 1.
|
||||||
const string currency = "HUF";
|
const string currency = "HUF";
|
||||||
|
|
|
||||||
|
|
@ -20,14 +20,14 @@ public interface IFruitBankEkaerService
|
||||||
Task<EkaerSubmitResult> SubmitShippingAsync(Shipping shipping, OperationType operation = OperationType.Create, CancellationToken cancellationToken = default);
|
Task<EkaerSubmitResult> SubmitShippingAsync(Shipping shipping, OperationType operation = OperationType.Create, CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Egy szállítólevélből legenerálja az EKÁER tradeCard XML-t és validálja — a (meglévő vagy új)
|
/// Egy szállítólevél-CSOPORTBÓL (egy EKÁER-egység dokumentumai) legenerálja az EKÁER tradeCard XML-t és validálja — a (meglévő vagy új)
|
||||||
/// <see cref="EkaerHistory"/> rekordot tölti: <c>XmlDoc</c> + <c>Status</c>
|
/// <see cref="EkaerHistory"/> rekordot tölti: <c>XmlDoc</c> + <c>Status</c>
|
||||||
/// (<see cref="EkaerStatus.Generated"/> / <see cref="EkaerStatus.ValidationError"/>) + <c>ErrorText</c>.
|
/// (<see cref="EkaerStatus.Generated"/> / <see cref="EkaerStatus.ValidationError"/>) + <c>ErrorText</c>.
|
||||||
/// NEM perzisztál és NEM hív NAV-ot — a mentés (upsert) a hívó SignalR endpoint dolga.
|
/// NEM perzisztál és NEM hív NAV-ot — a mentés (upsert) a hívó SignalR endpoint dolga.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="document">A szállítólevél a betöltött gráffal (Partner, Items+ProductDto, Shipping→járművek).</param>
|
/// <param name="documents">A deklarációhoz tartozó szállítólevél-CSOPORT (egy (Shipping, Partner, PartnerDepot) egység) a betöltött gráffal (Partner, Items+ProductDto, Shipping→járművek) — összevont tömeggel/értékkel EGY tradeCard.</param>
|
||||||
/// <param name="ekaerHistory">A dokumentum meglévő rekordja (újrageneráláskor); <c>null</c> → új rekord készül.</param>
|
/// <param name="ekaerHistory">A csoport meglévő rekordja (újrageneráláskor); <c>null</c> → új rekord készül.</param>
|
||||||
EkaerHistory GenerateEkaerXmlDocument(ShippingDocument document, EkaerHistory? ekaerHistory = null);
|
EkaerHistory GenerateEkaerXmlDocument(IReadOnlyCollection<ShippingDocument> documents, EkaerHistory? ekaerHistory = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Egy kimenő rendelésből (<see cref="OrderDto"/>) legenerálja az EKÁER tradeCard XML-t és validálja —
|
/// Egy kimenő rendelésből (<see cref="OrderDto"/>) legenerálja az EKÁER tradeCard XML-t és validálja —
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -33,6 +33,7 @@ public static class FruitBankConstClient
|
||||||
public const string PartnerDepotDbTableName = "fbPartnerDepot";
|
public const string PartnerDepotDbTableName = "fbPartnerDepot";
|
||||||
|
|
||||||
public const string EkaerHistoryDbTableName = "fbEkaerHistory";
|
public const string EkaerHistoryDbTableName = "fbEkaerHistory";
|
||||||
|
public const string EkaerHistoryMappingDbTableName = "fbEkaerHistoryMapping";
|
||||||
|
|
||||||
public const string OrderItemPalletDbTableName = "fbOrderItemPallet";
|
public const string OrderItemPalletDbTableName = "fbOrderItemPallet";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ public interface IFruitBankDataControllerCommon
|
||||||
public Task<List<EkaerHistory>?> GetEkaerHistoriesByForeignKey(int foreignKey);
|
public Task<List<EkaerHistory>?> GetEkaerHistoriesByForeignKey(int foreignKey);
|
||||||
public Task<EkaerHistory?> AddEkaerHistory(EkaerHistory ekaerHistory);
|
public Task<EkaerHistory?> AddEkaerHistory(EkaerHistory ekaerHistory);
|
||||||
public Task<EkaerHistory?> UpdateEkaerHistory(EkaerHistory ekaerHistory);
|
public Task<EkaerHistory?> UpdateEkaerHistory(EkaerHistory ekaerHistory);
|
||||||
public Task<EkaerHistory?> GenerateEkaerXmlDocument(int foreignKey, bool isOutgoing);
|
public Task<EkaerHistory?> GenerateEkaerXmlDocument(int ekaerHistoryId);
|
||||||
public Task<EkaerHistory?> CreateEkaerHistory(int foreignKey, bool isOutgoing);
|
public Task<EkaerHistory?> CreateEkaerHistory(int foreignKey, bool isOutgoing);
|
||||||
public Task<EkaerCreateResult?> CreateMissingEkaerHistories(DateTime fromDate);
|
public Task<EkaerCreateResult?> CreateMissingEkaerHistories(DateTime fromDate);
|
||||||
public Task<int> GetEkaerHistoryCount(EkaerHistoryFilter filter);
|
public Task<int> GetEkaerHistoryCount(EkaerHistoryFilter filter);
|
||||||
|
|
|
||||||
|
|
@ -41,8 +41,9 @@ namespace FruitBankHybrid.Shared.Tests
|
||||||
|
|
||||||
Assert.IsNotNull(ekaerHistory, $"shippingDocument.Id: {shippingDocument.Id}");
|
Assert.IsNotNull(ekaerHistory, $"shippingDocument.Id: {shippingDocument.Id}");
|
||||||
Assert.IsGreaterThan(0, ekaerHistory.Id, $"shippingDocument.Id: {shippingDocument.Id}");
|
Assert.IsGreaterThan(0, ekaerHistory.Id, $"shippingDocument.Id: {shippingDocument.Id}");
|
||||||
Assert.AreEqual(shippingDocument.Id, ekaerHistory.ForeignKey);
|
|
||||||
Assert.IsFalse(ekaerHistory.IsOutgoing);
|
Assert.IsFalse(ekaerHistory.IsOutgoing);
|
||||||
|
Assert.IsNotNull(ekaerHistory.Mappings, $"Mappings null (loadRelations?); shippingDocument.Id: {shippingDocument.Id}");
|
||||||
|
Assert.AreEqual(shippingDocument.Id, ekaerHistory.Mappings.Single().ForeignKey, $"A mapping nem a forrás-dokumentumra mutat; shippingDocument.Id: {shippingDocument.Id}");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Idempotencia: a második hívás a meglévőt adja vissza, nem duplikál.
|
// Idempotencia: a második hívás a meglévőt adja vissza, nem duplikál.
|
||||||
|
|
@ -73,15 +74,18 @@ namespace FruitBankHybrid.Shared.Tests
|
||||||
|
|
||||||
foreach (var shippingDocument in shippingDocuments)
|
foreach (var shippingDocument in shippingDocuments)
|
||||||
{
|
{
|
||||||
var ekaerHistory = await _signalRClient.GenerateEkaerXmlDocument(shippingDocument.Id, false);
|
// A generálás mostantól EkaerHistory-Id alapú → előbb a (mapping-elt) rekordot hozzuk létre.
|
||||||
|
var created = await _signalRClient.CreateEkaerHistory(shippingDocument.Id, false);
|
||||||
|
Assert.IsNotNull(created, $"CreateEkaerHistory null; shippingDocument.Id: {shippingDocument.Id}");
|
||||||
|
var ekaerHistory = await _signalRClient.GenerateEkaerXmlDocument(created.Id);
|
||||||
|
|
||||||
// A szerver által visszaadott állapot/hibalista logolása — az assertek ELŐTT, hogy hibánál is látsszon.
|
// A szerver által visszaadott állapot/hibalista logolása — az assertek ELŐTT, hogy hibánál is látsszon.
|
||||||
Console.WriteLine($"doc#{shippingDocument.Id}: Status: {(ekaerHistory == null ? "NULL VÁLASZ!" : ekaerHistory.Status.ToString())}");
|
Console.WriteLine($"doc#{shippingDocument.Id}: Status: {(ekaerHistory == null ? "NULL VÁLASZ!" : ekaerHistory.Status.ToString())}");
|
||||||
if (!string.IsNullOrWhiteSpace(ekaerHistory?.ErrorText)) Console.WriteLine($" ErrorText: {ekaerHistory.ErrorText}");
|
if (!string.IsNullOrWhiteSpace(ekaerHistory?.ErrorText)) Console.WriteLine($" ErrorText: {ekaerHistory.ErrorText}");
|
||||||
|
|
||||||
Assert.IsNotNull(ekaerHistory, $"shippingDocument.Id: {shippingDocument.Id}");
|
Assert.IsNotNull(ekaerHistory, $"shippingDocument.Id: {shippingDocument.Id}");
|
||||||
Assert.AreEqual(shippingDocument.Id, ekaerHistory.ForeignKey);
|
|
||||||
Assert.IsFalse(ekaerHistory.IsOutgoing);
|
Assert.IsFalse(ekaerHistory.IsOutgoing);
|
||||||
|
Assert.AreEqual(shippingDocument.Id, ekaerHistory.Mappings!.Single().ForeignKey, $"A mapping nem a forrás-dokumentumra mutat; shippingDocument.Id: {shippingDocument.Id}");
|
||||||
Assert.IsFalse(string.IsNullOrWhiteSpace(ekaerHistory.XmlDoc), $"XmlDoc üres; shippingDocument.Id: {shippingDocument.Id}");
|
Assert.IsFalse(string.IsNullOrWhiteSpace(ekaerHistory.XmlDoc), $"XmlDoc üres; shippingDocument.Id: {shippingDocument.Id}");
|
||||||
Assert.IsTrue(ekaerHistory.Status is EkaerStatus.Generated or EkaerStatus.ValidationError,
|
Assert.IsTrue(ekaerHistory.Status is EkaerStatus.Generated or EkaerStatus.ValidationError,
|
||||||
$"Status: {ekaerHistory.Status}; shippingDocument.Id: {shippingDocument.Id}; ErrorText: {ekaerHistory.ErrorText}");
|
$"Status: {ekaerHistory.Status}; shippingDocument.Id: {shippingDocument.Id}; ErrorText: {ekaerHistory.ErrorText}");
|
||||||
|
|
@ -105,8 +109,12 @@ namespace FruitBankHybrid.Shared.Tests
|
||||||
|
|
||||||
var shippingDocumentId = shippingDocuments[0].Id;
|
var shippingDocumentId = shippingDocuments[0].Id;
|
||||||
|
|
||||||
var first = await _signalRClient.GenerateEkaerXmlDocument(shippingDocumentId, false);
|
// Generálás EkaerHistory-Id alapján → előbb a rekord (mapping-gel), majd kétszeri generálás ugyanarra az Id-ra.
|
||||||
var second = await _signalRClient.GenerateEkaerXmlDocument(shippingDocumentId, false);
|
var created = await _signalRClient.CreateEkaerHistory(shippingDocumentId, false);
|
||||||
|
Assert.IsNotNull(created);
|
||||||
|
|
||||||
|
var first = await _signalRClient.GenerateEkaerXmlDocument(created.Id);
|
||||||
|
var second = await _signalRClient.GenerateEkaerXmlDocument(created.Id);
|
||||||
|
|
||||||
Assert.IsNotNull(first);
|
Assert.IsNotNull(first);
|
||||||
Assert.IsNotNull(second);
|
Assert.IsNotNull(second);
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,25 @@
|
||||||
OnGridFocusedRowChanged="Grid_FocusedRowChanged">
|
OnGridFocusedRowChanged="Grid_FocusedRowChanged">
|
||||||
<Columns>
|
<Columns>
|
||||||
<DxGridDataColumn FieldName="Id" SortIndex="0" SortOrder="GridColumnSortOrder.Descending" ReadOnly="true" />
|
<DxGridDataColumn FieldName="Id" SortIndex="0" SortOrder="GridColumnSortOrder.Descending" ReadOnly="true" />
|
||||||
<DxGridDataColumn FieldName="@nameof(EkaerHistory.ForeignKey)" ReadOnly="true" />
|
<DxGridDataColumn Caption="ForeignKey(s)" AllowSort="false" AllowGroup="false">
|
||||||
<DxGridDataColumn FieldName="@nameof(EkaerHistory.IsOutgoing)" ReadOnly="true" />
|
@* A lefedett forrás-rekordok (ShippingDocument/Order Id-k) a betöltött Mappings-ből összefűzve —
|
||||||
|
egyből látszik, ha több dokumentum van egy EKÁER-deklaráció alá vonva. *@
|
||||||
|
<CellDisplayTemplate>
|
||||||
|
@{
|
||||||
|
var row = (EkaerHistory)context.DataItem;
|
||||||
|
}
|
||||||
|
@if (row.Mappings is { Count: > 0 } maps)
|
||||||
|
{
|
||||||
|
var noun = row.IsOutgoing ? "rendelés" : "szállítólevél";
|
||||||
|
<span title="@(maps.Count > 1 ? $"{maps.Count} {noun} egy EKÁER alá vonva" : $"1 {noun}")">@string.Join(", ", maps.Select(m => $"#{m.ForeignKey}"))</span>
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
<span>—</span>
|
||||||
|
}
|
||||||
|
</CellDisplayTemplate>
|
||||||
|
</DxGridDataColumn>
|
||||||
|
<DxGridDataColumn FieldName="@nameof(EkaerHistory.IsOutgoing)" Caption="Kimenő?" ReadOnly="true" />
|
||||||
@* A kézi NAV-beadás fázisában a Status / EKÁER szám / SentDate kézzel szerkeszthető. *@
|
@* A kézi NAV-beadás fázisában a Status / EKÁER szám / SentDate kézzel szerkeszthető. *@
|
||||||
<DxGridDataColumn FieldName="@nameof(EkaerHistory.Status)" />
|
<DxGridDataColumn FieldName="@nameof(EkaerHistory.Status)" />
|
||||||
<DxGridDataColumn FieldName="@nameof(EkaerHistory.EkaerNumber)" Caption="EKÁER szám" />
|
<DxGridDataColumn FieldName="@nameof(EkaerHistory.EkaerNumber)" Caption="EKÁER szám" />
|
||||||
|
|
@ -209,11 +226,11 @@
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var updated = await FruitBankSignalRClient.GenerateEkaerXmlDocument(ekaerHistory.ForeignKey, ekaerHistory.IsOutgoing);
|
var updated = await FruitBankSignalRClient.GenerateEkaerXmlDocument(ekaerHistory.Id);
|
||||||
|
|
||||||
if (updated == null)
|
if (updated == null)
|
||||||
{
|
{
|
||||||
_logger.Error($"GenerateEkaerXmlDocument null választ adott; ForeignKey: {ekaerHistory.ForeignKey}");
|
_logger.Error($"GenerateEkaerXmlDocument null választ adott; EkaerHistory #{ekaerHistory.Id}");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -228,7 +245,7 @@
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
_logger.Error($"GenerateEkaerXmlDocument hiba; ForeignKey: {ekaerHistory.ForeignKey}", ex);
|
_logger.Error($"GenerateEkaerXmlDocument hiba; EkaerHistory #{ekaerHistory.Id}", ex);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -37,9 +37,11 @@ public class GridEkaerHistoryBase : FruitBankGridBase<EkaerHistory>, IGrid
|
||||||
{
|
{
|
||||||
if (ContextIds == null || ContextIds.Length == 0) ContextIds = [ParentDataItem!.Id];
|
if (ContextIds == null || ContextIds.Length == 0) ContextIds = [ParentDataItem!.Id];
|
||||||
|
|
||||||
// A ForeignKey általános (Shipping/Order stb.) — bármely szülőnél a ForeignKey-re szűrünk.
|
// Detail-mód: a forrás-rekord (Shipping/Order/ShippingDocument) EKÁER-deklarációi a mappingen át.
|
||||||
|
// Megj.: az EkaerHistory már NEM hordoz per-szülő mezőt (a kapcsolat az EkaerHistoryMapping junctionben él),
|
||||||
|
// ezért a kliens-oldali KeyFieldNameToParentId itt nem alkalmazható — a szerver-oldali szűrés
|
||||||
|
// (GetEkaerHistoriesByForeignKey → mapping) adja a szülőhöz tartozó sorokat. (Jelenleg nincs detail-használat.)
|
||||||
GetAllMessageTag = SignalRTags.GetEkaerHistoriesByForeignKey;
|
GetAllMessageTag = SignalRTags.GetEkaerHistoriesByForeignKey;
|
||||||
if (KeyFieldNameToParentId.IsNullOrWhiteSpace()) KeyFieldNameToParentId = nameof(EkaerHistory.ForeignKey);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
await base.OnInitializedAsync();
|
await base.OnInitializedAsync();
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ namespace FruitBankHybrid.Shared.Services.SignalRs
|
||||||
public Task<List<EkaerHistory>?> GetEkaerHistoriesByForeignKey(int foreignKey) => GetAllAsync<List<EkaerHistory>>(SignalRTags.GetEkaerHistoriesByForeignKey, [foreignKey]);
|
public Task<List<EkaerHistory>?> GetEkaerHistoriesByForeignKey(int foreignKey) => GetAllAsync<List<EkaerHistory>>(SignalRTags.GetEkaerHistoriesByForeignKey, [foreignKey]);
|
||||||
public Task<EkaerHistory?> AddEkaerHistory(EkaerHistory ekaerHistory) => PostDataAsync(SignalRTags.AddEkaerHistory, ekaerHistory);
|
public Task<EkaerHistory?> AddEkaerHistory(EkaerHistory ekaerHistory) => PostDataAsync(SignalRTags.AddEkaerHistory, ekaerHistory);
|
||||||
public Task<EkaerHistory?> UpdateEkaerHistory(EkaerHistory ekaerHistory) => PostDataAsync(SignalRTags.UpdateEkaerHistory, ekaerHistory);
|
public Task<EkaerHistory?> UpdateEkaerHistory(EkaerHistory ekaerHistory) => PostDataAsync(SignalRTags.UpdateEkaerHistory, ekaerHistory);
|
||||||
public Task<EkaerHistory?> GenerateEkaerXmlDocument(int foreignKey, bool isOutgoing) => GetByIdAsync<EkaerHistory?>(SignalRTags.GenerateEkaerXmlDocument, [foreignKey, isOutgoing]);
|
public Task<EkaerHistory?> GenerateEkaerXmlDocument(int ekaerHistoryId) => GetByIdAsync<EkaerHistory?>(SignalRTags.GenerateEkaerXmlDocument, ekaerHistoryId);
|
||||||
public Task<EkaerHistory?> CreateEkaerHistory(int foreignKey, bool isOutgoing) => GetByIdAsync<EkaerHistory?>(SignalRTags.CreateEkaerHistory, [foreignKey, isOutgoing]);
|
public Task<EkaerHistory?> CreateEkaerHistory(int foreignKey, bool isOutgoing) => GetByIdAsync<EkaerHistory?>(SignalRTags.CreateEkaerHistory, [foreignKey, isOutgoing]);
|
||||||
public Task<EkaerCreateResult?> CreateMissingEkaerHistories(DateTime fromDate) => GetByIdAsync<EkaerCreateResult?>(SignalRTags.CreateMissingEkaerHistories, fromDate);
|
public Task<EkaerCreateResult?> CreateMissingEkaerHistories(DateTime fromDate) => GetByIdAsync<EkaerCreateResult?>(SignalRTags.CreateMissingEkaerHistories, fromDate);
|
||||||
public Task<int> GetEkaerHistoryCount(EkaerHistoryFilter filter) => GetByIdAsync<int>(SignalRTags.GetEkaerHistoryCount, filter);
|
public Task<int> GetEkaerHistoryCount(EkaerHistoryFilter filter) => GetByIdAsync<int>(SignalRTags.GetEkaerHistoryCount, filter);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue