import { db } from '../db/db_index'; import { users, userDetails, orders, orderItems, complaints, notifCreds, unloggedUserTokens, userIncidents, orderStatus } from '../db/schema'; import { eq, sql, desc, asc, count, max, inArray } from 'drizzle-orm'; export async function createUserByMobile(mobile: string): Promise { const [newUser] = await db .insert(users) .values({ name: null, email: null, mobile, }) .returning(); return newUser; } export async function getUserByMobile(mobile: string): Promise { const [existingUser] = await db .select() .from(users) .where(eq(users.mobile, mobile)) .limit(1); return existingUser || null; } export async function getUnresolvedComplaintsCount(): Promise { const result = await db .select({ count: count(complaints.id) }) .from(complaints) .where(eq(complaints.isResolved, false)); return result[0]?.count || 0; } export async function getAllUsersWithFilters( limit: number, cursor?: number, search?: string ): Promise<{ users: any[]; hasMore: boolean }> { const whereConditions = []; if (search && search.trim()) { whereConditions.push(sql`${users.mobile} ILIKE ${`%${search.trim()}%`}`); } if (cursor) { whereConditions.push(sql`${users.id} > ${cursor}`); } const usersList = await db .select({ id: users.id, name: users.name, mobile: users.mobile, createdAt: users.createdAt, }) .from(users) .where(whereConditions.length > 0 ? sql.join(whereConditions, sql` AND `) : undefined) .orderBy(asc(users.id)) .limit(limit + 1); const hasMore = usersList.length > limit; const usersToReturn = hasMore ? usersList.slice(0, limit) : usersList; return { users: usersToReturn, hasMore }; } export async function getOrderCountsByUserIds(userIds: number[]): Promise<{ userId: number; totalOrders: number }[]> { if (userIds.length === 0) return []; return await db .select({ userId: orders.userId, totalOrders: count(orders.id), }) .from(orders) .where(sql`${orders.userId} IN (${sql.join(userIds, sql`, `)})`) .groupBy(orders.userId); } export async function getLastOrdersByUserIds(userIds: number[]): Promise<{ userId: number; lastOrderDate: Date | null }[]> { if (userIds.length === 0) return []; return await db .select({ userId: orders.userId, lastOrderDate: max(orders.createdAt), }) .from(orders) .where(sql`${orders.userId} IN (${sql.join(userIds, sql`, `)})`) .groupBy(orders.userId); } export async function getSuspensionStatusesByUserIds(userIds: number[]): Promise<{ userId: number; isSuspended: boolean }[]> { if (userIds.length === 0) return []; return await db .select({ userId: userDetails.userId, isSuspended: userDetails.isSuspended, }) .from(userDetails) .where(sql`${userDetails.userId} IN (${sql.join(userIds, sql`, `)})`); } export async function getUserBasicInfo(userId: number): Promise { const user = await db .select({ id: users.id, name: users.name, mobile: users.mobile, createdAt: users.createdAt, }) .from(users) .where(eq(users.id, userId)) .limit(1); return user[0] || null; } export async function getUserSuspensionStatus(userId: number): Promise { const userDetail = await db .select({ isSuspended: userDetails.isSuspended, }) .from(userDetails) .where(eq(userDetails.userId, userId)) .limit(1); return userDetail[0]?.isSuspended ?? false; } export async function getUserOrders(userId: number): Promise { return await db .select({ id: orders.id, readableId: orders.readableId, totalAmount: orders.totalAmount, createdAt: orders.createdAt, isFlashDelivery: orders.isFlashDelivery, }) .from(orders) .where(eq(orders.userId, userId)) .orderBy(desc(orders.createdAt)); } export async function getOrderStatusesByOrderIds(orderIds: number[]): Promise<{ orderId: number; isDelivered: boolean; isCancelled: boolean }[]> { if (orderIds.length === 0) return []; return await db .select({ orderId: orderStatus.orderId, isDelivered: orderStatus.isDelivered, isCancelled: orderStatus.isCancelled, }) .from(orderStatus) .where(sql`${orderStatus.orderId} IN (${sql.join(orderIds, sql`, `)})`); } export async function getItemCountsByOrderIds(orderIds: number[]): Promise<{ orderId: number; itemCount: number }[]> { if (orderIds.length === 0) return []; return await db .select({ orderId: orderItems.orderId, itemCount: count(orderItems.id), }) .from(orderItems) .where(sql`${orderItems.orderId} IN (${sql.join(orderIds, sql`, `)})`) .groupBy(orderItems.orderId); } export async function upsertUserSuspension(userId: number, isSuspended: boolean): Promise { const existingDetail = await db .select({ id: userDetails.id }) .from(userDetails) .where(eq(userDetails.userId, userId)) .limit(1); if (existingDetail.length > 0) { await db .update(userDetails) .set({ isSuspended }) .where(eq(userDetails.userId, userId)); } else { await db .insert(userDetails) .values({ userId, isSuspended, }); } } export async function searchUsers(search?: string): Promise { if (search && search.trim()) { return await db .select({ id: users.id, name: users.name, mobile: users.mobile, }) .from(users) .where(sql`${users.mobile} ILIKE ${`%${search.trim()}%`} OR ${users.name} ILIKE ${`%${search.trim()}%`}`); } else { return await db .select({ id: users.id, name: users.name, mobile: users.mobile, }) .from(users); } } export async function getAllNotifCreds(): Promise<{ userId: number, token: string }[]> { return await db .select({ userId: notifCreds.userId, token: notifCreds.token }) .from(notifCreds); } export async function getAllUnloggedTokens(): Promise<{ token: string }[]> { return await db .select({ token: unloggedUserTokens.token }) .from(unloggedUserTokens); } export async function getNotifTokensByUserIds(userIds: number[]): Promise<{ token: string }[]> { return await db .select({ token: notifCreds.token }) .from(notifCreds) .where(inArray(notifCreds.userId, userIds)); } export async function getUserIncidentsWithRelations(userId: number): Promise { return await db.query.userIncidents.findMany({ where: eq(userIncidents.userId, userId), with: { order: { with: { orderStatus: true, }, }, addedBy: true, }, orderBy: desc(userIncidents.dateAdded), }); } export async function createUserIncident( userId: number, orderId: number | undefined, adminComment: string | undefined, adminUserId: number, negativityScore: number | undefined ): Promise { const [incident] = await db.insert(userIncidents) .values({ userId, orderId, adminComment, addedBy: adminUserId, negativityScore, }) .returning(); return incident; }