diff --git a/FruitBank.Common.Server/Services/SignalRs/AcWebSignalRHubWithSessionBase.cs b/FruitBank.Common.Server/Services/SignalRs/AcWebSignalRHubWithSessionBase.cs index cd095e4..927bc6f 100644 --- a/FruitBank.Common.Server/Services/SignalRs/AcWebSignalRHubWithSessionBase.cs +++ b/FruitBank.Common.Server/Services/SignalRs/AcWebSignalRHubWithSessionBase.cs @@ -1,6 +1,7 @@ using AyCode.Core.Loggers; using AyCode.Services.Server.SignalRs; using AyCode.Services.SignalRs; +using FruitBank.Common.Dtos; using Microsoft.Extensions.Configuration; namespace FruitBank.Common.Server.Services.SignalRs; diff --git a/FruitBank.Common.Server/Services/SignalRs/SignalRSendToClientService.cs b/FruitBank.Common.Server/Services/SignalRs/SignalRSendToClientService.cs new file mode 100644 index 0000000..6078d15 --- /dev/null +++ b/FruitBank.Common.Server/Services/SignalRs/SignalRSendToClientService.cs @@ -0,0 +1,34 @@ +using AyCode.Core.Loggers; +using AyCode.Services.Server.SignalRs; +using FruitBank.Common.Dtos; +using FruitBank.Common.Entities; +using FruitBank.Common.Models.SignalRs; +using FruitBank.Common.SignalRs; +using Mango.Nop.Core.Loggers; +using Microsoft.AspNetCore.SignalR; + +namespace FruitBank.Common.Server.Services.SignalRs; + +public class SignalRSendToClientService(IHubContext signalRHub, IEnumerable logWriters) + : AcSignalRSendToClientService(signalRHub, new Logger(logWriters.ToArray())) +{ + public Task SendMeasuringNotification(string message) => SendMeasuringNotification(message, null); + public Task SendMeasuringNotification(OrderDto orderDto) => SendMeasuringNotification(null, orderDto); + + public Task SendMeasuringNotification(string? message, OrderDto? orderDto) + { + var notificationMessage = new SignalRMessageToClientWithText(message, orderDto); + return base.SendMessageToAllClients(SignalRTags.NotificationReceived, notificationMessage); + } + + public Task SendProductChanged(ProductDto productDto) => base.SendMessageToAllClients(SignalRTags.SendProductChanged, productDto); + + public Task SendOrderChanged(OrderDto orderDto) => base.SendMessageToAllClients(SignalRTags.SendOrderChanged, orderDto); + public Task SendOrderItemChanged(OrderItemDto orderItemDto) => base.SendMessageToAllClients(SignalRTags.SendOrderItemChanged, orderItemDto); + public Task SendOrderItemPalletChanged(OrderItemPallet orderItemPallet) => base.SendMessageToAllClients(SignalRTags.SendOrderItemPalletChanged, orderItemPallet); + + public Task SendShippingChanged(Shipping shipping) => base.SendMessageToAllClients(SignalRTags.SendShippingChanged, shipping); + public Task SendShippingItemChanged(ShippingItem shippingItem) => base.SendMessageToAllClients(SignalRTags.SendShippingItemChanged, shippingItem); + public Task SendShippingDocumentChanged(ShippingDocument shippingDocument) => base.SendMessageToAllClients(SignalRTags.SendShippingDocumentChanged, shippingDocument); + public Task SendShippingItemPalletChanged(ShippingItemPallet shippingItemPallet) => base.SendMessageToAllClients(SignalRTags.SendShippingItemPalletChanged, shippingItemPallet); +} \ No newline at end of file diff --git a/FruitBank.Common/Dtos/OrderDto.cs b/FruitBank.Common/Dtos/OrderDto.cs index f7f4890..568c54b 100644 --- a/FruitBank.Common/Dtos/OrderDto.cs +++ b/FruitBank.Common/Dtos/OrderDto.cs @@ -1,6 +1,7 @@ using AyCode.Core.Extensions; using AyCode.Utils.Extensions; using FruitBank.Common.Entities; +using FruitBank.Common.Enums; using FruitBank.Common.Interfaces; using FruitBank.Common.Models; using LinqToDB.Mapping; @@ -71,6 +72,20 @@ public class OrderDto : MgOrderDto, IOrderDto [NotColumn, JsonIgnore, System.Text.Json.Serialization.JsonIgnore] public int MeasurementOwnerId => GenericAttributes.GetValueOrDefault(nameof(IOrderDto.MeasurementOwnerId), 0); + [NotColumn, JsonIgnore, System.Text.Json.Serialization.JsonIgnore] + public bool IsAllOrderItemAudited => OrderItemDtos.Count > 0 && OrderItemDtos.All(oi => oi.IsAudited); + + [NotColumn, JsonIgnore, System.Text.Json.Serialization.JsonIgnore] + public MeasuringStatus MeasuringStatus + { + get + { + if (IsComplete) return MeasuringStatus.Audited; + if (IsMeasured) return MeasuringStatus.Finnished; + + return OrderItemDtos.Any(oip => oip.MeasuringStatus >= MeasuringStatus.Started) ? MeasuringStatus.Started : MeasuringStatus.NotStarted; + } + } //if (GenericAttributes.TryGetValue(nameof(IOrderDto.DateOfReceipt), out var value)) return value; //var dateOfReceipt = GenericAttributes.SingleOrDefault(x => x.Key == nameof(IOrderDto.DateOfReceipt))?.Value ?? string.Empty; //return dateOfReceipt.IsNullOrWhiteSpace() ? null : CommonHelper.To(dateOfReceipt); @@ -81,10 +96,11 @@ public class OrderDto : MgOrderDto, IOrderDto public OrderDto(Order order) : base(order) { } + [NotColumn, JsonIgnore, System.Text.Json.Serialization.JsonIgnore] public bool IsComplete => OrderStatus == OrderStatus.Complete; public bool HasMeasuringAccess(int? customerId, bool isRevisorUser = false) - => isRevisorUser || (customerId.HasValue && OrderStatus != OrderStatus.Complete && (customerId.Value == MeasurementOwnerId || MeasurementOwnerId == 0)); + => isRevisorUser || (customerId.HasValue && !IsComplete && (customerId.Value == MeasurementOwnerId || MeasurementOwnerId == 0)); public bool IsMeasuredAndValid() => Id > 0 && OrderItemDtos.Count > 0 && OrderItemDtos.All(x => x.IsMeasured); public bool IsValidMeasuringValues() => OrderItemDtos.Count > 0 && OrderItemDtos.All(x => x.IsValidMeasuringValues()); diff --git a/FruitBank.Common/Dtos/OrderItemDto.cs b/FruitBank.Common/Dtos/OrderItemDto.cs index fad5c72..535b3da 100644 --- a/FruitBank.Common/Dtos/OrderItemDto.cs +++ b/FruitBank.Common/Dtos/OrderItemDto.cs @@ -1,6 +1,5 @@ -using System.Globalization; -using System.Linq.Expressions; -using FruitBank.Common.Entities; +using FruitBank.Common.Entities; +using FruitBank.Common.Enums; using FruitBank.Common.Interfaces; using LinqToDB.Mapping; using Mango.Nop.Core.Dtos; @@ -8,6 +7,9 @@ using Newtonsoft.Json; using Nop.Core; using Nop.Core.Domain.Common; using Nop.Core.Domain.Orders; +using System.Globalization; +using System.Linq; +using System.Linq.Expressions; namespace FruitBank.Common.Dtos; @@ -82,6 +84,21 @@ public class OrderItemDto : MgOrderItemDto, IOrderItemDto } } + [NotColumn, JsonIgnore, System.Text.Json.Serialization.JsonIgnore] + public bool IsAudited => OrderItemPallets.Count > 0 && OrderItemPallets.All(oip => oip.IsAudited); + + [NotColumn, JsonIgnore, System.Text.Json.Serialization.JsonIgnore] + public MeasuringStatus MeasuringStatus + { + get + { + if (IsAudited) return MeasuringStatus.Audited; + if (IsMeasured) return MeasuringStatus.Finnished; + + return OrderItemPallets.Any(oip => oip.MeasuringStatus >= MeasuringStatus.Started) ? MeasuringStatus.Started : MeasuringStatus.NotStarted; + } + } + public OrderItemDto() : base() { } diff --git a/FruitBank.Common/Entities/MeasuringItemPalletBase.cs b/FruitBank.Common/Entities/MeasuringItemPalletBase.cs index 72fded7..6347059 100644 --- a/FruitBank.Common/Entities/MeasuringItemPalletBase.cs +++ b/FruitBank.Common/Entities/MeasuringItemPalletBase.cs @@ -1,4 +1,6 @@ -using FruitBank.Common.Interfaces; +using FruitBank.Common.Dtos; +using FruitBank.Common.Enums; +using FruitBank.Common.Interfaces; using LinqToDB; using LinqToDB.Mapping; using Mango.Nop.Core.Entities; @@ -57,6 +59,8 @@ public abstract class MeasuringItemPalletBase : MgEntityBase, IMeasuringItemPall public DateTime Created { get; set; } public DateTime Modified { get; set; } + public virtual MeasuringStatus MeasuringStatus => IsMeasured ? MeasuringStatus.Finnished : Id > 0 ? MeasuringStatus.Started : MeasuringStatus.NotStarted; + public virtual double CalculateNetWeight() => double.Round(GrossWeight - PalletWeight - (TareWeight * TrayQuantity), 1); /// diff --git a/FruitBank.Common/Entities/OrderItemPallet.cs b/FruitBank.Common/Entities/OrderItemPallet.cs index f9557d1..3a2cce5 100644 --- a/FruitBank.Common/Entities/OrderItemPallet.cs +++ b/FruitBank.Common/Entities/OrderItemPallet.cs @@ -1,4 +1,5 @@ using FruitBank.Common.Dtos; +using FruitBank.Common.Enums; using FruitBank.Common.Interfaces; using LinqToDB.Mapping; using Nop.Core.Domain.Orders; @@ -15,9 +16,13 @@ public class OrderItemPallet : MeasuringItemPalletBase, IOrderItemPallet set => ForeignItemId = value; } + public int RevisorId { get; set; } + public bool IsAudited => RevisorId > 0; + [Association(ThisKey = nameof(OrderItemId), OtherKey = nameof(OrderItemDto.Id), CanBeNull = true)] public OrderItemDto? OrderItemDto { get; set; } + public override MeasuringStatus MeasuringStatus => IsAudited ? MeasuringStatus.Audited : base.MeasuringStatus; public override double CalculateNetWeight() => base.CalculateNetWeight(); public override bool IsValidSafeMeasuringValues() diff --git a/FruitBank.Common/Entities/ShippingItem.cs b/FruitBank.Common/Entities/ShippingItem.cs index a628f70..f84566a 100644 --- a/FruitBank.Common/Entities/ShippingItem.cs +++ b/FruitBank.Common/Entities/ShippingItem.cs @@ -9,6 +9,7 @@ using System.ComponentModel.DataAnnotations; using Nop.Core.Domain.Catalog; using DataType = LinqToDB.DataType; using FruitBank.Common.Dtos; +using FruitBank.Common.Enums; using Newtonsoft.Json; namespace FruitBank.Common.Entities; @@ -76,6 +77,16 @@ public class ShippingItem : MgEntityBase, IShippingItem [SkipValuesOnUpdate] public DateTime Created { get; set; } public DateTime Modified { get; set; } + public MeasuringStatus MeasuringStatus + { + get + { + if (IsMeasured) return MeasuringStatus.Finnished; + + return ShippingItemPallets?.Any(oip => oip.MeasuringStatus == MeasuringStatus.Started) ?? false ? MeasuringStatus.Started : MeasuringStatus.NotStarted; + } + } + public bool IsValidMeasuringValues() { return /*ProductId > 0 && */MeasuringCount > 0 && MeasuredQuantity > 0 && (!IsMeasurable || (MeasuredNetWeight > 0 && MeasuredGrossWeight > 0)); diff --git a/FruitBank.Common/Enums/MeasuringStatus.cs b/FruitBank.Common/Enums/MeasuringStatus.cs new file mode 100644 index 0000000..c474ce3 --- /dev/null +++ b/FruitBank.Common/Enums/MeasuringStatus.cs @@ -0,0 +1,9 @@ +namespace FruitBank.Common.Enums; + +public enum MeasuringStatus +{ + NotStarted = 0, + Started = 10, + Finnished = 20, + Audited = 30 +} \ No newline at end of file diff --git a/FruitBank.Common/FruitBankConstClient.cs b/FruitBank.Common/FruitBankConstClient.cs index 71d6723..69f33f5 100644 --- a/FruitBank.Common/FruitBankConstClient.cs +++ b/FruitBank.Common/FruitBankConstClient.cs @@ -20,6 +20,9 @@ public static class FruitBankConstClient public static string DefaultHubName = "fbHub"; public static string LoggerHubName = "loggerHub"; + public static long SignalRKeepAliveIntervalSecond = 60; + public static long SignarlRTimeoutIntervalSecond = 120; + public const string PalletDbTableName = "fbPallet"; public const string FilesDbTableName = "fbFiles"; public const string PartnerDbTableName = "fbPartner"; diff --git a/FruitBank.Common/Interfaces/ICustomOrderSignalREndpointCommon.cs b/FruitBank.Common/Interfaces/ICustomOrderSignalREndpointCommon.cs index b29c81c..64c80ab 100644 --- a/FruitBank.Common/Interfaces/ICustomOrderSignalREndpointCommon.cs +++ b/FruitBank.Common/Interfaces/ICustomOrderSignalREndpointCommon.cs @@ -11,8 +11,27 @@ public interface ICustomOrderSignalREndpointCommon Task?> GetPendingOrderDtosForMeasuring(); Task?> GetAllOrderDtoByIds(int[] orderIds); Task GetOrderDtoById(int orderId); + + Task?> GetAllOrderDtoByProductId(int productId); + Task GetOrderItemDtoById(int orderItemId); + + Task?> GetAllOrderItemDtos(); + + Task?> GetAllOrderItemDtoByOrderId(int orderId); + + Task?> GetAllOrderItemDtoByProductId(int productId); + + Task?> GetAllOrderItemPallets(); + Task GetOrderItemPalletById(int orderItemPalletId); + Task?> GetAllOrderItemPalletByOrderItemId(int orderItemId); + + Task?> GetAllOrderItemPalletByOrderId(int orderId); + + Task?> GetAllOrderItemPalletByProductId(int productId); + Task AddOrUpdateMeasuredOrderItemPallet(OrderItemPallet orderItemPallet); Task StartMeasuring(int orderId, int userId); Task SetOrderStatusToComplete(int orderId, int revisorId); + } \ No newline at end of file diff --git a/FruitBank.Common/Interfaces/IMeasurable.cs b/FruitBank.Common/Interfaces/IMeasurable.cs index d1cb598..ba6c332 100644 --- a/FruitBank.Common/Interfaces/IMeasurable.cs +++ b/FruitBank.Common/Interfaces/IMeasurable.cs @@ -3,4 +3,5 @@ public interface IMeasurable { bool IsMeasurable { get; set; } + } \ No newline at end of file diff --git a/FruitBank.Common/Interfaces/IMeasurableStatus.cs b/FruitBank.Common/Interfaces/IMeasurableStatus.cs new file mode 100644 index 0000000..ac58fd0 --- /dev/null +++ b/FruitBank.Common/Interfaces/IMeasurableStatus.cs @@ -0,0 +1,8 @@ +using FruitBank.Common.Enums; + +namespace FruitBank.Common.Interfaces; + +public interface IMeasurableStatus +{ + MeasuringStatus MeasuringStatus { get; } +} \ No newline at end of file diff --git a/FruitBank.Common/Interfaces/IMeasurementServiceBase.cs b/FruitBank.Common/Interfaces/IMeasurementServiceBase.cs new file mode 100644 index 0000000..079a576 --- /dev/null +++ b/FruitBank.Common/Interfaces/IMeasurementServiceBase.cs @@ -0,0 +1,6 @@ +namespace FruitBank.Common.Interfaces; + +public interface IMeasurementServiceBase +{ + +} \ No newline at end of file diff --git a/FruitBank.Common/Interfaces/IMeasuringItemPalletBase.cs b/FruitBank.Common/Interfaces/IMeasuringItemPalletBase.cs index a1d35f7..90bddcf 100644 --- a/FruitBank.Common/Interfaces/IMeasuringItemPalletBase.cs +++ b/FruitBank.Common/Interfaces/IMeasuringItemPalletBase.cs @@ -2,10 +2,11 @@ using AyCode.Interfaces.Entities; using AyCode.Interfaces.TimeStampInfo; using FruitBank.Common.Entities; +using FruitBank.Common.Enums; namespace FruitBank.Common.Interfaces; -public interface IMeasuringItemPalletBase : IEntityInt, IMeasuringValues, IMeasured, ITimeStampInfo, ICustomForeignKeyInt +public interface IMeasuringItemPalletBase : IEntityInt, IMeasuringValues, IMeasured, ITimeStampInfo, ICustomForeignKeyInt, IMeasurableStatus { double TareWeight { get; set; } double PalletWeight { get; set; } diff --git a/FruitBank.Common/Interfaces/IOrderDto.cs b/FruitBank.Common/Interfaces/IOrderDto.cs index 58e5e1c..6d30b47 100644 --- a/FruitBank.Common/Interfaces/IOrderDto.cs +++ b/FruitBank.Common/Interfaces/IOrderDto.cs @@ -1,10 +1,11 @@ using FruitBank.Common.Dtos; +using FruitBank.Common.Enums; using Mango.Nop.Core.Dtos; using Mango.Nop.Core.Interfaces; namespace FruitBank.Common.Interfaces; -public interface IOrderDto : IMgOrderDto, IMeasured, IMeasurable +public interface IOrderDto : IMgOrderDto, IMeasured, IMeasurable, IMeasurableStatus { DateTime? DateOfReceipt { get; } DateTime DateOfReceiptOrCreated { get; } diff --git a/FruitBank.Common/Interfaces/IOrderItemDto.cs b/FruitBank.Common/Interfaces/IOrderItemDto.cs index d49122c..1faa504 100644 --- a/FruitBank.Common/Interfaces/IOrderItemDto.cs +++ b/FruitBank.Common/Interfaces/IOrderItemDto.cs @@ -1,12 +1,13 @@ using FruitBank.Common.Dtos; using FruitBank.Common.Entities; +using FruitBank.Common.Enums; using Mango.Nop.Core.Dtos; using Mango.Nop.Core.Interfaces; using Nop.Core.Domain.Catalog; namespace FruitBank.Common.Interfaces; -public interface IOrderItemDto : IMgOrderItemDto, IMeasuringValues, IMeasured, IMeasurable +public interface IOrderItemDto : IMgOrderItemDto, IMeasuringValues, IMeasured, IMeasurable, IMeasurableStatus { OrderDto OrderDto { get; set; } List OrderItemPallets { get; set; } diff --git a/FruitBank.Common/Interfaces/IOrderItemPallet.cs b/FruitBank.Common/Interfaces/IOrderItemPallet.cs index e12634f..2297768 100644 --- a/FruitBank.Common/Interfaces/IOrderItemPallet.cs +++ b/FruitBank.Common/Interfaces/IOrderItemPallet.cs @@ -7,5 +7,9 @@ namespace FruitBank.Common.Interfaces; public interface IOrderItemPallet : IMeasuringItemPalletBase { int OrderItemId { get; set; } + bool IsAudited { get; } + int RevisorId { get; set; } + public OrderItemDto? OrderItemDto { get; set; } + } \ No newline at end of file diff --git a/FruitBank.Common/Models/LoggedInModel.cs b/FruitBank.Common/Models/LoggedInModel.cs index 607eee7..3155bad 100644 --- a/FruitBank.Common/Models/LoggedInModel.cs +++ b/FruitBank.Common/Models/LoggedInModel.cs @@ -9,6 +9,7 @@ public class LoggedInModel { public bool IsLoggedIn => CustomerDto != null; public bool IsRevisor => IsLoggedIn && CustomerRoles.Any(x => x.SystemName.ToLowerInvariant() == "measuringrevisor"); + public bool IsAdministrator => IsLoggedIn && CustomerRoles.Any(x => x.SystemName.ToLowerInvariant() == "administrators"); public CustomerDto? CustomerDto { get; private set; } public List CustomerRoles { get; private set; } = []; diff --git a/FruitBank.Common/Models/SignalRs/SignalRMessageToClientWithText.cs b/FruitBank.Common/Models/SignalRs/SignalRMessageToClientWithText.cs new file mode 100644 index 0000000..3ef3d99 --- /dev/null +++ b/FruitBank.Common/Models/SignalRs/SignalRMessageToClientWithText.cs @@ -0,0 +1,9 @@ +using FruitBank.Common.Dtos; + +namespace FruitBank.Common.Models.SignalRs; + +public class SignalRMessageToClientWithText(string? message, T? content) +{ + public string? Message { get; set; } = message; + public T? Content { get; set; } = content; +} \ No newline at end of file diff --git a/FruitBank.Common/Services/MeasurementServiceBase.cs b/FruitBank.Common/Services/MeasurementServiceBase.cs new file mode 100644 index 0000000..23df5a4 --- /dev/null +++ b/FruitBank.Common/Services/MeasurementServiceBase.cs @@ -0,0 +1,8 @@ +using FruitBank.Common.Interfaces; + +namespace FruitBank.Common.Services; + +public class MeasurementServiceBase : IMeasurementServiceBase +{ + +} \ No newline at end of file diff --git a/FruitBank.Common/SignalRs/SignalRTags.cs b/FruitBank.Common/SignalRs/SignalRTags.cs index 4c003b5..e631f72 100644 --- a/FruitBank.Common/SignalRs/SignalRTags.cs +++ b/FruitBank.Common/SignalRs/SignalRTags.cs @@ -6,6 +6,8 @@ public class SignalRTags : AcSignalRTags { public const int GetSiteViewModelByUserId = int.MaxValue; + public const int NotificationReceived = 5; + public const int GetMeasuringModels = 10; public const int GetPartners = 20; @@ -39,7 +41,6 @@ public class SignalRTags : AcSignalRTags public const int GetAllMeasuringProductDtos = 82; public const int GetMeasuringProductDtoById = 83; - public const int AddShippingItemPallet = 95; public const int UpdateShippingItemPallet = 96; public const int AddOrUpdateMeasuredShippingItemPallet = 97; @@ -47,19 +48,43 @@ public class SignalRTags : AcSignalRTags public const int GetAllOrderDtos = 111; public const int GetOrderDtoById = 112; - public const int GetAllOrderDtoByIds = 114; - public const int GetPendingOrderDtos = 115; + public const int GetAllOrderDtoByIds = 113; + public const int GetPendingOrderDtos = 114; + public const int GetAllOrderDtoByProductId = 115; public const int GetPendingOrderDtosForMeasuring = 116; public const int StartMeasuring = 117; public const int SetOrderStatusToComplete = 118; - public const int AddOrderItemPallet = 131; - public const int UpdateOrderItemPallet = 132; - public const int AddOrUpdateMeasuredOrderItemPallet = 133; - public const int AddOrUpdateMeasuredOrderItemPallets = 134; + public const int GetOrderItemDtoById = 120; + public const int GetAllOrderItemDtos = 121; + public const int GetAllOrderItemDtoByOrderId = 122; + public const int GetAllOrderItemDtoByProductId = 123; + + public const int GetAllOrderItemPallets = 130; + public const int GetOrderItemPalletById = 131; + public const int GetAllOrderItemPalletByOrderItemId = 132; + public const int GetAllOrderItemPalletByProductId = 133; + public const int GetAllOrderItemPalletByOrderId = 134; + public const int AddOrderItemPallet = 135; + public const int UpdateOrderItemPallet = 136; + public const int AddOrUpdateMeasuredOrderItemPallet = 137; + public const int AddOrUpdateMeasuredOrderItemPallets = 138; public const int AuthenticateUser = 195; public const int RefreshToken = 200; + #region SendToClient + public const int SendOrderChanged = 500; + public const int SendOrderItemChanged = 501; + public const int SendOrderItemPalletChanged = 502; + + public const int SendShippingChanged = 520; + public const int SendShippingItemChanged = 521; + public const int SendShippingDocumentChanged = 522; + public const int SendShippingItemPalletChanged = 523; + + public const int SendProductChanged = 540; + #endregion SendToClient + public const int GetAllLogItemsByFilterText = 1000; } diff --git a/FruitBankHybrid.Shared.Tests/OrderClientTests.cs b/FruitBankHybrid.Shared.Tests/OrderClientTests.cs index f0fbbfa..ba4827a 100644 --- a/FruitBankHybrid.Shared.Tests/OrderClientTests.cs +++ b/FruitBankHybrid.Shared.Tests/OrderClientTests.cs @@ -55,7 +55,7 @@ public sealed class OrderClientTests [TestMethod] public async Task GetPendingOrderDtos() { - var pendingOrderDtos = await _signalRClient.GetPendingOrderDtosForMeasuring(); + var pendingOrderDtos = await _signalRClient.GetPendingOrderDtos(); Assert.IsNotNull(pendingOrderDtos); @@ -63,6 +63,17 @@ public sealed class OrderClientTests Assert.IsTrue(pendingOrderDtos.Count != 0); } + [TestMethod] + public async Task GetPendingOrderDtosForMeasuring() + { + var orderDtosForMeasuring = await _signalRClient.GetPendingOrderDtosForMeasuring(); + + Assert.IsNotNull(orderDtosForMeasuring); + //Assert.IsTrue(orderDtosForMeasuring.Any(x=>x.Id ==51)); + Assert.IsTrue(orderDtosForMeasuring.All(o => o.OrderStatus == OrderStatus.Pending)); + Assert.IsTrue(orderDtosForMeasuring.Count != 0); + } + [TestMethod] [DataRow(new[] {1,2,4,7})] public async Task GetOrderDtoByIds(int[] orderIds) diff --git a/FruitBankHybrid.Shared/Components/GridDetailOrderDto.razor b/FruitBankHybrid.Shared/Components/GridDetailOrderDto.razor new file mode 100644 index 0000000..88f2da7 --- /dev/null +++ b/FruitBankHybrid.Shared/Components/GridDetailOrderDto.razor @@ -0,0 +1,106 @@ +@using FruitBank.Common.Dtos +@using FruitBankHybrid.Shared.Services.SignalRs + +@inject FruitBankSignalRClient FruitBankSignalRClient + + + + + + + + + + + + + + + + + + @if (IsMasterGrid) + { + var orderDto = ((OrderDto)context.DataItem); + + + + + + + @{ + var orderItemPalletDtos = orderDto?.OrderItemDtos.SelectMany(oi => oi.OrderItemPallets).ToList() ?? []; + + } + + + + } + + @* + + + + + + + + *@ + + + + + + + +@code { + [Parameter] public bool IsMasterGrid { get; set; } = false; + //[Parameter] public OrderDto? OrderDto { get; set; } + [Parameter] public List? OrderDtos { get; set; } + + private int _activeTabIndex; + protected override void OnInitialized() + { + // if (OrderDto != null) + // OrderItemDtos = OrderDto.OrderItemDtos; + } + + protected async Task OnActiveTabChanged(int activeTabIndex) + { + _activeTabIndex = activeTabIndex; + return; + + // switch (_activeTabIndex) + // { + // case 0: + // if(ProductDtos == null) + // ProductDtos = (await FruitBankSignalRClient.GetProductDtos() ?? []); //.Where(o => o.HasMeasuringAccess(LoggedInModel.CustomerDto?.Id, LoggedInModel.IsRevisor)).OrderBy(o => o.DateOfReceipt).ToList(); + // break; + // case 1: + // if(OrderDtos == null) + // OrderDtos = (await FruitBankSignalRClient.GetAllOrderDtos() ?? []).OrderByDescending(o => o.Id).ToList(); //.Where(o => o.HasMeasuringAccess(LoggedInModel.CustomerDto?.Id, LoggedInModel.IsRevisor)).OrderBy(o => o.DateOfReceipt).ToList(); + // break; + // case 2: + // if (OrderItemDtos == null) + // OrderItemDtos = (await FruitBankSignalRClient.GetAllOrderItemDtos() ?? []).OrderByDescending(o => o.Id).ToList(); //.Where(o => o.HasMeasuringAccess(LoggedInModel.CustomerDto?.Id, LoggedInModel.IsRevisor)).OrderBy(o => o.DateOfReceipt).ToList(); + // break; + // } + } +} + diff --git a/FruitBankHybrid.Shared/Components/GridDetailOrderItemDto.razor b/FruitBankHybrid.Shared/Components/GridDetailOrderItemDto.razor new file mode 100644 index 0000000..dac0c33 --- /dev/null +++ b/FruitBankHybrid.Shared/Components/GridDetailOrderItemDto.razor @@ -0,0 +1,86 @@ +@using FruitBank.Common.Dtos +@using FruitBankHybrid.Shared.Services.SignalRs + +@inject FruitBankSignalRClient FruitBankSignalRClient + +@*
+ Contact Phone: @OrderDto.Email +
*@ + + + + + + + + + + + + + + + + + @* *@ + + + + + + + + + + + +@code { + [Parameter] public bool IsMasterGrid { get; set; } = false; + //[Parameter] public OrderDto? OrderDto { get; set; } + [Parameter] public List? OrderItemDtos { get; set; } + + protected override void OnInitialized() + { + // if (OrderDto != null) + // OrderItemDtos = OrderDto.OrderItemDtos; + } + +} + +@* List GenericAttributes { get; set; } + List OrderItemPallets { get; set; } + OrderDto OrderDto { get; set; } + bool IsMeasured + bool IsMeasurable + int TrayQuantity + double NetWeight + double GrossWeight + + public Guid OrderItemGuid { get; set; } + public int OrderId { get; set; } + public int ProductId { get; set; } + public int Quantity { get; set; } + + public decimal UnitPriceInclTax { get; set; } + public decimal UnitPriceExclTax { get; set; } + + public decimal PriceInclTax { get; set; } + public decimal PriceExclTax { get; set; } + + public string AttributesXml { get; set; } + public decimal? ItemWeight { get; set; } + + public string ProductName => ProductDto?.Name ?? "ProductDto is null!!!"; + + public TProductDto? ProductDto { get; set; } + *@ \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/GridDetailOrderItemPallets.razor b/FruitBankHybrid.Shared/Components/GridDetailOrderItemPallets.razor new file mode 100644 index 0000000..375567d --- /dev/null +++ b/FruitBankHybrid.Shared/Components/GridDetailOrderItemPallets.razor @@ -0,0 +1,110 @@ +@using FruitBank.Common.Dtos +@using FruitBank.Common.Entities +@using FruitBankHybrid.Shared.Services.SignalRs + +@inject FruitBankSignalRClient FruitBankSignalRClient + + + + + + + + + + + + + + + + + + + + + + + + + +@code { + IGrid gridOrderItemPallet; + + [Parameter] public bool IsMasterGrid { get; set; } = false; + [Parameter] public List? OrderItemPallets { get; set; } + + protected override async Task OnInitializedAsync() + { + if (OrderItemPallets == null) + { + OrderItemPallets = await FruitBankSignalRClient.GetAllOrderItemPallets(); + + if (OrderItemPallets != null && OrderItemPallets.Any(oip => oip.OrderItemDto?.ProductDto != null)) + { + gridOrderItemPallet.BeginUpdate(); + + gridOrderItemPallet.GetColumns().FirstOrDefault(x => x.Name == "ProductId")!.Visible = true; + gridOrderItemPallet.GetColumns().FirstOrDefault(x => x.Name == "ProductName")!.Visible = true; + + gridOrderItemPallet.EndUpdate(); + } + + } + } + + protected override Task OnAfterRenderAsync(bool firstRender) + { + if (firstRender) + { + // if (OrderItemPallets != null && OrderItemPallets.Any(oip => oip.OrderItemDto?.ProductDto != null)) + // { + // gridOrderItemPallet.BeginUpdate(); + + // gridOrderItemPallet.GetColumns().FirstOrDefault(x => x.Name == "ProductId")!.Visible = true; + // gridOrderItemPallet.GetColumns().FirstOrDefault(x => x.Name == "ProductName")!.Visible = true; + + // gridOrderItemPallet.EndUpdate(); + // } + } + + return base.OnAfterRenderAsync(firstRender); + } + +} + +@* List GenericAttributes { get; set; } + List OrderItemPallets { get; set; } + OrderDto OrderDto { get; set; } + bool IsMeasured + bool IsMeasurable + int TrayQuantity + double NetWeight + double GrossWeight + + public Guid OrderItemGuid { get; set; } + public int OrderId { get; set; } + public int ProductId { get; set; } + public int Quantity { get; set; } + + public decimal UnitPriceInclTax { get; set; } + public decimal UnitPriceExclTax { get; set; } + + public decimal PriceInclTax { get; set; } + public decimal PriceExclTax { get; set; } + + public string AttributesXml { get; set; } + public decimal? ItemWeight { get; set; } + + public string ProductName => ProductDto?.Name ?? "ProductDto is null!!!"; + + public TProductDto? ProductDto { get; set; } + *@ \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/GridProductDto.cs b/FruitBankHybrid.Shared/Components/GridProductDto.cs new file mode 100644 index 0000000..619e85c --- /dev/null +++ b/FruitBankHybrid.Shared/Components/GridProductDto.cs @@ -0,0 +1,5 @@ +namespace FruitBankHybrid.Shared.Components; + +public class GridProductDto : MgGridBase +{ +} \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor b/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor new file mode 100644 index 0000000..b3a303b --- /dev/null +++ b/FruitBankHybrid.Shared/Components/GridProductDtoTemplate.razor @@ -0,0 +1,120 @@ +@using AyCode.Core.Helpers +@using DevExpress.Internal.About +@using FruitBank.Common.Dtos +@using FruitBankHybrid.Shared.Services.SignalRs + +@inject FruitBankSignalRClient FruitBankSignalRClient + + + + + + + + + + + + + + @if (IsMasterGrid) + { + var productId = ((ProductDto)context.DataItem).Id; + + + + @{ + //GetOrderDtosFromDbAsync(productId).Forget(); + //var orderDtos = _orderDtos?.Where(o => o.OrderItemDtos.Any(oi => oi.ProductId == productId)).ToList() ?? []; + + } + + + @{ + //GetOrderItemDtosFromDbAsync(productId).Forget(); + //var orderItemDtos = _orderItemDtos?.Where(oi => oi.ProductId == productId).ToList() ?? []; + + } + + + + } + + + + + +@code { + private int _activeTabIndex; + + private List? _currentOrderDtos; + private List? _currentOrderItemDtos; + + private readonly Dictionary> _orderDtosByProductId = new(); + private readonly Dictionary> _orderItemDtosByProductId = new(); + + [Parameter] public bool IsMasterGrid { get; set; } = false; + [Parameter] public List? ProductDtos { get; set; } + //[Parameter] public List? OrderDtos { get; set; } + //[Parameter] public List? OrderItemDtos { get; set; } + + protected override async Task OnInitializedAsync() + { + ProductDtos ??= await FruitBankSignalRClient.GetProductDtos(); + + // if (ProductDtos is { Count: > 0 }) + // _currentOrderDtos = await GetOrderDtosFromDbAsync(ProductDtos[0].Id); + } + + private async Task> GetOrderDtosFromDbAsync(int productId) + { + if (_orderDtosByProductId.TryGetValue(productId, out var orderDtos)) return orderDtos; + + orderDtos = await FruitBankSignalRClient.GetAllOrderDtoByProductId(productId) ?? []; + _orderDtosByProductId[productId] = orderDtos; + + return _currentOrderDtos = orderDtos; + } + + private async Task> GetOrderItemDtosFromDbAsync(int productId) + { + if (_orderItemDtosByProductId.TryGetValue(productId, out var orderItemDtos)) return orderItemDtos; + + orderItemDtos = await FruitBankSignalRClient.GetAllOrderItemDtoByProductId(productId) ?? []; + _orderItemDtosByProductId[productId] = orderItemDtos; + + return _currentOrderItemDtos = orderItemDtos; + } + + protected async Task OnFocusedRowChanged(GridFocusedRowChangedEventArgs e) + { + var productDto = (ProductDto)e.DataItem; + + //if (e.Grid.IsDetailRowExpanded(e.VisibleIndex)) + { + _currentOrderDtos = null; + _currentOrderDtos = productDto != null ? await GetOrderDtosFromDbAsync(productDto.Id) : []; + } + } + + protected async Task OnActiveTabChanged(int activeTabIndex, int productId) + { + _activeTabIndex = activeTabIndex; + + switch (_activeTabIndex) + { + case 0: + //_currentOrderDtos = null; + _currentOrderDtos = await GetOrderDtosFromDbAsync(productId); + break; + case 1: + _currentOrderItemDtos = null; + _currentOrderItemDtos = await GetOrderItemDtosFromDbAsync(productId); + break; + } + } +} \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/MgGridBase.cs b/FruitBankHybrid.Shared/Components/MgGridBase.cs new file mode 100644 index 0000000..7c2b4d4 --- /dev/null +++ b/FruitBankHybrid.Shared/Components/MgGridBase.cs @@ -0,0 +1,87 @@ +using AyCode.Core.Loggers; +using DevExpress.Blazor; +using FruitBankHybrid.Shared.Services.SignalRs; +using Microsoft.AspNetCore.Components; + +namespace FruitBankHybrid.Shared.Components; + +public class MgGridBase : DxGrid +{ + private bool _isFirstInitializeParameters; + [Inject] public required IEnumerable LogWriters { get; set; } + [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } + + [Parameter] public bool IsMasterGrid { get; set; } = false; + + [Parameter] + public required object DataSource + { + get => Data; + set => Data = value; + } + + protected void OnCustomizeElement(GridCustomizeElementEventArgs e) + { + //if (!IsMasterGrid) e.CssClass = "hideDetailButton"; + + if (IsMasterGrid && e.ElementType == GridElementType.DataRow && e.VisibleIndex % 2 == 1 && !e.Grid.IsRowSelected(e.VisibleIndex) && !e.Grid.IsRowFocused(e.VisibleIndex)) + { + e.CssClass = " alt-item"; + } + + if(e.ElementType == GridElementType.HeaderCell) { + e.Style = "background-color: #E6E6E6;"; + //e.CssClass = "header-bold"; + } + } + protected override Task SetParametersAsyncCore(ParameterView parameters) + { + if (!_isFirstInitializeParameters) + { + //if (typeof(TDataItem) is IId || typeof(TDataItem) is IId) + KeyFieldName = "Id"; + + //base.DataItemDeleting = EventCallback.Factory.Create(this, OnItemDeleting); + //base.EditModelSaving = EventCallback.Factory.Create(this, OnItemSaving); + + CustomizeElement += OnCustomizeElement; + + //ShowFilterRow = true; + //PageSize = 4; + //ShowGroupPanel = true; + //AllowSort = false; + + TextWrapEnabled = false; + AllowSelectRowByClick = true; + HighlightRowOnHover = true; + AutoCollapseDetailRow = true; + AutoExpandAllGroupRows = false; + + //KeyboardNavigationEnabled = true; + + //var dataColumns = GetDataColumns(); + + //var idColumn = dataColumns.FirstOrDefault(x => x.FieldName == nameof(IId.Id)); + //if (idColumn != null) + //{ + // idColumn.ShowInColumnChooser = AcDomain.IsDeveloperVersion; + // idColumn.Visible = !AcDomain.IsDeveloperVersion; + //} + + _isFirstInitializeParameters = true; + } + + return base.SetParametersAsyncCore(parameters); + } + + + protected override void OnParametersSet() + { + base.OnParametersSet(); + + ShowGroupPanel = IsMasterGrid; + ShowSearchBox = IsMasterGrid; + DetailRowDisplayMode = IsMasterGrid ? GridDetailRowDisplayMode.Auto : GridDetailRowDisplayMode.Never; + DetailExpandButtonDisplayMode = IsMasterGrid ? GridDetailExpandButtonDisplayMode.Auto : GridDetailExpandButtonDisplayMode.Never; + } +} \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Components/PalletItemComponent.razor b/FruitBankHybrid.Shared/Components/PalletItemComponent.razor index 7235365..56fad7d 100644 --- a/FruitBankHybrid.Shared/Components/PalletItemComponent.razor +++ b/FruitBankHybrid.Shared/Components/PalletItemComponent.razor @@ -1,15 +1,17 @@ @using AyCode.Core.Loggers +@using FruitBank.Common.Dtos @using FruitBank.Common.Entities @using FruitBank.Common.Helpers @using FruitBank.Common.Interfaces @using FruitBank.Common.Models @using FruitBank.Common.SignalRs +@using FruitBankHybrid.Shared.Extensions @using FruitBankHybrid.Shared.Services @using FruitBankHybrid.Shared.Services.SignalRs @typeparam TPalletItem where TPalletItem : class, IMeasuringItemPalletBase + ItemUpdating="@((pair) => OnItemUpdating(pair.Key, pair.Value, PalletItem))" Enabled="IsEditable"> @(MeasuringIndex). MÉRÉS @@ -17,38 +19,51 @@ - - + Field="@nameof(ShippingItemPallet.TareWeight)" + Enabled="@(IsEditable && IsMeasurable && ProductId > 0)" + Caption="Tára(kg)" ColSpanMd="2" /> + + @* *@ + + Field="@nameof(ShippingItemPallet.TrayQuantity)" + Enabled="@(IsEditable && ProductId > 0)" + Caption="Rekesz/csomag" ColSpanMd="2" /> + Field="@nameof(ShippingItemPallet.GrossWeight)" + Enabled="@(IsEditable && IsMeasurable && ProductId > 0)" + Caption="Br.súly(kg)" ColSpanMd="2"> @(PalletItem.NetWeight) kg. - - + + + @if (HasAuditButton) + { + + + + } @code { + [Inject] public required IEnumerable LogWriters { get; set; } + [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } + [Inject] public required LoggedInModel LoggedInModel { get; set; } + [Inject] private IDialogService DialogService { get; set; } = null!; + [Parameter] public required TPalletItem PalletItem { get; set; } [Parameter] public required bool IsMeasurable { get; set; } [Parameter] public required int ProductId { get; set; } @@ -56,20 +71,28 @@ [Parameter] public int? AddOrUpdateSignalRTag { get; set; } = null; [Parameter] public int? MaxTrayQuantity { get; set; } = null; + [Parameter] public bool IsEditable { get; set; } = true; //[Parameter] public EventCallback OnPalletItemSaveClick { get; set; } [Parameter] public Func? OnPalletItemSaved { get; set; } [Parameter] public Func? OnPalletItemValueChanged { get; set; } - - [Inject] public required IEnumerable LogWriters { get; set; } - [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } - [Inject] public required LoggedInModel LoggedInModel { get; set; } + [Parameter] public Func? OnPalletItemAuditedClick { get; set; } //public bool LoadingPanelVisible { get; set; } = false; + //public bool IsEditable => !HasAuditButton || (OrderItemPallet.IsAudited); public bool BtnSaveEnabled { get; set; } + + bool HasAuditButton => LoggedInModel.IsRevisor && IsOrderItemPallet; + + + public bool IsOrderItemPallet => OrderItemPallet != null; + public OrderItemPallet? OrderItemPallet => (PalletItem as OrderItemPallet); + private bool GetBtnSaveEnabled() - => PalletItem.IsValidMeasuringValues(IsMeasurable) && !PalletItem.IsMeasured && (!MaxTrayQuantity.HasValue || PalletItem.TrayQuantity <= MaxTrayQuantity.Value); + { + return IsEditable && PalletItem.IsValidMeasuringValues(IsMeasurable) && !PalletItem.IsMeasured && (!MaxTrayQuantity.HasValue || PalletItem.TrayQuantity <= MaxTrayQuantity.Value); + } protected override async Task OnInitializedAsync() { @@ -81,7 +104,7 @@ private string GetOrderItemPalletsCssClassNames(string fieldName) - => MeasuringService.GetCustomItemPalletsCssClassNames(fieldName, PalletItem, IsMeasurable, MaxTrayQuantity); + => MeasurementService.GetCustomItemPalletsCssClassNames(fieldName, PalletItem, IsMeasurable, MaxTrayQuantity); private async Task PalletItemSaveClick() { @@ -91,8 +114,8 @@ if (AddOrUpdateSignalRTag == null) throw new Exception($"PalletItemComponent->PalletItemSaveClick(); AddOrUpdateSignalRTag == null"); PalletItem.ModifierId = LoggedInModel.CustomerDto?.Id; - var responseShippingItemPallet = await FruitBankSignalRClient.PostDataAsync(AddOrUpdateSignalRTag!.Value, 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!"); @@ -142,4 +165,29 @@ if (OnPalletItemValueChanged != null) await OnPalletItemValueChanged.Invoke(palletItem); } + + private async Task PalletItemAuditedClick() + { + if (OnPalletItemAuditedClick != 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)) + { + OrderItemPallet.RevisorId = LoggedInModel.CustomerDto!.Id; + + StateHasChanged(); //Az Audit button miatt kell a StateHasChanged(), most már van RevisorId és emiatt disabled lesz... + + var responseShippingItemPallet = await FruitBankSignalRClient.PostDataAsync(AddOrUpdateSignalRTag!.Value, PalletItem); + if (responseShippingItemPallet == null) + { + OrderItemPallet.RevisorId = 0; //Sikertelen volt a mentés... + 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); + } + } + } + } diff --git a/FruitBankHybrid.Shared/Layout/MainLayout.razor b/FruitBankHybrid.Shared/Layout/MainLayout.razor index 8a64a5c..ad11a2d 100644 --- a/FruitBankHybrid.Shared/Layout/MainLayout.razor +++ b/FruitBankHybrid.Shared/Layout/MainLayout.razor @@ -3,7 +3,7 @@
@@ -11,7 +11,7 @@ @if (LoggedInModel.IsLoggedIn) {
- @($"{LoggedInModel.CustomerDto!.FullName} [{string.Join(", ", LoggedInModel.CustomerRoles.Where(x=>x.SystemName.Contains("Measuring")).Select(x => x.Name))}]") + @($"{LoggedInModel.CustomerDto!.FullName} [{string.Join(", ", LoggedInModel.CustomerRoles.Where(x => x.SystemName.Contains("Measuring")).Select(x => x.Name))}]")
@@ -21,6 +21,17 @@
+ + + @Body diff --git a/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs b/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs index 813431f..af42fbe 100644 --- a/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs +++ b/FruitBankHybrid.Shared/Layout/MainLayout.razor.cs @@ -1,26 +1,79 @@ -using FruitBank.Common.Models; +using AyCode.Core.Consts; +using AyCode.Core.Extensions; +using AyCode.Core.Loggers; +using AyCode.Services.SignalRs; +using DevExpress.Blazor; +using FruitBank.Common.Dtos; +using FruitBank.Common.Models; +using FruitBank.Common.Models.SignalRs; +using FruitBank.Common.SignalRs; +using FruitBankHybrid.Shared.Pages; +using FruitBankHybrid.Shared.Services.Loggers; +using FruitBankHybrid.Shared.Services.SignalRs; +using Mango.Nop.Core.Loggers; +using MessagePack.Resolvers; using Microsoft.AspNetCore.Components; namespace FruitBankHybrid.Shared.Layout; public partial class MainLayout : LayoutComponentBase { + [Inject] public required IEnumerable LogWriters { get; set; } [Inject] public required NavigationManager NavManager{ get; set; } [Inject] public required LoggedInModel LoggedInModel { get; set; } + [Inject] IToastNotificationService ToastService { get; set; } + [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } private EventCallback RefreshMainLayoutEventCallback => EventCallback.Factory.Create(this, RefreshMainLayout); private NavMenu _navMenu = null!; + private ILogger _logger = null!; protected override void OnInitialized() { + _logger = new LoggerClient(LogWriters.ToArray()); + _logger.Info("OnInitializedAsync"); + var loginUri = NavManager.ToAbsoluteUri("/Login").ToString(); + FruitBankSignalRClient.OnMessageReceived += SignalRClientOnMessageReceived; + if (!LoggedInModel.IsLoggedIn && NavManager.Uri != loginUri) { NavManager.NavigateTo("/Login"); } } + private Task SignalRClientOnMessageReceived(int messageTag, string? jsonMessage) + { + if (messageTag != SignalRTags.NotificationReceived || !LoggedInModel.IsLoggedIn) return Task.CompletedTask; + + var notificationMessage = jsonMessage?.JsonTo>(); + if (notificationMessage == null) + { + _logger.Error($"notificationMessage == null"); + return Task.CompletedTask; + } + + if (!(notificationMessage.Content?.HasMeasuringAccess(LoggedInModel.CustomerDto!.Id, LoggedInModel.IsRevisor) ?? LoggedInModel.IsRevisor)) return Task.CompletedTask; + + var messageText = $"{notificationMessage.Message}"; + if (notificationMessage.Content != null) + { + messageText += $" Rendelés: #{notificationMessage.Content.CustomOrderNumber}. Átvétel: {notificationMessage.Content.DateOfReceipt}"; + } + + _logger.Info($"NotificationMessage received. {messageText}"); + + ToastService.ShowToast(new ToastOptions + { + ProviderName = "Positioning", + Title = "Király vagyok!", + Text = messageText, + }); + + return Task.CompletedTask; + } + private void OnLogoutClick() { LoggedInModel.LogOut(); diff --git a/FruitBankHybrid.Shared/Layout/NavMenu.razor b/FruitBankHybrid.Shared/Layout/NavMenu.razor index c78681c..858355e 100644 --- a/FruitBankHybrid.Shared/Layout/NavMenu.razor +++ b/FruitBankHybrid.Shared/Layout/NavMenu.razor @@ -36,6 +36,15 @@ Kimenő mérés
+ + @if (LoggedInModel.IsAdministrator) + { + + } } else { diff --git a/FruitBankHybrid.Shared/Pages/MeasuringIn.razor b/FruitBankHybrid.Shared/Pages/MeasuringIn.razor index ba13c7e..0340a99 100644 --- a/FruitBankHybrid.Shared/Pages/MeasuringIn.razor +++ b/FruitBankHybrid.Shared/Pages/MeasuringIn.razor @@ -20,7 +20,7 @@ Text="Adatok szinkronizálása folyamatban..."> - + new MeasuringDateSelectorModel(shipping.Id, shipping.ShippingDate.Date, shipping.IsAllMeasured)).ToList(); - NotMeasuredShippings = shippings.Where(shipping => MeasuringService.DaysEqual(shipping.ShippingDate.Date, dateTime)).ToList(); + NotMeasuredShippings = shippings.Where(shipping => MeasurementService.DaysEqual(shipping.ShippingDate.Date, dateTime)).ToList(); SelectedShipping = NotMeasuredShippings.FirstOrDefault(); @@ -69,13 +69,13 @@ namespace FruitBankHybrid.Shared.Pages private void OnCustomDisabledMeasuringDate(CalendarCustomDisabledDateEventArgs args) - => MeasuringService.OnCustomDisabledDate(args, _measuringDates); + => MeasurementService.OnCustomDisabledDate(args, _measuringDates); private string GetMeasuringDateCssClassNames(DateTime date) - => MeasuringService.GetShippingDateCssClassNames(date, _measuringDates); + => MeasurementService.GetShippingDateCssClassNames(date, _measuringDates); private string GetShippingPalletsCssClassNames(string fieldName, ShippingItemPallet shippingItemPallet) - => MeasuringService.GetCustomItemPalletsCssClassNames(fieldName, shippingItemPallet, SelectedShippingItem!.IsMeasurable); + => MeasurementService.GetCustomItemPalletsCssClassNames(fieldName, shippingItemPallet, SelectedShippingItem!.IsMeasurable); private void OnSelectedShippingChanged(SelectedDataItemChangedEventArgs eventArgs) { @@ -154,7 +154,7 @@ namespace FruitBankHybrid.Shared.Pages } private bool IsShippingitemPalletMeasuredAndValid(ShippingItemPallet shippingItemPallet) - => MeasuringService.IsCustomItemPalletMeasuredAndValid(shippingItemPallet, SelectedShippingItem!.IsMeasurable); + => MeasurementService.IsCustomItemPalletMeasuredAndValid(shippingItemPallet, SelectedShippingItem!.IsMeasurable); private void LogErrorAndDisplayText(string errorText, Exception? ex = null) { diff --git a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor index b255f92..54245d2 100644 --- a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor +++ b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor @@ -23,7 +23,7 @@ + CaptionCssClass="@(SelectedOrder != null && _measuringDates.Where(x => MeasurementService.DaysEqual(x.DateTime, SelectedOrder.DateOfReceiptOrCreated)).All(x => x.IsMeasured) ? "text-success" : "")"> - } @@ -124,7 +125,7 @@ Rendelés azonosító: #@(SelectedOrder?.CustomOrderNumber) - @@ -159,7 +160,7 @@ //text = ((OrderItemPallet)(context.DataItem)).OrderItemId.ToString() + " dfgdfsg"; //var selectedOrderItemDto = SelectedOrder!.OrderItemDtos.First(x => x.Id == orderItemPallet.OrderItemId); var selectedOrderItemDto = (OrderItemDto)(context.DataItem); - + SelectedOrderItem = selectedOrderItemDto; @for (var index = 0; index < (selectedOrderItemDto?.OrderItemPallets?.Count ?? 0); index++) @@ -169,24 +170,29 @@ + OnPalletItemValueChanged="pallet => OnOrderItemPalletValueChanged(pallet, selectedOrderItemDto)" + OnPalletItemAuditedClick="pallet => OnPalletItemAuditedClick(pallet, selectedOrderItemDto)"> } + diff --git a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor.cs b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor.cs index 49c522d..582f312 100644 --- a/FruitBankHybrid.Shared/Pages/MeasuringOut.razor.cs +++ b/FruitBankHybrid.Shared/Pages/MeasuringOut.razor.cs @@ -1,30 +1,36 @@ -using AyCode.Core.Loggers; +using AyCode.Core.Extensions; +using AyCode.Core.Loggers; +using AyCode.Services.SignalRs; using DevExpress.Blazor; +using DevExpress.Xpo.DB; using FruitBank.Common.Dtos; using FruitBank.Common.Entities; +using FruitBank.Common.Helpers; +using FruitBank.Common.Interfaces; using FruitBank.Common.Models; +using FruitBank.Common.Models.SignalRs; +using FruitBank.Common.SignalRs; +using FruitBankHybrid.Shared.Extensions; using FruitBankHybrid.Shared.Models; using FruitBankHybrid.Shared.Services; using FruitBankHybrid.Shared.Services.Loggers; using FruitBankHybrid.Shared.Services.SignalRs; +using Mango.Nop.Core.Extensions; using Mango.Nop.Core.Loggers; +using MessagePack.Resolvers; using Microsoft.AspNetCore.Components; +using Nop.Core.Domain.Orders; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using FruitBank.Common.Helpers; -using FruitBank.Common.Interfaces; -using AyCode.Core.Extensions; -using FruitBankHybrid.Shared.Extensions; -using Mango.Nop.Core.Extensions; -using Nop.Core.Domain.Orders; namespace FruitBankHybrid.Shared.Pages { public partial class MeasuringOut : ComponentBase { + private readonly object _lock = new object(); [Inject] public required IEnumerable LogWriters { get; set; } [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } [Inject] public required NavigationManager NavManager{ get; set; } @@ -35,9 +41,9 @@ namespace FruitBankHybrid.Shared.Pages private string _errorText; public bool HasMeasuringAccess; - public bool LoadingPanelVisible { get; set; } = true; - + public bool IsAllOrderItemPalletAudited => SelectedOrder?.IsAllOrderItemAudited ?? false; + private DateTime SelectedDate; private List SelectedDayOrders { get; set; } = null!; private OrderDto? SelectedOrder { get; set; } private OrderItemDto? SelectedOrderItem { get; set; } @@ -52,43 +58,117 @@ namespace FruitBankHybrid.Shared.Pages _logger = new LoggerClient(LogWriters.ToArray()); _logger.Info("OnInitializedAsync"); + FruitBankSignalRClient.OnMessageReceived += SignalRClientOnMessageReceived; + await RefreshOrdersFromDb(DateTime.Now); await base.OnInitializedAsync(); } + private async Task SignalRClientOnMessageReceived(int messageTag, string? jsonMessage) + { + if (!LoggedInModel.IsLoggedIn) return; + + if (messageTag != SignalRTags.SendOrderChanged && messageTag != SignalRTags.SendOrderItemChanged && + messageTag != SignalRTags.SendOrderItemPalletChanged && messageTag != SignalRTags.SendProductChanged) return; + + + _logger.Detail($"SignalRClientOnMessageReceived received. {jsonMessage}"); + + OrderDto? orderDto; + switch (messageTag) + { + case SignalRTags.SendOrderChanged: + orderDto = jsonMessage?.JsonTo(); + if (orderDto == null) break; + + if (orderDto.DateOfReceipt == null) 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)); + + if (SelectedDate != orderDto.DateOfReceipt.Value.Date) return; + + var selectedOrderId = SelectedOrder?.Id; + + SelectedDayOrders.UpdateCollection(orderDto, false); + if (selectedOrderId.GetValueOrDefault(-1) == orderDto.Id) SelectedOrder = orderDto; + } + + await InvokeAsync(StateHasChanged); + return; + case SignalRTags.SendOrderItemChanged: + var orderItemDto = jsonMessage?.JsonTo(); + if (orderItemDto == null) break; + + return; + case SignalRTags.SendOrderItemPalletChanged: + var orderItemPallet = jsonMessage?.JsonTo(); + if (orderItemPallet == null) break; + + lock (_lock) + { + var orderItemDtos = SelectedDayOrders.FirstOrDefault(x => x.OrderItemDtos.Any(oi => oi.Id == orderItemPallet.OrderItemId))?.OrderItemDtos; + var orderItem = orderItemDtos?.FirstOrDefault(oi => oi.Id == orderItemPallet.OrderItemId); + if (orderItem == null) return; + + var orderItemPalletsCount = orderItem.OrderItemPallets.Count; + + if (orderItem.OrderItemPallets[orderItemPalletsCount - 1].Id == 0) orderItem.OrderItemPallets.Insert(orderItemPalletsCount - 1, orderItemPallet); + else orderItem.OrderItemPallets.UpdateCollection(orderItemPallet, false); + } + + await InvokeAsync(StateHasChanged); + return; + case SignalRTags.SendProductChanged: + var productDto = jsonMessage?.JsonTo(); + if (productDto == null) break; + + return; + } + + _logger.Error($"SignalRClientOnMessageReceived message == null"); + } + private async Task RefreshOrdersFromDb(DateTime dateTime) { + SelectedDate = dateTime; LoadingPanelVisible = true; + var orders = (await FruitBankSignalRClient.GetPendingOrderDtosForMeasuring() ?? []).Where(o => o.HasMeasuringAccess(LoggedInModel.CustomerDto?.Id, LoggedInModel.IsRevisor)).OrderBy(o => o.DateOfReceipt).ToList(); - _measuringDates = orders.Select(order => new MeasuringDateSelectorModel(order.Id, order.DateOfReceiptOrCreated, order.IsMeasured)).ToList(); + lock (_lock) + { + _measuringDates = orders.Select(order => new MeasuringDateSelectorModel(order.Id, order.DateOfReceiptOrCreated, order.IsMeasured)).ToList(); - SelectedDayOrders = orders.Where(order => MeasuringService.DaysEqual(order.DateOfReceiptOrCreated, dateTime)).OrderBy(x => x.DateOfReceipt).ToList(); + SelectedDayOrders = orders.Where(order => MeasurementService.DaysEqual(order.DateOfReceiptOrCreated, dateTime)).OrderBy(x => x.DateOfReceipt).ToList(); - foreach (var orderDto in SelectedDayOrders) PrepareOrderDto(orderDto); + foreach (var orderDto in SelectedDayOrders) PrepareOrderDto(orderDto); - SelectedOrder = LoggedInModel.IsRevisor - ? SelectedDayOrders.FirstOrDefault(o => o is { IsComplete: false, IsMeasured: true }) - : SelectedDayOrders.FirstOrDefault(o => o.MeasurementOwnerId == 0 || (o.MeasurementOwnerId == (LoggedInModel.CustomerDto?.Id ?? 0) && !o.IsMeasured)); + SelectedOrder = LoggedInModel.IsRevisor + ? SelectedDayOrders.FirstOrDefault(o => o is { IsComplete: false, IsMeasured: true }) + : SelectedDayOrders.FirstOrDefault(o => o.MeasurementOwnerId == 0 || (o.MeasurementOwnerId == (LoggedInModel.CustomerDto?.Id ?? 0) && !o.IsMeasured)); + + SelectedOrder ??= SelectedDayOrders.FirstOrDefault(); + } - SelectedOrder ??= SelectedDayOrders.FirstOrDefault(); LoadingPanelVisible = SelectedOrder != null; //Lefut a change és ott lesz false! - J. } - private async Task OnMeasuringDateChanged(DateTime selectedDateTime) - => await RefreshOrdersFromDb(selectedDateTime); + private async Task OnMeasuringDateChanged(DateTime selectedDateTime) => await RefreshOrdersFromDb(selectedDateTime); private void OnCustomDisabledMeasuringDate(CalendarCustomDisabledDateEventArgs args) - => MeasuringService.OnCustomDisabledDate(args, _measuringDates); + => MeasurementService.OnCustomDisabledDate(args, _measuringDates); private string GetMeasuringDateCssClassNames(DateTime date) - => MeasuringService.GetShippingDateCssClassNames(date, _measuringDates); + => MeasurementService.GetShippingDateCssClassNames(date, _measuringDates); private string GetOrderItemPalletsCssClassNames(string fieldName, OrderItemPallet orderItemPallet) - => MeasuringService.GetCustomItemPalletsCssClassNames(fieldName, orderItemPallet, orderItemPallet.OrderItemDto!.IsMeasurable); + => MeasurementService.GetCustomItemPalletsCssClassNames(fieldName, orderItemPallet, orderItemPallet.OrderItemDto!.IsMeasurable); private bool IsOrderItemPalletMeasuredAndValid(OrderItemPallet orderItemPallet) - => MeasuringService.IsCustomItemPalletMeasuredAndValid(orderItemPallet, orderItemPallet.OrderItemDto!.IsMeasurable); + => MeasurementService.IsCustomItemPalletMeasuredAndValid(orderItemPallet, orderItemPallet.OrderItemDto!.IsMeasurable); private async Task OnSelectedOrderChanged(SelectedDataItemChangedEventArgs eventArgs) { @@ -136,6 +216,12 @@ namespace FruitBankHybrid.Shared.Pages return Task.CompletedTask; } + private Task OnPalletItemAuditedClick(OrderItemPallet? orderItemPallet, OrderItemDto selectedOrderItemDto) + { + StateHasChanged(); + return Task.CompletedTask; + } + private async Task OnOrderItemPalletSaved(OrderItemPallet? orderItemPallet, OrderItemDto selectedOrderItemDto) { if (orderItemPallet != null) @@ -152,7 +238,7 @@ namespace FruitBankHybrid.Shared.Pages { if (selectedOrderItemDto.OrderItemPallets[^1].Id > 0) { - selectedOrderItemDto.OrderItemPallets.Add(MeasuringService.CreateNewOrderItemPallet(selectedOrderItemDto, LoggedInModel.CustomerDto)); + selectedOrderItemDto.OrderItemPallets.Add(MeasurementService.CreateNewOrderItemPallet(selectedOrderItemDto, LoggedInModel.CustomerDto)); StateHasChanged(); } @@ -173,7 +259,10 @@ namespace FruitBankHybrid.Shared.Pages } private async Task OnOrdersRefreshClick() - => await RefreshOrdersFromDb(SelectedDayOrders.FirstOrDefault()?.DateOfReceiptOrCreated ?? DateTime.Now); + { + await RefreshOrdersFromDb(SelectedDayOrders.FirstOrDefault()?.DateOfReceiptOrCreated ?? DateTime.Now); + StateHasChanged(); + } private async Task OnStartMeasuringClick() { @@ -223,7 +312,7 @@ namespace FruitBankHybrid.Shared.Pages { foreach (var orderItemDto in orderDto.OrderItemDtos.Where(orderItem => orderItem.OrderItemPallets.Count == 0)) { - orderItemDto.OrderItemPallets.Add(MeasuringService.CreateNewOrderItemPallet(orderItemDto, LoggedInModel.CustomerDto)); + orderItemDto.OrderItemPallets.Add(MeasurementService.CreateNewOrderItemPallet(orderItemDto, LoggedInModel.CustomerDto)); } } diff --git a/FruitBankHybrid.Shared/Pages/Revisor.razor b/FruitBankHybrid.Shared/Pages/Revisor.razor new file mode 100644 index 0000000..d452b96 --- /dev/null +++ b/FruitBankHybrid.Shared/Pages/Revisor.razor @@ -0,0 +1,34 @@ +@page "/Revisor" +@using FruitBank.Common.Dtos +@using FruitBankHybrid.Shared.Components +

Revisor

+ + + +
+ + + + @* @bind-ActiveTabIndex="@ActiveTabIndex" *@ + + + + + + + + + + + + + + + +
\ No newline at end of file diff --git a/FruitBankHybrid.Shared/Pages/Revisor.razor.cs b/FruitBankHybrid.Shared/Pages/Revisor.razor.cs new file mode 100644 index 0000000..b6e26c0 --- /dev/null +++ b/FruitBankHybrid.Shared/Pages/Revisor.razor.cs @@ -0,0 +1,76 @@ +using AyCode.Core.Loggers; +using DevExpress.Blazor; +using FruitBank.Common.Dtos; +using FruitBank.Common.Models; +using FruitBankHybrid.Shared.Services.Loggers; +using FruitBankHybrid.Shared.Services.SignalRs; +using Mango.Nop.Core.Loggers; +using Microsoft.AspNetCore.Components; + +namespace FruitBankHybrid.Shared.Pages; + +public partial class Revisor : ComponentBase +{ + [Inject] public required IEnumerable LogWriters { get; set; } + [Inject] public required FruitBankSignalRClient FruitBankSignalRClient { get; set; } + [Inject] public required NavigationManager NavManager { get; set; } + [Inject] private IDialogService DialogService { get; set; } = null!; + [Inject] public required LoggedInModel LoggedInModel { get; set; } + + public IGrid gridOrder; + private List? ProductDtos { get; set; } = null!; + private List? OrderDtos { get; set; } = null!; + private List? OrderItemDtos { get; set; } = null!; + + public bool AutoCollapseDetailRow { get; set; } + public bool LoadingPanelVisible { get; set; } = true; + + private ILogger _logger = null!; + public int ActiveTabIndex; + + protected override async Task OnInitializedAsync() + { + if (!LoggedInModel.IsRevisor) NavManager.NavigateTo("/Login"); + + LoadingPanelVisible = true; + + _logger = new LoggerClient(LogWriters.ToArray()); + _logger.Info("OnInitializedAsync"); + + await RefreshOrdersFromDb(DateTime.Now); + await base.OnInitializedAsync(); + } + + private async Task RefreshOrdersFromDb(DateTime dateTime) + { + LoadingPanelVisible = true; + + OrderDtos = (await FruitBankSignalRClient.GetAllOrderDtos() ?? []).OrderByDescending(o=>o.Id).ToList();//.Where(o => o.HasMeasuringAccess(LoggedInModel.CustomerDto?.Id, LoggedInModel.IsRevisor)).OrderBy(o => o.DateOfReceipt).ToList(); + + LoadingPanelVisible = false; + } + + protected async Task OnActiveTabChanged(int activeTabIndex) + { + ActiveTabIndex = activeTabIndex; + LoadingPanelVisible = true; + + switch (ActiveTabIndex) + { + case 0: + if(ProductDtos == null) + ProductDtos = (await FruitBankSignalRClient.GetProductDtos() ?? []); //.Where(o => o.HasMeasuringAccess(LoggedInModel.CustomerDto?.Id, LoggedInModel.IsRevisor)).OrderBy(o => o.DateOfReceipt).ToList(); + break; + case 1: + if(OrderDtos == null) + OrderDtos = (await FruitBankSignalRClient.GetAllOrderDtos() ?? []).OrderByDescending(o => o.Id).ToList(); //.Where(o => o.HasMeasuringAccess(LoggedInModel.CustomerDto?.Id, LoggedInModel.IsRevisor)).OrderBy(o => o.DateOfReceipt).ToList(); + break; + case 2: + if (OrderItemDtos == null) + OrderItemDtos = (await FruitBankSignalRClient.GetAllOrderItemDtos() ?? []).OrderByDescending(o => o.Id).ToList(); //.Where(o => o.HasMeasuringAccess(LoggedInModel.CustomerDto?.Id, LoggedInModel.IsRevisor)).OrderBy(o => o.DateOfReceipt).ToList(); + break; + } + + LoadingPanelVisible = false; + } +} \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Pages/Revisor.razor.css b/FruitBankHybrid.Shared/Pages/Revisor.razor.css new file mode 100644 index 0000000..5f28270 --- /dev/null +++ b/FruitBankHybrid.Shared/Pages/Revisor.razor.css @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Services/IMeasurementService.cs b/FruitBankHybrid.Shared/Services/IMeasurementService.cs new file mode 100644 index 0000000..f0f781c --- /dev/null +++ b/FruitBankHybrid.Shared/Services/IMeasurementService.cs @@ -0,0 +1,8 @@ +using FruitBank.Common.Interfaces; + +namespace FruitBankHybrid.Shared.Services; + +public interface IMeasurementService : IMeasurementServiceBase +{ + +} \ No newline at end of file diff --git a/FruitBankHybrid.Shared/Services/MeasuringService.cs b/FruitBankHybrid.Shared/Services/MeasurementService.cs similarity index 96% rename from FruitBankHybrid.Shared/Services/MeasuringService.cs rename to FruitBankHybrid.Shared/Services/MeasurementService.cs index e3ef846..8d9e035 100644 --- a/FruitBankHybrid.Shared/Services/MeasuringService.cs +++ b/FruitBankHybrid.Shared/Services/MeasurementService.cs @@ -2,14 +2,15 @@ using FruitBank.Common.Dtos; using FruitBank.Common.Entities; using FruitBank.Common.Interfaces; +using FruitBank.Common.Services; using FruitBankHybrid.Shared.Models; using Mango.Nop.Core.Dtos; namespace FruitBankHybrid.Shared.Services; -public class MeasuringService +public class MeasurementService : MeasurementServiceBase, IMeasurementService { - public MeasuringService() + public MeasurementService() { } diff --git a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs index df4de16..2b36247 100644 --- a/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs +++ b/FruitBankHybrid.Shared/Services/SignalRs/FruitBankSignalRClient.cs @@ -1,4 +1,5 @@ -using AyCode.Core.Helpers; +using AyCode.Core.Extensions; +using AyCode.Core.Helpers; using AyCode.Core.Loggers; using AyCode.Services.Server.SignalRs; using AyCode.Services.SignalRs; @@ -11,7 +12,9 @@ using FruitBank.Common.SignalRs; using FruitBankHybrid.Shared.Services.Loggers; using Mango.Nop.Core.Dtos; using Mango.Nop.Core.Models; +using MessagePack.Resolvers; using Nop.Core.Domain.Customers; +using System.ServiceModel.Channels; namespace FruitBankHybrid.Shared.Services.SignalRs { @@ -22,6 +25,26 @@ namespace FruitBankHybrid.Shared.Services.SignalRs ConstHelper.NameByValue(0); } + /// + /// MessageTag, JSON + /// + public event Func OnMessageReceived = null!; + + protected override async Task MessageReceived(int messageTag, byte[] messageBytes) + { + var jsonMessage = messageBytes.MessagePackTo(ContractlessStandardResolver.Options); + + await OnMessageReceived(messageTag, jsonMessage.ResponseData); + } + + private void SendMessageToAllClients(int messageTag, string message) + { + if (messageTag == SignalRTags.NotificationReceived) + { + Logger.Info(message); + } + } + public Task?> GetMeasuringModels() => GetAllAsync>(SignalRTags.GetMeasuringModels); @@ -143,6 +166,9 @@ namespace FruitBankHybrid.Shared.Services.SignalRs public Task?> GetAllOrderDtoByIds(int[] orderIds) => GetAllAsync>(SignalRTags.GetAllOrderDtoByIds, [orderIds]); + public Task?> GetAllOrderItemDtos() + => GetAllAsync>(SignalRTags.GetAllOrderItemDtos); + public Task AddOrUpdateMeasuredOrderItemPallet(OrderItemPallet orderItemPallet) => PostDataAsync(SignalRTags.AddOrUpdateMeasuredOrderItemPallet, orderItemPallet); @@ -152,6 +178,33 @@ namespace FruitBankHybrid.Shared.Services.SignalRs public Task SetOrderStatusToComplete(int orderId, int revisorId) => GetByIdAsync(SignalRTags.SetOrderStatusToComplete, [orderId, revisorId]); + public Task?> GetAllOrderDtoByProductId(int productId) + => GetAllAsync>(SignalRTags.GetAllOrderDtoByProductId, [productId]); + + public Task GetOrderItemDtoById(int orderItemId) + => GetByIdAsync(SignalRTags.GetOrderItemDtoById, [orderItemId]); + + public Task?> GetAllOrderItemDtoByOrderId(int orderId) + => GetAllAsync>(SignalRTags.GetAllOrderItemDtoByOrderId, [orderId]); + + public Task?> GetAllOrderItemDtoByProductId(int productId) + => GetAllAsync>(SignalRTags.GetAllOrderItemDtoByProductId, [productId]); + + public Task?> GetAllOrderItemPallets() + => GetAllAsync>(SignalRTags.GetAllOrderItemPallets); + + public Task GetOrderItemPalletById(int orderItemPalletId) + => GetByIdAsync(SignalRTags.GetOrderItemPalletById, [orderItemPalletId]); + + public Task?> GetAllOrderItemPalletByOrderItemId(int orderItemId) + => GetAllAsync>(SignalRTags.GetAllOrderItemPalletByOrderItemId, [orderItemId]); + + public Task?> GetAllOrderItemPalletByOrderId(int orderId) + => GetAllAsync>(SignalRTags.GetAllOrderItemPalletByOrderId, [orderId]); + + public Task?> GetAllOrderItemPalletByProductId(int productId) + => GetAllAsync>(SignalRTags.GetAllOrderItemPalletByProductId, [productId]); + #endregion Orders } } diff --git a/FruitBankHybrid.Shared/wwwroot/app.css b/FruitBankHybrid.Shared/wwwroot/app.css index d8a0e89..b1d9222 100644 --- a/FruitBankHybrid.Shared/wwwroot/app.css +++ b/FruitBankHybrid.Shared/wwwroot/app.css @@ -79,3 +79,28 @@ h1:focus { .dd-body-class .dxbl-list-box-render-container { max-height: 600px !important; } + +/*region: DSGrids*/ +/*.dxbl-grid { + height: 522px; +} +*/ +.hideDetailButton .dxbl-grid-expand-button-cell .dxbl-grid-expand-button { + visibility: hidden; +} + +.header-bold span { + font-weight: 700; + color: #161616; +} +/* DevExpress and Bootstrap Themes */ +.alt-item > td:not(.dxbl-grid-empty-cell), +.alt-item > td:not(.dxbl-grid-indent-cell) { + background-color: #F7F7F7 !important; + color: #161616; +} +/* Fluent Themes */ +/*.alt-item { + --dxbl-grid-row-bg: var(--DS-color-surface-neutral-subdued-rest); +}*/ +/*endregion: DSGrids*/ \ No newline at end of file diff --git a/FruitBankHybrid.Web.Client/Program.cs b/FruitBankHybrid.Web.Client/Program.cs index 0e188af..0cecf6a 100644 --- a/FruitBankHybrid.Web.Client/Program.cs +++ b/FruitBankHybrid.Web.Client/Program.cs @@ -9,7 +9,7 @@ using Microsoft.AspNetCore.Components.WebAssembly.Hosting; var builder = WebAssemblyHostBuilder.CreateDefault(args); -builder.Services.AddDevExpressBlazor(configure => configure.SizeMode = DevExpress.Blazor.SizeMode.Large); +builder.Services.AddDevExpressBlazor(configure => configure.SizeMode = DevExpress.Blazor.SizeMode.Medium); // Add device-specific services used by the FruitBankHybrid.Shared project builder.Services.AddSingleton(); @@ -19,9 +19,9 @@ builder.Services.AddSingleton(); builder.Services.AddScoped(); #if DEBUG -builder.Services.AddSingleton(); +builder.Services.AddScoped(); #endif -builder.Services.AddSingleton(); +builder.Services.AddScoped(); await builder.Build().RunAsync(); diff --git a/FruitBankHybrid.Web/Program.cs b/FruitBankHybrid.Web/Program.cs index 21db277..05b22b2 100644 --- a/FruitBankHybrid.Web/Program.cs +++ b/FruitBankHybrid.Web/Program.cs @@ -16,9 +16,9 @@ builder.Services.AddMvc(); builder.Services.AddSingleton(); -builder.Services.AddScoped(); -builder.Services.AddScoped(); +builder.Services.AddSingleton(); builder.Services.AddScoped(); +//builder.Services.AddScoped(); //builder.Services.AddSingleton(); //builder.Services.AddScoped(); diff --git a/FruitBankHybrid.sln b/FruitBankHybrid.sln index 19de8bf..df6b7a7 100644 --- a/FruitBankHybrid.sln +++ b/FruitBankHybrid.sln @@ -27,6 +27,7 @@ Global GlobalSection(ProjectConfigurationPlatforms) = postSolution {85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Debug|Any CPU.Build.0 = Debug|Any CPU + {85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Debug|Any CPU.Deploy.0 = Debug|Any CPU {85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Release|Any CPU.ActiveCfg = Release|Any CPU {85ADEDE3-C271-47DF-B273-2EDB32792CEF}.Release|Any CPU.Build.0 = Release|Any CPU {899988C3-8F36-4B19-A1DE-1D1D85F114D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU diff --git a/FruitBankHybrid/FruitBankHybrid.csproj b/FruitBankHybrid/FruitBankHybrid.csproj index 1e2f7c0..65e89e5 100644 --- a/FruitBankHybrid/FruitBankHybrid.csproj +++ b/FruitBankHybrid/FruitBankHybrid.csproj @@ -23,7 +23,7 @@ 1 - None + 15.0 15.0 diff --git a/FruitBankHybrid/MauiProgram.cs b/FruitBankHybrid/MauiProgram.cs index 2fd08d3..308baf8 100644 --- a/FruitBankHybrid/MauiProgram.cs +++ b/FruitBankHybrid/MauiProgram.cs @@ -42,7 +42,7 @@ namespace FruitBankHybrid builder.Services.AddMauiBlazorWebView(); - builder.Services.AddDevExpressBlazor(configure => configure.SizeMode = DevExpress.Blazor.SizeMode.Large); + builder.Services.AddDevExpressBlazor(configure => configure.SizeMode = DevExpress.Blazor.SizeMode.Medium); #if DEBUG builder.Services.AddBlazorWebViewDeveloperTools();