From a2b22e8bf28dca52b5b51e70cb1c696625a5c2cf Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 5 Jan 2026 09:13:37 +0100 Subject: [PATCH 01/14] small fixes and android build changes --- FruitBank.Common/Dtos/OrderItemDto.cs | 3 +- FruitBank.Common/FruitBankConstClient.cs | 6 +- .../Components/GridShippingItemTemplate.razor | 425 +++++++++--------- FruitBankHybrid.Shared/Layout/NavMenu.razor | 2 +- .../FruitBankHybrid.Web.Client.csproj | 2 +- .../FruitBankHybrid.Web.csproj | 2 +- FruitBankHybrid/FruitBankHybrid.csproj | 10 +- .../Platforms/Windows/Package.appxmanifest | 2 +- FruitBankHybrid/fruitbank.keystore | Bin 0 -> 2750 bytes 9 files changed, 230 insertions(+), 222 deletions(-) create mode 100644 FruitBankHybrid/fruitbank.keystore diff --git a/FruitBank.Common/Dtos/OrderItemDto.cs b/FruitBank.Common/Dtos/OrderItemDto.cs index 59fb1d5a..1a8f9c54 100644 --- a/FruitBank.Common/Dtos/OrderItemDto.cs +++ b/FruitBank.Common/Dtos/OrderItemDto.cs @@ -92,8 +92,7 @@ public class OrderItemDto : MgOrderItemDto, IOrderItemDto public double AverageWeightDifference => IsMeasurable ? double.Round(ProductDto!.AverageWeight - AverageWeight, 1) : 0; [NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore] - public bool AverageWeightIsValid => !IsMeasurable || - (ProductDto!.AverageWeight > 0 && ((AverageWeightDifference / ProductDto!.AverageWeight) * 100) < ProductDto!.AverageWeightTreshold); + public bool AverageWeightIsValid => !IsMeasurable || (ProductDto!.AverageWeight > 0 && Math.Abs((AverageWeightDifference / ProductDto!.AverageWeight) * 100) < ProductDto!.AverageWeightTreshold); [NotColumn, NotMapped, JsonIgnore, System.Text.Json.Serialization.JsonIgnore] public bool IsAudited => OrderItemPallets.Count > 0 && OrderItemPallets.All(oip => oip.IsAudited); diff --git a/FruitBank.Common/FruitBankConstClient.cs b/FruitBank.Common/FruitBankConstClient.cs index a90f6ad6..f47072e8 100644 --- a/FruitBank.Common/FruitBankConstClient.cs +++ b/FruitBank.Common/FruitBankConstClient.cs @@ -7,11 +7,11 @@ public static class FruitBankConstClient { public static string DefaultLocale = "en-US"; - public static string BaseUrl = "https://localhost:59579"; //FrutiBank nop + //public static string BaseUrl = "https://localhost:59579"; //FrutiBank nop //public static string BaseUrl = "https://localhost:44372"; //FrutiBank nop - //public static string BaseUrl = "https://shop.fruitbank.hu"; //FrutiBank nop + public static string BaseUrl = "https://shop.fruitbank.hu"; //FrutiBank nop #if RELEASE - // public static string BaseUrl = "https://shop.fruitbank.hu"; //FrutiBank nop + //public static string BaseUrl = "https://shop.fruitbank.hu"; //FrutiBank nop #endif //public static string BaseUrl = "http://localhost:59579"; //FrutiBank nop diff --git a/FruitBankHybrid.Shared/Components/GridShippingItemTemplate.razor b/FruitBankHybrid.Shared/Components/GridShippingItemTemplate.razor index 665ba232..afd365c0 100644 --- a/FruitBankHybrid.Shared/Components/GridShippingItemTemplate.razor +++ b/FruitBankHybrid.Shared/Components/GridShippingItemTemplate.razor @@ -17,79 +17,80 @@ @inject FruitBankSignalRClient FruitBankSignalRClient - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - + - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - + + + - - + + + - - - - - @* + + + + + @* @{ if (context.DataColumn.FieldName == nameof(ShippingItem.ShippingDocumentId)) { @@ -103,185 +104,185 @@ } *@ - @{ - var shippingItemPallets = ((ShippingItem)context.DataItem).ShippingItemPallets; - - } - - - @if (IsMasterGrid) - { - - } - - - - - - - - + @{ + var shippingItemPallets = ((ShippingItem)context.DataItem).ShippingItemPallets; + + } + + + @if (IsMasterGrid) + { + + } + + + + + + + + @code { - //[Inject] public required ObjectLock ObjectLock { get; set; } - [Inject] public required DatabaseClient Database { get; set; } + //[Inject] public required ObjectLock ObjectLock { get; set; } + [Inject] public required DatabaseClient Database { get; set; } - //[Parameter] public int GetAllMessageTag { get; set; } - [Parameter] public IId? ParentDataItem { get; set; } + //[Parameter] public int GetAllMessageTag { get; set; } + [Parameter] public IId? ParentDataItem { get; set; } - [Parameter] public IEnumerable? ProductDtos { get; set; } - [Parameter] public AcObservableCollection? ShippingItems { get; set; } - [Parameter] public AcObservableCollection? ShippingDocuments { get; set; } + [Parameter] public IEnumerable? ProductDtos { get; set; } + [Parameter] public AcObservableCollection? ShippingItems { get; set; } + [Parameter] public AcObservableCollection? ShippingDocuments { get; set; } - public bool IsMasterGrid => ParentDataItem == null; - public bool ParentDataItemIsShippingDocument => (ParentDataItem is ShippingDocument); - string GridCss => !IsMasterGrid ? "hide-toolbar" : string.Empty; + public bool IsMasterGrid => ParentDataItem == null; + public bool ParentDataItemIsShippingDocument => (ParentDataItem is ShippingDocument); + string GridCss => !IsMasterGrid ? "hide-toolbar" : string.Empty; - MgGridToolbarTemplate toolbar; + MgGridToolbarTemplate toolbar; - const string ExportFileName = "ExportResult"; - string _localStorageKey = "GridShippingItem_"; + const string ExportFileName = "ExportResult"; + string _localStorageKey = "GridShippingItem_"; - string GridSearchText = ""; - bool EditItemsEnabled { get; set; } = true; - int FocusedRowVisibleIndex { get; set; } + string GridSearchText = ""; + bool EditItemsEnabled { get; set; } = true; + int FocusedRowVisibleIndex { get; set; } - public GridShippingItemBase Grid { get; set; } - private LoggerClient _logger; + public GridShippingItemBase Grid { get; set; } + private LoggerClient _logger; - protected override async Task OnInitializedAsync() - { - _logger = new LoggerClient(LogWriters.ToArray()); + protected override async Task OnInitializedAsync() + { + _logger = new LoggerClient(LogWriters.ToArray()); - await ReloadDataFromDb(false); - } + await ReloadDataFromDb(false); + } - public async Task ReloadDataFromDb(bool forceReload = false) - { - //using (await ObjectLock.GetSemaphore().UseWaitAsync()) - { - if (ProductDtos == null || !ProductDtos.Any() || forceReload) ProductDtos = await Database.ProductDtoTable.LoadDataAsync(!forceReload); - } + public async Task ReloadDataFromDb(bool forceReload = false) + { + //using (await ObjectLock.GetSemaphore().UseWaitAsync()) + { + if (ProductDtos == null || !ProductDtos.Any() || forceReload) ProductDtos = await Database.ProductDtoTable.LoadDataAsync(!forceReload); + } - if (!IsMasterGrid) - { - if (ShippingDocuments == null && ParentDataItem is ShippingDocument shippingDocumentParent) ShippingDocuments = [shippingDocumentParent]; - return; - } + if (!IsMasterGrid) + { + if (ShippingDocuments == null && ParentDataItem is ShippingDocument shippingDocumentParent) ShippingDocuments = [shippingDocumentParent]; + return; + } - using (await ObjectLock.GetSemaphore().UseWaitAsync()) - { - if (ShippingDocuments == null) - { - ShippingDocuments = new AcObservableCollection(await FruitBankSignalRClient.GetShippingDocuments() ?? []); - } - else if (ShippingDocuments.Count == 0 || forceReload) - { - ShippingDocuments.Replace(await FruitBankSignalRClient.GetShippingDocuments() ?? []); - } - } + using (await ObjectLock.GetSemaphore().UseWaitAsync()) + { + if (ShippingDocuments == null) + { + ShippingDocuments = new AcObservableCollection(await FruitBankSignalRClient.GetShippingDocuments() ?? []); + } + else if (ShippingDocuments.Count == 0 || forceReload) + { + ShippingDocuments.Replace(await FruitBankSignalRClient.GetShippingDocuments() ?? []); + } + } - if (Grid == null) return; + if (Grid == null) return; - using (await ObjectLock.GetSemaphore().UseWaitAsync()) - if (forceReload) await Grid.ReloadDataSourceAsync(); + using (await ObjectLock.GetSemaphore().UseWaitAsync()) + if (forceReload) await Grid.ReloadDataSourceAsync(); - if (forceReload) Grid.Reload(); - } + if (forceReload) Grid.Reload(); + } - static void Grid_CustomizeElement(GridCustomizeElementEventArgs e) - { - if (e.ElementType != GridElementType.DataCell) return; + static void Grid_CustomizeElement(GridCustomizeElementEventArgs e) + { + if (e.ElementType != GridElementType.DataCell) return; - if (e.Column.Name != nameof(ShippingItem.MeasuredNetWeight) && - e.Column.Name != nameof(ShippingItem.MeasuredGrossWeight) && - e.Column.Name != nameof(ShippingItem.MeasuredQuantity)) return; + if (e.Column.Name != nameof(ShippingItem.MeasuredNetWeight) && + e.Column.Name != nameof(ShippingItem.MeasuredGrossWeight) && + e.Column.Name != nameof(ShippingItem.MeasuredQuantity)) return; - var isMeasured = (bool)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.IsMeasured)); - if (!isMeasured) return; + var isMeasured = (bool)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.IsMeasured)); + if (!isMeasured) return; - switch (e.Column.Name) - { - case nameof(ShippingItem.MeasuredNetWeight) or nameof(ShippingItem.MeasuredGrossWeight): - { - var isMeasurable = (bool)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.IsMeasurable)); - if (!isMeasurable) return; + switch (e.Column.Name) + { + case nameof(ShippingItem.MeasuredNetWeight) or nameof(ShippingItem.MeasuredGrossWeight): + { + var isMeasurable = (bool)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.IsMeasurable)); + if (!isMeasurable) return; - var valueOnDocument = 0d; - var measuredValue = 0d; + var valueOnDocument = 0d; + var measuredValue = 0d; - if (e.Column.Name == nameof(ShippingItem.MeasuredGrossWeight)) - { - valueOnDocument = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.GrossWeightOnDocument)); - measuredValue = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredGrossWeight)); - } - else - { - valueOnDocument = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.NetWeightOnDocument)); - measuredValue = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredNetWeight)); - } + if (e.Column.Name == nameof(ShippingItem.MeasuredGrossWeight)) + { + valueOnDocument = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.GrossWeightOnDocument)); + measuredValue = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredGrossWeight)); + } + else + { + valueOnDocument = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.NetWeightOnDocument)); + measuredValue = (double)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredNetWeight)); + } - if (valueOnDocument > 0 && valueOnDocument > measuredValue) e.CssClass = "text-danger"; - //else if (valueOnDocument <= measuredValue) e.CssClass = "text-success"; + if (valueOnDocument > 0 && valueOnDocument > measuredValue) e.CssClass = "text-danger"; + else if (valueOnDocument > 0 && valueOnDocument < measuredValue) e.CssClass = "text-success"; - break; - } - case nameof(ShippingItem.MeasuredQuantity): - { - var quantityOnDocument = (int)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.QuantityOnDocument)); - var measuredQuantity = (int)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredQuantity)); + break; + } + case nameof(ShippingItem.MeasuredQuantity): + { + var quantityOnDocument = (int)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.QuantityOnDocument)); + var measuredQuantity = (int)e.Grid.GetRowValue(e.VisibleIndex, nameof(ShippingItem.MeasuredQuantity)); - if (quantityOnDocument > 0 && quantityOnDocument > measuredQuantity) e.CssClass = "text-danger"; - //else if (quantityOnDocument <= measuredQuantity) e.CssClass = "text-success"; - break; - } - } - } + if (quantityOnDocument > 0 && quantityOnDocument > measuredQuantity) e.CssClass = "text-danger"; + //else if (quantityOnDocument <= measuredQuantity) e.CssClass = "text-success"; + break; + } + } + } - async Task Grid_FocusedRowChanged(GridFocusedRowChangedEventArgs args) - { - if ((args.Grid.IsEditing() || args.Grid.IsEditingNewRow()) && (args.DataItem as IId).Id > 0) - await args.Grid.SaveChangesAsync(); + async Task Grid_FocusedRowChanged(GridFocusedRowChangedEventArgs args) + { + if ((args.Grid.IsEditing() || args.Grid.IsEditingNewRow()) && (args.DataItem as IId).Id > 0) + await args.Grid.SaveChangesAsync(); - if (toolbar != null) - { - var shippingItem = (args.DataItem as ShippingItem)!; - toolbar.EnableDelete = shippingItem.MeasuringStatus == MeasuringStatus.NotStarted; + if (toolbar != null) + { + var shippingItem = (args.DataItem as ShippingItem)!; + toolbar.EnableDelete = shippingItem.MeasuringStatus == MeasuringStatus.NotStarted; - } + } - FocusedRowVisibleIndex = args.VisibleIndex; - EditItemsEnabled = true; - } + FocusedRowVisibleIndex = args.VisibleIndex; + EditItemsEnabled = true; + } - async Task Grid_DataItemDeleting(GridDataItemDeletingEventArgs e) - { - } + async Task Grid_DataItemDeleting(GridDataItemDeletingEventArgs e) + { + } - async Task Grid_EditModelSaving(GridEditModelSavingEventArgs e) - { - ShippingItem? resultShippingItem = null; + async Task Grid_EditModelSaving(GridEditModelSavingEventArgs e) + { + ShippingItem? resultShippingItem = null; - if (!e.IsNew) - { - resultShippingItem = await FruitBankSignalRClient.UpdateShippingItem((ShippingItem)e.EditModel); - } - else - { - resultShippingItem = await FruitBankSignalRClient.AddShippingItem((ShippingItem)e.EditModel); - EditItemsEnabled = true; - } + if (!e.IsNew) + { + resultShippingItem = await FruitBankSignalRClient.UpdateShippingItem((ShippingItem)e.EditModel); + } + else + { + resultShippingItem = await FruitBankSignalRClient.AddShippingItem((ShippingItem)e.EditModel); + EditItemsEnabled = true; + } - // if (resultShippingItem != null) - // ShippingItems!.UpdateCollection(resultShippingItem, false); + // if (resultShippingItem != null) + // ShippingItems!.UpdateCollection(resultShippingItem, false); - EditItemsEnabled = true; - } + EditItemsEnabled = true; + } } \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Layout/NavMenu.razor b/FruitBankHybrid.Shared/Layout/NavMenu.razor index b2a2d3c2..03b90813 100644 --- a/FruitBankHybrid.Shared/Layout/NavMenu.razor +++ b/FruitBankHybrid.Shared/Layout/NavMenu.razor @@ -37,7 +37,7 @@ - @if (LoggedInModel.IsDeveloper) + @if (LoggedInModel.IsAdministrator) { - + @for (var index = 0; index < (SelectedStockTakingItem?.StockTakingItemPallets?.Count ?? 0); index++) { @@ -70,6 +70,7 @@ x.Id == resultStockTaking.Id)); + + await InvokeAsync(StateHasChanged); } private async Task StockTakingComboValueChanged(StockTaking? newValue) @@ -163,7 +166,7 @@ SelectedStockTakingItem = _stockTakingItems.FirstOrDefault(); - StateHasChanged(); + await InvokeAsync(StateHasChanged); } private void PrepareStockTakingItems(StockTaking? stockTaking) diff --git a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor index f17b4bf4..0695ff03 100644 --- a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor +++ b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor @@ -127,7 +127,7 @@ else { string? orderNote; - if (!(orderNote = SelectedOrder?.OrderNotes.LastOrDefault(x=>x.Note.StartsWith('*'))?.Note).IsNullOrWhiteSpace()) + if (!(orderNote = SelectedOrder?.OrderNotes.LastOrDefault(x => x.Note.StartsWith('*'))?.Note).IsNullOrWhiteSpace()) {
Megjegyzés: @(orderNote) @@ -159,7 +159,8 @@ var isValid = selectedOrderItemDto.IsValidMeasuringValues(); var isValidAndMeasured = isValid && selectedOrderItemDto.IsMeasuredAndValid(); // && selectedOrderItemDto.; - if (isValidAndMeasured) cssClass = "text-success"; + if (isValid && !selectedOrderItemDto.AverageWeightIsValid) cssClass = "text-warning"; + else if (isValidAndMeasured) cssClass = "text-success"; else if (isValid) cssClass = string.Empty; var displayText = $"{selectedOrderItemDto.ProductName} - [{trayQuantity}/{selectedOrderItemDto.Quantity} rekesz, {(selectedOrderItemDto.IsMeasurable ? "net.súly: " + selectedOrderItemDto.NetWeight + "kg." : "nem mérendő!")}]"; diff --git a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs index 8f00139c..8b8bc8e7 100644 --- a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs +++ b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs @@ -326,6 +326,10 @@ namespace FruitBankHybrid.Shared.Services.SignalRs throw new NotImplementedException(); } + public Task CloseStockTaking(int stockTakingId) + => PostDataAsync(SignalRTags.CloseStockTaking, stockTakingId); + + public async Task AddStockTakingItemPallet(StockTakingItemPallet stockTakingItemPallet) { throw new NotImplementedException(); From 650a6f3773bc5f73b2515efeadc8a6b4b60bf4b2 Mon Sep 17 00:00:00 2001 From: Loretta Date: Mon, 12 Jan 2026 07:20:50 +0100 Subject: [PATCH 05/14] Update PalletItemComponent to use 'Editable' parameter Replaced 'IsEditable' with 'Editable' in PalletItemComponent usage within StockTakingTemplate.razor and MeasuringOut.razor to align with updated component API. Editability logic remains unchanged. --- .../Components/StockTakings/StockTakingTemplate.razor | 2 +- FruitBankHybrid.Shared/Pages/MeasuringOut.razor | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor b/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor index 28b49d93..b76731df 100644 --- a/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor +++ b/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor @@ -70,7 +70,7 @@ Date: Fri, 16 Jan 2026 13:54:49 +0100 Subject: [PATCH 06/14] File hash, isCompressed, set current date as default --- FruitBank.Common/Entities/Files.cs | 3 ++- FruitBank.Common/Entities/Shipping.cs | 2 +- FruitBank.Common/Entities/ShippingDocument.cs | 2 +- FruitBankHybrid.Shared/Components/GridShippingDocument.razor | 4 ++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/FruitBank.Common/Entities/Files.cs b/FruitBank.Common/Entities/Files.cs index 34d626a2..aef8544d 100644 --- a/FruitBank.Common/Entities/Files.cs +++ b/FruitBank.Common/Entities/Files.cs @@ -11,7 +11,8 @@ public class Files : MgEntityBase, IFiles public string FileName { get; set; } public string FileExtension { get; set; } public string RawText { get; set; } - + public string FileHash { get; set; } + public bool IsCompressed { get; set; } [SkipValuesOnUpdate] public DateTime Created { get; set; } diff --git a/FruitBank.Common/Entities/Shipping.cs b/FruitBank.Common/Entities/Shipping.cs index c15aa779..704e893a 100644 --- a/FruitBank.Common/Entities/Shipping.cs +++ b/FruitBank.Common/Entities/Shipping.cs @@ -8,7 +8,7 @@ namespace FruitBank.Common.Entities; [System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDbTableName)] public class Shipping : MgEntityBase, IShipping { - public DateTime ShippingDate { get; set; } + public DateTime ShippingDate { get; set; } = DateTime.Now; public string LicencePlate { get; set; } public bool IsAllMeasured { get; set; } diff --git a/FruitBank.Common/Entities/ShippingDocument.cs b/FruitBank.Common/Entities/ShippingDocument.cs index 4ca89b89..c3e256dc 100644 --- a/FruitBank.Common/Entities/ShippingDocument.cs +++ b/FruitBank.Common/Entities/ShippingDocument.cs @@ -14,7 +14,7 @@ public class ShippingDocument : MgEntityBase, IShippingDocument public string DocumentIdNumber { get; set; } public string PdfFileName { get; set; } - public DateTime ShippingDate { get; set; } + public DateTime ShippingDate { get; set; } = DateTime.Now; public string Country { get; set; } public int TotalPallets { get; set; } diff --git a/FruitBankHybrid.Shared/Components/GridShippingDocument.razor b/FruitBankHybrid.Shared/Components/GridShippingDocument.razor index 40491569..faa475a9 100644 --- a/FruitBankHybrid.Shared/Components/GridShippingDocument.razor +++ b/FruitBankHybrid.Shared/Components/GridShippingDocument.razor @@ -47,7 +47,7 @@ - + From 328f906a3040463986c083a7a1b5e20707bbe764 Mon Sep 17 00:00:00 2001 From: Loretta Date: Sat, 24 Jan 2026 10:19:36 +0100 Subject: [PATCH 07/14] Add FileSubPath to Files; improve PDF rendering logic Added FileSubPath property to Files entity and IFiles interface for sub-path storage. Updated IFiles to include FileHash and IsCompressed. Refactored GridShippingDocumentInfoPanel.razor to select and render PDFs only when associated files exist, with improved type checks and null handling. Performed minor code cleanup. --- FruitBank.Common/Entities/Files.cs | 1 + FruitBank.Common/Interfaces/IFiles.cs | 3 +++ .../GridShippingDocumentInfoPanel.razor | 26 +++++++++++++------ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/FruitBank.Common/Entities/Files.cs b/FruitBank.Common/Entities/Files.cs index aef8544d..bae6a05a 100644 --- a/FruitBank.Common/Entities/Files.cs +++ b/FruitBank.Common/Entities/Files.cs @@ -9,6 +9,7 @@ namespace FruitBank.Common.Entities; public class Files : MgEntityBase, IFiles { public string FileName { get; set; } + public string FileSubPath { get; set; } public string FileExtension { get; set; } public string RawText { get; set; } public string FileHash { get; set; } diff --git a/FruitBank.Common/Interfaces/IFiles.cs b/FruitBank.Common/Interfaces/IFiles.cs index 9ff7cfc4..cd3329f5 100644 --- a/FruitBank.Common/Interfaces/IFiles.cs +++ b/FruitBank.Common/Interfaces/IFiles.cs @@ -6,6 +6,9 @@ namespace FruitBank.Common.Interfaces; public interface IFiles: IEntityInt, ITimeStampInfo { public string FileName { get; set; } + public string FileSubPath { get; set; } public string FileExtension { get; set; } public string RawText { get; set; } + public string FileHash { get; set; } + public bool IsCompressed { get; set; } } \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor b/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor index 9a0cc4d2..b20b4eac 100644 --- a/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor +++ b/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor @@ -94,7 +94,7 @@ { private readonly string[] _pdfFiles = [ - "1_Albaran_AH25007715.pdf", + "1_Albaran_AH25007715.pdf", "2_BANK FRA.pdf", "3_BP-30M35_20251113_163816.pdf" ]; @@ -110,16 +110,26 @@ private async Task OnDataItemChangedAsync(object? dataItem) { - @if (dataItem is not ShippingDocument && dataItem is not ShippingItem) return; + if (dataItem is not ShippingDocument && dataItem is not ShippingItem) return; - // Store the PDF to render - _randomPdf = _pdfFiles[Random.Shared.Next(_pdfFiles.Length)]; - _currentPdfToRender = $"_content/FruitBankHybrid.Shared/uploads/{_randomPdf}"; + ShippingDocument? shippingDocument = null; + + if (dataItem is ShippingItem shippingItem) shippingDocument = shippingItem.ShippingDocument; + else shippingDocument = dataItem as ShippingDocument; - // If MgLazyLoadContent is already visible, render the PDF immediately - if (_lazyContentRef is { IsVisible: true }) + if (shippingDocument == null) return; + + if (shippingDocument.ShippingDocumentToFiles?.Count > 0) { - await _lazyContentRef.TriggerContentVisibleAsync(); + // Store the PDF to render + _randomPdf = _pdfFiles[Random.Shared.Next(_pdfFiles.Length)]; + _currentPdfToRender = $"_content/FruitBankHybrid.Shared/uploads/{_randomPdf}"; + + // If MgLazyLoadContent is already visible, render the PDF immediately + if (_lazyContentRef is { IsVisible: true }) + { + await _lazyContentRef.TriggerContentVisibleAsync(); + } } } From 0343f7b677579bfe009139e957fbebdb2d8c47cc Mon Sep 17 00:00:00 2001 From: Loretta Date: Fri, 6 Feb 2026 22:27:04 +0100 Subject: [PATCH 08/14] Update schema compare: add tmp tables, set MARS to False Updated connection strings to explicitly set Multiple Active Result Sets (MARS) to False for both DEV and PROD databases. Added dbo.tmp_guestsAddressesToDelete and dbo.tmp_guestsToDelete tables to the schema comparison selection. --- SqlSchemaCompare_Dev_to_Prod.scmp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/SqlSchemaCompare_Dev_to_Prod.scmp b/SqlSchemaCompare_Dev_to_Prod.scmp index 96d28c06..f22fcf7e 100644 --- a/SqlSchemaCompare_Dev_to_Prod.scmp +++ b/SqlSchemaCompare_Dev_to_Prod.scmp @@ -3,12 +3,12 @@ 10 - Data Source=195.26.231.218;Initial Catalog=FruitBank_DEV;Integrated Security=False;Persist Security Info=False;User ID=sa;Pooling=False;Trust Server Certificate=True + Data Source=195.26.231.218;Initial Catalog=FruitBank_DEV;Integrated Security=False;Persist Security Info=False;User ID=sa;Pooling=False;Multiple Active Result Sets=False;Trust Server Certificate=True - Data Source=195.26.231.218;Initial Catalog=FruitBank_PROD;Integrated Security=False;Persist Security Info=False;User ID=sa;Pooling=False;Trust Server Certificate=True + Data Source=195.26.231.218;Initial Catalog=FruitBank_PROD;Integrated Security=False;Persist Security Info=False;User ID=sa;Pooling=False;Multiple Active Result Sets=False;Trust Server Certificate=True @@ -1105,5 +1105,13 @@ dbo DF_fbShipping_IsAllMeasured + + dbo + tmp_guestsAddressesToDelete + + + dbo + tmp_guestsToDelete + \ No newline at end of file From 5604f1e33832de608565cf5d64dc52a28d57b9bc Mon Sep 17 00:00:00 2001 From: Loretta Date: Sat, 7 Feb 2026 08:55:00 +0100 Subject: [PATCH 09/14] Improve toolbar controls and async UX in stock taking - Added EnableNew and EnableEdit parameters to MgGridToolbarTemplate for finer control of toolbar button states. - Disabled "New", "Edit", and "Delete" actions in history and item grids by passing explicit parameters. - Introduced DxLoadingPanel in StockTakingTemplate for better async feedback. - Disabled "New" and "Close" buttons during async operations to prevent duplicates. - Enhanced combo boxes with search/filter and usability features. - Updated new/close stock taking logic to show loading, handle errors, and prevent duplicate actions. - Set focus to item combo box after saving a StockTakingItemPallet. - Removed global loading panel from StockTaking.razor; loading is now handled locally. - Performed minor code cleanups and removed obsolete code. --- .../GridStockQuantityHistoryDtoTemplate.razor | 2 +- .../GridStockTakingItem.razor | 2 +- .../StockTakings/StockTakingTemplate.razor | 109 ++++++++++++++---- .../Pages/StockTaking.razor | 8 -- 4 files changed, 88 insertions(+), 33 deletions(-) diff --git a/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDtoTemplate.razor b/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDtoTemplate.razor index cb56f7c4..c2118fa6 100644 --- a/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDtoTemplate.razor +++ b/FruitBankHybrid.Shared/Components/Grids/Products/GridStockQuantityHistoryDtoTemplate.razor @@ -48,7 +48,7 @@ @if (IsMasterGrid) { - + } @* diff --git a/FruitBankHybrid.Shared/Components/Grids/StockTakingItems/GridStockTakingItem.razor b/FruitBankHybrid.Shared/Components/Grids/StockTakingItems/GridStockTakingItem.razor index 951bae92..868288d5 100644 --- a/FruitBankHybrid.Shared/Components/Grids/StockTakingItems/GridStockTakingItem.razor +++ b/FruitBankHybrid.Shared/Components/Grids/StockTakingItems/GridStockTakingItem.razor @@ -48,7 +48,7 @@ @if (IsMasterGrid) { - + } diff --git a/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor b/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor index b76731df..92504c87 100644 --- a/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor +++ b/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor @@ -12,10 +12,19 @@ @using FruitBankHybrid.Shared.Services.SignalRs @using Mango.Nop.Core.Entities + + @* CaptionCssClass="@(SelectedProductDto?.IsMeasured == true ? "text-success" : "")"> *@ - + InputId="cbProduct2" + SearchMode="ListSearchMode.AutoSearch" + SearchFilterCondition="ListSearchFilterCondition.Contains" + SearchTextParseMode="ListSearchTextParseMode.Default" + ClearButtonDisplayMode="DataEditorClearButtonDisplayMode.Auto" + DropDownTriggerMode="DropDownTriggerMode.Click" + @ref="cbStockTakingItems"> @* TextFieldName="StockTakingItem.Product.Name" *@ - + - +@* - - + *@ + @@ -95,6 +110,7 @@ }
+ @code { @@ -103,6 +119,12 @@ [Inject] public required IDialogService DialogService { get; set; } = null!; [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } + bool _btnDisabled = false; + bool LoadingPanelVisible = false; + + DxComboBox cbStockTakings; + DxComboBox cbStockTakingItems; + List _stockTakings { get; set; } = []; List _stockTakingItems { get; set; } = []; List _stockTakingItemPallets { get; set; } = []; @@ -116,25 +138,44 @@ public async Task ReloadDataFromDb(bool forceReload) { - LoadingPanelVisibility.Visible = true; + LoadingPanelVisible = true; _stockTakings = await FruitBankSignalRClient.GetStockTakings(false) ?? []; await StockTakingComboValueChanged(_stockTakings.FirstOrDefault()); - LoadingPanelVisibility.Visible = false; + LoadingPanelVisible = false; } private async Task NewStockTakingClick() { - var stockTaking = new StockTaking(); - stockTaking.StartDateTime = DateTime.Now; - stockTaking.Creator = LoggedInModel.CustomerDto!.Id; + _btnDisabled = true; - var resultStockTakings = await FruitBankSignalRClient.AddStockTaking(stockTaking); - if (resultStockTakings == null) return; + try + { + LoadingPanelVisible = true; - _stockTakings.UpdateCollection(resultStockTakings, false); - await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(x => x.Id == stockTaking.Id)); + var stockTaking = new StockTaking(); + stockTaking.StartDateTime = DateTime.Now; + stockTaking.Creator = LoggedInModel.CustomerDto!.Id; + + var resultStockTakings = await FruitBankSignalRClient.AddStockTaking(stockTaking); + if (resultStockTakings == null) + { + await DialogService.ShowMessageBoxAsync("Hiba", "Új leltár létrehozása sikertelen volt!", MessageBoxRenderStyle.Danger); + return; + } + + _stockTakings.UpdateCollection(resultStockTakings, false); + await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(x => x.Id == resultStockTakings.Id)); + } + finally + { + _btnDisabled = false; + LoadingPanelVisible = false; + } + + //cbStockTakings.Reload(); + await InvokeAsync(StateHasChanged); } private async Task UpdateStockTakingClick() @@ -148,11 +189,27 @@ private async Task StockTakingCloseClick(int stockTakingId) { - var resultStockTaking = await FruitBankSignalRClient.CloseStockTaking(stockTakingId); - if (resultStockTaking == null) return; + _btnDisabled = true; - _stockTakings.UpdateCollection(resultStockTaking, false); - await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(x => x.Id == resultStockTaking.Id)); + try + { + LoadingPanelVisible = true; + + var resultStockTaking = await FruitBankSignalRClient.CloseStockTaking(stockTakingId); + if (resultStockTaking == null) + { + await DialogService.ShowMessageBoxAsync("Hiba", "A leltár lezárása sikertelen volt, ellenőrizze a leltár adatait!", MessageBoxRenderStyle.Danger); + return; + } + + _stockTakings.UpdateCollection(resultStockTaking, false); + await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(x => x.Id == resultStockTaking.Id)); + } + finally + { + _btnDisabled = false; + LoadingPanelVisible = false; + } await InvokeAsync(StateHasChanged); } @@ -161,7 +218,7 @@ { SelectedStockTaking = newValue; SelectedStockTaking?.StockTakingItems = await FruitBankSignalRClient.GetStockTakingItemsByStockTakingId(SelectedStockTaking.Id); - + PrepareStockTakingItems(SelectedStockTaking); SelectedStockTakingItem = _stockTakingItems.FirstOrDefault(); @@ -194,19 +251,22 @@ } } - private Task OnStockTakingItemPalletValueChanged(StockTakingItemPallet stockTakingItemPallet, StockTakingItem stockTakingItem) + private async Task OnStockTakingItemPalletValueChanged(StockTakingItemPallet stockTakingItemPallet, StockTakingItem stockTakingItem) { // MeasuringValuesHelper.SetShippingItemTotalMeasuringValues(stockTakingItem); // BtnSaveEnabled = stockTakingItem.IsValidMeasuringValues() && stockTakingItemPallet.IsValidMeasuringValues(stockTakingItem.IsMeasurable); - StateHasChanged(); - return Task.CompletedTask; + //cbStockTakingItems.Reload(); + await InvokeAsync(StateHasChanged); + //return Task.CompletedTask; } private async Task OnStockTakingItemPalletSaved(StockTakingItemPallet? responseStockTakingItemPallet) { if (responseStockTakingItemPallet != null) { + //responseStockTakingItemPallet.IsMeasured = true; + responseStockTakingItemPallet.StockTakingItem = SelectedStockTakingItem; SelectedStockTakingItem!.MeasuredStockQuantity = responseStockTakingItemPallet.TrayQuantity; @@ -219,7 +279,10 @@ } else await DialogService.ShowMessageBoxAsync("Hiba", "Adatok mentése sikertelen volt, ellenőrizze a mérés adatait!", MessageBoxRenderStyle.Danger); + //cbStockTakingItems.Reload(); await InvokeAsync(StateHasChanged); + + await cbStockTakingItems.FocusAsync(); } } diff --git a/FruitBankHybrid.Shared/Pages/StockTaking.razor b/FruitBankHybrid.Shared/Pages/StockTaking.razor index 19e1c0ce..50731605 100644 --- a/FruitBankHybrid.Shared/Pages/StockTaking.razor +++ b/FruitBankHybrid.Shared/Pages/StockTaking.razor @@ -10,12 +10,6 @@
- - @@ -31,6 +25,4 @@ } - -
\ No newline at end of file From a7387f88cfc49433c84cd50d6a9e6bd34ee5329b Mon Sep 17 00:00:00 2001 From: Adam Date: Wed, 11 Feb 2026 01:19:08 +0100 Subject: [PATCH 10/14] baseurl --- .../Grids/ShippingDocuments/AiProcessFormTemplate.razor | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/AiProcessFormTemplate.razor b/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/AiProcessFormTemplate.razor index 8f2fb077..2c31cc10 100644 --- a/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/AiProcessFormTemplate.razor +++ b/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/AiProcessFormTemplate.razor @@ -1,4 +1,6 @@ - -@code { +@using FruitBank.Common + +@code { + public string baseUrl = FruitBankConstClient.BaseUrl + "/Admin/FileManager/ImageTextExtraction"; } From 73ee9fade1312664da9f9a436bd472b22ad2cc27 Mon Sep 17 00:00:00 2001 From: Loretta Date: Mon, 23 Feb 2026 18:04:43 +0100 Subject: [PATCH 11/14] Enhance grids: add links, format dates, show modifiers - Made ID columns clickable links to related edit pages - Added ModifierId and Modified columns to item/pallet grids - Applied consistent date formatting ("yyyy.MM.dd hh:mm") - Updated usings for required namespaces - Cleaned up lazy loading code and added null checks for safety --- .../Components/GridDetailOrderDto.razor | 10 +++++----- .../Components/GridDetailOrderItemDto.razor | 5 +++-- .../Components/GridDetailOrderItemPallets.razor | 5 +++++ .../Components/GridShippingItemPallets.razor | 10 +++++++++- .../GridShippingDocumentInfoPanel.razor | 11 ++++++----- 5 files changed, 28 insertions(+), 13 deletions(-) diff --git a/FruitBankHybrid.Shared/Components/GridDetailOrderDto.razor b/FruitBankHybrid.Shared/Components/GridDetailOrderDto.razor index 5d222e98..3d87187f 100644 --- a/FruitBankHybrid.Shared/Components/GridDetailOrderDto.razor +++ b/FruitBankHybrid.Shared/Components/GridDetailOrderDto.razor @@ -20,7 +20,7 @@ - + @@ -31,10 +31,10 @@ - - - - + + + + diff --git a/FruitBankHybrid.Shared/Components/GridDetailOrderItemDto.razor b/FruitBankHybrid.Shared/Components/GridDetailOrderItemDto.razor index 97a9668d..333e4e89 100644 --- a/FruitBankHybrid.Shared/Components/GridDetailOrderItemDto.razor +++ b/FruitBankHybrid.Shared/Components/GridDetailOrderItemDto.razor @@ -1,6 +1,7 @@ @using AyCode.Blazor.Components.Components.Grids @using AyCode.Core.Helpers @using AyCode.Utils.Extensions +@using FruitBank.Common @using FruitBank.Common.Dtos @using FruitBank.Common.Models @using FruitBankHybrid.Shared.Components.Grids.GenericAttributes @@ -18,7 +19,7 @@ FilterMenuButtonDisplayMode="@(IsMasterGrid ? GridFilterMenuButtonDisplayMode.Never : GridFilterMenuButtonDisplayMode.Always)"> - + @@ -49,7 +50,7 @@ - + diff --git a/FruitBankHybrid.Shared/Components/GridDetailOrderItemPallets.razor b/FruitBankHybrid.Shared/Components/GridDetailOrderItemPallets.razor index 4eff31bf..752983a8 100644 --- a/FruitBankHybrid.Shared/Components/GridDetailOrderItemPallets.razor +++ b/FruitBankHybrid.Shared/Components/GridDetailOrderItemPallets.razor @@ -1,5 +1,6 @@ @using AyCode.Blazor.Components.Components.Grids @using AyCode.Utils.Extensions +@using FruitBank.Common @using FruitBank.Common.Dtos @using FruitBank.Common.Entities @using FruitBank.Common.Models @@ -32,6 +33,10 @@ + + + + diff --git a/FruitBankHybrid.Shared/Components/GridShippingItemPallets.razor b/FruitBankHybrid.Shared/Components/GridShippingItemPallets.razor index 291c2864..dd2fd44a 100644 --- a/FruitBankHybrid.Shared/Components/GridShippingItemPallets.razor +++ b/FruitBankHybrid.Shared/Components/GridShippingItemPallets.razor @@ -1,10 +1,14 @@ -@using AyCode.Utils.Extensions +@using AyCode.Blazor.Components.Components.Grids +@using AyCode.Utils.Extensions +@using FruitBank.Common @using FruitBank.Common.Dtos @using FruitBank.Common.Entities +@using FruitBank.Common.Models @using FruitBankHybrid.Shared.Databases @using FruitBankHybrid.Shared.Services.SignalRs @inject FruitBankSignalRClient FruitBankSignalRClient +@inject LoggedInModel LoggedInModel + + + + diff --git a/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor b/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor index b20b4eac..9fb5e487 100644 --- a/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor +++ b/FruitBankHybrid.Shared/Components/Grids/ShippingDocuments/GridShippingDocumentInfoPanel.razor @@ -72,15 +72,16 @@ } -
-
- + *@ + + @*
@@ -113,13 +114,13 @@ if (dataItem is not ShippingDocument && dataItem is not ShippingItem) return; ShippingDocument? shippingDocument = null; - + if (dataItem is ShippingItem shippingItem) shippingDocument = shippingItem.ShippingDocument; else shippingDocument = dataItem as ShippingDocument; if (shippingDocument == null) return; - if (shippingDocument.ShippingDocumentToFiles?.Count > 0) + if (_lazyContentRef != null && shippingDocument.ShippingDocumentToFiles?.Count > 0) { // Store the PDF to render _randomPdf = _pdfFiles[Random.Shared.Next(_pdfFiles.Length)]; From 288b81f8f5fcb7f05dd8edd4cba91d35e633b212 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 2 Mar 2026 12:14:20 +0100 Subject: [PATCH 12/14] shipping updates --- .../FruitBank.Common.Server.csproj | 4 +++- FruitBank.Common/Entities/Shipping.cs | 7 +++++-- .../Components/Grids/Shippings/GridShipping.razor | 13 +++++++------ FruitBankHybrid/FruitBankHybrid.csproj | 2 +- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/FruitBank.Common.Server/FruitBank.Common.Server.csproj b/FruitBank.Common.Server/FruitBank.Common.Server.csproj index f73953cb..2cc380da 100644 --- a/FruitBank.Common.Server/FruitBank.Common.Server.csproj +++ b/FruitBank.Common.Server/FruitBank.Common.Server.csproj @@ -11,7 +11,9 @@ + + @@ -39,7 +41,7 @@ ..\..\..\..\Aycode\Source\AyCode.Core\AyCode.Services.Server\bin\FruitBank\Debug\net9.0\AyCode.Services.Server.dll - C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\9.0.11\ref\net9.0\Microsoft.AspNetCore.SignalR.Core.dll + C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\9.0.12\ref\net9.0\Microsoft.AspNetCore.SignalR.Core.dll ..\..\NopCommerce.Common\4.70\Libraries\Mango.Nop.Core\bin\FruitBank\Debug\net9.0\Mango.Nop.Core.dll diff --git a/FruitBank.Common/Entities/Shipping.cs b/FruitBank.Common/Entities/Shipping.cs index 704e893a..d3f72043 100644 --- a/FruitBank.Common/Entities/Shipping.cs +++ b/FruitBank.Common/Entities/Shipping.cs @@ -1,4 +1,5 @@ -using FruitBank.Common.Interfaces; +using AyCode.Interfaces.EntityComment; +using FruitBank.Common.Interfaces; using LinqToDB.Mapping; using Mango.Nop.Core.Entities; @@ -6,11 +7,13 @@ namespace FruitBank.Common.Entities; [Table(Name = FruitBankConstClient.ShippingDbTableName)] [System.ComponentModel.DataAnnotations.Schema.Table(FruitBankConstClient.ShippingDbTableName)] -public class Shipping : MgEntityBase, IShipping +public class Shipping : MgEntityBase, IShipping, IEntityComment { public DateTime ShippingDate { get; set; } = DateTime.Now; public string LicencePlate { get; set; } public bool IsAllMeasured { get; set; } + public string? Comment { get; set; } = string.Empty; + public string? CargoCompany { get; set; } public DateTime? MeasuredDate { get; set; } diff --git a/FruitBankHybrid.Shared/Components/Grids/Shippings/GridShipping.razor b/FruitBankHybrid.Shared/Components/Grids/Shippings/GridShipping.razor index 6142714a..03564592 100644 --- a/FruitBankHybrid.Shared/Components/Grids/Shippings/GridShipping.razor +++ b/FruitBankHybrid.Shared/Components/Grids/Shippings/GridShipping.razor @@ -23,12 +23,13 @@ - - - - - - + + + + + + + diff --git a/FruitBankHybrid/FruitBankHybrid.csproj b/FruitBankHybrid/FruitBankHybrid.csproj index 00784ad2..f25059b0 100644 --- a/FruitBankHybrid/FruitBankHybrid.csproj +++ b/FruitBankHybrid/FruitBankHybrid.csproj @@ -19,7 +19,7 @@ com.mango.fruitbank - 1.0 + 1.0.1 1 false From f5915f7f723354ed7fefe11582f82145af6c9e8d Mon Sep 17 00:00:00 2001 From: Loretta Date: Wed, 4 Mar 2026 15:22:51 +0100 Subject: [PATCH 13/14] Add RefreshStockTakingItem support and UI error handling Updated SignalR interface and tags to support refreshing individual StockTakingItems. Improved StockTakingTemplate.razor to show error messages and allow item refresh when invalid. Removed unused method and updated project reference to SignalR.Core 9.0.13. --- .../FruitBank.Common.Server.csproj | 2 +- .../Interfaces/IStockSignalREndpointCommon.cs | 1 + FruitBank.Common/SignalRs/SignalRTags.cs | 15 +++--- .../StockTakings/StockTakingTemplate.razor | 53 ++++++++++++------- .../SignalRs/FruitBankSignalRClient.cs | 1 + 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/FruitBank.Common.Server/FruitBank.Common.Server.csproj b/FruitBank.Common.Server/FruitBank.Common.Server.csproj index 2cc380da..c31b4f30 100644 --- a/FruitBank.Common.Server/FruitBank.Common.Server.csproj +++ b/FruitBank.Common.Server/FruitBank.Common.Server.csproj @@ -41,7 +41,7 @@ ..\..\..\..\Aycode\Source\AyCode.Core\AyCode.Services.Server\bin\FruitBank\Debug\net9.0\AyCode.Services.Server.dll - C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\9.0.12\ref\net9.0\Microsoft.AspNetCore.SignalR.Core.dll + C:\Program Files\dotnet\packs\Microsoft.AspNetCore.App.Ref\9.0.13\ref\net9.0\Microsoft.AspNetCore.SignalR.Core.dll ..\..\NopCommerce.Common\4.70\Libraries\Mango.Nop.Core\bin\FruitBank\Debug\net9.0\Mango.Nop.Core.dll diff --git a/FruitBank.Common/Interfaces/IStockSignalREndpointCommon.cs b/FruitBank.Common/Interfaces/IStockSignalREndpointCommon.cs index e943579d..2ec4d4ac 100644 --- a/FruitBank.Common/Interfaces/IStockSignalREndpointCommon.cs +++ b/FruitBank.Common/Interfaces/IStockSignalREndpointCommon.cs @@ -8,6 +8,7 @@ public interface IStockSignalREndpointCommon public Task?> GetStockTakings(bool loadRelations); public Task?> GetStockTakingsByProductId(int productId); public Task AddStockTaking(StockTaking stockTaking); + public Task RefreshStockTakingItem(int stockTakingItemId); public Task UpdateStockTaking(StockTaking stockTaking); public Task?> GetStockTakingItems(); diff --git a/FruitBank.Common/SignalRs/SignalRTags.cs b/FruitBank.Common/SignalRs/SignalRTags.cs index 30d07302..13f0471f 100644 --- a/FruitBank.Common/SignalRs/SignalRTags.cs +++ b/FruitBank.Common/SignalRs/SignalRTags.cs @@ -92,13 +92,14 @@ public class SignalRTags : AcSignalRTags public const int GetStockTakings = 170; public const int AddStockTaking = 171; - public const int UpdateStockTaking = 172; - public const int CloseStockTaking = 173; - public const int GetStockTakingItems = 174; - public const int GetStockTakingItemsById = 175; - public const int GetStockTakingItemsByProductId = 176; - public const int GetStockTakingItemsByStockTakingId = 177; - public const int AddOrUpdateMeasuredStockTakingItemPallet = 178; + public const int RefreshStockTakingItem = 172; + public const int UpdateStockTaking = 173; + public const int CloseStockTaking = 174; + public const int GetStockTakingItems = 175; + public const int GetStockTakingItemsById = 176; + public const int GetStockTakingItemsByProductId = 177; + public const int GetStockTakingItemsByStockTakingId = 178; + public const int AddOrUpdateMeasuredStockTakingItemPallet = 179; public const int AuthenticateUser = 195; diff --git a/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor b/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor index 92504c87..d4b7f485 100644 --- a/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor +++ b/FruitBankHybrid.Shared/Components/StockTakings/StockTakingTemplate.razor @@ -31,7 +31,7 @@ Context="ctxProduct" InputId="cbProduct" Value="@SelectedStockTaking" - ValueChanged="@(async (StockTaking stockTaking) => await StockTakingComboValueChanged(stockTaking))"> + ValueChanged="@(async (StockTaking stockTaking) => await StockTakingComboValueChanged(stockTaking, null))"> @@ -73,8 +73,15 @@
@{ var a = $"Várható rekesz: {SelectedStockTakingItem.TotalOriginalQuantity} ({SelectedStockTakingItem.OriginalStockQuantity} + {SelectedStockTakingItem.InProcessOrdersQuantity}), Várható net.súly: {SelectedStockTakingItem.OriginalNetWeight} kg."; - @a + @a } + + @if (SelectedStockTakingItem.IsInvalid) + { +
A várható mennyiség nem lehet negatív! A hibás adatok javítása után nyomja meg a "Frissítés" gombot.
+ + } +
@@ -141,11 +148,26 @@ LoadingPanelVisible = true; _stockTakings = await FruitBankSignalRClient.GetStockTakings(false) ?? []; - await StockTakingComboValueChanged(_stockTakings.FirstOrDefault()); + await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(), null); LoadingPanelVisible = false; } + private async Task RefreshErrorItemClick(StockTakingItem errorTakingItem) + { + var stockTakingItem = await FruitBankSignalRClient.RefreshStockTakingItem(errorTakingItem.Id); + if (stockTakingItem == null) + { + await DialogService.ShowMessageBoxAsync("Hiba", "Adatok frissése sikertelen volt!", MessageBoxRenderStyle.Danger); + return; + } + + await StockTakingComboValueChanged(SelectedStockTaking, stockTakingItem.Id); + + if (stockTakingItem.IsInvalid) + await DialogService.ShowMessageBoxAsync("Figyelem", "A termék továbbra is hibás!", MessageBoxRenderStyle.Warning); + } + private async Task NewStockTakingClick() { _btnDisabled = true; @@ -154,9 +176,11 @@ { LoadingPanelVisible = true; - var stockTaking = new StockTaking(); - stockTaking.StartDateTime = DateTime.Now; - stockTaking.Creator = LoggedInModel.CustomerDto!.Id; + var stockTaking = new StockTaking + { + StartDateTime = DateTime.Now, + Creator = LoggedInModel.CustomerDto!.Id + }; var resultStockTakings = await FruitBankSignalRClient.AddStockTaking(stockTaking); if (resultStockTakings == null) @@ -166,7 +190,7 @@ } _stockTakings.UpdateCollection(resultStockTakings, false); - await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(x => x.Id == resultStockTakings.Id)); + await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(x => x.Id == resultStockTakings.Id), null); } finally { @@ -178,15 +202,6 @@ await InvokeAsync(StateHasChanged); } - private async Task UpdateStockTakingClick() - { - // var resultStockTaking = await FruitBankSignalRClient.AddStockTaking(stockTaking); - // if (resultStockTaking == null) return; - - // _stockTakings.Add(resultStockTaking); - await InvokeAsync(StateHasChanged); - } - private async Task StockTakingCloseClick(int stockTakingId) { _btnDisabled = true; @@ -203,7 +218,7 @@ } _stockTakings.UpdateCollection(resultStockTaking, false); - await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(x => x.Id == resultStockTaking.Id)); + await StockTakingComboValueChanged(_stockTakings.FirstOrDefault(x => x.Id == resultStockTaking.Id), null); } finally { @@ -214,14 +229,14 @@ await InvokeAsync(StateHasChanged); } - private async Task StockTakingComboValueChanged(StockTaking? newValue) + private async Task StockTakingComboValueChanged(StockTaking? newValue, int? selectedStockTakingItemId) { SelectedStockTaking = newValue; SelectedStockTaking?.StockTakingItems = await FruitBankSignalRClient.GetStockTakingItemsByStockTakingId(SelectedStockTaking.Id); PrepareStockTakingItems(SelectedStockTaking); - SelectedStockTakingItem = _stockTakingItems.FirstOrDefault(); + SelectedStockTakingItem = selectedStockTakingItemId.HasValue ? _stockTakingItems.FirstOrDefault(x => x.Id == selectedStockTakingItemId.Value) : _stockTakingItems.FirstOrDefault(); await InvokeAsync(StateHasChanged); } diff --git a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs index 8b8bc8e7..6f5ea823 100644 --- a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs +++ b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs @@ -292,6 +292,7 @@ namespace FruitBankHybrid.Shared.Services.SignalRs } public Task AddStockTaking(StockTaking stockTaking) => PostDataAsync(SignalRTags.AddStockTaking, stockTaking); + public Task RefreshStockTakingItem(int stockTakingItemId) => GetByIdAsync(SignalRTags.RefreshStockTakingItem, stockTakingItemId); public Task UpdateStockTaking(StockTaking stockTaking) => PostDataAsync(SignalRTags.UpdateStockTaking, stockTaking); From a73b72f8318689f303d5d64c04c05c9bb0215ff4 Mon Sep 17 00:00:00 2001 From: Loretta Date: Fri, 6 Mar 2026 14:27:22 +0100 Subject: [PATCH 14/14] Refactor SignalR, pallet editing, and error handling - Refactored SignalRMessageToClientWithText to use explicit constructors and properties. - Added Shipping.Comment column to GridShippingDocument.razor. - Updated PalletItemComponent: renamed audit callback, added pre-save/audit callback, improved UI refresh logic. - MeasuringOut now uses new callbacks and _enablePalletItems flag to control editability during save/audit. - Wrapped SignalR message handling and logout logic in try/catch for better error logging. - MainLayout and MeasuringOut now implement IDisposable to unsubscribe SignalR events. - UI editability and state updates improved for thread safety and responsiveness. --- .../SignalRMessageToClientWithText.cs | 14 +- .../Components/GridShippingDocument.razor | 1 + .../Components/PalletItemComponent.razor | 22 ++- .../Layout/MainLayout.razor.cs | 74 +++++--- .../Pages/MeasuringOut.razor | 8 +- .../Pages/MeasuringOut.razor.cs | 178 ++++++++++-------- 6 files changed, 179 insertions(+), 118 deletions(-) diff --git a/FruitBank.Common/Models/SignalRs/SignalRMessageToClientWithText.cs b/FruitBank.Common/Models/SignalRs/SignalRMessageToClientWithText.cs index 3ef3d991..8fa31263 100644 --- a/FruitBank.Common/Models/SignalRs/SignalRMessageToClientWithText.cs +++ b/FruitBank.Common/Models/SignalRs/SignalRMessageToClientWithText.cs @@ -2,8 +2,16 @@ namespace FruitBank.Common.Models.SignalRs; -public class SignalRMessageToClientWithText(string? message, T? content) +public class SignalRMessageToClientWithText { - public string? Message { get; set; } = message; - public T? Content { get; set; } = content; + public SignalRMessageToClientWithText() + {} + public SignalRMessageToClientWithText(string? message, T? content) : this() + { + Message = message; + Content = content; + } + + public string? Message { get; set; } + public T? Content { get; set; } } \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/GridShippingDocument.razor b/FruitBankHybrid.Shared/Components/GridShippingDocument.razor index faa475a9..08c783a9 100644 --- a/FruitBankHybrid.Shared/Components/GridShippingDocument.razor +++ b/FruitBankHybrid.Shared/Components/GridShippingDocument.razor @@ -57,6 +57,7 @@ + diff --git a/FruitBankHybrid.Shared/Components/PalletItemComponent.razor b/FruitBankHybrid.Shared/Components/PalletItemComponent.razor index 14321490..8da64c72 100644 --- a/FruitBankHybrid.Shared/Components/PalletItemComponent.razor +++ b/FruitBankHybrid.Shared/Components/PalletItemComponent.razor @@ -60,7 +60,7 @@ } -@code { + @code { [Inject] public required IEnumerable LogWriters { get; set; } [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } [Inject] public required LoggedInModel LoggedInModel { get; set; } @@ -75,10 +75,14 @@ [Parameter] public int? MaxTrayQuantity { get; set; } = null; [Parameter] public bool Editable { get; set; } = true; - //[Parameter] public EventCallback OnPalletItemSaveClick { get; set; } [Parameter] public Func? OnPalletItemSaved { get; set; } [Parameter] public Func? OnPalletItemValueChanged { get; set; } - [Parameter] public Func? OnPalletItemAuditedClick { get; set; } + [Parameter] public Func? OnPalletItemAudited { get; set; } + + /// + /// Before Save or Audit + /// + [Parameter] public Func? OnPalletItemSaveOrAuditClick { get; set; } //public bool LoadingPanelVisible { get; set; } = false; //public bool Editable => !HasAuditButton || (OrderItemPallet.IsAudited); @@ -119,6 +123,8 @@ PalletItem.ModifierId = LoggedInModel.CustomerDto?.Id; + if (OnPalletItemSaveOrAuditClick != null) await OnPalletItemSaveOrAuditClick.Invoke(PalletItem); + var responseShippingItemPallet = await FruitBankSignalRClient.PostDataAsync(AddOrUpdateSignalRTag!.Value, PalletItem); if (responseShippingItemPallet != null) PalletItem.Id = responseShippingItemPallet.Id; //Az UpdateCollection miatt kell, hogy megtalálja mit kell kicserélni! - J. //else _logger.Error($"Sikertelen volt a raklap adatainak mentése!"); @@ -126,7 +132,7 @@ if (OnPalletItemSaved != null) await OnPalletItemSaved.Invoke(responseShippingItemPallet); //LoadingPanelVisible = false; - StateHasChanged(); + await InvokeAsync(StateHasChanged); } protected async Task OnItemUpdating(string fieldName, object newValue, TPalletItem palletItem) @@ -172,15 +178,17 @@ private async Task PalletItemAuditedClick() { - if (OnPalletItemAuditedClick != null) + if (OnPalletItemAudited != null) { if (OrderItemPallet == null) throw new Exception($"PalletItemComponent->PalletItemAuditedClick(); OrderItemPallet == null"); if (await DialogService.ShowConfirmBoxAsync("Megerősítés", "Biztoan jóváhagyja a mérést? Jóváhagyás után a mérés nem módosítható!", MessageBoxRenderStyle.Info)) { + if (OnPalletItemSaveOrAuditClick != null) await OnPalletItemSaveOrAuditClick.Invoke(PalletItem); + OrderItemPallet.RevisorId = LoggedInModel.CustomerDto!.Id; - StateHasChanged(); //Az Audit button miatt kell a StateHasChanged(), most már van RevisorId és emiatt disabled lesz... + await InvokeAsync(StateHasChanged); //Az Audit button miatt kell a StateHasChanged(), most már van RevisorId és emiatt disabled lesz... PalletItem.SetParentPropToNull(); @@ -191,7 +199,7 @@ await DialogService.ShowMessageBoxAsync("Hiba", "Adatok mentése sikertelen volt, ellenőrizze a mérés adatait!", MessageBoxRenderStyle.Danger); } - if (OnPalletItemAuditedClick != null) await OnPalletItemAuditedClick.Invoke(responseShippingItemPallet); + await OnPalletItemAudited.Invoke(responseShippingItemPallet); } } } diff --git a/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs b/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs index 42821e27..55e9bb7a 100644 --- a/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs +++ b/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs @@ -16,7 +16,7 @@ using Microsoft.AspNetCore.Components; namespace FruitBankHybrid.Shared.Layout; -public partial class MainLayout : LayoutComponentBase +public partial class MainLayout : LayoutComponentBase, IDisposable { [Inject] public required IEnumerable LogWriters { get; set; } [Inject] public required NavigationManager NavManager { get; set; } @@ -70,43 +70,57 @@ public partial class MainLayout : LayoutComponentBase { if (messageTag != SignalRTags.NotificationReceived || !LoggedInModel.IsLoggedIn) return; - var notificationMessage = responseDataMessage?.GetResponseData>(); - if (notificationMessage == null) + try { - _logger.Error($"notificationMessage == null"); - return; + var notificationMessage = responseDataMessage?.GetResponseData>(); + if (notificationMessage == null) + { + _logger.Error($"MainLayout.SignalRClientOnMessageReceived; notificationMessage == null; messageTag: {messageTag}"); + return; + } + + toastOrderNumber = null; + toastDateOfReceipt = null; + + toastMessage = notificationMessage.Message; + + var orderDto = notificationMessage.Content; + var hasPermission = orderDto == null || (orderDto.HasMeasuringAccess(LoggedInModel.CustomerDto!.Id, LoggedInModel.IsRevisor) || orderDto.MeasurementOwnerId == 0); + + if (orderDto != null && hasPermission) + { + toastOrderNumber = orderDto.CustomOrderNumber; + toastDateOfReceipt = orderDto.DateOfReceipt; + } + + if (!hasPermission) return; + + _logger.Debug($"MainLayout.SignalRClientOnMessageReceived; NotificationMessage received. {toastMessage}"); + + await InvokeAsync(() => + { + orderNotificationToast?.Show(); + StateHasChanged(); + }); } - - toastOrderNumber = null; - toastDateOfReceipt = null; - - toastMessage = notificationMessage.Message; - - var orderDto = notificationMessage.Content; - var hasPermission = orderDto == null || (orderDto.HasMeasuringAccess(LoggedInModel.CustomerDto!.Id, LoggedInModel.IsRevisor) || orderDto.MeasurementOwnerId == 0); - - if (orderDto != null && hasPermission) + catch (Exception ex) { - toastOrderNumber = orderDto.CustomOrderNumber; - toastDateOfReceipt = orderDto.DateOfReceipt; + _logger.Error($"MainLayout.SignalRClientOnMessageReceived ERROR; messageTag: {messageTag}", ex); } - - if (!hasPermission) return; - - _logger.Debug($"NotificationMessage received. {toastMessage}"); - - await InvokeAsync(() => - { - orderNotificationToast?.Show(); - StateHasChanged(); - }); } private async void OnLogoutClick() { - await LoggedInModel.LogOutAsync(); - RefreshMainLayout(); - NavManager.NavigateTo("/Login"); + try + { + await LoggedInModel.LogOutAsync(); + RefreshMainLayout(); + NavManager.NavigateTo("/Login"); + } + catch (Exception e) + { + _logger.Error($"OnLogoutClick error"); + } } public void RefreshMainLayout() diff --git a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor index e26c8de0..65ec04bc 100644 --- a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor +++ b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor @@ -176,7 +176,8 @@ { var selectedOrderItem = (OrderItemDto)(context.DataItem); - + @for (var index = 0; index < (selectedOrderItem?.OrderItemPallets?.Count ?? 0); index++) { @@ -185,14 +186,15 @@ + OnPalletItemAudited="pallet => OnOrderItemAudited(pallet, selectedOrderItem)"> } diff --git a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor.cs b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor.cs index 116dbd59..85858aa0 100644 --- a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor.cs +++ b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor.cs @@ -17,9 +17,10 @@ using Nop.Core.Domain.Orders; namespace FruitBankHybrid.Shared.Pages { - public partial class MeasuringOut : ComponentBase + public partial class MeasuringOut : ComponentBase, IDisposable { private readonly Lock _lock = new Lock(); + [Inject] public required IEnumerable LogWriters { get; set; } [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } [Inject] public required NavigationManager NavManager{ get; set; } @@ -29,6 +30,7 @@ namespace FruitBankHybrid.Shared.Pages private LoggerClient _logger = null!; private string _errorText; + private bool _enablePalletItems = true; private int _lastDaysCount = 1; public bool HasMeasuringAccess; public bool LoadingPanelVisible { get; set; } = true; @@ -59,99 +61,106 @@ namespace FruitBankHybrid.Shared.Pages if (messageTag != SignalRTags.SendOrderItemDeleted && messageTag != SignalRTags.SendOrderChanged && messageTag != SignalRTags.SendOrderItemChanged && messageTag != SignalRTags.SendOrderItemPalletChanged && messageTag != SignalRTags.SendProductChanged) return; - _logger.DebugConditional($"SignalRClientOnMessageReceived received. {responseDataMessage}"); + _logger.DebugConditional($"MeasuringOut.SignalRClientOnMessageReceived received. {responseDataMessage}"); - OrderDto? orderDto; - OrderItem? orderItem; - OrderItemDto? orderItemDto; - - switch (messageTag) + try { - case SignalRTags.SendOrderItemDeleted: - orderItem = responseDataMessage?.GetResponseData(); - if (orderItem == null) break; + OrderDto? orderDto; + OrderItem? orderItem; + OrderItemDto? orderItemDto; - lock (_lock) - { - orderDto = SelectedDayOrders.FirstOrDefault(o => o.OrderItemDtos.Any(oi => oi.Id == orderItem.Id)); - orderDto?.OrderItemDtos.RemoveAll(oi => oi.Id == orderItem.Id); - } + switch (messageTag) + { + case SignalRTags.SendOrderItemDeleted: + orderItem = responseDataMessage?.GetResponseData(); + if (orderItem == null) break; - await InvokeAsync(StateHasChanged); - return; - case SignalRTags.SendOrderChanged: - orderDto = responseDataMessage?.GetResponseData(); - if (orderDto == null) break; + lock (_lock) + { + orderDto = SelectedDayOrders.FirstOrDefault(o => o.OrderItemDtos.Any(oi => oi.Id == orderItem.Id)); + orderDto?.OrderItemDtos.RemoveAll(oi => oi.Id == orderItem.Id); + } - if (orderDto.DateOfReceipt == null) return; + await InvokeAsync(StateHasChanged); + return; + case SignalRTags.SendOrderChanged: + orderDto = responseDataMessage?.GetResponseData(); + if (orderDto == null) break; - lock (_lock) - { - if (_measuringDates.All(x => x.DateTime.Date != orderDto.DateOfReceipt.Value.Date)) - _measuringDates.Add(new MeasuringDateSelectorModel(orderDto.Id, orderDto.DateOfReceipt.Value.Date, orderDto.IsMeasured)); + if (orderDto.DateOfReceipt == null) return; - if (SelectedDate != orderDto.DateOfReceipt.Value.Date) return; + lock (_lock) + { + if (_measuringDates.All(x => x.DateTime.Date != orderDto.DateOfReceipt.Value.Date)) + _measuringDates.Add(new MeasuringDateSelectorModel(orderDto.Id, orderDto.DateOfReceipt.Value.Date, orderDto.IsMeasured)); - //Elég lenne ez is, csak a CopyTo a Collection - ökben lévő elemeket hozzáfűzi és duplikálva lesznek... -J. - if (SelectedOrder?.Id == orderDto.Id) orderDto.CopyTo(SelectedOrder); - else SelectedDayOrders.UpdateCollection(orderDto, false); + if (SelectedDate != orderDto.DateOfReceipt.Value.Date) return; - //var selectedOrderId = SelectedOrder?.Id; - //SelectedDayOrders.UpdateCollection(orderDto, false); + //Elég lenne ez is, csak a CopyTo a Collection - ökben lévő elemeket hozzáfűzi és duplikálva lesznek... -J. + if (SelectedOrder?.Id == orderDto.Id) orderDto.CopyTo(SelectedOrder); + else SelectedDayOrders.UpdateCollection(orderDto, false); - //if (selectedOrderId.GetValueOrDefault(-1) == orderDto.Id) SelectedOrder = orderDto; - } + //var selectedOrderId = SelectedOrder?.Id; + //SelectedDayOrders.UpdateCollection(orderDto, false); - await InvokeAsync(StateHasChanged); - return; - case SignalRTags.SendOrderItemChanged: - orderItemDto = responseDataMessage?.GetResponseData(); - if (orderItemDto == null) break; + //if (selectedOrderId.GetValueOrDefault(-1) == orderDto.Id) SelectedOrder = orderDto; + } - lock (_lock) - { - var localOrderDto = SelectedDayOrders.FirstOrDefault(o => o.OrderItemDtos.Any(oi => oi.Id == orderItemDto.Id)); - var localOrderItemDto = localOrderDto?.OrderItemDtos.FirstOrDefault(x => x.Id == orderItemDto.Id); - - if (localOrderItemDto == null) return; + await InvokeAsync(StateHasChanged); + return; + case SignalRTags.SendOrderItemChanged: + orderItemDto = responseDataMessage?.GetResponseData(); + if (orderItemDto == null) break; - //orderItemDto.OrderDto = localOrderDto!; + lock (_lock) + { + var localOrderDto = SelectedDayOrders.FirstOrDefault(o => o.OrderItemDtos.Any(oi => oi.Id == orderItemDto.Id)); + var localOrderItemDto = localOrderDto?.OrderItemDtos.FirstOrDefault(x => x.Id == orderItemDto.Id); - localOrderItemDto.Quantity = orderItemDto.Quantity; - localOrderItemDto.GenericAttributes.UpdateBaseEntityCollection(orderItemDto.GenericAttributes, false); - } + if (localOrderItemDto == null) return; - await InvokeAsync(StateHasChanged); - return; - case SignalRTags.SendOrderItemPalletChanged: - var orderItemPallet = responseDataMessage?.GetResponseData(); - if (orderItemPallet == null) break; + //orderItemDto.OrderDto = localOrderDto!; - lock (_lock) - { - var orderItemDtos = SelectedDayOrders.FirstOrDefault(x => x.OrderItemDtos.Any(oi => oi.Id == orderItemPallet.OrderItemId))?.OrderItemDtos; - - orderItemDto = orderItemDtos?.FirstOrDefault(oi => oi.Id == orderItemPallet.OrderItemId); - if (orderItemDto == null) return; + localOrderItemDto.Quantity = orderItemDto.Quantity; + localOrderItemDto.GenericAttributes.UpdateBaseEntityCollection(orderItemDto.GenericAttributes, false); + } - orderItemPallet.OrderItemDto = orderItemDto; - var orderItemPalletsCount = orderItemDto.OrderItemPallets.Count; + await InvokeAsync(StateHasChanged); + return; + case SignalRTags.SendOrderItemPalletChanged: + var orderItemPallet = responseDataMessage?.GetResponseData(); + if (orderItemPallet == null) break; - if (orderItemDto.OrderItemPallets[orderItemPalletsCount - 1].Id == 0) orderItemDto.OrderItemPallets.Insert(orderItemPalletsCount - 1, orderItemPallet); - else orderItemDto.OrderItemPallets.UpdateCollection(orderItemPallet, false); - } + lock (_lock) + { + var orderItemDtos = SelectedDayOrders.FirstOrDefault(x => x.OrderItemDtos.Any(oi => oi.Id == orderItemPallet.OrderItemId))?.OrderItemDtos; - await InvokeAsync(StateHasChanged); - return; - case SignalRTags.SendProductChanged: - var productDto = responseDataMessage?.GetResponseData(); - if (productDto == null) break; + orderItemDto = orderItemDtos?.FirstOrDefault(oi => oi.Id == orderItemPallet.OrderItemId); + if (orderItemDto == null) return; - await InvokeAsync(StateHasChanged); - return; + orderItemPallet.OrderItemDto = orderItemDto; + var orderItemPalletsCount = orderItemDto.OrderItemPallets.Count; + + if (orderItemDto.OrderItemPallets[orderItemPalletsCount - 1].Id == 0) orderItemDto.OrderItemPallets.Insert(orderItemPalletsCount - 1, orderItemPallet); + else orderItemDto.OrderItemPallets.UpdateCollection(orderItemPallet, false); + } + + await InvokeAsync(StateHasChanged); + return; + case SignalRTags.SendProductChanged: + var productDto = responseDataMessage?.GetResponseData(); + if (productDto == null) break; + + await InvokeAsync(StateHasChanged); + return; + } + + _logger.Error($"MeasuringOut.SignalRClientOnMessageReceived message == null; messageTag: {messageTag}"); + } + catch (Exception ex) + { + _logger.Error($"MeasuringOut.SignalRClientOnMessageReceived ERROR; messageTag: {messageTag}", ex); } - - _logger.Error($"SignalRClientOnMessageReceived message == null"); } private async Task RefreshOrdersFromDb(DateTime dateTime, int lastDaysCount) @@ -241,12 +250,25 @@ namespace FruitBankHybrid.Shared.Pages return Task.CompletedTask; } - private async Task OnPalletItemAuditedClick(OrderItemPallet? orderItemPallet, OrderItemDto selectedOrderItemDto) + private async Task OnOrderItemAudited(OrderItemPallet? orderItemPallet, OrderItemDto selectedOrderItemDto) { if (orderItemPallet == null) return; + + _enablePalletItems = false; + + await InvokeAsync(StateHasChanged); await OnOrderItemPalletSaved(orderItemPallet, selectedOrderItemDto); } + private async Task OnOrderItemSaveOrAuditClick(OrderItemPallet? orderItemPallet, OrderItemDto selectedOrderItemDto) + { + if (orderItemPallet != null) + { + _enablePalletItems = false; + await InvokeAsync(StateHasChanged); + } + } + private async Task OnOrderItemPalletSaved(OrderItemPallet? orderItemPallet, OrderItemDto selectedOrderItemDto) { if (orderItemPallet != null) @@ -258,7 +280,8 @@ namespace FruitBankHybrid.Shared.Pages } else await DialogService.ShowMessageBoxAsync("Hiba", "Adatok mentése sikertelen volt, ellenőrizze a mérés adatait!", MessageBoxRenderStyle.Danger); - StateHasChanged(); + _enablePalletItems = true; + await InvokeAsync(StateHasChanged); } private Task AddNewPalletItemClick(OrderItemDto selectedOrderItemDto) @@ -359,5 +382,10 @@ namespace FruitBankHybrid.Shared.Pages orderDto.GenericAttributes.UpdateBaseEntityCollection(genericAttributes, false); } } + + public void Dispose() + { + FruitBankSignalRClient.OnMessageReceived -= SignalRClientOnMessageReceived; + } } }