1// Client-side mirror of UVPrintPricing#quote (Ruby, BigDecimal). 2// 3// All arithmetic is done on integers â mills (1/1000 EUR) for unit prices, 4// basis points for the discount, cents for the multiplier â so 5// the half-up rounding matches the server exactly. Plain floats would show 6// e.g. 37 à 0.145 = 5.365 as 5.36499⦠and round a cent too low, making the 7// editor price differ from the cart. `test/models/uv_print_pricing_parity_test.rb` 8// runs this file under node against thousands of Ruby quotes. 9// 10// pricing: UVPrintPricing#client_config; items: [{ shape, studs }] 11// Returns the design's total in EUR. The setup fee is not part of it: the 12// cart charges it once per order (Cart::UVPrintSetupFeeable). 13export function quoteUVPrint(pricing, items, varnish) { 14 const plates = items.length 15 if (plates === 0) return 0 16 17 const studs = items.reduce((sum, item) => sum + item.studs, 0) 18 const tier = [...(pricing.discount_tiers || [])].reverse().find(t => studs >= t.min_studs) 19 const factorBp = 10000 - toBasisPoints(tier ? tier.percent : 0) 20 21 const blanks = divRound(items.reduce((sum, item) => sum + toMills(pricing.blanks[item.shape] || 0), 0), 10) 22 const handling = divRound(plates * toMills(pricing.handling_per_plate), 10) 23 const print = divRound(studs * toMills(pricing.print_per_stud) * factorBp, 100000) 24 const varnishPrice = varnish ? divRound(studs * toMills(pricing.varnish_per_stud) * factorBp, 100000) : 0 25 const floor = divRound(blanks * toCents(pricing.min_cost_multiplier), 100) 26 27 return Math.max(blanks + handling + print + varnishPrice, floor) / 100 28} 29 30const toMills = amount => Math.round(amount * 1000) 31const toCents = amount => Math.round(amount * 100) 32const toBasisPoints = percent => Math.round(percent * 100) 33 34// Half-up integer division for non-negative operands (d is even). 35const divRound = (n, d) => Math.floor((n + d / 2) / d)
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.