PageSourceSearch

https://trixbrix.eu/assets/helpers/uv_print_quote-5a779bfe.js

js trixbrix.eu collected 2026-09-25 14:37:37 UTC 1,885 bytes, 35 lines download raw bytes

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.