From 648a0a5d2864630c7e47b888a960e1fd61798099 Mon Sep 17 00:00:00 2001
From: shafi54 <108669266+shafi-aviz@users.noreply.github.com>
Date: Fri, 31 Jul 2026 21:54:46 +0530
Subject: [PATCH] enh
---
apps/admin-ui/app/(drawer)/products/edit.tsx | 2 +
apps/admin-ui/src/components/ProductForm.tsx | 1 +
apps/backend/src/sqliteImporter.ts | 6 +-
.../src/trpc/apis/admin-apis/apis/product.ts | 2 +
.../src/trpc/apis/admin-apis/apis/slots.ts | 2 +-
.../apis/admin-apis/apis/vendor-snippets.ts | 28 ++---
apps/user-ui/components/cart-page.tsx | 1 +
.../src/components/AddToCartDialog.tsx | 4 +-
packages/db_helper_sqlite/index.ts | 6 +-
.../src/admin-apis/product.ts | 110 ++++++++++--------
.../src/admin-apis/vendor-snippets.ts | 15 ++-
packages/db_helper_sqlite/src/db/porter.ts | 12 +-
.../db_helper_sqlite/src/user-apis/cart.ts | 72 ++++++------
.../db_helper_sqlite/src/user-apis/order.ts | 66 ++++++-----
.../db_helper_sqlite/src/user-apis/product.ts | 46 ++++----
packages/shared/types/admin.ts | 18 +--
16 files changed, 207 insertions(+), 184 deletions(-)
diff --git a/apps/admin-ui/app/(drawer)/products/edit.tsx b/apps/admin-ui/app/(drawer)/products/edit.tsx
index e343794..9cf0a7d 100644
--- a/apps/admin-ui/app/(drawer)/products/edit.tsx
+++ b/apps/admin-ui/app/(drawer)/products/edit.tsx
@@ -42,6 +42,7 @@ export default function EditProduct() {
longDescription: productData.longDescription || '',
storeId: productData.storeId || 1,
variants: (productData.skus || []).map((sku) => ({
+ id: sku.id,
name: sku.name || '',
price: sku.price || '',
marketPrice: sku.marketPrice || '',
@@ -106,6 +107,7 @@ export default function EditProduct() {
const allUrls = [...existingUrls, ...newUrls]
return {
+ id: variant.id,
name: variant.name || null,
price: parseFloat(variant.price),
marketPrice: variant.marketPrice ? parseFloat(variant.marketPrice) : undefined,
diff --git a/apps/admin-ui/src/components/ProductForm.tsx b/apps/admin-ui/src/components/ProductForm.tsx
index 7b660ca..b87a346 100644
--- a/apps/admin-ui/src/components/ProductForm.tsx
+++ b/apps/admin-ui/src/components/ProductForm.tsx
@@ -11,6 +11,7 @@ interface Attribute {
}
interface Variant {
+ id?: number
name: string
price: string
marketPrice: string
diff --git a/apps/backend/src/sqliteImporter.ts b/apps/backend/src/sqliteImporter.ts
index b55fb03..1e9fc4d 100644
--- a/apps/backend/src/sqliteImporter.ts
+++ b/apps/backend/src/sqliteImporter.ts
@@ -69,11 +69,11 @@ export {
checkProductExistsByName,
checkUnitExists,
getProductImagesById,
- createSpecialDealsForProduct,
- updateProductDeals,
+ createSpecialDealsForSku,
+ updateSkuDeals,
replaceProductTags,
mergeSkus,
- toggleProductOutOfStock,
+ toggleSkuOutOfStock,
updateSlotProducts,
getSlotProductIds,
getSlotsProductIds,
diff --git a/apps/backend/src/trpc/apis/admin-apis/apis/product.ts b/apps/backend/src/trpc/apis/admin-apis/apis/product.ts
index 0eb8a5d..55eccc6 100644
--- a/apps/backend/src/trpc/apis/admin-apis/apis/product.ts
+++ b/apps/backend/src/trpc/apis/admin-apis/apis/product.ts
@@ -310,6 +310,7 @@ export const productRouter = router({
storeId: z.number().min(1, 'Store is required'),
incrementStep: z.number().optional().default(1),
skus: z.array(z.object({
+ id: z.number().optional(),
name: z.string().optional().nullable(),
price: z.number().positive('Price must be positive'),
marketPrice: z.number().optional().nullable(),
@@ -334,6 +335,7 @@ export const productRouter = router({
const allUploadUrls: string[] = skus.flatMap((sku) => sku.images)
const skuInputs = skus.map((sku) => ({
+ id: sku.id,
name: sku.name ?? null,
price: sku.price,
marketPrice: sku.marketPrice ?? null,
diff --git a/apps/backend/src/trpc/apis/admin-apis/apis/slots.ts b/apps/backend/src/trpc/apis/admin-apis/apis/slots.ts
index 2de0549..c2e622c 100644
--- a/apps/backend/src/trpc/apis/admin-apis/apis/slots.ts
+++ b/apps/backend/src/trpc/apis/admin-apis/apis/slots.ts
@@ -209,7 +209,7 @@ export const slotsRouter = router({
});
}
- const result = await updateSlotProductsInDb(String(slotId), productIds.map(String))
+ const result = await updateSlotProductsInDb(String(slotId), skuIds.map(String))
/*
// Old implementation - direct DB queries:
diff --git a/apps/backend/src/trpc/apis/admin-apis/apis/vendor-snippets.ts b/apps/backend/src/trpc/apis/admin-apis/apis/vendor-snippets.ts
index 196671a..d077771 100644
--- a/apps/backend/src/trpc/apis/admin-apis/apis/vendor-snippets.ts
+++ b/apps/backend/src/trpc/apis/admin-apis/apis/vendor-snippets.ts
@@ -403,7 +403,7 @@ export const vendorSnippetsRouter = router({
const filteredOrders = matchingOrders.filter(order => {
const status = order.orderStatus;
if (status[0].isCancelled) return false;
- const orderProductIds = order.orderItems.map(item => item.productId);
+ const orderProductIds = order.orderItems.map(item => item.skuId);
return snippet.skuIds.some(productId => orderProductIds.includes(productId));
});
@@ -411,17 +411,17 @@ export const vendorSnippetsRouter = router({
const formattedOrders = filteredOrders.map(order => {
// Filter orderItems to only include products attached to the snippet
const attachedOrderItems = order.orderItems.filter(item =>
- snippet.skuIds.includes(item.productId)
+ snippet.skuIds.includes(item.skuId)
);
const products = attachedOrderItems.map(item => ({
orderItemId: item.id,
- productId: item.productId,
- productName: item.product.name,
+ productId: item.skuId,
+ productName: item.sku?.product?.name || 'Unknown',
quantity: parseFloat(item.quantity),
- productSize: item.product.productQuantity,
+ productSize: 1,
price: parseFloat((item.price ?? 0).toString()),
- unit: item.product.unit?.shortNotation || 'unit',
+ unit: (item.sku?.features || []).map((f: any) => f.featureValue).join(' ') || 'unit',
subtotal: parseFloat((item.price ?? 0).toString()) * parseFloat(item.quantity),
is_packaged: item.is_packaged,
is_package_verified: item.is_package_verified,
@@ -488,9 +488,9 @@ export const vendorSnippetsRouter = router({
orderDate: order.createdAt ? order.createdAt.toISOString() : new Date(0).toISOString(),
totalQuantity: order.orderItems.reduce((sum, item) => sum + parseFloat(item.quantity || '0'), 0),
products: order.orderItems.map(item => ({
- name: item.product.name,
+ name: item.sku?.product?.name || 'Unknown',
quantity: parseFloat(item.quantity || '0'),
- unit: item.product.unit?.shortNotation || 'unit',
+ unit: (item.sku?.features || []).map((f: any) => f.featureValue).join(' ') || 'unit',
})),
}))
}),
@@ -588,7 +588,7 @@ export const vendorSnippetsRouter = router({
const filteredOrders = matchingOrders.filter(order => {
const status = order.orderStatus;
if (status[0]?.isCancelled) return false;
- const orderProductIds = order.orderItems.map(item => item.productId);
+ const orderProductIds = order.orderItems.map(item => item.skuId);
return snippet.skuIds.some(productId => orderProductIds.includes(productId));
});
@@ -596,18 +596,18 @@ export const vendorSnippetsRouter = router({
const formattedOrders = filteredOrders.map(order => {
// Filter orderItems to only include products attached to the snippet
const attachedOrderItems = order.orderItems.filter(item =>
- snippet.skuIds.includes(item.productId)
+ snippet.skuIds.includes(item.skuId)
);
const products = attachedOrderItems.map(item => ({
orderItemId: item.id,
- productId: item.productId,
- productName: item.product.name,
+ productId: item.skuId,
+ productName: item.sku?.product?.name || 'Unknown',
quantity: parseFloat(item.quantity),
price: parseFloat((item.price ?? 0).toString()),
- unit: item.product.unit?.shortNotation || 'unit',
+ unit: (item.sku?.features || []).map((f: any) => f.featureValue).join(' ') || 'unit',
subtotal: parseFloat((item.price ?? 0).toString()) * parseFloat(item.quantity),
- productSize: item.product.productQuantity,
+ productSize: 1,
is_packaged: item.is_packaged,
is_package_verified: item.is_package_verified,
}));
diff --git a/apps/user-ui/components/cart-page.tsx b/apps/user-ui/components/cart-page.tsx
index c4202bb..af73daa 100644
--- a/apps/user-ui/components/cart-page.tsx
+++ b/apps/user-ui/components/cart-page.tsx
@@ -461,6 +461,7 @@ export default function CartPage({ isFlashDelivery = false }: CartPageProps) {
{(() => {
+ const unit = product?.unitNotation || '';
return unit;
})()}
diff --git a/apps/user-ui/src/components/AddToCartDialog.tsx b/apps/user-ui/src/components/AddToCartDialog.tsx
index 2f04705..b7f2d49 100644
--- a/apps/user-ui/src/components/AddToCartDialog.tsx
+++ b/apps/user-ui/src/components/AddToCartDialog.tsx
@@ -67,7 +67,7 @@ export default function AddToCartDialog() {
// Pre-select cart's slotId and quantity if item is already in cart
useEffect(() => {
if (isOpen && product) {
- const cartItem = cartData?.items?.find((item: any) => item.productId === product.id);
+ const cartItem = cartData?.items?.find((item: any) => item.skuId === product.id);
const cartQuantity = cartItem?.quantity || 0;
// Set quantity: 0 → 1, >1 → keep as is
@@ -109,7 +109,7 @@ export default function AddToCartDialog() {
.filter((slot) => dayjs(slot.freezeTime).isAfter(dayjs()));
// Find cart item for this product
- const cartItem = cartData?.items?.find((item: any) => item.productId === product?.id);
+ const cartItem = cartData?.items?.find((item: any) => item.skuId === product?.id);
// Determine if updating existing item (quantity > 1 means it's an update)
const isUpdate = (cartItem?.quantity || 0) >= 1;
diff --git a/packages/db_helper_sqlite/index.ts b/packages/db_helper_sqlite/index.ts
index f40fb44..d275d72 100644
--- a/packages/db_helper_sqlite/index.ts
+++ b/packages/db_helper_sqlite/index.ts
@@ -79,11 +79,11 @@ export {
checkProductExistsByName,
checkUnitExists,
getProductImagesById,
- createSpecialDealsForProduct,
- updateProductDeals,
+ createSpecialDealsForSku,
+ updateSkuDeals,
replaceProductTags,
mergeSkus,
- toggleProductOutOfStock,
+ toggleSkuOutOfStock,
updateSlotProducts,
getSlotProductIds,
getSlotsProductIds,
diff --git a/packages/db_helper_sqlite/src/admin-apis/product.ts b/packages/db_helper_sqlite/src/admin-apis/product.ts
index 1275a67..35637d2 100644
--- a/packages/db_helper_sqlite/src/admin-apis/product.ts
+++ b/packages/db_helper_sqlite/src/admin-apis/product.ts
@@ -109,7 +109,7 @@ const mapSku = (sku: SkuRow, features: SkuFeatureRow[] = []): AdminSku => ({
const mapSpecialDeal = (deal: SpecialDealRow): AdminSpecialDeal => ({
id: deal.id,
- productId: deal.productId,
+ skuId: deal.skuId,
quantity: String(deal.quantity ?? '0'),
price: String(deal.price ?? '0'),
validTill: deal.validTill,
@@ -298,37 +298,54 @@ export async function updateProduct(id: number, input: any): Promise skus.map((sku) => sku.id))
+ })
+ const existingSkuIdSet = new Set(existingSkus.map((s) => s.id))
- if (existingSkuIds.length > 0) {
- await db.delete(skuFeatures).where(inArray(skuFeatures.skuId, existingSkuIds))
- await db.delete(productSkus).where(inArray(productSkus.id, existingSkuIds))
- }
+ for (const sku of skus) {
+ if (sku.id != null && existingSkuIdSet.has(sku.id)) {
+ // Update existing SKU
+ await db.update(productSkus)
+ .set({
+ name: sku.name ?? null,
+ price: String(sku.price),
+ marketPrice: sku.marketPrice != null ? String(sku.marketPrice) : null,
+ images: sku.images ?? null,
+ isFlashAvailable: sku.isFlashAvailable ?? false,
+ flashPrice: sku.flashPrice != null ? String(sku.flashPrice) : null,
+ })
+ .where(eq(productSkus.id, sku.id))
- const skuRows = await db.insert(productSkus).values(
- skus.map((sku: any) => ({
- productId: id,
- name: sku.name ?? null,
- price: String(sku.price),
- marketPrice: sku.marketPrice != null ? String(sku.marketPrice) : null,
- images: sku.images ?? null,
- isFlashAvailable: sku.isFlashAvailable ?? false,
- flashPrice: sku.flashPrice != null ? String(sku.flashPrice) : null,
- }))
- ).returning()
+ await db.delete(skuFeatures).where(eq(skuFeatures.skuId, sku.id))
+ await db.insert(skuFeatures).values(
+ sku.features.map((f: any) => ({
+ skuId: sku.id,
+ featureName: f.featureName,
+ featureValue: f.featureValue,
+ }))
+ )
+ } else {
+ // Insert new SKU
+ const [newSku] = await db.insert(productSkus).values({
+ productId: id,
+ name: sku.name ?? null,
+ price: String(sku.price),
+ marketPrice: sku.marketPrice != null ? String(sku.marketPrice) : null,
+ images: sku.images ?? null,
+ isFlashAvailable: sku.isFlashAvailable ?? false,
+ flashPrice: sku.flashPrice != null ? String(sku.flashPrice) : null,
+ }).returning()
- for (let i = 0; i < skuRows.length; i++) {
- const sku = skus[i]
- await db.insert(skuFeatures).values(
- sku.features.map((f: any) => ({
- skuId: skuRows[i].id,
- featureName: f.featureName,
- featureValue: f.featureValue,
- }))
- )
+ await db.insert(skuFeatures).values(
+ sku.features.map((f: any) => ({
+ skuId: newSku.id,
+ featureName: f.featureName,
+ featureValue: f.featureValue,
+ }))
+ )
+ }
}
}
@@ -353,9 +370,9 @@ export async function updateProduct(id: number, input: any): Promise {
- const product = await db.query.productInfo.findFirst({
- where: eq(productInfo.id, id),
+export async function toggleSkuOutOfStock(id: number): Promise {
+ const product = await db.query.productSkus.findFirst({
+ where: eq(productSkus.id, id),
})
if (!product) {
@@ -363,18 +380,18 @@ export async function toggleProductOutOfStock(id: number): Promise {
@@ -386,16 +403,15 @@ export async function updateSlotProducts(slotId: string, productIds: string[]):
throw new Error(`Slot ${slotId} not found`)
}
- const currentProductIds = slot.productIds || []
- const newProductIds = productIds.map((id: string) => parseInt(id))
+ const currentSkuIds = slot.skuIds || []
+ const newSkuIds = productIds.map((id: string) => parseInt(id))
- // Simply update the productIds array
await db.update(deliverySlotInfo)
- .set({ productIds: newProductIds })
+ .set({ skuIds: newSkuIds })
.where(eq(deliverySlotInfo.id, parseInt(slotId)))
- const productsToAdd = newProductIds.filter((id: number) => !currentProductIds.includes(id))
- const productsToRemove = currentProductIds.filter((id: number) => !newProductIds.includes(id))
+ const productsToAdd = newSkuIds.filter((id: number) => !currentSkuIds.includes(id))
+ const productsToRemove = currentSkuIds.filter((id: number) => !newSkuIds.includes(id))
return {
message: 'Slot products updated successfully',
@@ -409,7 +425,7 @@ export async function getSlotProductIds(slotId: string): Promise {
where: eq(deliverySlotInfo.id, parseInt(slotId)),
})
- return slot?.productIds || []
+ return slot?.skuIds || []
}
export async function getAllUnits(): Promise {
@@ -573,7 +589,7 @@ export async function getSlotsProductIds(slotIds: number[]): Promise = {}
for (const slot of slots) {
- result[slot.id] = slot.productIds || []
+ result[slot.id] = slot.skuIds || []
}
slotIds.forEach((slotId) => {
@@ -856,8 +872,8 @@ export async function checkUnitExists(unitId: number): Promise {
}
export async function getProductImagesById(productId: number): Promise {
- const product = await db.query.productInfo.findFirst({
- where: eq(productInfo.id, productId),
+ const product = await db.query.productSkus.findFirst({
+ where: eq(productSkus.id, productId),
columns: { images: true },
})
@@ -874,7 +890,7 @@ export interface CreateSpecialDealInput {
validTill: string | Date
}
-export async function createSpecialDealsForProduct(
+export async function createSpecialDealsForSku(
productId: number,
deals: CreateSpecialDealInput[]
): Promise {
@@ -897,17 +913,17 @@ export async function createSpecialDealsForProduct(
return createdDeals.map(mapSpecialDeal)
}
-export async function updateProductDeals(
+export async function updateSkuDeals(
productId: number,
deals: CreateSpecialDealInput[]
): Promise {
if (deals.length === 0) {
- await db.delete(specialDeals).where(eq(specialDeals.productId, productId))
+ await db.delete(specialDeals).where(eq(specialDeals.skuId, productId))
return
}
const existingDeals = await db.query.specialDeals.findMany({
- where: eq(specialDeals.productId, productId),
+ where: eq(specialDeals.skuId, productId),
})
const existingDealsMap = new Map(
diff --git a/packages/db_helper_sqlite/src/admin-apis/vendor-snippets.ts b/packages/db_helper_sqlite/src/admin-apis/vendor-snippets.ts
index b32107c..07a58ef 100644
--- a/packages/db_helper_sqlite/src/admin-apis/vendor-snippets.ts
+++ b/packages/db_helper_sqlite/src/admin-apis/vendor-snippets.ts
@@ -156,9 +156,10 @@ export async function getVendorOrdersBySlotId(slotId: number) {
with: {
orderItems: {
with: {
- product: {
+ sku: {
with: {
- unit: true,
+ product: true,
+ features: true,
},
},
},
@@ -177,9 +178,10 @@ export async function getVendorOrders() {
user: true,
orderItems: {
with: {
- product: {
+ sku: {
with: {
- unit: true,
+ product: true,
+ features: true,
},
},
},
@@ -193,9 +195,10 @@ export async function getOrderItemsByOrderIds(orderIds: number[]) {
return await db.query.orderItems.findMany({
where: inArray(orderItems.orderId, orderIds),
with: {
- product: {
+ sku: {
with: {
- unit: true,
+ product: true,
+ features: true,
},
},
},
diff --git a/packages/db_helper_sqlite/src/db/porter.ts b/packages/db_helper_sqlite/src/db/porter.ts
index fcb94f9..76c08a6 100644
--- a/packages/db_helper_sqlite/src/db/porter.ts
+++ b/packages/db_helper_sqlite/src/db/porter.ts
@@ -5,7 +5,7 @@
import { db } from '@/src/db/db_index'
import {
userDetails,
- productInfo,
+ productSkus,
productTagInfo,
complaints,
} from '@/src/db/schema'
@@ -43,21 +43,21 @@ async function migrateUserDetails() {
}
async function migrateProductInfo() {
- console.log('Migrating productInfo...')
- const products = await db.select().from(productInfo).where(not(isNull(productInfo.images)))
+ console.log('Migrating productSkus...')
+ const products = await db.select().from(productSkus).where(not(isNull(productSkus.images)))
console.log(`Found ${products.length} product records with images`)
for (const product of products) {
if (product.images && Array.isArray(product.images)) {
const cleanedUrls = cleanImageUrls(product.images)
- await db.update(productInfo)
+ await db.update(productSkus)
.set({ images: cleanedUrls })
- .where(eq(productInfo.id, product.id))
+ .where(eq(productSkus.id, product.id))
}
}
- console.log('productInfo migration completed')
+ console.log('productSkus migration completed')
}
async function migrateProductTagInfo() {
diff --git a/packages/db_helper_sqlite/src/user-apis/cart.ts b/packages/db_helper_sqlite/src/user-apis/cart.ts
index 563122e..5ae13f2 100644
--- a/packages/db_helper_sqlite/src/user-apis/cart.ts
+++ b/packages/db_helper_sqlite/src/user-apis/cart.ts
@@ -1,5 +1,5 @@
import { db } from '../db/db_index'
-import { cartItems, productInfo, units } from '../db/schema'
+import { cartItems, productSkus } from '../db/schema'
import { and, eq, sql } from 'drizzle-orm'
import type { UserCartItem } from '@packages/shared'
@@ -9,55 +9,51 @@ const getStringArray = (value: unknown): string[] => {
}
export async function getCartItemsWithProducts(userId: number): Promise {
- const cartItemsWithProducts = await db
- .select({
- cartId: cartItems.id,
- productId: productInfo.id,
- productName: productInfo.name,
- productPrice: productInfo.price,
- productImages: productInfo.images,
- productQuantity: productInfo.productQuantity,
- isOutOfStock: productInfo.isOutOfStock,
- unitShortNotation: units.shortNotation,
- quantity: cartItems.quantity,
- addedAt: cartItems.addedAt,
- })
- .from(cartItems)
- .innerJoin(productInfo, eq(cartItems.productId, productInfo.id))
- .innerJoin(units, eq(productInfo.unitId, units.id))
- .where(eq(cartItems.userId, userId))
+ const cartItemsWithProducts = await db.query.cartItems.findMany({
+ where: eq(cartItems.userId, userId),
+ with: {
+ sku: {
+ with: {
+ product: true,
+ features: true,
+ },
+ },
+ },
+ })
return cartItemsWithProducts.map((item) => {
- const priceValue = item.productPrice ?? '0'
+ const sku = item.sku
+ const features = sku?.features || []
+ const priceValue = sku?.price ?? '0'
const quantityValue = item.quantity ?? '0'
return {
- id: item.cartId,
- productId: item.productId,
+ id: item.id,
+ skuId: item.skuId,
quantity: parseFloat(quantityValue),
addedAt: item.addedAt,
- product: {
- id: item.productId,
- name: item.productName,
- price: priceValue.toString(),
- productQuantity: item.productQuantity,
- unit: item.unitShortNotation,
- isOutOfStock: item.isOutOfStock,
- images: getStringArray(item.productImages),
- },
- subtotal: parseFloat(priceValue.toString()) * parseFloat(quantityValue),
+ product: {
+ id: sku?.id ?? 0,
+ name: sku?.product?.name ?? 'Unknown',
+ price: String(priceValue),
+ productQuantity: 1,
+ unit: features.map((f) => f.featureValue).join(' '),
+ isOutOfStock: sku?.isOutOfStock ?? false,
+ images: getStringArray(sku?.images),
+ },
+ subtotal: parseFloat(String(priceValue)) * parseFloat(quantityValue),
}
})
}
-export async function getProductById(productId: number) {
- return db.query.productInfo.findFirst({
- where: eq(productInfo.id, productId),
+export async function getProductById(skuId: number) {
+ return db.query.productSkus.findFirst({
+ where: eq(productSkus.id, skuId),
})
}
-export async function getCartItemByUserProduct(userId: number, productId: number) {
+export async function getCartItemByUserProduct(userId: number, skuId: number) {
return db.query.cartItems.findFirst({
- where: and(eq(cartItems.userId, userId), eq(cartItems.productId, productId)),
+ where: and(eq(cartItems.userId, userId), eq(cartItems.skuId, skuId)),
})
}
@@ -69,10 +65,10 @@ export async function incrementCartItemQuantity(itemId: number, quantity: number
.where(eq(cartItems.id, itemId))
}
-export async function insertCartItem(userId: number, productId: number, quantity: number): Promise {
+export async function insertCartItem(userId: number, skuId: number, quantity: number): Promise {
await db.insert(cartItems).values({
userId,
- productId,
+ skuId,
quantity: quantity.toString(),
})
}
diff --git a/packages/db_helper_sqlite/src/user-apis/order.ts b/packages/db_helper_sqlite/src/user-apis/order.ts
index acc4bc9..52ded76 100644
--- a/packages/db_helper_sqlite/src/user-apis/order.ts
+++ b/packages/db_helper_sqlite/src/user-apis/order.ts
@@ -649,32 +649,32 @@ export async function getProductsForRecentOrders(
productIds: number[],
limit: number
): Promise {
- const results = await db
- .select({
- id: productInfo.id,
- name: productInfo.name,
- shortDescription: productInfo.shortDescription,
- price: productInfo.price,
- images: productInfo.images,
- isOutOfStock: productInfo.isOutOfStock,
- unitShortNotation: units.shortNotation,
- incrementStep: productInfo.incrementStep,
- })
- .from(productInfo)
- .innerJoin(units, eq(productInfo.unitId, units.id))
- .where(
- and(
- inArray(productInfo.id, productIds),
- eq(productInfo.isSuspended, false)
- )
- )
- .orderBy(desc(productInfo.createdAt))
- .limit(limit)
+ const skus = await db.query.productSkus.findMany({
+ where: and(
+ inArray(productSkus.id, productIds),
+ eq(productSkus.isSuspended, false)
+ ),
+ with: {
+ product: true,
+ features: true,
+ },
+ orderBy: desc(productSkus.createdAt),
+ limit,
+ })
- return results.map((product) => ({
- ...product,
- price: String(product.price ?? '0'),
- }))
+ return skus.map((sku) => {
+ const features = sku.features || []
+ return {
+ id: sku.id,
+ name: sku.product?.name ?? 'Unknown',
+ shortDescription: sku.product?.shortDescription ?? null,
+ price: String(sku.price ?? '0'),
+ images: sku.images,
+ isOutOfStock: sku.isOutOfStock,
+ unitShortNotation: features.map((f) => f.featureValue).join(' '),
+ incrementStep: sku.product?.incrementStep ?? 1,
+ }
+ })
}
// ============================================================================
@@ -697,8 +697,10 @@ export interface OrderWithFullData {
} | null
orderItems: Array<{
quantity: string
- product: {
- name: string
+ sku: {
+ product: {
+ name: string
+ } | null
} | null
}>
slot: {
@@ -778,9 +780,13 @@ export async function getOrderByIdWithFullData(
},
orderItems: {
with: {
- product: {
- columns: {
- name: true,
+ sku: {
+ with: {
+ product: {
+ columns: {
+ name: true,
+ },
+ },
},
},
},
diff --git a/packages/db_helper_sqlite/src/user-apis/product.ts b/packages/db_helper_sqlite/src/user-apis/product.ts
index 17d8194..6c30982 100644
--- a/packages/db_helper_sqlite/src/user-apis/product.ts
+++ b/packages/db_helper_sqlite/src/user-apis/product.ts
@@ -1,5 +1,5 @@
import { db } from '../db/db_index'
-import { deliverySlotInfo, productInfo, productSkus, productReviews, productTags, specialDeals, storeInfo, units, users } from '../db/schema'
+import { deliverySlotInfo, productInfo, productSkus, productReviews, productTags, specialDeals, storeInfo, users } from '../db/schema'
import { and, desc, eq, gt, sql } from 'drizzle-orm'
import type { UserProductDetailData, UserProductReview } from '@packages/shared'
@@ -177,30 +177,32 @@ export async function getAllProductsWithUnits(tagId?: number): Promise 0) {
- whereCondition = inArray(productInfo.id, productIds)
+ whereCondition = inArray(productSkus.productId, productIds)
}
- const results = await db
- .select({
- id: productInfo.id,
- name: productInfo.name,
- shortDescription: productInfo.shortDescription,
- price: productInfo.price,
- marketPrice: productInfo.marketPrice,
- images: productInfo.images,
- isOutOfStock: productInfo.isOutOfStock,
- unitShortNotation: units.shortNotation,
- productQuantity: productInfo.productQuantity,
- })
- .from(productInfo)
- .innerJoin(units, eq(productInfo.unitId, units.id))
- .where(whereCondition)
+ const skus = await db.query.productSkus.findMany({
+ where: whereCondition,
+ with: {
+ product: true,
+ features: true,
+ },
+ })
- return results.map((product) => ({
- ...product,
- price: String(product.price ?? '0'),
- marketPrice: product.marketPrice ? String(product.marketPrice) : null,
- }))
+ return skus.map((sku) => {
+ const features = sku.features || []
+ return {
+ id: sku.product?.id ?? 0,
+ name: sku.product?.name ?? 'Unknown',
+ skuId: sku.id,
+ skuName: sku.name ?? null,
+ shortDescription: sku.product?.shortDescription ?? null,
+ price: String(sku.price ?? '0'),
+ marketPrice: sku.marketPrice ? String(sku.marketPrice) : null,
+ images: sku.images,
+ isOutOfStock: sku.isOutOfStock,
+ features: features.map((f) => ({ featureName: f.featureName, featureValue: f.featureValue })),
+ }
+ })
}
/**
diff --git a/packages/shared/types/admin.ts b/packages/shared/types/admin.ts
index 809df52..72e64a6 100644
--- a/packages/shared/types/admin.ts
+++ b/packages/shared/types/admin.ts
@@ -372,13 +372,7 @@ export interface AdminSkuVariant {
export interface AdminSku {
id: number
productId: number
- productName?: string
- skuCode: string | null
- displayName: string
- unitId: number
- unit?: AdminUnit
- productQuantity: number
- incrementStep: number
+ name: string | null
price: string
marketPrice: string | null
images: string[] | null
@@ -387,11 +381,9 @@ export interface AdminSku {
isSuspended: boolean
isFlashAvailable: boolean
flashPrice: string | null
- isComboOnly: boolean
- sortOrder: number
- isDefault: boolean
createdAt: Date
- variants: AdminSkuVariant[]
+ features: AdminSkuFeature[]
+}
}
export interface AdminProduct {
@@ -443,6 +435,8 @@ export interface CreateProductInput {
incrementStep?: number
skus: CreateSkuInput[]
}
+
+export interface AdminProductTagInfo {
id: number;
tagName: string;
tagDescription: string | null;
@@ -465,7 +459,7 @@ export interface AdminProductTagWithProducts extends AdminProductTagInfo {
export interface AdminSpecialDeal {
id: number;
- productId: number;
+ skuId: number;
quantity: string;
price: string;
validTill: Date;