98 lines
3.1 KiB
TypeScript
98 lines
3.1 KiB
TypeScript
import { db } from '../db/db_index'
|
|
import { cartItems, productSkus } from '../db/schema'
|
|
import { and, eq, sql } from 'drizzle-orm'
|
|
import type { UserCartItem } from '@packages/shared'
|
|
import { composeSkuName, composeUnitNotation } from '../lib/sku-features'
|
|
|
|
const getStringArray = (value: unknown): string[] => {
|
|
if (!Array.isArray(value)) return []
|
|
return value.map((item) => String(item))
|
|
}
|
|
|
|
export async function getCartItemsWithProducts(userId: number): Promise<UserCartItem[]> {
|
|
const cartItemsWithProducts = await db.query.cartItems.findMany({
|
|
where: eq(cartItems.userId, userId),
|
|
with: {
|
|
sku: {
|
|
with: {
|
|
product: true,
|
|
features: true,
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
return cartItemsWithProducts
|
|
.filter((item) => item.sku && !item.sku.isSuspended)
|
|
.map((item) => {
|
|
const sku = item.sku
|
|
const features = sku?.features || []
|
|
const priceValue = sku?.price ?? '0'
|
|
const quantityValue = item.quantity ?? '0'
|
|
return {
|
|
id: item.id,
|
|
skuId: item.skuId,
|
|
quantity: parseFloat(quantityValue),
|
|
addedAt: item.addedAt,
|
|
product: {
|
|
id: sku?.id ?? 0,
|
|
name: composeSkuName(sku?.product?.name ?? 'Unknown', features),
|
|
price: String(priceValue),
|
|
productQuantity: 1,
|
|
unit: composeUnitNotation(features),
|
|
isOutOfStock: sku?.isOutOfStock ?? false,
|
|
images: getStringArray(sku?.images),
|
|
},
|
|
subtotal: parseFloat(String(priceValue)) * parseFloat(quantityValue),
|
|
}
|
|
})
|
|
}
|
|
|
|
export async function getProductById(skuId: number) {
|
|
return db.query.productSkus.findFirst({
|
|
where: and(eq(productSkus.id, skuId), eq(productSkus.isSuspended, false)),
|
|
})
|
|
}
|
|
|
|
export async function getCartItemByUserProduct(userId: number, skuId: number) {
|
|
return db.query.cartItems.findFirst({
|
|
where: and(eq(cartItems.userId, userId), eq(cartItems.skuId, skuId)),
|
|
})
|
|
}
|
|
|
|
export async function incrementCartItemQuantity(itemId: number, quantity: number): Promise<void> {
|
|
await db.update(cartItems)
|
|
.set({
|
|
quantity: sql`${cartItems.quantity} + ${quantity}`,
|
|
})
|
|
.where(eq(cartItems.id, itemId))
|
|
}
|
|
|
|
export async function insertCartItem(userId: number, skuId: number, quantity: number): Promise<void> {
|
|
await db.insert(cartItems).values({
|
|
userId,
|
|
skuId,
|
|
quantity: quantity.toString(),
|
|
})
|
|
}
|
|
|
|
export async function updateCartItemQuantity(userId: number, itemId: number, quantity: number) {
|
|
const [updatedItem] = await db.update(cartItems)
|
|
.set({ quantity: quantity.toString() })
|
|
.where(and(eq(cartItems.id, itemId), eq(cartItems.userId, userId)))
|
|
.returning({ id: cartItems.id })
|
|
|
|
return !!updatedItem
|
|
}
|
|
|
|
export async function deleteCartItem(userId: number, itemId: number): Promise<boolean> {
|
|
const [deletedItem] = await db.delete(cartItems)
|
|
.where(and(eq(cartItems.id, itemId), eq(cartItems.userId, userId)))
|
|
.returning({ id: cartItems.id })
|
|
|
|
return !!deletedItem
|
|
}
|
|
|
|
export async function clearUserCart(userId: number): Promise<void> {
|
|
await db.delete(cartItems).where(eq(cartItems.userId, userId))
|
|
}
|