Merge duplicate powder lines on dashboard order queue
When multiple jobs need the same powder, the 'Powder in Queue to be Ordered' panel now collapses them into a single line (summed lbs) rather than showing one row per coat. 'Mark as Ordered' marks all contributing coats at once and injects each into the 'Awaiting Receipt' panel individually so per-coat receiving still works unchanged. - Add PowderOrderJobRefDto; PowderOrderLineDto gains CoatIds + Jobs lists (scalar CoatId/JobId/etc. become computed accessors for backward compat) - MapPowderOrderGroupsMerged: secondary GroupBy on (ColorName, ColorCode, Finish, SKU) within vendor group for the 'needed' panel - MapPowderOrderGroups kept per-coat for the 'awaiting receipt' panel - MarkPowderOrdered accepts comma-separated coatIds, returns coats array - Dashboard view: Customer column loops job refs for merged rows; JS posts coatIds and iterates data.coats to populate awaiting-receipt panel Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -528,11 +528,25 @@
|
||||
<tbody>
|
||||
@foreach (var line in vendorGroup.Lines)
|
||||
{
|
||||
<tr id="powder-line-@line.CoatId">
|
||||
<tr id="powder-line-@line.CoatIds[0]">
|
||||
<td>
|
||||
<a asp-controller="Jobs" asp-action="Details" asp-route-id="@line.JobId"
|
||||
class="fw-medium text-decoration-none">@line.CustomerName</a>
|
||||
<span class="text-muted ms-1">(@line.JobNumber)</span>
|
||||
@if (line.Jobs.Count == 1)
|
||||
{
|
||||
<a asp-controller="Jobs" asp-action="Details" asp-route-id="@line.Jobs[0].JobId"
|
||||
class="fw-medium text-decoration-none">@line.Jobs[0].CustomerName</a>
|
||||
<span class="text-muted ms-1">(@line.Jobs[0].JobNumber)</span>
|
||||
}
|
||||
else
|
||||
{
|
||||
@foreach (var jobRef in line.Jobs)
|
||||
{
|
||||
<div>
|
||||
<a asp-controller="Jobs" asp-action="Details" asp-route-id="@jobRef.JobId"
|
||||
class="fw-medium text-decoration-none">@jobRef.CustomerName</a>
|
||||
<span class="text-muted ms-1">(@jobRef.JobNumber · @jobRef.LbsToOrder.ToString("N2") lbs)</span>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
</td>
|
||||
<td>
|
||||
@if (!string.IsNullOrEmpty(line.ColorName))
|
||||
@@ -551,7 +565,7 @@
|
||||
</td>
|
||||
<td class="text-center">
|
||||
<button class="btn btn-sm btn-outline-danger mark-ordered-btn text-nowrap"
|
||||
data-coat-id="@line.CoatId"
|
||||
data-coat-ids="@string.Join(",", line.CoatIds)"
|
||||
title="Mark as ordered">
|
||||
<i class="bi bi-check2-circle me-1"></i>Mark as Ordered
|
||||
</button>
|
||||
@@ -875,10 +889,11 @@
|
||||
// Powder Orders - Mark as Ordered
|
||||
document.querySelectorAll('.mark-ordered-btn').forEach(btn => {
|
||||
btn.addEventListener('click', async function () {
|
||||
const coatId = this.dataset.coatId;
|
||||
const row = document.getElementById('powder-line-' + coatId);
|
||||
const token = document.querySelector('input[name="__RequestVerificationToken"]')?.value
|
||||
?? document.querySelector('meta[name="__RequestVerificationToken"]')?.content;
|
||||
const coatIds = this.dataset.coatIds;
|
||||
const firstId = coatIds.split(',')[0];
|
||||
const row = document.getElementById('powder-line-' + firstId);
|
||||
const token = document.querySelector('input[name="__RequestVerificationToken"]')?.value
|
||||
?? document.querySelector('meta[name="__RequestVerificationToken"]')?.content;
|
||||
|
||||
this.disabled = true;
|
||||
this.innerHTML = '<span class="spinner-border spinner-border-sm"></span>';
|
||||
@@ -887,7 +902,7 @@
|
||||
const resp = await fetch('@Url.Action("MarkPowderOrdered", "Dashboard")', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'RequestVerificationToken': token },
|
||||
body: 'coatId=' + coatId
|
||||
body: 'coatIds=' + encodeURIComponent(coatIds)
|
||||
});
|
||||
const data = await resp.json();
|
||||
if (data.success) {
|
||||
@@ -905,8 +920,8 @@
|
||||
badge.textContent = n;
|
||||
}
|
||||
}
|
||||
// Inject into Awaiting Receipt widget
|
||||
addToAwaitingReceipt(data.coat);
|
||||
// Inject each marked coat into the Awaiting Receipt widget
|
||||
(data.coats || []).forEach(c => addToAwaitingReceipt(c));
|
||||
}, 400);
|
||||
} else {
|
||||
alert(data.message || 'Could not update. Please try again.');
|
||||
|
||||
Reference in New Issue
Block a user