/** * Suppliers resource – Real HTTP implementation. * Endpoints: GET/POST /api/suppliers, GET/PUT /api/suppliers/{id}, * POST /api/suppliers/{id}/activate|deactivate, * POST /api/suppliers/{id}/rating, * POST /api/suppliers/{id}/certificates, * DELETE /api/suppliers/{id}/certificates (with body) * * NOTE: Backend returns domain objects with nested VOs: * { "id": {"value":"uuid"}, "name": {"value":"string"}, * "address": {"street":"...","houseNumber":"...","postalCode":"...","city":"...","country":"DE"}, * "contactInfo": {"phone":"...","email":"...","contactPerson":"..."}, * "paymentTerms": {"paymentDueDays":30,"description":"..."}, * "certificates": [{"certificateType":"...","issuer":"...","validFrom":"2024-01-01","validUntil":"2026-12-31"}], * "rating": {"qualityScore":4,"deliveryScore":4,"priceScore":5}, * "status": "ACTIVE", "createdAt":"...", "updatedAt":"..." } * DELETE /api/suppliers/{id}/certificates returns 204 No Content → re-fetch. */ import type { AxiosInstance } from 'axios'; export interface AddressDTO { street: string; houseNumber: string | null; postalCode: string; city: string; country: string; } export interface ContactInfoDTO { phone: string; email: string | null; contactPerson: string | null; } export interface PaymentTermsDTO { paymentDueDays: number; paymentDescription: string | null; } export interface QualityCertificateDTO { certificateType: string; issuer: string; validFrom: string; validUntil: string; } export interface SupplierRatingDTO { qualityScore: number; deliveryScore: number; priceScore: number; } export type SupplierStatus = 'ACTIVE' | 'INACTIVE'; export interface SupplierDTO { id: string; name: string; status: SupplierStatus; address: AddressDTO | null; contactInfo: ContactInfoDTO; paymentTerms: PaymentTermsDTO | null; certificates: QualityCertificateDTO[]; rating: SupplierRatingDTO | null; createdAt: string; updatedAt: string; } export interface CreateSupplierRequest { name: string; phone: string; email?: string; contactPerson?: string; street?: string; houseNumber?: string; postalCode?: string; city?: string; country?: string; paymentDueDays?: number; paymentDescription?: string; } export interface UpdateSupplierRequest { name?: string; phone?: string; email?: string | null; contactPerson?: string | null; street?: string | null; houseNumber?: string | null; postalCode?: string | null; city?: string | null; country?: string | null; paymentDueDays?: number | null; paymentDescription?: string | null; } export interface RateSupplierRequest { qualityScore: number; deliveryScore: number; priceScore: number; } export interface AddCertificateRequest { certificateType: string; issuer: string; validFrom: string; validUntil: string; } export interface RemoveCertificateRequest { certificateType: string; issuer: string; validFrom: string; } // ── Backend response shapes (domain objects with nested VOs) ───────────────── interface BackendAddress { street: string; houseNumber: string | null; postalCode: string; city: string; country: string; } interface BackendContactInfo { phone: string; email: string | null; contactPerson: string | null; } interface BackendPaymentTerms { paymentDueDays: number; description: string | null; // Note: backend field is "description", not "paymentDescription" } interface BackendQualityCertificate { certificateType: string; issuer: string; validFrom: string; // LocalDate → "2024-01-01" validUntil: string; } interface BackendSupplierRating { qualityScore: number; deliveryScore: number; priceScore: number; } interface BackendSupplier { id: { value: string }; name: { value: string }; address: BackendAddress | null; contactInfo: BackendContactInfo; paymentTerms: BackendPaymentTerms | null; certificates: BackendQualityCertificate[]; rating: BackendSupplierRating | null; status: SupplierStatus; createdAt: string; updatedAt: string; } function mapSupplier(bs: BackendSupplier): SupplierDTO { return { id: bs.id.value, name: bs.name.value, status: bs.status, address: bs.address, contactInfo: bs.contactInfo, paymentTerms: bs.paymentTerms ? { paymentDueDays: bs.paymentTerms.paymentDueDays, paymentDescription: bs.paymentTerms.description, } : null, certificates: bs.certificates, rating: bs.rating, createdAt: bs.createdAt, updatedAt: bs.updatedAt, }; } // ── Resource factory ───────────────────────────────────────────────────────── export function createSuppliersResource(client: AxiosInstance) { return { async list(): Promise { const res = await client.get('/api/suppliers'); return res.data.map(mapSupplier); }, async getById(id: string): Promise { const res = await client.get(`/api/suppliers/${id}`); return mapSupplier(res.data); }, async create(request: CreateSupplierRequest): Promise { const res = await client.post('/api/suppliers', request); return mapSupplier(res.data); }, async update(id: string, request: UpdateSupplierRequest): Promise { const res = await client.put(`/api/suppliers/${id}`, request); return mapSupplier(res.data); }, async activate(id: string): Promise { const res = await client.post(`/api/suppliers/${id}/activate`); return mapSupplier(res.data); }, async deactivate(id: string): Promise { const res = await client.post(`/api/suppliers/${id}/deactivate`); return mapSupplier(res.data); }, async rate(id: string, request: RateSupplierRequest): Promise { const res = await client.post(`/api/suppliers/${id}/rating`, request); return mapSupplier(res.data); }, async addCertificate(id: string, request: AddCertificateRequest): Promise { const res = await client.post(`/api/suppliers/${id}/certificates`, request); return mapSupplier(res.data); }, // Returns 204 No Content → re-fetch supplier async removeCertificate(id: string, request: RemoveCertificateRequest): Promise { await client.delete(`/api/suppliers/${id}/certificates`, { data: request }); const res = await client.get(`/api/suppliers/${id}`); return mapSupplier(res.data); }, }; } export type SuppliersResource = ReturnType;