138 lines
3.7 KiB
TypeScript
138 lines
3.7 KiB
TypeScript
import { db } from '@/src/db/db_index'
|
|
import { productInfo, units, productSlots, deliverySlotInfo, specialDeals, storeInfo, productReviews, users } from '@/src/db/schema'
|
|
import { eq, and, gt, sql, desc } from 'drizzle-orm'
|
|
|
|
/**
|
|
* Get product basic info with unit
|
|
*/
|
|
export async function getProductWithUnit(productId: number) {
|
|
return db
|
|
.select({
|
|
id: productInfo.id,
|
|
name: productInfo.name,
|
|
shortDescription: productInfo.shortDescription,
|
|
longDescription: productInfo.longDescription,
|
|
price: productInfo.price,
|
|
marketPrice: productInfo.marketPrice,
|
|
images: productInfo.images,
|
|
isOutOfStock: productInfo.isOutOfStock,
|
|
storeId: productInfo.storeId,
|
|
unitShortNotation: units.shortNotation,
|
|
incrementStep: productInfo.incrementStep,
|
|
productQuantity: productInfo.productQuantity,
|
|
isFlashAvailable: productInfo.isFlashAvailable,
|
|
flashPrice: productInfo.flashPrice,
|
|
})
|
|
.from(productInfo)
|
|
.innerJoin(units, eq(productInfo.unitId, units.id))
|
|
.where(eq(productInfo.id, productId))
|
|
.limit(1)
|
|
}
|
|
|
|
/**
|
|
* Get store info by ID
|
|
*/
|
|
export async function getStoreById(storeId: number) {
|
|
return db.query.storeInfo.findFirst({
|
|
where: eq(storeInfo.id, storeId),
|
|
columns: { id: true, name: true, description: true },
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Get delivery slots for product
|
|
*/
|
|
export async function getProductDeliverySlots(productId: number) {
|
|
return db
|
|
.select({
|
|
id: deliverySlotInfo.id,
|
|
deliveryTime: deliverySlotInfo.deliveryTime,
|
|
freezeTime: deliverySlotInfo.freezeTime,
|
|
})
|
|
.from(productSlots)
|
|
.innerJoin(deliverySlotInfo, eq(productSlots.slotId, deliverySlotInfo.id))
|
|
.where(
|
|
and(
|
|
eq(productSlots.productId, productId),
|
|
eq(deliverySlotInfo.isActive, true),
|
|
gt(deliverySlotInfo.deliveryTime, sql`NOW()`),
|
|
gt(deliverySlotInfo.freezeTime, sql`NOW()`)
|
|
)
|
|
)
|
|
.orderBy(deliverySlotInfo.deliveryTime)
|
|
}
|
|
|
|
/**
|
|
* Get special deals for product
|
|
*/
|
|
export async function getProductSpecialDeals(productId: number) {
|
|
return db
|
|
.select({
|
|
quantity: specialDeals.quantity,
|
|
price: specialDeals.price,
|
|
validTill: specialDeals.validTill,
|
|
})
|
|
.from(specialDeals)
|
|
.where(
|
|
and(
|
|
eq(specialDeals.productId, productId),
|
|
gt(specialDeals.validTill, sql`NOW()`)
|
|
)
|
|
)
|
|
.orderBy(specialDeals.quantity)
|
|
}
|
|
|
|
/**
|
|
* Get product reviews with user info
|
|
*/
|
|
export async function getProductReviews(productId: number, limit: number, offset: number) {
|
|
return db
|
|
.select({
|
|
id: productReviews.id,
|
|
reviewBody: productReviews.reviewBody,
|
|
ratings: productReviews.ratings,
|
|
imageUrls: productReviews.imageUrls,
|
|
reviewTime: productReviews.reviewTime,
|
|
userName: users.name,
|
|
})
|
|
.from(productReviews)
|
|
.innerJoin(users, eq(productReviews.userId, users.id))
|
|
.where(eq(productReviews.productId, productId))
|
|
.orderBy(desc(productReviews.reviewTime))
|
|
.limit(limit)
|
|
.offset(offset)
|
|
}
|
|
|
|
/**
|
|
* Count reviews for product
|
|
*/
|
|
export async function countProductReviews(productId: number) {
|
|
const result = await db
|
|
.select({ count: sql`count(*)` })
|
|
.from(productReviews)
|
|
.where(eq(productReviews.productId, productId))
|
|
|
|
return Number(result[0].count)
|
|
}
|
|
|
|
/**
|
|
* Check if product exists
|
|
*/
|
|
export async function checkProductExists(productId: number) {
|
|
return db.query.productInfo.findFirst({
|
|
where: eq(productInfo.id, productId),
|
|
})
|
|
}
|
|
|
|
/**
|
|
* Insert new review
|
|
*/
|
|
export async function insertReview(data: {
|
|
userId: number
|
|
productId: number
|
|
reviewBody: string
|
|
ratings: number
|
|
imageUrls: string[]
|
|
}) {
|
|
return db.insert(productReviews).values(data).returning()
|
|
}
|