Add vendor supply categories with inventory auto-filter

Vendors can now be tagged with one or more inventory categories (Powder,
Chemical, etc.) via checkboxes on the Create/Edit form. The inventory
Create/Edit vendor dropdown automatically filters to matching vendors when
a category is selected; falls back to all vendors if none are tagged.
Includes migration AddVendorCategories (VendorInventoryCategories join table).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-23 09:52:34 -04:00
parent a7bf97a2df
commit d77b3778ac
13 changed files with 10983 additions and 7 deletions
@@ -345,6 +345,10 @@
<option value="">Select vendor</option>
<option value="__new__">+ Add New Vendor&hellip;</option>
</select>
<div id="vendor-filter-note" class="form-text d-none">
<i class="bi bi-funnel me-1 text-info"></i><span class="text-info">Showing vendors for this category.</span>
<a href="#" id="vendor-filter-clear" class="ms-1">Show all</a>
</div>
<span asp-validation-for="PrimaryVendorId" class="text-danger"></span>
</div>
</div>
@@ -438,4 +442,38 @@
{
<script src="~/js/inventory-label-scan.js"></script>
}
<script>
(function () {
const categoryVendorMap = @Html.Raw(ViewBag.CategoryVendorMapJson ?? "{}");
const vendorSelect = document.getElementById('field-vendor');
const allVendorOptions = Array.from(vendorSelect.options).map(o => ({ v: o.value, t: o.text }));
function filterVendors(catId, forceAll) {
const vendorIds = (!forceAll && catId) ? (categoryVendorMap[catId] || []) : [];
const isFiltered = vendorIds.length > 0;
const currentVal = vendorSelect.value;
vendorSelect.innerHTML = '';
allVendorOptions.forEach(function (opt) {
if (!isFiltered || !opt.v || opt.v === '__new__' || vendorIds.includes(Number(opt.v)))
vendorSelect.add(new Option(opt.t, opt.v));
});
if (Array.from(vendorSelect.options).some(o => o.value === currentVal))
vendorSelect.value = currentVal;
document.getElementById('vendor-filter-note').classList.toggle('d-none', !isFiltered);
}
document.getElementById('field-category').addEventListener('change', function () {
filterVendors(this.value, false);
});
document.getElementById('vendor-filter-clear')?.addEventListener('click', function (e) {
e.preventDefault();
filterVendors(document.getElementById('field-category').value, true);
});
filterVendors(document.getElementById('field-category').value, false);
})();
</script>
}