From 81384426ff581e64a9e4edb872fddb9328267e2e Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Sat, 4 Jul 2026 13:10:22 +0300 Subject: [PATCH] Fix product performance grouped JSON build --- .../pages/ProductPerformanceProfitability.vue | 87 ++++++++++++++----- 1 file changed, 66 insertions(+), 21 deletions(-) diff --git a/ui/src/pages/ProductPerformanceProfitability.vue b/ui/src/pages/ProductPerformanceProfitability.vue index eb6369a..a36e291 100644 --- a/ui/src/pages/ProductPerformanceProfitability.vue +++ b/ui/src/pages/ProductPerformanceProfitability.vue @@ -1578,6 +1578,7 @@ const backendGroupedRows = ref({}) const backendGroupedLoading = ref(false) const imagePrimeLoading = ref(false) const filterBusy = ref(false) +const generalRowsLoaded = ref(false) let backendGroupedTimer = null let imagePrimeActiveRequests = 0 @@ -1587,7 +1588,7 @@ const expandedGroups = ref({}) const lastManualExpandedGroupKey = ref('') const selectedExpandLevelKeysByTab = reactive({ products: ['urun_ilk_grubu', 'askili_yan', 'kategori'], - product_detail: ['urun_ana_grubu', 'urun_alt_grubu'], + product_detail: ['urun_alt_grubu'], sales_color_yaka_market_customer: ['color_yaka'], idle: ['urun_ilk_grubu', 'askili_yan', 'kategori'], sales_product_country_segment_market_customer: ['market_key', 'customer_code', 'customer_name', 'urun_ilk_grubu', 'askili_yan'], @@ -2459,7 +2460,6 @@ const groupLevels = [ const tabGroupLevels = { products: groupLevels, product_detail: [ - { key: 'urun_ana_grubu', label: 'Ürün Ana Grubu' }, { key: 'urun_alt_grubu', label: 'Ürün Alt Grubu' }, { key: 'product_code', label: 'Ürün' }, { key: 'color_yaka', label: 'Renk/Yaka' }, @@ -2696,6 +2696,30 @@ const detailMainGroupOptions = computed(() => { .sort((a, b) => Number(b.sales_qty_90d || 0) - Number(a.sales_qty_90d || 0) || a.label.localeCompare(b.label, 'tr')) }) +function filterRowsBySelectedDetailMainGroup (sourceRows) { + const selected = String(selectedDetailMainGroup.value || '').trim() + const rows = Array.isArray(sourceRows) ? sourceRows : [] + if (!selected) return [] + return rows.filter(row => { + const value = productMainGroupValue(row) + if (value === selected) return true + return Boolean(row?.__group && row.group_field !== 'urun_ana_grubu' && !value) + }) +} + +function ensureDetailMainGroupSelection () { + const options = detailMainGroupOptions.value + if (!options.length) { + selectedDetailMainGroup.value = '' + return false + } + const preferred = options.find(option => String(option.value || '').toLocaleUpperCase('tr-TR') === 'TAKIM ELBISE') + if (!selectedDetailMainGroup.value || !options.some(option => option.value === selectedDetailMainGroup.value)) { + selectedDetailMainGroup.value = (preferred || options[0]).value + } + return true +} + const productGroupKeys = computed(() => { const keys = [] collectGroupKeys(keys, filteredProductRows.value, 0, ['tab:products'], groupLevels) @@ -2756,7 +2780,9 @@ function buildGroupedTableRows (tableKey, sourceRows) { function backendRowsForTab (tabKey, fallbackRows) { const rows = backendGroupedRows.value[tabKey] const backendRows = Array.isArray(rows) && rows.length ? rows : [] - const sourceRows = backendRows.length ? backendRows : fallbackRows + const sourceRows = tabKey === 'product_detail' + ? filterRowsBySelectedDetailMainGroup(backendRows.length ? backendRows : fallbackRows) + : (backendRows.length ? backendRows : fallbackRows) if (hasActiveTableFilters(tabKey)) { return filterRowsForTable(tabKey, sourceRows, columnsForTableKey(tabKey)) } @@ -4238,6 +4264,14 @@ function switchPerformanceTab (tabName) { async function loadBackendGroupedRows (options = {}) { const tabKey = activeTab.value if (!backendGroupedSupportedTab(tabKey)) return + if (tabKey === 'product_detail' && !ensureDetailMainGroupSelection()) { + backendGroupedRows.value = { + ...backendGroupedRows.value, + product_detail: [] + } + backendGroupedLoading.value = false + return + } pruneActiveExpandedGroups() backendGroupedLoading.value = true const params = { @@ -4331,10 +4365,12 @@ async function timedProductPerformanceGet (label, url, config = {}) { async function reload () { loading.value = true try { + generalRowsLoaded.value = false + generalRows.value = [] marketRowsLoaded.value = false countryRowsLoaded.value = false customerRowsLoaded.value = false - const [summaryResp, listResp, generalResp] = await Promise.all([ + const [summaryResp, listResp] = await Promise.all([ timedProductPerformanceGet('summary', '/pricing/product-performance/summary', { timeout: 60000 }), timedProductPerformanceGet('product-kpi', '/pricing/product-performance', { params: { @@ -4342,17 +4378,10 @@ async function reload () { limit: productKpiFetchLimit }, timeout: 60000 - }), - timedProductPerformanceGet('general', '/pricing/product-performance/general', { params: { limit: reportFetchLimit }, timeout: 60000 }) + }) ]) summary.value = summaryResp?.data || {} - const normalizedGeneralRows = (Array.isArray(generalResp?.data) ? generalResp.data : []).map(normalizeGeneralRow) - const generalByVariant = new Map(normalizedGeneralRows.map(row => [performanceVariantKey(row), generalMetricFields(row)])) - rows.value = (Array.isArray(listResp?.data?.rows) ? listResp.data.rows : []).map(row => { - const generalMetrics = generalByVariant.get(performanceVariantKey(row)) || {} - return normalizeRow({ ...row, ...generalMetrics }) - }) - generalRows.value = normalizedGeneralRows + rows.value = (Array.isArray(listResp?.data?.rows) ? listResp.data.rows : []).map(normalizeRow) await ensureActiveTabData(false) await loadBackendGroupedRows({ force: true }) } catch (err) { @@ -4362,6 +4391,27 @@ async function reload () { } } +async function loadGeneralRows (showLoading = true) { + if (generalRowsLoaded.value) return + if (showLoading) loading.value = true + try { + const resp = await timedProductPerformanceGet('general', '/pricing/product-performance/general', { params: { limit: reportFetchLimit }, timeout: 90000 }) + const normalizedGeneralRows = (Array.isArray(resp?.data) ? resp.data : []).map(normalizeGeneralRow) + generalRows.value = normalizedGeneralRows + generalRowsLoaded.value = true + + const generalByVariant = new Map(normalizedGeneralRows.map(row => [performanceVariantKey(row), generalMetricFields(row)])) + rows.value = rows.value.map(row => { + const generalMetrics = generalByVariant.get(performanceVariantKey(row)) || {} + return Object.keys(generalMetrics).length ? normalizeRow({ ...row, ...generalMetrics }) : row + }) + } catch (err) { + Notify.create({ type: 'negative', message: err?.response?.data || err?.message || 'Genel performans verisi alınamadı' }) + } finally { + if (showLoading) loading.value = false + } +} + async function loadOrderProductCustomers (showLoading = true) { if (showLoading) loading.value = true try { @@ -4441,6 +4491,7 @@ async function loadCustomerRows (showLoading = true) { async function ensureActiveTabData (showLoading = true) { const tab = activeTab.value + if (tab === 'general') return loadGeneralRows(showLoading) if (tab === 'markets') return loadMarketRows(showLoading) if (tab === 'countries') return loadCountryRows(showLoading) if (tab === 'customers') return loadCustomerRows(showLoading) @@ -4490,14 +4541,8 @@ watch(activeSelectedExpandLevelKeys, () => { scheduleLoadBackendGroupedRows() }) -watch(detailMainGroupOptions, options => { - if (!options.length) { - selectedDetailMainGroup.value = '' - return - } - if (!selectedDetailMainGroup.value || !options.some(option => option.value === selectedDetailMainGroup.value)) { - selectedDetailMainGroup.value = options[0].value - } +watch(detailMainGroupOptions, () => { + ensureDetailMainGroupSelection() }, { immediate: true }) watch(selectedDetailMainGroup, () => {