Fix NullReferenceException on Quote Details when quote total is zero
PricingBreakdown was only populated when quote.Total > 0, but the Details view unconditionally dereferences PricingBreakdown.ItemsSubtotal. Sandblast- only quotes can legitimately have a $0 total (no powder/oven costs), leaving PricingBreakdown null and crashing the Details render. Removed the Total > 0 guard from both Details action overloads — always populate PricingBreakdown from the stored snapshot fields (all values are 0 for an unpriced or sandblast-only quote, which is safe for display). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -365,33 +365,30 @@ public class QuotesController : Controller
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build pricing breakdown from stored snapshot values — never recalculate on load
|
// Build pricing breakdown from stored snapshot values — never recalculate on load
|
||||||
if (quote.Total > 0)
|
quoteDto.PricingBreakdown = new QuotePricingBreakdownDto
|
||||||
{
|
{
|
||||||
quoteDto.PricingBreakdown = new QuotePricingBreakdownDto
|
MaterialCosts = quote.MaterialCosts,
|
||||||
{
|
LaborCosts = quote.LaborCosts,
|
||||||
MaterialCosts = quote.MaterialCosts,
|
EquipmentCosts = quote.EquipmentCosts,
|
||||||
LaborCosts = quote.LaborCosts,
|
ItemsSubtotal = quote.ItemsSubtotal,
|
||||||
EquipmentCosts = quote.EquipmentCosts,
|
OvenBatchCost = quote.OvenBatchCost,
|
||||||
ItemsSubtotal = quote.ItemsSubtotal,
|
OvenBatches = quote.OvenBatches,
|
||||||
OvenBatchCost = quote.OvenBatchCost,
|
OvenCycleMinutes = quote.OvenCycleMinutes ?? 0,
|
||||||
OvenBatches = quote.OvenBatches,
|
ShopSuppliesAmount = quote.ShopSuppliesAmount,
|
||||||
OvenCycleMinutes = quote.OvenCycleMinutes ?? 0,
|
ShopSuppliesPercent = quote.ShopSuppliesPercent,
|
||||||
ShopSuppliesAmount = quote.ShopSuppliesAmount,
|
OverheadCosts = quote.OverheadAmount,
|
||||||
ShopSuppliesPercent = quote.ShopSuppliesPercent,
|
OverheadPercent = quote.OverheadPercent,
|
||||||
OverheadCosts = quote.OverheadAmount,
|
ProfitMargin = quote.ProfitMargin,
|
||||||
OverheadPercent = quote.OverheadPercent,
|
ProfitPercent = quote.ProfitPercent,
|
||||||
ProfitMargin = quote.ProfitMargin,
|
SubtotalBeforeDiscount = quote.SubTotal,
|
||||||
ProfitPercent = quote.ProfitPercent,
|
DiscountAmount = quote.DiscountAmount,
|
||||||
SubtotalBeforeDiscount = quote.SubTotal,
|
DiscountPercent = quote.DiscountPercent,
|
||||||
DiscountAmount = quote.DiscountAmount,
|
SubtotalAfterDiscount = quote.SubTotal - quote.DiscountAmount,
|
||||||
DiscountPercent = quote.DiscountPercent,
|
RushFee = quote.RushFee,
|
||||||
SubtotalAfterDiscount = quote.SubTotal - quote.DiscountAmount,
|
TaxPercent = quote.TaxPercent,
|
||||||
RushFee = quote.RushFee,
|
TaxAmount = quote.TaxAmount,
|
||||||
TaxPercent = quote.TaxPercent,
|
Total = quote.Total
|
||||||
TaxAmount = quote.TaxAmount,
|
};
|
||||||
Total = quote.Total
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load change history
|
// Load change history
|
||||||
var changeHistories = await _unitOfWork.Quotes.GetChangeHistoryAsync(id.Value);
|
var changeHistories = await _unitOfWork.Quotes.GetChangeHistoryAsync(id.Value);
|
||||||
@@ -544,33 +541,30 @@ public class QuotesController : Controller
|
|||||||
var currentUser = await _userManager.GetUserAsync(User);
|
var currentUser = await _userManager.GetUserAsync(User);
|
||||||
|
|
||||||
// Populate pricing breakdown from stored snapshot values — never recalculate on load
|
// Populate pricing breakdown from stored snapshot values — never recalculate on load
|
||||||
if (quote.Total > 0)
|
quoteDto.PricingBreakdown = new QuotePricingBreakdownDto
|
||||||
{
|
{
|
||||||
quoteDto.PricingBreakdown = new QuotePricingBreakdownDto
|
MaterialCosts = quote.MaterialCosts,
|
||||||
{
|
LaborCosts = quote.LaborCosts,
|
||||||
MaterialCosts = quote.MaterialCosts,
|
EquipmentCosts = quote.EquipmentCosts,
|
||||||
LaborCosts = quote.LaborCosts,
|
ItemsSubtotal = quote.ItemsSubtotal,
|
||||||
EquipmentCosts = quote.EquipmentCosts,
|
OvenBatchCost = quote.OvenBatchCost,
|
||||||
ItemsSubtotal = quote.ItemsSubtotal,
|
OvenBatches = quote.OvenBatches,
|
||||||
OvenBatchCost = quote.OvenBatchCost,
|
OvenCycleMinutes = quote.OvenCycleMinutes ?? 0,
|
||||||
OvenBatches = quote.OvenBatches,
|
ShopSuppliesAmount = quote.ShopSuppliesAmount,
|
||||||
OvenCycleMinutes = quote.OvenCycleMinutes ?? 0,
|
ShopSuppliesPercent = quote.ShopSuppliesPercent,
|
||||||
ShopSuppliesAmount = quote.ShopSuppliesAmount,
|
OverheadCosts = quote.OverheadAmount,
|
||||||
ShopSuppliesPercent = quote.ShopSuppliesPercent,
|
OverheadPercent = quote.OverheadPercent,
|
||||||
OverheadCosts = quote.OverheadAmount,
|
ProfitMargin = quote.ProfitMargin,
|
||||||
OverheadPercent = quote.OverheadPercent,
|
ProfitPercent = quote.ProfitPercent,
|
||||||
ProfitMargin = quote.ProfitMargin,
|
SubtotalBeforeDiscount = quote.SubTotal,
|
||||||
ProfitPercent = quote.ProfitPercent,
|
DiscountAmount = quote.DiscountAmount,
|
||||||
SubtotalBeforeDiscount = quote.SubTotal,
|
DiscountPercent = quote.DiscountPercent,
|
||||||
DiscountAmount = quote.DiscountAmount,
|
SubtotalAfterDiscount = quote.SubTotal - quote.DiscountAmount,
|
||||||
DiscountPercent = quote.DiscountPercent,
|
RushFee = quote.RushFee,
|
||||||
SubtotalAfterDiscount = quote.SubTotal - quote.DiscountAmount,
|
TaxPercent = quote.TaxPercent,
|
||||||
RushFee = quote.RushFee,
|
TaxAmount = quote.TaxAmount,
|
||||||
TaxPercent = quote.TaxPercent,
|
Total = quote.Total
|
||||||
TaxAmount = quote.TaxAmount,
|
};
|
||||||
Total = quote.Total
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (currentUser?.CompanyId == null)
|
if (currentUser?.CompanyId == null)
|
||||||
{
|
{
|
||||||
TempData["Error"] = "Company information not found.";
|
TempData["Error"] = "Company information not found.";
|
||||||
|
|||||||
Reference in New Issue
Block a user