302 lines
14 KiB
Plaintext
302 lines
14 KiB
Plaintext
@page "/MeasuringOut"
|
||
@using AyCode.Utils.Extensions
|
||
@using FruitBank.Common
|
||
@using FruitBank.Common.Dtos
|
||
@using FruitBank.Common.Entities
|
||
@using FruitBank.Common.Enums
|
||
@using FruitBank.Common.SignalRs
|
||
@using FruitBankHybrid.Shared.Components
|
||
@using FruitBankHybrid.Shared.Services
|
||
@using AyCode.Blazor.Components.Components.CardViews
|
||
@using Nop.Core.Domain.Orders
|
||
<h3>Áru kiadás</h3>
|
||
|
||
<DxDialogProvider />
|
||
|
||
<div style="margin-top: 30px;">
|
||
<DxLoadingPanel @bind-Visible="LoadingPanelVisible"
|
||
IsContentBlocked="true"
|
||
ApplyBackgroundShading="true"
|
||
IndicatorAreaVisible="true"
|
||
IsContentVisible="true"
|
||
IndicatorAnimationType="WaitIndicatorAnimationType.Spin"
|
||
Text="Adatok szinkronizálása folyamatban...">
|
||
|
||
<DxFormLayout CaptionPosition="CaptionPosition.Vertical" CssClass="w-100 measuring-form-layout">
|
||
<DxFormLayoutItem Caption="Dátum" ColSpanXs="8" ColSpanSm="8" ColSpanMd="2"
|
||
CaptionCssClass="@(SelectedOrder != null && _measuringDates.Where(x => MeasurementService.DaysEqual(x.DateTime, SelectedOrder.DateOfReceiptOrCreated)).All(x => x.IsMeasured) ? "text-success" : "")">
|
||
<DxDateEdit DisplayFormat="m"
|
||
Format="m"
|
||
Context="ctxOrderDate"
|
||
Date="@(SelectedOrder?.DateOfReceiptOrCreated.Date ?? DateTime.Now.Date)"
|
||
CustomDisabledDate="@OnCustomDisabledMeasuringDate"
|
||
DateChanged="@((DateTime newValue) => OnMeasuringDateChanged(newValue))"
|
||
InputId="deDisabledDates"
|
||
PickerDisplayMode="DatePickerDisplayMode.Calendar">
|
||
<DayCellTemplate>
|
||
@{
|
||
var cssClass = GetMeasuringDateCssClassNames(ctxOrderDate);
|
||
if (!cssClass.IsNullOrWhiteSpace())
|
||
{
|
||
<a class="@GetMeasuringDateCssClassNames(ctxOrderDate)">@ctxOrderDate.Day.ToString()</a>
|
||
}
|
||
else
|
||
{
|
||
<a>@ctxOrderDate.Day.ToString()</a>
|
||
}
|
||
}
|
||
</DayCellTemplate>
|
||
</DxDateEdit>
|
||
</DxFormLayoutItem>
|
||
<DxFormLayoutItem Caption="Napok száma" ColSpanXs="4" ColSpanSm="4" ColSpanMd="2">
|
||
<DxSpinEdit T="int" Value="1" Increment="1" MinValue="1"
|
||
ValueChanged="async i => await RefreshOrdersFromDb(DateTime.Now, i)" />
|
||
</DxFormLayoutItem>
|
||
</DxFormLayout>
|
||
|
||
<DxTabs ActiveTabIndex="(int)_activeTab" ActiveTabIndexChanged="i => _activeTab = (MeasuringTab)i" RenderMode="TabsRenderMode.OnDemand" CssClass="measuring-tabs">
|
||
<DxTabPage Text="Napi feladatok">
|
||
<div class="p-3">
|
||
<MgCardView TItem="OrderDto" Data="@FilteredOrders"
|
||
ShowFilterPanel="true"
|
||
OnCardClick="NavigateToMeasuringTab"
|
||
ScrollToItem="@SelectedOrder"
|
||
ItemKeySelector="o => o.Id"
|
||
Height="calc(100vh - 220px)">
|
||
<FilterPanel>
|
||
<DxTagBox Data="@(Enum.GetValues<MeasuringStatus>())"
|
||
NullText="Összes státusz"
|
||
@bind-Values="_statusFilter"
|
||
ClearButtonDisplayMode="DataEditorClearButtonDisplayMode.Auto"
|
||
CssClass="cw-480" />
|
||
</FilterPanel>
|
||
<CardTemplate>
|
||
<div class="d-flex justify-content-between align-items-start mb-2">
|
||
<h6 class="mb-0">#@context.CustomOrderNumber</h6>
|
||
<span class="badge @(MeasurementService.GetMeasuringStatusBadgeCssClass(context.MeasuringStatus))">@(MeasurementService.GetMeasuringStatusText(context.MeasuringStatus))</span>
|
||
</div>
|
||
<div class="text-muted small mb-2">
|
||
<strong>@context.DateOfReceiptOrCreated.ToString("HH:mm")</strong> — @context.Customer.Company
|
||
</div>
|
||
@foreach (var item in context.OrderItemDtos)
|
||
{
|
||
<div class="@(MeasurementService.GetMeasuringStatusCssClass(item.MeasuringStatus)) small">
|
||
@item.ProductName — @item.TrayQuantity/@item.Quantity rekesz
|
||
</div>
|
||
}
|
||
@{
|
||
var cardOrderNote = MeasurementService.GetOrderNote(context.OrderNotes);
|
||
}
|
||
@if (!string.IsNullOrWhiteSpace(cardOrderNote))
|
||
{
|
||
<div class="text-muted small mt-2 fst-italic">
|
||
📝 @cardOrderNote
|
||
</div>
|
||
}
|
||
</CardTemplate>
|
||
</MgCardView>
|
||
</div>
|
||
</DxTabPage>
|
||
<DxTabPage Text="Mérés">
|
||
<div class="p-3">
|
||
<DxFormLayout CaptionPosition="CaptionPosition.Vertical" CssClass="w-100">
|
||
<DxFormLayoutItem Caption="Átvétel időpontja:" ColSpanMd="5" CaptionCssClass="@(SelectedOrder?.IsMeasured == true ? "text-success" : "")">
|
||
<DxComboBox Data="@SelectedDayOrders"
|
||
@bind-Value="@SelectedOrder"
|
||
Text="Válasszon időpontot..."
|
||
ValueFieldName="@nameof(OrderDto.Id)"
|
||
TextFieldName="@nameof(OrderDto.TimeOfReceiptText)"
|
||
CssClass="cw-480"
|
||
Context="ctxOrder"
|
||
DropDownBodyCssClass="dd-body-class"
|
||
SearchMode="ListSearchMode.AutoSearch"
|
||
SearchFilterCondition="ListSearchFilterCondition.Contains"
|
||
SearchTextParseMode="ListSearchTextParseMode.GroupWordsByAnd"
|
||
ClearButtonDisplayMode="DataEditorClearButtonDisplayMode.Auto"
|
||
DropDownTriggerMode="DropDownTriggerMode.Click"
|
||
ListRenderMode="ListRenderMode.Entire"
|
||
ShowDropDownButton="true"
|
||
SelectedDataItemChanged="@((SelectedDataItemChangedEventArgs<OrderDto> args) => OnSelectedOrderChanged(args))"
|
||
InputId="cbOrders">
|
||
<ItemDisplayTemplate>
|
||
<span class="@(ctxOrder.DataItem.IsMeasured ? "text-success" : "")">@ctxOrder.DisplayText</span>
|
||
</ItemDisplayTemplate>
|
||
<Buttons>
|
||
<DxEditorButton IconCssClass="editor-icon editor-icon-add" Text="R" Tooltip="Adatok frissítése..."
|
||
Click="() => OnOrdersRefreshClick()" />
|
||
</Buttons>
|
||
</DxComboBox>
|
||
</DxFormLayoutItem>
|
||
|
||
@if (SelectedOrder == null)
|
||
{
|
||
<DxFormLayoutItem ColSpanMd="5">
|
||
<div class="alert alert-info mt-2" role="alert">
|
||
<i class="me-1">ℹ</i> Válasszon ki egy rendelést a mérés indításához.
|
||
</div>
|
||
</DxFormLayoutItem>
|
||
}
|
||
else
|
||
{
|
||
if (SelectedOrder is { MeasurementOwnerId: 0, IsComplete: false } && HasMeasuringAccess)
|
||
{
|
||
<DxFormLayoutItem ColSpanMd="2">
|
||
<DxButton Enabled="@(HasMeasuringAccess && SelectedOrder?.MeasurementOwnerId == 0)" Visible="(SelectedOrder != null)"
|
||
CssClass="w-100"
|
||
Text="@(HasMeasuringAccess && SelectedOrder?.MeasurementOwnerId == 0 ? "Indítás" : "Folyamatban...")"
|
||
Click="() => OnStartMeasuringClick()" />
|
||
</DxFormLayoutItem>
|
||
}
|
||
else
|
||
{
|
||
<DxFormLayoutItem ColSpanMd="2" Caption="Indította" CaptionCssClass="@(SelectedOrder?.IsMeasured == true ? "text-success" : "")">
|
||
<DxTextBox Enabled="false" Text="@(LoggedInModel.MeasuringUsers.FirstOrDefault(x => x.Id == SelectedOrder?.MeasurementOwnerId)?.LastName)" />
|
||
</DxFormLayoutItem>
|
||
}
|
||
}
|
||
|
||
@if (SelectedOrder != null && LoggedInModel.IsRevisor)
|
||
{
|
||
var isCompleteOrder = SelectedOrder.IsComplete;
|
||
|
||
<DxFormLayoutItem Caption="Revizor:" ColSpanMd="2" CaptionCssClass="@(isCompleteOrder ? "text-success" : "")">
|
||
<DxButton Text="@(isCompleteOrder ? "Lezárva" : "Lezárás")"
|
||
Enabled="@(!isCompleteOrder && IsAllOrderItemPalletAudited)" CssClass="w-100"
|
||
Click="() => OnMeasuringAuditorClick()" />
|
||
</DxFormLayoutItem>
|
||
}
|
||
</DxFormLayout>
|
||
|
||
@if (SelectedOrder == null || LoadingPanelVisible)
|
||
{
|
||
}
|
||
else if (!HasMeasuringAccess)
|
||
{
|
||
<div class="alert alert-warning mt-4" role="alert">
|
||
<strong>⚠ Figyelem!</strong> Jelenleg más felhasználó végzi a mérést ennél a rendelésnél.
|
||
</div>
|
||
}
|
||
else
|
||
{
|
||
var orderNote = MeasurementService.GetOrderNote(SelectedOrder?.OrderNotes);
|
||
if (!string.IsNullOrWhiteSpace(orderNote))
|
||
{
|
||
<div class="alert alert-info mt-3" role="alert">
|
||
<strong>📝 Megjegyzés:</strong> @(orderNote)
|
||
</div>
|
||
}
|
||
|
||
<div class="mt-5">
|
||
<h4 class="mb-1 @(SelectedOrder?.IsMeasured == true ? "text-success" : "")">
|
||
Rendelés azonosító: #@(SelectedOrder?.CustomOrderNumber)
|
||
</h4>
|
||
|
||
<DxAccordion Data="@SelectedOrder?.OrderItemDtos" Enabled="@((HasMeasuringAccess && SelectedOrder?.MeasurementOwnerId > 0 && (LoggedInModel.IsRevisor || !(SelectedOrder?.IsComplete ?? false))))"
|
||
ExpandMode="AccordionExpandMode.SingleOrNone"
|
||
ExpandCollapseAction="AccordionExpandCollapseAction.ExpandButtonClick"
|
||
AnimationType="LayoutAnimationType.Slide">
|
||
<DataMappings>
|
||
<DxAccordionDataMapping Text=ProductName></DxAccordionDataMapping>
|
||
</DataMappings>
|
||
<ItemHeaderTextTemplate>
|
||
@{
|
||
if (context.Level == 0)
|
||
{
|
||
var cssClass = "text-danger";
|
||
|
||
var selectedOrderItemDto = (OrderItemDto)(context.DataItem);
|
||
var trayQuantity = selectedOrderItemDto.TrayQuantity; //selectedOrderItemDto.OrderItemPallets.Where(x => x.IsMeasured).Sum(x => x.TrayQuantity);
|
||
|
||
var isValid = selectedOrderItemDto.IsValidMeasuringValues();
|
||
var isValidAndMeasured = isValid && selectedOrderItemDto.IsMeasuredAndValid(); // && selectedOrderItemDto.;
|
||
|
||
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ő!")}]";
|
||
if (selectedOrderItemDto.MeasuringStatus == MeasuringStatus.Audited) displayText = $"[{selectedOrderItemDto.MeasuringStatus}] " + displayText;
|
||
|
||
<h5 class="@cssClass">@(displayText)</h5>
|
||
}
|
||
}
|
||
</ItemHeaderTextTemplate>
|
||
<ItemContentTemplate>
|
||
@{
|
||
if (context.Level == 0)
|
||
{
|
||
var selectedOrderItem = (OrderItemDto)(context.DataItem);
|
||
|
||
<DxFormLayout Context="ctxFormLayout" Data="@selectedOrderItem" CaptionPosition="CaptionPosition.Vertical"
|
||
CssClass="w-100">
|
||
<DxFormLayoutItem Context="ctxFormLayoutItem" ColSpanMd="12">
|
||
@for (var index = 0; index < (selectedOrderItem?.OrderItemPallets?.Count ?? 0); index++)
|
||
{
|
||
var localI = index + 1;
|
||
var currentOrderItemPallet = selectedOrderItem!.OrderItemPallets![index];
|
||
|
||
<PalletItemComponent IsMeasurable="@selectedOrderItem.IsMeasurable"
|
||
MeasuringIndex="@localI"
|
||
Editable="@(_enablePalletItems && !currentOrderItemPallet.IsAudited && !(SelectedOrder?.IsComplete ?? false))"
|
||
PalletItem="@currentOrderItemPallet"
|
||
ProductId="@selectedOrderItem.ProductId"
|
||
MaxTrayQuantity="@selectedOrderItem.Quantity"
|
||
AddOrUpdateSignalRTag="SignalRTags.AddOrUpdateMeasuredOrderItemPallet"
|
||
OnPalletItemSaveOrAuditClick="pallet => OnOrderItemSaveOrAuditClick(pallet, selectedOrderItem)"
|
||
OnPalletItemSaved="pallet => OnOrderItemPalletSaved(pallet, selectedOrderItem)"
|
||
OnPalletItemValueChanged="pallet => OnOrderItemPalletValueChanged(pallet, selectedOrderItem)"
|
||
OnPalletItemAudited="pallet => OnOrderItemAudited(pallet, selectedOrderItem)">
|
||
</PalletItemComponent>
|
||
}
|
||
</DxFormLayoutItem>
|
||
|
||
<DxFormLayoutItem Context="ctxFromLayoutNewPallet" ColSpanMd="2" BeginRow="true">
|
||
<DxButton Text="Új sor" Click="() => AddNewPalletItemClick(selectedOrderItem)" CssClass="w-100"
|
||
Visible="@(!(SelectedOrder?.IsComplete ?? false))"
|
||
Enabled="@(selectedOrderItem.OrderItemPallets[^1].Id > 0)" />
|
||
</DxFormLayoutItem>
|
||
<DxFormLayoutItem Context="ctxFromLayoutNewPallet" ColSpanMd="3">
|
||
<DxButton Text="Utolsó sor törlése" Click="() => LastPalletItemDeleteClick(selectedOrderItem)" CssClass="w-100"
|
||
Visible="@(!(SelectedOrder?.IsComplete ?? false))"
|
||
Enabled="@(selectedOrderItem.OrderItemPallets.Count > 1 && selectedOrderItem.OrderItemPallets[^1].Id <= 0)" />
|
||
</DxFormLayoutItem>
|
||
|
||
<DxFormLayoutItem Context="ctxFromLayoutNewPallet" ColSpanMd="7" />
|
||
|
||
<DxFormLayoutItem Context="vfdfgfd" ColSpanMd="12" BeginRow="true">
|
||
<DxFormLayout CssClass="w-100" Context="dfcadsc">
|
||
<DxFormLayoutItem Context="dfcadsc2" ColSpanMd="1" BeginRow="false"><strong>TOTAL:</strong></DxFormLayoutItem>
|
||
<DxFormLayoutItem Context="dfcadsc2" ColSpanMd="2" BeginRow="false" />
|
||
<DxFormLayoutItem Context="dfcadsc2" ColSpanMd="2" BeginRow="false" />
|
||
<DxFormLayoutItem Context="dfcadsc2" ColSpanMd="1" BeginRow="false" />
|
||
<DxFormLayoutItem Context="dfcadsc2" ColSpanMd="2" BeginRow="false"><strong>Rekesz: @(selectedOrderItem.TrayQuantity) db</strong></DxFormLayoutItem>
|
||
<DxFormLayoutItem Context="dfcadsc2" ColSpanMd="2" BeginRow="false"><strong>Br: @(selectedOrderItem.GrossWeight) kg</strong></DxFormLayoutItem>
|
||
<DxFormLayoutItem Context="dfcadsc2" ColSpanMd="1" BeginRow="false"><strong>Net: @(selectedOrderItem.NetWeight) kg</strong></DxFormLayoutItem>
|
||
<DxFormLayoutItem Context="dfcadsc2" ColSpanMd="1" BeginRow="false" />
|
||
</DxFormLayout>
|
||
</DxFormLayoutItem>
|
||
|
||
@if (!_errorText.IsNullOrWhiteSpace())
|
||
{
|
||
<DxFormLayoutItem Context="ctxFromLayoutItemError" ColSpanMd="12" BeginRow="true">
|
||
<div class="alert alert-danger" role="alert">
|
||
<strong>⚠ Hiba:</strong> @_errorText
|
||
</div>
|
||
</DxFormLayoutItem>
|
||
}
|
||
</DxFormLayout>
|
||
<div class="mb-3"></div>
|
||
}
|
||
}
|
||
</ItemContentTemplate>
|
||
</DxAccordion>
|
||
</div>
|
||
}
|
||
</div>
|
||
</DxTabPage>
|
||
</DxTabs>
|
||
</DxLoadingPanel>
|
||
</div>
|
||
|
||
@code {
|
||
} |