package spread // CutRate is the only number in Spread's business model: we keep this // fraction of the savings we find, and nothing else. If savings are zero, // our cut is zero. const CutRate = 0.20 // LineItem is one row of an uploaded bill of materials, after parsing. // UnitPrice is what the customer pays today (their "market" price). type LineItem struct { Line int `json:"line"` PartNumber string `json:"part_number"` Description string `json:"description"` Manufacturer string `json:"manufacturer,omitempty"` Quantity float64 `json:"quantity"` UnitPrice float64 `json:"unit_price"` } // AnalyzedLine is a LineItem re-quoted against the supplier catalog. type AnalyzedLine struct { LineItem SpreadPrice float64 `json:"spread_price"` UnitSaving float64 `json:"unit_saving"` LineMarket float64 `json:"line_market"` LineSpread float64 `json:"line_spread"` LineSaving float64 `json:"line_saving"` // Matched is true when the part was found by exact part number in the // catalog; false when the price was estimated from the category model. Matched bool `json:"matched"` } // Totals is the summary block shown under the table. type Totals struct { Lines int `json:"lines"` Market float64 `json:"market"` Spread float64 `json:"spread"` Savings float64 `json:"savings"` OurCut float64 `json:"our_cut"` NetSavings float64 `json:"net_savings"` CutRate float64 `json:"cut_rate"` } // Report is the full analysis returned to the client. type Report struct { BOMRef string `json:"bom_ref"` Lines []AnalyzedLine `json:"lines"` Totals Totals `json:"totals"` }