* Further improvements to generate PackList

This commit is contained in:
2025-05-17 18:36:11 +02:00
parent bc28c5d63d
commit 6ab3960e50
20 changed files with 671 additions and 191 deletions

View File

@@ -22,5 +22,19 @@ namespace FaKrosnoApi.Controllers
CustomerOrderDto? scheduleOrder = await service.GetByOrderNumber(customerOrderNumber); CustomerOrderDto? scheduleOrder = await service.GetByOrderNumber(customerOrderNumber);
return scheduleOrder != null ? Ok(scheduleOrder) : NotFound(); return scheduleOrder != null ? Ok(scheduleOrder) : NotFound();
} }
[HttpGet("by-co-number")]
public async Task<ActionResult<CustomerOrderDto?>> GetByCoNumber([FromQuery] string customerOrderNumber)
{
CustomerOrderDto? scheduleOrder = await service.GetByCoNumber(customerOrderNumber);
return scheduleOrder != null ? Ok(scheduleOrder) : NotFound();
}
[HttpGet("items-by-co-number")]
public async Task<ActionResult<CustomerOrderDto?>> GetItemsByCoNumber([FromQuery] string customerOrderNumber)
{
var customerOrderLineItems = await service.GetItemsByCoNumber(customerOrderNumber);
return customerOrderLineItems != null ? Ok(customerOrderLineItems) : NotFound();
}
} }
} }

View File

@@ -17,154 +17,154 @@ public class HangfireJobsController(
ITaskSchedulerService service) : Controller ITaskSchedulerService service) : Controller
{ {
public async Task<ActionResult<IEnumerable<JobModel>>> GetJobsToRun() // public async Task<ActionResult<IEnumerable<JobModel>>> GetJobsToRun()
{ // {
IList<JobModel> jobsToRun = new List<JobModel>(); // IList<JobModel> jobsToRun = new List<JobModel>();
//
using (IStorageConnection? connection = jobStorage.GetConnection()) // using (IStorageConnection? connection = jobStorage.GetConnection())
{ // {
IList<RecurringJobDto>? recurringJobs = connection.GetRecurringJobs(); // IList<RecurringJobDto>? recurringJobs = connection.GetRecurringJobs();
IList<TaskSchedulerDto>? taskSchedulers = (await service.GetTaskSchedulers()).ToList(); // IList<TaskSchedulerDto>? taskSchedulers = (await service.GetTaskSchedulers()).ToList();
//
foreach (var recurringJob in recurringJobs) // foreach (var recurringJob in recurringJobs)
{ // {
TaskSchedulerDto? taskScheduler = taskSchedulers?.FirstOrDefault(ts => ts.Name == recurringJob.Id); // TaskSchedulerDto? taskScheduler = taskSchedulers?.FirstOrDefault(ts => ts.Name == recurringJob.Id);
//
if (taskScheduler != null) // if (taskScheduler != null)
{ // {
jobsToRun.Add(new JobModel(recurringJob.Id, recurringJob.Cron, taskScheduler.Path, // jobsToRun.Add(new JobModel(recurringJob.Id, recurringJob.Cron, taskScheduler.Path,
recurringJob.LastExecution, recurringJob.NextExecution, recurringJob.Job)); // recurringJob.LastExecution, recurringJob.NextExecution, recurringJob.Job));
} // }
} // }
} // }
//
return Ok(jobsToRun); // return Ok(jobsToRun);
} // }
//
[HttpPost("run")] // [HttpPost("run")]
public async Task<IActionResult> RunJobs() // public async Task<IActionResult> RunJobs()
{ // {
var jobsToRun = (await GetJobsToRun()).Value?.ToList(); // var jobsToRun = (await GetJobsToRun()).Value?.ToList();
//
if (jobsToRun == null || jobsToRun.Count == 0) // if (jobsToRun == null || jobsToRun.Count == 0)
{ // {
return BadRequest("Nie udało się pobrać zadań do uruchomienia."); // return BadRequest("Nie udało się pobrać zadań do uruchomienia.");
} // }
//
foreach (var job in jobsToRun) // foreach (var job in jobsToRun)
{ // {
if (!string.IsNullOrEmpty(job.Path)) // if (!string.IsNullOrEmpty(job.Path))
{ // {
recurringJobManager.AddOrUpdate(job.JobId, () => RunConsoleApplication(job.Path), job.Cron, // recurringJobManager.AddOrUpdate(job.JobId, () => RunConsoleApplication(job.Path), job.Cron,
new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }); // new RecurringJobOptions { TimeZone = TimeZoneInfo.Local });
} // }
} // }
//
return Ok("Zadania zostały zaplanowane do uruchamiania zgodnie z ich CRON."); // return Ok("Zadania zostały zaplanowane do uruchamiania zgodnie z ich CRON.");
} // }
//
[HttpPost("add")] // [HttpPost("add")]
public async Task<IActionResult> AddTask([FromBody] TaskSchedulerDto taskSchedulerDto) // public async Task<IActionResult> AddTask([FromBody] TaskSchedulerDto taskSchedulerDto)
{ // {
var taskScheduler = new OrdersManagementDataModel.Entities.TaskScheduler // var taskScheduler = new OrdersManagementDataModel.Entities.TaskScheduler
{ // {
Name = taskSchedulerDto.Name, // Name = taskSchedulerDto.Name,
Path = taskSchedulerDto.Path, // Path = taskSchedulerDto.Path,
CronOptions = taskSchedulerDto.CronOptions, // CronOptions = taskSchedulerDto.CronOptions,
CreateDate = DateTime.UtcNow // CreateDate = DateTime.UtcNow
}; // };
//
int result = await service.AddTaskScheduler(taskSchedulerDto); // int result = await service.AddTaskScheduler(taskSchedulerDto);
//
if (result == 0) // if (result == 0)
{ // {
return BadRequest("Nie udało się dodać zadania."); // return BadRequest("Nie udało się dodać zadania.");
} // }
//
recurringJobManager.AddOrUpdate(taskScheduler.Name, () => RunConsoleApplication(taskScheduler.Path), // recurringJobManager.AddOrUpdate(taskScheduler.Name, () => RunConsoleApplication(taskScheduler.Path),
taskScheduler.CronOptions, new RecurringJobOptions { TimeZone = TimeZoneInfo.Local }); // taskScheduler.CronOptions, new RecurringJobOptions { TimeZone = TimeZoneInfo.Local });
//
return Ok("Zadanie zostało dodane."); // return Ok("Zadanie zostało dodane.");
} // }
//
[HttpPost("delete")] // [HttpPost("delete")]
public async Task<IActionResult> DeleteTask([FromBody] TaskSchedulerDto taskSchedulerDto) // public async Task<IActionResult> DeleteTask([FromBody] TaskSchedulerDto taskSchedulerDto)
{ // {
int result = await service.DeleteTaskScheduler(taskSchedulerDto.RowPointer); // int result = await service.DeleteTaskScheduler(taskSchedulerDto.RowPointer);
//
if (result == 0) // if (result == 0)
{ // {
return BadRequest("Nie udało się usunąć zadania."); // return BadRequest("Nie udało się usunąć zadania.");
} // }
//
recurringJobManager.RemoveIfExists(taskSchedulerDto.Name); // recurringJobManager.RemoveIfExists(taskSchedulerDto.Name);
//
return Ok("Zadanie zostało usunięte."); // return Ok("Zadanie zostało usunięte.");
} // }
//
[HttpGet] // [HttpGet]
public async Task<ActionResult<IEnumerable<TaskSchedulerDto>>> GetTasks() // public async Task<ActionResult<IEnumerable<TaskSchedulerDto>>> GetTasks()
{ // {
var tasks = await service.GetTaskSchedulers(); // var tasks = await service.GetTaskSchedulers();
//
foreach (TaskSchedulerDto taskSchedulerDto in tasks) // foreach (TaskSchedulerDto taskSchedulerDto in tasks)
{ // {
var job = GetJob(taskSchedulerDto.Name); // var job = GetJob(taskSchedulerDto.Name);
taskSchedulerDto.LastExecution = job?.LastExecution; // taskSchedulerDto.LastExecution = job?.LastExecution;
taskSchedulerDto.NextExecution = job?.NextExecution; // taskSchedulerDto.NextExecution = job?.NextExecution;
} // }
//
return Ok(tasks); // return Ok(tasks);
} // }
//
[HttpGet("by-name")] // [HttpGet("by-name")]
public async Task<ActionResult<TaskSchedulerDto>> GetTaskSchedulerByTaskName([FromQuery] string name) // public async Task<ActionResult<TaskSchedulerDto>> GetTaskSchedulerByTaskName([FromQuery] string name)
{ // {
var taskSchedulerDto = await service.GetTaskSchedulerByTaskName(name); // var taskSchedulerDto = await service.GetTaskSchedulerByTaskName(name);
//
if (taskSchedulerDto == null) return NotFound(); // if (taskSchedulerDto == null) return NotFound();
//
var job = GetJob(taskSchedulerDto.Name); // var job = GetJob(taskSchedulerDto.Name);
taskSchedulerDto.LastExecution = job?.LastExecution; // taskSchedulerDto.LastExecution = job?.LastExecution;
taskSchedulerDto.NextExecution = job?.NextExecution; // taskSchedulerDto.NextExecution = job?.NextExecution;
//
return Ok(taskSchedulerDto); // return Ok(taskSchedulerDto);
} // }
//
private RecurringJobDto? GetJob(string jobId) // private RecurringJobDto? GetJob(string jobId)
{ // {
using IStorageConnection? connection = jobStorage.GetConnection(); // using IStorageConnection? connection = jobStorage.GetConnection();
IList<RecurringJobDto>? recurringJobs = connection.GetRecurringJobs(); // IList<RecurringJobDto>? recurringJobs = connection.GetRecurringJobs();
return recurringJobs.FirstOrDefault(x => x.Id == jobId); // return recurringJobs.FirstOrDefault(x => x.Id == jobId);
} // }
//
public void RunConsoleApplication(string pathToApp) // public void RunConsoleApplication(string pathToApp)
{ // {
try // try
{ // {
var process = new Process // var process = new Process
{ // {
StartInfo = new ProcessStartInfo // StartInfo = new ProcessStartInfo
{ // {
FileName = pathToApp, // FileName = pathToApp,
UseShellExecute = false, // UseShellExecute = false,
RedirectStandardOutput = true, // RedirectStandardOutput = true,
RedirectStandardError = true, // RedirectStandardError = true,
CreateNoWindow = true, // CreateNoWindow = true,
WorkingDirectory = Path.GetDirectoryName(pathToApp) // WorkingDirectory = Path.GetDirectoryName(pathToApp)
} // }
}; // };
process.Start(); // process.Start();
string output = process.StandardOutput.ReadToEnd(); // string output = process.StandardOutput.ReadToEnd();
string error = process.StandardError.ReadToEnd(); // string error = process.StandardError.ReadToEnd();
process.WaitForExit(); // process.WaitForExit();
//
Console.WriteLine($"Output: {output}"); // Console.WriteLine($"Output: {output}");
Console.WriteLine($"Error: {error}"); // Console.WriteLine($"Error: {error}");
} // }
catch (Exception ex) // catch (Exception ex)
{ // {
Console.WriteLine($"Error executing console application: {ex.Message}"); // Console.WriteLine($"Error executing console application: {ex.Message}");
} // }
} // }
} }

View File

@@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Mvc;
using SytelineSaAppEfDataModel.Dtos;
using SytelineSaAppEfDataModel.Services;
namespace FaKrosnoApi.Controllers;
[ApiController]
[Route("api/[controller]")]
public class ItemCustController(IItemCustService service) : Controller
{
public async Task<ActionResult<ItemCustDto>> GetItem([FromQuery] string itemNumber, [FromQuery] string customerNumber)
{
ItemCustDto item = await service.GetItem(itemNumber, customerNumber);
return item != null ? Ok(item) : NotFound();
}
}

View File

@@ -26,4 +26,23 @@ public class WzRowMeyleController(IWzRowMeyleService service) : Controller
await service.CreateRows(rows); await service.CreateRows(rows);
return CreatedAtAction(nameof(GetAll), new { count = rows.Count() }, rows); return CreatedAtAction(nameof(GetAll), new { count = rows.Count() }, rows);
} }
[HttpGet("by-wz-header-id")]
public async Task<ActionResult<IEnumerable<WzRowMeyleDto>>> GetByWzHeaderId(Guid wzHeaderId)
{
IEnumerable<WzRowMeyleDto> wzRows = await service.GetByWzHeaderId(wzHeaderId);
return Ok(wzRows);
}
[HttpPut]
public async Task<ActionResult> UpdateRows([FromBody] IEnumerable<WzRowMeyleDto> rows)
{
if (rows == null || !rows.Any())
{
return BadRequest("No rows provided.");
}
await service.UpdateRows(rows);
return NoContent();
}
} }

View File

@@ -69,19 +69,19 @@ builder.Services.AddOpenApiDocument(config =>
config.OperationProcessors.Add(new OperationSecurityScopeProcessor("Bearer")); config.OperationProcessors.Add(new OperationSecurityScopeProcessor("Bearer"));
}); });
builder.Services.AddHangfire(config => config // builder.Services.AddHangfire(config => config
.SetDataCompatibilityLevel(CompatibilityLevel.Version_170) // .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
.UseSimpleAssemblyNameTypeSerializer() // .UseSimpleAssemblyNameTypeSerializer()
.UseRecommendedSerializerSettings() // .UseRecommendedSerializerSettings()
.UseSqlServerStorage(builder.Configuration.GetConnectionString("OrdersManagementConnection"), new SqlServerStorageOptions // .UseSqlServerStorage(builder.Configuration.GetConnectionString("OrdersManagementConnection"), new SqlServerStorageOptions
{ // {
CommandBatchMaxTimeout = TimeSpan.FromMinutes(5), // CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5), // SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
QueuePollInterval = TimeSpan.Zero, // QueuePollInterval = TimeSpan.Zero,
UseRecommendedIsolationLevel = true, // UseRecommendedIsolationLevel = true,
DisableGlobalLocks = true // DisableGlobalLocks = true
})); // }));
builder.Services.AddHangfireServer(); // builder.Services.AddHangfireServer();
builder.Services.AddAutoMapper(typeof(FaKrosnoMappingProfile), typeof(SytelineSaAppMappingProfile), builder.Services.AddAutoMapper(typeof(FaKrosnoMappingProfile), typeof(SytelineSaAppMappingProfile),
typeof(OrdersManagementMappingProfile)); typeof(OrdersManagementMappingProfile));
@@ -104,6 +104,7 @@ builder.Services.AddScoped<IMaterialTransactionService, MaterialTransactionServi
builder.Services.AddScoped<IWzClientService, WzClientService>(); builder.Services.AddScoped<IWzClientService, WzClientService>();
builder.Services.AddScoped<IWzHeaderService, WzHeaderService>(); builder.Services.AddScoped<IWzHeaderService, WzHeaderService>();
builder.Services.AddScoped<IWzRowMeyleService, WzRowMeyleService>(); builder.Services.AddScoped<IWzRowMeyleService, WzRowMeyleService>();
builder.Services.AddScoped<IItemCustService, ItemCustService>();
builder.Services.AddHostedService<TimedHostedService>(); builder.Services.AddHostedService<TimedHostedService>();
@@ -119,6 +120,6 @@ app.UseAuthorization();
app.MapControllers(); app.MapControllers();
app.UseHangfireDashboard(); // app.UseHangfireDashboard();
app.Run(); app.Run();

View File

@@ -9,6 +9,7 @@
@using Syncfusion.Blazor.Navigations @using Syncfusion.Blazor.Navigations
@inject WarehouseService WarehouseService @inject WarehouseService WarehouseService
@inject NavigationManager NavigationManager
<div class="h-100 d-flex justify-content-center align-items-start"> <div class="h-100 d-flex justify-content-center align-items-start">
<SfCard CssClass="shadow" style="width: 100%; max-width: 1200px;"> <SfCard CssClass="shadow" style="width: 100%; max-width: 1200px;">
@@ -30,12 +31,10 @@
AllowSorting="true" AllowSorting="true"
AllowSelection="true" AllowSelection="true"
TValue="MaterialTransactionDto" TValue="MaterialTransactionDto"
DataSource="@_materialTransactions" DataSource="@_dataSource"
EnableAdaptiveUI="true"> EnableAdaptiveUI="true">
<GridColumns> <GridColumns>
<GridColumn Field=@nameof(MaterialTransactionDto.MTGroupNum) HeaderText="Numer WZ" TextAlign="TextAlign.Center" Width="110"></GridColumn> <GridColumn Field=@nameof(MaterialTransactionDto.MTGroupNum) HeaderText="Numer WZ" TextAlign="TextAlign.Center" Width="110"></GridColumn>
<GridColumn Field=@nameof(MaterialTransactionDto.Item) HeaderText="Indeks" TextAlign="TextAlign.Center" Width="80"></GridColumn>
<GridColumn Field=@nameof(MaterialTransactionDto.Qty) HeaderText="Ilość sztuk" TextAlign="TextAlign.Right" Width="90"></GridColumn>
<GridColumn Field=@nameof(MaterialTransactionDto.CreateDate) HeaderText="Data utworzenia" TextAlign="TextAlign.Center" Width="100"></GridColumn> <GridColumn Field=@nameof(MaterialTransactionDto.CreateDate) HeaderText="Data utworzenia" TextAlign="TextAlign.Center" Width="100"></GridColumn>
<GridColumn Field=@nameof(MaterialTransactionDto.RefNum) HeaderText="Numer zamówienia" TextAlign="TextAlign.Center" Width="110"></GridColumn> <GridColumn Field=@nameof(MaterialTransactionDto.RefNum) HeaderText="Numer zamówienia" TextAlign="TextAlign.Center" Width="110"></GridColumn>
</GridColumns> </GridColumns>
@@ -48,7 +47,6 @@
<GridFilterSettings Type="FilterType.Excel"/> <GridFilterSettings Type="FilterType.Excel"/>
<GridPageSettings PageSize="10" PageSizes="@(new[] { 10, 20, 50, 100 })"/> <GridPageSettings PageSize="10" PageSizes="@(new[] { 10, 20, 50, 100 })"/>
<GridSelectionSettings Mode="SelectionMode.Row" Type="SelectionType.Multiple"/> <GridSelectionSettings Mode="SelectionMode.Row" Type="SelectionType.Multiple"/>
@* <GridEvents TValue="EdiCustomerOrderDto" OnRecordDoubleClick="OnRowDoubleClick" RowSelected="RowSelected"/> *@
</SfGrid> </SfGrid>
} }
</CardContent> </CardContent>
@@ -60,10 +58,11 @@
@code { @code {
private SfGrid<MaterialTransactionDto> _grid; private SfGrid<MaterialTransactionDto> _grid;
IEnumerable<WzClientDto> _clients = new List<WzClientDto>(); private IEnumerable<WzClientDto> _clients = new List<WzClientDto>();
IEnumerable<MaterialTransactionDto> _materialTransactions = new List<MaterialTransactionDto>(); private IEnumerable<MaterialTransactionDto> _materialTransactions = new List<MaterialTransactionDto>();
private IEnumerable<MaterialTransactionDto> _dataSource = new List<MaterialTransactionDto>();
WzClientDto? _selectedClient; private WzClientDto? _selectedClient;
bool _isVisible = false; bool _isVisible = false;
@@ -83,6 +82,7 @@
_selectedClient = args.ItemData; _selectedClient = args.ItemData;
_isVisible = true; _isVisible = true;
_materialTransactions = await WarehouseService.GetAllClientWzsAsync(_selectedClient.CustomerNumber, _selectedClient.CustomerSequence ?? 0); _materialTransactions = await WarehouseService.GetAllClientWzsAsync(_selectedClient.CustomerNumber, _selectedClient.CustomerSequence ?? 0);
_dataSource = _materialTransactions.GroupBy(x => x.MTGroupNum).Select(x => x.First()).ToList();
} }
else else
{ {
@@ -110,17 +110,29 @@
{ {
case "MEYLE": case "MEYLE":
IList<WzRowMeyleDto> rows = new List<WzRowMeyleDto>(); IList<WzRowMeyleDto> rows = new List<WzRowMeyleDto>();
foreach (MaterialTransactionDto materialTransactionDto in selectedRecords) IList<MaterialTransactionDto> materialTransactions = _materialTransactions.Where(x => selectedRecords.Any(y => y.MTGroupNum == x.MTGroupNum)).ToList();
foreach (MaterialTransactionDto materialTransactionDto in materialTransactions)
{ {
CustomerOrderDto customerOrder = await WarehouseService.GetCustomerOrder(materialTransactionDto.RefNum ?? string.Empty);
ItemCustDto item = await WarehouseService.GetItem(materialTransactionDto.Item ?? string.Empty, customerOrder.CustNum);
rows.Add(new WzRowMeyleDto rows.Add(new WzRowMeyleDto
{ {
ID = Guid.NewGuid(), ID = Guid.NewGuid(),
Quantity = Math.Abs((int?)materialTransactionDto.Qty ?? 0), Quantity = Math.Abs((int?)materialTransactionDto.Qty ?? 0),
//ItemNumber = ItemNumber = item.CustItem,
OrderNumber = customerOrder.CustPo,
WzNumber = materialTransactionDto.MTGroupNum ?? string.Empty,
FK_Header = wzHeader.ID
}); });
} }
await WarehouseService.CreateWzRowsMeyleAsync(rows);
break; break;
} }
NavigationManager.NavigateTo("/Warehouse/PackList/" + wzHeader.ID);
} }
} }
} }

View File

@@ -1,7 +1,104 @@
@page "/Warehouse/PackList" @page "/Warehouse/PackList/{WzHeader:guid}"
@using Syncfusion.Blazor.Cards
@using Syncfusion.Blazor.Grids
@using SytelineSaAppEfDataModel.Dtos
@using Syncfusion.Blazor.Navigations
<h3>WarehousePackList</h3> @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>
<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" Id="SaveButton"
PrefixIcon="e-icons e-save" OnClick="SaveChanges"/>
<ToolbarItem Type="ItemType.Button" Id="Generuj XLS" PrefixIcon="e-icons export-xls"
Text="Usuń Zapisane Filtry" 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.ItemNumber) AllowEditing="false"
TextAlign="TextAlign.Center" HeaderText="Meyle Numer" 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.PartNumber) AllowEditing="true" TextAlign="TextAlign.Center"
HeaderText="Nr Partii" 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>
<CardFooter>
<small class="text-muted">FA Krosno Manager © @(DateTime.Now.Year)</small>
</CardFooter>
</SfCard>
</div>
@code { @code {
[Parameter] public Guid WzHeader { get; set; }
private SfGrid<WzRowMeyleDto> _grid;
private IEnumerable<WzRowMeyleDto> _wzRowsMeyle { get; set; } = new List<WzRowMeyleDto>();
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
_wzRowsMeyle = await WarehouseService.GetWzRowsByWzHeaderId(WzHeader);
StateHasChanged();
}
}
private async Task SaveChanges()
{
await _grid.EndEditAsync();
}
private async Task OnBatchSave(BeforeBatchSaveArgs<WzRowMeyleDto> obj)
{
var changes = obj.BatchChanges;
var changedRecords = changes.ChangedRecords;
await WarehouseService.UpdateWzRowsMeyleAsync(changedRecords);
_wzRowsMeyle = await WarehouseService.GetWzRowsByWzHeaderId(WzHeader);
StateHasChanged();
await _grid.Refresh();
}
private async Task ExportXls()
{
await _grid.ExportToExcelAsync();
}
} }

View File

@@ -31,13 +31,53 @@ public class WarehouseService(IHttpClientFactory httpClientFactory)
} }
} }
public async Task CreateWzRowMeyleAsync(IEnumerable<WzRowMeyleDto> wzRowMeyles) public async Task CreateWzRowsMeyleAsync(IEnumerable<WzRowMeyleDto> wzRowMeyles)
{ {
var response = await _httpClient.PostAsJsonAsync("api/WzRowMeyle", wzRowMeyles); if (wzRowMeyles == null || !wzRowMeyles.Any())
response.EnsureSuccessStatusCode();
if (response.StatusCode != System.Net.HttpStatusCode.Created)
{ {
throw new Exception("Failed to create WzRowMeyle"); throw new ArgumentException("No rows provided to create.");
} }
var response = await _httpClient.PostAsJsonAsync("api/WzRowMeyle", wzRowMeyles);
if (!response.IsSuccessStatusCode)
{
var errorContent = await response.Content.ReadAsStringAsync();
throw new HttpRequestException($"Failed to create WzRowMeyle: {response.StatusCode}, Content: {errorContent}");
}
}
public async Task<CustomerOrderDto> GetCustomerOrder(string customerOrderNumber)
{
var response = await _httpClient.GetAsync(
$"api/CustomerOrders/by-co-number/?customerOrderNumber={customerOrderNumber}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<CustomerOrderDto>();
}
public async Task<ItemCustDto> GetItem(string itemNumber, string customerNumber)
{
var response = await _httpClient.GetAsync(
$"api/ItemCust?itemNumber={itemNumber}&customerNumber={customerNumber}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<ItemCustDto>();
}
public async Task<IEnumerable<WzRowMeyleDto>> GetWzRowsByWzHeaderId(Guid wzHeaderId)
{
var response = await _httpClient.GetAsync($"api/WzRowMeyle/by-wz-header-id?wzHeaderId={wzHeaderId}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadFromJsonAsync<IEnumerable<WzRowMeyleDto>>();
}
public async Task UpdateWzRowsMeyleAsync(IEnumerable<WzRowMeyleDto> wzRowsMeyle)
{
if (wzRowsMeyle == null || !wzRowsMeyle.Any())
{
throw new ArgumentException("No rows provided to update.");
}
var response = await _httpClient.PutAsJsonAsync("api/WzRowMeyle", wzRowsMeyle);
response.EnsureSuccessStatusCode();
} }
} }

View File

@@ -0,0 +1,30 @@
namespace SytelineSaAppEfDataModel.Dtos;
public class ItemCustDto
{
public string Item { get; set; }
public string CustNum { get; set; }
public int CustItemSeq { get; set; }
public string CustItem { get; set; }
public int? PurchYtd { get; set; }
public decimal? OrderYtd { get; set; }
public decimal? ShipYtd { get; set; }
public decimal? OrderPtd { get; set; }
public string UM { get; set; }
public int? DuePeriod { get; set; }
public byte NoteExistsFlag { get; set; }
public DateTime RecordDate { get; set; }
public Guid RowPointer { get; set; }
public string CreatedBy { get; set; }
public string UpdatedBy { get; set; }
public DateTime CreateDate { get; set; }
public byte InWorkflow { get; set; }
public int? Rank { get; set; }
public string EndUser { get; set; }
public string Uf_FKR_CustItem2 { get; set; }
public string Uf_KOD_EAN13 { get; set; }
public string Uf_Paleta_BROSE { get; set; }
public string Uf_Pojemnik_BROSE { get; set; }
public string Uf_Paleta_BROSE_Pokrywa { get; set; }
public string Uf_RewizjaRysunku { get; set; }
}

View File

@@ -9,5 +9,5 @@ public class WzRowMeyleDto
public int? Quantity { get; set; } public int? Quantity { get; set; }
public int? PalletNumber { get; set; } public int? PalletNumber { get; set; }
public string WzNumber { get; set; } public string WzNumber { get; set; }
public string PartNumber { get; set; } public string? PartNumber { get; set; }
} }

View File

@@ -0,0 +1,30 @@
namespace SytelineSaAppEfDataModel.Entities;
public class ItemCust
{
public string Item { get; set; }
public string CustNum { get; set; }
public int CustItemSeq { get; set; }
public string CustItem { get; set; }
public int? PurchYtd { get; set; }
public decimal? OrderYtd { get; set; }
public decimal? ShipYtd { get; set; }
public decimal? OrderPtd { get; set; }
public string UM { get; set; }
public int? DuePeriod { get; set; }
public byte NoteExistsFlag { get; set; }
public DateTime RecordDate { get; set; }
public Guid RowPointer { get; set; }
public string CreatedBy { get; set; }
public string UpdatedBy { get; set; }
public DateTime CreateDate { get; set; }
public byte InWorkflow { get; set; }
public int? Rank { get; set; }
public string EndUser { get; set; }
public string Uf_FKR_CustItem2 { get; set; }
public string Uf_KOD_EAN13 { get; set; }
public string Uf_Paleta_BROSE { get; set; }
public string Uf_Pojemnik_BROSE { get; set; }
public string Uf_Paleta_BROSE_Pokrywa { get; set; }
public string Uf_RewizjaRysunku { get; set; }
}

View File

@@ -9,7 +9,7 @@ public class WzRowMeyle
public int? Quantity { get; set; } public int? Quantity { get; set; }
public int? PalletNumber { get; set; } public int? PalletNumber { get; set; }
public string WzNumber { get; set; } public string WzNumber { get; set; }
public string PartNumber { get; set; } public string? PartNumber { get; set; }
// Navigation property // Navigation property
public WzHeader Header { get; set; } public WzHeader Header { get; set; }

View File

@@ -23,6 +23,7 @@ namespace SytelineSaAppEfDataModel
CreateMap<WzClient, WzClientDto>().ReverseMap(); CreateMap<WzClient, WzClientDto>().ReverseMap();
CreateMap<WzHeader, WzHeaderDto>().ReverseMap(); CreateMap<WzHeader, WzHeaderDto>().ReverseMap();
CreateMap<WzRowMeyle, WzRowMeyleDto>().ReverseMap(); CreateMap<WzRowMeyle, WzRowMeyleDto>().ReverseMap();
CreateMap<ItemCust, ItemCustDto>().ReverseMap();
} }
} }
} }

View File

@@ -1,9 +1,4 @@
using AutoMapper; using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using SytelineSaAppEfDataModel.Dtos; using SytelineSaAppEfDataModel.Dtos;
@@ -42,5 +37,41 @@ namespace SytelineSaAppEfDataModel.Services
return customerOrder; return customerOrder;
} }
public async Task<CustomerOrderDto?> GetByCoNumber(string orderNumber)
{
CustomerOrderDto? customerOrder = await context.CustomerOrders
.Where(x => x.CoNum == orderNumber)
.Select(x => mapper.Map<CustomerOrderDto>(x)).FirstOrDefaultAsync();
if (customerOrder == null) return null;
customerOrder.CustomerOrderLines = await context.CustomerOrderLines
.Where(x => x.CoNum == customerOrder.CoNum)
.Select(x => mapper.Map<CustomerOrderLineDto>(x)).ToListAsync();
foreach (CustomerOrderLineDto customerOrderLine in customerOrder.CustomerOrderLines)
{
customerOrderLine.CustomerOrderLineItems = await context.CustomerOrderLineItems
.Where(x => x.CoNum == customerOrder.CoNum && x.CoLine == customerOrderLine.CoLine)
.Select(x => mapper.Map<CustomerOrderLineItemDto>(x)).ToListAsync();
}
IList<EdiCustomerOrderTranslateDto> ediCustomerOrderTranslates = await context.EdiCustomerOrderTranslates
.Where(x => x.CoCoNum == customerOrder.CoNum)
.Select(x => mapper.Map<EdiCustomerOrderTranslateDto>(x)).ToListAsync();
customerOrder.EdiCustomerOrderTranslates = ediCustomerOrderTranslates;
return customerOrder;
}
public async Task<IEnumerable<CustomerOrderLineItemDto>?> GetItemsByCoNumber(string customerOrderNumber)
{
List<CustomerOrderLineItemDto> customerOrderLineItems = await context.CustomerOrderLineItems
.Where(x => x.CoNum == customerOrderNumber)
.Select(x => mapper.Map<CustomerOrderLineItemDto>(x)).ToListAsync();
return customerOrderLineItems;
}
} }
} }

View File

@@ -11,5 +11,7 @@ namespace SytelineSaAppEfDataModel.Services
{ {
Task<IEnumerable<CustomerOrderDto>> GetAll(); Task<IEnumerable<CustomerOrderDto>> GetAll();
Task<CustomerOrderDto?> GetByOrderNumber(Guid orderNumber); Task<CustomerOrderDto?> GetByOrderNumber(Guid orderNumber);
Task<CustomerOrderDto?> GetByCoNumber(string orderNumber);
Task<IEnumerable<CustomerOrderLineItemDto>?> GetItemsByCoNumber(string customerOrderNumber);
} }
} }

View File

@@ -0,0 +1,8 @@
using SytelineSaAppEfDataModel.Dtos;
namespace SytelineSaAppEfDataModel.Services;
public interface IItemCustService
{
Task<ItemCustDto> GetItem(string itemNumber, string customerNumber);
}

View File

@@ -6,4 +6,6 @@ public interface IWzRowMeyleService
{ {
Task<IEnumerable<WzRowMeyleDto>> GetAll(); Task<IEnumerable<WzRowMeyleDto>> GetAll();
Task CreateRows(IEnumerable<WzRowMeyleDto> rows); Task CreateRows(IEnumerable<WzRowMeyleDto> rows);
Task<IEnumerable<WzRowMeyleDto>> GetByWzHeaderId(Guid wzHeaderId);
Task UpdateRows(IEnumerable<WzRowMeyleDto> rows);
} }

View File

@@ -0,0 +1,17 @@
using AutoMapper;
using SytelineSaAppEfDataModel.Dtos;
namespace SytelineSaAppEfDataModel.Services;
public class ItemCustService(SytelineSaAppDbContext context, IMapper mapper) : IItemCustService
{
public Task<ItemCustDto> GetItem(string itemNumber, string customerNumber)
{
var item = context.ItemCusts
.FirstOrDefault(x => x.Item == itemNumber && x.CustNum == customerNumber);
return item == null
? Task.FromResult<ItemCustDto>(null)
: Task.FromResult(mapper.Map<ItemCustDto>(item));
}
}

View File

@@ -18,4 +18,19 @@ public class WzRowMeyleService(SytelineSaAppDbContext context, IMapper mapper) :
await context.WzRowsMeyle.AddRangeAsync(entities); await context.WzRowsMeyle.AddRangeAsync(entities);
await context.SaveChangesAsync(); await context.SaveChangesAsync();
} }
public async Task<IEnumerable<WzRowMeyleDto>> GetByWzHeaderId(Guid wzHeaderId)
{
return await context.WzRowsMeyle
.Where(x => x.FK_Header == wzHeaderId)
.Select(x => mapper.Map<WzRowMeyleDto>(x))
.ToListAsync();
}
public async Task UpdateRows(IEnumerable<WzRowMeyleDto> rows)
{
var entities = mapper.Map<IEnumerable<WzRowMeyle>>(rows);
context.WzRowsMeyle.UpdateRange(entities);
await context.SaveChangesAsync();
}
} }

View File

@@ -25,6 +25,8 @@ namespace SytelineSaAppEfDataModel
public DbSet<WzHeader> WzHeaders { get; set; } public DbSet<WzHeader> WzHeaders { get; set; }
public DbSet<WzRowMeyle> WzRowsMeyle { get; set; } public DbSet<WzRowMeyle> WzRowsMeyle { get; set; }
public DbSet<ItemCust> ItemCusts { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{ {
var configuration = new ConfigurationBuilder() var configuration = new ConfigurationBuilder()
@@ -990,6 +992,149 @@ namespace SytelineSaAppEfDataModel
.HasForeignKey(e => e.FK_Header) .HasForeignKey(e => e.FK_Header)
.HasConstraintName("wz_rows_meyle_wz_header_ID_fk"); .HasConstraintName("wz_rows_meyle_wz_header_ID_fk");
}); });
modelBuilder.Entity<ItemCust>(entity =>
{
entity.ToTable("itemcust");
entity.HasKey(e => new { e.Item, e.CustNum, e.CustItemSeq });
entity.Property(e => e.Item)
.HasColumnName("item")
.HasMaxLength(60)
.IsRequired();
entity.Property(e => e.CustNum)
.HasColumnName("cust_num")
.HasMaxLength(14)
.IsRequired();
entity.Property(e => e.CustItemSeq)
.HasColumnName("cust_item_seq")
.HasColumnType("int")
.HasDefaultValueSql("1");
entity.Property(e => e.CustItem)
.HasColumnName("cust_item")
.HasMaxLength(60)
.IsRequired(false);
entity.Property(e => e.PurchYtd)
.HasColumnName("purch_ytd")
.HasDefaultValueSql("0")
.IsRequired(false);
entity.Property(e => e.OrderYtd)
.HasColumnName("order_ytd")
.HasDefaultValueSql("0")
.IsRequired(false);
entity.Property(e => e.ShipYtd)
.HasColumnName("ship_ytd")
.HasDefaultValueSql("0")
.IsRequired(false);
entity.Property(e => e.OrderPtd)
.HasColumnName("order_ptd")
.HasDefaultValueSql("0")
.IsRequired(false);
entity.Property(e => e.UM)
.HasColumnName("u_m")
.HasMaxLength(6)
.IsRequired(false);
entity.Property(e => e.DuePeriod)
.HasColumnName("due_period")
.HasColumnType("smallint")
.IsRequired(false);
entity.Property(e => e.NoteExistsFlag)
.HasColumnName("NoteExistsFlag")
.HasColumnType("tinyint")
.HasDefaultValueSql("0");
entity.Property(e => e.RecordDate)
.HasColumnName("RecordDate")
.HasDefaultValueSql("getdate()");
entity.Property(e => e.RowPointer)
.HasColumnName("RowPointer")
.HasColumnType("uniqueidentifier")
.HasDefaultValueSql("newid()");
entity.Property(e => e.CreatedBy)
.HasColumnName("CreatedBy")
.HasMaxLength(60)
.HasDefaultValueSql("suser_sname()");
entity.Property(e => e.UpdatedBy)
.HasColumnName("UpdatedBy")
.HasMaxLength(60)
.HasDefaultValueSql("suser_sname()");
entity.Property(e => e.CreateDate)
.HasColumnName("CreateDate")
.HasDefaultValueSql("getdate()");
entity.Property(e => e.InWorkflow)
.HasColumnName("InWorkflow")
.HasColumnType("tinyint")
.HasDefaultValueSql("0");
entity.Property(e => e.Rank)
.HasColumnName("rank")
.HasColumnType("int")
.IsRequired(false);
entity.Property(e => e.EndUser)
.HasColumnName("end_user")
.HasMaxLength(60)
.IsRequired(false);
entity.Property(e => e.Uf_FKR_CustItem2)
.HasColumnName("Uf_FKR_CustItem2")
.HasMaxLength(30)
.IsRequired(false);
entity.Property(e => e.Uf_KOD_EAN13)
.HasColumnName("Uf_KOD_EAN13")
.HasMaxLength(13)
.IsRequired(false);
entity.Property(e => e.Uf_Paleta_BROSE)
.HasColumnName("Uf_Paleta_BROSE")
.HasMaxLength(20)
.IsRequired(false);
entity.Property(e => e.Uf_Pojemnik_BROSE)
.HasColumnName("Uf_Pojemnik_BROSE")
.HasMaxLength(20)
.IsRequired(false);
entity.Property(e => e.Uf_Paleta_BROSE_Pokrywa)
.HasColumnName("Uf_Paleta_BROSE_Pokrywa")
.HasMaxLength(30)
.IsRequired(false);
entity.Property(e => e.Uf_RewizjaRysunku)
.HasColumnName("Uf_RewizjaRysunku")
.HasMaxLength(20)
.IsRequired(false);
// Indexes
entity.HasIndex(e => new { e.CustNum, e.Item, e.CustItemSeq })
.HasDatabaseName("IX_itemcust_custitem")
.IsUnique();
entity.HasIndex(e => new { e.CustNum, e.Item, e.CustItem })
.HasDatabaseName("IX_itemcust_custitemci")
.IsUnique();
entity.HasIndex(e => e.RowPointer)
.HasDatabaseName("IX_itemcust_RowPointer")
.IsUnique();
});
} }
} }
} }