Add Custom Powder Order line item and fix CSV import FinalPrice crash

Custom powder/incoming powder material cost now flows into a separate
auto-generated 'Custom Powder Order' line item instead of rolling into
individual item prices, so users can add shipping charges before the
customer sees the total. A dashed yellow preview card in the wizard
shows the material cost and lets users edit the total (including shipping)
before saving. After first save the price is user-owned.

Also fixes a fatal CSV import crash when FinalPrice contains a non-numeric
value (e.g. 'false' from a spreadsheet formula): the job CSV importer now
streams rows one at a time with a lenient decimal converter, treating bad
values as $0 with a per-row warning instead of aborting the entire import.

Updated HelpKnowledgeBase.cs and Help articles (Jobs, Quotes) with
Custom Powder Order behavior and a new Data Import / Export section.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-25 23:37:46 -04:00
parent e476b4744d
commit a7ad0e1de8
19 changed files with 721 additions and 78 deletions
@@ -251,6 +251,13 @@
</h5>
</div>
<div class="card-body">
@if (Model.QuoteItems != null && Model.QuoteItems.Any(i => i.Description != null && i.Description.StartsWith("Custom Powder Order")))
{
<div class="alert alert-warning alert-permanent mb-3" role="alert">
<i class="bi bi-truck me-2"></i><strong>Custom Powder Order</strong> &mdash;
The line item below shows material cost only. Add shipping charges before sending this quote to the customer.
</div>
}
@if (Model.QuoteItems != null && Model.QuoteItems.Any())
{
var catalogItems = Model.QuoteItems.Where(i => i.CatalogItemId.HasValue).ToList();