Spaces:
Runtime error
Runtime error
| import type { Prisma } from "@prisma/client"; | |
| import { CUSTOMERS_PAGE_SIZE } from "@/lib/constants"; | |
| import type { | |
| CustomerDatePresetValue, | |
| CustomerGenderValue, | |
| } from "@/lib/constants"; | |
| import { trimOrUndefined } from "@/lib/utils"; | |
| import { db } from "@/server/db"; | |
| import { AppError } from "@/server/errors"; | |
| import type { | |
| CustomerInput, | |
| CustomerListQueryInput, | |
| } from "@/server/validation/customer"; | |
| export type CustomerListFilters = { | |
| search?: string; | |
| gender?: CustomerGenderValue; | |
| createdPreset: CustomerDatePresetValue; | |
| page: number; | |
| }; | |
| export function normalizeCustomerListFilters( | |
| input: CustomerListQueryInput, | |
| ): CustomerListFilters { | |
| return { | |
| search: trimOrUndefined(input.search), | |
| gender: input.gender, | |
| createdPreset: input.createdPreset, | |
| page: input.page, | |
| }; | |
| } | |
| function getCreatedAtRange(preset: CustomerDatePresetValue) { | |
| if (preset === "all") { | |
| return undefined; | |
| } | |
| const start = new Date(); | |
| start.setHours(0, 0, 0, 0); | |
| if (preset === "today") { | |
| return { gte: start }; | |
| } | |
| if (preset === "thisWeek") { | |
| const day = start.getDay(); | |
| const diff = (day + 6) % 7; | |
| start.setDate(start.getDate() - diff); | |
| return { gte: start }; | |
| } | |
| start.setDate(1); | |
| return { gte: start }; | |
| } | |
| function buildCustomerWhere( | |
| ownerId: string, | |
| filters: CustomerListFilters, | |
| ): Prisma.CustomerWhereInput { | |
| const clauses: Prisma.CustomerWhereInput[] = [{ ownerId }]; | |
| if (filters.search) { | |
| clauses.push({ | |
| OR: [ | |
| { | |
| firstName: { | |
| contains: filters.search, | |
| mode: "insensitive", | |
| }, | |
| }, | |
| { | |
| middleName: { | |
| contains: filters.search, | |
| mode: "insensitive", | |
| }, | |
| }, | |
| { | |
| lastName: { | |
| contains: filters.search, | |
| mode: "insensitive", | |
| }, | |
| }, | |
| { | |
| phone: { | |
| contains: filters.search, | |
| mode: "insensitive", | |
| }, | |
| }, | |
| ], | |
| }); | |
| } | |
| if (filters.gender) { | |
| clauses.push({ | |
| gender: filters.gender, | |
| }); | |
| } | |
| const createdAt = getCreatedAtRange(filters.createdPreset); | |
| if (createdAt) { | |
| clauses.push({ createdAt }); | |
| } | |
| return { | |
| AND: clauses, | |
| }; | |
| } | |
| export async function listCustomers(ownerId: string, filters: CustomerListFilters) { | |
| const where = buildCustomerWhere(ownerId, filters); | |
| const skip = (filters.page - 1) * CUSTOMERS_PAGE_SIZE; | |
| const [totalCount, items] = await db.$transaction([ | |
| db.customer.count({ where }), | |
| db.customer.findMany({ | |
| where, | |
| orderBy: { | |
| updatedAt: "desc", | |
| }, | |
| skip, | |
| take: CUSTOMERS_PAGE_SIZE, | |
| }), | |
| ]); | |
| return { | |
| items, | |
| totalCount, | |
| totalPages: Math.max(1, Math.ceil(totalCount / CUSTOMERS_PAGE_SIZE)), | |
| page: filters.page, | |
| pageSize: CUSTOMERS_PAGE_SIZE, | |
| }; | |
| } | |
| export async function createCustomer(ownerId: string, input: CustomerInput) { | |
| return db.customer.create({ | |
| data: { | |
| ownerId, | |
| firstName: input.firstName.trim(), | |
| middleName: trimOrUndefined(input.middleName), | |
| lastName: input.lastName.trim(), | |
| gender: input.gender, | |
| phone: input.phone.trim(), | |
| }, | |
| }); | |
| } | |
| export async function getCustomerByIdForOwner(customerId: string, ownerId: string) { | |
| return db.customer.findFirst({ | |
| where: { | |
| id: customerId, | |
| ownerId, | |
| }, | |
| }); | |
| } | |
| export async function requireCustomerByIdForOwner( | |
| customerId: string, | |
| ownerId: string, | |
| ) { | |
| const customer = await getCustomerByIdForOwner(customerId, ownerId); | |
| if (!customer) { | |
| throw new AppError("العميل ده مش موجود.", 404); | |
| } | |
| return customer; | |
| } | |
| export async function updateCustomer( | |
| customerId: string, | |
| ownerId: string, | |
| input: CustomerInput, | |
| ) { | |
| await requireCustomerByIdForOwner(customerId, ownerId); | |
| return db.customer.update({ | |
| where: { | |
| id: customerId, | |
| }, | |
| data: { | |
| firstName: input.firstName.trim(), | |
| middleName: trimOrUndefined(input.middleName), | |
| lastName: input.lastName.trim(), | |
| gender: input.gender, | |
| phone: input.phone.trim(), | |
| }, | |
| }); | |
| } | |