250 lines
6.6 KiB
TypeScript
250 lines
6.6 KiB
TypeScript
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<typeof vendorSnippets>
|
|
type DeliverySlotRow = InferSelectModel<typeof deliverySlotInfo>
|
|
type ProductRow = InferSelectModel<typeof productInfo>
|
|
|
|
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<boolean> {
|
|
const existingSnippet = await db.query.vendorSnippets.findFirst({
|
|
where: eq(vendorSnippets.snippetCode, snippetCode),
|
|
})
|
|
return !!existingSnippet
|
|
}
|
|
|
|
export async function getVendorSnippetById(id: number): Promise<AdminVendorSnippetWithSlot | null> {
|
|
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<AdminVendorSnippet | null> {
|
|
const snippet = await db.query.vendorSnippets.findFirst({
|
|
where: eq(vendorSnippets.snippetCode, snippetCode),
|
|
})
|
|
|
|
return snippet ? mapVendorSnippet(snippet) : null
|
|
}
|
|
|
|
export async function getAllVendorSnippets(): Promise<AdminVendorSnippetWithSlot[]> {
|
|
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<AdminVendorSnippet> {
|
|
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<AdminVendorSnippet | null> {
|
|
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<AdminVendorSnippet | null> {
|
|
const [result] = await db.delete(vendorSnippets)
|
|
.where(eq(vendorSnippets.id, id))
|
|
.returning()
|
|
|
|
return result ? mapVendorSnippet(result) : null
|
|
}
|
|
|
|
export async function getProductsByIds(productIds: number[]): Promise<AdminVendorSnippetProduct[]> {
|
|
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<AdminDeliverySlot | null> {
|
|
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<AdminVendorUpdatePackagingResult> {
|
|
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 }
|
|
}
|