d8622b3187
QuoteItem was missing IncludePrepCost, so the Edit GET always deserialized it as true (DTO default). On save, prep service labor was added on top of the catalog base price, silently bumping prices whenever any quote field (e.g. oven cycle minutes) was changed without touching items. Migration defaults new column to false for catalog items and true for non-catalog items (matching the wizard's historical defaults). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
65 lines
2.7 KiB
C#
65 lines
2.7 KiB
C#
namespace PowderCoating.Core.Entities;
|
|
|
|
public class QuoteItem : BaseEntity
|
|
{
|
|
public int QuoteId { get; set; }
|
|
public string Description { get; set; } = string.Empty;
|
|
public decimal Quantity { get; set; }
|
|
|
|
// Measurements (optional for quoting)
|
|
public decimal? SurfaceArea { get; set; }
|
|
public decimal SurfaceAreaSqFt { get; set; } // Surface area in square feet for pricing
|
|
|
|
// Catalog item reference (optional)
|
|
public int? CatalogItemId { get; set; } // Link to catalog item (optional)
|
|
|
|
// Pricing
|
|
public decimal UnitPrice { get; set; }
|
|
public decimal TotalPrice { get; set; }
|
|
|
|
// Cost breakdown snapshot (set at save time for breakdown display)
|
|
public decimal ItemMaterialCost { get; set; }
|
|
public decimal ItemLaborCost { get; set; }
|
|
public decimal ItemEquipmentCost { get; set; }
|
|
public bool IsGenericItem { get; set; }
|
|
public decimal? ManualUnitPrice { get; set; }
|
|
public decimal? PowderCostOverride { get; set; } // Optional unit price override for catalog items
|
|
public bool IsLaborItem { get; set; }
|
|
public bool IsSalesItem { get; set; }
|
|
public string? Sku { get; set; }
|
|
|
|
// Processing estimates
|
|
public bool RequiresSandblasting { get; set; }
|
|
public bool RequiresMasking { get; set; }
|
|
public int EstimatedMinutes { get; set; }
|
|
|
|
// Whether to add prep service labor cost on top of this item's base price.
|
|
// Defaults to false for catalog items (catalog price assumed to include standard labor);
|
|
// true for calculated items where prep is a separate billable add-on.
|
|
public bool IncludePrepCost { get; set; }
|
|
|
|
public string? Notes { get; set; }
|
|
|
|
// Part complexity level — applies a price multiplier for calculated items
|
|
// Values: "Simple" | "Moderate" | "Complex" | "Extreme"
|
|
public string? Complexity { get; set; }
|
|
|
|
// True when this item was generated via AI photo analysis.
|
|
// Must be persisted so that recalculations (Details view, Edit view) can
|
|
// honour ManualUnitPrice instead of running the regular pricing engine.
|
|
public bool IsAiItem { get; set; }
|
|
|
|
// AI-generated standardized tags (comma-separated, e.g. "automotive,tubular")
|
|
public string? AiTags { get; set; }
|
|
|
|
// Link to shared AI prediction record (null for non-AI items)
|
|
public int? AiPredictionId { get; set; }
|
|
public virtual AiItemPrediction? AiPrediction { get; set; }
|
|
|
|
// Relationships
|
|
public virtual Quote Quote { get; set; } = null!;
|
|
public virtual CatalogItem? CatalogItem { get; set; }
|
|
public virtual ICollection<QuoteItemCoat> Coats { get; set; } = new List<QuoteItemCoat>();
|
|
public virtual ICollection<QuoteItemPrepService> PrepServices { get; set; } = new List<QuoteItemPrepService>();
|
|
}
|