114 lines
3.7 KiB
TypeScript
114 lines
3.7 KiB
TypeScript
/**
|
|
* ════════════════════════════════════════════════════════════
|
|
* مُصادَق (Musadaq) — Companies Service
|
|
* ════════════════════════════════════════════════════════════
|
|
*/
|
|
|
|
import {
|
|
Injectable,
|
|
NotFoundException,
|
|
ForbiddenException,
|
|
Inject,
|
|
forwardRef,
|
|
} from '@nestjs/common';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Repository } from 'typeorm';
|
|
import { Company } from './entities/company.entity';
|
|
import { EncryptionService } from '../../services/encryption/encryption.service';
|
|
import { SubscriptionsService } from '../subscriptions/subscription.service';
|
|
|
|
@Injectable()
|
|
export class CompaniesService {
|
|
constructor(
|
|
@InjectRepository(Company)
|
|
private companyRepository: Repository<Company>,
|
|
private encryptionService: EncryptionService,
|
|
@Inject(forwardRef(() => SubscriptionsService))
|
|
private subscriptionsService: SubscriptionsService,
|
|
) {}
|
|
|
|
/**
|
|
* إنشاء شركة جديدة مع التحقق من حدود الاشتراك
|
|
*/
|
|
async create(tenantId: string, dto: any): Promise<Company> {
|
|
// 1. Check subscription limits
|
|
const canCreate = await this.subscriptionsService.checkCompanyLimit(tenantId);
|
|
if (!canCreate) {
|
|
throw new ForbiddenException('Company limit reached for your current plan');
|
|
}
|
|
|
|
const company = this.companyRepository.create({
|
|
...dto,
|
|
tenant_id: tenantId,
|
|
});
|
|
|
|
return this.companyRepository.save(company);
|
|
}
|
|
|
|
/**
|
|
* قائمة الشركات التابعة للمكتب
|
|
*/
|
|
async findAll(tenantId: string): Promise<Company[]> {
|
|
return this.companyRepository.find({
|
|
where: { tenant_id: tenantId, is_active: true },
|
|
order: { created_at: 'DESC' },
|
|
});
|
|
}
|
|
|
|
/**
|
|
* تفاصيل شركة محددة
|
|
*/
|
|
async findOne(tenantId: string, id: string): Promise<Company> {
|
|
const company = await this.companyRepository.findOne({
|
|
where: { id, tenant_id: tenantId },
|
|
});
|
|
if (!company) throw new NotFoundException('Company not found');
|
|
return company;
|
|
}
|
|
|
|
/**
|
|
* تحديث بيانات شركة
|
|
*/
|
|
async update(tenantId: string, id: string, dto: any): Promise<Company> {
|
|
const company = await this.findOne(tenantId, id);
|
|
Object.assign(company, dto);
|
|
return this.companyRepository.save(company);
|
|
}
|
|
|
|
/**
|
|
* حفظ مفاتيح جو فوترة (مُشفرة)
|
|
*/
|
|
async setJoFotaraCredentials(
|
|
tenantId: string,
|
|
id: string,
|
|
clientId: string,
|
|
secretKey: string,
|
|
): Promise<void> {
|
|
const company = await this.findOne(tenantId, id);
|
|
|
|
company.jofotara_client_id_encrypted = this.encryptionService.encrypt(clientId);
|
|
company.jofotara_secret_key_encrypted = this.encryptionService.encrypt(secretKey);
|
|
|
|
await this.companyRepository.save(company);
|
|
}
|
|
|
|
/**
|
|
* الحصول على المفاتيح (مفكوك تشفيرها) — للاستخدام الداخلي فقط
|
|
*/
|
|
async getDecryptedCredentials(tenantId: string, id: string) {
|
|
const company = await this.companyRepository.findOne({
|
|
where: { id, tenant_id: tenantId },
|
|
select: ['jofotara_client_id_encrypted', 'jofotara_secret_key_encrypted'],
|
|
});
|
|
|
|
if (!company || !company.jofotara_client_id_encrypted || !company.jofotara_secret_key_encrypted) {
|
|
throw new NotFoundException('JoFotara credentials not set for this company');
|
|
}
|
|
|
|
return {
|
|
clientId: this.encryptionService.decrypt(company.jofotara_client_id_encrypted),
|
|
secretKey: this.encryptionService.decrypt(company.jofotara_secret_key_encrypted),
|
|
};
|
|
}
|
|
}
|