feat: set stock and weight on Shopify product creation

- inventory_management: shopify + inventory_levels/set.json pour le stock
- weight/weight_unit sur le variant pour l'expédition

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-24 15:11:17 +02:00
parent 34ade6beb2
commit caef95bd55
3 changed files with 43 additions and 3 deletions
+1
View File
@@ -79,6 +79,7 @@ export async function POST(req: NextRequest) {
description: longDesc, description: longDesc,
price: product.priceActual || '0.00', price: product.priceActual || '0.00',
stock: product.stock, stock: product.stock,
weightKg: product.weightKg,
status: 'active', status: 'active',
}) })
if (product.collectionId) await addProductToCollection(shopifyId, product.collectionId) if (product.collectionId) await addProductToCollection(shopifyId, product.collectionId)
+40 -2
View File
@@ -91,13 +91,23 @@ async function fetchByStatus(status: 'active' | 'draft'): Promise<ShopifyProduct
export async function createShopifyProduct(product: SyncProduct): Promise<string> { export async function createShopifyProduct(product: SyncProduct): Promise<string> {
const { baseUrl, headers } = getConfig() const { baseUrl, headers } = getConfig()
const variant: Record<string, unknown> = {
price: product.price,
sku: product.ref,
inventory_management: 'shopify',
}
if (product.weightKg != null && product.weightKg > 0) {
variant.weight = product.weightKg
variant.weight_unit = 'kg'
}
const body = { const body = {
product: { product: {
title: product.title, title: product.title,
body_html: product.description, body_html: product.description,
handle: product.handle, handle: product.handle,
status: product.status, status: product.status,
variants: [{ price: product.price, sku: product.ref }], variants: [variant],
}, },
} }
@@ -113,7 +123,35 @@ export async function createShopifyProduct(product: SyncProduct): Promise<string
} }
const data = await res.json() const data = await res.json()
return String(data.product.id) const shopifyId = String(data.product.id)
const variantId = String(data.product.variants[0].id)
// Récupérer le location_id par défaut pour setter le stock
if (product.stock > 0) {
try {
const locRes = await fetch(`${baseUrl}/locations.json`, { headers })
if (locRes.ok) {
const locData = await locRes.json() as { locations: Array<{ id: number }> }
const locationId = locData.locations[0]?.id
if (locationId) {
await fetch(`${baseUrl}/inventory_levels/set.json`, {
method: 'POST',
headers,
body: JSON.stringify({
location_id: locationId,
inventory_item_id: data.product.variants[0].inventory_item_id,
available: product.stock,
}),
})
}
}
} catch {
// Non bloquant : le produit est créé, le stock peut être corrigé manuellement
}
}
void variantId
return shopifyId
} }
/** /**
+2 -1
View File
@@ -7,7 +7,8 @@ export interface SyncProduct {
title: string // colonne B title: string // colonne B
description: string // colonne C (texte brut, stocké en body_html) description: string // colonne C (texte brut, stocké en body_html)
price: string // colonne D — "29.99" (2 décimales) price: string // colonne D — "29.99" (2 décimales)
stock: number // colonne E — info affichage uniquement (non synchronisé) stock: number // colonne E
weightKg?: number // poids en kg pour l'expédition
status: 'active' | 'draft' // colonne F : "inactif"/"inactif" → draft, tout autre → active status: 'active' | 'draft' // colonne F : "inactif"/"inactif" → draft, tout autre → active
} }