fix(consignment): 验收结算补上寄卖货款,并修指派打手线报酬 100 倍单位错
问题:工单 #100171 验收完成时卖家钱包只有押金 -20/+20,货卖掉了但货款收益没进卖家钱包。 查证:工单报酬 reward_amount=14500 分(发单方付 ¥145),货的结算价 cost_price_fen=12400 分 (卖家应得 ¥124),而 assigned_worker_id 为空(内部现货履约)。通用结算的规则是"把工单报酬 付给接单人",内部现货单没有接单人 → 这笔钱谁也没拿到,卖家只拿回自己的押金。 - 新增 settleConsignmentSupplierPayoutByWorkOrderWithClient():验收完成时把货的结算价 (cost_price_fen,缺省退回 asking_price_fen)补给供货卖家,单位与通用报酬一致(分), 同样做售后欠款抵扣、按售后策略决定是否延迟解冻、写 reward_settlement/reward_pending_unfreeze 流水(说明「寄卖货款结算 #单号」) - 不重复付款:接单人就是供货卖家本人时跳过(指派打手线里货物已随工单报酬付过) - 修 100 倍单位错:指派打手线把工单报酬改写成货的结算价时写了 (cost_price_fen/100).toFixed(2), ¥124 被写成 ¥1.24;reward_amount 的单位是分(已用真实数据核对)。抽成纯函数 resolveConsignmentAssignRewardFen() 并加测试钉住单位 真实库端到端验证:卖家钱包 ¥205.50 → ¥329.50(+¥124.00 寄卖货款结算),累计结算同步 +¥124.00; 验证脚本改动的开发库数据已还原,临时数据残留 0。
This commit is contained in:
@@ -361,6 +361,21 @@ export async function fulfillWorkOrderWithConsignment(input: {
|
||||
/**
|
||||
* 选用内部寄售库存并走接单平台指派打手(冻结押金担保履约)
|
||||
*/
|
||||
/**
|
||||
* 指派打手线里工单报酬要改成"货的结算价":卖家拿结算价、平台赚差价。
|
||||
*
|
||||
* 单位必须是**分**(与钱包、流水、其它工单报酬一致)。这里以前多除了 100,
|
||||
* 会把 ¥124 写成 ¥1.24 —— 卖家只拿到结算价的百分之一。
|
||||
*/
|
||||
export function resolveConsignmentAssignRewardFen(input: {
|
||||
costPriceFen: unknown
|
||||
orderRewardFen: unknown
|
||||
}): number {
|
||||
const costPriceFen = Math.round(Number(input.costPriceFen || 0))
|
||||
if (costPriceFen > 0) return costPriceFen
|
||||
return Math.round(Number(input.orderRewardFen || 0))
|
||||
}
|
||||
|
||||
export async function assignWorkOrderWithConsignmentWorker(input: {
|
||||
workOrderId: number | string
|
||||
inventoryId: number | string
|
||||
@@ -460,14 +475,14 @@ export async function assignWorkOrderWithConsignmentWorker(input: {
|
||||
},
|
||||
}
|
||||
|
||||
const rewardAmountYuan =
|
||||
Number(claimed.cost_price_fen || 0) > 0
|
||||
? Number((Number(claimed.cost_price_fen) / 100).toFixed(2))
|
||||
: Number(workOrder.reward_amount || 0)
|
||||
const rewardAmountFen = resolveConsignmentAssignRewardFen({
|
||||
costPriceFen: claimed.cost_price_fen,
|
||||
orderRewardFen: workOrder.reward_amount,
|
||||
})
|
||||
|
||||
await updateWorkOrder(workOrder.id, {
|
||||
material_json: updatedMaterial,
|
||||
reward_amount: rewardAmountYuan,
|
||||
reward_amount: rewardAmountFen,
|
||||
updated_at: now,
|
||||
})
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import test from 'node:test'
|
||||
import { readFile } from 'node:fs/promises'
|
||||
|
||||
import { resolveConsignmentAssignRewardFen } from './consignment-fulfillment-service.js'
|
||||
|
||||
const SETTLEMENT_REPO = new URL(
|
||||
'../../repositories/worker-platform/work-order-settlement-repo.ts',
|
||||
import.meta.url,
|
||||
)
|
||||
const DEPOSIT_REPO = new URL(
|
||||
'../../repositories/worker-platform/consignment-deposit-repo.ts',
|
||||
import.meta.url,
|
||||
)
|
||||
|
||||
test('指派打手线的工单报酬用分(不再多除 100)', () => {
|
||||
// ¥124.00 的货 → 12400 分。以前是 Number((12400 / 100).toFixed(2)) = 124,只等于 ¥1.24
|
||||
assert.equal(
|
||||
resolveConsignmentAssignRewardFen({ costPriceFen: 12400, orderRewardFen: 14500 }),
|
||||
12400,
|
||||
)
|
||||
assert.equal(resolveConsignmentAssignRewardFen({ costPriceFen: 2500, orderRewardFen: 999 }), 2500)
|
||||
})
|
||||
|
||||
test('没有结算价时退回原工单报酬,且都是分', () => {
|
||||
assert.equal(resolveConsignmentAssignRewardFen({ costPriceFen: 0, orderRewardFen: 14500 }), 14500)
|
||||
assert.equal(resolveConsignmentAssignRewardFen({ costPriceFen: null, orderRewardFen: null }), 0)
|
||||
})
|
||||
|
||||
test('验收结算必须补寄卖货款,否则内部现货单的卖家只拿回押金', async () => {
|
||||
const source = await readFile(SETTLEMENT_REPO, 'utf8')
|
||||
assert.ok(source.includes('settleConsignmentSupplierPayoutByWorkOrderWithClient('))
|
||||
assert.ok(source.includes('assignedWorkerId: workerId'))
|
||||
})
|
||||
|
||||
test('寄卖货款:接单人就是供货卖家时不重复付款,金额取货的结算价', async () => {
|
||||
const source = await readFile(DEPOSIT_REPO, 'utf8')
|
||||
assert.ok(source.includes('const supplierId ='))
|
||||
assert.ok(source.includes('if (Number(input.assignedWorkerId || 0) === supplierId) return null'))
|
||||
assert.ok(source.includes('cost_price_fen'))
|
||||
assert.ok(source.includes('寄卖货款结算'), '货款流水要有可读说明')
|
||||
// 和通用报酬结算一样:售后欠款抵扣 + 按售后策略决定是否延迟解冻
|
||||
assert.ok(source.includes('offsetWorkerAfterSalesDebtsWithClient('))
|
||||
assert.ok(source.includes('enqueueDepositUnfreezeWithClient('))
|
||||
})
|
||||
Reference in New Issue
Block a user