# DoliMiddlewareApi - API Reference BFF (Backend For Frontend) between the Vue.js frontend and Dolibarr ERP. Base URL: `http://localhost:5269` (dev) / `http://localhost:5000` (Docker) Auth: All endpoints except `POST /api/Auth/login` require a JWT Bearer token. --- ## Authentication ### POST /api/Auth/login Login and get JWT token. **Request:** ```json { "username": "admin", "password": "12345678" } ``` **Response:** `200 OK` ```json { "token": "eyJhbGciOiJIUzI1NiIs..." } ``` After login, include the token in all requests: `Authorization: Bearer ` --- ## Clients ### GET /api/Clients List clients with their contacts. **Query params:** `limit` (default 50), `page` (default 1) **Response:** `200 OK` ```json [ { "id": 1, "name": "Client Name", "codeClient": "CU0001", "typentCode": null, "status": "1", "email": "client@example.com", "phone": "+34600000000", "contacts": [ { "id": 1, "lastname": "Garcia", "firstname": "Ana", "email": "ana@example.com", "phonePro": "...", "phonePerso": "...", "phoneMobile": "...", "clientId": 1 } ] } ] ``` ### GET /api/Clients/{id} Get client detail with contacts and full address info. **Response:** `200 OK` ```json { "id": 1, "name": "Client Name", "codeClient": "CU0001", "typentCode": null, "status": "1", "email": "client@example.com", "phone": "+34600000000", "address": "Calle Mayor 1", "town": "Madrid", "zip": "28001", "countryCode": "ES", "vatNumber": "B12345678", "url": null, "notePublic": null, "notePrivate": null, "contacts": [...] } ``` ### POST /api/Clients Create a new client. **Request:** ```json { "name": "New Client", "address": "Calle Example 5", "zip": "28001", "town": "Madrid", "phone": "+34600000000", "email": "client@example.com", "countryCode": "ES", "vatNumber": null, "url": null, "notePublic": null, "notePrivate": null } ``` **Response:** `201 Created` → Returns new client ID (int) ### PUT /api/Clients/{id} Update a client. Only send fields you want to change. **Request:** ```json { "name": "Updated Name", "phone": "+34611111111" } ``` **Response:** `204 No Content` ### DELETE /api/Clients/{id} Delete a client. **Response:** `204 No Content` --- ## Contacts ### GET /api/Contacts List contacts. Optionally filter by client. **Query params:** `limit` (default 50), `page` (default 1), `thirdpartyIds` (comma-separated client IDs) Example: `GET /api/Contacts?thirdpartyIds=1,2&limit=100` **Response:** `200 OK` ```json [ { "id": 1, "lastname": "Garcia", "firstname": "Ana", "email": "ana@example.com", "phonePro": "...", "phonePerso": null, "phoneMobile": "...", "clientId": 1 } ] ``` ### GET /api/Contacts/{id} Get contact detail with address and civility info. **Response:** `200 OK` ```json { "id": 1, "lastname": "Garcia", "firstname": "Ana", "email": "ana@example.com", "phonePro": "+34910000000", "phonePerso": null, "phoneMobile": "+34600000001", "clientId": 1, "address": "Calle Example 5", "town": "Madrid", "zip": "28001", "civilityCode": null, "status": "active" } ``` ### GET /api/Contacts/email/{email} Find a contact by email address. **Response:** `200 OK` → Same as `GET /api/Contacts/{id}` ### POST /api/Contacts Create a contact. **Request:** ```json { "lastname": "Garcia", "firstname": "Ana", "clientId": 1, "email": "ana@example.com", "phonePro": "+34910000000", "phoneMobile": "+34600000001", "address": "Calle Example 5", "zip": "28001", "town": "Madrid" } ``` **Response:** `201 Created` → Returns new contact ID (int) ### PUT /api/Contacts/{id} Update a contact. Only send fields to change. **Response:** `204 No Content` ### DELETE /api/Contacts/{id} Delete a contact. **Response:** `204 No Content` --- ## Invoices ### GET /api/Invoices List invoices. **Query params:** `limit` (default 50), `page` (default 1), `status` (draft/unpaid/paid), `search` (ref search) ### GET /api/Invoices/{id} Get invoice detail with lines, totals, and payment info. ### POST /api/Invoices Create invoice. See existing frontend for request body format. ### PUT /api/Invoices/{id} Update invoice (expireDate, notePublic, notePrivate, number). ### PATCH /api/Invoices/{id}/status Change invoice status: `{ "status": "draft" | "unpaid" | "paid" }` ### POST /api/Invoices/{id}/validate Validate (confirm) a draft invoice. ### DELETE /api/Invoices/{id} Delete a draft invoice. ### POST /api/Invoices/{id}/lines Add a line to a draft invoice. **Request:** ```json { "description": "Service", "quantity": 1, "unitPrice": 100, "taxRate": 21 } ``` ### PUT /api/Invoices/{invoiceId}/lines/{lineId} Update a line in a draft invoice. **Request:** ```json { "description": "Updated desc", "quantity": 2, "unitPrice": 150, "taxRate": 10 } ``` All fields optional — only send what you want to change. ### DELETE /api/Invoices/{invoiceId}/lines/{lineId} Delete a line from a draft invoice. ### GET /api/Invoices/{id}/payments List payments for an invoice. ### POST /api/Invoices/{id}/payments Add payment to an invoice. ### GET /api/Invoices/templates List invoice templates (recurring invoices in Dolibarr). --- ## Documents ### GET /api/Document/invoice/{invoiceRef}/pdf Download/build a PDF for an invoice. Returns `application/pdf` file. ### GET /api/Document/list List documents for an element. **Query params:** `modulePart` (default "invoice"), `refId` (required — invoice ref or societe id) ### GET /api/Document/download Download a document file. **Query params:** `modulePart` (default "invoice"), `file` (required — file path in Dolibarr) --- ## Setup (Reference Data) These endpoints return dictionary/reference data from Dolibarr, useful for populating dropdowns and selectors. ### GET /api/Setup/payment-types Returns payment type options (Cash, Cheque, Credit card, etc.) ```json [ { "id": "4", "code": "LIQ", "label": "Cash", "type": "2" }, { "id": "6", "code": "CB", "label": "Credit card", "type": "2" }, { "id": "7", "code": "CHQ", "label": "Cheque", "type": "2" } ] ``` ### GET /api/Setup/countries Returns country list with ISO codes. ### GET /api/Setup/civilities Returns civility titles (Mr, Mrs, etc.). ### GET /api/Setup/contact-types Returns contact type labels. ### GET /api/Setup/payment-terms Returns payment terms (Due on receipt, 30 days, etc.). ### GET /api/Setup/company Returns your company info (name, address, VAT number, etc.). --- ## Deployment ### Docker Compose 1. Copy `.env.example` to `.env` and set `JWT_SECRET` to a long random string 2. Run: `docker compose up -d` 3. BFF will be available at `http://localhost:5000` 4. Swagger UI at `http://localhost:5000/swagger` ### Environment Variables | Variable | Required | Description | |----------|----------|-------------| | `Jwt__Secret` | Yes | JWT signing key, min 32 chars | | `Dolibarr__ApiUrl` | Yes | Dolibarr API base URL (e.g. `http://dolibarr/api/index.php`) | | `Cors__AllowedOrigins` | No | Semicolon-separated CORS origins. Empty = allow all | | `ASPNETCORE_ENVIRONMENT` | No | `Production` or `Development` | ### Frontend .env ``` VITE_API_BASE_URL=http://localhost:5000 ``` When connecting to the BFF in Docker, use `http://localhost:5000` (the BFF port), not the Dolibarr port directly.