* Further improvements

This commit is contained in:
2025-06-17 22:05:15 +02:00
parent a8e3a8be66
commit 30d2984add
6 changed files with 133 additions and 58 deletions

View File

@@ -41,6 +41,13 @@ public class WzRowMeyleController(IWzRowMeyleService service, IMaterialTransacti
return Ok(materialTransaction); return Ok(materialTransaction);
} }
[HttpGet("transactions-with-part-number")]
public async Task<ActionResult<MaterialTransactionDto>> GetTransactionsWithPartNumber()
{
IEnumerable<MaterialTransactionDto> materialTransactions = await materialTransactionService.GetWithPartNumber();
return Ok(materialTransactions);
}
[HttpPut] [HttpPut]
public async Task<ActionResult> UpdateRows([FromBody] IEnumerable<WzRowMeyleDto> rows) public async Task<ActionResult> UpdateRows([FromBody] IEnumerable<WzRowMeyleDto> rows)
{ {

View File

@@ -30,9 +30,6 @@
<label for="textBox" class="form-label">Zeskanowana wartość:</label> <label for="textBox" class="form-label">Zeskanowana wartość:</label>
<SfTextBox ID="scannedValue" ValueChange="ScanValue" @bind-Value="ScannedValue" <SfTextBox ID="scannedValue" ValueChange="ScanValue" @bind-Value="ScannedValue"
CssClass="e-outline" @ref="_scanner" /> 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> </CardContent>
</SfCard> </SfCard>
<SfGrid @ref="_grid" <SfGrid @ref="_grid"
@@ -103,6 +100,21 @@
<p>Błąd: Nie Wszystkie linie mają wypełniony <b>NUMER PALETY</b>.<br/>Packing List nie zostanie <p>Błąd: Nie Wszystkie linie mają wypełniony <b>NUMER PALETY</b>.<br/>Packing List nie zostanie
wygenerowany!</p> wygenerowany!</p>
} }
else if (!_notValidatedNumber)
{
<p>Błąd: Proszę zeskanować poprawny Numer Partii SL (istniejący w tabeli) lub poprawny numer Partii Meyle zaczynający się od <b>@($"{DateTime.Now.Year - 2001}X")</b>!</p>
}
</Content>
</DialogTemplates>
<DialogButtons>
<DialogButton Content="OK" IsPrimary="true" OnClick="@HideModal"/>
</DialogButtons>
</SfDialog>
<SfDialog Width="500px" Title="Błąd" IsModal="true" @bind-Visible="VisibilityValidation" AllowPrerender="true">
<DialogTemplates>
<Content>
<p>Błąd: Proszę zeskanować poprawny Numer Partii SL (istniejący w tabeli) lub poprawny numer Partii Meyle zaczynający się od <b>@($"{DateTime.Now.Year - 2000}X")</b>!</p>
</Content> </Content>
</DialogTemplates> </DialogTemplates>
<DialogButtons> <DialogButtons>
@@ -120,21 +132,22 @@
[Parameter] public Guid WzHeader { get; set; } [Parameter] public Guid WzHeader { get; set; }
private SfGrid<WzRowMeyleDto> _grid; private SfGrid<WzRowMeyleDto> _grid;
private List<WzRowMeyleDto> WzRowsMeyle { get; set; } = new List<WzRowMeyleDto>(); private List<WzRowMeyleDto> WzRowsMeyle { get; set; } = new();
private IDictionary<string, List<TransactionModel>> TransactionModelsByPartNumber { get; set; } = new Dictionary<string, List<TransactionModel>>();
private List<WzRowMeyleDto> ChangedRecords = new();
private WzHeaderDto _wzHeader; private WzHeaderDto _wzHeader;
private SfTextBox _scanner; private SfTextBox _scanner;
private WzRowMeyleDto? SelectedRow { get; set; } private WzRowMeyleDto? SelectedRow { get; set; }
private bool _isValid; private bool _isValid;
private bool _notValidatedNumber;
private bool Visibility { get; set; } private bool Visibility { get; set; }
private bool VisibilityValidation { get; set; }
private string? EmailAddresses { get; set; } = string.Empty; private string? EmailAddresses { get; set; } = string.Empty;
private string PalletNumber { get; set; } = "0"; 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 LastScannedValue { get; set; } = string.Empty;
private string ScannedValue { get; set; } = string.Empty; private string ScannedValue { get; set; } = string.Empty;
@@ -142,6 +155,7 @@
private void HideModal() private void HideModal()
{ {
Visibility = false; Visibility = false;
VisibilityValidation = false;
} }
protected override async Task OnAfterRenderAsync(bool firstRender) protected override async Task OnAfterRenderAsync(bool firstRender)
@@ -150,15 +164,9 @@
{ {
_wzHeader = await WarehouseService.GetWzHeaderByIdAsync(WzHeader); _wzHeader = await WarehouseService.GetWzHeaderByIdAsync(WzHeader);
WzRowsMeyle = (await WarehouseService.GetWzRowsByWzHeaderId(WzHeader)).ToList(); WzRowsMeyle = (await WarehouseService.GetWzRowsByWzHeaderId(WzHeader)).ToList();
WzRowsMeyle.ToList().ForEach(x => ScannedValuesWithItems.Add(new RowMeyleModel TransactionModelsByPartNumber = await GetTransactionModels();
{
ItemNumber = x.ItemNumber.Replace(" ", "").Replace("-", ""),
PartNumberSl = x.PartNumberSl,
TransactionNumber = x.TransactionNumber,
WzNumber = x.WzNumber
}, null));
EmailAddresses = _wzHeader.EmailAddresses; EmailAddresses = _wzHeader.EmailAddresses;
await _scanner.FocusAsync(); await _scanner.FocusAsync();
@@ -167,29 +175,15 @@
} }
private async Task SaveChanges() private async Task SaveChanges()
{ {
List<WzRowMeyleDto> changedRecords = new List<WzRowMeyleDto>();
if (!string.IsNullOrWhiteSpace(EmailAddresses)) if (!string.IsNullOrWhiteSpace(EmailAddresses))
{ {
await WarehouseService.AddEmailsToWzHeaderAsync(WzHeader, 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); if (ChangedRecords.Any())
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); await UpdateRows(ChangedRecords);
rowMeyleDto.PalletNumber = int.Parse(PalletNumber);
rowMeyleDto.PartNumber = scannedValueWithNotNullValue.Value;
changedRecords.Add(rowMeyleDto);
}
if (changedRecords.Any())
{
await UpdateRows(changedRecords);
} }
await _grid.EndEditAsync(); await _grid.EndEditAsync();
@@ -223,55 +217,75 @@
private async Task ScanValue(ChangedEventArgs obj) private async Task ScanValue(ChangedEventArgs obj)
{ {
_notValidatedNumber = false;
if (string.IsNullOrWhiteSpace(obj.Value)) return; if (string.IsNullOrWhiteSpace(obj.Value)) return;
MaterialTransactionDto? materialTransactionByPartNumber = await GetMaterialTransactionByPartNumber(ScannedValue).ConfigureAwait(false); TransactionModelsByPartNumber.TryGetValue(obj.Value.Trim(), out List<TransactionModel>? materialTransactionsByPartNumber);
TransactionModel? materialTransactionByPartNumber = materialTransactionsByPartNumber?.FirstOrDefault();
if (materialTransactionByPartNumber != null) if (materialTransactionByPartNumber != null)
{ {
var rowIndex = WzRowsMeyle.FindIndex(x => x.FaIndex == materialTransactionByPartNumber.Item && x.Quantity == materialTransactionByPartNumber.Qty); var rowIndex = WzRowsMeyle.FindIndex(x => x.FaIndex == materialTransactionByPartNumber.ItemNumber && x.Quantity == materialTransactionByPartNumber.Quantity);
rowIndex = WzRowsMeyle.FindIndex(x => x.FaIndex == "FA24278.18" && x.Quantity == 70); rowIndex = WzRowsMeyle.FindIndex(x => x.FaIndex == "FA23956.18" && x.Quantity == 130);
SelectedRow = WzRowsMeyle[rowIndex];
SelectedRow.PartNumberSl = ScannedValue;
if (ChangedRecords.All(x => x.TransactionNumber != SelectedRow.TransactionNumber))
{
ChangedRecords.Add(SelectedRow);
}
await SaveChanges();
await InvokeAsync(StateHasChanged);
await _grid.Refresh();
if (_grid.AllowPaging) if (_grid.AllowPaging)
{ {
int pageSize = _grid.PageSettings.PageSize; int pageSize = _grid.PageSettings.PageSize;
int targetPage = (rowIndex / pageSize) + 1; int targetPage = (rowIndex / pageSize) + 1;
await _grid.GoToPageAsync(targetPage).ConfigureAwait(false); await _grid.GoToPageAsync(targetPage);
rowIndex %= pageSize; rowIndex %= pageSize;
} }
await _grid.SelectRowAsync(rowIndex).ConfigureAwait(false); await _grid.SelectRowAsync(rowIndex);
await _grid.ScrollIntoViewAsync(rowIndex: rowIndex).ConfigureAwait(false); await _grid.ScrollIntoViewAsync(rowIndex: rowIndex);
await _grid.FocusAsync().ConfigureAwait(false); await _grid.FocusAsync();
SelectedRow = WzRowsMeyle[rowIndex]; ChangedRecords.Clear();
} }
else if (ValidateScannedValue(obj.Value) && SelectedRow != null) else if (ValidateScannedValue(obj.Value) && SelectedRow != null)
{ {
SelectedRow.PartNumber = obj.Value.Trim(); SelectedRow.PartNumber = obj.Value.Trim();
await InvokeAsync(StateHasChanged).ConfigureAwait(false);
await _grid.Refresh().ConfigureAwait(false); if (ChangedRecords.All(x => x.TransactionNumber != SelectedRow.TransactionNumber))
{
ChangedRecords.Add(SelectedRow);
}
await SaveChanges();
await InvokeAsync(StateHasChanged);
await _grid.Refresh();
ChangedRecords.Clear();
} }
else else
{ {
_notValidatedNumber = true;
VisibilityValidation = true;
ScannedValue = obj.Value.Trim(); ScannedValue = obj.Value.Trim();
SelectedRow = null; 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; LastScannedValue = ScannedValue;
ScannedValue = string.Empty; ScannedValue = string.Empty;
await _scanner.FocusAsync();
} }
private bool ValidateScannedValue(string scannedValue) private bool ValidateScannedValue(string scannedValue)
@@ -290,12 +304,17 @@
return materialTransaction; return materialTransaction;
} }
private async Task<IDictionary<string, List<TransactionModel>>> GetTransactionModels()
{
return await WarehouseService.GetTransactionsModels();
}
private async Task UpdateRows(IList<WzRowMeyleDto> changedRecords) private async Task UpdateRows(IList<WzRowMeyleDto> changedRecords)
{ {
await WarehouseService.UpdateWzRowsMeyleAsync(changedRecords); await WarehouseService.UpdateWzRowsMeyleAsync(changedRecords);
WzRowsMeyle = (await WarehouseService.GetWzRowsByWzHeaderId(WzHeader)).ToList(); WzRowsMeyle = (await WarehouseService.GetWzRowsByWzHeaderId(WzHeader)).ToList();
StateHasChanged(); await InvokeAsync(StateHasChanged);
await _grid.Refresh(); await _grid.Refresh();
} }
} }

View File

@@ -0,0 +1,29 @@
namespace OrdersManagement.Models;
public class TransactionModel : IEquatable<TransactionModel>
{
public string? PartNumber { get; set; }
public string? ItemNumber { get; set; }
public decimal? Quantity { get; set; }
public bool Equals(TransactionModel? other)
{
if (other is null) return false;
if (ReferenceEquals(this, other)) return true;
return PartNumber == other.PartNumber;
}
public override bool Equals(object? obj)
{
if (obj is null) return false;
if (ReferenceEquals(this, obj)) return true;
if (obj.GetType() != GetType()) return false;
return Equals((TransactionModel)obj);
}
public override int GetHashCode()
{
return PartNumber.GetHashCode();
}
}

View File

@@ -1,5 +1,6 @@
using System.Net; using System.Net;
using System.Web; using System.Web;
using OrdersManagement.Models;
using SytelineSaAppEfDataModel.Dtos; using SytelineSaAppEfDataModel.Dtos;
namespace OrdersManagement.Services; namespace OrdersManagement.Services;
@@ -100,7 +101,18 @@ public class WarehouseService(IHttpClientFactory httpClientFactory)
response.EnsureSuccessStatusCode(); response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<IEnumerable<WzRowMeyleDto>>(); return await response.Content.ReadFromJsonAsync<IEnumerable<WzRowMeyleDto>>();
} }
public async Task<IDictionary<string, List<TransactionModel>>> GetTransactionsModels()
{
var response = await _httpClient.GetAsync($"api/WzRowMeyle/transactions-with-part-number");
response.EnsureSuccessStatusCode();
IEnumerable<MaterialTransactionDto> materialTransactions =
await response.Content.ReadFromJsonAsync<IEnumerable<MaterialTransactionDto>>();
return materialTransactions.GroupBy(x => x.NR_KARTY_KONTROLNEJ).ToDictionary(x => x.Key ?? "",
y => y.Select(z => new TransactionModel() { ItemNumber = z.Item, PartNumber = z.NR_KARTY_KONTROLNEJ, Quantity = z.Qty }).ToList());
}
public async Task UpdateWzRowsMeyleAsync(IEnumerable<WzRowMeyleDto?> wzRowsMeyle) public async Task UpdateWzRowsMeyleAsync(IEnumerable<WzRowMeyleDto?> wzRowsMeyle)
{ {
if (wzRowsMeyle == null || !wzRowsMeyle.Any()) if (wzRowsMeyle == null || !wzRowsMeyle.Any())

View File

@@ -11,4 +11,5 @@ public interface IMaterialTransactionService
Task<IEnumerable<MaterialTransactionDto>> GetOrderNumbersByWz(ISet<string> wzNumbers); Task<IEnumerable<MaterialTransactionDto>> GetOrderNumbersByWz(ISet<string> wzNumbers);
Task<IEnumerable<MaterialTransactionDto>> GetByCustomerNumber(string customerNumber, int customerSequence); Task<IEnumerable<MaterialTransactionDto>> GetByCustomerNumber(string customerNumber, int customerSequence);
Task<MaterialTransactionDto?> GetByPartNumber(string partNumber); Task<MaterialTransactionDto?> GetByPartNumber(string partNumber);
Task<IEnumerable<MaterialTransactionDto>> GetWithPartNumber();
} }

View File

@@ -90,4 +90,11 @@ public class MaterialTransactionService(SytelineSaAppDbContext context, IMapper
.Where(x => x.NR_KARTY_KONTROLNEJ == partNumber) .Where(x => x.NR_KARTY_KONTROLNEJ == partNumber)
.Select(x => mapper.Map<MaterialTransactionDto>(x)).FirstOrDefaultAsync(); .Select(x => mapper.Map<MaterialTransactionDto>(x)).FirstOrDefaultAsync();
} }
public async Task<IEnumerable<MaterialTransactionDto>> GetWithPartNumber()
{
return await context.MaterialTransactions
.Where(x => x.NR_KARTY_KONTROLNEJ != null)
.Select(x => mapper.Map<MaterialTransactionDto>(x)).ToListAsync();
}
} }