E-Ticaret Panel
Mağazalar
Mağaza Düzenle
Mağaza Adı
XML Linki
Shopify Store Name
.myshopify.com
Access Token
API Version
2025-07 (En Güncel - Önerilen)
2025-04
2025-01
2024-10
2024-07
2024-04 (Legacy)
2024-01 (Legacy)
Mevcut: 2025-07
Kontrol Süresi
Saniye
Dakika
Saat
Gün
Product Path (Opsiyonel)
XML'de ürünlerin bulunduğu path
🏷️ Vendor (Marka) Filtreleme
📦 Tüm markalar işleniyor
← Ana sayfadan "Filtre Ekle" butonuyla vendor seçimi yapabilirsiniz
Converter Kodunuz
module.exports = function convert (item, utils = {}) { /* ---------- XML sarmallarını aç ---------- */ if (!item) return []; if (item.Root?.Urunler?.Urun) { const l = Array.isArray(item.Root.Urunler.Urun) ? item.Root.Urunler.Urun : [item.Root.Urunler.Urun]; return l.flatMap(u => convert(u, utils)); } if (item.Urunler?.Urun) { const l = Array.isArray(item.Urunler.Urun) ? item.Urunler.Urun : [item.Urunler.Urun]; return l.flatMap(u => convert(u, utils)); } if (item.Urun) item = item.Urun; /* ---------- yardımcılar ---------- */ const get = v => { if (v == null) return ''; if (Array.isArray(v)) return get(v[0]); if (typeof v === 'object') { if ('_' in v) return String(v._).trim(); if ('Deger' in v) return String(v.Deger).trim(); if ('Tanim' in v) return String(v.Tanim).trim(); return ''; } return String(v).trim(); }; const toNum = v => { const n = parseFloat(String(v ?? '').replace(',', '.').trim()); return Number.isFinite(n) ? n : 0; }; const toPrice = v => { const n = toNum(v); // Fiyatı 40.5 ile çarp const multiplied = n >= 0 ? (n * 40.5) : 0; return multiplied.toFixed(2); }; const uniqUrls = list => { const set = new Set(), out = []; (list || []).forEach(u => { const url = String(u || '').trim(); if (/^https?:\/\//i.test(url) && !set.has(url)) { set.add(url); out.push(url); } }); return out; }; const stripHtml = s => String(s || '') .replace(/<[^>]*>/g, ' ') .replace(/\s+/g, ' ') .trim(); const norm = s => String(s || '').trim().replace(/\s+/g, ' '); const safeColor = s => norm(s) || 'Renk Yok'; /* ---------- sabitler ---------- */ const OPT1 = 'Beden'; const OPT2 = 'Renk'; const OPT3 = ''; // üçüncü seçenek kullanılmıyor /* ---------- temel alanlar ---------- */ const id = get(item.UrunKartiID) || ''; const rawTitle = get(item.UrunAdi) || 'İsimsiz Ürün'; const title = utils.normalizeTitle ? utils.normalizeTitle(rawTitle) : rawTitle; const vendorRaw = get(item.Marka) || 'Sobe'; const vendor = utils.normalizeVendor ? utils.normalizeVendor(vendorRaw) : vendorRaw; const type = get(item.Kategori) || ''; const tags = get(item.KategoriTree) || ''; const onYazi = get(item.OnYazi); const aciklama = get(item.Aciklama); const ozelAlan1 = get(item.OzelAlan1); /* ---------- teknik detay ---------- */ let teknikList = []; (() => { let td = item.TeknikDetaylar; if (Array.isArray(td)) td = td[0]; if (td && td.TeknikDetay) { const lst = Array.isArray(td.TeknikDetay) ? td.TeknikDetay : [td.TeknikDetay]; teknikList = lst .map(t => ({ name: get(t.OzellikTanim), val: get(t.DegerTanim) })) .filter(o => o.name || o.val); } })(); /* ---------- ürün görselleri ---------- */ let imageUrls = []; (() => { let r = item.Resimler; if (Array.isArray(r)) r = r[0]; const raws = r?.Resim ? (Array.isArray(r.Resim) ? r.Resim : [r.Resim]) : []; imageUrls = uniqUrls(raws.map(get)); })(); /* ---------- varyant sarmalı ---------- */ let secenekler = []; (() => { const wrap = item.UrunSecenek; if (!wrap) return; const secWraps = Array.isArray(wrap) ? wrap : [wrap]; secWraps.forEach(w => { const lst = w?.Secenek ? (Array.isArray(w.Secenek) ? w.Secenek : [w.Secenek]) : []; lst.forEach(s => s && secenekler.push(s)); }); })(); // pickOptionValue fonksiyonuna bu debug satırları ekleyin: function pickOptionValue (secenek, key) { let ozellikleri = []; // EkSecenekOzellik array olabileceği için önce onu handle et let ekSecenek = secenek?.EkSecenekOzellik; // Eğer array ise ilk elemanı al if (Array.isArray(ekSecenek)) { ekSecenek = ekSecenek[0]; } // Şimdi Ozellik'e eriş if (ekSecenek?.Ozellik) { const ozl = ekSecenek.Ozellik; ozellikleri = Array.isArray(ozl) ? ozl : [ozl]; } // Özellikleri ara for (const o of ozellikleri) { let tanimVal = ''; let degerVal = ''; // xml2js formatı: { $: {Tanim, Deger}, _: 'text' } if (o.$ && typeof o.$ === 'object') { tanimVal = o.$.Tanim || o.$.tanim || ''; degerVal = o.$.Deger || o.$.deger || ''; } // Doğrudan attribute'lar if (!tanimVal) { tanimVal = o.Tanim || o.tanim || o['@Tanim'] || o['@tanim'] || ''; } if (!degerVal) { degerVal = o.Deger || o.deger || o['@Deger'] || o['@deger'] || ''; } // Element içeriği if (!degerVal) { degerVal = o._ || o['#text'] || ''; } // String'e çevir ve temizle tanimVal = String(tanimVal || '').trim(); degerVal = String(degerVal || '').trim(); // Karşılaştırma (case-insensitive) if (tanimVal.toLowerCase() === key.toLowerCase()) { return degerVal; } } return ''; } /* ---------- ham varyant listesi ---------- */ const rawDetails = (secenekler.length ? secenekler : [{}]).map((s, idx) => { const sku = get(s.StokKodu) || `${id}-SKU${idx + 1}`; const barcode = get(s.Barkod); const qty = parseInt(get(s.StokAdedi) || '0', 10) || 0; const indirim = toNum(get(s.IndirimliFiyat)); const price = indirim > 0 ? toPrice(indirim) : toPrice(get(s.SatisFiyati)); const paraBrm = (get(s.ParaBirimiKodu) || get(s.ParaBirimi) || 'USD').toUpperCase(); const renk = safeColor(pickOptionValue(s, 'Renk')); const beden = norm(pickOptionValue(s, 'Beden')) || 'STD'; const desi = toNum(get(s.Desi)); const grams = desi > 0 ? Math.round(desi * 1000) : 500; return { sku, barcode, qty, price, paraBrm, renk, beden, grams }; }); /* ---------- aynı beden‑renkleri birleştir ---------- */ const merged = new Map(); rawDetails.forEach(d => { const k = `${d.beden}||${d.renk}`; if (merged.has(k)) { const m = merged.get(k); m.qty += d.qty; if (!m.barcode && d.barcode) m.barcode = d.barcode; } else { merged.set(k, { ...d }); } }); const details = Array.from(merged.values()); /* ---------- açıklama HTML ---------- */ function buildDescriptionHTML () { const blocks = []; if (onYazi) blocks.push(onYazi); if (aciklama) blocks.push(aciklama); if (ozelAlan1) blocks.push('<strong>Set İçerik Bilgisi:</strong> ' + ozelAlan1); if (teknikList.length) { const li = teknikList.map(t => `<li><strong>${t.name}:</strong> ${t.val}</li>`).join(''); blocks.push('<h3>Teknik Detaylar</h3><ul>' + li + '</ul>'); } const rows = details.map(d => ` <tr> <td>${d.sku}</td> <td>${d.renk}</td> <td>${d.beden}</td> <td>${d.qty}</td> <td>${d.price} ${d.paraBrm}</td> <td>${d.barcode || '-'}</td> </tr>`).join(''); blocks.push(` <h3>Varyasyonlar</h3> <table border="1" cellpadding="6" cellspacing="0"> <thead> <tr> <th>SKU</th><th>Renk</th><th>Beden</th><th>Stok</th><th>Fiyat</th><th>Barkod</th> </tr> </thead> <tbody>${rows}</tbody> </table>`.trim()); const barkodlar = Array.from(new Set(details.map(d => d.barcode).filter(Boolean))); if (barkodlar.length) blocks.push('<strong>Barkod:</strong> ' + barkodlar.join(' , ')); return blocks.join('<br/>'); } const bodyHtml = buildDescriptionHTML(); const seoDesc = stripHtml(bodyHtml).substring(0, 160); /* ---------- handle ---------- */ const base = `${id}-${title}`; const handle = utils.toHandle ? utils.toHandle(base) : base.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/^-+|-+$/g, ''); const PRODUCT_KEY = handle; /* ---------- satır şablonları ---------- */ function baseRow () { return { '__PRODUCT_KEY' : PRODUCT_KEY, 'Handle' : handle, 'Title' : '', 'Body (HTML)' : '', 'Vendor' : '', 'Type' : '', 'Tags' : '', 'Published' : 'TRUE', 'Option1 Name' : OPT1, 'Option1 Value' : '', 'Option2 Name' : OPT2, 'Option2 Value' : '', 'Option3 Name' : OPT3, 'Option3 Value' : '', 'Variant SKU' : '', 'Variant Grams' : 0, 'Variant Inventory Tracker' : 'shopify', 'Variant Inventory Qty' : 0, 'Variant Inventory Policy' : 'deny', 'Variant Fulfillment Service' : 'manual', 'Variant Price' : '0.00', 'Variant Compare At Price' : '', 'Variant Requires Shipping' : 'TRUE', 'Variant Taxable' : 'TRUE', 'Variant Barcode' : '', 'Image Src' : '', 'Image Position' : '', 'Image Alt Text' : '', 'Gift Card' : 'FALSE', 'SEO Title' : '', 'SEO Description' : '', 'Google Shopping / Google Product Category' : '', 'Google Shopping / Gender' : 'female', 'Google Shopping / Age Group' : 'adult', 'Google Shopping / MPN' : '', 'Google Shopping / Condition' : 'new', 'Variant Image' : '', 'Variant Weight Unit': 'kg', 'Variant Tax Code' : '', 'Cost per item' : '', 'Status' : 'active' }; } function imageOnlyRow (src, pos) { const r = baseRow(); r.Published = ''; r['Variant Inventory Tracker'] = ''; r['Variant Inventory Qty'] = ''; r['Variant Inventory Policy'] = ''; r['Variant Fulfillment Service'] = ''; r['Variant Price'] = ''; r['Variant Requires Shipping'] = ''; r['Variant Taxable'] = ''; r['Variant Barcode'] = ''; r['Variant Grams'] = ''; r['Variant Weight Unit'] = ''; r.Status = ''; r['Body (HTML)'] = ''; r.Vendor = ''; r.Type = ''; r.Tags = ''; r['SEO Title'] = ''; r['SEO Description'] = ''; r['Image Src'] = src || ''; r['Image Position'] = pos || ''; r['Image Alt Text'] = title; r['Option1 Value'] = ''; r['Option2 Value'] = ''; r['Option3 Value'] = ''; r['Variant Image'] = ''; return r; } /* ---------- satırları derle ---------- */ const rows = []; const emitted = new Set(); let nextPos = 1; const primary = imageUrls[0] || ''; details.forEach((d, idx) => { const r = baseRow(); if (idx === 0) { r.Title = title; r['Body (HTML)'] = bodyHtml; r.Vendor = vendor; r.Type = type; r.Tags = tags; r['SEO Title'] = title; r['SEO Description'] = seoDesc; } r['Option1 Value'] = d.beden; r['Option2 Value'] = d.renk; r['Option3 Value'] = ''; r['Variant SKU'] = d.sku; r['Variant Price'] = d.price; r['Variant Inventory Qty'] = d.qty; r['Variant Barcode'] = d.barcode || ''; r['Variant Grams'] = d.grams; if (idx === 0 && primary) { r['Image Src'] = primary; r['Image Position'] = String(nextPos++); r['Variant Image'] = primary; r['Image Alt Text'] = `${title} ${d.renk} ${d.beden}`.trim(); emitted.add(primary); } rows.push(r); }); /* diğer görseller */ for (let i = 1; i < imageUrls.length; i += 1) { const url = imageUrls[i]; if (!url || emitted.has(url)) continue; rows.push(imageOnlyRow(url, String(nextPos++))); emitted.add(url); } return rows; };
Güncelle
İptal
İstatistikler
Toplam Çalışma
2355
Başarı Oranı
90%
İşlenen Ürün
0
Push Edilen
0