feat: add stat_dispoperm and phenix_quantite_conseille to sync pipeline

- Add ARTCENTRALE column to articles sync
- Add stat_dispoperm table (gamme conseillée, joins via ARTCENTRALE)
- Add phenix_quantite_conseille table (journal de commande ERP)
- Register both tables in sync/index.js steps

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
MichaelandClaude Sonnet 4.6 committed 2026-03-27 08:13:14 +01:00
1 parent c5faddde1f
commit 52c47acc67
5 files changed
+129 -3

No files matched your search

+29
View File
@@ -341,3 +341,32 @@ CREATE TABLE IF NOT EXISTS stat_dispoperm (
PRIMARY KEY (codesite, code_art)
);
CREATE INDEX IF NOT EXISTS idx_stat_dispoperm_code_art ON stat_dispoperm (code_art);
-- ============================================================
-- Journal de commande conseillé (PHENIX_QUANTITE_CONSEILLE)
-- ============================================================
CREATE TABLE IF NOT EXISTS phenix_quantite_conseille (
ident BIGINT PRIMARY KEY,
site TEXT,
codein TEXT,
libelle_article TEXT,
code1 TEXT,
libelle1 TEXT,
idartfou1 BIGINT,
art_no_id BIGINT,
colisage NUMERIC(10,3),
moyenne_vente_jour NUMERIC(12,6),
nb_jour_vte INTEGER,
besoin_calcule NUMERIC(12,4),
stock_mini NUMERIC(12,3),
stock_maxi NUMERIC(12,3),
qte_non_recue NUMERIC(12,3),
qte_stock NUMERIC(12,3),
besoin_pris NUMERIC(12,4),
a_commander NUMERIC(12,3),
montant NUMERIC(14,4)
);
CREATE INDEX IF NOT EXISTS idx_phenix_cde_site ON phenix_quantite_conseille (site);
CREATE INDEX IF NOT EXISTS idx_phenix_cde_codein ON phenix_quantite_conseille (codein);
CREATE INDEX IF NOT EXISTS idx_phenix_cde_artfou1 ON phenix_quantite_conseille (idartfou1);
+5 -1
View File
@@ -8,6 +8,8 @@ const { syncMouvements, syncStatOpCA } = require('./tables/mouvements');
const { syncCommandes } = require('./tables/commandes');
const { syncReferentiel } = require('./tables/referentiel');
const { syncRanking } = require('./tables/ranking');
const { syncStatDispoperm } = require('./tables/stat_dispoperm');
const { syncPhenixQuantiteConseille } = require('./tables/phenix_quantite_conseille');
const { closeAll } = require('./db');
const {
startDashboard, registerSyncFn,
@@ -26,7 +28,9 @@ const STEPS = [
{ name: 'mouvements', fn: syncMouvements },
{ name: 'statopca', fn: syncStatOpCA },
{ name: 'commandes', fn: syncCommandes },
{ name: 'ranking', fn: syncRanking },
{ name: 'ranking', fn: syncRanking },
{ name: 'stat_dispoperm', fn: syncStatDispoperm },
{ name: 'phenix_quantite_conseille', fn: syncPhenixQuantiteConseille },
];
async function syncAll(force = false) {
+3 -2
View File
@@ -4,7 +4,7 @@ const { batchUpsert, getLastSync, logSync, safeStr, safeBit } = require('../util
const ARTICLES_COLS = [
'no_id','codein','libelle1','libelle2','lib_ticket',
'tax_code','ach_code','utilisable','actif','suspendu',
'suividatecreation','suividatemodif','nom_no_id',
'suividatecreation','suividatemodif','nom_no_id','artcentrale',
];
const INFOSUP_COLS = [
'artnoid','prix_vente_mini','prix_vente_maxi','eco_ht','eco_ttc',
@@ -26,7 +26,7 @@ async function syncArticles(force) {
const res = await ms.request().query(`
SELECT NO_ID, CODEIN, LIBELLE1, LIBELLE2, LIB_TICKET,
TAX_CODE, ACH_CODE, UTILISABLE, ACTIF, SUSPENDU,
SUIVIDATECREATION, SUIVIDATEMODIF, NOM_NO_ID
SUIVIDATECREATION, SUIVIDATEMODIF, NOM_NO_ID, ARTCENTRALE
FROM ARTICLES ${where}
`);
@@ -44,6 +44,7 @@ async function syncArticles(force) {
suividatecreation: r.SUIVIDATECREATION,
suividatemodif: r.SUIVIDATEMODIF,
nom_no_id: r.NOM_NO_ID,
artcentrale: r.ARTCENTRALE ?? null,
}));
const count = await batchUpsert(pg, 'articles', rows, ['no_id'], ARTICLES_COLS);
+55
View File
@@ -0,0 +1,55 @@
const { getMssql, getPg } = require('../db');
const { fullRefresh, logSync } = require('../utils');
const COLS = [
'ident','site','codein','libelle_article','code1','libelle1',
'idartfou1','art_no_id','colisage','moyenne_vente_jour','nb_jour_vte',
'besoin_calcule','stock_mini','stock_maxi','qte_non_recue','qte_stock',
'besoin_pris','a_commander','montant',
];
async function syncPhenixQuantiteConseille(force) {
const ms = await getMssql();
const pg = getPg();
try {
const res = await ms.request().query(`
SELECT ident, site, CODEIN, LibelleArticle, code1, libelle1,
Idartfou1, Art_no_id, colisage, MoyenneVenteParJour, NbJourVte,
BesoinCalcule, StockMini, StockMaxi, QteNonRecue, QteStock,
BesoinPrisEnCompte, ACommander, Montant
FROM PHENIX_QUANTITE_CONSEILLE
`);
const rows = res.recordset.map(r => ({
ident: r.ident,
site: r.site,
codein: r.CODEIN,
libelle_article: r.LibelleArticle,
code1: r.code1,
libelle1: r.libelle1,
idartfou1: r.Idartfou1,
art_no_id: r.Art_no_id,
colisage: r.colisage,
moyenne_vente_jour: r.MoyenneVenteParJour,
nb_jour_vte: r.NbJourVte,
besoin_calcule: r.BesoinCalcule,
stock_mini: r.StockMini ?? null,
stock_maxi: r.StockMaxi ?? null,
qte_non_recue: r.QteNonRecue ?? null,
qte_stock: r.QteStock ?? null,
besoin_pris: r.BesoinPrisEnCompte,
a_commander: r.ACommander,
montant: r.Montant,
}));
const count = await fullRefresh(pg, 'phenix_quantite_conseille', rows, COLS);
await logSync(pg, 'phenix_quantite_conseille', count, 'ok');
console.log(`[phenix_quantite_conseille] ${count} lignes`);
} catch (err) {
await logSync(pg, 'phenix_quantite_conseille', 0, 'error', err.message);
console.error(`[phenix_quantite_conseille] ERREUR: ${err.message}`);
}
}
module.exports = { syncPhenixQuantiteConseille };
+37
View File
@@ -0,0 +1,37 @@
const { getMssql, getPg } = require('../db');
const { batchUpsert, logSync } = require('../utils');
const COLS = ['codesite','code_art','recommand','statut','qtemoyer','qtemoyes','camoyes','nbreclient'];
async function syncStatDispoperm(force) {
const ms = await getMssql();
const pg = getPg();
try {
const res = await ms.request().query(`
SELECT CodeSite, Code_Art, Recommand, Statut,
QteMoyAch, QteMoyRes, CaMoyRes, NbreClient
FROM STAT_DISPOPERM
`);
const rows = res.recordset.map(r => ({
codesite: r.CodeSite,
code_art: r.Code_Art,
recommand: r.Recommand ?? null,
statut: r.Statut ?? null,
qtemoyer: r.QteMoyAch ?? null,
qtemoyes: r.QteMoyRes ?? null,
camoyes: r.CaMoyRes ?? null,
nbreclient: r.NbreClient ?? null,
}));
const count = await batchUpsert(pg, 'stat_dispoperm', rows, ['codesite','code_art'], COLS);
await logSync(pg, 'stat_dispoperm', count, 'ok');
console.log(`[stat_dispoperm] ${count} lignes upsert`);
} catch (err) {
await logSync(pg, 'stat_dispoperm', 0, 'error', err.message);
console.error(`[stat_dispoperm] ERREUR: ${err.message}`);
}
}
module.exports = { syncStatDispoperm };