🚀 Initialize Musadaq SaaS: Full Backend + AI + React Dashboard + Docker Setup
This commit is contained in:
113
backend/src/modules/companies/company.service.ts
Normal file
113
backend/src/modules/companies/company.service.ts
Normal file
@@ -0,0 +1,113 @@
|
||||
/**
|
||||
* ════════════════════════════════════════════════════════════
|
||||
* مُصادَق (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),
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user