67 lines
6.2 KiB
TypeScript
67 lines
6.2 KiB
TypeScript
import { overseasHttp } from '@/shared/api/overseasHttp'
|
|
import { unwrapApiResponse, type ApiEnvelope } from '@/shared/api/http'
|
|
|
|
const basePath = '/platform/v1/last-leg/finance-fee-sources'
|
|
type RawResource = Record<string, unknown>
|
|
|
|
export type OverseasContainerFeeItem = 'PORT_FEE' | 'STORAGE_FEE' | 'CONTAINER_REPAIR_FEE' | 'CRANE_FEE' | 'TERMINAL_DRAYAGE_FEE' | 'OTHER'
|
|
export type OverseasContainerFeeDirection = 'RECEIVABLE' | 'PAYABLE'
|
|
|
|
export interface OverseasContainerCustomer { customerId: string; customerName: string | null }
|
|
export interface OverseasContainerFeeSource {
|
|
id: string; sourceFeeId: string; sourceVersion: number; customerId: string; customerName: string | null
|
|
sourceType: 'OVERSEAS_CONTAINER_FEE'; businessType: 'OVERSEAS_CONTAINER'; businessId: string; businessNo: string
|
|
containerBookingId: string; containerNo: string; feeItemCode: OverseasContainerFeeItem; feeItemName: string
|
|
direction: OverseasContainerFeeDirection; supplierId: string | null; supplierName: string | null; supplierCategory: string | null
|
|
settlementMode: string | null; paidAt: string | null; paymentMethod: string | null; paymentReferenceNo: string | null
|
|
paymentVoucherFileIds: string[]; businessDate: string; currency: 'CNY'; amount: number
|
|
reviewStatus: 'DRAFT' | 'PENDING' | 'APPROVED' | 'REJECTED'; sourceStatus: 'ACTIVE' | 'SUPERSEDED' | 'VOIDED'
|
|
reviewReason: string | null; reviewedAt: string | null
|
|
}
|
|
export interface OverseasContainerFeeSaveRequest {
|
|
customerId: string; customerName: string | null; sourceType: 'OVERSEAS_CONTAINER_FEE'; businessType: 'OVERSEAS_CONTAINER'
|
|
businessId: string; businessNo: string; orderId: null; inboundId: null; inboundCode: null; containerId: null
|
|
containerBookingId: string; containerNo: string; warehouseId: null; feeItemCode: OverseasContainerFeeItem; feeItemName: string
|
|
direction: OverseasContainerFeeDirection; supplierId: string | null; supplierName: string | null; supplierCategory: string | null
|
|
settlementMode: 'ON_ACCOUNT' | 'DIRECT_PAID' | null; paidAt: string | null
|
|
paymentMethod: 'ONLINE' | 'BANK_TRANSFER' | 'CASH' | 'OTHER' | null; paymentReferenceNo: string | null; paymentVoucherFileIds: string[] | null
|
|
businessDate: string; currency: 'CNY'; amount: number
|
|
}
|
|
|
|
const text = (value: unknown) => value == null || value === '' ? null : String(value)
|
|
const requiredText = (value: unknown) => String(value ?? '')
|
|
const numberValue = (value: unknown) => Number.isFinite(Number(value)) ? Number(value) : 0
|
|
function normalizeFee(raw: RawResource): OverseasContainerFeeSource {
|
|
return {
|
|
id: requiredText(raw.id), sourceFeeId: requiredText(raw.sourceFeeId), sourceVersion: numberValue(raw.sourceVersion), customerId: requiredText(raw.customerId), customerName: text(raw.customerName),
|
|
sourceType: 'OVERSEAS_CONTAINER_FEE', businessType: 'OVERSEAS_CONTAINER', businessId: requiredText(raw.businessId), businessNo: requiredText(raw.businessNo), containerBookingId: requiredText(raw.containerBookingId), containerNo: requiredText(raw.containerNo),
|
|
feeItemCode: raw.feeItemCode as OverseasContainerFeeItem, feeItemName: requiredText(raw.feeItemName), direction: raw.direction as OverseasContainerFeeDirection,
|
|
supplierId: text(raw.supplierId), supplierName: text(raw.supplierName), supplierCategory: text(raw.supplierCategory), settlementMode: text(raw.settlementMode), paidAt: text(raw.paidAt), paymentMethod: text(raw.paymentMethod), paymentReferenceNo: text(raw.paymentReferenceNo),
|
|
paymentVoucherFileIds: Array.isArray(raw.paymentVoucherFileIds) ? raw.paymentVoucherFileIds.map(String) : [], businessDate: requiredText(raw.businessDate), currency: 'CNY', amount: numberValue(raw.amount),
|
|
reviewStatus: raw.reviewStatus as OverseasContainerFeeSource['reviewStatus'], sourceStatus: raw.sourceStatus as OverseasContainerFeeSource['sourceStatus'], reviewReason: text(raw.reviewReason), reviewedAt: text(raw.reviewedAt),
|
|
}
|
|
}
|
|
export async function listOverseasContainerFees(containerBookingId: string) {
|
|
const response = await overseasHttp.get<ApiEnvelope<RawResource[]>, ApiEnvelope<RawResource[]>>(basePath, { params: { containerBookingId } })
|
|
return unwrapApiResponse(response).map(normalizeFee)
|
|
}
|
|
export async function listOverseasContainerCustomers(containerBookingId: string) {
|
|
const response = await overseasHttp.get<ApiEnvelope<Array<{ customerId: unknown; customerName?: unknown }>>, ApiEnvelope<Array<{ customerId: unknown; customerName?: unknown }>>>(`${basePath}/container-customers`, { params: { containerBookingId } })
|
|
return unwrapApiResponse(response).map((item) => ({ customerId: requiredText(item.customerId), customerName: text(item.customerName) }))
|
|
}
|
|
export async function createOverseasContainerFee(payload: OverseasContainerFeeSaveRequest, idempotencyKey: string) {
|
|
return normalizeFee(unwrapApiResponse(await overseasHttp.post<ApiEnvelope<RawResource>, ApiEnvelope<RawResource>>(basePath, payload, { headers: { 'Idempotency-Key': idempotencyKey } })))
|
|
}
|
|
export async function submitOverseasContainerFee(sourceFeeId: string, idempotencyKey: string) {
|
|
return normalizeFee(unwrapApiResponse(await overseasHttp.post<ApiEnvelope<RawResource>, ApiEnvelope<RawResource>>(`${basePath}/${encodeURIComponent(sourceFeeId)}/submit`, { idempotencyKey })))
|
|
}
|
|
export async function reviewOverseasContainerFee(sourceFeeId: string, decision: 'APPROVE' | 'REJECT', reason: string | null, idempotencyKey: string) {
|
|
return normalizeFee(unwrapApiResponse(await overseasHttp.post<ApiEnvelope<RawResource>, ApiEnvelope<RawResource>>(`${basePath}/${encodeURIComponent(sourceFeeId)}/review`, { decision, reason, idempotencyKey })))
|
|
}
|
|
export async function adjustOverseasContainerFee(sourceFeeId: string, expectedVersion: number, fee: OverseasContainerFeeSaveRequest, idempotencyKey: string) {
|
|
return normalizeFee(unwrapApiResponse(await overseasHttp.post<ApiEnvelope<RawResource>, ApiEnvelope<RawResource>>(`${basePath}/${encodeURIComponent(sourceFeeId)}/adjust`, { expectedVersion, fee, idempotencyKey })))
|
|
}
|
|
export async function voidOverseasContainerFee(sourceFeeId: string, expectedVersion: number, reason: string, idempotencyKey: string) {
|
|
return normalizeFee(unwrapApiResponse(await overseasHttp.post<ApiEnvelope<RawResource>, ApiEnvelope<RawResource>>(`${basePath}/${encodeURIComponent(sourceFeeId)}/void`, { expectedVersion, reason, idempotencyKey })))
|
|
}
|