diff options
Diffstat (limited to 'src/pages/api/magento-product.ts')
| -rw-r--r-- | src/pages/api/magento-product.ts | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/src/pages/api/magento-product.ts b/src/pages/api/magento-product.ts new file mode 100644 index 00000000..28738878 --- /dev/null +++ b/src/pages/api/magento-product.ts @@ -0,0 +1,168 @@ +// pages/api/magento-product.ts +import type { NextApiRequest, NextApiResponse } from 'next'; + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse +) { + // Kita terima 'skus' (banyak) dan 'main_sku' (utama/pertama) + const { skus, main_sku } = req.query; + + if (!skus) { + return res.status(400).json({ error: 'SKUs are required' }); + } + + const token = process.env.MAGENTO_API_KEY || ''; + const baseUrl = process.env.MAGENTO_API_HOST || ''; + + try { + const skuList = String(skus).split(','); // Contoh: ['221', '222', '223'] + const mainSku = String(main_sku || skuList[0]).trim(); // Fallback ke yang pertama + + // ===================================================================== + // 1. FETCH SEMUA VARIAN SEKALIGUS (Optimasi 'IN' Operator) + // ===================================================================== + const searchParams = new URLSearchParams({ + 'searchCriteria[filter_groups][0][filters][0][field]': 'sku', + 'searchCriteria[filter_groups][0][filters][0][value]': skuList.join(','), + 'searchCriteria[filter_groups][0][filters][0][condition_type]': 'in' + }); + + const productUrl = `${baseUrl}/products?${searchParams.toString()}`; + + const productResponse = await fetch(productUrl, { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + 'Authorization': `Bearer ${token}`, + }, + }); + + if (!productResponse.ok) { + return res.status(200).json({ specsMatrix: [], upsell_ids: [], related_ids: [] }); + } + + const productData = await productResponse.json(); + const items = productData.items || []; + + if (items.length === 0) { + return res.status(200).json({ specsMatrix: [], upsell_ids: [], related_ids: [] }); + } + + const cleanAttributeValue = (val: any) => { + if (val === null || val === undefined) return ''; + let str = String(val).trim(); + if (str.length >= 2 && str.startsWith('"') && str.endsWith('"')) { + str = str.slice(1, -1).trim(); + } + return str; + }; + + // ===================================================================== + // 2. BUILD SPECS MATRIX + // ===================================================================== + + // Kumpulkan semua kode atribut unik + const allAttributeCodes = new Set<string>(); + items.forEach((p: any) => { + if (p.custom_attributes) { + p.custom_attributes.forEach((attr: any) => { + if (attr.attribute_code.startsWith('z')) { + allAttributeCodes.add(attr.attribute_code); + } + }); + } + }); + + // Fetch Label untuk atribut-atribut tersebut (Sekali jalan) + const labelsMap: Record<string, string> = {}; + await Promise.all(Array.from(allAttributeCodes).map(async (code) => { + try { + const attrUrl = `${baseUrl}/products/attributes/${code}`; + const res = await fetch(attrUrl, { headers: { 'Authorization': `Bearer ${token}` } }); + if (res.ok) { + const json = await res.json(); + labelsMap[code] = json.default_frontend_label || code; + } + } catch (e) {} + + // Fallback label jika gagal + if (!labelsMap[code]) { + labelsMap[code] = code.substring(1).replace(/_/g, ' ').trim(); + } + })); + + // Susun Matrix + // Struktur: { code, label, values: { [sku]: value } } + const matrix: any[] = []; + + Array.from(allAttributeCodes).forEach((code) => { + const row: any = { + code: code, + label: labelsMap[code], + values: {} + }; + + let hasData = false; + + items.forEach((p: any) => { + const attr = p.custom_attributes.find((a: any) => a.attribute_code === code); + // Gunakan helper cleanAttributeValue disini + const rawVal = attr ? cleanAttributeValue(attr.value) : ''; + + if (rawVal !== '' && rawVal !== '-') { + hasData = true; + } + row.values[p.sku] = rawVal; + }); + + if (hasData) { + matrix.push(row); + } + }); + + // Deskripsi produk per varian + const descriptions:Record<string, string> = {}; + items.forEach((p: any) => { + const descAttr = p.custom_attributes.find((a: any) => a.attribute_code === 'description' || a.attribute_code === 'short_description'); + descriptions[p.sku] = descAttr ? descAttr.value : ''; + }); + + const warranties: Record<string, string> = {}; + items.forEach((p: any) => { + const warAttr = p.custom_attributes.find((a: any) => a.attribute_code === 'z_warranty'); + warranties[p.sku] = warAttr ? cleanAttributeValue(warAttr.value) : ''; + }); + + // ===================================================================== + // 3. AMBIL LINKS (UPSELL & RELATED) DARI MAIN VARIANT SAJA + // ===================================================================== + const mainProduct = items.find((p: any) => String(p.sku) === mainSku) || items[0]; + + let upsellIds: number[] = []; + let relatedIds: number[] = []; + + if (mainProduct && mainProduct.product_links) { + mainProduct.product_links.forEach((link: any) => { + if (link.link_type === 'upsell') { + upsellIds.push(Number(link.linked_product_sku)); + } else if (link.link_type === 'related') { + relatedIds.push(Number(link.linked_product_sku)); + } + }); + } + + // Response + res.status(200).json({ + specsMatrix: matrix, + upsell_ids: upsellIds, + related_ids: relatedIds, + descriptions: descriptions, + warranties: warranties, + }); + + } catch (error) { + console.error('Proxy Error:', error); + res.status(500).json({ error: 'Internal Server Error' }); + } +}
\ No newline at end of file |
