mirror of
https://github.com/R0m1k3/LogiFlow.git
synced 2026-10-12 01:37:40 +02:00
feat: implement DLC tracking page with EAN lookup and CRUD operations for product expiration management
This commit is contained in:
1 parent
44950d2239
commit
a91027c10b
3 files changed
+53
-11
No files matched your search
@@ -128,19 +128,33 @@ export default function DlcPage() {
|
||||
eanDebounceRef.current = setTimeout(async () => {
|
||||
setEanLookupLoading(true);
|
||||
try {
|
||||
// Étape 1 : récupérer l'article par EAN
|
||||
const res = await fetch(`/api/ffnancy/articles?ean=${encodeURIComponent(gencodeValue)}&limit=1`, { credentials: 'include' });
|
||||
if (!res.ok) return;
|
||||
const data = await res.json();
|
||||
const article = data.articles?.[0];
|
||||
if (!article) return;
|
||||
|
||||
// Toujours mettre à jour le nom du produit
|
||||
form.setValue("productName", article.libelle1, { shouldValidate: true });
|
||||
|
||||
// Matcher le fournisseur par codefou en priorité, sinon par nom
|
||||
if (article.codefou_principal) {
|
||||
// Étape 2 : chercher le fournisseur de la dernière entrée en stock
|
||||
let codefouToMatch = article.codefou_principal;
|
||||
try {
|
||||
const mvtRes = await fetch(
|
||||
`/api/ffnancy/mouvements/entrees?artNoId=${article.no_id}&limit=1&dateDebut=2000-01-01`,
|
||||
{ credentials: 'include' }
|
||||
);
|
||||
if (mvtRes.ok) {
|
||||
const mvtData = await mvtRes.json();
|
||||
const lastEntree = mvtData.entrees?.[0];
|
||||
if (lastEntree?.codefou) codefouToMatch = lastEntree.codefou;
|
||||
}
|
||||
} catch { /* fallback sur codefou_principal */ }
|
||||
|
||||
// Matching : codefou exact en priorité, fallback par nom
|
||||
if (codefouToMatch) {
|
||||
const matched = (suppliers as any[]).find((s: any) =>
|
||||
s.codefou && s.codefou.trim().toLowerCase() === article.codefou_principal.trim().toLowerCase()
|
||||
s.codefou && s.codefou.trim().toLowerCase() === codefouToMatch.trim().toLowerCase()
|
||||
) || (suppliers as any[]).find((s: any) =>
|
||||
s.name.toLowerCase().trim().includes(article.nom_fou_principal?.toLowerCase().trim() || '') ||
|
||||
(article.nom_fou_principal?.toLowerCase().trim() || '').includes(s.name.toLowerCase().trim())
|
||||
|
||||
@@ -153,6 +153,7 @@ export default function MobileDlcPage() {
|
||||
eanDebounceRef.current = setTimeout(async () => {
|
||||
setEanLookupLoading(true);
|
||||
try {
|
||||
// Étape 1 : récupérer l'article par EAN
|
||||
const res = await fetch(`/api/ffnancy/articles?ean=${encodeURIComponent(gencodeValue)}&limit=1`, { credentials: 'include' });
|
||||
if (!res.ok) return;
|
||||
const data = await res.json();
|
||||
@@ -161,9 +162,24 @@ export default function MobileDlcPage() {
|
||||
|
||||
form.setValue("productName", article.libelle1, { shouldValidate: true });
|
||||
|
||||
if (article.codefou_principal) {
|
||||
// Étape 2 : chercher le fournisseur de la dernière entrée en stock
|
||||
let codefouToMatch = article.codefou_principal;
|
||||
try {
|
||||
const mvtRes = await fetch(
|
||||
`/api/ffnancy/mouvements/entrees?artNoId=${article.no_id}&limit=1&dateDebut=2000-01-01`,
|
||||
{ credentials: 'include' }
|
||||
);
|
||||
if (mvtRes.ok) {
|
||||
const mvtData = await mvtRes.json();
|
||||
const lastEntree = mvtData.entrees?.[0];
|
||||
if (lastEntree?.codefou) codefouToMatch = lastEntree.codefou;
|
||||
}
|
||||
} catch { /* fallback sur codefou_principal */ }
|
||||
|
||||
// Matching : codefou exact en priorité, fallback par nom
|
||||
if (codefouToMatch) {
|
||||
const matched = (suppliers as any[]).find((s: any) =>
|
||||
s.codefou && s.codefou.trim().toLowerCase() === article.codefou_principal.trim().toLowerCase()
|
||||
s.codefou && s.codefou.trim().toLowerCase() === codefouToMatch.trim().toLowerCase()
|
||||
) || (suppliers as any[]).find((s: any) =>
|
||||
s.name.toLowerCase().trim().includes(article.nom_fou_principal?.toLowerCase().trim() || '') ||
|
||||
(article.nom_fou_principal?.toLowerCase().trim() || '').includes(s.name.toLowerCase().trim())
|
||||
|
||||
+17
-5
@@ -6040,12 +6040,24 @@ RÉSUMÉ DU SCAN
|
||||
if (req.query[key]) params.append(key, req.query[key] as string);
|
||||
}
|
||||
const response = await fetch(`https://api.ffnancy.fr/api/articles?${params}`);
|
||||
if (!response.ok) {
|
||||
return res.status(response.status).json({ error: 'API ffnancy error' });
|
||||
if (!response.ok) return res.status(response.status).json({ error: 'API ffnancy error' });
|
||||
res.json(await response.json());
|
||||
} catch {
|
||||
res.status(500).json({ error: 'Failed to reach API ffnancy' });
|
||||
}
|
||||
});
|
||||
|
||||
app.get('/api/ffnancy/mouvements/entrees', requireAuth, async (req: Request, res: Response) => {
|
||||
try {
|
||||
const params = new URLSearchParams();
|
||||
const allowed = ['artNoId', 'dateDebut', 'dateFin', 'site', 'page', 'limit'];
|
||||
for (const key of allowed) {
|
||||
if (req.query[key]) params.append(key, req.query[key] as string);
|
||||
}
|
||||
const data = await response.json();
|
||||
res.json(data);
|
||||
} catch (error) {
|
||||
const response = await fetch(`https://api.ffnancy.fr/api/mouvements/entrees?${params}`);
|
||||
if (!response.ok) return res.status(response.status).json({ error: 'API ffnancy error' });
|
||||
res.json(await response.json());
|
||||
} catch {
|
||||
res.status(500).json({ error: 'Failed to reach API ffnancy' });
|
||||
}
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user