Files
FA_WEB/OrdersManagement/Components/Pages/WarehousePackList.razor
Piotr Kus a8e3a8be66 * Added Lot table and service
* Changed behaviour of scanning to scan first PartNumber, select specific record and then scan MeylePartNumber
2025-06-17 08:30:10 +02:00

301 lines
13 KiB
Plaintext

@page "/Warehouse/PackList/{WzHeader:guid}"
@using OrdersManagement.Models
@using Syncfusion.Blazor.Cards
@using Syncfusion.Blazor.Grids
@using SytelineSaAppEfDataModel.Dtos
@using Syncfusion.Blazor.Navigations
@using Syncfusion.Blazor.Popups
@using Syncfusion.Blazor.Inputs
@inject WarehouseService WarehouseService
<div class="h-100 d-flex justify-content-center align-items-start">
<SfCard CssClass="shadow" style="width: 100%; max-width: 1200px;">
<CardHeader>
<h3 class="text-primary">Packing List</h3>
</CardHeader>
<CardContent>
<SfCard CssClass="shadow" style="width: 100%; max-width: 1200px;">
<CardContent>
<label for="textBox" class="form-label">Adresy Email do Wysyłki raportu:</label>
<SfTextBox ID="textBox" Placeholder="Wprowadź adresy..." @bind-Value="@EmailAddresses"
CssClass="e-outline"/>
</CardContent>
</SfCard>
<SfCard>
<CardContent>
<label for="textBox" class="form-label">Wprowadź numer palety:</label>
<SfTextBox ID="palletNumber" Type="InputType.Number" @bind-Value="@PalletNumber"
CssClass="e-outline"/>
<label for="textBox" class="form-label">Zeskanowana wartość:</label>
<SfTextBox ID="scannedValue" ValueChange="ScanValue" @bind-Value="ScannedValue"
CssClass="e-outline" @ref="_scanner" />
<label for="textBox" class="form-label">Zeskanowane wartości:</label>
<SfTextBox ID="scannedText" Multiline="true" @bind-Value="@ScannedValues" Readonly="true"
CssClass="e-outline"/>
</CardContent>
</SfCard>
<SfGrid @ref="_grid"
AllowFiltering="true"
AllowPaging="true"
AllowSorting="true"
AllowSelection="true"
TValue="WzRowMeyleDto"
DataSource="@WzRowsMeyle"
EnableAdaptiveUI="true">
<SfToolbar>
<ToolbarItems>
<ToolbarItem Type="ItemType.Button" Text="Zapisz zmiany" Id="SaveButton"
PrefixIcon="e-icons e-save" OnClick="SaveChanges"/>
<ToolbarItem Type="ItemType.Button" Id="Generuj XLS i Wyślij" PrefixIcon="e-icons e-export-xls"
Text="Generuj XLS i Wyślij" OnClick="ExportXls"/>
</ToolbarItems>
</SfToolbar>
<GridColumns>
<GridColumn Field=@nameof(WzRowMeyleDto.ID) IsPrimaryKey="true" Visible="false" AllowEditing="false"
TextAlign="TextAlign.Center" HeaderText="ID" Width="70"></GridColumn>
<GridColumn Field=@nameof(WzRowMeyleDto.OrderNumber) AllowEditing="false"
TextAlign="TextAlign.Center" HeaderText="Numer Zamówienia Meyle"
Width="70"></GridColumn>
<GridColumn Field=@nameof(WzRowMeyleDto.FaIndex) AllowEditing="false"
TextAlign="TextAlign.Center" HeaderText="Numer Indeksu FA" Width="100"></GridColumn>
<GridColumn Field=@nameof(WzRowMeyleDto.ItemNumber) AllowEditing="false"
TextAlign="TextAlign.Center" HeaderText="Numer Indeksu Meyle" Width="100"></GridColumn>
<GridColumn Field=@nameof(WzRowMeyleDto.Quantity) AllowEditing="false" TextAlign="TextAlign.Center"
HeaderText="Ilość w Dostawie" Width="80"></GridColumn>
<GridColumn Field=@nameof(WzRowMeyleDto.PalletNumber) AllowEditing="true"
TextAlign="TextAlign.Center" HeaderText="Nr Palety" Width="100"></GridColumn>
<GridColumn Field=@nameof(WzRowMeyleDto.WzNumber) AllowEditing="false" TextAlign="TextAlign.Center"
HeaderText="Nr WZ" Width="100"></GridColumn>
<GridColumn Field=@nameof(WzRowMeyleDto.PartNumberSl) AllowEditing="true" TextAlign="TextAlign.Center"
HeaderText="Nr Partii SL" Width="80"></GridColumn>
<GridColumn Field=@nameof(WzRowMeyleDto.PartNumber) AllowEditing="true" TextAlign="TextAlign.Center"
HeaderText="Nr Partii Meyle" Width="80"></GridColumn>
</GridColumns>
<GridEditSettings AllowDeleting="false"
AllowAdding="false"
AllowEditing="true"
AllowNextRowEdit="true"
AllowEditOnDblClick="true"
ShowConfirmDialog="false"
Mode="EditMode.Batch">
</GridEditSettings>
<GridFilterSettings Type="FilterType.Excel"/>
<GridPageSettings PageSize="10"/>
<GridSelectionSettings Mode="SelectionMode.Row" Type="SelectionType.Single"/>
<GridEvents OnBatchSave="OnBatchSave" TValue="WzRowMeyleDto"></GridEvents>
</SfGrid>
</CardContent>
<SfDialog Width="500px" Title="Informacja" IsModal="true" @bind-Visible="Visibility" AllowPrerender="true">
<DialogTemplates>
<Content>
@if (_isValid)
{
<p>Packing List został wygenerowany i wysłany!</p>
}
else if (string.IsNullOrWhiteSpace(EmailAddresses))
{
<p>Błąd: Proszę wprowadzić przynajmniej jeden <b>ADRES EMAIL</b> do wysyłki raportu!</p>
}
else if (!_isValid)
{
<p>Błąd: Nie Wszystkie linie mają wypełniony <b>NUMER PALETY</b>.<br/>Packing List nie zostanie
wygenerowany!</p>
}
</Content>
</DialogTemplates>
<DialogButtons>
<DialogButton Content="OK" IsPrimary="true" OnClick="@HideModal"/>
</DialogButtons>
</SfDialog>
<CardFooter>
<small class="text-muted">FA Krosno Manager © @(DateTime.Now.Year)</small>
</CardFooter>
</SfCard>
</div>
@code {
[Parameter] public Guid WzHeader { get; set; }
private SfGrid<WzRowMeyleDto> _grid;
private List<WzRowMeyleDto> WzRowsMeyle { get; set; } = new List<WzRowMeyleDto>();
private WzHeaderDto _wzHeader;
private SfTextBox _scanner;
private WzRowMeyleDto? SelectedRow { get; set; }
private bool _isValid;
private bool Visibility { get; set; }
private string? EmailAddresses { get; set; } = string.Empty;
private string PalletNumber { get; set; } = "0";
private string ScannedValues { get; set; } = string.Empty;
private IDictionary<RowMeyleModel, string?> ScannedValuesWithItems { get; set; } = new Dictionary<RowMeyleModel, string?>();
private string LastScannedValue { get; set; } = string.Empty;
private string ScannedValue { get; set; } = string.Empty;
private void HideModal()
{
Visibility = false;
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
_wzHeader = await WarehouseService.GetWzHeaderByIdAsync(WzHeader);
WzRowsMeyle = (await WarehouseService.GetWzRowsByWzHeaderId(WzHeader)).ToList();
WzRowsMeyle.ToList().ForEach(x => ScannedValuesWithItems.Add(new RowMeyleModel
{
ItemNumber = x.ItemNumber.Replace(" ", "").Replace("-", ""),
PartNumberSl = x.PartNumberSl,
TransactionNumber = x.TransactionNumber,
WzNumber = x.WzNumber
}, null));
EmailAddresses = _wzHeader.EmailAddresses;
await _scanner.FocusAsync();
StateHasChanged();
}
}
private async Task SaveChanges()
{
List<WzRowMeyleDto> changedRecords = new List<WzRowMeyleDto>();
if (!string.IsNullOrWhiteSpace(EmailAddresses))
{
await WarehouseService.AddEmailsToWzHeaderAsync(WzHeader, EmailAddresses);
}
IDictionary<RowMeyleModel, string?> scannedValuesWithNotNullValues = ScannedValuesWithItems.Where(x => x.Value is not null).ToDictionary(x => x.Key, y => y.Value);
foreach (KeyValuePair<RowMeyleModel, string?> scannedValueWithNotNullValue in scannedValuesWithNotNullValues)
{
WzRowMeyleDto rowMeyleDto = WzRowsMeyle.First(r => r.ItemNumber.Replace(" ", "").Replace("-", "").Trim() == scannedValueWithNotNullValue.Key.ItemNumber && r.PartNumberSl == scannedValueWithNotNullValue.Key.PartNumberSl && r.WzNumber == scannedValueWithNotNullValue.Key.WzNumber);
rowMeyleDto.PalletNumber = int.Parse(PalletNumber);
rowMeyleDto.PartNumber = scannedValueWithNotNullValue.Value;
changedRecords.Add(rowMeyleDto);
}
if (changedRecords.Any())
{
await UpdateRows(changedRecords);
}
await _grid.EndEditAsync();
}
private async Task OnBatchSave(BeforeBatchSaveArgs<WzRowMeyleDto> obj)
{
var changes = obj.BatchChanges;
List<WzRowMeyleDto> changedRecords = changes.ChangedRecords;
if (!changedRecords.Any()) return;
await UpdateRows(changedRecords);
}
private async Task ExportXls()
{
int count = WzRowsMeyle.Count(x => x.PalletNumber == null);
_isValid = count == 0;
_isValid = _isValid && !string.IsNullOrWhiteSpace(EmailAddresses);
if (_isValid)
{
await WarehouseService.AddEmailsToWzHeaderAsync(WzHeader, EmailAddresses);
await WarehouseService.GenerateXlsForMeyleAsync(WzHeader);
}
Visibility = true;
}
private async Task ScanValue(ChangedEventArgs obj)
{
if (string.IsNullOrWhiteSpace(obj.Value)) return;
MaterialTransactionDto? materialTransactionByPartNumber = await GetMaterialTransactionByPartNumber(ScannedValue).ConfigureAwait(false);
if (materialTransactionByPartNumber != null)
{
var rowIndex = WzRowsMeyle.FindIndex(x => x.FaIndex == materialTransactionByPartNumber.Item && x.Quantity == materialTransactionByPartNumber.Qty);
rowIndex = WzRowsMeyle.FindIndex(x => x.FaIndex == "FA24278.18" && x.Quantity == 70);
if (_grid.AllowPaging)
{
int pageSize = _grid.PageSettings.PageSize;
int targetPage = (rowIndex / pageSize) + 1;
await _grid.GoToPageAsync(targetPage).ConfigureAwait(false);
rowIndex %= pageSize;
}
await _grid.SelectRowAsync(rowIndex).ConfigureAwait(false);
await _grid.ScrollIntoViewAsync(rowIndex: rowIndex).ConfigureAwait(false);
await _grid.FocusAsync().ConfigureAwait(false);
SelectedRow = WzRowsMeyle[rowIndex];
}
else if (ValidateScannedValue(obj.Value) && SelectedRow != null)
{
SelectedRow.PartNumber = obj.Value.Trim();
await InvokeAsync(StateHasChanged).ConfigureAwait(false);
await _grid.Refresh().ConfigureAwait(false);
}
else
{
ScannedValue = obj.Value.Trim();
SelectedRow = null;
}
// if (ScannedValuesWithItems.All(x => x.Key.ItemNumber != ScannedValue.Replace(" ", "").Trim()) && ScannedValuesWithItems.Any(x => x.Key.ItemNumber == LastScannedValue.Replace(" ", "").Trim()))
// {
// RowMeyleModel key = ScannedValuesWithItems.First(x => x.Key.ItemNumber == LastScannedValue).Key;
// ScannedValuesWithItems[key] = ScannedValue.Trim();
// ScannedValues += $"{ScannedValue}\n";
// }
// else if (!string.IsNullOrWhiteSpace(ScannedValue))
// {
// ScannedValues += $"{ScannedValue}: ";
// }
LastScannedValue = ScannedValue;
ScannedValue = string.Empty;
}
private bool ValidateScannedValue(string scannedValue)
{
int year = DateTime.Now.Year - 2000;
string format = $"{year}X";
return scannedValue.StartsWith(format);
}
private async Task<MaterialTransactionDto?> GetMaterialTransactionByPartNumber(string partNumber)
{
MaterialTransactionDto? materialTransaction = await WarehouseService.GetMaterialTransactionByPartNumberAsync(partNumber).ConfigureAwait(false);
return materialTransaction;
}
private async Task UpdateRows(IList<WzRowMeyleDto> changedRecords)
{
await WarehouseService.UpdateWzRowsMeyleAsync(changedRecords);
WzRowsMeyle = (await WarehouseService.GetWzRowsByWzHeaderId(WzHeader)).ToList();
StateHasChanged();
await _grid.Refresh();
}
}