import { db } from '../db/db_index' import { vendorSnippets, deliverySlotInfo, productInfo, orders, orderItems, orderStatus } from '../db/schema' import { desc, eq, inArray } from 'drizzle-orm' import type { InferSelectModel } from 'drizzle-orm' import type { AdminDeliverySlot, AdminVendorSnippet, AdminVendorSnippetWithSlot, AdminVendorSnippetProduct, AdminVendorUpdatePackagingResult, } from '@packages/shared' type VendorSnippetRow = InferSelectModel type DeliverySlotRow = InferSelectModel type ProductRow = InferSelectModel const mapVendorSnippet = (snippet: VendorSnippetRow): AdminVendorSnippet => ({ id: snippet.id, snippetCode: snippet.snippetCode, slotId: snippet.slotId ?? null, productIds: snippet.productIds || [], isPermanent: snippet.isPermanent, validTill: snippet.validTill ?? null, createdAt: snippet.createdAt, }) const mapDeliverySlot = (slot: DeliverySlotRow): AdminDeliverySlot => ({ id: slot.id, deliveryTime: slot.deliveryTime, freezeTime: slot.freezeTime, isActive: slot.isActive, isFlash: slot.isFlash, isCapacityFull: slot.isCapacityFull, deliverySequence: slot.deliverySequence, groupIds: slot.groupIds, }) const mapProductSummary = (product: { id: number; name: string }): AdminVendorSnippetProduct => ({ id: product.id, name: product.name, }) export async function checkVendorSnippetExists(snippetCode: string): Promise { const existingSnippet = await db.query.vendorSnippets.findFirst({ where: eq(vendorSnippets.snippetCode, snippetCode), }) return !!existingSnippet } export async function getVendorSnippetById(id: number): Promise { const snippet = await db.query.vendorSnippets.findFirst({ where: eq(vendorSnippets.id, id), with: { slot: true, }, }) if (!snippet) { return null } return { ...mapVendorSnippet(snippet), slot: snippet.slot ? mapDeliverySlot(snippet.slot) : null, } } export async function getVendorSnippetByCode(snippetCode: string): Promise { const snippet = await db.query.vendorSnippets.findFirst({ where: eq(vendorSnippets.snippetCode, snippetCode), }) return snippet ? mapVendorSnippet(snippet) : null } export async function getAllVendorSnippets(): Promise { const snippets = await db.query.vendorSnippets.findMany({ with: { slot: true, }, orderBy: desc(vendorSnippets.createdAt), }) return snippets.map((snippet: VendorSnippetRow & { slot: DeliverySlotRow | null }) => ({ ...mapVendorSnippet(snippet), slot: snippet.slot ? mapDeliverySlot(snippet.slot) : null, })) } export async function createVendorSnippet(input: { snippetCode: string slotId?: number productIds: number[] isPermanent: boolean validTill?: Date }): Promise { const [result] = await db.insert(vendorSnippets).values({ snippetCode: input.snippetCode, slotId: input.slotId, productIds: input.productIds, isPermanent: input.isPermanent, validTill: input.validTill, }).returning() return mapVendorSnippet(result) } export async function updateVendorSnippet(id: number, updates: { snippetCode?: string slotId?: number | null productIds?: number[] isPermanent?: boolean validTill?: Date | null }): Promise { const [result] = await db.update(vendorSnippets) .set(updates) .where(eq(vendorSnippets.id, id)) .returning() return result ? mapVendorSnippet(result) : null } export async function deleteVendorSnippet(id: number): Promise { const [result] = await db.delete(vendorSnippets) .where(eq(vendorSnippets.id, id)) .returning() return result ? mapVendorSnippet(result) : null } export async function getProductsByIds(productIds: number[]): Promise { const products = await db.query.productInfo.findMany({ where: inArray(productInfo.id, productIds), columns: { id: true, name: true }, }) const prods = products.map(mapProductSummary) return prods } export async function getVendorSlotById(slotId: number): Promise { const slot = await db.query.deliverySlotInfo.findFirst({ where: eq(deliverySlotInfo.id, slotId), }) return slot ? mapDeliverySlot(slot) : null } export async function getVendorOrdersBySlotId(slotId: number) { return await db.query.orders.findMany({ where: eq(orders.slotId, slotId), with: { orderItems: { with: { product: { with: { unit: true, }, }, }, }, orderStatus: true, user: true, slot: true, }, orderBy: desc(orders.createdAt), }) } export async function getVendorOrders() { return await db.query.orders.findMany({ with: { user: true, orderItems: { with: { product: { with: { unit: true, }, }, }, }, }, orderBy: desc(orders.createdAt), }) } export async function getOrderItemsByOrderIds(orderIds: number[]) { return await db.query.orderItems.findMany({ where: inArray(orderItems.orderId, orderIds), with: { product: { with: { unit: true, }, }, }, }) } export async function getOrderStatusByOrderIds(orderIds: number[]) { return await db.query.orderStatus.findMany({ where: inArray(orderStatus.orderId, orderIds), }) } export async function updateVendorOrderItemPackaging( orderItemId: number, isPackaged: boolean ): Promise { const orderItem = await db.query.orderItems.findFirst({ where: eq(orderItems.id, orderItemId), with: { order: { with: { slot: true, }, }, }, }) if (!orderItem) { return { success: false, message: 'Order item not found' } } if (!orderItem.order.slotId) { return { success: false, message: 'Order item not associated with a vendor slot' } } const snippetExists = await db.query.vendorSnippets.findFirst({ where: eq(vendorSnippets.slotId, orderItem.order.slotId), }) if (!snippetExists) { return { success: false, message: "No vendor snippet found for this order's slot" } } const [updatedItem] = await db.update(orderItems) .set({ is_packaged: isPackaged, }) .where(eq(orderItems.id, orderItemId)) .returning({ id: orderItems.id }) if (!updatedItem) { return { success: false, message: 'Failed to update packaging status' } } return { success: true, orderItemId, is_packaged: isPackaged } }