This commit is contained in:
2026-08-17 17:49:03 +08:00
parent c71db4b481
commit 7c66097672
21 changed files with 1227 additions and 14 deletions
@@ -2,7 +2,7 @@ import assert from 'node:assert/strict'
import { readFileSync } from 'node:fs'
import test from 'node:test'
import { PRODUCT_CATALOG, buildOrderPayload, diversifyRoutes, parseArguments, randomOrderOptions, validateCount } from './create-pending-review-orders.mjs'
import { PRODUCT_CATALOG, buildOrderPayload, diversifyRoutes, parseArguments, randomOrderOptions, selectSameChannelRoutes, validateCount } from './create-pending-review-orders.mjs'
const source = readFileSync(new URL('./create-pending-review-orders.mjs', import.meta.url), 'utf8')
@@ -101,3 +101,21 @@ test('interleaves different logistics combinations before repeating one', () =>
const secondKey = `${diversified[1].channel.channelCode}|${diversified[1].pricingTaxMode}`
assert.notEqual(firstKey, secondKey)
})
test('selects routes from exactly one logistics channel', () => {
const route = (receivingId, channelCode, pricingTaxMode, destinationCode) => ({
receiving: { id: receivingId }, channel: { channelCode }, pricingTaxMode,
destination: { warehouseCode: destinationCode },
})
const selected = selectSameChannelRoutes([
route('1', 'SEA-A', 'TAX_INCLUDED', 'A1'),
route('1', 'SEA-A', 'TAX_INCLUDED', 'A2'),
route('1', 'SEA-B', 'TAX_EXCLUDED', 'B1'),
])
assert.equal(selected.length, 2)
assert.equal(new Set(selected.map((item) => `${item.receiving.id}|${item.channel.channelCode}|${item.pricingTaxMode}`)).size, 1)
})
test('parses same-channel as a boolean flag', () => {
assert.deepEqual(parseArguments(['--count', '10', '--same-channel']), { count: '10', 'same-channel': true })
})
+22 -5
View File
@@ -33,18 +33,20 @@ export const PRODUCT_CATALOG = [
const CONFIG = {
GATEWAY: 'http://8.163.30.128:9000',
USERNAME: '17512095155',
PASSWORD: 'd6KW2ZC4vv44WJ4a',
PASSWORD: 'M4mmp4YWcH5DiYPT',
COUNT: 50,
}
export function parseArguments(values) {
const options = {}
const booleanOptions = new Set(['help', 'same-channel'])
for (let index = 0; index < values.length; index += 1) {
const value = values[index]
if (!value.startsWith('--')) throw new Error(`Unknown argument: ${value}`)
const [rawKey, inlineValue] = value.slice(2).split('=', 2)
if (rawKey === 'help') {
options.help = true
if (booleanOptions.has(rawKey)) {
if (inlineValue !== undefined) throw new Error(`--${rawKey} does not accept a value`)
options[rawKey] = true
continue
}
const next = inlineValue ?? values[index + 1]
@@ -123,6 +125,19 @@ export function diversifyRoutes(routes) {
return result
}
export function selectSameChannelRoutes(routes) {
const grouped = new Map()
for (const route of routes) {
const key = logisticsKey(route)
if (!grouped.has(key)) grouped.set(key, [])
grouped.get(key).push(route)
}
const candidates = [...grouped.values()]
if (candidates.length === 0) throw new Error('No priced route is available for same-channel orders')
const maxDestinationCount = Math.max(...candidates.map((group) => group.length))
return shuffled(pickRandom(candidates.filter((group) => group.length === maxDestinationCount)))
}
export function randomOrderOptions() {
return {
tradeTerm: pickRandom(TRADE_TERMS),
@@ -324,7 +339,7 @@ export function buildOrderPayload({ marker, index, profile, master, product, pac
function printHelp() {
console.log(`Usage:
node scripts/create-pending-review-orders.mjs --gateway <url> --count <1-${MAX_COUNT}>
node scripts/create-pending-review-orders.mjs --gateway <url> --count <1-${MAX_COUNT}> [--same-channel]
Environment:
CLIENT_TEST_GATEWAY Test environment Gateway URL
@@ -374,7 +389,8 @@ export async function main(argv = process.argv.slice(2)) {
const routePool = await loadPricedRoutes(gateway, timeoutMs, token)
const productImageFileId = await uploadProductImage(gateway, timeoutMs, token, marker)
const randomizedProducts = shuffled(PRODUCT_CATALOG)
const randomizedRoutes = diversifyRoutes(routePool)
const sameChannel = args['same-channel'] === true
const randomizedRoutes = sameChannel ? selectSameChannelRoutes(routePool) : diversifyRoutes(routePool)
for (let index = 1; index <= count; index += 1) {
const master = randomizedRoutes[(index - 1) % randomizedRoutes.length]
@@ -446,6 +462,7 @@ export async function main(argv = process.argv.slice(2)) {
tenantId: String(profile.id),
requestedCount: count,
createdCount: orders.length,
sameChannel,
startedAt,
completedAt: new Date().toISOString(),
productImageFileId: String(productImageFileId),