import type { ShipmentDetailDto, ShipmentInput, ShipmentOrderOptionDto, ShipmentStatus, ShipmentSummaryDto, } from "@mrp/shared/dist/shipping/types.js"; import { prisma } from "../../lib/prisma.js"; type ShipmentRecord = { id: string; shipmentNumber: string; status: string; shipDate: Date | null; carrier: string; serviceLevel: string; trackingNumber: string; packageCount: number; notes: string; createdAt: Date; updatedAt: Date; salesOrder: { id: string; documentNumber: string; customer: { name: string; }; }; }; function mapShipment(record: ShipmentRecord): ShipmentDetailDto { return { id: record.id, shipmentNumber: record.shipmentNumber, salesOrderId: record.salesOrder.id, salesOrderNumber: record.salesOrder.documentNumber, customerName: record.salesOrder.customer.name, status: record.status as ShipmentStatus, carrier: record.carrier, serviceLevel: record.serviceLevel, trackingNumber: record.trackingNumber, packageCount: record.packageCount, shipDate: record.shipDate ? record.shipDate.toISOString() : null, notes: record.notes, createdAt: record.createdAt.toISOString(), updatedAt: record.updatedAt.toISOString(), }; } async function nextShipmentNumber() { const next = (await prisma.shipment.count()) + 1; return `SHP-${String(next).padStart(5, "0")}`; } export async function listShipmentOrderOptions(): Promise { const orders = await prisma.salesOrder.findMany({ include: { customer: { select: { name: true, }, }, lines: { select: { quantity: true, unitPrice: true, }, }, }, orderBy: [{ issueDate: "desc" }, { createdAt: "desc" }], }); return orders.map((order) => ({ id: order.id, documentNumber: order.documentNumber, customerName: order.customer.name, status: order.status, total: order.lines.reduce((sum, line) => sum + line.quantity * line.unitPrice, 0), })); } export async function listShipments(filters: { q?: string; status?: ShipmentStatus; salesOrderId?: string } = {}) { const query = filters.q?.trim(); const shipments = await prisma.shipment.findMany({ where: { ...(filters.status ? { status: filters.status } : {}), ...(filters.salesOrderId ? { salesOrderId: filters.salesOrderId } : {}), ...(query ? { OR: [ { shipmentNumber: { contains: query } }, { trackingNumber: { contains: query } }, { carrier: { contains: query } }, { salesOrder: { documentNumber: { contains: query } } }, { salesOrder: { customer: { name: { contains: query } } } }, ], } : {}), }, include: { salesOrder: { include: { customer: { select: { name: true, }, }, }, }, }, orderBy: [{ createdAt: "desc" }], }); return shipments.map((shipment) => mapShipment(shipment)); } export async function getShipmentById(shipmentId: string) { const shipment = await prisma.shipment.findUnique({ where: { id: shipmentId }, include: { salesOrder: { include: { customer: { select: { name: true, }, }, }, }, }, }); return shipment ? mapShipment(shipment) : null; } export async function createShipment(payload: ShipmentInput) { const order = await prisma.salesOrder.findUnique({ where: { id: payload.salesOrderId }, select: { id: true }, }); if (!order) { return { ok: false as const, reason: "Sales order was not found." }; } const shipmentNumber = await nextShipmentNumber(); const shipment = await prisma.shipment.create({ data: { shipmentNumber, salesOrderId: payload.salesOrderId, status: payload.status, shipDate: payload.shipDate ? new Date(payload.shipDate) : null, carrier: payload.carrier.trim(), serviceLevel: payload.serviceLevel.trim(), trackingNumber: payload.trackingNumber.trim(), packageCount: payload.packageCount, notes: payload.notes, }, select: { id: true }, }); const detail = await getShipmentById(shipment.id); return detail ? { ok: true as const, shipment: detail } : { ok: false as const, reason: "Unable to load saved shipment." }; } export async function updateShipment(shipmentId: string, payload: ShipmentInput) { const existing = await prisma.shipment.findUnique({ where: { id: shipmentId }, select: { id: true }, }); if (!existing) { return { ok: false as const, reason: "Shipment was not found." }; } const order = await prisma.salesOrder.findUnique({ where: { id: payload.salesOrderId }, select: { id: true }, }); if (!order) { return { ok: false as const, reason: "Sales order was not found." }; } await prisma.shipment.update({ where: { id: shipmentId }, data: { salesOrderId: payload.salesOrderId, status: payload.status, shipDate: payload.shipDate ? new Date(payload.shipDate) : null, carrier: payload.carrier.trim(), serviceLevel: payload.serviceLevel.trim(), trackingNumber: payload.trackingNumber.trim(), packageCount: payload.packageCount, notes: payload.notes, }, select: { id: true }, }); const detail = await getShipmentById(shipmentId); return detail ? { ok: true as const, shipment: detail } : { ok: false as const, reason: "Unable to load saved shipment." }; } export async function updateShipmentStatus(shipmentId: string, status: ShipmentStatus) { const existing = await prisma.shipment.findUnique({ where: { id: shipmentId }, select: { id: true }, }); if (!existing) { return { ok: false as const, reason: "Shipment was not found." }; } await prisma.shipment.update({ where: { id: shipmentId }, data: { status }, select: { id: true }, }); const detail = await getShipmentById(shipmentId); return detail ? { ok: true as const, shipment: detail } : { ok: false as const, reason: "Unable to load updated shipment." }; }