fix: record customs results in Shanghai business time
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
import { beforeEach, describe, expect, it, vi } from 'vitest'
|
||||||
import { http } from '@/shared/api/http'
|
import { http } from '@/shared/api/http'
|
||||||
|
import { recordClearanceResult, type DeclarationBatch } from './platformContainerCustoms'
|
||||||
import { completeAllBuyContainerCustoms, downloadContainerCustomsReceipt, downloadContainerCustomsDocument, getContainerCustoms, sendContainerCustomsToBroker, startContainerCustoms, uploadContainerCustomsReceipt } from './platformContainerCustoms'
|
import { completeAllBuyContainerCustoms, downloadContainerCustomsReceipt, downloadContainerCustomsDocument, getContainerCustoms, sendContainerCustomsToBroker, startContainerCustoms, uploadContainerCustomsReceipt } from './platformContainerCustoms'
|
||||||
|
|
||||||
const customs = {
|
const customs = {
|
||||||
@@ -14,6 +15,20 @@ const customs = {
|
|||||||
describe('platform container customs API', () => {
|
describe('platform container customs API', () => {
|
||||||
beforeEach(() => vi.restoreAllMocks())
|
beforeEach(() => vi.restoreAllMocks())
|
||||||
|
|
||||||
|
it('records domestic customs time in Shanghai even when UTC falls on the previous day', async () => {
|
||||||
|
vi.useFakeTimers()
|
||||||
|
try {
|
||||||
|
vi.setSystemTime(new Date('2026-09-29T16:30:00Z'))
|
||||||
|
const post = vi.spyOn(http, 'post').mockResolvedValue({ code: '200', data: { id: '1' } })
|
||||||
|
await recordClearanceResult({ id: '123', version: 1 } as DeclarationBatch, 'OTHER', 'test')
|
||||||
|
expect(post).toHaveBeenCalledWith('/platform/v1/customs/loading-plans/declaration-batches/123/results',
|
||||||
|
expect.objectContaining({ occurredAt: '2026-09-30T00:30:00', resultType: 'OTHER', resolution: 'test' }),
|
||||||
|
expect.objectContaining({ headers: { 'Idempotency-Key': expect.any(String) } }))
|
||||||
|
} finally {
|
||||||
|
vi.useRealTimers()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
it('uses the frozen customs-v1 paths and preserves long ids as strings', async () => {
|
it('uses the frozen customs-v1 paths and preserves long ids as strings', async () => {
|
||||||
const get = vi.spyOn(http, 'get').mockResolvedValue({ code: '200', message: 'ok', data: customs })
|
const get = vi.spyOn(http, 'get').mockResolvedValue({ code: '200', message: 'ok', data: customs })
|
||||||
const result = await getContainerCustoms('2092438843630391402')
|
const result = await getContainerCustoms('2092438843630391402')
|
||||||
|
|||||||
@@ -189,7 +189,13 @@ export async function submitDeclarationBatch(batch: DeclarationBatch, customsEnt
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function recordClearanceResult(batch: DeclarationBatch, resultType: ClearanceResultType, resolution?: string) {
|
export async function recordClearanceResult(batch: DeclarationBatch, resultType: ClearanceResultType, resolution?: string) {
|
||||||
const response = await http.post<ApiEnvelope<ClearanceResult>, ApiEnvelope<ClearanceResult>>(`${basePath}/declaration-batches/${encodeURIComponent(batch.id)}/results`, { expectedVersion: batch.version, resultType, occurredAt: new Date().toISOString(), resolution: resolution?.trim() || null, evidenceFileId: null, resolved: false }, { headers: { 'Idempotency-Key': operationId('customs-clearance-result-record') } })
|
// The domestic API stores LocalDateTime; send Shanghai wall time, not UTC with a discarded offset.
|
||||||
|
const parts = Object.fromEntries(new Intl.DateTimeFormat('en-CA', {
|
||||||
|
timeZone: 'Asia/Shanghai', year: 'numeric', month: '2-digit', day: '2-digit',
|
||||||
|
hour: '2-digit', minute: '2-digit', second: '2-digit', hourCycle: 'h23',
|
||||||
|
}).formatToParts(new Date()).map(({ type, value }) => [type, value]))
|
||||||
|
const occurredAt = `${parts.year}-${parts.month}-${parts.day}T${parts.hour}:${parts.minute}:${parts.second}`
|
||||||
|
const response = await http.post<ApiEnvelope<ClearanceResult>, ApiEnvelope<ClearanceResult>>(`${basePath}/declaration-batches/${encodeURIComponent(batch.id)}/results`, { expectedVersion: batch.version, resultType, occurredAt, resolution: resolution?.trim() || null, evidenceFileId: null, resolved: false }, { headers: { 'Idempotency-Key': operationId('customs-clearance-result-record') } })
|
||||||
return normalizeClearanceResult(unwrapApiResponse(response))
|
return normalizeClearanceResult(unwrapApiResponse(response))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user