summaryrefslogtreecommitdiff
path: root/src/pages/api/magento-product.ts
diff options
context:
space:
mode:
Diffstat (limited to 'src/pages/api/magento-product.ts')
-rw-r--r--src/pages/api/magento-product.ts168
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