freshyo/packages/db_helper_sqlite/src/user-apis/address.ts
2026-03-26 17:16:56 +05:30

148 lines
4.4 KiB
TypeScript

import { db } from '../db/db_index'
import { addresses, deliverySlotInfo, orders, orderStatus } from '../db/schema'
import { and, eq, gte } from 'drizzle-orm'
import type { InferSelectModel } from 'drizzle-orm'
import type { UserAddress } from '@packages/shared'
type AddressRow = InferSelectModel<typeof addresses>
const mapUserAddress = (address: AddressRow): UserAddress => ({
id: address.id,
userId: address.userId,
name: address.name,
phone: address.phone,
addressLine1: address.addressLine1,
addressLine2: address.addressLine2 ?? null,
city: address.city,
state: address.state,
pincode: address.pincode,
isDefault: address.isDefault,
latitude: address.latitude ?? null,
longitude: address.longitude ?? null,
googleMapsUrl: address.googleMapsUrl ?? null,
adminLatitude: address.adminLatitude ?? null,
adminLongitude: address.adminLongitude ?? null,
zoneId: address.zoneId ?? null,
createdAt: address.createdAt,
})
export async function getDefaultAddress(userId: number): Promise<UserAddress | null> {
const [defaultAddress] = await db
.select()
.from(addresses)
.where(and(eq(addresses.userId, userId), eq(addresses.isDefault, true)))
.limit(1)
return defaultAddress ? mapUserAddress(defaultAddress) : null
}
export async function getUserAddresses(userId: number): Promise<UserAddress[]> {
const userAddresses = await db.select().from(addresses).where(eq(addresses.userId, userId))
return userAddresses.map(mapUserAddress)
}
export async function getUserAddressById(userId: number, addressId: number): Promise<UserAddress | null> {
const [address] = await db
.select()
.from(addresses)
.where(and(eq(addresses.id, addressId), eq(addresses.userId, userId)))
.limit(1)
return address ? mapUserAddress(address) : null
}
export async function clearDefaultAddress(userId: number): Promise<void> {
await db.update(addresses).set({ isDefault: false }).where(eq(addresses.userId, userId))
}
export async function createUserAddress(input: {
userId: number
name: string
phone: string
addressLine1: string
addressLine2?: string
city: string
state: string
pincode: string
isDefault: boolean
latitude?: number
longitude?: number
googleMapsUrl?: string
}): Promise<UserAddress> {
const [newAddress] = await db.insert(addresses).values({
userId: input.userId,
name: input.name,
phone: input.phone,
addressLine1: input.addressLine1,
addressLine2: input.addressLine2,
city: input.city,
state: input.state,
pincode: input.pincode,
isDefault: input.isDefault,
latitude: input.latitude,
longitude: input.longitude,
googleMapsUrl: input.googleMapsUrl,
}).returning()
return mapUserAddress(newAddress)
}
export async function updateUserAddress(input: {
userId: number
addressId: number
name: string
phone: string
addressLine1: string
addressLine2?: string
city: string
state: string
pincode: string
isDefault: boolean
latitude?: number
longitude?: number
googleMapsUrl?: string
}): Promise<UserAddress | null> {
const [updatedAddress] = await db.update(addresses)
.set({
name: input.name,
phone: input.phone,
addressLine1: input.addressLine1,
addressLine2: input.addressLine2,
city: input.city,
state: input.state,
pincode: input.pincode,
isDefault: input.isDefault,
googleMapsUrl: input.googleMapsUrl,
latitude: input.latitude,
longitude: input.longitude,
})
.where(and(eq(addresses.id, input.addressId), eq(addresses.userId, input.userId)))
.returning()
return updatedAddress ? mapUserAddress(updatedAddress) : null
}
export async function deleteUserAddress(userId: number, addressId: number): Promise<boolean> {
const [deleted] = await db.delete(addresses)
.where(and(eq(addresses.id, addressId), eq(addresses.userId, userId)))
.returning({ id: addresses.id })
return !!deleted
}
export async function hasOngoingOrdersForAddress(addressId: number): Promise<boolean> {
const ongoingOrders = await db.select({
orderId: orders.id,
})
.from(orders)
.innerJoin(orderStatus, eq(orders.id, orderStatus.orderId))
.innerJoin(deliverySlotInfo, eq(orders.slotId, deliverySlotInfo.id))
.where(and(
eq(orders.addressId, addressId),
eq(orderStatus.isCancelled, false),
gte(deliverySlotInfo.deliveryTime, new Date())
))
.limit(1)
return ongoingOrders.length > 0
}