Files
gestion-materiaux-destock/src/lib/creationSheets.ts
T

117 lines
4.6 KiB
TypeScript

import type { PendingProduct } from '@/types/creation'
const COMMON_HEADERS = new Set([
'ID', 'Type', 'UGS', 'Nom', 'Publié', 'Mis en avant ?',
'Description courte', 'Description longue',
'Date de début de promo', 'Date de fin de promo',
'État de la TVA', 'Classe de TVA', 'En stock ?',
'Stock (en pièce)', 'Vendre individuellement ?',
'Prix marché', 'Prix remisé', 'Code ecopart', 'Ecopart montant',
'Famille', 'Sous famille',
"Classe d'expédition (en retrait, livraison)",
'Conditionnement', 'Surface (m2)', 'Poids (kg) fonction unité',
'Images', 'Unité', 'Marque', 'Neuf ?', 'PHOTO ?',
'ID FAMILLE', 'ID SOUS FAMILLE',
])
export function findColIndex(headers: string[], search: string): number {
const exact = headers.findIndex(h => h === search)
if (exact !== -1) return exact
return headers.findIndex(h => h.startsWith(search))
}
export function extractSpecificFields(headers: string[], row: string[]): Record<string, string> {
const result: Record<string, string> = {}
headers.forEach((header, i) => {
if (!header) return
const isCommon = COMMON_HEADERS.has(header) || header.startsWith('Commentaire')
if (isCommon) return
const val = (row[i] ?? '').trim()
if (val) result[header] = val
})
return result
}
export function parseTabRows(tab: string, headers: string[], rows: string[][]): PendingProduct[] {
const idx = {
id: findColIndex(headers, 'ID'),
sku: findColIndex(headers, 'UGS'),
nom: findColIndex(headers, 'Nom'),
publie: findColIndex(headers, 'Publié'),
stock: findColIndex(headers, 'Stock (en pièce)'),
prixMarche: findColIndex(headers, 'Prix marché'),
prixRemise: findColIndex(headers, 'Prix remisé'),
poids: findColIndex(headers, 'Poids (kg) fonction unité'),
marque: findColIndex(headers, 'Marque'),
famille: findColIndex(headers, 'Famille'),
sousFamille: findColIndex(headers, 'Sous famille'),
commentaire: findColIndex(headers, 'Commentaire'),
photo: findColIndex(headers, 'PHOTO ?'),
collectionId: findColIndex(headers, 'ID FAMILLE'),
subCollectionId: findColIndex(headers, 'ID SOUS FAMILLE'),
}
const get = (row: string[], i: number) => (i >= 0 ? (row[i] ?? '').trim() : '')
return rows
.map((row, rowIdx): PendingProduct | null => {
const id = get(row, idx.id)
const publie = get(row, idx.publie)
if (id !== '' || publie !== '1') return null
return {
tab,
rowNumber: rowIdx + 2,
sku: get(row, idx.sku),
title: get(row, idx.nom),
priceMarket: get(row, idx.prixMarche).replace(',', '.'),
priceActual: get(row, idx.prixRemise).replace(',', '.'),
stock: parseInt(get(row, idx.stock) || '0', 10) || 0,
weightKg: parseFloat(get(row, idx.poids).replace(',', '.') || '0') || 0,
vendor: get(row, idx.marque),
famille: get(row, idx.famille),
sousFamille: get(row, idx.sousFamille),
comment: get(row, idx.commentaire),
collectionId: get(row, idx.collectionId),
subCollectionId: get(row, idx.subCollectionId),
hasPhoto: get(row, idx.photo) !== '',
specificFields: extractSpecificFields(headers, row),
}
})
.filter((p): p is PendingProduct => p !== null)
}
export async function fetchPendingProducts(
alreadyCreatedRows: Set<string>,
): Promise<PendingProduct[]> {
const apiKey = process.env.GOOGLE_API_KEY
const sheetId = process.env.GOOGLE_SHEETS_ID
if (!apiKey || !sheetId) throw new Error('GOOGLE_API_KEY et GOOGLE_SHEETS_ID requis')
const metaRes = await fetch(
`https://sheets.googleapis.com/v4/spreadsheets/${sheetId}?key=${apiKey}&fields=sheets.properties.title`,
)
if (!metaRes.ok) throw new Error(`Sheets metadata error: ${metaRes.status}`)
const meta = await metaRes.json()
const tabs: string[] = (meta.sheets as Array<{ properties: { title: string } }>).map(
s => s.properties.title,
)
const all: PendingProduct[] = []
for (const tab of tabs) {
const range = encodeURIComponent(`${tab}!A1:BZ`)
const res = await fetch(
`https://sheets.googleapis.com/v4/spreadsheets/${sheetId}/values/${range}?key=${apiKey}`,
)
if (!res.ok) continue
const data = await res.json()
const rows = (data.values ?? []) as string[][]
if (rows.length < 2) continue
const [headers, ...dataRows] = rows
const pending = parseTabRows(tab, headers, dataRows).filter(
p => !alreadyCreatedRows.has(`${p.tab}:${p.rowNumber}`),
)
all.push(...pending)
}
return all
}