172 lines
4.8 KiB
TypeScript
172 lines
4.8 KiB
TypeScript
import { Injectable, NotFoundException } from '@nestjs/common';
|
|
import { PrismaService } from '../prisma/prisma.service';
|
|
import { PaginationDto } from '../common/dto/pagination.dto';
|
|
import { CreatePetDto } from './dto/create-pet.dto';
|
|
import { UpdatePetDto } from './dto/update-pet.dto';
|
|
|
|
@Injectable()
|
|
export class PetsService {
|
|
constructor(private prisma: PrismaService) {}
|
|
|
|
async create(userId: string, createPetDto: CreatePetDto) {
|
|
const { name, type, breed, weight, age, activityLevel, medicalConditions } = createPetDto;
|
|
|
|
return this.prisma.pet.create({
|
|
data: {
|
|
name,
|
|
type,
|
|
breed: breed || '',
|
|
activityLevel: activityLevel || 'متوسط',
|
|
age: age || 1,
|
|
weight: weight || 0,
|
|
userId,
|
|
medicalConditions: medicalConditions?.length ? {
|
|
create: medicalConditions.map(condition => ({ condition }))
|
|
} : undefined,
|
|
},
|
|
include: { medicalConditions: true, reminders: true, healthLogs: true },
|
|
});
|
|
}
|
|
|
|
async findAllByUser(userId: string, filters: PaginationDto) {
|
|
const { search, page = 1, limit = 10, sortBy = 'createdAt', sortOrder = 'desc' } = filters;
|
|
|
|
const whereClause: any = { userId };
|
|
if (search) {
|
|
whereClause.OR = [
|
|
{ name: { contains: search, mode: 'insensitive' } },
|
|
{ breed: { contains: search, mode: 'insensitive' } },
|
|
];
|
|
}
|
|
|
|
const skip = (page - 1) * limit;
|
|
|
|
const [data, total] = await Promise.all([
|
|
this.prisma.pet.findMany({
|
|
where: whereClause,
|
|
skip,
|
|
take: limit,
|
|
orderBy: { [sortBy]: sortOrder },
|
|
}),
|
|
this.prisma.pet.count({ where: whereClause })
|
|
]);
|
|
|
|
return {
|
|
data,
|
|
meta: {
|
|
total,
|
|
page,
|
|
lastPage: Math.ceil(total / limit),
|
|
limit,
|
|
}
|
|
};
|
|
}
|
|
|
|
async findOne(id: string, userId: string) {
|
|
const pet = await this.prisma.pet.findFirst({
|
|
where: { id, userId },
|
|
include: { medicalConditions: true, reminders: true, healthLogs: true },
|
|
});
|
|
if (!pet) {
|
|
throw new NotFoundException('حیوان خانگی یافت نشد');
|
|
}
|
|
return pet;
|
|
}
|
|
|
|
async update(id: string, userId: string, updatePetDto: UpdatePetDto) {
|
|
await this.findOne(id, userId); // Ensure it exists and belongs to user
|
|
|
|
if (updatePetDto.medicalConditions) {
|
|
await this.prisma.petMedicalCondition.deleteMany({ where: { petId: id } });
|
|
}
|
|
|
|
return this.prisma.pet.update({
|
|
where: { id },
|
|
data: {
|
|
name: updatePetDto.name,
|
|
type: updatePetDto.type,
|
|
breed: updatePetDto.breed,
|
|
weight: updatePetDto.weight,
|
|
age: updatePetDto.age,
|
|
activityLevel: updatePetDto.activityLevel,
|
|
medicalConditions: updatePetDto.medicalConditions ? {
|
|
create: updatePetDto.medicalConditions.map(condition => ({ condition }))
|
|
} : undefined,
|
|
},
|
|
include: { medicalConditions: true, reminders: true, healthLogs: true },
|
|
});
|
|
}
|
|
|
|
async remove(id: string, userId: string) {
|
|
await this.findOne(id, userId);
|
|
return this.prisma.pet.delete({
|
|
where: { id },
|
|
});
|
|
}
|
|
|
|
async addReminder(userId: string, petId: string, data: any) {
|
|
await this.findOne(petId, userId);
|
|
return this.prisma.reminder.create({
|
|
data: {
|
|
petId,
|
|
productId: data.productId || null,
|
|
title: data.title,
|
|
time: data.time,
|
|
frequency: data.frequency,
|
|
},
|
|
});
|
|
}
|
|
|
|
async toggleReminder(userId: string, petId: string, reminderId: string, dateStr: string) {
|
|
await this.findOne(petId, userId);
|
|
|
|
const reminder = await this.prisma.reminder.findUnique({
|
|
where: { id: reminderId },
|
|
});
|
|
if (!reminder || reminder.petId !== petId) {
|
|
throw new NotFoundException('یادآور یافت نشد');
|
|
}
|
|
|
|
const dateParts = dateStr.split('-');
|
|
const completedDate = new Date(Date.UTC(Number(dateParts[0]), Number(dateParts[1]) - 1, Number(dateParts[2])));
|
|
|
|
const existingCompletion = await this.prisma.reminderCompletion.findUnique({
|
|
where: {
|
|
reminderId_completedDate: {
|
|
reminderId,
|
|
completedDate,
|
|
},
|
|
},
|
|
});
|
|
|
|
if (existingCompletion) {
|
|
await this.prisma.reminderCompletion.delete({
|
|
where: { id: existingCompletion.id },
|
|
});
|
|
return { completed: false };
|
|
} else {
|
|
await this.prisma.reminderCompletion.create({
|
|
data: {
|
|
reminderId,
|
|
completedDate,
|
|
},
|
|
});
|
|
return { completed: true };
|
|
}
|
|
}
|
|
|
|
async addHealthLog(userId: string, petId: string, data: any) {
|
|
await this.findOne(petId, userId);
|
|
return this.prisma.healthLog.create({
|
|
data: {
|
|
petId,
|
|
appetite: data.appetite,
|
|
energy: data.energy,
|
|
digestion: data.digestion,
|
|
note: data.note || null,
|
|
loggedDate: new Date(),
|
|
},
|
|
});
|
|
}
|
|
}
|