feat(pl): 装送货段增加同市标记,并同步额度证件与计划表单。
同市易制毒段只校验购买证;同步 Web/H5 表单、额度统计展示与相关回归测试。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
d58f6ea5bd
commit
522b4be705
40 files changed
+576
-107
No files matched your search
@@ -2,7 +2,8 @@ import assert from 'node:assert/strict'
|
||||
import { describe, it } from 'node:test'
|
||||
import {
|
||||
canManualToggleStopDibang,
|
||||
resolveStopDibangDefaults
|
||||
resolveStopDibangDefaults,
|
||||
toxicStopCertBindingMessage
|
||||
} from './pl-plan-stop-form'
|
||||
import { isPlDibangOptionalVehiclePlate } from './pl-internal-customer'
|
||||
|
||||
@@ -23,6 +24,28 @@ describe('isPlDibangOptionalVehiclePlate', () => {
|
||||
})
|
||||
})
|
||||
|
||||
describe('toxicStopCertBindingMessage', () => {
|
||||
it('same-city stop only requires the purchase certificate', () => {
|
||||
assert.equal(
|
||||
toxicStopCertBindingMessage([
|
||||
{
|
||||
contractId: 'c1',
|
||||
contractNo: 'HT-1',
|
||||
sameCity: 1,
|
||||
certificates: [{ certType: 'purchase' }]
|
||||
}
|
||||
]),
|
||||
''
|
||||
)
|
||||
assert.equal(
|
||||
toxicStopCertBindingMessage([
|
||||
{ contractId: 'c1', contractNo: 'HT-1', sameCity: true, certificates: [] }
|
||||
]),
|
||||
'合同HT-1的同市段尚未绑定购买证,请先到合同中绑定后再安排运输'
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('resolveStopDibangDefaults + canManualToggleStopDibang', () => {
|
||||
it('internal + normal vehicle: auto-check, not manual', () => {
|
||||
assert.deepEqual(resolveStopDibangDefaults(INTERNAL, 'load', '皖A11111'), {
|
||||
|
||||
@@ -102,6 +102,8 @@ export interface PlanLoadForm {
|
||||
notes: string
|
||||
generateDibang: number
|
||||
dibangDirection: string
|
||||
/** 1 时本段易制毒只校验购买证 */
|
||||
sameCity: number
|
||||
contracts: PlanContractLink[]
|
||||
products: PlanStopProductFormRow[]
|
||||
}
|
||||
@@ -119,6 +121,8 @@ export interface PlanDeliveryForm {
|
||||
notes: string
|
||||
generateDibang: number
|
||||
dibangDirection: string
|
||||
/** 1 时本段易制毒只校验购买证 */
|
||||
sameCity: number
|
||||
contracts: PlanContractLink[]
|
||||
products: PlanStopProductFormRow[]
|
||||
}
|
||||
@@ -146,6 +150,49 @@ export function resolveStopDibangDefaults(
|
||||
return { generateDibang: 1, dibangDirection: 'inbound' }
|
||||
}
|
||||
|
||||
/** 安排前检查易制毒段的合同证件。同市段只要求购买证。 */
|
||||
export function toxicStopCertBindingMessage(
|
||||
rows: Array<{
|
||||
partyName?: string | null
|
||||
sameCity?: boolean | number | null
|
||||
certificates?: { certType?: string | null }[] | null
|
||||
contractId?: string | null
|
||||
contractNo?: string | null
|
||||
productName?: string | null
|
||||
sourceStopProductId?: string | null
|
||||
}>
|
||||
): string {
|
||||
const missingBoth = new Map<string, string>()
|
||||
const missingPurchase = new Map<string, string>()
|
||||
for (const row of rows) {
|
||||
if (isPlInternalCustomerName(row.partyName)) continue
|
||||
const certificates = row.certificates || []
|
||||
const hasPurchase = certificates.some((cert) => cert.certType === 'purchase')
|
||||
const hasTransport = certificates.some((cert) => cert.certType === 'transport')
|
||||
const sameCity = row.sameCity === true || Number(row.sameCity) === 1
|
||||
const key = row.contractId || row.contractNo || row.productName || row.sourceStopProductId || ''
|
||||
const label = row.contractNo || '未编号合同'
|
||||
if (sameCity) {
|
||||
if (!hasPurchase) missingPurchase.set(key, label)
|
||||
continue
|
||||
}
|
||||
if (hasPurchase && hasTransport) continue
|
||||
missingBoth.set(key, label)
|
||||
}
|
||||
const parts: string[] = []
|
||||
if (missingBoth.size) {
|
||||
parts.push(
|
||||
`合同${[...missingBoth.values()].join('、')}尚未绑定购买证和运输证,请先到合同中绑定后再安排运输`
|
||||
)
|
||||
}
|
||||
if (missingPurchase.size) {
|
||||
parts.push(
|
||||
`合同${[...missingPurchase.values()].join('、')}的同市段尚未绑定购买证,请先到合同中绑定后再安排运输`
|
||||
)
|
||||
}
|
||||
return parts.join(';')
|
||||
}
|
||||
|
||||
/** 仅「内部客户 + 地磅可选车」允许用户手动勾选地磅单 */
|
||||
export function canManualToggleStopDibang(
|
||||
customerName?: string | null,
|
||||
@@ -433,6 +480,7 @@ export function createEmptyLoadForm(): PlanLoadForm {
|
||||
notes: '',
|
||||
generateDibang: 0,
|
||||
dibangDirection: 'none',
|
||||
sameCity: 0,
|
||||
contracts: [],
|
||||
products: []
|
||||
}
|
||||
@@ -451,6 +499,7 @@ export function createEmptyDeliveryForm(seq = 1): PlanDeliveryForm {
|
||||
notes: '',
|
||||
generateDibang: 0,
|
||||
dibangDirection: 'none',
|
||||
sameCity: 0,
|
||||
contracts: [],
|
||||
products: []
|
||||
}
|
||||
@@ -540,6 +589,7 @@ export function mapLoadFromApi(
|
||||
notes: load.notes || '',
|
||||
generateDibang: dibang.generateDibang,
|
||||
dibangDirection: dibang.dibangDirection,
|
||||
sameCity: Number(load.sameCity) === 1 ? 1 : 0,
|
||||
contracts: (load.contracts || []).map((item) => ({
|
||||
contractId: String(item.contractId || ''),
|
||||
contractNo: item.contractNo
|
||||
@@ -574,6 +624,7 @@ export function mapDeliveriesFromApi(
|
||||
notes: row.notes || '',
|
||||
generateDibang: dibang.generateDibang,
|
||||
dibangDirection: dibang.dibangDirection,
|
||||
sameCity: Number(row.sameCity) === 1 ? 1 : 0,
|
||||
contracts: (row.contracts || []).map((item) => ({
|
||||
contractId: String(item.contractId || ''),
|
||||
contractNo: item.contractNo
|
||||
@@ -617,6 +668,7 @@ export function mapLegacyPlanToStops(plan: Plan): {
|
||||
notes: plan.pickupNotes || '',
|
||||
generateDibang: loadDefaults.generateDibang,
|
||||
dibangDirection: loadDefaults.dibangDirection,
|
||||
sameCity: 0,
|
||||
contracts: (plan.supplierContracts || []).map((item) => ({
|
||||
contractId: String(item.contractId || ''),
|
||||
contractNo: item.contractNo
|
||||
@@ -636,6 +688,7 @@ export function mapLegacyPlanToStops(plan: Plan): {
|
||||
notes: plan.destinationNotes || '',
|
||||
generateDibang: deliveryDefaults.generateDibang,
|
||||
dibangDirection: deliveryDefaults.dibangDirection,
|
||||
sameCity: 0,
|
||||
contracts: (plan.demanderContracts || []).map((item) => ({
|
||||
contractId: String(item.contractId || ''),
|
||||
contractNo: item.contractNo
|
||||
@@ -900,6 +953,7 @@ export function buildLoadPayload(load: PlanLoadForm) {
|
||||
notes: load.notes || undefined,
|
||||
generateDibang: load.generateDibang,
|
||||
dibangDirection: load.dibangDirection,
|
||||
sameCity: load.sameCity === 1 ? 1 : 0,
|
||||
contracts: load.contracts,
|
||||
products: load.products.map(buildStopProductPayload)
|
||||
}
|
||||
@@ -919,6 +973,7 @@ export function buildDeliveriesPayload(deliveries: PlanDeliveryForm[]) {
|
||||
notes: row.notes || undefined,
|
||||
generateDibang: row.generateDibang,
|
||||
dibangDirection: row.dibangDirection,
|
||||
sameCity: row.sameCity === 1 ? 1 : 0,
|
||||
contracts: row.contracts,
|
||||
products: row.products.map(buildStopProductPayload)
|
||||
}))
|
||||
|
||||
Reference in new issue
Block a user