COURTRIX / src /server /customers /service.ts
Ali-Developments's picture
Upload 125 files
ad79323 verified
Raw
History Blame Contribute Delete
4.16 kB
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(),
},
});
}