86 lines
2.6 KiB
TypeScript
86 lines
2.6 KiB
TypeScript
// web-admin/src/utils/pl-batch-print.ts
|
||
import type { Plan, PlanProduct } from '@/api/pl'
|
||
import type { PlPrintSlipCommand } from '@/utils/pl-display'
|
||
|
||
export type SlipPlanProduct = PlanProduct & { slipPlanNo?: string }
|
||
|
||
export function normalizeCustomerName(name?: string | null) {
|
||
return String(name || '').trim()
|
||
}
|
||
|
||
export function canBatchPrintSlip(
|
||
plans: Array<Pick<Plan, 'customerName' | 'planDate'>>,
|
||
command: PlPrintSlipCommand
|
||
): { ok: boolean; reason?: string } {
|
||
if (!plans?.length) return { ok: false, reason: '请先勾选运输计划' }
|
||
|
||
if (plans.length === 1) {
|
||
return { ok: true }
|
||
}
|
||
|
||
if (command === 'inbound' || command === 'delivery') {
|
||
const c = normalizeCustomerName(plans[0].customerName)
|
||
const d = plans[0].planDate
|
||
const slipLabel = command === 'inbound' ? '入库单' : '送(提)货单'
|
||
if (!c || !d || !plans.every((p) => normalizeCustomerName(p.customerName) === c && p.planDate === d)) {
|
||
return {
|
||
ok: false,
|
||
reason: `合打${slipLabel}要求:客户名称一致且计划日期一致`
|
||
}
|
||
}
|
||
return { ok: true }
|
||
}
|
||
|
||
if (command === 'subpack') {
|
||
return { ok: true }
|
||
}
|
||
|
||
return { ok: false, reason: '未知单据类型' }
|
||
}
|
||
|
||
export function mergeBatchPrintRemarks(plans: Array<Pick<Plan, 'planNo' | 'remark'>>) {
|
||
return plans
|
||
.map((p) => {
|
||
const text = String(p.remark || '').trim()
|
||
if (!text) return ''
|
||
return `${p.planNo}:${text}`
|
||
})
|
||
.filter(Boolean)
|
||
.join('\n')
|
||
}
|
||
|
||
/** 备注写入 HTML 模版时换行 */
|
||
export function formatRemarkForSlipHtml(remark?: string | null) {
|
||
return String(remark || '')
|
||
.replace(/&/g, '&')
|
||
.replace(/</g, '<')
|
||
.replace(/>/g, '>')
|
||
.replace(/\n/g, '<br />')
|
||
}
|
||
|
||
/** 合打视图:首条为抬头基准;产品展开并打 slipPlanNo;清空车辆;备注合并 */
|
||
export function buildBatchPrintPlanView(plans: Plan[]): Plan {
|
||
if (!plans.length) throw new Error('plans empty')
|
||
const base = { ...plans[0] }
|
||
const products: SlipPlanProduct[] = []
|
||
for (const p of plans) {
|
||
for (const prod of p.products || []) {
|
||
products.push({ ...prod, slipPlanNo: p.planNo })
|
||
}
|
||
}
|
||
base.products = products
|
||
base.remark = mergeBatchPrintRemarks(plans)
|
||
base.licensePlate = undefined
|
||
base.vehicleId = undefined
|
||
base.driverId = undefined
|
||
base.driverName = undefined
|
||
base.trailerNo = undefined
|
||
base.personnelSummary = undefined
|
||
return base
|
||
}
|
||
|
||
export function normalizePlanIds(planIdOrIds: string | string[]): string[] {
|
||
const ids = Array.isArray(planIdOrIds) ? planIdOrIds : [planIdOrIds]
|
||
return ids.map((id) => String(id || '').trim()).filter(Boolean)
|
||
}
|