feat: add shared child batch creation

This commit is contained in:
inman committed 2026-09-09 17:24:16 +08:00
1 parent 515b545b32
commit 6ac90f838a
32 files changed
+958 -90

No files matched your search

+65
View File
@@ -214,6 +214,71 @@ test('shared-child leader lookup survives the strict execution gate', () => {
assert.deepEqual(validateStandardOperation(operation), []);
});
test('shared-child batch dispatch is Program-only, resolves all parents, and enters the guarded batch adapter', () => {
const parsed = {
action: 'shared_child_order_batch_create',
order_nature: 'formal',
submit_mode: 'dry_run',
data: {
customer: { name: '合成客户', keyword: '合成客户' },
product: { name: '老挝行程--广东', keyword: '老挝行程--广东' },
leader: { name: '张三', keyword: '张三' },
recurrence: { start_date: '2026-10-06', end_date: '2026-11-03' },
passenger_counts: { adult: 20, leader: 1 }
}
};
const dispatch = plans.validateDispatchOperation(parsed);
assert.equal(dispatch.ok, true, dispatch.blockers.join('; '));
assert.equal(dispatch.execution, 'browser_live_split_child_batch');
assert.equal(dispatch.requiresErpResolution, true);
assert.equal(plans.validateOperation(parsed).ok, false, 'execution gate requires ERP-resolved batch targets');
const resolved = {
...parsed,
data: {
...parsed.data,
batch_targets: [
{ parent_group_no: 'LW-261006-A', tid: '61006', departure_date: '2026-10-06' },
{ parent_group_no: 'LW-261103-A', tid: '61103', departure_date: '2026-11-03' }
],
resolution: {
stage: 'erp_readonly', target: 'batch', candidate_count: 2,
target_kind: 'shared_plan', write_attempted: false
}
}
};
const execution = plans.validateOperation(resolved);
assert.equal(execution.ok, true, execution.blockers.join('; '));
assert.equal(execution.execution, 'browser_live_split_child_batch');
assert.equal(execution.noErpWrite, false);
assert.deepEqual(validateStandardOperation(resolved), []);
});
test('shared-child batch execution rejects duplicate or out-of-range resolved parents', () => {
const operation = {
action: 'shared_child_order_batch_create',
order_nature: 'formal',
submit_mode: 'dry_run',
data: {
customer: { name: '合成客户' },
product: { name: '合成产品' },
recurrence: { start_date: '2026-10-06', end_date: '2026-11-03' },
passenger_counts: { adult: 20, leader: 1 },
batch_targets: [
{ parent_group_no: 'LW-261006-A', tid: '61006', departure_date: '2026-10-06' },
{ parent_group_no: 'LW-261006-A', tid: '61006', departure_date: '2026-11-04' }
],
resolution: {
stage: 'erp_readonly', target: 'batch', candidate_count: 2,
target_kind: 'shared_plan', write_attempted: false
}
}
};
const result = plans.validateOperation(operation);
assert.equal(result.ok, false);
assert.match(result.blockers.join('\n'), /重复母团目标|不在请求日期范围/);
});
test('blocks a marked split-child parent when the child remark loses the test marker', () => {
const result = plans.validateOperation({
action: 'shared_child_order_create',