117 lines
4.6 KiB
TypeScript
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
|
|
}
|