Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-06-04 14:33:10 +03:00
parent 00626152c2
commit 7b1588d69d
11 changed files with 2065 additions and 78 deletions

View File

@@ -90,6 +90,23 @@
:disable="selectedRowCount === 0"
@click="bulkDialogOpen = true"
/>
<q-btn
color="primary"
flat
icon="download"
label="Sayfayi Excel'e Aktar"
:disable="filteredRows.length === 0"
@click="exportCurrentView"
/>
<q-btn
color="primary"
outline
icon="download_for_offline"
label="Tum Filtreyi Excel'e Aktar"
:disable="filteredRows.length === 0 || exportAllLoading"
:loading="exportAllLoading"
@click="exportAllFiltered"
/>
<q-pagination
v-model="currentPage"
color="primary"
@@ -491,8 +508,9 @@
<script setup>
import { computed, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { Notify } from 'quasar'
import { useProductPricingStore } from 'src/stores/ProductPricingStore'
import api from 'src/services/api'
import api, { download } from 'src/services/api'
const store = useProductPricingStore()
const PAGE_LIMIT = 250
@@ -742,6 +760,7 @@ const bulkDialogOpen = ref(false)
const bulkField = ref('expenseForBasePrice')
const bulkValue = ref('')
const selectedCurrencies = ref(['USD', 'EUR', 'TRY'])
const exportAllLoading = ref(false)
const showSelectedOnly = ref(false)
const editableColumns = [
@@ -859,6 +878,8 @@ const visibleColumns = computed(() => {
})
})
const exportableColumns = computed(() => visibleColumns.value.filter((col) => col.name !== 'select' && col.name !== 'calcAction'))
const stickyLeftMap = computed(() => {
const map = {}
let left = 0
@@ -1205,6 +1226,100 @@ function formatDateDisplay (val) {
return `${day}.${month}.${year}`
}
function exportCellValue (row, field) {
if (field === 'stockQty') return formatStock(row?.[field])
if (field === 'stockEntryDate' || field === 'lastCostingDate' || field === 'lastPricingDate') return formatDateDisplay(row?.[field])
if (editableColumnSet.has(field)) return String(round2(row?.[field] || 0))
return String(row?.[field] ?? '').trim()
}
function csvSafe (value) {
let text = String(value ?? '').replaceAll('\r', ' ').replaceAll('\n', ' ').trim()
if (text.includes(';') || text.includes('"')) {
text = `"${text.replaceAll('"', '""')}"`
}
return text
}
function exportCurrentView () {
const cols = exportableColumns.value
const list = filteredRows.value
if (cols.length === 0 || list.length === 0) return
const lines = [cols.map((col) => csvSafe(col.label)).join(';')]
for (const row of list) {
lines.push(cols.map((col) => csvSafe(exportCellValue(row, col.field))).join(';'))
}
const bom = '\uFEFF'
const blob = new Blob([bom + lines.join('\n')], { type: 'text/csv;charset=utf-8;' })
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `product_pricing_${new Date().toISOString().slice(0, 10)}.csv`
document.body.appendChild(a)
a.click()
a.remove()
URL.revokeObjectURL(url)
}
async function exportAllFiltered () {
exportAllLoading.value = true
try {
const filters = buildServerFilters()
const params = {
product_code: (filters.product_code || []).join(','),
brand_group_selection: (filters.brand_group_selection || []).join(','),
marka: (filters.marka || []).join(','),
askili_yan: (filters.askili_yan || []).join(','),
kategori: (filters.kategori || []).join(','),
urun_ilk_grubu: (filters.urun_ilk_grubu || []).join(','),
urun_ana_grubu: (filters.urun_ana_grubu || []).join(','),
urun_alt_grubu: (filters.urun_alt_grubu || []).join(','),
icerik: (filters.icerik || []).join(','),
karisim: (filters.karisim || []).join(','),
sort_by: tablePagination.value?.sortBy || '',
desc: tablePagination.value?.descending ? 1 : 0,
currencies: (selectedCurrencies.value || []).join(',')
}
for (const field of valueFilterFields) {
const values = valueFilters.value[field] || []
if (values.length > 0) {
params[`vf_${field}`] = values.join(',')
}
}
const stockQtyMin = String(numberRangeFilters.value.stockQty?.min || '').trim()
const stockQtyMax = String(numberRangeFilters.value.stockQty?.max || '').trim()
if (stockQtyMin) params.stock_qty_min = stockQtyMin
if (stockQtyMax) params.stock_qty_max = stockQtyMax
const stockEntryFrom = String(dateRangeFilters.value.stockEntryDate?.from || '').trim()
const stockEntryTo = String(dateRangeFilters.value.stockEntryDate?.to || '').trim()
const lastPricingFrom = String(dateRangeFilters.value.lastPricingDate?.from || '').trim()
const lastPricingTo = String(dateRangeFilters.value.lastPricingDate?.to || '').trim()
if (stockEntryFrom) params.stock_entry_from = stockEntryFrom
if (stockEntryTo) params.stock_entry_to = stockEntryTo
if (lastPricingFrom) params.last_pricing_from = lastPricingFrom
if (lastPricingTo) params.last_pricing_to = lastPricingTo
const blob = await download('/pricing/products/export-all', params)
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = `product_pricing_all_${new Date().toISOString().slice(0, 10)}.csv`
document.body.appendChild(a)
a.click()
a.remove()
URL.revokeObjectURL(url)
} catch (err) {
Notify.create({ type: 'negative', message: err?.message || 'Tum filtre export alinamadi' })
} finally {
exportAllLoading.value = false
}
}
function needsRepricing (row) {
const stockEntryDate = String(row?.stockEntryDate || '').trim()
const lastPricingDate = String(row?.lastPricingDate || '').trim()