canina/backend/src/pets/pets.service.ts
2026-07-11 12:30:17 +03:30

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(),
},
});
}
}