305 lines
20 KiB
JavaScript
305 lines
20 KiB
JavaScript
import assert from 'node:assert/strict'
|
|
import test from 'node:test'
|
|
import { readInitialization, tableDefinitions, table, seedRows, roleAuthorities } from '../sql-baseline-contract-helpers.mjs'
|
|
|
|
const cn = readInitialization()
|
|
const overseas = readInitialization('OVERSEAS')
|
|
const domesticSchemas = ['baiyue_auth', 'baiyue_iam', 'baiyue_order', 'baiyue_warehouse',
|
|
'baiyue_firstleg', 'baiyue_file', 'baiyue_audit', 'baiyue_finance']
|
|
const overseasSchemas = ['baiyue_lastleg', 'baiyue_lastlag_warehouse']
|
|
|
|
test('种子解析覆盖多行多值、函数括号及带逗号和引号的文本', () => {
|
|
const sql = "INSERT INTO sample (id,label,stamp,note) VALUES\r\n (1,'甲,乙',CURRENT_TIMESTAMP(3),NULL),\r\n (2,'客户''名称',CURRENT_TIMESTAMP(3),'已确认');\r\n"
|
|
assert.deepEqual(seedRows(sql, 'sample'), [
|
|
{ id: '1', label: '甲,乙', stamp: 'CURRENT_TIMESTAMP(3)', note: null },
|
|
{ id: '2', label: "客户'名称", stamp: 'CURRENT_TIMESTAMP(3)', note: '已确认' },
|
|
])
|
|
})
|
|
|
|
test('两个入口分别只操作八个主业务库与两个仓储业务库,包括限定名引用', () => {
|
|
for (const [sql, allowed, other, count] of [[cn, domesticSchemas, overseasSchemas, 227], [overseas, overseasSchemas, domesticSchemas, 228]]) {
|
|
assert.deepEqual([...sql.matchAll(/^CREATE DATABASE IF NOT EXISTS (\w+)/gm)].map(m => m[1]), allowed)
|
|
assert.deepEqual([...new Set([...sql.matchAll(/^USE (\w+);/gm)].map(m => m[1]))], allowed)
|
|
const body = sql.replace(/^--.*$/gm, '')
|
|
for (const schema of other) assert.doesNotMatch(body, new RegExp('\\b' + schema + '\\b'))
|
|
assert.equal(tableDefinitions(sql).size, count)
|
|
for (const key of tableDefinitions(sql).keys()) assert.ok(allowed.includes(key.split('.')[0]))
|
|
}
|
|
})
|
|
|
|
test('转运收货命令锁定原来源和原请求,多来源可共享目标资源锁', () => {
|
|
const command = table(overseas, 'baiyue_lastleg', 'll_warehouse_transfer_receipt_command')
|
|
assert.match(command, /UNIQUE KEY uk_ll_wh_receipt_cmd_source\s*\(transfer_order_id,\s*source_inventory_position_id\)/i)
|
|
assert.match(command, /UNIQUE KEY uk_ll_wh_receipt_cmd_key\s*\(customer_id,\s*idempotency_key\)/i)
|
|
assert.match(command, /request_json JSON NOT NULL/i)
|
|
assert.match(command, /target_json JSON NOT NULL/i)
|
|
assert.match(command, /resource_lock_id BIGINT NULL/i)
|
|
assert.match(command, /CHECK\s*\(status IN \('PREPARED','RESERVED','COMPLETED'\)\)/i)
|
|
assert.doesNotMatch(command, /UNIQUE[^\n]*resource_lock_id/i)
|
|
})
|
|
|
|
test('纯初始化禁止迁移、数据回填、清理、重复建表和提前成功', () => {
|
|
for (const sql of [cn, overseas]) {
|
|
const body = sql.replace(/^--.*$/gm, '')
|
|
assert.doesNotMatch(body, /\bALTER\s+TABLE|\bDROP\s+(?:DATABASE|TABLE)|\bTRUNCATE\b|\bRENAME\s+TABLE/i)
|
|
assert.doesNotMatch(body, /\bCREATE\s+(?:TEMPORARY\s+TABLE|PROCEDURE)|\bPREPARE\b|\bEXECUTE\b|\bON DUPLICATE KEY UPDATE|\bINSERT IGNORE/i)
|
|
// Runtime trigger bodies legitimately update the current loading aggregate.
|
|
assert.doesNotMatch(body.replace(/^CREATE TRIGGER [\s\S]*?\$\$/gm, ''), /^\s*(?:UPDATE|DELETE FROM|REPLACE INTO)\b/gmi)
|
|
assert.doesNotMatch(body, /CREATE TABLE IF NOT EXISTS/i)
|
|
assert.equal((body.match(/AS initialization_status/g) ?? []).length, 1)
|
|
const end = body.trim().match(/SELECT 'PASS' AS initialization_status, '(CN|OVERSEAS)' AS region, (\d+) AS initialized_tables;$/)
|
|
assert.ok(end, 'only the final statement may announce successful initialization')
|
|
assert.equal(Number(end[2]), tableDefinitions(sql).size)
|
|
assert.equal(end[1], sql === cn ? 'CN' : 'OVERSEAS')
|
|
}
|
|
})
|
|
|
|
test('车次直接成本按车次幂等并保留独立币种与不可变更正历史', () => {
|
|
const cost = table(overseas, 'baiyue_lastleg', 'll_fleet_trip_cost')
|
|
const history = table(overseas, 'baiyue_lastleg', 'll_fleet_trip_cost_history')
|
|
assert.match(cost, /UNIQUE KEY uk_fleet_trip_cost_request\(trip_id,created_by,request_key\)/i)
|
|
assert.match(cost, /FOREIGN KEY\(trip_id\) REFERENCES ll_fleet_trip\(id\)/i)
|
|
assert.match(cost, /CHECK\(amount>=0\)/i)
|
|
assert.match(cost, /CHECK\(currency IN \('CNY','USD'\)\)/i)
|
|
assert.match(history, /UNIQUE KEY uk_fleet_trip_cost_history\(cost_id,record_version\)/i)
|
|
assert.match(history, /FOREIGN KEY\(cost_id\) REFERENCES ll_fleet_trip_cost\(id\)/i)
|
|
assert.match(history, /snapshot_json JSON NOT NULL/i)
|
|
})
|
|
|
|
test('退回实收按真实流水唯一保存,重派拣货必须明确唯一来源', () => {
|
|
const receipt = table(overseas, 'baiyue_lastleg', 'll_return_stock_receipt')
|
|
assert.match(receipt, /UNIQUE KEY uk_return_stock_receipt_ledger\(customer_id,inventory_ledger_id\)/i)
|
|
assert.match(receipt, /UNIQUE KEY uk_return_stock_receipt_no\(customer_id,receipt_no\)/i)
|
|
assert.match(receipt, /CHECK\(received_packages>0\)/i)
|
|
for (const name of ['ll_dispatch_item', 'll_dispatch_pallet_lock', 'll_dispatch_pda_pick_order']) {
|
|
assert.match(table(overseas, 'baiyue_lastleg', name), /return_receipt_id BIGINT NULL/i)
|
|
}
|
|
const pick = table(overseas, 'baiyue_lastleg', 'll_dispatch_pda_pick_order')
|
|
assert.match(pick, /\breceipt_id BIGINT NULL/i)
|
|
assert.match(pick, /\bdispatch_item_source_id BIGINT NULL/i)
|
|
assert.match(pick, /CHECK\(\(receipt_id IS NOT NULL\) \+ \(return_receipt_id IS NOT NULL\) \+ \(return_carton_id IS NOT NULL\) \+ \(dispatch_item_source_id IS NOT NULL\) = 1\)/i)
|
|
})
|
|
|
|
test('同实托初始化分离无代表客户的物理占用与逐来源占用', () => {
|
|
const physical = table(overseas, 'baiyue_lastleg', 'll_dispatch_physical_pallet_lock')
|
|
assert.doesNotMatch(physical, /\bcustomer_id\b/i)
|
|
assert.match(physical, /UNIQUE KEY[^\n]*\(active_warehouse_pallet_id\)/i)
|
|
assert.match(physical, /CHECK\(\(status='ACTIVE' AND active_warehouse_pallet_id IS NOT NULL AND active_warehouse_pallet_id=warehouse_pallet_id\)/i)
|
|
assert.match(physical, /dispatch_order_id IS NOT NULL AND draft_token IS NULL AND draft_container_id IS NULL/i)
|
|
assert.match(physical, /dispatch_order_id IS NULL AND draft_token IS NOT NULL AND draft_container_id IS NOT NULL/i)
|
|
const logical = table(overseas, 'baiyue_lastleg', 'll_dispatch_pallet_lock')
|
|
assert.match(logical, /physical_lock_id BIGINT NULL/i)
|
|
assert.match(logical, /UNIQUE KEY[^\n]*\(customer_id,active_key\)/i)
|
|
assert.doesNotMatch(logical, /active_warehouse_pallet_id/i)
|
|
assert.match(table(overseas, 'baiyue_lastleg', 'll_dispatch_item'), /UNIQUE KEY[^\n]*\(dispatch_order_id,source_key\)/i)
|
|
const source = table(overseas, 'baiyue_lastleg', 'll_dispatch_item_source')
|
|
assert.match(source, /UNIQUE KEY[^\n]*\(dispatch_item_id,relabel_item_id,inventory_position_id\)/i)
|
|
assert.match(source, /product_quantity BIGINT NULL/i)
|
|
assert.match(source, /source_inbound_order_id BIGINT NULL/i)
|
|
assert.match(source, /relabel_round_key VARCHAR\(128\) NOT NULL/i)
|
|
assert.match(source, /unit_facts_json JSON NOT NULL/i)
|
|
})
|
|
|
|
test('实托组成串行点只保存真实主键和首次创建时间', () => {
|
|
const guard = table(overseas, 'baiyue_lastleg', 'll_physical_pallet_guard')
|
|
assert.match(guard, /warehouse_pallet_id BIGINT NOT NULL/i)
|
|
assert.match(guard, /created_at DATETIME\(3\) NOT NULL DEFAULT CURRENT_TIMESTAMP\(3\)/i)
|
|
assert.match(guard, /PRIMARY KEY\s*\(warehouse_pallet_id\)/i)
|
|
assert.doesNotMatch(guard, /\b(?:customer_id|status|expires_at|dispatch_order_id|draft_token|draft_container_id)\b/i)
|
|
})
|
|
|
|
test('同实托六表定义在模块和统一空库入口保持一致', () => {
|
|
const module = 'USE baiyue_lastleg;\n' + readFileSync(new URL('../../lastleg-service/src/main/resources/db/lastleg.sql', import.meta.url), 'utf8')
|
|
.replace(/^[ \t]*CREATE TABLE IF NOT EXISTS /gm, 'CREATE TABLE ')
|
|
.replace(/^[ \t]+\) ENGINE=/gm, ') ENGINE=')
|
|
const body = value => value.slice(value.indexOf('('), value.lastIndexOf(') ENGINE='))
|
|
.replace(/\r\n/g, '\n').replace(/[ \t]+/g, ' ').trim()
|
|
for (const name of ['ll_dispatch_item', 'll_dispatch_item_source', 'll_physical_pallet_guard', 'll_dispatch_physical_pallet_lock', 'll_dispatch_pallet_lock', 'll_dispatch_pda_pick_order']) {
|
|
assert.equal(body(table(overseas, 'baiyue_lastleg', name)), body(table(module, 'baiyue_lastleg', name)), name)
|
|
}
|
|
})
|
|
|
|
test('车辆报价与实测记录保留业务去重和不可变版本', () => {
|
|
const booking = table(overseas, 'baiyue_lastleg', 'll_fleet_external_booking')
|
|
assert.match(booking, /quote_source_json JSON NULL/i)
|
|
assert.match(booking, /agreed_amount DECIMAL\(16,2\) NULL/i)
|
|
const quote = table(overseas, 'baiyue_lastleg', 'll_fleet_quote')
|
|
assert.match(quote, /UNIQUE KEY uk_fleet_quote_no \(quote_no\)/i)
|
|
assert.match(quote, /UNIQUE KEY uk_fleet_quote_natural \(natural_key\)/i)
|
|
assert.match(quote, /UNIQUE KEY uk_fleet_quote_create \(created_by,create_key\)/i)
|
|
assert.match(table(overseas, 'baiyue_lastleg', 'll_fleet_quote_history'), /UNIQUE KEY uk_fleet_quote_history_version \(quote_id,record_version\)/i)
|
|
const measured = table(overseas, 'baiyue_lastleg', 'll_fleet_trip_operations_record')
|
|
assert.match(measured, /UNIQUE KEY uk_fleet_operations_version \(trip_no,record_version\)/i)
|
|
assert.match(measured, /UNIQUE KEY uk_fleet_operations_request \(trip_no,operator_id,request_key\)/i)
|
|
})
|
|
|
|
test('公司车辆费用隔离于客户账务并约束实际付款金额', () => {
|
|
const cost = table(cn, 'baiyue_finance', 'fin_vehicle_cost')
|
|
assert.doesNotMatch(cost, /\b(customer_id|tenant_id)\b/i)
|
|
assert.match(cost, /subject_id BIGINT UNSIGNED NOT NULL/i)
|
|
assert.match(cost, /UNIQUE KEY uk_fin_vehicle_cost_source \(subject_id,source_type,source_no\)/i)
|
|
assert.match(cost, /CHECK \(amount>0 AND paid_amount>=0 AND paid_amount<=amount\)/i)
|
|
assert.match(table(cn, 'baiyue_finance', 'fin_vehicle_cost_payment'), /FOREIGN KEY \(cost_id\) REFERENCES fin_vehicle_cost\(id\)/i)
|
|
assert.match(table(cn, 'baiyue_finance', 'fin_vehicle_cost_revision'), /UNIQUE KEY uk_fin_vehicle_cost_request \(operator_id,action,request_key\)/i)
|
|
const admin = roleAuthorities(cn, 'PLATFORM_ADMIN'), merchant = roleAuthorities(cn, 'MERCHANT_OWNER')
|
|
for (const action of ['list', 'approve', 'void', 'pay', 'upload']) {
|
|
assert.ok(admin.has(`platform:finance:vehicle-cost:${action}`))
|
|
assert.ok(!merchant.has(`platform:finance:vehicle-cost:${action}`))
|
|
}
|
|
})
|
|
|
|
test('退货出库不可变流水限制重复扣减并保存数量守恒快照', () => {
|
|
const journal = table(overseas, 'baiyue_lastleg', 'll_return_inventory_outbound_movement')
|
|
assert.match(journal, /UNIQUE KEY uk_ll_return_outbound_pick_sku\(outbound_pick_id,sku_code\)/i)
|
|
assert.match(journal, /KEY idx_ll_return_outbound_carton_sku\(customer_id,carton_id,sku_code\)/i)
|
|
assert.doesNotMatch(journal, /UNIQUE KEY uk_ll_return_outbound_carton_sku/i)
|
|
assert.match(journal, /CHECK\(quantity>0 AND total_after>=0 AND available_after>=0/i)
|
|
assert.match(journal, /total_before-total_after=quantity AND available_before-available_after=quantity/i)
|
|
assert.match(journal, /cartons_before-cartons_after IN \(0,1\) AND total_after>=available_after/i)
|
|
})
|
|
|
|
test('平台管理员由外部bcrypt引导,强制首登改密且不创建客户', () => {
|
|
const accounts = seedRows(cn, 'auth_account')
|
|
assert.equal(accounts.length, 1)
|
|
assert.equal(accounts[0].username, 'platform_admin')
|
|
assert.equal(accounts[0].password_change_required, '1')
|
|
assert.match(accounts[0].password_hash, /@platform_admin_password_hash/)
|
|
assert.match(accounts[0].password_hash, /REGEXP/)
|
|
assert.match(accounts[0].password_hash, /, NULL\)$/)
|
|
assert.doesNotMatch(cn, /'\$2[aby]\$[0-9]{2}\$[./A-Za-z0-9]{53}'/)
|
|
assert.deepEqual(seedRows(cn, 'iam_tenant').map(r => r.id), ['0'])
|
|
assert.deepEqual(seedRows(cn, 'iam_user').map(r => r.auth_user_id), ['1000001'])
|
|
assert.doesNotMatch(cn, /'merchant_admin'|'IT_TEST'|'EXP-TEST'|'CAR-001'|'TP-001'|'YW-TP-002'/)
|
|
})
|
|
|
|
test('必要系统种子完整保留,但不写入示例资源与业务事实', () => {
|
|
for (const [name, count] of Object.entries({ iam_role: 8, iam_permission: 433, iam_role_permission: 614,
|
|
iam_data_scope: 7, wh_warehouse: 318, wh_warehouse_address: 318, wh_service_capability: 4,
|
|
fl_fee_item: 112, fl_price_channel_catalog: 15, fl_price_origin_alias: 7, fl_price_warehouse_mapping: 4,
|
|
file_export_task_guard: 1, fin_subject: 1 })) assert.equal(seedRows(cn, name).length, count, name)
|
|
for (const name of ['wh_pallet', 'wh_location', 'wh_partner', 'wh_partner_type', 'wh_express_company',
|
|
'ord_order', 'fl_inbound_order', 'fin_fee_source']) assert.equal(seedRows(cn, name).length, 0, name)
|
|
assert.deepEqual([...new Set([...overseas.matchAll(/^INSERT INTO (\w+)/gm)].map(m => m[1]))], ['ll_appointment_work_guard'])
|
|
assert.deepEqual(seedRows(overseas, 'll_appointment_work_guard'), [{ id: '1', initialized: 'FALSE' }])
|
|
assert.ok(seedRows(cn, 'wh_warehouse').every(r => r.tenant_id === '0'))
|
|
assert.ok(seedRows(cn, 'wh_service_capability').every(r => r.service_type === 'RECEIVING' || r.capability_code === 'RECEIVING' || Object.values(r).includes('RECEIVING')))
|
|
})
|
|
|
|
test('国内IAM权限与角色授权没有丢失或悬挂,客户模板仍完整', () => {
|
|
const roles = seedRows(cn, 'iam_role'), permissions = seedRows(cn, 'iam_permission')
|
|
const roleIds = new Set(roles.map(r => r.id)), permissionIds = new Set(permissions.map(r => r.id))
|
|
assert.equal(permissionIds.size, permissions.length, 'duplicate permission ID')
|
|
const grants = seedRows(cn, 'iam_role_permission')
|
|
assert.equal(new Set(grants.map(r => `${r.role_id}:${r.permission_id}:${r.tenant_id}`)).size, grants.length,
|
|
'duplicate role permission grant')
|
|
assert.equal(new Set(permissions.map(r => r.permission_code)).size, permissions.length)
|
|
for (const row of seedRows(cn, 'iam_role_permission')) {
|
|
assert.ok(roleIds.has(row.role_id), 'missing role ' + row.role_id)
|
|
assert.ok(permissionIds.has(row.permission_id), 'missing permission ' + row.permission_id)
|
|
}
|
|
for (const row of permissions) if (row.parent_id && row.parent_id !== '0') assert.ok(permissionIds.has(row.parent_id), 'missing parent ' + row.parent_id)
|
|
const merchant = roleAuthorities(cn, 'MERCHANT_OWNER')
|
|
for (const code of ['merchant:enterprise', 'merchant:order:quick-create', 'merchant:finance:statement',
|
|
'merchant:warehouse:delivery:list', 'merchant:warehouse:delivery:create']) assert.ok(merchant.has(code), code)
|
|
const admin = roleAuthorities(cn, 'PLATFORM_ADMIN')
|
|
assert.ok(admin.has('platform:overseas-warehouse:discard:approve'), 'discard review endpoint must be grantable to platform administrator')
|
|
for (const action of ['list', 'create', 'edit', 'status', 'review', 'upload']) {
|
|
assert.ok(admin.has(`platform:overseas-master-data:driver:${action}`))
|
|
}
|
|
for (const action of ['list', 'create', 'edit', 'assign', 'cancel', 'cost-create', 'cost-edit']) {
|
|
assert.ok(admin.has(`platform:fleet:trip:${action}`))
|
|
}
|
|
for (const action of ['list', 'create', 'edit', 'status', 'delete', 'import', 'export']) {
|
|
assert.ok(admin.has(`platform:fleet:quote:${action}`))
|
|
assert.ok(!merchant.has(`platform:fleet:quote:${action}`))
|
|
}
|
|
for (const action of ['list', 'export', 'edit']) {
|
|
assert.ok(admin.has(`platform:fleet:operations:${action}`))
|
|
assert.ok(!merchant.has(`platform:fleet:operations:${action}`))
|
|
}
|
|
assert.ok(!permissions.some(row => row.permission_code === 'platform:order:complete'),
|
|
'订单完成必须由可信履约回写产生,不能恢复人工完成权限')
|
|
for (const code of ['platform:order:declaration:edit', 'platform:firstleg:inbound:hold',
|
|
'platform:overseas-warehouse:last-mile-order:list', 'platform:overseas-business:purchase:list',
|
|
'platform:overseas-master-data:quote:list', 'platform:finance:fee-source:review',
|
|
'platform:mojia-sku-sync:list', 'platform:mojia-sku-sync:edit',
|
|
'platform:mojia-sku-sync:retry']) assert.ok(admin.has(code), code)
|
|
const operator = roleAuthorities(cn, 'ORDER_OPERATOR')
|
|
for (const code of ['platform:mojia-sku-sync:list', 'platform:mojia-sku-sync:edit',
|
|
'platform:mojia-sku-sync:retry']) assert.ok(operator.has(code), code)
|
|
})
|
|
|
|
test('近期头程与海外结构完整进入各自统一初始化入口', () => {
|
|
const membership = table(cn, 'baiyue_iam', 'iam_membership')
|
|
assert.match(membership, /domestic_warehouse_id bigint DEFAULT NULL/i)
|
|
assert.match(membership, /idx_membership_domestic_warehouse \(tenant_id,domestic_warehouse_id,status\)/i)
|
|
|
|
const receipt = table(cn, 'baiyue_firstleg', 'fl_mojia_measurement_receipt')
|
|
for (const field of ['measurement_kind', 'weight_kg', 'sync_status', 'sync_failure_code',
|
|
'sync_failure_reason', 'lingxing_sku_id', 'revision']) assert.match(receipt, new RegExp(`\\b${field}\\b`, 'i'))
|
|
assert.match(receipt, /weight_kg decimal\(18,3\) DEFAULT NULL/i)
|
|
|
|
const relabel = table(overseas, 'baiyue_lastleg', 'll_relabel_application')
|
|
assert.match(relabel, /KEY idx_ll_relabel_application_order \(lastleg_order_id\)/i)
|
|
assert.doesNotMatch(relabel, /UNIQUE KEY uk_ll_relabel_application_order/i)
|
|
assert.match(table(overseas, 'baiyue_lastlag_warehouse', 'wh_location'),
|
|
/shared_overflow tinyint\(1\) NOT NULL DEFAULT '?0'?/i)
|
|
})
|
|
|
|
test('统一认证保留持久版本,不再初始化安全投影或桥接发件箱', () => {
|
|
for (const retired of ['iam_security_event_outbox', 'll_security_event_inbox', 'll_security_projection']) {
|
|
assert.doesNotMatch(cn + overseas, new RegExp('CREATE TABLE ' + retired + '\\b'))
|
|
}
|
|
assert.ok(table(cn, 'baiyue_iam', 'iam_security_subject_version'))
|
|
assert.ok(table(cn, 'baiyue_iam', 'iam_security_tenant_version'))
|
|
assert.equal(seedRows(overseas, 'll_security_projection').length, 0)
|
|
})
|
|
|
|
test('跨区域放错位置的最终字段归正确区域且保留财务精度', () => {
|
|
const fee = table(overseas, 'baiyue_lastleg', 'll_finance_fee_source')
|
|
for (const name of ['original_currency', 'original_amount', 'exchange_rate', 'exchange_rate_month',
|
|
'chargeable_quantity', 'quantity_unit', 'unit_price', 'period_start', 'period_end']) assert.match(fee, new RegExp('\\b' + name + '\\b'))
|
|
assert.match(fee, /original_amount decimal\(20,6\)/i)
|
|
assert.match(fee, /exchange_rate decimal\(20,6\)/i)
|
|
const returns = table(overseas, 'baiyue_lastleg', 'll_return_order')
|
|
assert.match(returns, /lastleg_order_id bigint/i)
|
|
assert.match(returns, /lastleg_order_no varchar\(32\)/i)
|
|
assert.match(table(cn, 'baiyue_finance', 'fin_fee_source'), /idx_fin_fee_source_wallet_hold \(wallet_hold_id\)/)
|
|
})
|
|
|
|
test('最终业务触发器与循环外键均存在,不留下发布过程', () => {
|
|
assert.equal((cn.match(/^CREATE TRIGGER /gm) ?? []).length, 64)
|
|
assert.doesNotMatch(cn, /CREATE DEFINER=/)
|
|
for (const name of ['trg_container_booking_before_update', 'trg_loading_pick_task_before_update',
|
|
'trg_order_fulfillment_split_insert', 'trg_inbound_split_item_before_delete']) assert.match(cn, new RegExp('CREATE TRIGGER ' + name + '\\b'))
|
|
assert.match(table(cn, 'baiyue_firstleg', 'fl_inbound_measurement_item'), /REFERENCES fl_inbound_split_item/)
|
|
assert.match(table(cn, 'baiyue_firstleg', 'fl_inbound_split_item'), /REFERENCES fl_inbound_measurement_item/)
|
|
const disable = cn.indexOf('SET SESSION foreign_key_checks = 0;')
|
|
const enable = cn.indexOf('SET SESSION foreign_key_checks = 1;')
|
|
assert.ok(disable >= 0 && enable > disable)
|
|
assert.ok(!cn.slice(disable, enable).includes('INSERT INTO'))
|
|
})
|
|
|
|
|
|
test('退货合箱最终字段直接进入空库建表定义', () => {
|
|
for (const [name, fields] of Object.entries({
|
|
ll_return_packing_plan: ['source_items_json', 'result_marks_json', 'result_labels_json', 'request_hash', 'completion_hash'],
|
|
ll_return_packing_trace: ['source_carton_mark', 'target_carton_mark', 'return_no', 'sku_code'],
|
|
ll_return_inventory_carton_item: ['packing_reserved_quantity'],
|
|
ll_return_inventory_operation: ['result_json'],
|
|
ll_dispatch_pda_pick: ['return_carton_id'],
|
|
ll_dispatch_pda_pick_order: ['return_carton_id', 'return_receipt_id']
|
|
})) {
|
|
const definition = table(overseas, 'baiyue_lastleg', name)
|
|
for (const field of fields) assert.ok(definition.includes(field), name + '.' + field)
|
|
}
|
|
})
|
|
|
|
test('退货预占状态符合空库数量和状态约束', () => {
|
|
const carton = table(overseas, 'baiyue_lastleg', 'll_return_inventory_carton')
|
|
for (const name of ['chk_ll_return_inventory_carton_quantity', 'chk_ll_return_inventory_carton_status']) {
|
|
const constraint = carton.split('CONSTRAINT ' + name)[1].split('\n')[0]
|
|
for (const status of ['PACKING_RESERVED', 'OUTBOUND_PENDING']) assert.ok(constraint.includes(status), name + ':' + status)
|
|
}
|
|
})
|