enh
This commit is contained in:
parent
faea152d5d
commit
5591afb57f
31 changed files with 0 additions and 2700 deletions
|
|
@ -56,102 +56,3 @@ export const getAllProductsSummary = async (c: Context) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { eq, gt, and, sql, inArray } from "drizzle-orm";
|
|
||||||
import { db } from "@/src/db/db_index"
|
|
||||||
import { productInfo, units, productSlots, deliverySlotInfo, productTags } from "@/src/db/schema"
|
|
||||||
|
|
||||||
const getNextDeliveryDate = async (productId: number): Promise<Date | null> => {
|
|
||||||
const result = await db
|
|
||||||
.select({ deliveryTime: deliverySlotInfo.deliveryTime })
|
|
||||||
.from(productSlots)
|
|
||||||
.innerJoin(deliverySlotInfo, eq(productSlots.slotId, deliverySlotInfo.id))
|
|
||||||
.where(
|
|
||||||
and(
|
|
||||||
eq(productSlots.productId, productId),
|
|
||||||
eq(deliverySlotInfo.isActive, true),
|
|
||||||
gt(deliverySlotInfo.deliveryTime, sql`NOW()`)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
.orderBy(deliverySlotInfo.deliveryTime)
|
|
||||||
.limit(1);
|
|
||||||
|
|
||||||
return result[0]?.deliveryTime || null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const getAllProductsSummary = async (req: Request, res: Response) => {
|
|
||||||
try {
|
|
||||||
const { tagId } = req.query;
|
|
||||||
const tagIdNum = tagId ? parseInt(tagId as string) : null;
|
|
||||||
|
|
||||||
let productIds: number[] | null = null;
|
|
||||||
|
|
||||||
// If tagId is provided, get products that have this tag
|
|
||||||
if (tagIdNum) {
|
|
||||||
const taggedProducts = await db
|
|
||||||
.select({ productId: productTags.productId })
|
|
||||||
.from(productTags)
|
|
||||||
.where(eq(productTags.tagId, tagIdNum));
|
|
||||||
|
|
||||||
productIds = taggedProducts.map(tp => tp.productId);
|
|
||||||
}
|
|
||||||
|
|
||||||
let whereCondition = undefined;
|
|
||||||
|
|
||||||
// Filter by product IDs if tag filtering is applied
|
|
||||||
if (productIds && productIds.length > 0) {
|
|
||||||
whereCondition = inArray(productInfo.id, productIds);
|
|
||||||
} else if (tagIdNum) {
|
|
||||||
// If tagId was provided but no products found, return empty array
|
|
||||||
return res.status(200).json({
|
|
||||||
products: [],
|
|
||||||
count: 0,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const productsWithUnits = 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);
|
|
||||||
|
|
||||||
// Generate signed URLs for product images
|
|
||||||
const formattedProducts = await Promise.all(
|
|
||||||
productsWithUnits.map(async (product) => {
|
|
||||||
const nextDeliveryDate = await getNextDeliveryDate(product.id);
|
|
||||||
return {
|
|
||||||
id: product.id,
|
|
||||||
name: product.name,
|
|
||||||
shortDescription: product.shortDescription,
|
|
||||||
price: product.price,
|
|
||||||
marketPrice: product.marketPrice,
|
|
||||||
unit: product.unitShortNotation,
|
|
||||||
productQuantity: product.productQuantity,
|
|
||||||
isOutOfStock: product.isOutOfStock,
|
|
||||||
nextDeliveryDate: nextDeliveryDate ? nextDeliveryDate.toISOString() : null,
|
|
||||||
images: scaffoldAssetUrl((product.images as string[]) || []),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return res.status(200).json({
|
|
||||||
products: formattedProducts,
|
|
||||||
count: formattedProducts.length,
|
|
||||||
});
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Get products summary error:", error);
|
|
||||||
return res.status(500).json({ error: "Failed to fetch products summary" });
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -33,68 +33,3 @@ export const checkPendingPayments = async () => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { payments, orders, deliverySlotInfo, refunds } from '@/src/db/schema'
|
|
||||||
import { eq, and, gt, isNotNull } from 'drizzle-orm';
|
|
||||||
|
|
||||||
export const checkRefundStatuses = async () => {
|
|
||||||
try {
|
|
||||||
const initiatedRefunds = await db
|
|
||||||
.select()
|
|
||||||
.from(refunds)
|
|
||||||
.where(and(
|
|
||||||
eq(refunds.refundStatus, 'initiated'),
|
|
||||||
isNotNull(refunds.merchantRefundId)
|
|
||||||
));
|
|
||||||
|
|
||||||
// Process refunds concurrently using Promise.allSettled
|
|
||||||
const promises = initiatedRefunds.map(async (refund) => {
|
|
||||||
if (!refund.merchantRefundId) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const razorpayRefund = await RazorpayPaymentService.fetchRefund(refund.merchantRefundId);
|
|
||||||
|
|
||||||
if (razorpayRefund.status === 'processed') {
|
|
||||||
await db
|
|
||||||
.update(refunds)
|
|
||||||
.set({ refundStatus: 'success', refundProcessedAt: new Date() })
|
|
||||||
.where(eq(refunds.id, refund.id));
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Error checking refund ${refund.id}:`, error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// Wait for all promises to complete
|
|
||||||
await Promise.allSettled(promises);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error in checkRefundStatuses:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
export const checkPendingPayments = async () => {
|
|
||||||
try {
|
|
||||||
const pendingPayments = await db
|
|
||||||
.select({
|
|
||||||
payment: payments,
|
|
||||||
order: orders,
|
|
||||||
slot: deliverySlotInfo,
|
|
||||||
})
|
|
||||||
.from(payments)
|
|
||||||
.innerJoin(orders, eq(payments.orderId, orders.id))
|
|
||||||
.innerJoin(deliverySlotInfo, eq(orders.slotId, deliverySlotInfo.id))
|
|
||||||
.where(and(
|
|
||||||
eq(payments.status, 'pending'),
|
|
||||||
gt(deliverySlotInfo.freezeTime, new Date()) // Freeze time not passed
|
|
||||||
));
|
|
||||||
|
|
||||||
for (const record of pendingPayments) {
|
|
||||||
createPaymentNotification(record);
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error checking pending payments:', error);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -183,13 +183,6 @@ async function createBannersFileInternal(version: number): Promise<string> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function createAllStoresFilesInternal(version: number): Promise<string[]> {
|
async function createAllStoresFilesInternal(version: number): Promise<string[]> {
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { storeInfo } from '@/src/db/schema'
|
|
||||||
|
|
||||||
const stores = await db.select({ id: storeInfo.id }).from(storeInfo)
|
|
||||||
*/
|
|
||||||
|
|
||||||
const stores = await getStoresSummary()
|
const stores = await getStoresSummary()
|
||||||
const results: string[] = []
|
const results: string[] = []
|
||||||
|
|
|
||||||
|
|
@ -8,14 +8,6 @@ export const computeConstants = async (): Promise<void> => {
|
||||||
try {
|
try {
|
||||||
console.log('Computing constants from database...');
|
console.log('Computing constants from database...');
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { keyValStore } from '@/src/db/schema'
|
|
||||||
|
|
||||||
const constants = await db.select().from(keyValStore);
|
|
||||||
*/
|
|
||||||
|
|
||||||
const constants = await getAllKeyValStore();
|
const constants = await getAllKeyValStore();
|
||||||
|
|
||||||
// for (const constant of constants) {
|
// for (const constant of constants) {
|
||||||
|
|
|
||||||
|
|
@ -20,45 +20,3 @@ export const deleteOrders = async (orderIds: number[]): Promise<void> => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { orders, orderItems, orderStatus, payments, refunds, couponUsage, complaints } from '@/src/db/schema'
|
|
||||||
import { eq, inArray } from 'drizzle-orm';
|
|
||||||
|
|
||||||
export const deleteOrders = async (orderIds: number[]): Promise<void> => {
|
|
||||||
if (orderIds.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
// Delete child records first (in correct order to avoid FK constraint errors)
|
|
||||||
|
|
||||||
// 1. Delete coupon usage records
|
|
||||||
await db.delete(couponUsage).where(inArray(couponUsage.orderId, orderIds));
|
|
||||||
|
|
||||||
// 2. Delete complaints related to these orders
|
|
||||||
await db.delete(complaints).where(inArray(complaints.orderId, orderIds));
|
|
||||||
|
|
||||||
// 3. Delete refunds
|
|
||||||
await db.delete(refunds).where(inArray(refunds.orderId, orderIds));
|
|
||||||
|
|
||||||
// 4. Delete payments
|
|
||||||
await db.delete(payments).where(inArray(payments.orderId, orderIds));
|
|
||||||
|
|
||||||
// 5. Delete order status records
|
|
||||||
await db.delete(orderStatus).where(inArray(orderStatus.orderId, orderIds));
|
|
||||||
|
|
||||||
// 6. Delete order items
|
|
||||||
await db.delete(orderItems).where(inArray(orderItems.orderId, orderIds));
|
|
||||||
|
|
||||||
// 7. Finally delete the orders themselves
|
|
||||||
await db.delete(orders).where(inArray(orders.id, orderIds));
|
|
||||||
|
|
||||||
console.log(`Successfully deleted ${orderIds.length} orders and all related records`);
|
|
||||||
} catch (error) {
|
|
||||||
console.error(`Failed to delete orders ${orderIds.join(', ')}:`, error);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
|
||||||
|
|
@ -20,16 +20,6 @@ export const authenticateUser = async (c: Context, next: Next) => {
|
||||||
|
|
||||||
// Check if this is a staff token (has staffId)
|
// Check if this is a staff token (has staffId)
|
||||||
if (decoded.staffId) {
|
if (decoded.staffId) {
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { staffUsers } from '@/src/db/schema'
|
|
||||||
import { eq } from 'drizzle-orm';
|
|
||||||
|
|
||||||
const staff = await db.query.staffUsers.findFirst({
|
|
||||||
where: eq(staffUsers.id, decoded.staffId),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// This is a staff token, verify staff exists
|
// This is a staff token, verify staff exists
|
||||||
const staff = await getStaffUserById(decoded.staffId);
|
const staff = await getStaffUserById(decoded.staffId);
|
||||||
|
|
@ -46,21 +36,6 @@ export const authenticateUser = async (c: Context, next: Next) => {
|
||||||
// This is a regular user token
|
// This is a regular user token
|
||||||
c.set('user', decoded);
|
c.set('user', decoded);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { userDetails } from '@/src/db/schema'
|
|
||||||
import { eq } from 'drizzle-orm';
|
|
||||||
|
|
||||||
const details = await db.query.userDetails.findFirst({
|
|
||||||
where: eq(userDetails.userId, decoded.userId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (details?.isSuspended) {
|
|
||||||
throw new ApiError('Account suspended', 403);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Check if user is suspended
|
// Check if user is suspended
|
||||||
const suspended = await isUserSuspended(decoded.userId);
|
const suspended = await isUserSuspended(decoded.userId);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,18 +12,6 @@ export async function initializeBannerStore(): Promise<void> {
|
||||||
|
|
||||||
const banners = await getAllBannersForCache()
|
const banners = await getAllBannersForCache()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { homeBanners } from '@/src/db/schema'
|
|
||||||
import { isNotNull, asc } from 'drizzle-orm'
|
|
||||||
|
|
||||||
const banners = await db.query.homeBanners.findMany({
|
|
||||||
where: isNotNull(homeBanners.serialNum),
|
|
||||||
orderBy: asc(homeBanners.serialNum),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Store each banner in Redis
|
// Store each banner in Redis
|
||||||
// for (const banner of banners) {
|
// for (const banner of banners) {
|
||||||
// const signedImageUrl = banner.imageUrl
|
// const signedImageUrl = banner.imageUrl
|
||||||
|
|
|
||||||
|
|
@ -44,32 +44,6 @@ export async function initializeProducts(): Promise<void> {
|
||||||
// Fetch all products with full details (similar to productMega logic)
|
// Fetch all products with full details (similar to productMega logic)
|
||||||
const productsData = await getAllProductsForCache()
|
const productsData = await getAllProductsForCache()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { productInfo, units } from '@/src/db/schema'
|
|
||||||
|
|
||||||
const productsData = await 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));
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Fetch all stores
|
// Fetch all stores
|
||||||
const allStores = await getAllStoresForCache()
|
const allStores = await getAllStoresForCache()
|
||||||
const storeMap = new Map(allStores.map((s) => [s.id, s]))
|
const storeMap = new Map(allStores.map((s) => [s.id, s]))
|
||||||
|
|
|
||||||
|
|
@ -48,41 +48,9 @@ export async function initializeProductTagStore(): Promise<void> {
|
||||||
// Fetch all tags
|
// Fetch all tags
|
||||||
const tagsData = await getAllTagsForCache()
|
const tagsData = await getAllTagsForCache()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { productTagInfo } from '@/src/db/schema'
|
|
||||||
|
|
||||||
const tagsData = await db
|
|
||||||
.select({
|
|
||||||
id: productTagInfo.id,
|
|
||||||
tagName: productTagInfo.tagName,
|
|
||||||
tagDescription: productTagInfo.tagDescription,
|
|
||||||
imageUrl: productTagInfo.imageUrl,
|
|
||||||
isDashboardTag: productTagInfo.isDashboardTag,
|
|
||||||
relatedStores: productTagInfo.relatedStores,
|
|
||||||
})
|
|
||||||
.from(productTagInfo);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Fetch product IDs for each tag
|
// Fetch product IDs for each tag
|
||||||
const productTagsData = await getAllTagProductMappings()
|
const productTagsData = await getAllTagProductMappings()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { productTags } from '@/src/db/schema'
|
|
||||||
import { inArray } from 'drizzle-orm'
|
|
||||||
|
|
||||||
const tagIds = tagsData.map(t => t.id);
|
|
||||||
const productTagsData = await db
|
|
||||||
.select({
|
|
||||||
tagId: productTags.tagId,
|
|
||||||
productId: productTags.productId,
|
|
||||||
})
|
|
||||||
.from(productTags)
|
|
||||||
.where(inArray(productTags.tagId, tagIds));
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Group product IDs by tag
|
// Group product IDs by tag
|
||||||
const productIdsByTag = new Map<number, number[]>()
|
const productIdsByTag = new Map<number, number[]>()
|
||||||
for (const pt of productTagsData) {
|
for (const pt of productTagsData) {
|
||||||
|
|
|
||||||
|
|
@ -75,34 +75,6 @@ export async function initializeSlotStore(): Promise<void> {
|
||||||
// Fetch active delivery slots with future delivery times
|
// Fetch active delivery slots with future delivery times
|
||||||
const slots = await getAllSlotsWithProductsForCache()
|
const slots = await getAllSlotsWithProductsForCache()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { deliverySlotInfo } from '@/src/db/schema'
|
|
||||||
import { eq, gt, and, asc } from 'drizzle-orm'
|
|
||||||
|
|
||||||
const now = new Date();
|
|
||||||
const slots = await db.query.deliverySlotInfo.findMany({
|
|
||||||
where: and(
|
|
||||||
eq(deliverySlotInfo.isActive, true),
|
|
||||||
gt(deliverySlotInfo.deliveryTime, now),
|
|
||||||
),
|
|
||||||
with: {
|
|
||||||
productSlots: {
|
|
||||||
with: {
|
|
||||||
product: {
|
|
||||||
with: {
|
|
||||||
unit: true,
|
|
||||||
store: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
orderBy: asc(deliverySlotInfo.deliveryTime),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Transform data for storage
|
// Transform data for storage
|
||||||
const slotsWithProducts = await Promise.all(
|
const slotsWithProducts = await Promise.all(
|
||||||
slots.map(async (slot) => ({
|
slots.map(async (slot) => ({
|
||||||
|
|
|
||||||
|
|
@ -10,21 +10,6 @@ export async function initializeUserNegativityStore(): Promise<void> {
|
||||||
|
|
||||||
const results = await getAllUserNegativityScoresFromDb()
|
const results = await getAllUserNegativityScoresFromDb()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { userIncidents } from '@/src/db/schema'
|
|
||||||
import { sum } from 'drizzle-orm'
|
|
||||||
|
|
||||||
const results = await db
|
|
||||||
.select({
|
|
||||||
userId: userIncidents.userId,
|
|
||||||
totalNegativityScore: sum(userIncidents.negativityScore).mapWith(Number),
|
|
||||||
})
|
|
||||||
.from(userIncidents)
|
|
||||||
.groupBy(userIncidents.userId);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// for (const { userId, totalNegativityScore } of results) {
|
// for (const { userId, totalNegativityScore } of results) {
|
||||||
// await redisClient.set(
|
// await redisClient.set(
|
||||||
// `user:negativity:${userId}`,
|
// `user:negativity:${userId}`,
|
||||||
|
|
@ -111,23 +96,6 @@ export async function recomputeUserNegativityScore(userId: number): Promise<void
|
||||||
try {
|
try {
|
||||||
const totalScore = await getUserNegativityScoreFromDb(userId)
|
const totalScore = await getUserNegativityScoreFromDb(userId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { userIncidents } from '@/src/db/schema'
|
|
||||||
import { eq, sum } from 'drizzle-orm'
|
|
||||||
|
|
||||||
const [result] = await db
|
|
||||||
.select({
|
|
||||||
totalNegativityScore: sum(userIncidents.negativityScore).mapWith(Number),
|
|
||||||
})
|
|
||||||
.from(userIncidents)
|
|
||||||
.where(eq(userIncidents.userId, userId))
|
|
||||||
.limit(1);
|
|
||||||
|
|
||||||
const totalScore = result?.totalNegativityScore || 0;
|
|
||||||
*/
|
|
||||||
|
|
||||||
// const key = `user:negativity:${userId}`
|
// const key = `user:negativity:${userId}`
|
||||||
// await redisClient.set(key, totalScore.toString())
|
// await redisClient.set(key, totalScore.toString())
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ import {
|
||||||
} from '@/src/dbService'
|
} from '@/src/dbService'
|
||||||
import type { Banner } from '@packages/shared'
|
import type { Banner } from '@packages/shared'
|
||||||
|
|
||||||
|
|
||||||
export const bannerRouter = router({
|
export const bannerRouter = router({
|
||||||
// Get all banners
|
// Get all banners
|
||||||
getBanners: protectedProcedure
|
getBanners: protectedProcedure
|
||||||
|
|
@ -22,14 +21,6 @@ export const bannerRouter = router({
|
||||||
// Using dbService helper (new implementation)
|
// Using dbService helper (new implementation)
|
||||||
const banners = await getBannersFromDb();
|
const banners = await getBannersFromDb();
|
||||||
|
|
||||||
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
// const banners = await db.query.homeBanners.findMany({
|
|
||||||
// orderBy: desc(homeBanners.createdAt), // Order by creation date instead
|
|
||||||
// Removed product relationship since we now use skuIds array
|
|
||||||
// });
|
|
||||||
|
|
||||||
|
|
||||||
// Convert S3 keys to signed URLs for client
|
// Convert S3 keys to signed URLs for client
|
||||||
const bannersWithSignedUrls = await Promise.all(
|
const bannersWithSignedUrls = await Promise.all(
|
||||||
banners.map(async (banner) => {
|
banners.map(async (banner) => {
|
||||||
|
|
@ -69,14 +60,6 @@ export const bannerRouter = router({
|
||||||
.query(async ({ input }): Promise<Banner | null> => {
|
.query(async ({ input }): Promise<Banner | null> => {
|
||||||
// Using dbService helper (new implementation)
|
// Using dbService helper (new implementation)
|
||||||
const banner = await getBannerByIdFromDb(input.id);
|
const banner = await getBannerByIdFromDb(input.id);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const banner = await db.query.homeBanners.findFirst({
|
|
||||||
where: eq(homeBanners.id, input.id),
|
|
||||||
// Removed product relationship since we now use skuIds array
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (banner) {
|
if (banner) {
|
||||||
try {
|
try {
|
||||||
|
|
@ -122,20 +105,6 @@ export const bannerRouter = router({
|
||||||
isActive: false, // Default to inactive
|
isActive: false, // Default to inactive
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const imageUrl = extractKeyFromPresignedUrl(input.imageUrl)
|
|
||||||
const [banner] = await db.insert(homeBanners).values({
|
|
||||||
name: input.name,
|
|
||||||
imageUrl: imageUrl,
|
|
||||||
description: input.description,
|
|
||||||
skuIds: input.skuIds || [],
|
|
||||||
redirectUrl: input.redirectUrl,
|
|
||||||
serialNum: 999, // Default value, not used
|
|
||||||
isActive: false, // Default to inactive
|
|
||||||
}).returning();
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
// Reinitialize stores to reflect changes
|
||||||
await scheduleStoreInitialization()
|
await scheduleStoreInitialization()
|
||||||
|
|
||||||
|
|
@ -178,31 +147,6 @@ export const bannerRouter = router({
|
||||||
|
|
||||||
const banner = await updateBannerInDb(id, processedData);
|
const banner = await updateBannerInDb(id, processedData);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const { id, ...updateData } = input;
|
|
||||||
const incomingProductIds = input.skuIds;
|
|
||||||
// Extract S3 key from presigned URL if imageUrl is provided
|
|
||||||
const processedData = {
|
|
||||||
...updateData,
|
|
||||||
...(updateData.imageUrl && {
|
|
||||||
imageUrl: extractKeyFromPresignedUrl(updateData.imageUrl)
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Handle serialNum null case
|
|
||||||
const finalData: any = { ...processedData };
|
|
||||||
if ('serialNum' in finalData && finalData.serialNum === null) {
|
|
||||||
// Set to null explicitly
|
|
||||||
finalData.serialNum = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [banner] = await db.update(homeBanners)
|
|
||||||
.set({ ...finalData, lastUpdated: new Date(), })
|
|
||||||
.where(eq(homeBanners.id, id))
|
|
||||||
.returning();
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
// Reinitialize stores to reflect changes
|
||||||
await scheduleStoreInitialization()
|
await scheduleStoreInitialization()
|
||||||
|
|
||||||
|
|
@ -220,11 +164,6 @@ export const bannerRouter = router({
|
||||||
// Using dbService helper (new implementation)
|
// Using dbService helper (new implementation)
|
||||||
await deleteBannerFromDb(input.id);
|
await deleteBannerFromDb(input.id);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
await db.delete(homeBanners).where(eq(homeBanners.id, input.id));
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
// Reinitialize stores to reflect changes
|
||||||
await scheduleStoreInitialization()
|
await scheduleStoreInitialization()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,36 +36,6 @@ export const complaintRouter = router({
|
||||||
// Using dbService helper (new implementation)
|
// Using dbService helper (new implementation)
|
||||||
const { complaints: complaintsData, hasMore } = await getComplaintsFromDb(cursor, limit);
|
const { complaints: complaintsData, hasMore } = await getComplaintsFromDb(cursor, limit);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const { cursor, limit } = input;
|
|
||||||
|
|
||||||
let whereCondition = cursor
|
|
||||||
? lt(complaints.id, cursor)
|
|
||||||
: undefined;
|
|
||||||
|
|
||||||
const complaintsData = await db
|
|
||||||
.select({
|
|
||||||
id: complaints.id,
|
|
||||||
complaintBody: complaints.complaintBody,
|
|
||||||
userId: complaints.userId,
|
|
||||||
orderId: complaints.orderId,
|
|
||||||
isResolved: complaints.isResolved,
|
|
||||||
createdAt: complaints.createdAt,
|
|
||||||
userName: users.name,
|
|
||||||
userMobile: users.mobile,
|
|
||||||
images: complaints.images,
|
|
||||||
})
|
|
||||||
.from(complaints)
|
|
||||||
.leftJoin(users, eq(complaints.userId, users.id))
|
|
||||||
.where(whereCondition)
|
|
||||||
.orderBy(desc(complaints.id))
|
|
||||||
.limit(limit + 1);
|
|
||||||
|
|
||||||
const hasMore = complaintsData.length > limit;
|
|
||||||
const complaintsToReturn = hasMore ? complaintsData.slice(0, limit) : complaintsData;
|
|
||||||
*/
|
|
||||||
|
|
||||||
const complaintsToReturn = hasMore ? complaintsData.slice(0, limit) : complaintsData;
|
const complaintsToReturn = hasMore ? complaintsData.slice(0, limit) : complaintsData;
|
||||||
|
|
||||||
const complaintsWithImageUrls = complaintsToReturn.map((c: ComplaintWithUser) => {
|
const complaintsWithImageUrls = complaintsToReturn.map((c: ComplaintWithUser) => {
|
||||||
|
|
@ -132,14 +102,6 @@ export const complaintRouter = router({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
await db
|
|
||||||
.update(complaints)
|
|
||||||
.set({ isResolved: true, response: input.response })
|
|
||||||
.where(eq(complaints.id, parseInt(input.id)));
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { message: 'Complaint resolved successfully' };
|
return { message: 'Complaint resolved successfully' };
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,16 +18,6 @@ export const constRouter = router({
|
||||||
// Using dbService helper (new implementation)
|
// Using dbService helper (new implementation)
|
||||||
const constants = await getAllConstantsFromDb();
|
const constants = await getAllConstantsFromDb();
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const constants = await db.select().from(keyValStore);
|
|
||||||
|
|
||||||
const resp = constants.map(c => ({
|
|
||||||
key: c.key,
|
|
||||||
value: c.value,
|
|
||||||
}));
|
|
||||||
*/
|
|
||||||
|
|
||||||
return constants;
|
return constants;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -54,20 +44,6 @@ export const constRouter = router({
|
||||||
// Using dbService helper (new implementation)
|
// Using dbService helper (new implementation)
|
||||||
await upsertConstantsInDb(constants);
|
await upsertConstantsInDb(constants);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
await db.transaction(async (tx) => {
|
|
||||||
for (const { key, value } of constants) {
|
|
||||||
await tx.insert(keyValStore)
|
|
||||||
.values({ key, value })
|
|
||||||
.onConflictDoUpdate({
|
|
||||||
target: keyValStore.key,
|
|
||||||
set: { value },
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Refresh all constants in Redis after database update
|
// Refresh all constants in Redis after database update
|
||||||
await computeConstants();
|
await computeConstants();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -207,44 +207,6 @@ export const couponRouter = router({
|
||||||
updates.applicableProducts
|
updates.applicableProducts
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const result = await db.update(coupons)
|
|
||||||
.set(updateData)
|
|
||||||
.where(eq(coupons.id, id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (result.length === 0) {
|
|
||||||
throw new Error("Coupon not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update applicable users: delete existing and insert new
|
|
||||||
if (updates.applicableUsers !== undefined) {
|
|
||||||
await db.delete(couponApplicableUsers).where(eq(couponApplicableUsers.couponId, id));
|
|
||||||
if (updates.applicableUsers.length > 0) {
|
|
||||||
await db.insert(couponApplicableUsers).values(
|
|
||||||
updates.applicableUsers.map(userId => ({
|
|
||||||
couponId: id,
|
|
||||||
userId,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update applicable products: delete existing and insert new
|
|
||||||
if (updates.applicableProducts !== undefined) {
|
|
||||||
await db.delete(couponApplicableProducts).where(eq(couponApplicableProducts.couponId, id));
|
|
||||||
if (updates.applicableProducts.length > 0) {
|
|
||||||
await db.insert(couponApplicableProducts).values(
|
|
||||||
updates.applicableProducts.map(skuId => ({
|
|
||||||
couponId: id,
|
|
||||||
skuId,
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return coupon;
|
return coupon;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -305,43 +267,6 @@ export const couponRouter = router({
|
||||||
couponCode
|
couponCode
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query with transaction:
|
|
||||||
const coupon = await db.transaction(async (tx) => {
|
|
||||||
// Calculate expiry date (30 days from now)
|
|
||||||
const expiryDate = new Date();
|
|
||||||
expiryDate.setDate(expiryDate.getDate() + 30);
|
|
||||||
|
|
||||||
// Create the coupon
|
|
||||||
const result = await tx.insert(coupons).values({
|
|
||||||
couponCode,
|
|
||||||
isUserBased: true,
|
|
||||||
flatDiscount: orderAmount.toString(),
|
|
||||||
minOrder: orderAmount.toString(),
|
|
||||||
maxValue: orderAmount.toString(),
|
|
||||||
validTill: expiryDate,
|
|
||||||
maxLimitForUser: 1,
|
|
||||||
createdBy: staffUserId,
|
|
||||||
isApplyForAll: false,
|
|
||||||
}).returning();
|
|
||||||
|
|
||||||
const coupon = result[0];
|
|
||||||
|
|
||||||
// Insert applicable users
|
|
||||||
await tx.insert(couponApplicableUsers).values({
|
|
||||||
couponId: coupon.id,
|
|
||||||
userId: order.userId,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Update order_status with refund coupon ID
|
|
||||||
await tx.update(orderStatus)
|
|
||||||
.set({ refundCouponId: coupon.id })
|
|
||||||
.where(eq(orderStatus.orderId, orderId));
|
|
||||||
|
|
||||||
return coupon;
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
return coupon;
|
return coupon;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -471,43 +396,6 @@ export const couponRouter = router({
|
||||||
|
|
||||||
const { coupon, user } = await createCouponForUser(cleanMobile, couponCode, staffUserId);
|
const { coupon, user } = await createCouponForUser(cleanMobile, couponCode, staffUserId);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query with transaction:
|
|
||||||
// Check if user exists, create if not
|
|
||||||
let user = await db.query.users.findFirst({
|
|
||||||
where: eq(users.mobile, cleanMobile),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!user) {
|
|
||||||
const [newUser] = await db.insert(users).values({
|
|
||||||
name: null,
|
|
||||||
email: null,
|
|
||||||
mobile: cleanMobile,
|
|
||||||
}).returning();
|
|
||||||
user = newUser;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the coupon
|
|
||||||
const [coupon] = await db.insert(coupons).values({
|
|
||||||
couponCode,
|
|
||||||
isUserBased: true,
|
|
||||||
discountPercent: "20",
|
|
||||||
minOrder: "1000",
|
|
||||||
maxValue: "500",
|
|
||||||
maxLimitForUser: 1,
|
|
||||||
isApplyForAll: false,
|
|
||||||
exclusiveApply: false,
|
|
||||||
createdBy: staffUserId,
|
|
||||||
validTill: dayjs().add(90, 'days').toDate(),
|
|
||||||
}).returning();
|
|
||||||
|
|
||||||
// Associate coupon with user
|
|
||||||
await db.insert(couponApplicableUsers).values({
|
|
||||||
couponId: coupon.id,
|
|
||||||
userId: user.id,
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
coupon: {
|
coupon: {
|
||||||
|
|
|
||||||
|
|
@ -93,21 +93,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await updateOrderNotesInDb(orderId, adminNotes || null)
|
const result = await updateOrderNotesInDb(orderId, adminNotes || null)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const result = await db
|
|
||||||
.update(orders)
|
|
||||||
.set({
|
|
||||||
adminNotes: adminNotes || null,
|
|
||||||
})
|
|
||||||
.where(eq(orders.id, orderId))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (result.length === 0) {
|
|
||||||
throw new Error("Order not found");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new Error("Order not found")
|
throw new Error("Order not found")
|
||||||
}
|
}
|
||||||
|
|
@ -122,171 +107,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const orderDetails = await getOrderDetailsInDb(orderId)
|
const orderDetails = await getOrderDetailsInDb(orderId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Single optimized query with all relations
|
|
||||||
const orderData = await db.query.orders.findFirst({
|
|
||||||
where: eq(orders.id, orderId),
|
|
||||||
with: {
|
|
||||||
user: true,
|
|
||||||
address: true,
|
|
||||||
slot: true,
|
|
||||||
orderItems: {
|
|
||||||
with: {
|
|
||||||
product: {
|
|
||||||
with: {
|
|
||||||
unit: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
payment: true,
|
|
||||||
paymentInfo: true,
|
|
||||||
orderStatus: true,
|
|
||||||
refunds: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!orderData) {
|
|
||||||
throw new Error("Order not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get coupon usage for this specific order using new orderId field
|
|
||||||
const couponUsageData = await db.query.couponUsage.findMany({
|
|
||||||
where: eq(couponUsage.orderId, orderData.id),
|
|
||||||
with: {
|
|
||||||
coupon: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
let couponData = null;
|
|
||||||
if (couponUsageData.length > 0) {
|
|
||||||
// Calculate total discount from multiple coupons
|
|
||||||
let totalDiscountAmount = 0;
|
|
||||||
const orderTotal = parseFloat(orderData.totalAmount.toString());
|
|
||||||
|
|
||||||
for (const usage of couponUsageData) {
|
|
||||||
let discountAmount = 0;
|
|
||||||
|
|
||||||
if (usage.coupon.discountPercent) {
|
|
||||||
discountAmount =
|
|
||||||
(orderTotal *
|
|
||||||
parseFloat(usage.coupon.discountPercent.toString())) /
|
|
||||||
100;
|
|
||||||
} else if (usage.coupon.flatDiscount) {
|
|
||||||
discountAmount = parseFloat(usage.coupon.flatDiscount.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply max value limit if set
|
|
||||||
if (
|
|
||||||
usage.coupon.maxValue &&
|
|
||||||
discountAmount > parseFloat(usage.coupon.maxValue.toString())
|
|
||||||
) {
|
|
||||||
discountAmount = parseFloat(usage.coupon.maxValue.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
totalDiscountAmount += discountAmount;
|
|
||||||
}
|
|
||||||
|
|
||||||
couponData = {
|
|
||||||
couponCode: couponUsageData
|
|
||||||
.map((u) => u.coupon.couponCode)
|
|
||||||
.join(", "),
|
|
||||||
couponDescription: `${couponUsageData.length} coupons applied`,
|
|
||||||
discountAmount: totalDiscountAmount,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Status determination from included relation
|
|
||||||
const statusRecord = orderData.orderStatus?.[0];
|
|
||||||
let status: "pending" | "delivered" | "cancelled" = "pending";
|
|
||||||
if (statusRecord?.isCancelled) {
|
|
||||||
status = "cancelled";
|
|
||||||
} else if (statusRecord?.isDelivered) {
|
|
||||||
status = "delivered";
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always include refund data (will be null/undefined if not cancelled)
|
|
||||||
const refund = orderData.refunds?.[0];
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: orderData.id,
|
|
||||||
readableId: orderData.id,
|
|
||||||
userId: orderData.user.id,
|
|
||||||
customerName: `${orderData.user.name}`,
|
|
||||||
customerEmail: orderData.user.email,
|
|
||||||
customerMobile: orderData.user.mobile,
|
|
||||||
address: {
|
|
||||||
name: orderData.address.name,
|
|
||||||
line1: orderData.address.addressLine1,
|
|
||||||
line2: orderData.address.addressLine2,
|
|
||||||
city: orderData.address.city,
|
|
||||||
state: orderData.address.state,
|
|
||||||
pincode: orderData.address.pincode,
|
|
||||||
phone: orderData.address.phone,
|
|
||||||
},
|
|
||||||
slotInfo: orderData.slot
|
|
||||||
? {
|
|
||||||
time: orderData.slot.deliveryTime.toISOString(),
|
|
||||||
sequence: orderData.slot.deliverySequence,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
isCod: orderData.isCod,
|
|
||||||
isOnlinePayment: orderData.isOnlinePayment,
|
|
||||||
totalAmount: parseFloat(orderData.totalAmount?.toString() || '0') - parseFloat(orderData.deliveryCharge?.toString() || '0'),
|
|
||||||
deliveryCharge: parseFloat(orderData.deliveryCharge?.toString() || '0'),
|
|
||||||
adminNotes: orderData.adminNotes,
|
|
||||||
userNotes: orderData.userNotes,
|
|
||||||
createdAt: orderData.createdAt,
|
|
||||||
status,
|
|
||||||
isPackaged: statusRecord?.isPackaged || false,
|
|
||||||
isDelivered: statusRecord?.isDelivered || false,
|
|
||||||
items: orderData.orderItems.map((item) => ({
|
|
||||||
id: item.id,
|
|
||||||
name: item.product.name,
|
|
||||||
quantity: item.quantity,
|
|
||||||
productSize: item.product.productQuantity,
|
|
||||||
price: item.price,
|
|
||||||
unit: item.product.unit?.shortNotation,
|
|
||||||
amount:
|
|
||||||
parseFloat(item.price.toString()) *
|
|
||||||
parseFloat(item.quantity || "0"),
|
|
||||||
isPackaged: item.is_packaged,
|
|
||||||
isPackageVerified: item.is_package_verified,
|
|
||||||
})),
|
|
||||||
payment: orderData.payment
|
|
||||||
? {
|
|
||||||
status: orderData.payment.status,
|
|
||||||
gateway: orderData.payment.gateway,
|
|
||||||
merchantOrderId: orderData.payment.merchantOrderId,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
paymentInfo: orderData.paymentInfo
|
|
||||||
? {
|
|
||||||
status: orderData.paymentInfo.status,
|
|
||||||
gateway: orderData.paymentInfo.gateway,
|
|
||||||
merchantOrderId: orderData.paymentInfo.merchantOrderId,
|
|
||||||
}
|
|
||||||
: null,
|
|
||||||
// Cancellation details (always included, null if not cancelled)
|
|
||||||
cancelReason: statusRecord?.cancelReason || null,
|
|
||||||
cancellationReviewed: statusRecord?.cancellationReviewed || false,
|
|
||||||
isRefundDone: refund?.refundStatus === "processed" || false,
|
|
||||||
refundStatus: refund?.refundStatus as RefundStatus,
|
|
||||||
refundAmount: refund?.refundAmount
|
|
||||||
? parseFloat(refund.refundAmount.toString())
|
|
||||||
: null,
|
|
||||||
// Coupon information
|
|
||||||
couponData: couponData,
|
|
||||||
couponCode: couponData?.couponCode || null,
|
|
||||||
couponDescription: couponData?.couponDescription || null,
|
|
||||||
discountAmount: couponData?.discountAmount || null,
|
|
||||||
orderStatus: statusRecord,
|
|
||||||
refundRecord: refund,
|
|
||||||
isFlashDelivery: orderData.isFlashDelivery,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!orderDetails) {
|
if (!orderDetails) {
|
||||||
throw new Error('Order not found')
|
throw new Error('Order not found')
|
||||||
}
|
}
|
||||||
|
|
@ -301,35 +121,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await updateOrderPackagedInDb(orderId, isPackaged)
|
const result = await updateOrderPackagedInDb(orderId, isPackaged)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Update all order items to the specified packaged state
|
|
||||||
await db
|
|
||||||
.update(orderItems)
|
|
||||||
.set({ is_packaged: isPackaged })
|
|
||||||
.where(eq(orderItems.orderId, parseInt(orderId)));
|
|
||||||
|
|
||||||
// Also update the order status table for backward compatibility
|
|
||||||
if (!isPackaged) {
|
|
||||||
await db
|
|
||||||
.update(orderStatus)
|
|
||||||
.set({ isPackaged, isDelivered: false })
|
|
||||||
.where(eq(orderStatus.orderId, parseInt(orderId)));
|
|
||||||
} else {
|
|
||||||
await db
|
|
||||||
.update(orderStatus)
|
|
||||||
.set({ isPackaged })
|
|
||||||
.where(eq(orderStatus.orderId, parseInt(orderId)));
|
|
||||||
}
|
|
||||||
|
|
||||||
const order = await db.query.orders.findFirst({
|
|
||||||
where: eq(orders.id, parseInt(orderId)),
|
|
||||||
});
|
|
||||||
if (order) await sendOrderPackagedNotification(order.userId, orderId);
|
|
||||||
|
|
||||||
return { success: true };
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (result.userId) await sendOrderPackagedNotification(result.userId, orderId)
|
if (result.userId) await sendOrderPackagedNotification(result.userId, orderId)
|
||||||
|
|
||||||
return { success: true, userId: result.userId }
|
return { success: true, userId: result.userId }
|
||||||
|
|
@ -342,21 +133,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await updateOrderDeliveredInDb(orderId, isDelivered)
|
const result = await updateOrderDeliveredInDb(orderId, isDelivered)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
await db
|
|
||||||
.update(orderStatus)
|
|
||||||
.set({ isDelivered })
|
|
||||||
.where(eq(orderStatus.orderId, parseInt(orderId)));
|
|
||||||
|
|
||||||
const order = await db.query.orders.findFirst({
|
|
||||||
where: eq(orders.id, parseInt(orderId)),
|
|
||||||
});
|
|
||||||
if (order) await sendOrderDeliveredNotification(order.userId, orderId);
|
|
||||||
|
|
||||||
return { success: true };
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (result.userId) await sendOrderDeliveredNotification(result.userId, orderId)
|
if (result.userId) await sendOrderDeliveredNotification(result.userId, orderId)
|
||||||
|
|
||||||
return { success: true, userId: result.userId }
|
return { success: true, userId: result.userId }
|
||||||
|
|
@ -369,35 +145,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await updateOrderItemPackagingInDb(orderItemId, isPackaged, isPackageVerified)
|
const result = await updateOrderItemPackagingInDb(orderItemId, isPackaged, isPackageVerified)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Validate that orderItem exists
|
|
||||||
const orderItem = await db.query.orderItems.findFirst({
|
|
||||||
where: eq(orderItems.id, orderItemId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!orderItem) {
|
|
||||||
throw new ApiError("Order item not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Build update object with only provided fields
|
|
||||||
const updateData: any = {};
|
|
||||||
if (isPackaged !== undefined) {
|
|
||||||
updateData.is_packaged = isPackaged;
|
|
||||||
}
|
|
||||||
if (isPackageVerified !== undefined) {
|
|
||||||
updateData.is_package_verified = isPackageVerified;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the order item
|
|
||||||
await db
|
|
||||||
.update(orderItems)
|
|
||||||
.set(updateData)
|
|
||||||
.where(eq(orderItems.id, orderItemId));
|
|
||||||
|
|
||||||
return { success: true };
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result.updated) {
|
if (!result.updated) {
|
||||||
throw new ApiError('Order item not found', 404)
|
throw new ApiError('Order item not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -412,31 +159,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await removeDeliveryChargeInDb(orderId)
|
const result = await removeDeliveryChargeInDb(orderId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const order = await db.query.orders.findFirst({
|
|
||||||
where: eq(orders.id, orderId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!order) {
|
|
||||||
throw new Error('Order not found');
|
|
||||||
}
|
|
||||||
|
|
||||||
const currentDeliveryCharge = parseFloat(order.deliveryCharge?.toString() || '0');
|
|
||||||
const currentTotalAmount = parseFloat(order.totalAmount?.toString() || '0');
|
|
||||||
const newTotalAmount = currentTotalAmount - currentDeliveryCharge;
|
|
||||||
|
|
||||||
await db
|
|
||||||
.update(orders)
|
|
||||||
.set({
|
|
||||||
deliveryCharge: '0',
|
|
||||||
totalAmount: newTotalAmount.toString()
|
|
||||||
})
|
|
||||||
.where(eq(orders.id, orderId));
|
|
||||||
|
|
||||||
return { success: true, message: 'Delivery charge removed' };
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new Error('Order not found')
|
throw new Error('Order not found')
|
||||||
}
|
}
|
||||||
|
|
@ -451,86 +173,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await getSlotOrdersInDb(slotId)
|
const result = await getSlotOrdersInDb(slotId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const slotOrders = await db.query.orders.findMany({
|
|
||||||
where: eq(orders.slotId, parseInt(slotId)),
|
|
||||||
with: {
|
|
||||||
user: true,
|
|
||||||
address: true,
|
|
||||||
slot: true,
|
|
||||||
orderItems: {
|
|
||||||
with: {
|
|
||||||
product: {
|
|
||||||
with: {
|
|
||||||
unit: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
orderStatus: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const filteredOrders = slotOrders.filter((order) => {
|
|
||||||
const statusRecord = order.orderStatus[0];
|
|
||||||
return (
|
|
||||||
order.isCod ||
|
|
||||||
(statusRecord && statusRecord.paymentStatus === "success")
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const formattedOrders = filteredOrders.map((order) => {
|
|
||||||
const statusRecord = order.orderStatus[0]; // assuming one status per order
|
|
||||||
let status: "pending" | "delivered" | "cancelled" = "pending";
|
|
||||||
if (statusRecord?.isCancelled) {
|
|
||||||
status = "cancelled";
|
|
||||||
} else if (statusRecord?.isDelivered) {
|
|
||||||
status = "delivered";
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = order.orderItems.map((item) => ({
|
|
||||||
id: item.id,
|
|
||||||
name: item.product.name,
|
|
||||||
quantity: parseFloat(item.quantity),
|
|
||||||
price: parseFloat(item.price.toString()),
|
|
||||||
amount: parseFloat(item.quantity) * parseFloat(item.price.toString()),
|
|
||||||
unit: item.product.unit?.shortNotation || "",
|
|
||||||
isPackaged: item.is_packaged,
|
|
||||||
isPackageVerified: item.is_package_verified,
|
|
||||||
}));
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: order.id,
|
|
||||||
readableId: order.id,
|
|
||||||
customerName: order.user.name,
|
|
||||||
address: `${order.address.addressLine1}${
|
|
||||||
order.address.addressLine2 ? `, ${order.address.addressLine2}` : ""
|
|
||||||
}, ${order.address.city}, ${order.address.state} - ${
|
|
||||||
order.address.pincode
|
|
||||||
}, Phone: ${order.address.phone}`,
|
|
||||||
addressId: order.addressId,
|
|
||||||
latitude: order.address.adminLatitude ?? order.address.latitude,
|
|
||||||
longitude: order.address.adminLongitude ?? order.address.longitude,
|
|
||||||
totalAmount: parseFloat(order.totalAmount),
|
|
||||||
items,
|
|
||||||
deliveryTime: order.slot?.deliveryTime.toISOString() || null,
|
|
||||||
status,
|
|
||||||
isPackaged:
|
|
||||||
order.orderItems.every((item) => item.is_packaged) || false,
|
|
||||||
isDelivered: statusRecord?.isDelivered || false,
|
|
||||||
isCod: order.isCod,
|
|
||||||
paymentMode: order.isCod ? "COD" : "Online",
|
|
||||||
paymentStatus: statusRecord?.paymentStatus || "pending",
|
|
||||||
slotId: order.slotId,
|
|
||||||
adminNotes: order.adminNotes,
|
|
||||||
userNotes: order.userNotes,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return { success: true, data: formattedOrders };
|
|
||||||
*/
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -547,24 +189,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await updateAddressCoordsInDb(addressId, latitude, longitude)
|
const result = await updateAddressCoordsInDb(addressId, latitude, longitude)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const result = await db
|
|
||||||
.update(addresses)
|
|
||||||
.set({
|
|
||||||
adminLatitude: latitude,
|
|
||||||
adminLongitude: longitude,
|
|
||||||
})
|
|
||||||
.where(eq(addresses.id, addressId))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (result.length === 0) {
|
|
||||||
throw new ApiError("Address not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true };
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new ApiError('Address not found', 404)
|
throw new ApiError('Address not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -588,171 +212,6 @@ export const orderRouter = router({
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const {
|
|
||||||
cursor,
|
|
||||||
limit,
|
|
||||||
slotId,
|
|
||||||
packagedFilter,
|
|
||||||
deliveredFilter,
|
|
||||||
cancellationFilter,
|
|
||||||
flashDeliveryFilter,
|
|
||||||
} = input;
|
|
||||||
|
|
||||||
let whereCondition: SQL<unknown> | undefined = eq(orders.id, orders.id); // always true
|
|
||||||
if (cursor) {
|
|
||||||
whereCondition = and(whereCondition, lt(orders.id, cursor));
|
|
||||||
}
|
|
||||||
if (slotId) {
|
|
||||||
whereCondition = and(whereCondition, eq(orders.slotId, slotId));
|
|
||||||
}
|
|
||||||
if (packagedFilter === "packaged") {
|
|
||||||
whereCondition = and(
|
|
||||||
whereCondition,
|
|
||||||
eq(orderStatus.isPackaged, true)
|
|
||||||
);
|
|
||||||
} else if (packagedFilter === "not_packaged") {
|
|
||||||
whereCondition = and(
|
|
||||||
whereCondition,
|
|
||||||
eq(orderStatus.isPackaged, false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (deliveredFilter === "delivered") {
|
|
||||||
whereCondition = and(
|
|
||||||
whereCondition,
|
|
||||||
eq(orderStatus.isDelivered, true)
|
|
||||||
);
|
|
||||||
} else if (deliveredFilter === "not_delivered") {
|
|
||||||
whereCondition = and(
|
|
||||||
whereCondition,
|
|
||||||
eq(orderStatus.isDelivered, false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (cancellationFilter === "cancelled") {
|
|
||||||
whereCondition = and(
|
|
||||||
whereCondition,
|
|
||||||
eq(orderStatus.isCancelled, true)
|
|
||||||
);
|
|
||||||
} else if (cancellationFilter === "not_cancelled") {
|
|
||||||
whereCondition = and(
|
|
||||||
whereCondition,
|
|
||||||
eq(orderStatus.isCancelled, false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (flashDeliveryFilter === "flash") {
|
|
||||||
whereCondition = and(
|
|
||||||
whereCondition,
|
|
||||||
eq(orders.isFlashDelivery, true)
|
|
||||||
);
|
|
||||||
} else if (flashDeliveryFilter === "regular") {
|
|
||||||
whereCondition = and(
|
|
||||||
whereCondition,
|
|
||||||
eq(orders.isFlashDelivery, false)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const allOrders = await db.query.orders.findMany({
|
|
||||||
where: whereCondition,
|
|
||||||
orderBy: desc(orders.createdAt),
|
|
||||||
limit: limit + 1, // fetch one extra to check if there's more
|
|
||||||
with: {
|
|
||||||
user: true,
|
|
||||||
address: true,
|
|
||||||
slot: true,
|
|
||||||
orderItems: {
|
|
||||||
with: {
|
|
||||||
product: {
|
|
||||||
with: {
|
|
||||||
unit: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
orderStatus: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
const hasMore = allOrders.length > limit;
|
|
||||||
const ordersToReturn = hasMore ? allOrders.slice(0, limit) : allOrders;
|
|
||||||
|
|
||||||
const userIds = [...new Set(ordersToReturn.map(o => o.userId))];
|
|
||||||
const negativityScores = await getMultipleUserNegativityScores(userIds);
|
|
||||||
|
|
||||||
const filteredOrders = ordersToReturn.filter((order) => {
|
|
||||||
const statusRecord = order.orderStatus[0];
|
|
||||||
return (
|
|
||||||
order.isCod ||
|
|
||||||
(statusRecord && statusRecord.paymentStatus === "success")
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
const formattedOrders = filteredOrders.map((order) => {
|
|
||||||
const statusRecord = order.orderStatus[0];
|
|
||||||
let status: "pending" | "delivered" | "cancelled" = "pending";
|
|
||||||
if (statusRecord?.isCancelled) {
|
|
||||||
status = "cancelled";
|
|
||||||
} else if (statusRecord?.isDelivered) {
|
|
||||||
status = "delivered";
|
|
||||||
}
|
|
||||||
|
|
||||||
const items = order.orderItems
|
|
||||||
.map((item) => ({
|
|
||||||
id: item.id,
|
|
||||||
name: item.product.name,
|
|
||||||
quantity: parseFloat(item.quantity),
|
|
||||||
price: parseFloat(item.price.toString()),
|
|
||||||
amount:
|
|
||||||
parseFloat(item.quantity) * parseFloat(item.price.toString()),
|
|
||||||
unit: item.product.unit?.shortNotation || "",
|
|
||||||
productSize: item.product.productQuantity,
|
|
||||||
isPackaged: item.is_packaged,
|
|
||||||
isPackageVerified: item.is_package_verified,
|
|
||||||
}))
|
|
||||||
.sort((first, second) => first.id - second.id);
|
|
||||||
dayjs.extend(utc);
|
|
||||||
return {
|
|
||||||
id: order.id,
|
|
||||||
orderId: order.id.toString(),
|
|
||||||
readableId: order.id,
|
|
||||||
customerName: order.user.name,
|
|
||||||
customerMobile: order.user.mobile,
|
|
||||||
address: `${order.address.addressLine1}${
|
|
||||||
order.address.addressLine2
|
|
||||||
? `, ${order.address.addressLine2}`
|
|
||||||
: ""
|
|
||||||
}, ${order.address.city}, ${order.address.state} - ${
|
|
||||||
order.address.pincode
|
|
||||||
}, Phone: ${order.address.phone}`,
|
|
||||||
addressId: order.addressId,
|
|
||||||
latitude: order.address.adminLatitude ?? order.address.latitude,
|
|
||||||
longitude: order.address.adminLongitude ?? order.address.longitude,
|
|
||||||
totalAmount: parseFloat(order.totalAmount),
|
|
||||||
deliveryCharge: parseFloat(order.deliveryCharge || "0"),
|
|
||||||
items,
|
|
||||||
createdAt: order.createdAt,
|
|
||||||
// deliveryTime: order.slot ? dayjs.utc(order.slot.deliveryTime).format('ddd, MMM D • h:mm A') : 'Not scheduled',
|
|
||||||
deliveryTime: order.slot?.deliveryTime.toISOString() || null,
|
|
||||||
status,
|
|
||||||
isPackaged:
|
|
||||||
order.orderItems.every((item) => item.is_packaged) || false,
|
|
||||||
isDelivered: statusRecord?.isDelivered || false,
|
|
||||||
isCod: order.isCod,
|
|
||||||
isFlashDelivery: order.isFlashDelivery,
|
|
||||||
userNotes: order.userNotes,
|
|
||||||
adminNotes: order.adminNotes,
|
|
||||||
userNegativityScore: negativityScores[order.userId] || 0,
|
|
||||||
};
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
orders: formattedOrders,
|
|
||||||
nextCursor: hasMore
|
|
||||||
? ordersToReturn[ordersToReturn.length - 1].id
|
|
||||||
: undefined,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
orders,
|
orders,
|
||||||
nextCursor: result.nextCursor,
|
nextCursor: result.nextCursor,
|
||||||
|
|
@ -769,78 +228,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await rebalanceSlotsInDb(slotIds)
|
const result = await rebalanceSlotsInDb(slotIds)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const ordersList = await db.query.orders.findMany({
|
|
||||||
where: inArray(orders.slotId, slotIds),
|
|
||||||
with: {
|
|
||||||
orderItems: {
|
|
||||||
with: {
|
|
||||||
product: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
couponUsages: {
|
|
||||||
with: {
|
|
||||||
coupon: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const processedOrdersData = ordersList.map((order) => {
|
|
||||||
|
|
||||||
let newTotal = order.orderItems.reduce((acc,item) => {
|
|
||||||
const latestPrice = +item.product.price;
|
|
||||||
const amount = (latestPrice * Number(item.quantity));
|
|
||||||
return acc+amount;
|
|
||||||
},0)
|
|
||||||
|
|
||||||
order.orderItems.forEach(item => {
|
|
||||||
item.price = item.product.price;
|
|
||||||
item.discountedPrice = item.product.price
|
|
||||||
})
|
|
||||||
|
|
||||||
const coupon = order.couponUsages[0]?.coupon;
|
|
||||||
|
|
||||||
let discount = 0;
|
|
||||||
if(coupon && !coupon.isInvalidated && (!coupon.validTill || new Date(coupon.validTill) > new Date())) {
|
|
||||||
const proportion = Number(order.orderGroupProportion || 1);
|
|
||||||
if(coupon.discountPercent) {
|
|
||||||
const maxDiscount = Number(coupon.maxValue || Infinity) * proportion;
|
|
||||||
discount = Math.min((newTotal * parseFloat(coupon.discountPercent)) / 100, maxDiscount);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
discount = Number(coupon.flatDiscount) * proportion;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
newTotal -= discount
|
|
||||||
|
|
||||||
const { couponUsages, orderItems: orderItemsRaw, ...rest} = order;
|
|
||||||
const updatedOrderItems = orderItemsRaw.map(item => {
|
|
||||||
const { product, ...rawOrderItem } = item;
|
|
||||||
return rawOrderItem;
|
|
||||||
})
|
|
||||||
return {order: rest, updatedOrderItems, newTotal }
|
|
||||||
})
|
|
||||||
|
|
||||||
const updatedOrderIds: number[] = [];
|
|
||||||
await db.transaction(async (tx) => {
|
|
||||||
for (const { order, updatedOrderItems, newTotal } of processedOrdersData) {
|
|
||||||
await tx.update(orders).set({ totalAmount: newTotal.toString() }).where(eq(orders.id, order.id));
|
|
||||||
updatedOrderIds.push(order.id);
|
|
||||||
|
|
||||||
for (const item of updatedOrderItems) {
|
|
||||||
await tx.update(orderItems).set({
|
|
||||||
price: item.price,
|
|
||||||
discountedPrice: item.discountedPrice
|
|
||||||
}).where(eq(orderItems.id, item.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return { success: true, updatedOrders: updatedOrderIds, message: `Rebalanced ${updatedOrderIds.length} orders.` };
|
|
||||||
*/
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -854,61 +241,6 @@ export const orderRouter = router({
|
||||||
|
|
||||||
const result = await cancelOrderInDb(orderId, reason)
|
const result = await cancelOrderInDb(orderId, reason)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const order = await db.query.orders.findFirst({
|
|
||||||
where: eq(orders.id, orderId),
|
|
||||||
with: {
|
|
||||||
orderStatus: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!order) {
|
|
||||||
throw new ApiError("Order not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const status = order.orderStatus[0];
|
|
||||||
if (!status) {
|
|
||||||
throw new ApiError("Order status not found", 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.isCancelled) {
|
|
||||||
throw new ApiError("Order is already cancelled", 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status.isDelivered) {
|
|
||||||
throw new ApiError("Cannot cancel delivered order", 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await db.transaction(async (tx) => {
|
|
||||||
await tx
|
|
||||||
.update(orderStatus)
|
|
||||||
.set({
|
|
||||||
isCancelled: true,
|
|
||||||
isCancelledByAdmin: true,
|
|
||||||
cancelReason: reason,
|
|
||||||
cancellationAdminNotes: reason,
|
|
||||||
cancellationReviewed: true,
|
|
||||||
cancellationReviewedAt: new Date(),
|
|
||||||
})
|
|
||||||
.where(eq(orderStatus.id, status.id));
|
|
||||||
|
|
||||||
const refundStatus = order.isCod ? "na" : "pending";
|
|
||||||
|
|
||||||
await tx.insert(refunds).values({
|
|
||||||
orderId: order.id,
|
|
||||||
refundStatus,
|
|
||||||
});
|
|
||||||
|
|
||||||
return { orderId: order.id, userId: order.userId };
|
|
||||||
});
|
|
||||||
|
|
||||||
// Publish to Redis for Telegram notification
|
|
||||||
await publishCancellation(result.orderId, 'admin', reason);
|
|
||||||
|
|
||||||
return { success: true, message: "Order cancelled successfully" };
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
if (result.error === 'order_not_found') {
|
if (result.error === 'order_not_found') {
|
||||||
throw new ApiError(result.message, 404)
|
throw new ApiError(result.message, 404)
|
||||||
|
|
@ -939,16 +271,4 @@ export const orderRouter = router({
|
||||||
export async function deleteOrderById(orderId: number): Promise<void> {
|
export async function deleteOrderById(orderId: number): Promise<void> {
|
||||||
await deleteOrderByIdInDb(orderId)
|
await deleteOrderByIdInDb(orderId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
await db.transaction(async (tx) => {
|
|
||||||
await tx.delete(orderItems).where(eq(orderItems.orderId, orderId));
|
|
||||||
await tx.delete(orderStatus).where(eq(orderStatus.orderId, orderId));
|
|
||||||
await tx.delete(payments).where(eq(payments.orderId, orderId));
|
|
||||||
await tx.delete(refunds).where(eq(refunds.orderId, orderId));
|
|
||||||
await tx.delete(couponUsage).where(eq(couponUsage.orderId, orderId));
|
|
||||||
await tx.delete(complaints).where(eq(complaints.orderId, orderId));
|
|
||||||
await tx.delete(orders).where(eq(orders.id, orderId));
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -41,23 +41,11 @@ import type {
|
||||||
AdminToggleOutOfStockResult,
|
AdminToggleOutOfStockResult,
|
||||||
} from '@packages/shared'
|
} from '@packages/shared'
|
||||||
|
|
||||||
|
|
||||||
export const productRouter = router({
|
export const productRouter = router({
|
||||||
getProducts: protectedProcedure
|
getProducts: protectedProcedure
|
||||||
.query(async (): Promise<AdminProductListResponse> => {
|
.query(async (): Promise<AdminProductListResponse> => {
|
||||||
const products = await getAllProductsInDb()
|
const products = await getAllProductsInDb()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const products = await db.query.productInfo.findMany({
|
|
||||||
orderBy: productInfo.name,
|
|
||||||
with: {
|
|
||||||
unit: true,
|
|
||||||
store: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
const productsWithImageUrls = products.map((product) => ({
|
const productsWithImageUrls = products.map((product) => ({
|
||||||
...product,
|
...product,
|
||||||
skus: product.skus.map((sku) => ({
|
skus: product.skus.map((sku) => ({
|
||||||
|
|
@ -81,46 +69,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const product = await getProductByIdInDb(id)
|
const product = await getProductByIdInDb(id)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const product = await db.query.productInfo.findFirst({
|
|
||||||
where: eq(productInfo.id, id),
|
|
||||||
with: {
|
|
||||||
unit: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!product) {
|
|
||||||
throw new ApiError("Product not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch special deals for this product
|
|
||||||
const deals = await db.query.specialDeals.findMany({
|
|
||||||
where: eq(specialDeals.productId, id),
|
|
||||||
orderBy: specialDeals.quantity,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Fetch associated tags for this product
|
|
||||||
const productTagsData = await db.query.productTags.findMany({
|
|
||||||
where: eq(productTags.productId, id),
|
|
||||||
with: {
|
|
||||||
tag: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// Generate signed URLs for product images
|
|
||||||
const productWithSignedUrls = {
|
|
||||||
...product,
|
|
||||||
images: await generateSignedUrlsFromS3Urls((product.images as string[]) || []),
|
|
||||||
deals,
|
|
||||||
tags: productTagsData.map(pt => pt.tag),
|
|
||||||
};
|
|
||||||
|
|
||||||
return {
|
|
||||||
product: productWithSignedUrls,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!product) {
|
if (!product) {
|
||||||
throw new ApiError('Product not found', 404)
|
throw new ApiError('Product not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -147,18 +95,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const deletedProduct = await deleteProductInDb(id)
|
const deletedProduct = await deleteProductInDb(id)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const [deletedProduct] = await db
|
|
||||||
.delete(productInfo)
|
|
||||||
.where(eq(productInfo.id, id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (!deletedProduct) {
|
|
||||||
throw new ApiError("Product not found", 404);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!deletedProduct) {
|
if (!deletedProduct) {
|
||||||
throw new ApiError('Product not found', 404)
|
throw new ApiError('Product not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -391,47 +327,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const { reviews, totalCount } = await getProductReviewsInDb(productId, limit, offset)
|
const { reviews, totalCount } = await getProductReviewsInDb(productId, limit, offset)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const reviews = await db
|
|
||||||
.select({
|
|
||||||
id: productReviews.id,
|
|
||||||
reviewBody: productReviews.reviewBody,
|
|
||||||
ratings: productReviews.ratings,
|
|
||||||
imageUrls: productReviews.imageUrls,
|
|
||||||
reviewTime: productReviews.reviewTime,
|
|
||||||
adminResponse: productReviews.adminResponse,
|
|
||||||
adminResponseImages: productReviews.adminResponseImages,
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Generate signed URLs for images
|
|
||||||
const reviewsWithSignedUrls = await Promise.all(
|
|
||||||
reviews.map(async (review) => ({
|
|
||||||
...review,
|
|
||||||
signedImageUrls: await generateSignedUrlsFromS3Urls((review.imageUrls as string[]) || []),
|
|
||||||
signedAdminImageUrls: await generateSignedUrlsFromS3Urls((review.adminResponseImages as string[]) || []),
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check if more reviews exist
|
|
||||||
const totalCountResult = await db
|
|
||||||
.select({ count: sql`count(*)` })
|
|
||||||
.from(productReviews)
|
|
||||||
.where(eq(productReviews.productId, productId));
|
|
||||||
|
|
||||||
const totalCount = Number(totalCountResult[0].count);
|
|
||||||
const hasMore = offset + limit < totalCount;
|
|
||||||
|
|
||||||
return { reviews: reviewsWithSignedUrls, hasMore };
|
|
||||||
*/
|
|
||||||
|
|
||||||
const reviewsWithImageUrls = reviews.map((review) => ({
|
const reviewsWithImageUrls = reviews.map((review) => ({
|
||||||
...review,
|
...review,
|
||||||
signedImageUrls: scaffoldAssetUrl((review.imageUrls as string[]) || []),
|
signedImageUrls: scaffoldAssetUrl((review.imageUrls as string[]) || []),
|
||||||
|
|
@ -455,30 +350,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const updatedReview = await respondToReviewInDb(reviewId, adminResponse, adminResponseImages)
|
const updatedReview = await respondToReviewInDb(reviewId, adminResponse, adminResponseImages)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const [updatedReview] = await db
|
|
||||||
.update(productReviews)
|
|
||||||
.set({
|
|
||||||
adminResponse,
|
|
||||||
adminResponseImages,
|
|
||||||
})
|
|
||||||
.where(eq(productReviews.id, reviewId))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (!updatedReview) {
|
|
||||||
throw new ApiError('Review not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Claim upload URLs
|
|
||||||
if (uploadUrls && uploadUrls.length > 0) {
|
|
||||||
// const { claimUploadUrl } = await import('@/src/lib/s3-client');
|
|
||||||
await Promise.all(uploadUrls.map(url => claimUploadUrl(url)));
|
|
||||||
}
|
|
||||||
|
|
||||||
return { success: true, review: updatedReview };
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!updatedReview) {
|
if (!updatedReview) {
|
||||||
throw new ApiError('Review not found', 404)
|
throw new ApiError('Review not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -512,34 +383,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const newGroup = await createProductGroupInDb(group_name, description, product_ids)
|
const newGroup = await createProductGroupInDb(group_name, description, product_ids)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const [newGroup] = await db
|
|
||||||
.insert(productGroupInfo)
|
|
||||||
.values({
|
|
||||||
groupName: group_name,
|
|
||||||
description,
|
|
||||||
})
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (product_ids.length > 0) {
|
|
||||||
const memberships = product_ids.map(productId => ({
|
|
||||||
productId,
|
|
||||||
groupId: newGroup.id,
|
|
||||||
}));
|
|
||||||
|
|
||||||
await db.insert(productGroupMembership).values(memberships);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
|
||||||
await scheduleStoreInitialization()
|
|
||||||
|
|
||||||
return {
|
|
||||||
group: newGroup,
|
|
||||||
message: 'Group created successfully',
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
await scheduleStoreInitialization()
|
await scheduleStoreInitialization()
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
@ -560,46 +403,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const updatedGroup = await updateProductGroupInDb(id, group_name, description, product_ids)
|
const updatedGroup = await updateProductGroupInDb(id, group_name, description, product_ids)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const updateData: any = {};
|
|
||||||
if (group_name !== undefined) updateData.groupName = group_name;
|
|
||||||
if (description !== undefined) updateData.description = description;
|
|
||||||
|
|
||||||
const [updatedGroup] = await db
|
|
||||||
.update(productGroupInfo)
|
|
||||||
.set(updateData)
|
|
||||||
.where(eq(productGroupInfo.id, id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (!updatedGroup) {
|
|
||||||
throw new ApiError('Group not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (product_ids !== undefined) {
|
|
||||||
// Delete existing memberships
|
|
||||||
await db.delete(productGroupMembership).where(eq(productGroupMembership.groupId, id));
|
|
||||||
|
|
||||||
// Insert new memberships
|
|
||||||
if (product_ids.length > 0) {
|
|
||||||
const memberships = product_ids.map(productId => ({
|
|
||||||
productId,
|
|
||||||
groupId: id,
|
|
||||||
}));
|
|
||||||
|
|
||||||
await db.insert(productGroupMembership).values(memberships);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
|
||||||
await scheduleStoreInitialization()
|
|
||||||
|
|
||||||
return {
|
|
||||||
group: updatedGroup,
|
|
||||||
message: 'Group updated successfully',
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!updatedGroup) {
|
if (!updatedGroup) {
|
||||||
throw new ApiError('Group not found', 404)
|
throw new ApiError('Group not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -621,29 +424,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const deletedGroup = await deleteProductGroupInDb(id)
|
const deletedGroup = await deleteProductGroupInDb(id)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Delete memberships first
|
|
||||||
await db.delete(productGroupMembership).where(eq(productGroupMembership.groupId, id));
|
|
||||||
|
|
||||||
// Delete group
|
|
||||||
const [deletedGroup] = await db
|
|
||||||
.delete(productGroupInfo)
|
|
||||||
.where(eq(productGroupInfo.id, id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (!deletedGroup) {
|
|
||||||
throw new ApiError('Group not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
|
||||||
await scheduleStoreInitialization()
|
|
||||||
|
|
||||||
return {
|
|
||||||
message: 'Group deleted successfully',
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!deletedGroup) {
|
if (!deletedGroup) {
|
||||||
throw new ApiError('Group not found', 404)
|
throw new ApiError('Group not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -674,52 +454,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const result = await updateProductPricesInDb(updates)
|
const result = await updateProductPricesInDb(updates)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
if (updates.length === 0) {
|
|
||||||
throw new ApiError('No updates provided', 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate that all productIds exist
|
|
||||||
const productIds = updates.map(u => u.productId);
|
|
||||||
const existingProducts = await db.query.productInfo.findMany({
|
|
||||||
where: inArray(productInfo.id, productIds),
|
|
||||||
columns: { id: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
const existingIds = new Set(existingProducts.map(p => p.id));
|
|
||||||
const invalidIds = productIds.filter(id => !existingIds.has(id));
|
|
||||||
|
|
||||||
if (invalidIds.length > 0) {
|
|
||||||
throw new ApiError(`Invalid product IDs: ${invalidIds.join(', ')}`, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Perform batch update
|
|
||||||
const updatePromises = updates.map(async (update) => {
|
|
||||||
const { productId, price, marketPrice, flashPrice, isFlashAvailable } = update;
|
|
||||||
const updateData: any = {};
|
|
||||||
if (price !== undefined) updateData.price = price;
|
|
||||||
if (marketPrice !== undefined) updateData.marketPrice = marketPrice;
|
|
||||||
if (flashPrice !== undefined) updateData.flashPrice = flashPrice;
|
|
||||||
if (isFlashAvailable !== undefined) updateData.isFlashAvailable = isFlashAvailable;
|
|
||||||
|
|
||||||
return db
|
|
||||||
.update(productInfo)
|
|
||||||
.set(updateData)
|
|
||||||
.where(eq(productInfo.id, productId));
|
|
||||||
});
|
|
||||||
|
|
||||||
await Promise.all(updatePromises);
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
|
||||||
await scheduleStoreInitialization()
|
|
||||||
|
|
||||||
return {
|
|
||||||
message: `Updated prices for ${updates.length} product(s)`,
|
|
||||||
updatedCount: updates.length,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (result.invalidIds.length > 0) {
|
if (result.invalidIds.length > 0) {
|
||||||
throw new ApiError(`Invalid product IDs: ${result.invalidIds.join(', ')}`, 400)
|
throw new ApiError(`Invalid product IDs: ${result.invalidIds.join(', ')}`, 400)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@ import type {
|
||||||
AdminUpdateSlotCapacityResult,
|
AdminUpdateSlotCapacityResult,
|
||||||
} from '@packages/shared'
|
} from '@packages/shared'
|
||||||
|
|
||||||
|
|
||||||
interface CachedDeliverySequence {
|
interface CachedDeliverySequence {
|
||||||
[userId: string]: number[];
|
[userId: string]: number[];
|
||||||
}
|
}
|
||||||
|
|
@ -83,35 +82,6 @@ export const slotsRouter = router({
|
||||||
|
|
||||||
const slots = await getActiveSlotsWithProductsInDb(20)
|
const slots = await getActiveSlotsWithProductsInDb(20)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const slots = await db.query.deliverySlotInfo
|
|
||||||
.findMany({
|
|
||||||
where: eq(deliverySlotInfo.isActive, true),
|
|
||||||
orderBy: desc(deliverySlotInfo.deliveryTime),
|
|
||||||
with: {
|
|
||||||
productSlots: {
|
|
||||||
with: {
|
|
||||||
product: {
|
|
||||||
columns: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
images: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
.then((slots) =>
|
|
||||||
slots.map((slot) => ({
|
|
||||||
...slot,
|
|
||||||
deliverySequence: slot.deliverySequence as number[],
|
|
||||||
products: slot.productSlots.map((ps) => ps.product),
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
slots,
|
slots,
|
||||||
count: slots.length,
|
count: slots.length,
|
||||||
|
|
@ -149,68 +119,6 @@ export const slotsRouter = router({
|
||||||
groupIds,
|
groupIds,
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const result = await db.transaction(async (tx) => {
|
|
||||||
// Create slot
|
|
||||||
const [newSlot] = await tx
|
|
||||||
.insert(deliverySlotInfo)
|
|
||||||
.values({
|
|
||||||
deliveryTime: new Date(deliveryTime),
|
|
||||||
freezeTime: new Date(freezeTime),
|
|
||||||
isActive: isActive !== undefined ? isActive : true,
|
|
||||||
groupIds: groupIds !== undefined ? groupIds : [],
|
|
||||||
})
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
// Insert product associations if provided
|
|
||||||
if (productIds && productIds.length > 0) {
|
|
||||||
const associations = productIds.map((productId) => ({
|
|
||||||
productId,
|
|
||||||
slotId: newSlot.id,
|
|
||||||
}));
|
|
||||||
await tx.insert(productSlots).values(associations);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create vendor snippets if provided
|
|
||||||
let createdSnippets: any[] = [];
|
|
||||||
if (snippets && snippets.length > 0) {
|
|
||||||
for (const snippet of snippets) {
|
|
||||||
// Validate products exist
|
|
||||||
const products = await tx.query.productInfo.findMany({
|
|
||||||
where: inArray(productInfo.id, snippet.productIds),
|
|
||||||
});
|
|
||||||
if (products.length !== snippet.productIds.length) {
|
|
||||||
throw new ApiError(`One or more invalid product IDs in snippet "${snippet.name}"`, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if snippet name already exists
|
|
||||||
const existingSnippet = await tx.query.vendorSnippets.findFirst({
|
|
||||||
where: eq(vendorSnippets.snippetCode, snippet.name),
|
|
||||||
});
|
|
||||||
if (existingSnippet) {
|
|
||||||
throw new ApiError(`Snippet name "${snippet.name}" already exists`, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [createdSnippet] = await tx.insert(vendorSnippets).values({
|
|
||||||
snippetCode: snippet.name,
|
|
||||||
slotId: newSlot.id,
|
|
||||||
productIds: snippet.productIds,
|
|
||||||
validTill: snippet.validTill ? new Date(snippet.validTill) : undefined,
|
|
||||||
}).returning();
|
|
||||||
|
|
||||||
createdSnippets.push(createdSnippet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
slot: newSlot,
|
|
||||||
createdSnippets,
|
|
||||||
message: "Slot created successfully",
|
|
||||||
};
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Regenerate slots cache file (availability/products stay as-is)
|
// Regenerate slots cache file (availability/products stay as-is)
|
||||||
await createSlotsCacheFile().catch((error) => {
|
await createSlotsCacheFile().catch((error) => {
|
||||||
console.error('Failed to regenerate slots cache after slot create:', error)
|
console.error('Failed to regenerate slots cache after slot create:', error)
|
||||||
|
|
@ -235,27 +143,6 @@ export const slotsRouter = router({
|
||||||
|
|
||||||
const slot = await getSlotByIdWithRelationsInDb(id)
|
const slot = await getSlotByIdWithRelationsInDb(id)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const slot = await db.query.deliverySlotInfo.findFirst({
|
|
||||||
where: eq(deliverySlotInfo.id, id),
|
|
||||||
with: {
|
|
||||||
productSlots: {
|
|
||||||
with: {
|
|
||||||
product: {
|
|
||||||
columns: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
images: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
vendorSnippets: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!slot) {
|
if (!slot) {
|
||||||
throw new ApiError('Slot not found', 404)
|
throw new ApiError('Slot not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -300,89 +187,6 @@ export const slotsRouter = router({
|
||||||
groupIds,
|
groupIds,
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Filter groupIds to only include valid (existing) groups
|
|
||||||
let validGroupIds = groupIds;
|
|
||||||
if (groupIds && groupIds.length > 0) {
|
|
||||||
const existingGroups = await db.query.productGroupInfo.findMany({
|
|
||||||
where: inArray(productGroupInfo.id, groupIds),
|
|
||||||
columns: { id: true },
|
|
||||||
});
|
|
||||||
validGroupIds = existingGroups.map(g => g.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await db.transaction(async (tx) => {
|
|
||||||
const [updatedSlot] = await tx
|
|
||||||
.update(deliverySlotInfo)
|
|
||||||
.set({
|
|
||||||
deliveryTime: new Date(deliveryTime),
|
|
||||||
freezeTime: new Date(freezeTime),
|
|
||||||
isActive: isActive !== undefined ? isActive : true,
|
|
||||||
groupIds: validGroupIds !== undefined ? validGroupIds : [],
|
|
||||||
})
|
|
||||||
.where(eq(deliverySlotInfo.id, id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (!updatedSlot) {
|
|
||||||
throw new ApiError("Slot not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update product associations
|
|
||||||
if (productIds !== undefined) {
|
|
||||||
// Delete existing associations
|
|
||||||
await tx.delete(productSlots).where(eq(productSlots.slotId, id));
|
|
||||||
|
|
||||||
// Insert new associations
|
|
||||||
if (productIds.length > 0) {
|
|
||||||
const associations = productIds.map((productId) => ({
|
|
||||||
productId,
|
|
||||||
slotId: id,
|
|
||||||
}));
|
|
||||||
await tx.insert(productSlots).values(associations);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create vendor snippets if provided
|
|
||||||
let createdSnippets: any[] = [];
|
|
||||||
if (snippets && snippets.length > 0) {
|
|
||||||
for (const snippet of snippets) {
|
|
||||||
// Validate products exist
|
|
||||||
const products = await tx.query.productInfo.findMany({
|
|
||||||
where: inArray(productInfo.id, snippet.productIds),
|
|
||||||
});
|
|
||||||
if (products.length !== snippet.productIds.length) {
|
|
||||||
throw new ApiError(`One or more invalid product IDs in snippet "${snippet.name}"`, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if snippet name already exists
|
|
||||||
const existingSnippet = await tx.query.vendorSnippets.findFirst({
|
|
||||||
where: eq(vendorSnippets.snippetCode, snippet.name),
|
|
||||||
});
|
|
||||||
if (existingSnippet) {
|
|
||||||
throw new ApiError(`Snippet name "${snippet.name}" already exists`, 400);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [createdSnippet] = await tx.insert(vendorSnippets).values({
|
|
||||||
snippetCode: snippet.name,
|
|
||||||
slotId: id,
|
|
||||||
productIds: snippet.productIds,
|
|
||||||
validTill: snippet.validTill ? new Date(snippet.validTill) : undefined,
|
|
||||||
|
|
||||||
}).returning();
|
|
||||||
|
|
||||||
createdSnippets.push(createdSnippet);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
slot: updatedSlot,
|
|
||||||
createdSnippets,
|
|
||||||
message: "Slot updated successfully",
|
|
||||||
};
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new ApiError('Slot not found', 404)
|
throw new ApiError('Slot not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -425,19 +229,6 @@ export const slotsRouter = router({
|
||||||
// Fallback to DB
|
// Fallback to DB
|
||||||
const slot = await getSlotDeliverySequenceInDb(slotId)
|
const slot = await getSlotDeliverySequenceInDb(slotId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const slot = await db.query.deliverySlotInfo.findFirst({
|
|
||||||
where: eq(deliverySlotInfo.id, slotId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!slot) {
|
|
||||||
throw new ApiError("Slot not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const sequence = cachedSequenceSchema.parse(slot.deliverySequence || {});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!slot) {
|
if (!slot) {
|
||||||
throw new ApiError('Slot not found', 404)
|
throw new ApiError('Slot not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -466,22 +257,6 @@ export const slotsRouter = router({
|
||||||
|
|
||||||
const updatedSlot = await updateSlotDeliverySequenceInDb(id, deliverySequence)
|
const updatedSlot = await updateSlotDeliverySequenceInDb(id, deliverySequence)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const [updatedSlot] = await db
|
|
||||||
.update(deliverySlotInfo)
|
|
||||||
.set({ deliverySequence })
|
|
||||||
.where(eq(deliverySlotInfo.id, id))
|
|
||||||
.returning({
|
|
||||||
id: deliverySlotInfo.id,
|
|
||||||
deliverySequence: deliverySlotInfo.deliverySequence,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!updatedSlot) {
|
|
||||||
throw new ApiError("Slot not found", 404);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!updatedSlot) {
|
if (!updatedSlot) {
|
||||||
throw new ApiError('Slot not found', 404)
|
throw new ApiError('Slot not found', 404)
|
||||||
}
|
}
|
||||||
|
|
@ -515,28 +290,6 @@ export const slotsRouter = router({
|
||||||
|
|
||||||
const result = await updateSlotCapacityInDb(slotId, isCapacityFull)
|
const result = await updateSlotCapacityInDb(slotId, isCapacityFull)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const [updatedSlot] = await db
|
|
||||||
.update(deliverySlotInfo)
|
|
||||||
.set({ isCapacityFull })
|
|
||||||
.where(eq(deliverySlotInfo.id, slotId))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (!updatedSlot) {
|
|
||||||
throw new ApiError("Slot not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
|
||||||
await scheduleStoreInitialization()
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
slot: updatedSlot,
|
|
||||||
message: `Slot ${isCapacityFull ? 'marked as full capacity' : 'capacity reset'}`,
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new ApiError('Slot not found', 404)
|
throw new ApiError('Slot not found', 404)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -71,27 +71,6 @@ export const storeRouter = router({
|
||||||
products
|
products
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const [newStore] = await db
|
|
||||||
.insert(storeInfo)
|
|
||||||
.values({
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
imageUrl: imageKey,
|
|
||||||
owner,
|
|
||||||
})
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
// Assign selected products to this store
|
|
||||||
if (products && products.length > 0) {
|
|
||||||
await db
|
|
||||||
.update(productInfo)
|
|
||||||
.set({ storeId: newStore.id })
|
|
||||||
.where(inArray(productInfo.id, products));
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
// Reinitialize stores to reflect changes
|
||||||
await scheduleStoreInitialization()
|
await scheduleStoreInitialization()
|
||||||
|
|
||||||
|
|
@ -148,41 +127,6 @@ export const storeRouter = router({
|
||||||
products
|
products
|
||||||
);
|
);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const [updatedStore] = await db
|
|
||||||
.update(storeInfo)
|
|
||||||
.set({
|
|
||||||
name,
|
|
||||||
description,
|
|
||||||
imageUrl: newImageKey,
|
|
||||||
owner,
|
|
||||||
})
|
|
||||||
.where(eq(storeInfo.id, id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (!updatedStore) {
|
|
||||||
throw new ApiError("Store not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update products if provided
|
|
||||||
if (products) {
|
|
||||||
// First, set storeId to null for products not in the list but currently assigned to this store
|
|
||||||
await db
|
|
||||||
.update(productInfo)
|
|
||||||
.set({ storeId: null })
|
|
||||||
.where(eq(productInfo.storeId, id));
|
|
||||||
|
|
||||||
// Then, assign the selected products to this store
|
|
||||||
if (products.length > 0) {
|
|
||||||
await db
|
|
||||||
.update(productInfo)
|
|
||||||
.set({ storeId: id })
|
|
||||||
.where(inArray(productInfo.id, products));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes
|
// Reinitialize stores to reflect changes
|
||||||
await scheduleStoreInitialization()
|
await scheduleStoreInitialization()
|
||||||
|
|
||||||
|
|
@ -201,31 +145,6 @@ export const storeRouter = router({
|
||||||
|
|
||||||
const result = await deleteStoreFromDb(storeId);
|
const result = await deleteStoreFromDb(storeId);
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query with transaction:
|
|
||||||
const result = await db.transaction(async (tx) => {
|
|
||||||
// First, update all products of this store to set storeId to null
|
|
||||||
await tx
|
|
||||||
.update(productInfo)
|
|
||||||
.set({ storeId: null })
|
|
||||||
.where(eq(productInfo.storeId, storeId));
|
|
||||||
|
|
||||||
// Then delete the store
|
|
||||||
const [deletedStore] = await tx
|
|
||||||
.delete(storeInfo)
|
|
||||||
.where(eq(storeInfo.id, storeId))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (!deletedStore) {
|
|
||||||
throw new ApiError("Store not found", 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
message: "Store deleted successfully",
|
|
||||||
};
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Reinitialize stores to reflect changes (outside transaction)
|
// Reinitialize stores to reflect changes (outside transaction)
|
||||||
await scheduleStoreInitialization()
|
await scheduleStoreInitialization()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -82,45 +82,6 @@ export const vendorSnippetsRouter = router({
|
||||||
validTill: validTill ? new Date(validTill) : undefined,
|
validTill: validTill ? new Date(validTill) : undefined,
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Validate slot exists
|
|
||||||
if(slotId) {
|
|
||||||
const slot = await db.query.deliverySlotInfo.findFirst({
|
|
||||||
where: eq(deliverySlotInfo.id, slotId),
|
|
||||||
});
|
|
||||||
if (!slot) {
|
|
||||||
throw new Error("Invalid slot ID");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate products exist
|
|
||||||
const products = await db.query.productInfo.findMany({
|
|
||||||
where: inArray(productInfo.id, skuIds),
|
|
||||||
});
|
|
||||||
if (products.length !== skuIds.length) {
|
|
||||||
throw new Error("One or more invalid product IDs");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if snippet code already exists
|
|
||||||
const existingSnippet = await db.query.vendorSnippets.findFirst({
|
|
||||||
where: eq(vendorSnippets.snippetCode, snippetCode),
|
|
||||||
});
|
|
||||||
if (existingSnippet) {
|
|
||||||
throw new Error("Snippet code already exists");
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await db.insert(vendorSnippets).values({
|
|
||||||
snippetCode,
|
|
||||||
slotId,
|
|
||||||
skuIds,
|
|
||||||
isPermanent,
|
|
||||||
validTill: validTill ? new Date(validTill) : undefined,
|
|
||||||
}).returning();
|
|
||||||
|
|
||||||
return result[0];
|
|
||||||
*/
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -143,33 +104,6 @@ export const vendorSnippetsRouter = router({
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const result = await db.query.vendorSnippets.findMany({
|
|
||||||
with: {
|
|
||||||
slot: true,
|
|
||||||
},
|
|
||||||
orderBy: (vendorSnippets, { desc }) => [desc(vendorSnippets.createdAt)],
|
|
||||||
});
|
|
||||||
|
|
||||||
const snippetsWithProducts = await Promise.all(
|
|
||||||
result.map(async (snippet) => {
|
|
||||||
const products = await db.query.productInfo.findMany({
|
|
||||||
where: inArray(productInfo.id, snippet.skuIds),
|
|
||||||
columns: { id: true, name: true },
|
|
||||||
});
|
|
||||||
|
|
||||||
return {
|
|
||||||
...snippet,
|
|
||||||
accessUrl: `${getAppUrl()}/vendor-order-list?id=${snippet.snippetCode}`,
|
|
||||||
products: products.map(p => ({ id: p.id, name: p.name })),
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
return snippetsWithProducts;
|
|
||||||
*/
|
|
||||||
|
|
||||||
return snippetsWithProducts
|
return snippetsWithProducts
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
|
|
@ -218,62 +152,6 @@ export const vendorSnippetsRouter = router({
|
||||||
|
|
||||||
const result = await updateVendorSnippetInDb(id, updateData)
|
const result = await updateVendorSnippetInDb(id, updateData)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const existingSnippet = await db.query.vendorSnippets.findFirst({
|
|
||||||
where: eq(vendorSnippets.id, id),
|
|
||||||
});
|
|
||||||
if (!existingSnippet) {
|
|
||||||
throw new Error("Vendor snippet not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate slot if being updated
|
|
||||||
if (updates.slotId) {
|
|
||||||
const slot = await db.query.deliverySlotInfo.findFirst({
|
|
||||||
where: eq(deliverySlotInfo.id, updates.slotId),
|
|
||||||
});
|
|
||||||
if (!slot) {
|
|
||||||
throw new Error("Invalid slot ID");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Validate products if being updated
|
|
||||||
if (updates.skuIds) {
|
|
||||||
const products = await db.query.productInfo.findMany({
|
|
||||||
where: inArray(productInfo.id, updates.skuIds),
|
|
||||||
});
|
|
||||||
if (products.length !== updates.skuIds.length) {
|
|
||||||
throw new Error("One or more invalid product IDs");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check snippet code uniqueness if being updated
|
|
||||||
if (updates.snippetCode && updates.snippetCode !== existingSnippet.snippetCode) {
|
|
||||||
const duplicateSnippet = await db.query.vendorSnippets.findFirst({
|
|
||||||
where: eq(vendorSnippets.snippetCode, updates.snippetCode),
|
|
||||||
});
|
|
||||||
if (duplicateSnippet) {
|
|
||||||
throw new Error("Snippet code already exists");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateData: any = { ...updates };
|
|
||||||
if (updates.validTill !== undefined) {
|
|
||||||
updateData.validTill = updates.validTill ? new Date(updates.validTill) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
const result = await db.update(vendorSnippets)
|
|
||||||
.set(updateData)
|
|
||||||
.where(eq(vendorSnippets.id, id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (result.length === 0) {
|
|
||||||
throw new Error("Failed to update vendor snippet");
|
|
||||||
}
|
|
||||||
|
|
||||||
return result[0];
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new Error('Failed to update vendor snippet')
|
throw new Error('Failed to update vendor snippet')
|
||||||
}
|
}
|
||||||
|
|
@ -288,19 +166,6 @@ export const vendorSnippetsRouter = router({
|
||||||
|
|
||||||
const result = await deleteVendorSnippetInDb(id)
|
const result = await deleteVendorSnippetInDb(id)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const result = await db.delete(vendorSnippets)
|
|
||||||
.where(eq(vendorSnippets.id, id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (result.length === 0) {
|
|
||||||
throw new Error("Vendor snippet not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
return { message: "Vendor snippet deleted successfully" };
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new Error('Vendor snippet not found')
|
throw new Error('Vendor snippet not found')
|
||||||
}
|
}
|
||||||
|
|
@ -317,43 +182,6 @@ export const vendorSnippetsRouter = router({
|
||||||
|
|
||||||
const snippet = await getVendorSnippetByCodeInDb(snippetCode)
|
const snippet = await getVendorSnippetByCodeInDb(snippetCode)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Find the snippet
|
|
||||||
const snippet = await db.query.vendorSnippets.findFirst({
|
|
||||||
where: eq(vendorSnippets.snippetCode, snippetCode),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!snippet) {
|
|
||||||
throw new Error("Vendor snippet not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if snippet is still valid
|
|
||||||
if (snippet.validTill && new Date(snippet.validTill) < new Date()) {
|
|
||||||
throw new Error("Vendor snippet has expired");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query orders that match the snippet criteria
|
|
||||||
const matchingOrders = await db.query.orders.findMany({
|
|
||||||
where: eq(orders.slotId, snippet.slotId!),
|
|
||||||
with: {
|
|
||||||
orderItems: {
|
|
||||||
with: {
|
|
||||||
product: {
|
|
||||||
with: {
|
|
||||||
unit: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
orderStatus: true,
|
|
||||||
user: true,
|
|
||||||
slot: true,
|
|
||||||
},
|
|
||||||
orderBy: (orders, { desc }) => [desc(orders.createdAt)],
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!snippet) {
|
if (!snippet) {
|
||||||
throw new Error('Vendor snippet not found')
|
throw new Error('Vendor snippet not found')
|
||||||
}
|
}
|
||||||
|
|
@ -433,17 +261,6 @@ export const vendorSnippetsRouter = router({
|
||||||
const threeHoursAgo = dayjs().subtract(3, 'hour').toDate();
|
const threeHoursAgo = dayjs().subtract(3, 'hour').toDate();
|
||||||
const slots = await getSlotsAfterDateInDb(threeHoursAgo)
|
const slots = await getSlotsAfterDateInDb(threeHoursAgo)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const slots = await db.query.deliverySlotInfo.findMany({
|
|
||||||
where: and(
|
|
||||||
eq(deliverySlotInfo.isActive, true),
|
|
||||||
gt(deliverySlotInfo.deliveryTime, threeHoursAgo)
|
|
||||||
),
|
|
||||||
orderBy: asc(deliverySlotInfo.deliveryTime),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
data: slots.map(slot => ({
|
data: slots.map(slot => ({
|
||||||
|
|
@ -466,47 +283,6 @@ export const vendorSnippetsRouter = router({
|
||||||
const snippet = await getVendorSnippetByCodeInDb(snippetCode)
|
const snippet = await getVendorSnippetByCodeInDb(snippetCode)
|
||||||
const slot = await getVendorSlotByIdInDb(slotId)
|
const slot = await getVendorSlotByIdInDb(slotId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Find the snippet
|
|
||||||
const snippet = await db.query.vendorSnippets.findFirst({
|
|
||||||
where: eq(vendorSnippets.snippetCode, snippetCode),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!snippet) {
|
|
||||||
throw new Error("Vendor snippet not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the slot
|
|
||||||
const slot = await db.query.deliverySlotInfo.findFirst({
|
|
||||||
where: eq(deliverySlotInfo.id, slotId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!slot) {
|
|
||||||
throw new Error("Slot not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Query orders that match the slot and snippet criteria
|
|
||||||
const matchingOrders = await db.query.orders.findMany({
|
|
||||||
where: eq(orders.slotId, slotId),
|
|
||||||
with: {
|
|
||||||
orderItems: {
|
|
||||||
with: {
|
|
||||||
product: {
|
|
||||||
with: {
|
|
||||||
unit: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
orderStatus: true,
|
|
||||||
user: true,
|
|
||||||
slot: true,
|
|
||||||
},
|
|
||||||
orderBy: (orders, { desc }) => [desc(orders.createdAt)],
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!snippet) {
|
if (!snippet) {
|
||||||
throw new Error('Vendor snippet not found')
|
throw new Error('Vendor snippet not found')
|
||||||
}
|
}
|
||||||
|
|
@ -599,55 +375,6 @@ export const vendorSnippetsRouter = router({
|
||||||
|
|
||||||
const result = await updateVendorOrderItemPackagingInDb(orderItemId, is_packaged)
|
const result = await updateVendorOrderItemPackagingInDb(orderItemId, is_packaged)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
// Check if order item exists and get related data
|
|
||||||
const orderItem = await db.query.orderItems.findFirst({
|
|
||||||
where: eq(orderItems.id, orderItemId),
|
|
||||||
with: {
|
|
||||||
order: {
|
|
||||||
with: {
|
|
||||||
slot: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!orderItem) {
|
|
||||||
throw new Error("Order item not found");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if this order item belongs to a slot that has vendor snippets
|
|
||||||
// This ensures only order items from vendor-accessible orders can be updated
|
|
||||||
if (!orderItem.order.slotId) {
|
|
||||||
throw new Error("Order item not associated with a vendor slot");
|
|
||||||
}
|
|
||||||
|
|
||||||
const snippetExists = await db.query.vendorSnippets.findFirst({
|
|
||||||
where: eq(vendorSnippets.slotId, orderItem.order.slotId),
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!snippetExists) {
|
|
||||||
throw new Error("No vendor snippet found for this order's slot");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the is_packaged field
|
|
||||||
const result = await db.update(orderItems)
|
|
||||||
.set({ is_packaged })
|
|
||||||
.where(eq(orderItems.id, orderItemId))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
if (result.length === 0) {
|
|
||||||
throw new Error("Failed to update packaging status");
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
success: true,
|
|
||||||
orderItemId,
|
|
||||||
is_packaged
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error(result.message)
|
throw new Error(result.message)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -54,19 +54,6 @@ export const commonApiRouter = router({
|
||||||
|
|
||||||
getStoresSummary: publicProcedure
|
getStoresSummary: publicProcedure
|
||||||
.query(async (): Promise<StoresSummaryResponse> => {
|
.query(async (): Promise<StoresSummaryResponse> => {
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { storeInfo } from '@/src/db/schema'
|
|
||||||
|
|
||||||
const stores = await db.query.storeInfo.findMany({
|
|
||||||
columns: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
description: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
const stores = await getStoresSummary();
|
const stores = await getStoresSummary();
|
||||||
|
|
||||||
|
|
@ -143,15 +130,6 @@ export const commonApiRouter = router({
|
||||||
|
|
||||||
healthCheck: publicProcedure
|
healthCheck: publicProcedure
|
||||||
.query(async () => {
|
.query(async () => {
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { keyValStore, productInfo } from '@/src/db/schema'
|
|
||||||
|
|
||||||
// Test DB connection by selecting product names
|
|
||||||
// await db.select({ name: productInfo.name }).from(productInfo).limit(1);
|
|
||||||
await db.select({ key: keyValStore.key }).from(keyValStore).limit(1);
|
|
||||||
*/
|
|
||||||
|
|
||||||
const result = await healthCheck();
|
const result = await healthCheck();
|
||||||
return result;
|
return result;
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,6 @@ export async function scaffoldProducts() {
|
||||||
let products = await getAllProductsFromCache();
|
let products = await getAllProductsFromCache();
|
||||||
products = products.filter(item => Boolean(item.id))
|
products = products.filter(item => Boolean(item.id))
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
import { db } from '@/src/db/db_index'
|
|
||||||
import { productInfo } from '@/src/db/schema'
|
|
||||||
import { eq } from 'drizzle-orm';
|
|
||||||
|
|
||||||
// Get suspended product IDs to filter them out
|
|
||||||
const suspendedProducts = await db
|
|
||||||
.select({ id: productInfo.id })
|
|
||||||
.from(productInfo)
|
|
||||||
.where(eq(productInfo.isSuspended, true));
|
|
||||||
*/
|
|
||||||
|
|
||||||
const suspendedSkuIds = new Set(await getSuspendedSkuIds());
|
const suspendedSkuIds = new Set(await getSuspendedSkuIds());
|
||||||
|
|
||||||
// Filter out suspended products
|
// Filter out suspended products
|
||||||
|
|
@ -152,18 +139,4 @@ export const commonRouter = router({
|
||||||
return { skus }
|
return { skus }
|
||||||
}),
|
}),
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - moved to common-trpc-index.ts:
|
|
||||||
getStoresSummary: publicProcedure
|
|
||||||
.query(async () => {
|
|
||||||
const stores = await getStoresSummary();
|
|
||||||
return { stores };
|
|
||||||
}),
|
|
||||||
|
|
||||||
healthCheck: publicProcedure
|
|
||||||
.query(async () => {
|
|
||||||
const result = await healthCheck();
|
|
||||||
return result;
|
|
||||||
}),
|
|
||||||
*/
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,6 @@ export const addressRouter = router({
|
||||||
|
|
||||||
const defaultAddress = await getDefaultAddressInDb(userId)
|
const defaultAddress = await getDefaultAddressInDb(userId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const [defaultAddress] = await db
|
|
||||||
.select()
|
|
||||||
.from(addresses)
|
|
||||||
.where(and(eq(addresses.userId, userId), eq(addresses.isDefault, true)))
|
|
||||||
.limit(1);
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { success: true, data: defaultAddress }
|
return { success: true, data: defaultAddress }
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -41,11 +32,6 @@ export const addressRouter = router({
|
||||||
const userId = ctx.user.userId;
|
const userId = ctx.user.userId;
|
||||||
const userAddresses = await getUserAddressesInDb(userId)
|
const userAddresses = await getUserAddressesInDb(userId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const userAddresses = await db.select().from(addresses).where(eq(addresses.userId, userId));
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { success: true, data: userAddresses }
|
return { success: true, data: userAddresses }
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -102,28 +88,6 @@ export const addressRouter = router({
|
||||||
googleMapsUrl,
|
googleMapsUrl,
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
if (isDefault) {
|
|
||||||
await db.update(addresses).set({ isDefault: false }).where(eq(addresses.userId, userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
const [newAddress] = await db.insert(addresses).values({
|
|
||||||
userId,
|
|
||||||
name,
|
|
||||||
phone,
|
|
||||||
addressLine1,
|
|
||||||
addressLine2,
|
|
||||||
city,
|
|
||||||
state,
|
|
||||||
pincode,
|
|
||||||
isDefault: isDefault || false,
|
|
||||||
latitude,
|
|
||||||
longitude,
|
|
||||||
googleMapsUrl,
|
|
||||||
}).returning();
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { success: true, data: newAddress }
|
return { success: true, data: newAddress }
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -183,34 +147,6 @@ export const addressRouter = router({
|
||||||
longitude,
|
longitude,
|
||||||
})
|
})
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
if (isDefault) {
|
|
||||||
await db.update(addresses).set({ isDefault: false }).where(eq(addresses.userId, userId));
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateData: any = {
|
|
||||||
name,
|
|
||||||
phone,
|
|
||||||
addressLine1,
|
|
||||||
addressLine2,
|
|
||||||
city,
|
|
||||||
state,
|
|
||||||
pincode,
|
|
||||||
isDefault: isDefault || false,
|
|
||||||
googleMapsUrl,
|
|
||||||
};
|
|
||||||
|
|
||||||
if (latitude !== undefined) {
|
|
||||||
updateData.latitude = latitude;
|
|
||||||
}
|
|
||||||
if (longitude !== undefined) {
|
|
||||||
updateData.longitude = longitude;
|
|
||||||
}
|
|
||||||
|
|
||||||
const [updatedAddress] = await db.update(addresses).set(updateData).where(and(eq(addresses.id, id), eq(addresses.userId, userId))).returning();
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { success: true, data: updatedAddress }
|
return { success: true, data: updatedAddress }
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -238,39 +174,6 @@ export const addressRouter = router({
|
||||||
|
|
||||||
const deleted = await deleteUserAddressInDb(userId, id)
|
const deleted = await deleteUserAddressInDb(userId, id)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const existingAddress = await db.select().from(addresses).where(and(eq(addresses.id, id), eq(addresses.userId, userId))).limit(1);
|
|
||||||
if (existingAddress.length === 0) {
|
|
||||||
throw new Error('Address not found or does not belong to user');
|
|
||||||
}
|
|
||||||
|
|
||||||
const ongoingOrders = await db.select({
|
|
||||||
order: orders,
|
|
||||||
status: orderStatus,
|
|
||||||
slot: deliverySlotInfo
|
|
||||||
})
|
|
||||||
.from(orders)
|
|
||||||
.innerJoin(orderStatus, eq(orders.id, orderStatus.orderId))
|
|
||||||
.innerJoin(deliverySlotInfo, eq(orders.slotId, deliverySlotInfo.id))
|
|
||||||
.where(and(
|
|
||||||
eq(orders.addressId, id),
|
|
||||||
eq(orderStatus.isCancelled, false),
|
|
||||||
gte(deliverySlotInfo.deliveryTime, new Date())
|
|
||||||
))
|
|
||||||
.limit(1);
|
|
||||||
|
|
||||||
if (ongoingOrders.length > 0) {
|
|
||||||
throw new Error('Address is attached to an ongoing order. Please cancel the order first.');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (existingAddress[0].isDefault) {
|
|
||||||
throw new Error('Cannot delete default address. Please set another address as default first.');
|
|
||||||
}
|
|
||||||
|
|
||||||
await db.delete(addresses).where(and(eq(addresses.id, id), eq(addresses.userId, userId)));
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!deleted) {
|
if (!deleted) {
|
||||||
throw new Error('Address not found or does not belong to user')
|
throw new Error('Address not found or does not belong to user')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -264,24 +264,6 @@ export const authRouter = router({
|
||||||
// Insert if not exists, then update if exists
|
// Insert if not exists, then update if exists
|
||||||
await upsertUserAuthPasswordInDb(userId, hashedPassword)
|
await upsertUserAuthPasswordInDb(userId, hashedPassword)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
try {
|
|
||||||
await db.insert(userCreds).values({
|
|
||||||
userId: userId,
|
|
||||||
userPassword: hashedPassword,
|
|
||||||
});
|
|
||||||
} catch (error: any) {
|
|
||||||
if (error.code === '23505') {
|
|
||||||
await db.update(userCreds).set({
|
|
||||||
userPassword: hashedPassword,
|
|
||||||
}).where(eq(userCreds.userId, userId));
|
|
||||||
} else {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { success: true, message: 'Password updated successfully' }
|
return { success: true, message: 'Password updated successfully' }
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
@ -420,42 +402,6 @@ export const authRouter = router({
|
||||||
// Use transaction for atomic deletion
|
// Use transaction for atomic deletion
|
||||||
await deleteUserAuthAccountInDb(userId)
|
await deleteUserAuthAccountInDb(userId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
await db.transaction(async (tx) => {
|
|
||||||
await tx.delete(notifCreds).where(eq(notifCreds.userId, userId));
|
|
||||||
await tx.delete(couponApplicableUsers).where(eq(couponApplicableUsers.userId, userId));
|
|
||||||
await tx.delete(couponUsage).where(eq(couponUsage.userId, userId));
|
|
||||||
await tx.delete(complaints).where(eq(complaints.userId, userId));
|
|
||||||
await tx.delete(cartItems).where(eq(cartItems.userId, userId));
|
|
||||||
await tx.delete(notifications).where(eq(notifications.userId, userId));
|
|
||||||
await tx.delete(productReviews).where(eq(productReviews.userId, userId));
|
|
||||||
await tx.update(reservedCoupons)
|
|
||||||
.set({ redeemedBy: null })
|
|
||||||
.where(eq(reservedCoupons.redeemedBy, userId));
|
|
||||||
|
|
||||||
const userOrders = await tx
|
|
||||||
.select({ id: orders.id })
|
|
||||||
.from(orders)
|
|
||||||
.where(eq(orders.userId, userId));
|
|
||||||
|
|
||||||
for (const order of userOrders) {
|
|
||||||
await tx.delete(orderItems).where(eq(orderItems.orderId, order.id));
|
|
||||||
await tx.delete(orderStatus).where(eq(orderStatus.orderId, order.id));
|
|
||||||
await tx.delete(payments).where(eq(payments.orderId, order.id));
|
|
||||||
await tx.delete(refunds).where(eq(refunds.orderId, order.id));
|
|
||||||
await tx.delete(couponUsage).where(eq(couponUsage.orderId, order.id));
|
|
||||||
await tx.delete(complaints).where(eq(complaints.orderId, order.id));
|
|
||||||
}
|
|
||||||
|
|
||||||
await tx.delete(orders).where(eq(orders.userId, userId));
|
|
||||||
await tx.delete(addresses).where(eq(addresses.userId, userId));
|
|
||||||
await tx.delete(userDetails).where(eq(userDetails.userId, userId));
|
|
||||||
await tx.delete(userCreds).where(eq(userCreds.userId, userId));
|
|
||||||
await tx.delete(users).where(eq(users.id, userId));
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { success: true, message: 'Account deleted successfully' }
|
return { success: true, message: 'Account deleted successfully' }
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,6 @@ import type { UserBannersResponse } from '@packages/shared'
|
||||||
export async function scaffoldBanners(): Promise<UserBannersResponse> {
|
export async function scaffoldBanners(): Promise<UserBannersResponse> {
|
||||||
const banners = await getUserActiveBannersInDb()
|
const banners = await getUserActiveBannersInDb()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const banners = await db.query.homeBanners.findMany({
|
|
||||||
where: isNotNull(homeBanners.serialNum), // Only show assigned banners
|
|
||||||
orderBy: asc(homeBanners.serialNum), // Order by slot number 1-4
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
const bannersWithSignedUrls = banners.map((banner) => ({
|
const bannersWithSignedUrls = banners.map((banner) => ({
|
||||||
...banner,
|
...banner,
|
||||||
imageUrl: banner.imageUrl ? scaffoldAssetUrl(banner.imageUrl) : banner.imageUrl,
|
imageUrl: banner.imageUrl ? scaffoldAssetUrl(banner.imageUrl) : banner.imageUrl,
|
||||||
|
|
|
||||||
|
|
@ -13,33 +13,6 @@ export const complaintRouter = router({
|
||||||
|
|
||||||
const userComplaints = await getUserComplaintsInDb(userId)
|
const userComplaints = await getUserComplaintsInDb(userId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const userComplaints = await db
|
|
||||||
.select({
|
|
||||||
id: complaints.id,
|
|
||||||
complaintBody: complaints.complaintBody,
|
|
||||||
response: complaints.response,
|
|
||||||
isResolved: complaints.isResolved,
|
|
||||||
createdAt: complaints.createdAt,
|
|
||||||
orderId: complaints.orderId,
|
|
||||||
})
|
|
||||||
.from(complaints)
|
|
||||||
.where(eq(complaints.userId, userId))
|
|
||||||
.orderBy(complaints.createdAt);
|
|
||||||
|
|
||||||
return {
|
|
||||||
complaints: userComplaints.map(c => ({
|
|
||||||
id: c.id,
|
|
||||||
complaintBody: c.complaintBody,
|
|
||||||
response: c.response,
|
|
||||||
isResolved: c.isResolved,
|
|
||||||
createdAt: c.createdAt,
|
|
||||||
orderId: c.orderId,
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
complaints: userComplaints,
|
complaints: userComplaints,
|
||||||
}
|
}
|
||||||
|
|
@ -71,15 +44,6 @@ export const complaintRouter = router({
|
||||||
imageUrls && imageUrls.length > 0 ? imageUrls : null
|
imageUrls && imageUrls.length > 0 ? imageUrls : null
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
await db.insert(complaints).values({
|
|
||||||
userId,
|
|
||||||
orderId: orderIdNum,
|
|
||||||
complaintBody: complaintBody.trim(),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { success: true, message: 'Complaint raised successfully' }
|
return { success: true, message: 'Complaint raised successfully' }
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -44,34 +44,6 @@ export const userCouponRouter = router({
|
||||||
|
|
||||||
const allCoupons = await getUserActiveCouponsWithRelationsInDb(userId)
|
const allCoupons = await getUserActiveCouponsWithRelationsInDb(userId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const allCoupons = await db.query.coupons.findMany({
|
|
||||||
where: and(
|
|
||||||
eq(coupons.isInvalidated, false),
|
|
||||||
or(
|
|
||||||
isNull(coupons.validTill),
|
|
||||||
gt(coupons.validTill, new Date())
|
|
||||||
)
|
|
||||||
),
|
|
||||||
with: {
|
|
||||||
usages: {
|
|
||||||
where: eq(couponUsage.userId, userId)
|
|
||||||
},
|
|
||||||
applicableUsers: {
|
|
||||||
with: {
|
|
||||||
user: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
applicableProducts: {
|
|
||||||
with: {
|
|
||||||
product: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Filter to only coupons applicable to current user
|
// Filter to only coupons applicable to current user
|
||||||
const isFirstOrder = (await getUserOrderCountInDb(userId)) === 0;
|
const isFirstOrder = (await getUserOrderCountInDb(userId)) === 0;
|
||||||
const applicableCoupons = allCoupons.filter(coupon => {
|
const applicableCoupons = allCoupons.filter(coupon => {
|
||||||
|
|
@ -95,22 +67,6 @@ export const userCouponRouter = router({
|
||||||
|
|
||||||
const allCoupons = await getUserAllCouponsWithRelationsInDb(userId)
|
const allCoupons = await getUserAllCouponsWithRelationsInDb(userId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const allCoupons = await db.query.coupons.findMany({
|
|
||||||
with: {
|
|
||||||
usages: {
|
|
||||||
where: eq(couponUsage.userId, userId)
|
|
||||||
},
|
|
||||||
applicableUsers: {
|
|
||||||
with: {
|
|
||||||
user: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Filter coupons in JS: not invalidated, applicable to user, not expired, and first-order eligible
|
// Filter coupons in JS: not invalidated, applicable to user, not expired, and first-order eligible
|
||||||
const isFirstOrder = (await getUserOrderCountInDb(userId)) === 0;
|
const isFirstOrder = (await getUserOrderCountInDb(userId)) === 0;
|
||||||
const applicableCoupons = allCoupons.filter(coupon => {
|
const applicableCoupons = allCoupons.filter(coupon => {
|
||||||
|
|
@ -172,16 +128,6 @@ export const userCouponRouter = router({
|
||||||
|
|
||||||
const reservedCoupon = await getUserReservedCouponByCodeInDb(secretCode)
|
const reservedCoupon = await getUserReservedCouponByCodeInDb(secretCode)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const reservedCoupon = await db.query.reservedCoupons.findFirst({
|
|
||||||
where: and(
|
|
||||||
eq(reservedCoupons.secretCode, secretCode.toUpperCase()),
|
|
||||||
eq(reservedCoupons.isRedeemed, false)
|
|
||||||
),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!reservedCoupon) {
|
if (!reservedCoupon) {
|
||||||
throw new ApiError("Invalid or already redeemed coupon code", 400);
|
throw new ApiError("Invalid or already redeemed coupon code", 400);
|
||||||
}
|
}
|
||||||
|
|
@ -198,41 +144,6 @@ export const userCouponRouter = router({
|
||||||
|
|
||||||
const couponResult = await redeemUserReservedCouponInDb(userId, reservedCoupon)
|
const couponResult = await redeemUserReservedCouponInDb(userId, reservedCoupon)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const couponResult = await db.transaction(async (tx) => {
|
|
||||||
const couponInsert = await tx.insert(coupons).values({
|
|
||||||
couponCode: reservedCoupon.couponCode,
|
|
||||||
isUserBased: true,
|
|
||||||
discountPercent: reservedCoupon.discountPercent,
|
|
||||||
flatDiscount: reservedCoupon.flatDiscount,
|
|
||||||
minOrder: reservedCoupon.minOrder,
|
|
||||||
skuIds: reservedCoupon.skuIds,
|
|
||||||
maxValue: reservedCoupon.maxValue,
|
|
||||||
isApplyForAll: false,
|
|
||||||
validTill: reservedCoupon.validTill,
|
|
||||||
maxLimitForUser: reservedCoupon.maxLimitForUser,
|
|
||||||
exclusiveApply: reservedCoupon.exclusiveApply,
|
|
||||||
createdBy: reservedCoupon.createdBy,
|
|
||||||
}).returning();
|
|
||||||
|
|
||||||
const coupon = couponInsert[0];
|
|
||||||
|
|
||||||
await tx.insert(couponApplicableUsers).values({
|
|
||||||
couponId: coupon.id,
|
|
||||||
userId,
|
|
||||||
});
|
|
||||||
|
|
||||||
await tx.update(reservedCoupons).set({
|
|
||||||
isRedeemed: true,
|
|
||||||
redeemedBy: userId,
|
|
||||||
redeemedAt: new Date(),
|
|
||||||
}).where(eq(reservedCoupons.id, reservedCoupon.id));
|
|
||||||
|
|
||||||
return coupon;
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
return { success: true, coupon: couponResult };
|
return { success: true, coupon: couponResult };
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,6 @@ import type {
|
||||||
UserPaymentFailResponse,
|
UserPaymentFailResponse,
|
||||||
} from '@packages/shared'
|
} from '@packages/shared'
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export const paymentRouter = router({
|
export const paymentRouter = router({
|
||||||
createRazorpayOrder: protectedProcedure //either create a new payment order or return the existing one
|
createRazorpayOrder: protectedProcedure //either create a new payment order or return the existing one
|
||||||
.input(z.object({
|
.input(z.object({
|
||||||
|
|
@ -32,13 +29,6 @@ export const paymentRouter = router({
|
||||||
|
|
||||||
const order = await getUserPaymentOrderByIdInDb(parseInt(orderId))
|
const order = await getUserPaymentOrderByIdInDb(parseInt(orderId))
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const order = await db.query.orders.findFirst({
|
|
||||||
where: eq(orders.id, parseInt(orderId)),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!order) {
|
if (!order) {
|
||||||
throw new ApiError("Order not found", 404)
|
throw new ApiError("Order not found", 404)
|
||||||
}
|
}
|
||||||
|
|
@ -50,13 +40,6 @@ export const paymentRouter = router({
|
||||||
// Check for existing pending payment
|
// Check for existing pending payment
|
||||||
const existingPayment = await getUserPaymentByOrderIdInDb(parseInt(orderId))
|
const existingPayment = await getUserPaymentByOrderIdInDb(parseInt(orderId))
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const existingPayment = await db.query.payments.findFirst({
|
|
||||||
where: eq(payments.orderId, parseInt(orderId)),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (existingPayment && existingPayment.status === 'pending') {
|
if (existingPayment && existingPayment.status === 'pending') {
|
||||||
return {
|
return {
|
||||||
razorpayOrderId: existingPayment.merchantOrderId,
|
razorpayOrderId: existingPayment.merchantOrderId,
|
||||||
|
|
@ -77,8 +60,6 @@ export const paymentRouter = router({
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
verifyPayment: protectedProcedure
|
verifyPayment: protectedProcedure
|
||||||
.input(z.object({
|
.input(z.object({
|
||||||
razorpay_payment_id: z.string(),
|
razorpay_payment_id: z.string(),
|
||||||
|
|
@ -113,13 +94,6 @@ export const paymentRouter = router({
|
||||||
// Get current payment record
|
// Get current payment record
|
||||||
const currentPayment = await getUserPaymentByMerchantOrderIdInDb(razorpay_order_id)
|
const currentPayment = await getUserPaymentByMerchantOrderIdInDb(razorpay_order_id)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const currentPayment = await db.query.payments.findFirst({
|
|
||||||
where: eq(payments.merchantOrderId, razorpay_order_id),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!currentPayment) {
|
if (!currentPayment) {
|
||||||
throw new ApiError("Payment record not found", 404);
|
throw new ApiError("Payment record not found", 404);
|
||||||
}
|
}
|
||||||
|
|
@ -133,25 +107,6 @@ export const paymentRouter = router({
|
||||||
|
|
||||||
const updatedPayment = await updateUserPaymentSuccessInDb(razorpay_order_id, updatedPayload)
|
const updatedPayment = await updateUserPaymentSuccessInDb(razorpay_order_id, updatedPayload)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const [updatedPayment] = await db
|
|
||||||
.update(payments)
|
|
||||||
.set({
|
|
||||||
status: 'success',
|
|
||||||
payload: updatedPayload,
|
|
||||||
})
|
|
||||||
.where(eq(payments.merchantOrderId, razorpay_order_id))
|
|
||||||
.returning();
|
|
||||||
|
|
||||||
await db
|
|
||||||
.update(orderStatus)
|
|
||||||
.set({
|
|
||||||
paymentStatus: 'success',
|
|
||||||
})
|
|
||||||
.where(eq(orderStatus.orderId, updatedPayment.orderId));
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!updatedPayment) {
|
if (!updatedPayment) {
|
||||||
throw new ApiError("Payment record not found", 404)
|
throw new ApiError("Payment record not found", 404)
|
||||||
}
|
}
|
||||||
|
|
@ -175,13 +130,6 @@ export const paymentRouter = router({
|
||||||
// Find payment by merchantOrderId
|
// Find payment by merchantOrderId
|
||||||
const payment = await getUserPaymentByMerchantOrderIdInDb(merchantOrderId)
|
const payment = await getUserPaymentByMerchantOrderIdInDb(merchantOrderId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const payment = await db.query.payments.findFirst({
|
|
||||||
where: eq(payments.merchantOrderId, merchantOrderId),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!payment) {
|
if (!payment) {
|
||||||
throw new ApiError("Payment not found", 404);
|
throw new ApiError("Payment not found", 404);
|
||||||
}
|
}
|
||||||
|
|
@ -189,13 +137,6 @@ export const paymentRouter = router({
|
||||||
// Check if payment belongs to user's order
|
// Check if payment belongs to user's order
|
||||||
const order = await getUserPaymentOrderByIdInDb(payment.orderId)
|
const order = await getUserPaymentOrderByIdInDb(payment.orderId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const order = await db.query.orders.findFirst({
|
|
||||||
where: eq(orders.id, payment.orderId),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!order || order.userId !== userId) {
|
if (!order || order.userId !== userId) {
|
||||||
throw new ApiError("Payment does not belong to user", 403);
|
throw new ApiError("Payment does not belong to user", 403);
|
||||||
}
|
}
|
||||||
|
|
@ -203,14 +144,6 @@ export const paymentRouter = router({
|
||||||
// Update payment status to failed
|
// Update payment status to failed
|
||||||
await markUserPaymentFailedInDb(payment.id)
|
await markUserPaymentFailedInDb(payment.id)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
await db
|
|
||||||
.update(payments)
|
|
||||||
.set({ status: 'failed' })
|
|
||||||
.where(eq(payments.id, payment.id));
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
message: "Payment marked as failed",
|
message: "Payment marked as failed",
|
||||||
|
|
|
||||||
|
|
@ -76,33 +76,6 @@ export const productRouter = router({
|
||||||
|
|
||||||
const { reviews, totalCount } = await getUserProductReviewsInDb(productId, limit, offset)
|
const { reviews, totalCount } = await getUserProductReviewsInDb(productId, limit, offset)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const reviews = await 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);
|
|
||||||
|
|
||||||
const totalCountResult = await db
|
|
||||||
.select({ count: sql`count(*)` })
|
|
||||||
.from(productReviews)
|
|
||||||
.where(eq(productReviews.productId, productId));
|
|
||||||
|
|
||||||
const totalCount = Number(totalCountResult[0].count);
|
|
||||||
const hasMore = offset + limit < totalCount;
|
|
||||||
*/
|
|
||||||
|
|
||||||
const reviewsWithSignedUrls: UserProductReviewWithSignedUrls[] = reviews.map((review) => ({
|
const reviewsWithSignedUrls: UserProductReviewWithSignedUrls[] = reviews.map((review) => ({
|
||||||
...review,
|
...review,
|
||||||
signedImageUrls: scaffoldAssetUrl(review.imageUrls || []),
|
signedImageUrls: scaffoldAssetUrl(review.imageUrls || []),
|
||||||
|
|
@ -133,24 +106,6 @@ export const productRouter = router({
|
||||||
const imageKeys = uploadUrls.map(item => extractKeyFromPresignedUrl(item))
|
const imageKeys = uploadUrls.map(item => extractKeyFromPresignedUrl(item))
|
||||||
const newReview = await createUserProductReviewInDb(userId, productId, reviewBody, ratings, imageKeys)
|
const newReview = await createUserProductReviewInDb(userId, productId, reviewBody, ratings, imageKeys)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const product = await db.query.productInfo.findFirst({
|
|
||||||
where: eq(productInfo.id, productId),
|
|
||||||
});
|
|
||||||
if (!product) {
|
|
||||||
throw new ApiError('Product not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const [newReview] = await db.insert(productReviews).values({
|
|
||||||
userId,
|
|
||||||
productId,
|
|
||||||
reviewBody,
|
|
||||||
ratings,
|
|
||||||
imageUrls: uploadUrls.map(item => extractKeyFromPresignedUrl(item)),
|
|
||||||
}).returning();
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Claim upload URLs
|
// Claim upload URLs
|
||||||
if (uploadUrls && uploadUrls.length > 0) {
|
if (uploadUrls && uploadUrls.length > 0) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -36,13 +36,6 @@ export const slotsRouter = router({
|
||||||
getSlots: publicProcedure.query(async (): Promise<UserSlotsListResponse> => {
|
getSlots: publicProcedure.query(async (): Promise<UserSlotsListResponse> => {
|
||||||
const slots = await getUserActiveSlotsListInDb()
|
const slots = await getUserActiveSlotsListInDb()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB query:
|
|
||||||
const slots = await db.query.deliverySlotInfo.findMany({
|
|
||||||
where: eq(deliverySlotInfo.isActive, true),
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
slots,
|
slots,
|
||||||
count: slots.length,
|
count: slots.length,
|
||||||
|
|
|
||||||
|
|
@ -14,24 +14,6 @@ import type {
|
||||||
export async function scaffoldStores(): Promise<UserStoresResponse> {
|
export async function scaffoldStores(): Promise<UserStoresResponse> {
|
||||||
const storesData = await getUserStoreSummariesInDb()
|
const storesData = await getUserStoreSummariesInDb()
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const storesData = await db
|
|
||||||
.select({
|
|
||||||
id: storeInfo.id,
|
|
||||||
name: storeInfo.name,
|
|
||||||
description: storeInfo.description,
|
|
||||||
imageUrl: storeInfo.imageUrl,
|
|
||||||
productCount: sql<number>`count(${productInfo.id})`.as('productCount'),
|
|
||||||
})
|
|
||||||
.from(storeInfo)
|
|
||||||
.leftJoin(
|
|
||||||
productInfo,
|
|
||||||
and(eq(productInfo.storeId, storeInfo.id), eq(productInfo.isSuspended, false))
|
|
||||||
)
|
|
||||||
.groupBy(storeInfo.id);
|
|
||||||
*/
|
|
||||||
|
|
||||||
const storesWithDetails: UserStoreSummary[] = storesData.map((store) => {
|
const storesWithDetails: UserStoreSummary[] = storesData.map((store) => {
|
||||||
const signedImageUrl = store.imageUrl ? scaffoldAssetUrl(store.imageUrl) : null
|
const signedImageUrl = store.imageUrl ? scaffoldAssetUrl(store.imageUrl) : null
|
||||||
const sampleProducts = store.sampleProducts.map((product) => ({
|
const sampleProducts = store.sampleProducts.map((product) => ({
|
||||||
|
|
@ -60,78 +42,6 @@ export async function scaffoldStores(): Promise<UserStoresResponse> {
|
||||||
export async function scaffoldStoreWithProducts(storeId: number): Promise<UserStoreDetail> {
|
export async function scaffoldStoreWithProducts(storeId: number): Promise<UserStoreDetail> {
|
||||||
const storeDetail = await getUserStoreDetailInDb(storeId)
|
const storeDetail = await getUserStoreDetailInDb(storeId)
|
||||||
|
|
||||||
/*
|
|
||||||
// Old implementation - direct DB queries:
|
|
||||||
const storeData = await db.query.storeInfo.findFirst({
|
|
||||||
where: eq(storeInfo.id, storeId),
|
|
||||||
columns: {
|
|
||||||
id: true,
|
|
||||||
name: true,
|
|
||||||
description: true,
|
|
||||||
imageUrl: true,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!storeData) {
|
|
||||||
throw new ApiError('Store not found', 404);
|
|
||||||
}
|
|
||||||
|
|
||||||
const signedImageUrl = storeData.imageUrl ? scaffoldAssetUrl(storeData.imageUrl) : null;
|
|
||||||
|
|
||||||
const productsData = await db
|
|
||||||
.select({
|
|
||||||
id: productInfo.id,
|
|
||||||
name: productInfo.name,
|
|
||||||
shortDescription: productInfo.shortDescription,
|
|
||||||
price: productInfo.price,
|
|
||||||
marketPrice: productInfo.marketPrice,
|
|
||||||
images: productInfo.images,
|
|
||||||
isOutOfStock: productInfo.isOutOfStock,
|
|
||||||
incrementStep: productInfo.incrementStep,
|
|
||||||
unitShortNotation: units.shortNotation,
|
|
||||||
unitNotation: units.shortNotation,
|
|
||||||
productQuantity: productInfo.productQuantity,
|
|
||||||
})
|
|
||||||
.from(productInfo)
|
|
||||||
.innerJoin(units, eq(productInfo.unitId, units.id))
|
|
||||||
.where(and(eq(productInfo.storeId, storeId), eq(productInfo.isSuspended, false)));
|
|
||||||
|
|
||||||
const productsWithSignedUrls = await Promise.all(
|
|
||||||
productsData.map(async (product) => ({
|
|
||||||
id: product.id,
|
|
||||||
name: product.name,
|
|
||||||
shortDescription: product.shortDescription,
|
|
||||||
price: product.price,
|
|
||||||
marketPrice: product.marketPrice,
|
|
||||||
incrementStep: product.incrementStep,
|
|
||||||
unit: product.unitShortNotation,
|
|
||||||
unitNotation: product.unitNotation,
|
|
||||||
images: scaffoldAssetUrl((product.images as string[]) || []),
|
|
||||||
isOutOfStock: product.isOutOfStock,
|
|
||||||
productQuantity: product.productQuantity
|
|
||||||
}))
|
|
||||||
);
|
|
||||||
|
|
||||||
const tags = await getTagsByStoreId(storeId);
|
|
||||||
|
|
||||||
return {
|
|
||||||
store: {
|
|
||||||
id: storeData.id,
|
|
||||||
name: storeData.name,
|
|
||||||
description: storeData.description,
|
|
||||||
signedImageUrl,
|
|
||||||
},
|
|
||||||
products: productsWithSignedUrls,
|
|
||||||
tags: tags.map(tag => ({
|
|
||||||
id: tag.id,
|
|
||||||
tagName: tag.tagName,
|
|
||||||
tagDescription: tag.tagDescription,
|
|
||||||
imageUrl: tag.imageUrl,
|
|
||||||
productIds: tag.productIds,
|
|
||||||
})),
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (!storeDetail) {
|
if (!storeDetail) {
|
||||||
throw new ApiError('Store not found', 404)
|
throw new ApiError('Store not found', 404)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue