package spread import ( "strings" "unicode" ) // catalog holds the parts we can source at a fixed unit price, keyed by // normalized part number. In the demo these are hardcoded; in production // this map would be backed by live supplier quotes. // // The five parts below match the canonical example on the landing page, so // the shipped example-bom.csv reproduces the exact $883.50 savings figure. var catalog = map[string]float64{ "GRM188R71H104KA93D": 0.0142, "DIN 912": 0.0335, "UL1007": 0.9450, "STM32F103C8T6": 2.9200, "RC0805FR-0710KL": 0.0086, } // categoryDiscount maps a keyword found in a part's description to the // fraction we can typically shave off market price for that category. // Ordering matters: the first keyword that matches wins. var categoryDiscount = []struct { keyword string discount float64 }{ {"capacitor", 0.21}, {"resistor", 0.28}, {"inductor", 0.22}, {"diode", 0.24}, {"transistor", 0.24}, {"mcu", 0.24}, {"microcontroller", 0.24}, {"ic", 0.23}, {"regulator", 0.23}, {"connector", 0.19}, {"header", 0.19}, {"led", 0.26}, {"crystal", 0.20}, {"oscillator", 0.20}, {"screw", 0.25}, {"bolt", 0.25}, {"nut", 0.25}, {"washer", 0.27}, {"fastener", 0.25}, {"standoff", 0.24}, {"wire", 0.21}, {"cable", 0.21}, {"pcb", 0.16}, {"enclosure", 0.15}, {"heatsink", 0.18}, } // defaultDiscount applies when no category keyword matches. const defaultDiscount = 0.15 // NormalizePN canonicalizes a part number for catalog lookups: uppercased, // trimmed, internal whitespace collapsed. The app stores and looks up catalog // keys with the same function so matching is consistent. func NormalizePN(pn string) string { pn = strings.ToUpper(strings.TrimSpace(pn)) return strings.Join(strings.Fields(pn), " ") } // Catalog is an exact-match supplier price source. Parts it doesn't know fall // back to the category model inside the analyzer. type Catalog interface { Lookup(partNumber string) (spreadPrice float64, ok bool) } // BuiltinCatalog is the demo's hardcoded catalog, used by the public endpoint. type BuiltinCatalog struct{} func (BuiltinCatalog) Lookup(partNumber string) (float64, bool) { p, ok := catalog[NormalizePN(partNumber)] return p, ok } // tokenize lowercases and splits text into whole words so short keywords // like "ic" match only as words, not as substrings of "generic". func tokenize(s string) map[string]bool { set := map[string]bool{} for _, f := range strings.FieldsFunc(strings.ToLower(s), func(r rune) bool { return !unicode.IsLetter(r) && !unicode.IsDigit(r) }) { set[f] = true } return set } // modelDiscount estimates a discount for a part we don't stock by name, // based on its category plus a small volume bonus for large quantities. func modelDiscount(li LineItem) float64 { words := tokenize(li.Description + " " + li.PartNumber) d := defaultDiscount for _, c := range categoryDiscount { if words[c.keyword] { d = c.discount break } } // Volume bonus: up to +4 points for high-quantity lines. switch { case li.Quantity >= 10000: d += 0.04 case li.Quantity >= 1000: d += 0.02 case li.Quantity >= 100: d += 0.01 } if d > 0.45 { d = 0.45 } return d }