148 lines
4.4 KiB
TypeScript
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
|
|
}
|