dcb-backoffice/src/app/modules/transactions/services/transactions.service.ts

177 lines
5.4 KiB
TypeScript

import { Injectable, inject } from '@angular/core';
import { HttpClient, HttpParams } from '@angular/common/http';
import { environment } from '@environments/environment';
import { Observable, map, catchError, throwError } from 'rxjs';
import {
Transaction,
TransactionQuery,
PaginatedTransactions,
TransactionStats,
RefundRequest
} from '../models/transaction';
@Injectable({ providedIn: 'root' })
export class TransactionsService {
private http = inject(HttpClient);
private apiUrl = `${environment.localServiceTestApiUrl}/transactions`;
// === CRUD OPERATIONS ===
getTransactions(query: TransactionQuery): Observable<PaginatedTransactions> {
let params = new HttpParams();
// Ajouter tous les paramètres de query
Object.keys(query).forEach(key => {
const value = query[key as keyof TransactionQuery];
if (value !== undefined && value !== null) {
if (value instanceof Date) {
params = params.set(key, value.toISOString());
} else {
params = params.set(key, value.toString());
}
}
});
return this.http.get<PaginatedTransactions>(`${this.apiUrl}`, { params }).pipe(
catchError(error => {
console.error('Error loading transactions:', error);
return throwError(() => error);
})
);
}
getTransactionById(id: string): Observable<Transaction> {
return this.http.get<Transaction>(`${this.apiUrl}/${id}`).pipe(
catchError(error => {
console.error('Error loading transaction:', error);
return throwError(() => error);
})
);
}
// === ACTIONS ===
refundTransaction(refundRequest: RefundRequest): Observable<{ message: string; transaction: Transaction }> {
return this.http.post<{ message: string; transaction: Transaction }>(
`${this.apiUrl}/${refundRequest.transactionId}/refund`,
refundRequest
);
}
cancelTransaction(transactionId: string): Observable<{ message: string }> {
return this.http.post<{ message: string }>(
`${this.apiUrl}/${transactionId}/cancel`,
{}
);
}
retryTransaction(transactionId: string): Observable<{ message: string; transaction: Transaction }> {
return this.http.post<{ message: string; transaction: Transaction }>(
`${this.apiUrl}/${transactionId}/retry`,
{}
);
}
// === STATISTIQUES ===
getTransactionStats(query?: Partial<TransactionQuery>): Observable<TransactionStats> {
let params = new HttpParams();
if (query) {
Object.keys(query).forEach(key => {
const value = query[key as keyof TransactionQuery];
if (value !== undefined && value !== null) {
if (value instanceof Date) {
params = params.set(key, value.toISOString());
} else {
params = params.set(key, value.toString());
}
}
});
}
return this.http.get<TransactionStats>(`${this.apiUrl}/stats`, { params });
}
// === EXPORT ===
exportTransactions(exportRequest: any): Observable<{ url: string; filename: string }> {
return this.http.post<{ url: string; filename: string }>(
`${this.apiUrl}/export`,
exportRequest
);
}
// === MOCK DATA POUR LE DÉVELOPPEMENT ===
getMockTransactions(): Transaction[] {
return [
{
id: 'tx_001',
msisdn: '+33612345678',
operator: 'Orange',
operatorId: 'orange_fr',
country: 'FR',
amount: 4.99,
currency: 'EUR',
status: 'SUCCESS',
productId: 'prod_premium',
productName: 'Contenu Premium',
productCategory: 'ENTERTAINMENT',
transactionDate: new Date('2024-01-15T14:30:00'),
createdAt: new Date('2024-01-15T14:30:00'),
updatedAt: new Date('2024-01-15T14:30:00'),
externalId: 'ext_123456',
merchantName: 'MediaCorp'
},
{
id: 'tx_002',
msisdn: '+33798765432',
operator: 'Free',
operatorId: 'free_fr',
country: 'FR',
amount: 2.99,
currency: 'EUR',
status: 'PENDING',
productId: 'prod_basic',
productName: 'Abonnement Basique',
productCategory: 'SUBSCRIPTION',
transactionDate: new Date('2024-01-15T14:25:00'),
createdAt: new Date('2024-01-15T14:25:00'),
updatedAt: new Date('2024-01-15T14:25:00'),
externalId: 'ext_123457'
},
{
id: 'tx_003',
msisdn: '+33687654321',
operator: 'SFR',
operatorId: 'sfr_fr',
country: 'FR',
amount: 9.99,
currency: 'EUR',
status: 'FAILED',
productId: 'prod_pro',
productName: 'Pack Professionnel',
productCategory: 'BUSINESS',
transactionDate: new Date('2024-01-15T14:20:00'),
createdAt: new Date('2024-01-15T14:20:00'),
updatedAt: new Date('2024-01-15T14:20:00'),
errorCode: 'INSUFFICIENT_FUNDS',
errorMessage: 'Solde insuffisant'
},
{
id: 'tx_004',
msisdn: '+33611223344',
operator: 'Bouygues',
operatorId: 'bouygues_fr',
country: 'FR',
amount: 1.99,
currency: 'EUR',
status: 'REFUNDED',
productId: 'prod_mini',
productName: 'Pack Découverte',
productCategory: 'GAMING',
transactionDate: new Date('2024-01-15T14:15:00'),
createdAt: new Date('2024-01-15T14:15:00'),
updatedAt: new Date('2024-01-15T16:30:00'),
merchantName: 'GameStudio'
}
];
}
}