test
This commit is contained in:
@@ -24,6 +24,7 @@ export interface Resultat {
|
||||
totalMises: number;
|
||||
masseAPartager: number;
|
||||
prelevementsLegaux: number;
|
||||
statut: ResultatStatut;
|
||||
montantRembourse: number;
|
||||
montantCagnotte: number;
|
||||
adeadHeat: boolean;
|
||||
|
||||
@@ -9,7 +9,7 @@ import { normalizePage } from '@shared/paging/normalize-page';
|
||||
import { ListParams, PagedResult } from '@shared/paging/paging';
|
||||
|
||||
const USE_SERVER = true;
|
||||
const API_BASE = '/api/v1/agents';
|
||||
const API_BASE = '/api/agents';
|
||||
|
||||
// Interface to match the API response structure for TPE (nested in Agent)
|
||||
// Note: When TPE is nested in Agent's tpes array, the agent field might be omitted or be a reference
|
||||
@@ -270,49 +270,39 @@ export class AgentService {
|
||||
|
||||
// GET /api/v1/agents - List all
|
||||
list(params?: ListParams): Observable<PagedResult<Agent>> {
|
||||
if (USE_SERVER) {
|
||||
let httpParams = new HttpParams();
|
||||
if (params) {
|
||||
if (params.page) httpParams = httpParams.set('page', params.page.toString());
|
||||
if (params.size) httpParams = httpParams.set('perPage', params.size.toString());
|
||||
if (params.search) httpParams = httpParams.set('search', params.search);
|
||||
if (params.sortKey) httpParams = httpParams.set('sortKey', params.sortKey);
|
||||
if (params.sortDir) httpParams = httpParams.set('sortDir', params.sortDir);
|
||||
}
|
||||
|
||||
return this.http
|
||||
.get<AgentApiResponse[]>(this.apiUrl, {
|
||||
params: httpParams,
|
||||
headers: this.getNgrokHeaders(),
|
||||
})
|
||||
.pipe(
|
||||
map((list) => {
|
||||
const agents = list.map((apiAgent) => {
|
||||
const transformed = this.transformAgent(apiAgent);
|
||||
return transformed;
|
||||
});
|
||||
// If pagination params provided, return paginated result
|
||||
if (params) {
|
||||
return normalizePage<Agent>(
|
||||
{ data: agents, meta: { total: agents.length } },
|
||||
params.page || 1,
|
||||
params.size || 10
|
||||
);
|
||||
}
|
||||
// Otherwise return all as single page
|
||||
return normalizePage<Agent>(
|
||||
{ data: agents, meta: { total: agents.length } },
|
||||
1,
|
||||
agents.length
|
||||
);
|
||||
}),
|
||||
catchError((err) => {
|
||||
console.error('Error fetching agents:', err);
|
||||
return of(normalizePage<Agent>({ data: [], meta: { total: 0 } }, 1, 10));
|
||||
})
|
||||
);
|
||||
let httpParams = new HttpParams();
|
||||
if (params) {
|
||||
if (params.page) httpParams = httpParams.set('page', params.page.toString());
|
||||
if (params.size) httpParams = httpParams.set('perPage', params.size.toString());
|
||||
if (params.search) httpParams = httpParams.set('search', params.search);
|
||||
if (params.sortKey) httpParams = httpParams.set('sortKey', params.sortKey);
|
||||
if (params.sortDir) httpParams = httpParams.set('sortDir', params.sortDir);
|
||||
}
|
||||
return of(normalizePage<Agent>({ data: [], meta: { total: 0 } }, 1, 10));
|
||||
|
||||
return this.http
|
||||
.get<PagedResult<AgentApiResponse>>(this.apiUrl, {
|
||||
params: httpParams,
|
||||
headers: this.getNgrokHeaders(),
|
||||
})
|
||||
.pipe(
|
||||
map((res) => {
|
||||
const agents = res.content.map((apiAgent) => {
|
||||
const transformed = this.transformAgent(apiAgent);
|
||||
return transformed;
|
||||
});
|
||||
// If pagination params provided, return paginated result
|
||||
const resAgent = {
|
||||
...res,
|
||||
content: agents
|
||||
}
|
||||
// Otherwise return all as single page
|
||||
return resAgent;
|
||||
}),
|
||||
catchError((err) => {
|
||||
console.error('Error fetching agents:', err);
|
||||
return of(normalizePage<Agent>({ content: [], meta: { total: 0 } }, 1, 10));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// POST /api/v1/agents - Create
|
||||
|
||||
40
src/app/core/services/depouillement.spec.ts
Normal file
40
src/app/core/services/depouillement.spec.ts
Normal file
@@ -0,0 +1,40 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
|
||||
import { Depouillement, ResultatCourse } from './depouillement';
|
||||
import { environment } from 'src/environments/environment.development';
|
||||
|
||||
describe('Depouillement', () => {
|
||||
let service: Depouillement;
|
||||
let httpMock: HttpTestingController;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({ imports: [HttpClientTestingModule] });
|
||||
service = TestBed.inject(Depouillement);
|
||||
httpMock = TestBed.inject(HttpTestingController);
|
||||
});
|
||||
|
||||
afterEach(() => httpMock.verify());
|
||||
|
||||
it('should be created', () => {
|
||||
expect(service).toBeTruthy();
|
||||
});
|
||||
|
||||
it('should POST resultat to depouillement endpoint', () => {
|
||||
const payload: ResultatCourse = {
|
||||
id: 12,
|
||||
course: { id: '1', hippodrome: undefined, reunionNumero: 0, reunionDate: '', nom: 'C1', numero: 1, heureDepartPrevue: '', discipline: '', distanceMetres: 0, categorie: '', nombrePartants: 0, statut: '', annulee: false, reporteeMemeJour: false, reporteeAutreJour: false, incidentTechnique: false, nonPartants: [], typesParisOuverts: [] },
|
||||
statut: 0 as any,
|
||||
ordreArrivee: '1,2,3',
|
||||
} as ResultatCourse;
|
||||
|
||||
service.sendResultat(payload).subscribe((res) => {
|
||||
expect(res).toBeTruthy();
|
||||
expect(res.id).toEqual(payload.id);
|
||||
});
|
||||
|
||||
const req = httpMock.expectOne(environment.apiBaseUrl + '/api/depouillement');
|
||||
expect(req.request.method).toBe('POST');
|
||||
expect(req.request.body).toEqual(payload);
|
||||
req.flush(payload);
|
||||
});
|
||||
});
|
||||
53
src/app/core/services/depouillement.ts
Normal file
53
src/app/core/services/depouillement.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { Injectable } from '@angular/core';
|
||||
import { HttpClient } from '@angular/common/http';
|
||||
import { Observable, of } from 'rxjs';
|
||||
import { catchError, map } from 'rxjs/operators';
|
||||
import { Course } from '../interfaces/course';
|
||||
import { ResultatStatut } from '../interfaces/resultat';
|
||||
import { environment } from 'src/environments/environment.development';
|
||||
|
||||
export interface ResultatCourse {
|
||||
id: number;
|
||||
course: Course;
|
||||
statut: ResultatStatut;
|
||||
ordreArrivee: string;
|
||||
datePublication?: string; // ISO string
|
||||
dateValidation?: string; // ISO string
|
||||
dateAnnulation?: string; // ISO string
|
||||
notes?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
}
|
||||
|
||||
const API_BASE = '/api/v1/depouillement';
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class Depouillement {
|
||||
private apiUrl = environment.depouillementBaseUrl + API_BASE;
|
||||
|
||||
constructor(private http: HttpClient) {}
|
||||
|
||||
private getNgrokHeaders(): Record<string, string> {
|
||||
const isNgrok =
|
||||
environment.apiBaseUrl.includes('ngrok-free.app') ||
|
||||
environment.apiBaseUrl.includes('ngrok.io') ||
|
||||
environment.apiBaseUrl.includes('ngrok');
|
||||
return isNgrok ? { 'ngrok-skip-browser-warning': 'true' } : {};
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a resultat to the dépouillement endpoint.
|
||||
* The backend expects a payload shaped like ResultatCourse.
|
||||
*/
|
||||
sendResultat(resultat: Omit<ResultatCourse, "id">): Observable<{}> {
|
||||
return this.http.post<ResultatCourse>(this.apiUrl, resultat, { headers: this.getNgrokHeaders() }).pipe(
|
||||
map((res) => res as ResultatCourse),
|
||||
catchError((err) => {
|
||||
console.error('Error sending resultat to depouillement:', err);
|
||||
return of(resultat); // return original payload on error to allow UI to proceed gracefully
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -137,28 +137,43 @@ export class ResultatService {
|
||||
})
|
||||
.pipe(
|
||||
switchMap((raw) => {
|
||||
// Some courses don't have a resultat yet.
|
||||
// In that case the API returns 200 with a body like:
|
||||
// { "message": "Aucun résultat disponible pour cette course" }
|
||||
// We interpret this as "no resultat" and return undefined.
|
||||
if (
|
||||
raw &&
|
||||
typeof raw === 'object' &&
|
||||
'message' in raw &&
|
||||
!('id' in raw) &&
|
||||
!('ordreArrivee' in raw)
|
||||
) {
|
||||
// Debug raw response shape to help detect API changes
|
||||
console.debug(`ResultatService.getByCourseId(${courseId}) raw:`, raw);
|
||||
// Handle common variants of server responses:
|
||||
// - { message: '...' } -> no resultat
|
||||
// - { id: ..., ordreArrivee: '...' } -> single resultat
|
||||
// - [ { ... } ] -> array of resultats (pick first)
|
||||
// - { content: [...] } -> take first content
|
||||
|
||||
if (!raw) return of<Resultat | undefined>(undefined);
|
||||
|
||||
// message-only response -> no resultat
|
||||
if (typeof raw === 'object' && 'message' in raw && !('id' in raw) && !('ordreArrivee' in raw)) {
|
||||
return of<Resultat | undefined>(undefined);
|
||||
}
|
||||
|
||||
const apiResultat = raw as ResultatApiResponse;
|
||||
let apiResultat: ResultatApiResponse | undefined;
|
||||
|
||||
if (Array.isArray(raw)) {
|
||||
apiResultat = raw.length > 0 ? (raw[0] as ResultatApiResponse) : undefined;
|
||||
} else if (raw && typeof raw === 'object') {
|
||||
if ('id' in raw || 'ordreArrivee' in raw) {
|
||||
apiResultat = raw as ResultatApiResponse;
|
||||
} else if ('content' in raw && Array.isArray(raw.content) && raw.content.length > 0) {
|
||||
apiResultat = raw.content[0] as ResultatApiResponse;
|
||||
} else if ('data' in raw && raw.data && typeof raw.data === 'object') {
|
||||
apiResultat = raw.data as ResultatApiResponse;
|
||||
}
|
||||
}
|
||||
|
||||
if (!apiResultat) return of<Resultat | undefined>(undefined);
|
||||
|
||||
return this.courseService.getById(courseId).pipe(
|
||||
map((course) => {
|
||||
if (!course) {
|
||||
return undefined;
|
||||
}
|
||||
return this.transformApiResponse(apiResultat, course);
|
||||
return this.transformApiResponse(apiResultat!, course);
|
||||
})
|
||||
);
|
||||
}),
|
||||
@@ -264,6 +279,7 @@ export class ResultatService {
|
||||
course,
|
||||
// API now returns 'ordreArrivee' as CSV/string; normalize to number[]
|
||||
ordreArrivee: apiResultat.ordreArrivee,
|
||||
statut: apiResultat.statut,
|
||||
// dead-heat not provided by new API shape — default to empty
|
||||
chevauxDeadHeat: [],
|
||||
// Financial fields may not be present in new API; default to 0
|
||||
|
||||
@@ -9,64 +9,72 @@ import { normalizePage } from '@shared/paging/normalize-page';
|
||||
import { ListParams, PagedResult } from '@shared/paging/paging';
|
||||
|
||||
const USE_SERVER = true;
|
||||
const API_BASE = '/api/v1/tpes';
|
||||
const API_BASE = '/api/terminaux';
|
||||
|
||||
// Interface to match the API response structure for Agent (nested in TPE)
|
||||
interface AgentApiResponse {
|
||||
id: number;
|
||||
code: string;
|
||||
profile: string;
|
||||
principalCode?: string;
|
||||
caisseProfile?: string;
|
||||
statut: string;
|
||||
zone?: string;
|
||||
kiosk?: string;
|
||||
fonction?: string;
|
||||
dateEmbauche?: string;
|
||||
nom: string;
|
||||
prenom: string;
|
||||
autresNoms?: string;
|
||||
dateNaissance?: string;
|
||||
lieuNaissance?: string;
|
||||
ville?: string;
|
||||
adresse?: string;
|
||||
autoriserAides?: boolean;
|
||||
phone: string;
|
||||
pin?: string;
|
||||
limiteInferieure?: number;
|
||||
limiteSuperieure?: number;
|
||||
limiteParTransaction?: number;
|
||||
limiteMinAirtime?: number;
|
||||
limiteMaxAirtime?: number;
|
||||
maxPeripheriques?: number;
|
||||
limitId?: number;
|
||||
nationalite?: string;
|
||||
cni?: string;
|
||||
cniDelivreeLe?: string;
|
||||
cniDelivreeA?: string;
|
||||
residence?: string;
|
||||
autreAdresse1?: string;
|
||||
statutMarital?: string;
|
||||
epoux?: string;
|
||||
autreTelephone?: string;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
createdBy?: string;
|
||||
id: number,
|
||||
code: String,
|
||||
profil: String,
|
||||
principalCode: String,
|
||||
caisseProfile: String,
|
||||
statut: AgentStatus,
|
||||
zone: String,
|
||||
kiosk: String,
|
||||
fonction: String,
|
||||
dateEmbauche: String,
|
||||
nom: String,
|
||||
"prenom": String,
|
||||
"autresNoms": String,
|
||||
"dateNaissance": String,
|
||||
"lieuNaissance": String,
|
||||
"ville": String,
|
||||
"adresse": String,
|
||||
"autoriserAides": boolean,
|
||||
"phone": String,
|
||||
"limiteInferieure": number,
|
||||
"limiteSuperieure": number,
|
||||
"limiteParTransaction": number,
|
||||
"limiteMinAirtime": number,
|
||||
"limiteMaxAirtime": number,
|
||||
"maxPeripheriques": number,
|
||||
"limitId": String,
|
||||
"nationalite": String,
|
||||
"cni": String,
|
||||
"cniDelivreeLe": String,
|
||||
"cniDelivreeA": String,
|
||||
"residence": String,
|
||||
"autreAdresse1": String,
|
||||
"statutMarital": String,
|
||||
"epoux": String,
|
||||
"autreTelephone": String,
|
||||
"createdAt": String,
|
||||
"updatedAt": String,
|
||||
"createdBy": String,
|
||||
"terminauxIds": [
|
||||
number[]
|
||||
]
|
||||
}
|
||||
|
||||
// Interface to match the API response structure
|
||||
interface TpeApiResponse {
|
||||
id: number;
|
||||
imei: string;
|
||||
serial: string;
|
||||
type: string;
|
||||
marque: string;
|
||||
modele: string;
|
||||
statut: string; // API uses uppercase: VALIDE, INVALIDE, EN_PANNE, BLOQUE
|
||||
agent?: AgentApiResponse;
|
||||
assigne: boolean;
|
||||
createdAt?: string;
|
||||
updatedAt?: string;
|
||||
id: number,
|
||||
numeroSerie: String,
|
||||
pointDeVenteId: number,
|
||||
statut: TpeStatus,
|
||||
derniereConnexion: String,
|
||||
versionLogicielle: String,
|
||||
typeTerminal: String,
|
||||
plateforme: String,
|
||||
modeleAppareil: String,
|
||||
systemeExploitation: String,
|
||||
versionOs: String,
|
||||
adresseIp: String,
|
||||
adresseMac: String,
|
||||
agentConnecteId: number,
|
||||
derniereConnexionAgent: String,
|
||||
derniereDeconnexionAgent: String,
|
||||
journalSession: String
|
||||
}
|
||||
|
||||
// Stats interfaces
|
||||
@@ -114,29 +122,29 @@ export class TpeService {
|
||||
return statut; // Already uppercase, no transformation needed
|
||||
}
|
||||
|
||||
// Transform API Agent response to Agent
|
||||
// Transform API Agent response to Agent (lightweight mapping)
|
||||
private transformAgent(apiAgent: AgentApiResponse): Agent {
|
||||
return {
|
||||
id: String(apiAgent.id),
|
||||
code: apiAgent.code,
|
||||
profile: apiAgent.profile,
|
||||
principalCode: apiAgent.principalCode,
|
||||
caisseProfile: apiAgent.caisseProfile,
|
||||
code: String((apiAgent as any).code || ''),
|
||||
profile: String((apiAgent as any).profile || ''),
|
||||
principalCode: (apiAgent as any).principalCode ? String((apiAgent as any).principalCode) : undefined,
|
||||
caisseProfile: (apiAgent as any).caisseProfile ? String((apiAgent as any).caisseProfile) : undefined,
|
||||
statut: apiAgent.statut as AgentStatus,
|
||||
zone: apiAgent.zone,
|
||||
kiosk: apiAgent.kiosk,
|
||||
fonction: apiAgent.fonction,
|
||||
dateEmbauche: apiAgent.dateEmbauche,
|
||||
nom: apiAgent.nom,
|
||||
prenom: apiAgent.prenom,
|
||||
autresNoms: apiAgent.autresNoms,
|
||||
dateNaissance: apiAgent.dateNaissance,
|
||||
lieuNaissance: apiAgent.lieuNaissance,
|
||||
ville: apiAgent.ville,
|
||||
adresse: apiAgent.adresse,
|
||||
autoriserAides: apiAgent.autoriserAides,
|
||||
phone: apiAgent.phone,
|
||||
pin: apiAgent.pin,
|
||||
zone: (apiAgent as any).zone ? String((apiAgent as any).zone) : undefined,
|
||||
kiosk: (apiAgent as any).kiosk ? String((apiAgent as any).kiosk) : undefined,
|
||||
fonction: (apiAgent as any).fonction ? String((apiAgent as any).fonction) : undefined,
|
||||
dateEmbauche: apiAgent.dateEmbauche ? String(apiAgent.dateEmbauche) : undefined,
|
||||
nom: String(apiAgent.nom || ''),
|
||||
prenom: String(apiAgent.prenom || ''),
|
||||
autresNoms: apiAgent.autresNoms ? String(apiAgent.autresNoms) : undefined,
|
||||
dateNaissance: apiAgent.dateNaissance ? String(apiAgent.dateNaissance) : undefined,
|
||||
lieuNaissance: apiAgent.lieuNaissance ? String(apiAgent.lieuNaissance) : undefined,
|
||||
ville: apiAgent.ville ? String(apiAgent.ville) : undefined,
|
||||
adresse: apiAgent.adresse ? String(apiAgent.adresse) : undefined,
|
||||
autoriserAides: Boolean(apiAgent.autoriserAides),
|
||||
phone: String(apiAgent.phone || ''),
|
||||
pin: (apiAgent as any).pin ? String((apiAgent as any).pin) : undefined,
|
||||
limiteInferieure: apiAgent.limiteInferieure,
|
||||
limiteSuperieure: apiAgent.limiteSuperieure,
|
||||
limiteParTransaction: apiAgent.limiteParTransaction,
|
||||
@@ -144,146 +152,138 @@ export class TpeService {
|
||||
limiteMaxAirtime: apiAgent.limiteMaxAirtime,
|
||||
maxPeripheriques: apiAgent.maxPeripheriques,
|
||||
limitId: apiAgent.limitId ? String(apiAgent.limitId) : undefined,
|
||||
nationalite: apiAgent.nationalite,
|
||||
cni: apiAgent.cni,
|
||||
cniDelivreeLe: apiAgent.cniDelivreeLe,
|
||||
cniDelivreeA: apiAgent.cniDelivreeA,
|
||||
residence: apiAgent.residence,
|
||||
autreAdresse1: apiAgent.autreAdresse1,
|
||||
statutMarital: apiAgent.statutMarital,
|
||||
epoux: apiAgent.epoux,
|
||||
autreTelephone: apiAgent.autreTelephone,
|
||||
createdAt: apiAgent.createdAt,
|
||||
updatedAt: apiAgent.updatedAt,
|
||||
createdBy: apiAgent.createdBy,
|
||||
nationalite: apiAgent.nationalite ? String(apiAgent.nationalite) : undefined,
|
||||
cni: apiAgent.cni ? String(apiAgent.cni) : undefined,
|
||||
cniDelivreeLe: apiAgent.cniDelivreeLe ? String(apiAgent.cniDelivreeLe) : undefined,
|
||||
cniDelivreeA: apiAgent.cniDelivreeA ? String(apiAgent.cniDelivreeA) : undefined,
|
||||
residence: apiAgent.residence ? String(apiAgent.residence) : undefined,
|
||||
autreAdresse1: apiAgent.autreAdresse1 ? String(apiAgent.autreAdresse1) : undefined,
|
||||
statutMarital: apiAgent.statutMarital ? String(apiAgent.statutMarital) : undefined,
|
||||
epoux: apiAgent.epoux ? String(apiAgent.epoux) : undefined,
|
||||
autreTelephone: apiAgent.autreTelephone ? String(apiAgent.autreTelephone) : undefined,
|
||||
createdAt: apiAgent.createdAt ? String(apiAgent.createdAt) : undefined,
|
||||
updatedAt: apiAgent.updatedAt ? String(apiAgent.updatedAt) : undefined,
|
||||
createdBy: apiAgent.createdBy ? String(apiAgent.createdBy) : undefined,
|
||||
};
|
||||
}
|
||||
|
||||
// Transform API response to TpeDevice
|
||||
private transformTpe(apiTpe: TpeApiResponse): TpeDevice {
|
||||
// Map API-specific names to our generic interface where possible
|
||||
const serial = (apiTpe as any).numeroSerie || (apiTpe as any).serial || '';
|
||||
const imei = (apiTpe as any).imei || serial || '';
|
||||
const typeRaw = String((apiTpe as any).typeTerminal || '').toUpperCase();
|
||||
const type = typeRaw.includes('POS') ? ('POS' as TpeType) : ('OTHER' as TpeType);
|
||||
const marque = (apiTpe as any).plateforme || (apiTpe as any).marque || '';
|
||||
const modele = (apiTpe as any).modeleAppareil || (apiTpe as any).modele || '';
|
||||
const statut = this.transformStatut(String(apiTpe.statut || 'INVALIDE'));
|
||||
// Agent mapping: sometimes API returns an agent object or only an id
|
||||
let agent: Agent | undefined = undefined;
|
||||
if ((apiTpe as any).agent && typeof (apiTpe as any).agent === 'object' && (apiTpe as any).agent.id) {
|
||||
agent = this.transformAgent((apiTpe as any).agent as AgentApiResponse);
|
||||
}
|
||||
const assigne = Boolean((apiTpe as any).agentConnecteId || (apiTpe as any).assigne);
|
||||
|
||||
return {
|
||||
id: String(apiTpe.id),
|
||||
imei: apiTpe.imei,
|
||||
serial: apiTpe.serial,
|
||||
type: apiTpe.type as TpeType,
|
||||
marque: apiTpe.marque,
|
||||
modele: apiTpe.modele,
|
||||
statut: this.transformStatut(apiTpe.statut),
|
||||
agent: apiTpe.agent ? this.transformAgent(apiTpe.agent) : undefined,
|
||||
assigne: apiTpe.assigne,
|
||||
createdAt: apiTpe.createdAt,
|
||||
updatedAt: apiTpe.updatedAt,
|
||||
imei: String(imei),
|
||||
serial: String(serial),
|
||||
type,
|
||||
marque: String(marque),
|
||||
modele: String(modele),
|
||||
statut,
|
||||
agent,
|
||||
assigne,
|
||||
createdAt: (apiTpe as any).createdAt,
|
||||
updatedAt: (apiTpe as any).updatedAt,
|
||||
};
|
||||
}
|
||||
|
||||
// Transform TpeDevice to API payload
|
||||
// Transform TpeDevice to API payload (best-effort)
|
||||
private transformToApiPayload(tpe: Partial<TpeDevice>): any {
|
||||
const payload: any = {};
|
||||
if (tpe.imei !== undefined) payload.imei = tpe.imei;
|
||||
if (tpe.serial !== undefined) payload.serial = tpe.serial;
|
||||
if (tpe.type !== undefined) payload.type = tpe.type;
|
||||
if (tpe.marque !== undefined) payload.marque = tpe.marque;
|
||||
if (tpe.modele !== undefined) payload.modele = tpe.modele;
|
||||
if (tpe.imei !== undefined) payload.numeroSerie = tpe.imei;
|
||||
if (tpe.serial !== undefined) payload.numeroSerie = tpe.serial;
|
||||
if (tpe.type !== undefined) payload.typeTerminal = tpe.type;
|
||||
if (tpe.marque !== undefined) payload.plateforme = tpe.marque;
|
||||
if (tpe.modele !== undefined) payload.modeleAppareil = tpe.modele;
|
||||
if (tpe.statut !== undefined) payload.statut = this.transformStatutToApi(tpe.statut);
|
||||
if (tpe.assigne !== undefined) payload.assigne = tpe.assigne;
|
||||
return payload;
|
||||
}
|
||||
|
||||
// GET /api/v1/tpes/{id} - Get by ID
|
||||
getById(id: string): Observable<TpeDevice | undefined> {
|
||||
if (USE_SERVER) {
|
||||
return this.http
|
||||
.get<TpeApiResponse>(`${this.apiUrl}/${id}`, { headers: this.getNgrokHeaders() })
|
||||
.pipe(
|
||||
map((apiTpe) => this.transformTpe(apiTpe)),
|
||||
catchError((err) => {
|
||||
console.error(`Error fetching TPE ${id}:`, err);
|
||||
return of(undefined);
|
||||
})
|
||||
);
|
||||
}
|
||||
return of(undefined);
|
||||
getById(id: string): Observable<TpeDevice | undefined> {
|
||||
if (USE_SERVER) {
|
||||
return this.http.get<TpeApiResponse>(`${this.apiUrl}/${id}`, { headers: this.getNgrokHeaders() }).pipe(
|
||||
map((api) => this.transformTpe(api)),
|
||||
catchError((err) => {
|
||||
console.error(`Error fetching TPE ${id}:`, err);
|
||||
return of(undefined);
|
||||
})
|
||||
);
|
||||
}
|
||||
return of(undefined);
|
||||
}
|
||||
|
||||
|
||||
// GET /api/v1/tpes - List all
|
||||
list(params?: ListParams): Observable<PagedResult<TpeDevice>> {
|
||||
if (USE_SERVER) {
|
||||
let httpParams = new HttpParams();
|
||||
if (params) {
|
||||
if (params.page) httpParams = httpParams.set('page', params.page.toString());
|
||||
if (params.size) httpParams = httpParams.set('perPage', params.size.toString());
|
||||
if (params.search) httpParams = httpParams.set('search', params.search);
|
||||
if (params.sortKey) httpParams = httpParams.set('sortKey', params.sortKey);
|
||||
if (params.sortDir) httpParams = httpParams.set('sortDir', params.sortDir);
|
||||
}
|
||||
|
||||
return this.http
|
||||
.get<TpeApiResponse[]>(this.apiUrl, {
|
||||
params: httpParams,
|
||||
headers: this.getNgrokHeaders(),
|
||||
})
|
||||
.pipe(
|
||||
map((list) => {
|
||||
const tpes = list.map((apiTpe) => this.transformTpe(apiTpe));
|
||||
// If pagination params provided, return paginated result
|
||||
if (params) {
|
||||
return normalizePage<TpeDevice>(
|
||||
{ data: tpes, meta: { total: tpes.length } },
|
||||
params.page || 1,
|
||||
params.size || 10
|
||||
);
|
||||
}
|
||||
// Otherwise return all as single page
|
||||
return normalizePage<TpeDevice>(
|
||||
{ data: tpes, meta: { total: tpes.length } },
|
||||
1,
|
||||
tpes.length
|
||||
);
|
||||
}),
|
||||
catchError((err) => {
|
||||
console.error('Error fetching TPEs:', err);
|
||||
return of(normalizePage<TpeDevice>({ data: [], meta: { total: 0 } }, 1, 10));
|
||||
})
|
||||
);
|
||||
let httpParams = new HttpParams();
|
||||
if (params) {
|
||||
if (params.page) httpParams = httpParams.set('page', params.page.toString());
|
||||
if (params.size) httpParams = httpParams.set('perPage', params.size.toString());
|
||||
if (params.search) httpParams = httpParams.set('search', params.search);
|
||||
if (params.sortKey) httpParams = httpParams.set('sortKey', params.sortKey);
|
||||
if (params.sortDir) httpParams = httpParams.set('sortDir', params.sortDir);
|
||||
}
|
||||
return of(normalizePage<TpeDevice>({ data: [], meta: { total: 0 } }, 1, 10));
|
||||
}
|
||||
|
||||
return this.http
|
||||
.get<PagedResult<TpeApiResponse>>(this.apiUrl, {
|
||||
params: httpParams,
|
||||
headers: this.getNgrokHeaders(),
|
||||
})
|
||||
.pipe(
|
||||
map((list) => {
|
||||
const content = (list.content || []).map((api) => this.transformTpe(api));
|
||||
return { ...list, content } as PagedResult<TpeDevice>;
|
||||
}),
|
||||
catchError((err) => {
|
||||
console.error('Error fetching TPEs:', err);
|
||||
return of(normalizePage<TpeDevice>({ content: [], meta: { total: 0 } }, 1, 10));
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// POST /api/v1/tpes - Create
|
||||
create(payload: Omit<TpeDevice, 'id' | 'createdAt' | 'updatedAt'>): Observable<TpeDevice> {
|
||||
if (USE_SERVER) {
|
||||
const apiPayload = this.transformToApiPayload(payload);
|
||||
return this.http
|
||||
.post<TpeApiResponse>(this.apiUrl, apiPayload, { headers: this.getNgrokHeaders() })
|
||||
.pipe(
|
||||
map((apiTpe) => this.transformTpe(apiTpe)),
|
||||
catchError((err) => {
|
||||
console.error('Error creating TPE:', err);
|
||||
throw err;
|
||||
})
|
||||
);
|
||||
}
|
||||
throw new Error('Server mode is required');
|
||||
create(payload: Partial<TpeDevice>): Observable<TpeDevice> {
|
||||
const apiPayload = this.transformToApiPayload(payload);
|
||||
return this.http
|
||||
.post<TpeApiResponse>(this.apiUrl, apiPayload, { headers: this.getNgrokHeaders() })
|
||||
.pipe(
|
||||
map((apiTpe) => this.transformTpe(apiTpe)),
|
||||
catchError((err) => {
|
||||
console.error('Error creating TPE:', err);
|
||||
throw err;
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
// PUT /api/v1/tpes/{id} - Update
|
||||
update(id: string, payload: Partial<TpeDevice>): Observable<TpeDevice | undefined> {
|
||||
if (USE_SERVER) {
|
||||
const apiPayload = this.transformToApiPayload(payload);
|
||||
return this.http
|
||||
.put<TpeApiResponse>(`${this.apiUrl}/${id}`, apiPayload, {
|
||||
headers: this.getNgrokHeaders(),
|
||||
// PUT /api/v1/tpes/{id} - Update
|
||||
update(id: string, payload: Partial<TpeDevice>): Observable<TpeDevice | undefined> {
|
||||
const apiPayload = this.transformToApiPayload(payload);
|
||||
return this.http
|
||||
.put<TpeApiResponse>(`${this.apiUrl}/${id}`, apiPayload, {
|
||||
headers: this.getNgrokHeaders(),
|
||||
})
|
||||
.pipe(
|
||||
map((apiTpe) => this.transformTpe(apiTpe)),
|
||||
catchError((err) => {
|
||||
console.error(`Error updating TPE ${id}:`, err);
|
||||
return of(undefined);
|
||||
})
|
||||
.pipe(
|
||||
map((apiTpe) => this.transformTpe(apiTpe)),
|
||||
catchError((err) => {
|
||||
console.error(`Error updating TPE ${id}:`, err);
|
||||
return of(undefined);
|
||||
})
|
||||
);
|
||||
}
|
||||
return of(undefined);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// DELETE /api/v1/tpes/{id} - Delete
|
||||
delete(id: string): Observable<boolean> {
|
||||
|
||||
Reference in New Issue
Block a user