From 10c173d41d3a661750ca2c90d3849f5afb59e703 Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Fri, 19 Jun 2026 23:30:14 +0300 Subject: [PATCH] Merge remote-tracking branch 'origin/master' --- ui/src/pages/OrderPriceList.vue | 149 ++++++++++++++++++---------- ui/src/pages/ProductPricing.vue | 47 +++++---- ui/src/pages/WholesaleCampaigns.vue | 15 ++- 3 files changed, 135 insertions(+), 76 deletions(-) diff --git a/ui/src/pages/OrderPriceList.vue b/ui/src/pages/OrderPriceList.vue index 9fee32d..f1492a1 100644 --- a/ui/src/pages/OrderPriceList.vue +++ b/ui/src/pages/OrderPriceList.vue @@ -794,7 +794,27 @@ function toText (value) { } function toNumber (value) { - const n = Number(String(value ?? '0').replace(/\./g, '').replace(',', '.')) + if (typeof value === 'number') return Number.isFinite(value) ? value : 0 + const text = String(value ?? '').trim().replace(/\s/g, '') + if (!text) return 0 + const lastComma = text.lastIndexOf(',') + const lastDot = text.lastIndexOf('.') + let normalized = text + if (lastComma >= 0 && lastDot >= 0) { + normalized = lastComma > lastDot + ? text.replace(/\./g, '').replace(',', '.') + : text.replace(/,/g, '') + } else if (lastComma >= 0) { + normalized = text.replace(/\./g, '').replace(',', '.') + } else if (lastDot >= 0) { + const parts = text.split('.') + const lastPart = parts[parts.length - 1] || '' + const looksLikeThousands = parts.length > 1 && lastPart.length === 3 && parts.slice(0, -1).every((p, i) => ( + i === 0 ? p.length >= 1 && p.length <= 3 : p.length === 3 + )) + normalized = looksLikeThousands ? text.replace(/\./g, '') : text + } + const n = Number(normalized) return Number.isFinite(n) ? n : 0 } @@ -1582,57 +1602,82 @@ function exportFileStamp () { return `${d.getFullYear()}${pad(d.getMonth() + 1)}${pad(d.getDate())}-${pad(d.getHours())}${pad(d.getMinutes())}` } -function buildServerPriceListExportPayload () { - const filters = columnFilters.value || {} - return { - in_stock_only: !!showInStockOnly.value, - include_meta: true, - include_cost: false, - include_base: false, - price_fields: [...selectedPriceOptions.value], - product_code: selectedProductCodes.value.length > 0 ? [...selectedProductCodes.value] : [], - brand_group: Array.isArray(filters.brandGroupSelection) ? filters.brandGroupSelection : [], - marka: Array.isArray(filters.marka) ? filters.marka : [], - askili_yan: Array.isArray(filters.askiliYan) ? filters.askiliYan : [], - kategori: Array.isArray(filters.kategori) ? filters.kategori : [], - urun_ilk_grubu: topUrunIlkGrubu.value ? [topUrunIlkGrubu.value] : (Array.isArray(filters.urunIlkGrubu) ? filters.urunIlkGrubu : []), - urun_ana_grubu: topUrunAnaGrubu.value ? [topUrunAnaGrubu.value] : (Array.isArray(filters.urunAnaGrubu) ? filters.urunAnaGrubu : []), - urun_alt_grubu: Array.isArray(filters.urunAltGrubu) ? filters.urunAltGrubu : [], - icerik: Array.isArray(filters.icerik) ? filters.icerik : [], - karisim: Array.isArray(filters.karisim) ? filters.karisim : [] - } -} - -function downloadBlob (blob, fileName) { - const url = URL.createObjectURL(blob) - const a = document.createElement('a') - a.href = url - a.download = fileName - document.body.appendChild(a) - a.click() - a.remove() - URL.revokeObjectURL(url) -} - async function printVisibleRows () { - try { - const fileName = `Fiyat_Listesi-${exportFileStamp()}.pdf` - const res = await api.request({ - method: 'POST', - url: '/order/price-list/export-pdf', - data: buildServerPriceListExportPayload(), - responseType: 'blob', - timeout: 0 - }) - const blob = res?.data instanceof Blob - ? res.data - : new Blob([res?.data || ''], { type: 'application/pdf' }) - downloadBlob(blob, fileName) - await notifyExportTaken('pdf') - Notify.create({ type: 'positive', message: 'PDF indirildi.' }) - } catch (err) { - Notify.create({ type: 'negative', message: err?.response?.data || err?.message || 'PDF olusturulamadi' }) + const stamp = exportFileStamp() + const title = `Fiyat_Listesi-${stamp}` + const cols = visibleColumns.value + const generatedAt = new Date().toLocaleString('tr-TR') + const body = filteredRows.value.map((row) => `${cols.map((c) => { + if (c.name === 'image') { + return row.imageUrl + ? `` + : '' + } + const cls = [ + isExcelNumericColumn(c) ? 'num' : '', + priceColumnNames.includes(c.name) ? 'price' : '', + c.name.endsWith('Campaign') ? 'campaign-price' : '', + c.name === 'karisim' ? 'wrap' : '' + ].filter(Boolean).join(' ') + return `${escapeHtml(exportCell(row, c))}` + }).join('')}`).join('') + const headerCols = cols.map((c) => `${escapeHtml(c.label || 'Gorsel')}`).join('') + const html = `${escapeHtml(title)} + + + + ${headerCols} + + ${body} +
+
Fiyat Listesi
+
Tarih: ${escapeHtml(generatedAt)} | Satir: ${filteredRows.value.length} | Fiyatlar: ${escapeHtml(selectedPriceOptions.value.join(', '))}
+
+ +