using AyCode.Core.Loggers; using DevExpress.Blazor; using FruitBank.Common.Dtos; using FruitBank.Common.Entities; using FruitBank.Common.Enums; using FruitBank.Common.Interfaces; using FruitBank.Common.Services; using FruitBankHybrid.Shared.Models; using FruitBankHybrid.Shared.Services.Loggers; using Mango.Nop.Core.Dtos; using Mango.Nop.Core.Loggers; using Nop.Core.Domain.Orders; namespace FruitBankHybrid.Shared.Services; public class MeasurementService(IEnumerable logWriters) : MeasurementServiceBase(new LoggerClient(logWriters.ToArray())), IMeasurementService { public static bool DaysEqual(DateTime date1, DateTime date2) => (date1.Year == date2.Year && date1.DayOfYear == date2.DayOfYear); public static void OnCustomDisabledDate(CalendarCustomDisabledDateEventArgs args, List? measuringDates) => args.IsDisabled = measuringDates == null || !measuringDates.Exists(shippingDateModel => DaysEqual(shippingDateModel.DateTime, args.Date)); public static string GetShippingDateCssClassNames(DateTime date, List? measuringDates) { if (measuringDates == null) return string.Empty; if (measuringDates.Exists(shipping => !shipping.IsMeasured && shipping.DateTime.Date <= DateTime.Now.Date && DaysEqual(shipping.DateTime, date))) return "fw-bold text-danger"; if (measuringDates.Exists(shipping => shipping.IsMeasured && DaysEqual(shipping.DateTime, date))) return "fw-bold text-success"; if (measuringDates.Exists(shipping => !shipping.IsMeasured && DaysEqual(shipping.DateTime, date))) return "fw-bold"; return string.Empty; } public static string GetCustomItemPalletsCssClassNames(string fieldName, IMeasuringItemPalletBase shippingItemPallet, bool isMeasurable, int? maxTrayQuantity = null) { //if (shippingItemPallet.NetWeight < 0) return "text-danger"; switch (fieldName) { case nameof(ShippingItemPallet.TareWeight): return IsCustomItemPalletMeasuredAndValid(shippingItemPallet, isMeasurable) ? "text-success" : (shippingItemPallet.TareWeight < 0 || shippingItemPallet.NetWeight < 0 ? "text-danger" : ""); break; case nameof(ShippingItemPallet.PalletWeight): return IsCustomItemPalletMeasuredAndValid(shippingItemPallet, isMeasurable) ? "text-success" : (shippingItemPallet.PalletWeight < 0 || shippingItemPallet.NetWeight < 0 ? "text-danger" : ""); break; case nameof(ShippingItemPallet.TrayQuantity): //return IsCustomItemPalletMeasuredAndValid(shippingItemPallet, isMeasurable) ? "text-success" : (shippingItemPallet.TrayQuantity < 0 || (maxTrayQuantity.HasValue && shippingItemPallet.TrayQuantity > maxTrayQuantity.Value) ? "text-danger" : ""); return shippingItemPallet.TrayQuantity < 0 || (maxTrayQuantity.HasValue && shippingItemPallet.TrayQuantity > maxTrayQuantity.Value) ? "text-danger" : (IsCustomItemPalletMeasuredAndValid(shippingItemPallet, isMeasurable) ? "text-success" : ""); break; case nameof(ShippingItemPallet.GrossWeight): return IsCustomItemPalletMeasuredAndValid(shippingItemPallet, isMeasurable) ? "text-success" : (shippingItemPallet.GrossWeight < 0 || shippingItemPallet.NetWeight < 0 ? "text-danger" : ""); break; case nameof(ShippingItemPallet.NetWeight): return IsCustomItemPalletMeasuredAndValid(shippingItemPallet, isMeasurable) ? "text-success" : (shippingItemPallet.NetWeight < 0 ? "text-danger" : ""); break; } return string.Empty; } public static ShippingItemPallet CreateNewShippingItemPallet(ShippingItem shippingItem, CustomerDto? customerDto) { var shippingItemPallet = CreatePalletItemBase(shippingItem.Id, shippingItem.ProductDto?.Tare, shippingItem.IsMeasurable, customerDto); shippingItemPallet.ShippingItem = shippingItem; shippingItemPallet.PalletWeight = shippingItem.IsMeasurable ? shippingItem.Pallet?.Weight ?? 0 : 0; return shippingItemPallet; } public static OrderItemPallet CreateNewOrderItemPallet(OrderItemDto orderItemDto, CustomerDto? customerDto) { var orderItemPallet = CreatePalletItemBase(orderItemDto.Id, orderItemDto.ProductDto?.Tare, orderItemDto.IsMeasurable, customerDto); orderItemPallet.OrderItemDto = orderItemDto; return orderItemPallet; } public static StockTakingItemPallet CreateNewStockTakingItemPallet(StockTakingItem stockTakingItem, CustomerDto? customerDto) { var stockTakingItemPallet = CreatePalletItemBase(stockTakingItem.Id, stockTakingItem.Product?.Tare, stockTakingItem.IsMeasurable, customerDto); stockTakingItemPallet.GrossWeight = stockTakingItem.IsMeasurable ? -1 : 0; stockTakingItemPallet.TrayQuantity = -1; stockTakingItemPallet.StockTakingItem = stockTakingItem; return stockTakingItemPallet; } private static TPalletItem CreatePalletItemBase(int foreignKey, double? tare, bool isMeasurable, CustomerDto? customerDto) where TPalletItem : MeasuringItemPalletBase { var palletItem = Activator.CreateInstance(); palletItem.SetForeignKey(foreignKey); //palletItem.PalletWeight = isMeasurable ? orderItemDto.Pallet?.Weight ?? 0 : 0; palletItem.TareWeight = isMeasurable ? tare ?? 0 : 0; palletItem.CreatorId = customerDto?.Id; palletItem.ModifierId = customerDto?.Id; return palletItem; } public static bool IsCustomItemPalletMeasuredAndValid(IMeasuringItemPalletBase customItemPallet, bool isMeasurable) => customItemPallet.IsMeasuredAndValid(isMeasurable); /// /// Returns the last order note starting with '*', or null if none exists. /// public static string? GetOrderNote(IEnumerable? orderNotes) => orderNotes?.LastOrDefault(x => x.Note.StartsWith('*'))?.Note; /// /// Returns a Bootstrap badge CSS class for the given measuring status. /// When is false, Finnished is treated as the final state (success/green). /// public static string GetMeasuringStatusBadgeCssClass(MeasuringStatus status, bool hasAuditedStage = true) => status switch { MeasuringStatus.Audited => "bg-success", MeasuringStatus.Finnished => hasAuditedStage ? "bg-primary" : "bg-success", MeasuringStatus.Started => "bg-warning text-dark", _ => "bg-secondary" }; /// /// Returns a localized display text for the given measuring status. /// public static string GetMeasuringStatusText(MeasuringStatus status) => status switch { MeasuringStatus.Audited => "Lezárva", MeasuringStatus.Finnished => "Kész", MeasuringStatus.Started => "Folyamatban", _ => "Nem kezdett" }; /// /// Returns a text color CSS class for the given measuring status. /// When is false, Finnished is treated as the final state (success/green). /// public static string GetMeasuringStatusCssClass(MeasuringStatus status, bool hasAuditedStage = true) => status switch { MeasuringStatus.Audited => "text-success", MeasuringStatus.Finnished => hasAuditedStage ? "text-primary" : "text-success", MeasuringStatus.Started => "text-warning", _ => "text-muted" }; /// /// Computes a shipping-level MeasuringStatus from its items. /// public static MeasuringStatus GetShippingMeasuringStatus(Shipping shipping) { var items = shipping.ShippingDocuments? .Where(sd => sd.ShippingItems is not null) .SelectMany(sd => sd.ShippingItems!); if (items is null || !items.Any()) return MeasuringStatus.NotStarted; if (items.All(si => si.IsMeasured)) return MeasuringStatus.Finnished; if (items.Any(si => si.MeasuringStatus == MeasuringStatus.Started || si.IsMeasured)) return MeasuringStatus.Started; return MeasuringStatus.NotStarted; } }