diff --git a/API_DOCUMENTATION.md b/API_DOCUMENTATION.md index 72eccb4..c533a16 100644 --- a/API_DOCUMENTATION.md +++ b/API_DOCUMENTATION.md @@ -32,9 +32,17 @@ GET /api/articles | `ean` | string | EAN / GTIN | — | | `codefou` | string | Code fournisseur (partiel) | — | | `actif` | `1`/`0`| `1` = actif, `0` = suspendu | — | +| `artcentrale` | string | Code centrale (partiel) | — | +| `has_artcentrale` | `1`/`0` | `1` = référencé centrale, `0` = non référencé | — | | `page` | int | Numéro de page | 1 | | `limit` | int | Lignes par page (max 500) | 50 | +> **Code centrale** (`artcentrale`) : identifiant LaFoir'Fouille sur 11 chiffres, préfixe `1000x` +> (ex. `10000137005`). Seuls les produits référencés par la centrale en possèdent un — +> environ 355 800 articles sur 427 700. Pour les autres, le champ vaut `null`. +> `has_artcentrale=1` ne retient que les codes conformes : quelques valeurs parasites +> (`10000`, `10000192289P`) ont le bon préfixe mais pas la bonne longueur, et sont exclues. + **Réponse** : ```json { @@ -54,6 +62,7 @@ GET /api/articles "suspendu": null, "suividatecreation": "2020-01-15T00:00:00.000Z", "suividatemodif": "2024-06-01T00:00:00.000Z", + "artcentrale": "10000137005", "prix_vente_mini": 15.00, "prix_vente_maxi": 25.00, "eco_ttc": 0.10, @@ -85,7 +94,7 @@ GET /api/articles/:id **Réponse** : ```json { - "article": { "no_id": 12345, "codein": "...", "libelle1": "...", "pa": 10.50, "..." : "..." }, + "article": { "no_id": 12345, "codein": "...", "libelle1": "...", "artcentrale": "10000137005", "pa": 10.50, "..." : "..." }, "gtins": [ { "gtin": "3760000000001", "preferentiel": 1 } ], diff --git a/src/routes/articles.js b/src/routes/articles.js index 882df03..cba82ab 100644 --- a/src/routes/articles.js +++ b/src/routes/articles.js @@ -2,11 +2,12 @@ const express = require('express'); const router = express.Router(); const { getPool } = require('../config/database'); -// GET /api/articles?search=&codein=&ean=&actif=&codefou=&page=&limit= +// GET /api/articles?search=&codein=&ean=&actif=&codefou=&artcentrale=&has_artcentrale=&page=&limit= router.get('/', async (req, res) => { try { const pool = getPool(); - const { search = '', codein = '', ean = '', actif = '', codefou = '', page = 1, limit = 50 } = req.query; + const { search = '', codein = '', ean = '', actif = '', codefou = '', + artcentrale = '', has_artcentrale = '', page = 1, limit = 50 } = req.query; const pageNum = Math.max(1, parseInt(page) || 1); const limitNum = Math.max(1, Math.min(parseInt(limit) || 50, 500)); const offsetNum = (pageNum - 1) * limitNum; @@ -16,6 +17,7 @@ router.get('/', async (req, res) => { a.NO_ID, a.CODEIN, a.LIBELLE1, a.LIBELLE2, a.LIB_TICKET, a.TAX_CODE, a.ACH_CODE, a.UTILISABLE, a.ACTIF, a.SUSPENDU, a.SUIVIDATECREATION, a.SUIVIDATEMODIF, + NULLIF(TRIM(a.ARTCENTRALE), '') AS ARTCENTRALE, ai.PRIX_VENTE_MINI, ai.PRIX_VENTE_MAXI, ai.ECO_TTC, ai.ON_WEB, ai.INTERDIT_REMISE, ai.NOMPHOTO, ai.DATEDEBVENTE, ai.DATEFINVENTE, @@ -50,9 +52,22 @@ router.get('/', async (req, res) => { AND ($4 = '%%' OR EXISTS ( SELECT 1 FROM ARTFOU1 f WHERE f.ART_NO_ID = a.NO_ID AND f.CODE LIKE $4 )) + AND ($6 = '%%' OR TRIM(a.ARTCENTRALE) LIKE $6) + -- code centrale LaFoir'Fouille : préfixe 1000x sur 11 chiffres. + -- COALESCE car les articles non référencés valent '' ou NULL. + AND ($7 = '' OR ( + $7 = '1' AND TRIM(COALESCE(a.ARTCENTRALE, '')) LIKE '1000%' + AND LENGTH(TRIM(COALESCE(a.ARTCENTRALE, ''))) = 11 + ) OR ( + $7 = '0' AND NOT ( + TRIM(COALESCE(a.ARTCENTRALE, '')) LIKE '1000%' + AND LENGTH(TRIM(COALESCE(a.ARTCENTRALE, ''))) = 11 + ) + )) ORDER BY a.LIBELLE1 LIMIT ${limitNum} OFFSET ${offsetNum} - `, [`%${search}%`, `%${codein}%`, `%${ean}%`, `%${codefou}%`, actif]); + `, [`%${search}%`, `%${codein}%`, `%${ean}%`, `%${codefou}%`, actif, + `%${artcentrale}%`, has_artcentrale]); const articles = result.rows.map(a => { const photoCode = a.nomphoto ? a.nomphoto.replace(/\.[^.]+$/, '') : null; @@ -123,6 +138,7 @@ router.get('/:id', async (req, res) => { res.json({ article: { ...art, + artcentrale: art.artcentrale?.trim() || null, photo_url: photoCode ? `/api/articles/${req.params.id}/photo` : null, photo_url_large: photoCode ? `/api/articles/${req.params.id}/photo?size=large` : null, }, diff --git a/sync/tables/articles.js b/sync/tables/articles.js index 6bb4369..134bfef 100644 --- a/sync/tables/articles.js +++ b/sync/tables/articles.js @@ -44,7 +44,7 @@ async function syncArticles(force) { suividatecreation: r.SUIVIDATECREATION, suividatemodif: r.SUIVIDATEMODIF, nom_no_id: r.NOM_NO_ID, - artcentrale: r.ARTCENTRALE ?? null, + artcentrale: safeStr(r.ARTCENTRALE), })); const count = await batchUpsert(pg, 'articles', rows, ['no_id'], ARTICLES_COLS);