diff options
| author | FIN-IT_AndriFP <andrifebriyadiputra@gmail.com> | 2025-12-03 17:06:01 +0700 |
|---|---|---|
| committer | FIN-IT_AndriFP <andrifebriyadiputra@gmail.com> | 2025-12-03 17:06:01 +0700 |
| commit | 43b2ce4d59c153655eb9b7a2190b83050fd48855 (patch) | |
| tree | a62d30507950ce7b1003d848a9e63f6b8854b04c /src | |
| parent | 219c61c5c14e3a8dfed3d7158d59d11c476e3586 (diff) | |
(andri) table spek untuk product dengan variant lebih dari 1
Diffstat (limited to 'src')
| -rw-r--r-- | src/pages/api/magento-product.ts | 186 |
1 files changed, 92 insertions, 94 deletions
diff --git a/src/pages/api/magento-product.ts b/src/pages/api/magento-product.ts index 32dd0e5c..297f0ebc 100644 --- a/src/pages/api/magento-product.ts +++ b/src/pages/api/magento-product.ts @@ -5,31 +5,32 @@ export default async function handler( req: NextApiRequest, res: NextApiResponse ) { - const { sku } = req.query; + // Kita terima 'skus' (banyak) dan 'main_sku' (utama/pertama) + const { skus, main_sku } = req.query; - if (!sku) { - return res.status(400).json({ error: 'SKU is required' }); + if (!skus) { + return res.status(400).json({ error: 'SKUs are required' }); } - // Token Magento const token = 'vxrtcjvztv1icgjzsui45de9kmwlz0lf'; - const baseUrl = 'https://pimdev.1211.my.id/rest/V1/products'; + const baseUrl = 'https://pimdev.1211.my.id/rest/V1'; try { - // 1. Pastikan SKU menjadi string dan hapus spasi kiri/kanan - const cleanSku = String(sku).trim(); - - // 2. Encode SKU - const encodedSku = encodeURIComponent(cleanSku); - - // 3. Bentuk URL Final - const finalUrl = `${baseUrl}/${encodedSku}`; + const skuList = String(skus).split(','); // Contoh: ['221', '222', '223'] + const mainSku = String(main_sku || skuList[0]).trim(); // Fallback ke yang pertama - // --- DEBUGGING LOG --- - console.log('Fetching URL:', finalUrl); + // ===================================================================== + // 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' + }); - // Request ke Product Endpoint - const response = await fetch(finalUrl, { + const productUrl = `${baseUrl}/products?${searchParams.toString()}`; + + const productResponse = await fetch(productUrl, { method: 'GET', headers: { 'Content-Type': 'application/json', @@ -37,102 +38,99 @@ export default async function handler( }, }); - if (!response.ok) { - console.error(`Magento Error: ${response.status} ${response.statusText}`); - return res.status(response.status).json({ - error: 'Failed to fetch from Magento', - magentoStatus: response.status, - checkedUrl: finalUrl - }); + if (!productResponse.ok) { + return res.status(200).json({ specsMatrix: [], upsell_ids: [], related_ids: [] }); } - const data = await response.json(); + const productData = await productResponse.json(); + const items = productData.items || []; + + if (items.length === 0) { + return res.status(200).json({ specsMatrix: [], upsell_ids: [], related_ids: [] }); + } // ===================================================================== - // TAMBAHAN 1: FETCH LABEL ATRIBUT (z_*) + // 2. BUILD SPECS MATRIX + // Kita butuh daftar semua atribut unik (z_*) dari seluruh varian // ===================================================================== - let specsWithLabels: any[] = []; - - if (data.custom_attributes) { - const zAttributes = data.custom_attributes.filter((attr: any) => - attr.attribute_code.startsWith('z') - ); - - specsWithLabels = await Promise.all( - zAttributes.map(async (attr: any) => { - try { - const attrUrl = `https://pimdev.1211.my.id/rest/V1/products/attributes/${attr.attribute_code}`; - - const attrRes = await fetch(attrUrl, { - method: 'GET', - headers: { - 'Authorization': `Bearer ${token}`, - 'Content-Type': 'application/json', - } - }); - - if (attrRes.ok) { - const attrData = await attrRes.json(); - return { - code: attr.attribute_code, - label: attrData.default_frontend_label || attr.attribute_code, - value: attr.value - }; - } - } catch (err) { - console.error(`Failed to fetch label for ${attr.attribute_code}`); + // 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); } + }); + } + }); - const fallbackLabel = attr.attribute_code - .substring(1).replace(/_/g, ' ').trim(); + // 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: {} // Key = SKU/ID Variant, Value = Isi Atribut + }; + + items.forEach((p: any) => { + const attr = p.custom_attributes.find((a: any) => a.attribute_code === code); + // Simpan value berdasarkan SKU (ID Variant dari Odoo) + row.values[p.sku] = attr ? attr.value : '-'; + }); - return { - code: attr.attribute_code, - label: fallbackLabel, - value: attr.value - }; - }) - ); - } + matrix.push(row); + }); // ===================================================================== - // TAMBAHAN 2: AMBIL UP-SELLS (product_links type = upsell) + // 3. AMBIL LINKS (UPSELL & RELATED) DARI MAIN VARIANT SAJA // ===================================================================== - let upsellIds: number[] = []; - - if (data.product_links && Array.isArray(data.product_links)) { - upsellIds = data.product_links - .filter((link: any) => link.link_type === 'upsell') - .map((link: any) => Number(link.linked_product_sku)); - } + // Cari data milik varian utama (varian pertama) + const mainProduct = items.find((p: any) => String(p.sku) === mainSku) || items[0]; - // ===================================================================== - // TAMBAHAN 3: AMBIL RELATED PRODUCTS (product_links type = related) - // ===================================================================== + let upsellIds: number[] = []; let relatedIds: number[] = []; - if (data.product_links && Array.isArray(data.product_links)) { - relatedIds = data.product_links - .filter((link: any) => link.link_type === 'related') - .map((link: any) => Number(link.linked_product_sku)); + 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 GABUNGAN - // ===================================================================== - const responseData = { - ...data, - specs: specsWithLabels, // Data Spesifikasi (z_*) - upsell_ids: upsellIds, // Data Upsell ID - related_ids: relatedIds // Data Related ID (BARU) - }; - - res.status(200).json(responseData); - console.log(responseData); + // Response + res.status(200).json({ + specsMatrix: matrix, + upsell_ids: upsellIds, + related_ids: relatedIds + }); } catch (error) { - console.error('Proxy Server Error:', error); + console.error('Proxy Error:', error); res.status(500).json({ error: 'Internal Server Error' }); } }
\ No newline at end of file |
