dcb-backoffice/src/app/core/models/merchant-config.model.ts

239 lines
5.8 KiB
TypeScript

// === ENUMS COHÉRENTS ===
export enum UserType {
HUB = 'HUB',
MERCHANT_PARTNER = 'MERCHANT'
}
export enum UserRole {
// Rôles Hub (sans merchantPartnerId)
DCB_ADMIN = 'dcb-admin',
DCB_SUPPORT = 'dcb-support',
DCB_PARTNER = 'dcb-partner',
// Rôles Merchant Partner (avec merchantPartnerId obligatoire)
DCB_PARTNER_ADMIN = 'dcb-partner-admin',
DCB_PARTNER_MANAGER = 'dcb-partner-manager',
DCB_PARTNER_SUPPORT = 'dcb-partner-support'
}
export enum MerchantStatus {
ACTIVE = 'ACTIVE',
INACTIVE = 'INACTIVE',
PENDING = 'PENDING',
SUSPENDED = 'SUSPENDED'
}
export enum ConfigType {
API_KEY = 'API_KEY',
SECRET_KEY = 'SECRET_KEY',
WEBHOOK_URL = 'WEBHOOK_URL',
CALLBACK_URL = 'CALLBACK_URL',
TIMEOUT = 'TIMEOUT',
RETRY_COUNT = 'RETRY_COUNT',
CUSTOM = 'CUSTOM'
}
export enum Operator {
ORANGE_CI = 1,
MTN_CI = 2,
MOOV_CI = 3,
WAVE = 4
}
// === MODÈLES PRINCIPAUX ===
export interface MerchantConfig {
id?: number;
name: ConfigType | string;
value: string;
operatorId: Operator;
merchantId?: number;
createdAt?: string;
updatedAt?: string;
}
export interface TechnicalContact {
id?: number;
firstName: string;
lastName: string;
phone: string;
email: string;
merchantId?: number;
createdAt?: string;
updatedAt?: string;
}
export interface MerchantUser {
userId: string;
role: UserRole; // Utilisation de vos rôles existants
username?: string;
email?: string;
firstName?: string;
lastName?: string;
merchantPartnerId?: number;
}
export interface Merchant {
id?: number;
name: string;
logo?: string;
description?: string;
adresse: string;
phone: string;
status?: MerchantStatus;
configs: MerchantConfig[];
users: MerchantUser[];
technicalContacts: TechnicalContact[];
createdAt?: string;
updatedAt?: string;
createdBy?: string;
createdByUsername?: string;
}
// === DTOs CRUD ===
export interface CreateMerchantDto {
name: string;
logo?: string;
description?: string;
adresse: string;
phone: string;
configs: Omit<MerchantConfig, 'id' | 'merchantId' | 'createdAt' | 'updatedAt'>[];
technicalContacts: Omit<TechnicalContact, 'id' | 'merchantId' | 'createdAt' | 'updatedAt'>[];
}
export interface UpdateMerchantDto extends Partial<CreateMerchantDto> {
status?: MerchantStatus;
}
export interface AddUserToMerchantDto {
userId: string;
role: UserRole; // Utilisation de vos rôles existants
merchantPartnerId: number;
}
export interface UpdateUserRoleDto {
role: UserRole; // Utilisation de vos rôles existants
}
// === RÉPONSES API ===
export interface ApiResponse<T> {
success: boolean;
data?: T;
error?: string;
message?: string;
}
export interface PaginatedResponse<T> {
items: T[];
total: number;
page: number;
limit: number;
totalPages: number;
}
export interface MerchantStatsResponse {
totalMerchants: number;
activeMerchants: number;
inactiveMerchants: number;
pendingMerchants: number;
totalConfigs: number;
totalTechnicalContacts: number;
}
// === SEARCH ===
export interface SearchMerchantsParams {
query?: string;
status?: MerchantStatus;
page?: number;
limit?: number;
}
// === UTILITAIRES ===
export class MerchantUtils {
static getStatusDisplayName(status: MerchantStatus): string {
const statusNames = {
[MerchantStatus.ACTIVE]: 'Actif',
[MerchantStatus.INACTIVE]: 'Inactif',
[MerchantStatus.PENDING]: 'En attente',
[MerchantStatus.SUSPENDED]: 'Suspendu'
};
return statusNames[status] || status;
}
static getStatusBadgeClass(status: MerchantStatus): string {
const statusClasses = {
[MerchantStatus.ACTIVE]: 'badge bg-success',
[MerchantStatus.INACTIVE]: 'badge bg-secondary',
[MerchantStatus.PENDING]: 'badge bg-warning',
[MerchantStatus.SUSPENDED]: 'badge bg-danger'
};
return statusClasses[status] || 'badge bg-secondary';
}
static getOperatorName(operatorId: Operator): string {
const operatorNames = {
[Operator.ORANGE_CI]: 'Orange CI',
[Operator.MTN_CI]: 'MTN CI',
[Operator.MOOV_CI]: 'Moov CI',
[Operator.WAVE]: 'Wave'
};
return operatorNames[operatorId] || 'Inconnu';
}
static getConfigTypeName(configName: ConfigType | string): string {
const configTypeNames = {
[ConfigType.API_KEY]: 'Clé API',
[ConfigType.SECRET_KEY]: 'Clé Secrète',
[ConfigType.WEBHOOK_URL]: 'URL Webhook',
[ConfigType.CALLBACK_URL]: 'URL Callback',
[ConfigType.TIMEOUT]: 'Timeout (ms)',
[ConfigType.RETRY_COUNT]: 'Nombre de tentatives',
[ConfigType.CUSTOM]: 'Personnalisé'
};
return configTypeNames[configName as ConfigType] || configName;
}
static validateMerchantCreation(merchant: CreateMerchantDto): string[] {
const errors: string[] = [];
if (!merchant.name?.trim()) {
errors.push('Le nom du merchant est requis');
}
if (!merchant.adresse?.trim()) {
errors.push('L\'adresse est requise');
}
if (!merchant.phone?.trim()) {
errors.push('Le téléphone est requis');
}
if (!merchant.technicalContacts || merchant.technicalContacts.length === 0) {
errors.push('Au moins un contact technique est requis');
}
if (!merchant.configs || merchant.configs.length === 0) {
errors.push('Au moins une configuration est requise');
}
return errors;
}
// Méthode pour obtenir les rôles disponibles pour les merchants
static getAvailableMerchantRoles(): UserRole[] {
return [
UserRole.DCB_PARTNER_ADMIN,
UserRole.DCB_PARTNER_MANAGER,
UserRole.DCB_PARTNER_SUPPORT
];
}
// Vérifier si un rôle est valide pour un merchant
static isValidMerchantRole(role: UserRole): boolean {
const merchantRoles = [
UserRole.DCB_PARTNER_ADMIN,
UserRole.DCB_PARTNER_MANAGER,
UserRole.DCB_PARTNER_SUPPORT
];
return merchantRoles.includes(role);
}
}