import { http } from './http.js'; /** * Normalizes a retouresummary record from either snake_case (raw view) or camelCase. * Fields: manifest_id, retoure_number, retoure_date, entity_id, customer_name, * positions, gross_total, paid_total, ordered_quantity, shipped_quantity, is_paid, is_shipped, created_at */ export function normalizeRetoureSummary(row) { if (!row) return null; const id = row.manifest_id ?? row.id; const num = row.retoure_number ?? row.number ?? (id ? `RET-${id}` : ''); const dt = row.retoure_date ?? row.date ?? row.created_at ?? row.createdAt; const entityId = row.entity_id ?? row.entityId ?? null; const customerName = row.customer_name ?? row.customerName ?? ''; const positions = Number(row.positions) || 0; const grossTotal = row.gross_total != null ? Number(row.gross_total) : (row.grossTotal != null ? Number(row.grossTotal) : 0); const paidTotal = row.paid_total != null ? Number(row.paid_total) : (row.paidTotal != null ? Number(row.paidTotal) : 0); const orderedQuantity = row.ordered_quantity != null ? Number(row.ordered_quantity) : (row.orderedQuantity != null ? Number(row.orderedQuantity) : 0); const shippedQuantity = row.shipped_quantity != null ? Number(row.shipped_quantity) : (row.shippedQuantity != null ? Number(row.shippedQuantity) : 0); const isPaid = Boolean(row.is_paid ?? row.isPaid); const isShipped = Boolean(row.is_shipped ?? row.isShipped); const createdAt = row.created_at ?? row.createdAt ?? null; return { id, manifest_id: id, number: num, retoure_number: num, date: dt, retoure_date: dt, entityId, entity_id: entityId, customerName, customer_name: customerName, positions, grossTotal, gross_total: grossTotal, paidTotal, paid_total: paidTotal, orderedQuantity, ordered_quantity: orderedQuantity, shippedQuantity, shipped_quantity: shippedQuantity, isPaid, is_paid: isPaid, isShipped, is_shipped: isShipped, createdAt, created_at: createdAt, lines: row.lines ?? [], files: row.files ?? [], shipments: row.shipments ?? [], payments: row.payments ?? [], }; } /** * Customer Returns / Retouren (manifest type = retoure). */ export const retoure = { /** * GET /api/retoure * Query params: q, from, to, isPaid, isShipped, page, pageSize, offset, limit, entityId * → { retoures: RetoureSummary[], total: number, unfilteredTotal: number } */ // #region GET /api/retoure — list async list({ q, search, from, to, isPaid, isShipped, onlyUnpaid, onlyUndelivered, page, pageSize, offset, limit, entityId, seekMonths, } = {}) { const params = new URLSearchParams(); const query = q || search; if (query && String(query).trim()) { params.set('q', String(query).trim()); params.set('search', String(query).trim()); } if (from) params.set('from', String(from)); if (to) params.set('to', String(to)); if (isPaid !== undefined && isPaid !== null) { params.set('isPaid', String(isPaid)); } else if (onlyUnpaid === true || onlyUnpaid === 'true') { params.set('isPaid', 'false'); } if (isShipped !== undefined && isShipped !== null) { params.set('isShipped', String(isShipped)); } else if (onlyUndelivered === true || onlyUndelivered === 'true') { params.set('isShipped', 'false'); } if (page != null) params.set('page', String(page)); if (pageSize != null) params.set('pageSize', String(pageSize)); if (offset != null) params.set('offset', String(offset)); if (limit != null) params.set('limit', String(limit)); if (entityId != null) params.set('entityId', String(entityId)); if (seekMonths != null && Number(seekMonths) < 0) { params.set('seekMonths', String(Math.floor(Number(seekMonths)))); } const qs = params.toString(); const res = await http(`/api/retoure${qs ? `?${qs}` : ''}`); const rawList = res?.retoures ?? res?.summaries ?? res?.items ?? (Array.isArray(res) ? res : []); const items = rawList.map(normalizeRetoureSummary); const total = Number(res?.total ?? res?.count ?? items.length); const unfilteredTotal = res?.unfilteredTotal != null ? Number(res.unfilteredTotal) : total; return { retoures: items, summaries: items, items, total, unfilteredTotal, raw: res, }; }, // #endregion /** GET /api/retoure/:id → { retoure: Retoure } */ // #region GET /api/retoure/:id — get async get(id) { const res = await http(`/api/retoure/${id}`); if (res && !res.retoure && (res.id != null || res.manifest_id != null)) { return { retoure: res }; } return res; }, // #endregion /** * POST /api/retoure * Body: { number?, date, entityId?, externalNumber?, lines } * → 201 { retoure: Retoure } */ // #region POST /api/retoure — create async create(body) { const res = await http('/api/retoure', { method: 'POST', body }); if (res && !res.retoure && (res.id != null || res.manifest_id != null)) { return { retoure: res }; } return res; }, // #endregion /** * PUT /api/retoure/:id * Body: { number?, date?, entityId?, externalNumber?, lines? } * → 200 { retoure: Retoure } */ // #region PUT /api/retoure/:id — update async update(id, body) { const res = await http(`/api/retoure/${id}`, { method: 'PUT', body }); if (res && !res.retoure && (res.id != null || res.manifest_id != null)) { return { retoure: res }; } return res; }, // #endregion /** DELETE /api/retoure/:id → 204 */ // #region DELETE /api/retoure/:id — delete delete(id) { return http(`/api/retoure/${id}`, { method: 'DELETE' }); }, // #endregion /** * POST /api/retoure/:id/shipment * Creates return shipment. * Body: { date?, externalNumber?, lines?: Array<{ sku?: string, orderLineId?: number, amount?: number }>, shipping?: { carrierId, type, state, warehouseId } } * → 201 { shipment: Shipment } */ // #region POST /api/retoure/:id/shipment — createShipment createShipment(id, body = {}) { return http(`/api/retoure/${id}/shipment`, { method: 'POST', body }); }, // #endregion };