feat(fulfillment): 收敛履约状态写入口并追加状态事件
This commit is contained in:
@@ -6,6 +6,10 @@ import { formatShanghaiDate, shiftDate } from '../../utils/finance-date-range.js
|
||||
import { nowIso } from '../../utils/time.js'
|
||||
import { upsertInternalSkuChannel } from '../fulfillment/internal-sku-channel-service.js'
|
||||
import { reconcilePendingCarriers } from '../fulfillment/carrier-reconciliation-service.js'
|
||||
import {
|
||||
transitionFulfillmentStateBatch,
|
||||
transitionFulfillmentStateBatchWithExecutor,
|
||||
} from '../fulfillment/fulfillment-state-service.js'
|
||||
import { canonicalizeInternalSku, containsCjk } from '../fulfillment/internal-sku-resolver.js'
|
||||
import { refreshFactsForDates } from '../finance/refresh-facts.js'
|
||||
import {
|
||||
@@ -581,12 +585,13 @@ async function retryPendingManualItems(skuKey: string): Promise<number> {
|
||||
)
|
||||
const ids = candidates.rows.map((row) => Number(row.id))
|
||||
if (ids.length === 0) return 0
|
||||
await query(
|
||||
`UPDATE order_items
|
||||
SET fulfillment_locked = FALSE, updated_at = NOW()
|
||||
WHERE id = ANY($1::bigint[]) AND fulfillment_status = 'pending'`,
|
||||
[ids],
|
||||
)
|
||||
await transitionFulfillmentStateBatch({
|
||||
orderItemIds: ids,
|
||||
expected: { status: 'pending', locked: true },
|
||||
patch: { locked: false },
|
||||
eventType: 'manual_config_retry_unlocked',
|
||||
actor: { type: 'system' },
|
||||
})
|
||||
const result = await reconcilePendingCarriers({
|
||||
orderItemIds: ids,
|
||||
limit: ids.length,
|
||||
@@ -763,29 +768,28 @@ export async function deleteManualSkuClassification(
|
||||
)
|
||||
|
||||
if (itemIds.length > 0) {
|
||||
await client.query(
|
||||
`
|
||||
UPDATE order_items
|
||||
SET fulfillment_channel = NULL,
|
||||
fulfillment_status = 'pending',
|
||||
fulfillment_source = '',
|
||||
fulfillment_locked = FALSE,
|
||||
fulfillment_config_id = NULL,
|
||||
fulfillment_pending_reason = 'no_channel_capability',
|
||||
fulfillment_pending_detail = jsonb_build_object(
|
||||
'reason', 'manual_classification_removed',
|
||||
'removedAt', NOW()
|
||||
),
|
||||
fulfillment_reason = '运营移除错误的人工分类',
|
||||
fulfillment_decided_by = NULL,
|
||||
fulfillment_decided_at = NULL,
|
||||
updated_at = NOW()
|
||||
WHERE id = ANY($1::bigint[])
|
||||
AND fulfillment_status = 'assigned'
|
||||
AND fulfillment_channel = 'manual'
|
||||
`,
|
||||
[itemIds],
|
||||
)
|
||||
await transitionFulfillmentStateBatchWithExecutor(client, {
|
||||
orderItemIds: itemIds,
|
||||
expected: { status: 'assigned', channel: 'manual' },
|
||||
patch: {
|
||||
status: 'pending',
|
||||
channel: null,
|
||||
source: '',
|
||||
locked: false,
|
||||
configId: null,
|
||||
pendingReason: 'no_channel_capability',
|
||||
pendingDetail: {
|
||||
reason: 'manual_classification_removed',
|
||||
removedAt: nowIso(),
|
||||
},
|
||||
reason: '运营移除错误的人工分类',
|
||||
decidedBy: null,
|
||||
decidedAt: null,
|
||||
},
|
||||
eventType: 'manual_classification_removed',
|
||||
actor: { type: 'operator' },
|
||||
reason: key,
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user