import { query } from '../db/client.js' import type { OrderCreateInput, OrderListQueryInput, OrderUpdateInput, } from '../types/repository-inputs.js' import type { OrderListQueryResult, OrderListRow, OrderRow, } from '../types/repository-rows.js' type OrderPlatformLookupInput = { provider?: string platform: string shopId?: string platformOrderId: string } type OrderPlatformCandidateLookupInput = { provider?: string platform?: string shopIds?: unknown[] platformOrderId?: string } export async function findOrderByPlatformOrderId({ provider = '91kaquan', platform, shopId = '', platformOrderId, }: OrderPlatformLookupInput): Promise { const result = await query( ` SELECT * FROM orders WHERE provider = $1 AND platform = $2 AND shop_id = $3 AND platform_order_id = $4 LIMIT 1 `, [provider, platform, shopId, platformOrderId], ) return result.rows[0] || null } export async function findOrderByPlatformOrderIdCandidates({ provider = '91kaquan', platform, shopIds = [], platformOrderId, }: OrderPlatformCandidateLookupInput): Promise { const normalizedShopIds = [...new Set((Array.isArray(shopIds) ? shopIds : []) .map((item) => String(item || '').trim()) .filter(Boolean))] if (!platform || !platformOrderId || normalizedShopIds.length === 0) { return null } const result = await query( ` SELECT * FROM orders WHERE provider = $1 AND platform = $2 AND shop_id = ANY($3::text[]) AND platform_order_id = $4 ORDER BY id DESC LIMIT 1 `, [provider, platform, normalizedShopIds, platformOrderId], ) return result.rows[0] || null } export async function createOrder(input: OrderCreateInput): Promise { const result = await query( ` INSERT INTO orders ( provider, platform, shop_id, shop_name, platform_order_id, order_status, pay_status, buyer_id, buyer_name, receiver_contact, total_amount, currency, raw_payload_json, paid_at, created_at, updated_at ) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13::jsonb, $14, $15, $16) RETURNING * `, [ input.provider, input.platform, input.shopId, input.shopName, input.platformOrderId, input.orderStatus, input.payStatus, input.buyerId, input.buyerName, input.receiverContact, input.totalAmount, input.currency, input.rawPayloadJson || '{}', input.paidAt || null, input.createdAt, input.updatedAt, ], ) return result.rows[0] || null } export async function updateOrder(orderId: number | string, input: OrderUpdateInput): Promise { const result = await query( ` UPDATE orders SET provider = $1, platform = $2, shop_id = $3, shop_name = $4, order_status = $5, pay_status = $6, buyer_id = $7, buyer_name = $8, receiver_contact = $9, total_amount = $10, currency = $11, raw_payload_json = $12::jsonb, paid_at = $13, updated_at = $14 WHERE id = $15 RETURNING * `, [ input.provider, input.platform, input.shopId, input.shopName, input.orderStatus, input.payStatus, input.buyerId, input.buyerName, input.receiverContact, input.totalAmount, input.currency, input.rawPayloadJson || '{}', input.paidAt || null, input.updatedAt, Number(orderId), ], ) return result.rows[0] || null } export async function getOrderById(orderId: number | string): Promise { const result = await query('SELECT * FROM orders WHERE id = $1 LIMIT 1', [Number(orderId)]) return result.rows[0] || null } export async function listOrders({ page = 1, pageSize = 20, platformOrderId = '', payStatus = '', skuCode = '', dateFrom = '', dateTo = '', }: OrderListQueryInput = {}): Promise { const offset = (page - 1) * pageSize const filters: string[] = [] const params: unknown[] = [] if (platformOrderId) { params.push(`%${platformOrderId}%`) filters.push(`o.platform_order_id ILIKE $${params.length}`) } if (payStatus) { params.push(payStatus) filters.push(`o.pay_status = $${params.length}`) } if (skuCode) { params.push(skuCode) filters.push(`EXISTS (SELECT 1 FROM order_items oi WHERE oi.order_id = o.id AND oi.sku_code = $${params.length})`) } if (dateFrom) { params.push(dateFrom) filters.push(`o.created_at >= $${params.length}`) } if (dateTo) { params.push(dateTo) filters.push(`o.created_at <= $${params.length}`) } const whereClause = filters.length > 0 ? `WHERE ${filters.join(' AND ')}` : '' const totalResult = await query<{ [column: string]: unknown, total: number }>( `SELECT COUNT(*)::int AS total FROM orders o ${whereClause}`, params, ) params.push(pageSize) params.push(offset) const itemsResult = await query( ` SELECT o.*, (SELECT COUNT(*)::int FROM fulfillment_tasks ft WHERE ft.order_id = o.id) AS task_count FROM orders o ${whereClause} ORDER BY o.id DESC LIMIT $${params.length - 1} OFFSET $${params.length} `, params, ) return { items: itemsResult.rows, total: Number(totalResult.rows[0]?.total || 0), } }