dcb-backoffice/src/app/modules/dcb-dashboard/services/dashboard-access.service.ts
2026-01-13 03:49:10 +00:00

274 lines
8.0 KiB
TypeScript

import { Injectable } from '@angular/core';
import { Observable, of, BehaviorSubject } from 'rxjs';
import { map, catchError, switchMap, take, filter, tap } from 'rxjs/operators';
import { UserRole, RoleManagementService } from '@core/services/hub-users-roles-management.service';
import { MerchantConfigService } from '@modules/merchant-config/merchant-config.service';
import { AuthService } from '@core/services/auth.service';
export interface DashboardAccess {
isHubUser: boolean;
isMerchantUser: boolean;
userRole: UserRole;
merchantId?: number;
}
export interface AllowedMerchant {
id: number | undefined;
name: string;
}
@Injectable({ providedIn: 'root' })
export class DashboardAccessService {
private accessCache: DashboardAccess | null = null;
private merchantsCache: AllowedMerchant[] | null = null;
private currentMerchantId: number | null = null;
private ready$ = new BehaviorSubject<boolean>(false);
private profileLoaded = false;
constructor(
private roleService: RoleManagementService,
private merchantService: MerchantConfigService,
private authService: AuthService
) {
// Initialisation simple
this.initialize();
}
private initialize(): void {
console.log('🚀 DashboardAccessService: Initialisation');
// S'abonner aux changements de profil
this.authService.getUserProfile().subscribe({
next: (profile) => {
if (profile) {
console.log('✅ DashboardAccessService: Profil chargé', {
username: profile.username,
merchantPartnerId: profile.merchantPartnerId,
userType: profile.userType
});
this.profileLoaded = true;
this.ready$.next(true);
}
},
error: (err) => {
console.error('❌ DashboardAccessService: Erreur de profil:', err);
this.profileLoaded = false;
this.ready$.next(false);
}
});
// Nettoyer à la déconnexion
this.authService.getAuthState().subscribe(isAuthenticated => {
if (!isAuthenticated) {
console.log('🚨 DashboardAccessService: Déconnexion détectée');
this.clearCache();
this.profileLoaded = false;
this.ready$.next(false);
}
});
}
// Attendre que le service soit prêt AVEC PROFIL CHARGÉ
waitForReady(): Observable<boolean> {
return this.ready$.pipe(
filter(ready => ready && this.profileLoaded),
take(1),
tap(() => {
console.log('✅ DashboardAccessService: waitForReady() - Service vraiment prêt');
})
);
}
// Obtenir l'accès dashboard
getDashboardAccess(): DashboardAccess {
if (this.accessCache) {
return this.accessCache;
}
// VÉRIFIER que le profil est chargé
if (!this.profileLoaded) {
console.warn('⚠️ DashboardAccessService: Tentative d\'accès avant chargement du profil');
throw new Error('Profil non chargé');
}
const profile = this.authService.getCurrentUserProfile();
// VÉRIFIER que le profil existe
if (!profile) {
console.error('❌ DashboardAccessService: Profil null dans getDashboardAccess()');
throw new Error('Profil utilisateur non disponible');
}
console.log('📊 DashboardAccessService: getDashboardAccess() avec profil:', {
username: profile.username,
merchantPartnerId: profile.merchantPartnerId,
userType: profile.userType
});
const userRole = this.roleService.getCurrentRole();
const isHubUser = this.roleService.isHubUser();
let merchantId: number | undefined = undefined;
if (!isHubUser && profile.merchantPartnerId) {
merchantId = Number(profile.merchantPartnerId);
if (isNaN(merchantId) || merchantId <= 0) {
console.warn(`⚠️ DashboardAccessService: merchantPartnerId invalide: ${profile.merchantPartnerId}`);
merchantId = undefined;
}
}
this.accessCache = {
isHubUser,
isMerchantUser: !isHubUser,
userRole: userRole || UserRole.DCB_SUPPORT,
merchantId
};
console.log('🎯 DashboardAccessService: Accès créé:', this.accessCache);
return this.accessCache;
}
// Obtenir l'accès dashboard avec attente
getDashboardAccessAsync(): Observable<DashboardAccess> {
return this.waitForReady().pipe(
map(() => this.getDashboardAccess())
);
}
// Obtenir les marchands disponibles
getAvailableMerchants(): Observable<AllowedMerchant[]> {
return this.waitForReady().pipe(
switchMap(() => {
if (this.merchantsCache) {
return of(this.merchantsCache);
}
const access = this.getDashboardAccess();
if (access.isHubUser) {
return this.merchantService.getAllMerchants().pipe(
map(merchants => {
const available: AllowedMerchant[] = merchants.items.map(m => ({
id: m.id,
name: m.name
}));
// Option globale pour les hub users
available.unshift({ id: 0, name: '🌐 Données globales' });
this.merchantsCache = available;
return available;
}),
catchError(() => {
return of([{ id: 0, name: '🌐 Données globales' }]);
})
);
} else {
// Merchant user: seulement son merchant
const merchantId = access.merchantId;
if (merchantId) {
const merchants = [{ id: merchantId, name: `🏪 Merchant ${merchantId}` }];
this.merchantsCache = merchants;
return of(merchants);
}
return of([]);
}
})
);
}
// Définir le marchand sélectionné (hub users seulement)
setSelectedMerchantId(merchantId: number): void {
if (this.getDashboardAccess().isHubUser) {
this.currentMerchantId = merchantId;
}
}
// Obtenir le marchand sélectionné
getSelectedMerchantId(): number | null {
const access = this.getDashboardAccess();
if (access.isMerchantUser) {
return access.merchantId || null;
}
return this.currentMerchantId;
}
// Nettoyer le cache
clearCache(): void {
this.accessCache = null;
this.merchantsCache = null;
this.currentMerchantId = null;
}
// ============ MÉTHODES UTILITAIRES SIMPLES ============
shouldShowSystemHealth(): boolean {
return this.getDashboardAccess().isHubUser;
}
shouldShowAlerts(): boolean {
return true;
}
canTriggerSync(): boolean {
const access = this.getDashboardAccess();
return access.isHubUser && access.userRole === UserRole.DCB_ADMIN;
}
canManageMerchants(): boolean {
const access = this.getDashboardAccess();
return access.isHubUser && access.userRole === UserRole.DCB_ADMIN;
}
canSelectMerchant(): boolean {
return this.getDashboardAccess().isHubUser;
}
canEditMerchantFilter(): boolean {
const access = this.getDashboardAccess();
if (access.isHubUser) {
return access.userRole === UserRole.DCB_ADMIN;
}
return access.userRole === UserRole.DCB_PARTNER_ADMIN;
}
shouldShowMerchantId(): boolean {
const access = this.getDashboardAccess();
return access.isMerchantUser ||
(access.isHubUser && this.getSelectedMerchantId() !== null);
}
canViewGlobalData(): boolean {
return this.getDashboardAccess().isHubUser;
}
isViewingGlobalData(): boolean {
const access = this.getDashboardAccess();
if (access.isHubUser) {
return this.currentMerchantId === 0 || this.currentMerchantId === null;
}
return false;
}
getCurrentMerchantName(): string {
const access = this.getDashboardAccess();
if (access.isMerchantUser && access.merchantId) {
return `Merchant ${access.merchantId}`;
}
if (access.isHubUser) {
if (this.currentMerchantId === 0 || this.currentMerchantId === null) {
return 'Données globales';
} else if (this.currentMerchantId) {
return `Merchant ${this.currentMerchantId}`;
}
}
return 'Inconnu';
}
}