92 lines
2.8 KiB
TypeScript
92 lines
2.8 KiB
TypeScript
/**
|
|
* ════════════════════════════════════════════════════════════
|
|
* مُصادَق (Musadaq) — Users Service
|
|
* ════════════════════════════════════════════════════════════
|
|
*/
|
|
|
|
import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Repository } from 'typeorm';
|
|
import * as bcrypt from 'bcrypt';
|
|
import { User } from './entities/user.entity';
|
|
|
|
@Injectable()
|
|
export class UsersService {
|
|
constructor(
|
|
@InjectRepository(User)
|
|
private userRepository: Repository<User>,
|
|
) {}
|
|
|
|
/**
|
|
* إضافة مستخدم لمكتب محاسبة
|
|
*/
|
|
async create(tenantId: string, dto: any): Promise<User> {
|
|
const existing = await this.userRepository.findOne({
|
|
where: { email: dto.email, tenant_id: tenantId },
|
|
});
|
|
|
|
if (existing) {
|
|
throw new ConflictException('User with this email already exists in this office');
|
|
}
|
|
|
|
const passwordHash = await bcrypt.hash(dto.password, 12);
|
|
|
|
const user = this.userRepository.create({
|
|
...dto,
|
|
password_hash: passwordHash,
|
|
tenant_id: tenantId,
|
|
} as Partial<User>);
|
|
|
|
return this.userRepository.save(user);
|
|
}
|
|
|
|
/**
|
|
* قائمة مستخدمي المكتب
|
|
*/
|
|
async findAll(tenantId: string): Promise<User[]> {
|
|
return this.userRepository.find({
|
|
where: { tenant_id: tenantId, is_active: true },
|
|
order: { created_at: 'ASC' },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* تفاصيل مستخدم
|
|
*/
|
|
async findOne(tenantId: string, id: string): Promise<User> {
|
|
const user = await this.userRepository.findOne({
|
|
where: { id, tenant_id: tenantId },
|
|
});
|
|
if (!user) throw new NotFoundException('User not found');
|
|
return user;
|
|
}
|
|
|
|
/**
|
|
* تعطيل مستخدم
|
|
*/
|
|
async remove(tenantId: string, id: string, currentUserId: string): Promise<void> {
|
|
if (id === currentUserId) {
|
|
throw new ConflictException('لا يمكنك تعطيل حسابك الشخصي');
|
|
}
|
|
const user = await this.findOne(tenantId, id);
|
|
await this.userRepository.update(id, { is_active: false });
|
|
}
|
|
|
|
/**
|
|
* تحديث بيانات مستخدم
|
|
*/
|
|
async update(id: string, dto: any): Promise<User> {
|
|
const user = await this.userRepository.findOne({ where: { id } });
|
|
if (!user) throw new NotFoundException('User not found');
|
|
|
|
// Hash password if provided
|
|
if (dto.password) {
|
|
dto.password_hash = await bcrypt.hash(dto.password, 12);
|
|
delete dto.password;
|
|
}
|
|
|
|
Object.assign(user, dto);
|
|
return this.userRepository.save(user);
|
|
}
|
|
}
|