Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -5,14 +5,17 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
state: () => ({
|
||||
filters: {
|
||||
selectedDate: new Date().toISOString().slice(0, 10),
|
||||
excludeZeroBalance12: false,
|
||||
excludeZeroBalance13: false,
|
||||
cariSearch: '',
|
||||
appliedCariSearch: '',
|
||||
cariIlkGrup: [],
|
||||
piyasa: [],
|
||||
temsilci: [],
|
||||
riskDurumu: [],
|
||||
islemTipi: [],
|
||||
ulke: []
|
||||
ulke: [],
|
||||
il: [],
|
||||
ilce: []
|
||||
},
|
||||
rows: [],
|
||||
loading: false,
|
||||
@@ -25,26 +28,47 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
cariIlkGrupOptions: (state) => uniqueOptions(state.rows, 'cari_ilk_grup'),
|
||||
piyasaOptions: (state) => uniqueOptions(state.rows, 'piyasa'),
|
||||
temsilciOptions: (state) => uniqueOptions(state.rows, 'temsilci'),
|
||||
riskDurumuOptions: (state) => uniqueOptions(state.rows, 'ozellik03'),
|
||||
riskDurumuOptions: (state) => uniqueOptions(state.rows, 'risk_durumu'),
|
||||
ulkeOptions: (state) => uniqueOptions(state.rows, 'ozellik05'),
|
||||
ilOptions: (state) => uniqueOptions(state.rows, 'il'),
|
||||
ilceOptions: (state) => uniqueOptions(state.rows, 'ilce'),
|
||||
|
||||
filteredRows: (state) => {
|
||||
const selectedCariIlkGrup = new Set((state.filters.cariIlkGrup || []).map(v => normalizeText(v)))
|
||||
const selectedPiyasa = new Set((state.filters.piyasa || []).map(v => normalizeText(v)))
|
||||
const selectedTemsilci = new Set((state.filters.temsilci || []).map(v => normalizeText(v)))
|
||||
const selectedRiskDurumu = new Set((state.filters.riskDurumu || []).map(v => normalizeText(v)))
|
||||
const selectedUlke = new Set((state.filters.ulke || []).map(v => normalizeText(v)))
|
||||
const selectedIl = new Set((state.filters.il || []).map(v => normalizeText(v)))
|
||||
const selectedIlce = new Set((state.filters.ilce || []).map(v => normalizeText(v)))
|
||||
|
||||
const matchMulti = (selectedSet, value) => {
|
||||
if (!selectedSet.size) return true
|
||||
const normalized = normalizeText(value)
|
||||
if (!normalized) return true
|
||||
return selectedSet.has(normalized)
|
||||
}
|
||||
|
||||
return state.rows.filter((row) => {
|
||||
const bak12 = Number(row.bakiye_1_2) || 0
|
||||
const bak13 = Number(row.bakiye_1_3) || 0
|
||||
const usd12 = Number(row.usd_bakiye_1_2) || 0
|
||||
const try12 = Number(row.tl_bakiye_1_2) || 0
|
||||
const usd13 = Number(row.usd_bakiye_1_3) || 0
|
||||
const try13 = Number(row.tl_bakiye_1_3) || 0
|
||||
const cariSearchNeedle = normalizeText(state.filters.cariSearch || '')
|
||||
|
||||
const cariIlkGrupOk =
|
||||
!state.filters.cariIlkGrup.length ||
|
||||
state.filters.cariIlkGrup.includes(row.cari_ilk_grup)
|
||||
matchMulti(selectedCariIlkGrup, row.cari_ilk_grup)
|
||||
|
||||
const piyasaOk =
|
||||
!state.filters.piyasa.length ||
|
||||
state.filters.piyasa.includes(row.piyasa)
|
||||
matchMulti(selectedPiyasa, row.piyasa)
|
||||
|
||||
const temsilciOk =
|
||||
!state.filters.temsilci.length ||
|
||||
state.filters.temsilci.includes(row.temsilci)
|
||||
matchMulti(selectedTemsilci, row.temsilci)
|
||||
|
||||
const riskDurumuOk =
|
||||
!state.filters.riskDurumu.length ||
|
||||
state.filters.riskDurumu.includes(row.ozellik03)
|
||||
matchMulti(selectedRiskDurumu, row.risk_durumu)
|
||||
|
||||
const cariText = normalizeText([
|
||||
row.ana_cari_kodu || '',
|
||||
@@ -52,25 +76,22 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
row.cari_kodu || '',
|
||||
row.cari_detay || ''
|
||||
].join(' '))
|
||||
const cariSearchNeedle = normalizeText(state.filters.appliedCariSearch || '')
|
||||
const cariSearchOk =
|
||||
!cariSearchNeedle ||
|
||||
cariText.includes(cariSearchNeedle)
|
||||
|
||||
const ulkeOk =
|
||||
!state.filters.ulke.length ||
|
||||
state.filters.ulke.includes(row.ozellik05)
|
||||
matchMulti(selectedUlke, row.ozellik05)
|
||||
|
||||
const ilOk =
|
||||
matchMulti(selectedIl, row.il)
|
||||
|
||||
const ilceOk =
|
||||
matchMulti(selectedIlce, row.ilce)
|
||||
|
||||
const islemTipiOk =
|
||||
!state.filters.islemTipi.length ||
|
||||
state.filters.islemTipi.some((t) => {
|
||||
const bak12 = Number(row.bakiye_1_2) || 0
|
||||
const bak13 = Number(row.bakiye_1_3) || 0
|
||||
const usd12 = Number(row.usd_bakiye_1_2) || 0
|
||||
const try12 = Number(row.tl_bakiye_1_2) || 0
|
||||
const usd13 = Number(row.usd_bakiye_1_3) || 0
|
||||
const try13 = Number(row.tl_bakiye_1_3) || 0
|
||||
|
||||
if (t === 'prbr_1_2') return bak12 !== 0
|
||||
if (t === 'prbr_1_3') return bak13 !== 0
|
||||
if (t === 'usd_1_2') return usd12 !== 0
|
||||
@@ -80,7 +101,12 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
return false
|
||||
})
|
||||
|
||||
return cariIlkGrupOk && piyasaOk && temsilciOk && riskDurumuOk && cariSearchOk && ulkeOk && islemTipiOk
|
||||
const excludeZero12Ok = !state.filters.excludeZeroBalance12 || bak12 !== 0
|
||||
const excludeZero13Ok = !state.filters.excludeZeroBalance13 || bak13 !== 0
|
||||
|
||||
return cariIlkGrupOk && piyasaOk && temsilciOk && riskDurumuOk &&
|
||||
cariSearchOk && ulkeOk && ilOk && ilceOk && islemTipiOk &&
|
||||
excludeZero12Ok && excludeZero13Ok
|
||||
})
|
||||
},
|
||||
|
||||
@@ -88,10 +114,10 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
const grouped = new Map()
|
||||
|
||||
for (const row of this.filteredRows) {
|
||||
const key = `${row.ana_cari_kodu || ''}||${row.ana_cari_adi || ''}`
|
||||
const key = String(row.ana_cari_kodu || '').trim()
|
||||
const current = grouped.get(key) || {
|
||||
group_key: key,
|
||||
ana_cari_kodu: row.ana_cari_kodu || '',
|
||||
ana_cari_kodu: key,
|
||||
ana_cari_adi: row.ana_cari_adi || '',
|
||||
piyasa: '',
|
||||
piyasa_set: new Set(),
|
||||
@@ -104,8 +130,7 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
usd_bakiye_1_2: 0,
|
||||
tl_bakiye_1_2: 0,
|
||||
usd_bakiye_1_3: 0,
|
||||
tl_bakiye_1_3: 0,
|
||||
kalan_fatura_ortalama_vade_tarihi: ''
|
||||
tl_bakiye_1_3: 0
|
||||
}
|
||||
|
||||
current.usd_bakiye_1_2 += Number(row.usd_bakiye_1_2) || 0
|
||||
@@ -113,6 +138,10 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
current.usd_bakiye_1_3 += Number(row.usd_bakiye_1_3) || 0
|
||||
current.tl_bakiye_1_3 += Number(row.tl_bakiye_1_3) || 0
|
||||
|
||||
if (!String(current.ana_cari_adi || '').trim() && String(row.ana_cari_adi || '').trim()) {
|
||||
current.ana_cari_adi = row.ana_cari_adi
|
||||
}
|
||||
|
||||
const curr = String(row.cari_doviz || '').trim().toUpperCase() || 'N/A'
|
||||
current.bakiye_1_2_map[curr] =
|
||||
(Number(current.bakiye_1_2_map[curr]) || 0) + (Number(row.bakiye_1_2) || 0)
|
||||
@@ -125,14 +154,7 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
const temsilci = String(row.temsilci || '').trim()
|
||||
if (temsilci) current.temsilci_set.add(temsilci)
|
||||
|
||||
if (
|
||||
!current.kalan_fatura_ortalama_vade_tarihi &&
|
||||
row.kalan_fatura_ortalama_vade_tarihi
|
||||
) {
|
||||
current.kalan_fatura_ortalama_vade_tarihi = row.kalan_fatura_ortalama_vade_tarihi
|
||||
}
|
||||
|
||||
const risk = String(row.ozellik03 || '').trim()
|
||||
const risk = String(row.risk_durumu || row.ozellik03 || '').trim()
|
||||
if (risk) current.risk_set.add(risk)
|
||||
|
||||
const riskValues = Array.from(current.risk_set)
|
||||
@@ -172,7 +194,7 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
const { data } = await api.get('/finance/customer-balances', {
|
||||
params: {
|
||||
selected_date: this.filters.selectedDate,
|
||||
cari_search: String(this.filters.appliedCariSearch || this.filters.cariSearch || '').trim()
|
||||
cari_search: String(this.filters.cariSearch || '').trim()
|
||||
}
|
||||
})
|
||||
this.rows = Array.isArray(data) ? data : []
|
||||
@@ -195,26 +217,25 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
|
||||
getDetailsByGroup (groupKey) {
|
||||
return this.filteredRows.filter(r =>
|
||||
`${r.ana_cari_kodu || ''}||${r.ana_cari_adi || ''}` === groupKey
|
||||
String(r.ana_cari_kodu || '').trim() === String(groupKey || '').trim()
|
||||
)
|
||||
},
|
||||
|
||||
resetFilters () {
|
||||
this.filters.excludeZeroBalance12 = false
|
||||
this.filters.excludeZeroBalance13 = false
|
||||
this.filters.cariSearch = ''
|
||||
this.filters.appliedCariSearch = ''
|
||||
this.filters.cariIlkGrup = []
|
||||
this.filters.piyasa = []
|
||||
this.filters.temsilci = []
|
||||
this.filters.riskDurumu = []
|
||||
this.filters.islemTipi = []
|
||||
this.filters.ulke = []
|
||||
this.filters.il = []
|
||||
this.filters.ilce = []
|
||||
this.defaultsInitialized = false
|
||||
},
|
||||
|
||||
applyCariSearch () {
|
||||
this.filters.appliedCariSearch = String(this.filters.cariSearch || '').trim()
|
||||
},
|
||||
|
||||
selectAll (field, options) {
|
||||
this.filters[field] = options.map(o => o.value)
|
||||
},
|
||||
@@ -224,10 +245,14 @@ export const useCustomerBalanceListStore = defineStore('customerBalanceList', {
|
||||
},
|
||||
|
||||
applyInitialFilterDefaults () {
|
||||
const transferKey = normalizeText('transfer')
|
||||
const excludedCariIlkGrup = new Set([
|
||||
normalizeText('transfer'),
|
||||
normalizeText('perakende'),
|
||||
normalizeText('dtf')
|
||||
])
|
||||
this.filters.cariIlkGrup = this.cariIlkGrupOptions
|
||||
.map(o => o.value)
|
||||
.filter(v => normalizeText(v) !== transferKey)
|
||||
.filter(v => !excludedCariIlkGrup.has(normalizeText(v)))
|
||||
|
||||
const excludedRisk = new Set([
|
||||
normalizeText('avukat'),
|
||||
@@ -260,3 +285,4 @@ function normalizeText (str) {
|
||||
.replace(/[\u0300-\u036f]/g, '')
|
||||
.trim()
|
||||
}
|
||||
|
||||
|
||||
222
ui/src/stores/statementAgingStore.js
Normal file
222
ui/src/stores/statementAgingStore.js
Normal file
@@ -0,0 +1,222 @@
|
||||
import { defineStore } from 'pinia'
|
||||
import api from 'src/services/api'
|
||||
import qs from 'qs'
|
||||
|
||||
export const useStatementAgingStore = defineStore('statementAging', {
|
||||
state: () => ({
|
||||
rows: [],
|
||||
masterRows: [],
|
||||
currencyRowsByMaster: {},
|
||||
detailByCurrency: {},
|
||||
loading: false
|
||||
}),
|
||||
|
||||
actions: {
|
||||
async load(params = {}) {
|
||||
this.loading = true
|
||||
try {
|
||||
const { data } = await api.get('/finance/account-aging-statement', {
|
||||
params,
|
||||
paramsSerializer: p => qs.stringify(p, { arrayFormat: 'repeat' })
|
||||
})
|
||||
|
||||
const base = Array.isArray(data) ? data.map(normalizeRowKeys) : []
|
||||
this.rows = base.map((r, idx) => ({
|
||||
...r,
|
||||
detail_key: `${idx}-${r.cari8 || ''}-${r.doc_currency_code || ''}-${r.fatura_ref || ''}-${r.odeme_ref || ''}`
|
||||
}))
|
||||
|
||||
this.rebuildHierarchical()
|
||||
} catch (err) {
|
||||
console.error('Aging statement load failed:', err)
|
||||
this.reset()
|
||||
throw err
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
},
|
||||
|
||||
rebuildHierarchical() {
|
||||
const masterMap = {}
|
||||
const currencyMap = {}
|
||||
const detailMap = {}
|
||||
|
||||
for (const row of this.rows) {
|
||||
const cari8 = String(row?.cari8 || '').trim()
|
||||
const curr = String(row?.doc_currency_code || '').trim().toUpperCase() || 'N/A'
|
||||
if (!cari8) continue
|
||||
|
||||
const masterKey = cari8
|
||||
const currencyKey = `${cari8}|${curr}`
|
||||
const tutar = Number(row?.eslesen_tutar) || 0
|
||||
const usd = Number(row?.usd_tutar) || 0
|
||||
const trY = Number(row?.try_tutar) || 0
|
||||
const absTry = Math.abs(trY)
|
||||
const gun = Number(row?.gun_sayisi) || 0
|
||||
const gunDoc = Number(row?.gun_sayisi_docdate) || 0
|
||||
const aciklama = String(row?.aciklama || '').toUpperCase()
|
||||
const isAcik = aciklama === 'ACIKKALEM'
|
||||
|
||||
if (!masterMap[masterKey]) {
|
||||
masterMap[masterKey] = {
|
||||
group_key: masterKey,
|
||||
cari8: masterKey,
|
||||
cari_detay: String(row?.cari_detay || '').trim(),
|
||||
acik_kalem_tutari_usd: 0,
|
||||
acik_kalem_tutari_try: 0,
|
||||
acik_kalem_ort_vade_gun: 0,
|
||||
acik_kalem_ort_belge_gun: 0,
|
||||
normal_usd_tutar: 0,
|
||||
normal_try_tutar: 0,
|
||||
ortalama_vade_gun: 0,
|
||||
ortalama_belge_gun: 0,
|
||||
weighted_all_base: 0,
|
||||
weighted_all_gun_sum: 0,
|
||||
weighted_all_doc_sum: 0,
|
||||
weighted_open_base: 0,
|
||||
weighted_open_gun_sum: 0,
|
||||
weighted_open_doc_sum: 0,
|
||||
}
|
||||
}
|
||||
|
||||
if (!currencyMap[currencyKey]) {
|
||||
currencyMap[currencyKey] = {
|
||||
group_key: currencyKey,
|
||||
master_key: masterKey,
|
||||
cari8,
|
||||
cari_detay: String(row?.cari_detay || '').trim(),
|
||||
doviz_cinsi: curr,
|
||||
acik_kalem_tutari: 0,
|
||||
acik_kalem_usd: 0,
|
||||
acik_kalem_try: 0,
|
||||
ort_gun: 0,
|
||||
ort_belge_gun: 0,
|
||||
weighted_open_base: 0,
|
||||
weighted_open_gun_sum: 0,
|
||||
weighted_open_doc_sum: 0
|
||||
}
|
||||
}
|
||||
|
||||
const m = masterMap[masterKey]
|
||||
const c = currencyMap[currencyKey]
|
||||
|
||||
if (isAcik) {
|
||||
m.acik_kalem_tutari_usd += usd
|
||||
m.acik_kalem_tutari_try += trY
|
||||
c.acik_kalem_tutari += tutar
|
||||
c.acik_kalem_usd += usd
|
||||
c.acik_kalem_try += trY
|
||||
} else {
|
||||
m.normal_usd_tutar += usd
|
||||
m.normal_try_tutar += trY
|
||||
}
|
||||
|
||||
if (absTry > 0) {
|
||||
m.weighted_all_base += absTry
|
||||
m.weighted_all_gun_sum += absTry * gun
|
||||
m.weighted_all_doc_sum += absTry * gunDoc
|
||||
|
||||
if (isAcik) {
|
||||
m.weighted_open_base += absTry
|
||||
m.weighted_open_gun_sum += absTry * gun
|
||||
m.weighted_open_doc_sum += absTry * gunDoc
|
||||
|
||||
c.weighted_open_base += absTry
|
||||
c.weighted_open_gun_sum += absTry * gun
|
||||
c.weighted_open_doc_sum += absTry * gunDoc
|
||||
}
|
||||
}
|
||||
|
||||
if (!detailMap[currencyKey]) detailMap[currencyKey] = []
|
||||
detailMap[currencyKey].push(row)
|
||||
}
|
||||
|
||||
this.masterRows = Object.values(masterMap)
|
||||
.map((m) => ({
|
||||
...m,
|
||||
acik_kalem_ort_vade_gun: m.weighted_open_base > 0 ? ceilDay(m.weighted_open_gun_sum / m.weighted_open_base) : 0,
|
||||
acik_kalem_ort_belge_gun: m.weighted_open_base > 0 ? ceilDay(m.weighted_open_doc_sum / m.weighted_open_base) : 0,
|
||||
ortalama_vade_gun: m.weighted_all_base > 0 ? ceilDay(m.weighted_all_gun_sum / m.weighted_all_base) : 0,
|
||||
ortalama_belge_gun: m.weighted_all_base > 0 ? ceilDay(m.weighted_all_doc_sum / m.weighted_all_base) : 0
|
||||
}))
|
||||
.sort((a, b) => String(a.cari8).localeCompare(String(b.cari8), 'tr', { sensitivity: 'base' }))
|
||||
|
||||
const currencyByMaster = {}
|
||||
for (const c of Object.values(currencyMap)) {
|
||||
const row = {
|
||||
...c,
|
||||
ort_gun: c.weighted_open_base > 0 ? ceilDay(c.weighted_open_gun_sum / c.weighted_open_base) : 0,
|
||||
ort_belge_gun: c.weighted_open_base > 0 ? ceilDay(c.weighted_open_doc_sum / c.weighted_open_base) : 0
|
||||
}
|
||||
if (!currencyByMaster[row.master_key]) currencyByMaster[row.master_key] = []
|
||||
currencyByMaster[row.master_key].push(row)
|
||||
}
|
||||
|
||||
for (const key of Object.keys(currencyByMaster)) {
|
||||
currencyByMaster[key].sort((a, b) => String(a.doviz_cinsi).localeCompare(String(b.doviz_cinsi), 'en', { sensitivity: 'base' }))
|
||||
}
|
||||
|
||||
this.currencyRowsByMaster = currencyByMaster
|
||||
for (const key of Object.keys(detailMap)) {
|
||||
detailMap[key].sort((a, b) => {
|
||||
const aEmpty = !a?.odeme_tarihi
|
||||
const bEmpty = !b?.odeme_tarihi
|
||||
if (aEmpty && !bEmpty) return -1
|
||||
if (!aEmpty && bEmpty) return 1
|
||||
if (aEmpty && bEmpty) return 0
|
||||
const aTs = Date.parse(a.odeme_tarihi)
|
||||
const bTs = Date.parse(b.odeme_tarihi)
|
||||
const aNum = Number.isFinite(aTs) ? aTs : -Infinity
|
||||
const bNum = Number.isFinite(bTs) ? bTs : -Infinity
|
||||
return bNum - aNum
|
||||
})
|
||||
}
|
||||
this.detailByCurrency = detailMap
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.rows = []
|
||||
this.masterRows = []
|
||||
this.currencyRowsByMaster = {}
|
||||
this.detailByCurrency = {}
|
||||
this.loading = false
|
||||
},
|
||||
|
||||
getCurrenciesByMaster(masterKey) {
|
||||
return this.currencyRowsByMaster[String(masterKey || '').trim()] || []
|
||||
},
|
||||
|
||||
getDetailsByCurrency(currencyKey) {
|
||||
return this.detailByCurrency[String(currencyKey || '').trim()] || []
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function normalizeRowKeys(row) {
|
||||
if (!row || typeof row !== 'object') return {}
|
||||
return {
|
||||
cari8: row.Cari8 ?? row.cari8 ?? null,
|
||||
cari_detay: row.CariDetay ?? row.cari_detay ?? null,
|
||||
fatura_cari: row.FaturaCari ?? row.fatura_cari ?? null,
|
||||
odeme_cari: row.OdemeCari ?? row.odeme_cari ?? null,
|
||||
fatura_ref: row.FaturaRef ?? row.fatura_ref ?? null,
|
||||
odeme_ref: row.OdemeRef ?? row.odeme_ref ?? null,
|
||||
fatura_tarihi: row.FaturaTarihi ?? row.fatura_tarihi ?? null,
|
||||
odeme_tarihi: row.OdemeTarihi ?? row.odeme_tarihi ?? null,
|
||||
odeme_doc_date: row.OdemeDocDate ?? row.odeme_doc_date ?? null,
|
||||
eslesen_tutar: Number(row.EslesenTutar ?? row.eslesen_tutar ?? 0),
|
||||
usd_tutar: Number(row.UsdTutar ?? row.usd_tutar ?? 0),
|
||||
try_tutar: Number(row.TryTutar ?? row.try_tutar ?? 0),
|
||||
gun_sayisi: Number(row.GunSayisi ?? row.gun_sayisi ?? 0),
|
||||
gun_sayisi_docdate: Number(row.GunSayisi_DocDate ?? row.gun_sayisi_docdate ?? 0),
|
||||
gun_kur: Number(row.GunKur ?? row.gun_kur ?? 0),
|
||||
aciklama: row.Aciklama ?? row.aciklama ?? null,
|
||||
doc_currency_code: row.DocCurrencyCode ?? row.doc_currency_code ?? null
|
||||
}
|
||||
}
|
||||
|
||||
function ceilDay(value) {
|
||||
const n = Number(value)
|
||||
if (!Number.isFinite(n)) return 0
|
||||
return Math.ceil(n)
|
||||
}
|
||||
Reference in New Issue
Block a user