Commit a970a2ac by tdgiang

Cap product combo qty by real stock instead of a fixed 3 per line

Live E2E testing against the real Sổ Bán Lẻ catalog (64 usable
products, avg price ~24k) showed the fixed maxQtyPerLine=3 capped the
achievable order total at ~4.86M regardless of retry count - a
structural ceiling, not bad luck. 7/10 test amounts above ~4.2M failed
with NO_PRODUCT_COMBO_MATCH every time.

Default per-line qty is now bounded only by the product's actual stock
(previously min(3, qty), now just qty), raising the real ceiling to
~2B on the current catalog. maxQtyPerLine is still available as an
explicit override for callers that want a cap.

Verified against the real catalog: all 7 previously-failing amounts
(4.2M-19.5M) now succeed, real order totals landing within the
50,000 tolerance band every time.
Co-Authored-By: 's avatarClaude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017KPzWwuTEeX2vXGXvyGn4q
parent f19658e1
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
var DEFAULT_TOLERANCE = 50000; var DEFAULT_TOLERANCE = 50000;
var DEFAULT_MAX_ATTEMPTS = 20; var DEFAULT_MAX_ATTEMPTS = 20;
var DEFAULT_MAX_QTY_PER_LINE = 3;
function shuffle(list, random) { function shuffle(list, random) {
var arr = list.slice(); var arr = list.slice();
...@@ -28,7 +27,7 @@ function pickProductCombo(products, targetAmount, options) { ...@@ -28,7 +27,7 @@ function pickProductCombo(products, targetAmount, options) {
var tolerance = typeof options.tolerance === "number" ? options.tolerance : DEFAULT_TOLERANCE; var tolerance = typeof options.tolerance === "number" ? options.tolerance : DEFAULT_TOLERANCE;
var maxAttempts = options.maxAttempts || DEFAULT_MAX_ATTEMPTS; var maxAttempts = options.maxAttempts || DEFAULT_MAX_ATTEMPTS;
var random = options.random || Math.random; var random = options.random || Math.random;
var maxQtyPerLine = options.maxQtyPerLine || DEFAULT_MAX_QTY_PER_LINE; var maxQtyPerLine = typeof options.maxQtyPerLine === "number" ? options.maxQtyPerLine : null;
var candidates = products.filter(function (p) { var candidates = products.filter(function (p) {
return p.qty > 0 && p.price > 0; return p.qty > 0 && p.price > 0;
...@@ -46,7 +45,7 @@ function pickProductCombo(products, targetAmount, options) { ...@@ -46,7 +45,7 @@ function pickProductCombo(products, targetAmount, options) {
for (var i = 0; i < shuffled.length; i++) { for (var i = 0; i < shuffled.length; i++) {
var product = shuffled[i]; var product = shuffled[i];
var maxQty = Math.min(maxQtyPerLine, product.qty); var maxQty = maxQtyPerLine === null ? product.qty : Math.min(maxQtyPerLine, product.qty);
var qty = 1 + Math.floor(random() * maxQty); var qty = 1 + Math.floor(random() * maxQty);
var lineTotal = computeLineTotal(product, qty); var lineTotal = computeLineTotal(product, qty);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment