Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-03-06 13:59:17 +03:00
parent 46f4d15ac7
commit 807bbad0e7
6 changed files with 340 additions and 64 deletions

View File

@@ -453,6 +453,11 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router
"finance", "export", "finance", "export",
wrapV3(routes.ExportStatementAgingPDFHandler(mssql)), wrapV3(routes.ExportStatementAgingPDFHandler(mssql)),
) )
bindV3(r, pgDB,
"/api/finance/account-aging-statement/export-screen-pdf", "GET",
"finance", "export",
wrapV3(routes.ExportStatementAgingScreenPDFHandler(mssql)),
)
bindV3(r, pgDB, bindV3(r, pgDB,
"/api/finance/account-aging-statement/export-excel", "GET", "/api/finance/account-aging-statement/export-excel", "GET",
"finance", "export", "finance", "export",

View File

@@ -85,6 +85,7 @@ func ExportCustomerBalancePDFHandler(_ *sql.DB) http.HandlerFunc {
selectedDate, selectedDate,
params.CariSearch, params.CariSearch,
detailed, detailed,
"Cari Bakiye Listesi",
summaries, summaries,
detailsByMaster, detailsByMaster,
) )
@@ -233,6 +234,7 @@ func drawCustomerBalancePDF(
selectedDate string, selectedDate string,
searchText string, searchText string,
detailed bool, detailed bool,
reportTitle string,
summaries []balanceSummaryPDF, summaries []balanceSummaryPDF,
detailsByMaster map[string][]models.CustomerBalanceListRow, detailsByMaster map[string][]models.CustomerBalanceListRow,
) { ) {
@@ -251,7 +253,11 @@ func drawCustomerBalancePDF(
pdf.SetFont("dejavu", "B", 15) pdf.SetFont("dejavu", "B", 15)
pdf.SetTextColor(149, 113, 22) pdf.SetTextColor(149, 113, 22)
pdf.SetXY(marginL, marginT) pdf.SetXY(marginL, marginT)
pdf.CellFormat(120, 7, "Cari Bakiye Listesi", "", 0, "L", false, 0, "") title := strings.TrimSpace(reportTitle)
if title == "" {
title = "Cari Bakiye Listesi"
}
pdf.CellFormat(120, 7, title, "", 0, "L", false, 0, "")
pdf.SetFont("dejavu", "", 9) pdf.SetFont("dejavu", "", 9)
pdf.SetTextColor(20, 20, 20) pdf.SetTextColor(20, 20, 20)

View File

@@ -77,6 +77,7 @@ func ExportStatementAgingPDFHandler(_ *sql.DB) http.HandlerFunc {
selectedDate, selectedDate,
params.CariSearch, params.CariSearch,
detailed, detailed,
"Cari Yaslandirmali Ekstre",
summaries, summaries,
detailsByMaster, detailsByMaster,
) )

View File

@@ -0,0 +1,302 @@
package routes
import (
"bssapp-backend/auth"
"bssapp-backend/models"
"bssapp-backend/queries"
"bytes"
"database/sql"
"fmt"
"net/http"
"strconv"
"strings"
"time"
"github.com/jung-kurt/gofpdf"
)
type agingScreenPDFRow struct {
Cari8 string
CariDetay string
FaturaCari string
OdemeCari string
FaturaRef string
OdemeRef string
FaturaTarihi string
OdemeTarihi string
OdemeDocDate string
EslesenTutar float64
UsdTutar float64
CurrencyTryRate float64
GunSayisi float64
GunSayisiDocDate float64
Aciklama string
DocCurrencyCode string
}
func ExportStatementAgingScreenPDFHandler(_ *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
claims, ok := auth.GetClaimsFromContext(r.Context())
if !ok || claims == nil {
http.Error(w, "unauthorized", http.StatusUnauthorized)
return
}
selectedDate := strings.TrimSpace(r.URL.Query().Get("enddate"))
if selectedDate == "" {
selectedDate = strings.TrimSpace(r.URL.Query().Get("selected_date"))
}
if selectedDate == "" {
selectedDate = time.Now().Format("2006-01-02")
}
params := models.StatementAgingParams{
AccountCode: strings.TrimSpace(r.URL.Query().Get("accountcode")),
EndDate: selectedDate,
Parislemler: r.URL.Query()["parislemler"],
}
if err := queries.RebuildStatementAgingCache(r.Context()); err != nil {
http.Error(w, "Error rebuilding aging cache: "+err.Error(), http.StatusInternalServerError)
return
}
rawRows, err := queries.GetStatementAging(params)
if err != nil {
http.Error(w, "Error fetching aging statement: "+err.Error(), http.StatusInternalServerError)
return
}
rows := make([]agingScreenPDFRow, 0, len(rawRows))
for _, r := range rawRows {
rows = append(rows, agingScreenPDFRow{
Cari8: pickString(r, "Cari8", "cari8"),
CariDetay: pickString(r, "CariDetay", "cari_detay"),
FaturaCari: pickString(r, "FaturaCari", "fatura_cari"),
OdemeCari: pickString(r, "OdemeCari", "odeme_cari"),
FaturaRef: pickString(r, "FaturaRef", "fatura_ref"),
OdemeRef: pickString(r, "OdemeRef", "odeme_ref"),
FaturaTarihi: pickString(r, "FaturaTarihi", "fatura_tarihi"),
OdemeTarihi: pickString(r, "OdemeTarihi", "odeme_tarihi"),
OdemeDocDate: pickString(r, "OdemeDocDate", "odeme_doc_date"),
EslesenTutar: pickFloat(r, "EslesenTutar", "eslesen_tutar"),
UsdTutar: pickFloat(r, "UsdTutar", "usd_tutar"),
CurrencyTryRate: pickFloat(r, "CurrencyTryRate", "currency_try_rate"),
GunSayisi: pickFloat(r, "GunSayisi", "gun_sayisi"),
GunSayisiDocDate: pickFloat(r, "GunSayisi_DocDate", "gun_sayisi_docdate"),
Aciklama: pickString(r, "Aciklama", "aciklama"),
DocCurrencyCode: pickString(r, "DocCurrencyCode", "doc_currency_code"),
})
}
pdf := gofpdf.New("L", "mm", "A3", "")
pdf.SetMargins(8, 8, 8)
pdf.SetAutoPageBreak(false, 10)
if err := registerDejavuFonts(pdf, "dejavu"); err != nil {
http.Error(w, "pdf font error: "+err.Error(), http.StatusInternalServerError)
return
}
drawStatementAgingScreenPDF(pdf, selectedDate, params.AccountCode, rows)
if err := pdf.Error(); err != nil {
http.Error(w, "pdf render error: "+err.Error(), http.StatusInternalServerError)
return
}
var buf bytes.Buffer
if err := pdf.Output(&buf); err != nil {
http.Error(w, "pdf output error: "+err.Error(), http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/pdf")
w.Header().Set("Content-Disposition", `inline; filename="account-aging-screen.pdf"`)
_, _ = w.Write(buf.Bytes())
}
}
func drawStatementAgingScreenPDF(pdf *gofpdf.Fpdf, selectedDate, accountCode string, rows []agingScreenPDFRow) {
pageW, _ := pdf.GetPageSize()
marginL, marginT, marginR, marginB := 8.0, 8.0, 8.0, 10.0
tableW := pageW - marginL - marginR
cols := []string{
"Ana Cari", "Ana Cari Detay", "Fatura Cari", "Odeme Cari", "Fatura Ref", "Odeme Ref",
"Fatura Tarihi", "Odeme Vade", "Odeme DocDate", "Eslesen Tutar", "USD Tutar", "Kur",
"Gun", "Gun (DocDate)", "Aciklama", "Doviz",
}
widths := normalizeWidths([]float64{
18, 34, 18, 18, 22, 22,
16, 16, 18, 19, 16, 12,
10, 13, 28, 11,
}, tableW)
header := func() {
pdf.AddPage()
pdf.SetFont("dejavu", "B", 14)
pdf.SetTextColor(149, 113, 22)
pdf.SetXY(marginL, marginT)
pdf.CellFormat(150, 6, "Cari Yaslandirmali Ekstre", "", 0, "L", false, 0, "")
pdf.SetFont("dejavu", "", 8.5)
pdf.SetTextColor(30, 30, 30)
pdf.SetXY(pageW-marginR-90, marginT+0.5)
pdf.CellFormat(90, 4.8, "Son Tarih: "+selectedDate, "", 0, "R", false, 0, "")
if strings.TrimSpace(accountCode) != "" {
pdf.SetXY(pageW-marginR-90, marginT+5)
pdf.CellFormat(90, 4.8, "Cari: "+accountCode, "", 0, "R", false, 0, "")
}
pdf.SetDrawColor(149, 113, 22)
pdf.Line(marginL, marginT+10.5, pageW-marginR, marginT+10.5)
pdf.SetDrawColor(200, 200, 200)
pdf.SetY(marginT + 13)
pdf.SetFont("dejavu", "B", 7.2)
pdf.SetTextColor(255, 255, 255)
pdf.SetFillColor(149, 113, 22)
y := pdf.GetY()
x := marginL
for i, c := range cols {
pdf.Rect(x, y, widths[i], 6.2, "DF")
pdf.SetXY(x+0.8, y+1)
pdf.CellFormat(widths[i]-1.6, 4.2, c, "", 0, "C", false, 0, "")
x += widths[i]
}
pdf.SetY(y + 6.2)
}
needPage := func(needH float64) bool {
return pdf.GetY()+needH+marginB > 297.0
}
header()
pdf.SetFont("dejavu", "", 6.8)
pdf.SetTextColor(25, 25, 25)
for _, r := range rows {
if needPage(5.5) {
header()
pdf.SetFont("dejavu", "", 6.8)
pdf.SetTextColor(25, 25, 25)
}
line := []string{
r.Cari8,
r.CariDetay,
r.FaturaCari,
r.OdemeCari,
r.FaturaRef,
r.OdemeRef,
r.FaturaTarihi,
r.OdemeTarihi,
r.OdemeDocDate,
formatMoneyPDF(r.EslesenTutar),
formatMoneyPDF(r.UsdTutar),
formatMoneyPDF(r.CurrencyTryRate),
fmt.Sprintf("%.0f", r.GunSayisi),
fmt.Sprintf("%.0f", r.GunSayisiDocDate),
r.Aciklama,
r.DocCurrencyCode,
}
y := pdf.GetY()
x := marginL
for i, v := range line {
pdf.Rect(x, y, widths[i], 5.5, "")
align := "L"
if i >= 9 && i <= 11 {
align = "R"
}
if i == 12 || i == 13 {
align = "C"
}
pdf.SetXY(x+0.8, y+0.8)
pdf.CellFormat(widths[i]-1.6, 3.8, v, "", 0, align, false, 0, "")
x += widths[i]
}
pdf.SetY(y + 5.5)
}
}
func pickString(m map[string]interface{}, keys ...string) string {
for _, k := range keys {
if v, ok := m[k]; ok {
return strings.TrimSpace(toStringValue(v))
}
}
return ""
}
func pickFloat(m map[string]interface{}, keys ...string) float64 {
for _, k := range keys {
if v, ok := m[k]; ok {
return toFloat64Value(v)
}
}
return 0
}
func toStringValue(v interface{}) string {
switch x := v.(type) {
case nil:
return ""
case string:
return x
case []byte:
return string(x)
default:
return fmt.Sprint(x)
}
}
func toFloat64Value(v interface{}) float64 {
switch x := v.(type) {
case nil:
return 0
case float64:
return x
case float32:
return float64(x)
case int:
return float64(x)
case int64:
return float64(x)
case int32:
return float64(x)
case string:
return parseFloatValue(x)
case []byte:
return parseFloatValue(string(x))
default:
return parseFloatValue(fmt.Sprint(x))
}
}
func parseFloatValue(s string) float64 {
s = strings.TrimSpace(s)
if s == "" {
return 0
}
hasComma := strings.Contains(s, ",")
hasDot := strings.Contains(s, ".")
if hasComma && hasDot {
if strings.LastIndex(s, ",") > strings.LastIndex(s, ".") {
s = strings.ReplaceAll(s, ".", "")
s = strings.Replace(s, ",", ".", 1)
} else {
s = strings.ReplaceAll(s, ",", "")
}
} else if hasComma {
s = strings.ReplaceAll(s, ".", "")
s = strings.Replace(s, ",", ".", 1)
}
n, err := strconv.ParseFloat(s, 64)
if err != nil {
return 0
}
return n
}

View File

@@ -64,33 +64,13 @@
:label="filtersCollapsed ? 'Filtreleri Genişlet' : 'Filtreleri Daralt'" :label="filtersCollapsed ? 'Filtreleri Genişlet' : 'Filtreleri Daralt'"
@click="toggleFiltersCollapsed" @click="toggleFiltersCollapsed"
/> />
<q-btn-dropdown <q-btn
v-if="canExportFinance" v-if="canExportFinance"
flat flat
color="red" color="red"
icon="picture_as_pdf" icon="picture_as_pdf"
label="Yazdır" label="PDF Yazdır"
> @click="downloadAgingScreenPDF"
<q-list style="min-width: 240px">
<q-item clickable v-close-popup @click="downloadAgingBalancePDF(true)">
<q-item-section class="text-primary">
Detaylı Cari Yaşlandırmalı Bakiye Listesi Yazdır
</q-item-section>
</q-item>
<q-item clickable v-close-popup @click="downloadAgingBalancePDF(false)">
<q-item-section class="text-secondary">
Detaysız Cari Yaşlandırmalı Bakiye Listesi Yazdır
</q-item-section>
</q-item>
</q-list>
</q-btn-dropdown>
<q-btn
v-if="canExportFinance"
flat
color="green-8"
icon="table_view"
label="Excel"
@click="downloadAgingBalanceExcel"
/> />
<q-btn <q-btn
flat flat
@@ -155,6 +135,7 @@
<div class="cgh-cell cgh-num">Toplam USD</div> <div class="cgh-cell cgh-num">Toplam USD</div>
<div class="cgh-cell cgh-num">Normal</div> <div class="cgh-cell cgh-num">Normal</div>
<div class="cgh-cell cgh-num">ık Kalem</div> <div class="cgh-cell cgh-num">ık Kalem</div>
<div class="cgh-cell cgh-num">Kur</div>
<div class="cgh-cell cgh-center">Ort. Gün</div> <div class="cgh-cell cgh-center">Ort. Gün</div>
<div class="cgh-cell cgh-center">Ort. Gün (DocDate)</div> <div class="cgh-cell cgh-center">Ort. Gün (DocDate)</div>
</div> </div>
@@ -180,6 +161,7 @@
<div class="cgh-cell cgh-num">{{ formatAmount(currRow.toplam_usd) }}</div> <div class="cgh-cell cgh-num">{{ formatAmount(currRow.toplam_usd) }}</div>
<div class="cgh-cell cgh-num">{{ formatAmount(currRow.normal_tutar) }}</div> <div class="cgh-cell cgh-num">{{ formatAmount(currRow.normal_tutar) }}</div>
<div class="cgh-cell cgh-num">{{ formatAmount(currRow.acik_kalem_tutar) }}</div> <div class="cgh-cell cgh-num">{{ formatAmount(currRow.acik_kalem_tutar) }}</div>
<div class="cgh-cell cgh-num">{{ formatAmount(currRow.kur) }}</div>
<div class="cgh-cell cgh-center">{{ formatAmount(currRow.ortalama_gun, 0) }}</div> <div class="cgh-cell cgh-center">{{ formatAmount(currRow.ortalama_gun, 0) }}</div>
<div class="cgh-cell cgh-center">{{ formatAmount(currRow.ortalama_gun_docdate, 0) }}</div> <div class="cgh-cell cgh-center">{{ formatAmount(currRow.ortalama_gun_docdate, 0) }}</div>
</div> </div>
@@ -204,6 +186,9 @@
<template #body-cell-usd_tutar="d"> <template #body-cell-usd_tutar="d">
<q-td :props="d" class="text-right">{{ formatAmount(d.row.usd_tutar) }}</q-td> <q-td :props="d" class="text-right">{{ formatAmount(d.row.usd_tutar) }}</q-td>
</template> </template>
<template #body-cell-currency_try_rate="d">
<q-td :props="d" class="text-right">{{ formatAmount(d.row.currency_try_rate) }}</q-td>
</template>
<template #body-cell-gun_sayisi="d"> <template #body-cell-gun_sayisi="d">
<q-td :props="d" class="text-center">{{ formatAmount(d.row.gun_sayisi, 0) }}</q-td> <q-td :props="d" class="text-center">{{ formatAmount(d.row.gun_sayisi, 0) }}</q-td>
</template> </template>
@@ -267,7 +252,8 @@ const masterColumns = [
{ name: 'normal_usd', label: 'Normal USD', field: 'normal_usd', align: 'right', sortable: true }, { name: 'normal_usd', label: 'Normal USD', field: 'normal_usd', align: 'right', sortable: true },
{ name: 'acik_kalem_usd', label: 'Açık Kalem USD', field: 'acik_kalem_usd', align: 'right', sortable: true }, { name: 'acik_kalem_usd', label: 'Açık Kalem USD', field: 'acik_kalem_usd', align: 'right', sortable: true },
{ name: 'ortalama_gun', label: 'Ort. Gün', field: 'ortalama_gun', align: 'center', sortable: true }, { name: 'ortalama_gun', label: 'Ort. Gün', field: 'ortalama_gun', align: 'center', sortable: true },
{ name: 'ortalama_gun_docdate', label: 'Ort. Gün (DocDate)', field: 'ortalama_gun_docdate', align: 'center', sortable: true } { name: 'ortalama_gun_docdate', label: 'Ort. Gün (DocDate)', field: 'ortalama_gun_docdate', align: 'center', sortable: true },
{ name: 'kur', label: 'Kur', field: 'kur', align: 'right', sortable: true }
] ]
const detailColumns = [ const detailColumns = [
@@ -280,13 +266,14 @@ const detailColumns = [
{ name: 'odeme_doc_date', label: 'Ödeme DocDate', field: 'odeme_doc_date', align: 'left' }, { name: 'odeme_doc_date', label: 'Ödeme DocDate', field: 'odeme_doc_date', align: 'left' },
{ name: 'eslesen_tutar', label: 'Eşleşen Tutar', field: 'eslesen_tutar', align: 'right' }, { name: 'eslesen_tutar', label: 'Eşleşen Tutar', field: 'eslesen_tutar', align: 'right' },
{ name: 'usd_tutar', label: 'USD Tutar', field: 'usd_tutar', align: 'right' }, { name: 'usd_tutar', label: 'USD Tutar', field: 'usd_tutar', align: 'right' },
{ name: 'currency_try_rate', label: 'Kur', field: 'currency_try_rate', align: 'right' },
{ name: 'gun_sayisi', label: 'Gün', field: 'gun_sayisi', align: 'center' }, { name: 'gun_sayisi', label: 'Gün', field: 'gun_sayisi', align: 'center' },
{ name: 'gun_sayisi_docdate', label: 'Gün (DocDate)', field: 'gun_sayisi_docdate', align: 'center' }, { name: 'gun_sayisi_docdate', label: 'Gün (DocDate)', field: 'gun_sayisi_docdate', align: 'center' },
{ name: 'aciklama', label: 'Açıklama', field: 'aciklama', align: 'left' }, { name: 'aciklama', label: 'Açıklama', field: 'aciklama', align: 'left' },
{ name: 'doc_currency_code', label: 'Döviz', field: 'doc_currency_code', align: 'left' } { name: 'doc_currency_code', label: 'Döviz', field: 'doc_currency_code', align: 'left' }
] ]
const masterNumericCols = ['satir_sayisi', 'toplam_usd', 'normal_usd', 'acik_kalem_usd', 'ortalama_gun', 'ortalama_gun_docdate'] const masterNumericCols = ['satir_sayisi', 'toplam_usd', 'normal_usd', 'acik_kalem_usd', 'ortalama_gun', 'ortalama_gun_docdate', 'kur']
const masterCenteredCols = ['ortalama_gun', 'ortalama_gun_docdate'] const masterCenteredCols = ['ortalama_gun', 'ortalama_gun_docdate']
function normalizeText(str) { function normalizeText(str) {
@@ -401,20 +388,19 @@ function toggleFiltersCollapsed() {
filtersCollapsed.value = !filtersCollapsed.value filtersCollapsed.value = !filtersCollapsed.value
} }
function buildExportParams(detailed = false) { function buildExportParams() {
return { return {
accountcode: String(selectedCari.value || '').trim(), accountcode: String(selectedCari.value || '').trim(),
cari_search: String(selectedCari.value || '').trim(), cari_search: String(selectedCari.value || '').trim(),
enddate: dateTo.value, enddate: dateTo.value,
selected_date: dateTo.value, selected_date: dateTo.value,
parislemler: selectedMonType.value, parislemler: selectedMonType.value,
detailed: detailed ? '1' : '0',
exclude_zero_12: '0', exclude_zero_12: '0',
exclude_zero_13: '0' exclude_zero_13: '0'
} }
} }
async function downloadAgingBalancePDF(detailed) { async function downloadAgingScreenPDF() {
if (!canExportFinance.value) { if (!canExportFinance.value) {
$q.notify({ type: 'negative', message: 'PDF export yetkiniz yok', position: 'top-right' }) $q.notify({ type: 'negative', message: 'PDF export yetkiniz yok', position: 'top-right' })
return return
@@ -425,7 +411,7 @@ async function downloadAgingBalancePDF(detailed) {
} }
try { try {
const blob = await download('/finance/account-aging-statement/export-pdf', buildExportParams(detailed)) const blob = await download('/finance/account-aging-statement/export-screen-pdf', buildExportParams())
const pdfUrl = window.URL.createObjectURL(new Blob([blob], { type: 'application/pdf' })) const pdfUrl = window.URL.createObjectURL(new Blob([blob], { type: 'application/pdf' }))
window.open(pdfUrl, '_blank') window.open(pdfUrl, '_blank')
} catch (err) { } catch (err) {
@@ -438,37 +424,6 @@ async function downloadAgingBalancePDF(detailed) {
} }
} }
async function downloadAgingBalanceExcel() {
if (!canExportFinance.value) {
$q.notify({ type: 'negative', message: 'Excel export yetkiniz yok', position: 'top-right' })
return
}
if (!selectedCari.value || !dateTo.value) {
$q.notify({ type: 'warning', message: 'Önce cari ve son tarih seçiniz.', position: 'top-right' })
return
}
try {
const file = await download('/finance/account-aging-statement/export-excel', buildExportParams(false))
const blob = new Blob([file], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' })
const url = window.URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'cari_yaslandirmali_bakiye_listesi.xlsx'
document.body.appendChild(a)
a.click()
a.remove()
window.URL.revokeObjectURL(url)
} catch (err) {
const detail = await extractApiErrorDetail(err?.original || err)
$q.notify({
type: 'negative',
message: detail || 'Excel oluşturulamadı',
position: 'top-right'
})
}
}
function formatAmount(value, fraction = 2) { function formatAmount(value, fraction = 2) {
const n = Number(value || 0) const n = Number(value || 0)
return new Intl.NumberFormat('tr-TR', { return new Intl.NumberFormat('tr-TR', {
@@ -586,7 +541,7 @@ function formatAmount(value, fraction = 2) {
top: 36px; top: 36px;
z-index: 26; z-index: 26;
display: grid; display: grid;
grid-template-columns: 48px 100px 80px 1.2fr 1.2fr 1.1fr 1.1fr 110px 140px; grid-template-columns: 48px 100px 80px 1.2fr 1.2fr 1.1fr 1.1fr 100px 110px 140px;
align-items: center; align-items: center;
gap: 0; gap: 0;
background: var(--q-secondary); background: var(--q-secondary);
@@ -601,7 +556,7 @@ function formatAmount(value, fraction = 2) {
top: 72px; top: 72px;
z-index: 24; z-index: 24;
display: grid; display: grid;
grid-template-columns: 48px 100px 80px 1.2fr 1.2fr 1.1fr 1.1fr 110px 140px; grid-template-columns: 48px 100px 80px 1.2fr 1.2fr 1.1fr 1.1fr 100px 110px 140px;
align-items: center; align-items: center;
gap: 0; gap: 0;
background: #4c5f7a; background: #4c5f7a;
@@ -686,7 +641,7 @@ function formatAmount(value, fraction = 2) {
} }
.currency-group-header { .currency-group-header {
grid-template-columns: 44px 90px 70px 1.1fr 1.1fr 1fr 1fr 90px 120px; grid-template-columns: 44px 90px 70px 1.1fr 1.1fr 1fr 1fr 84px 90px 120px;
} }
} }
</style> </style>

View File

@@ -61,9 +61,11 @@ export const useStatementAgingStore = defineStore('statementAging', {
cari8: masterKey, cari8: masterKey,
cari_detay: String(row?.cari_detay || '').trim(), cari_detay: String(row?.cari_detay || '').trim(),
satir_sayisi: 0, satir_sayisi: 0,
toplam_tutar: 0,
toplam_usd: 0, toplam_usd: 0,
normal_usd: 0, normal_usd: 0,
acik_kalem_usd: 0, acik_kalem_usd: 0,
kur: 0,
weighted_gun_sum: 0, weighted_gun_sum: 0,
weighted_gun_doc_sum: 0, weighted_gun_doc_sum: 0,
weighted_base: 0, weighted_base: 0,
@@ -84,6 +86,7 @@ export const useStatementAgingStore = defineStore('statementAging', {
toplam_usd: 0, toplam_usd: 0,
normal_tutar: 0, normal_tutar: 0,
acik_kalem_tutar: 0, acik_kalem_tutar: 0,
kur: 0,
weighted_gun_sum: 0, weighted_gun_sum: 0,
weighted_gun_doc_sum: 0, weighted_gun_doc_sum: 0,
weighted_base: 0, weighted_base: 0,
@@ -96,6 +99,7 @@ export const useStatementAgingStore = defineStore('statementAging', {
const c = currencyMap[currencyKey] const c = currencyMap[currencyKey]
m.satir_sayisi += 1 m.satir_sayisi += 1
m.toplam_tutar += tutar
m.toplam_usd += usd m.toplam_usd += usd
if (aciklama === 'ACIKKALEM') { if (aciklama === 'ACIKKALEM') {
m.acik_kalem_usd += usd m.acik_kalem_usd += usd
@@ -129,6 +133,7 @@ export const useStatementAgingStore = defineStore('statementAging', {
this.masterRows = Object.values(masterMap) this.masterRows = Object.values(masterMap)
.map((m) => ({ .map((m) => ({
...m, ...m,
kur: Math.abs(m.toplam_usd) > 0 ? (m.toplam_tutar / m.toplam_usd) : 0,
ortalama_gun: m.weighted_base > 0 ? (m.weighted_gun_sum / m.weighted_base) : 0, ortalama_gun: m.weighted_base > 0 ? (m.weighted_gun_sum / m.weighted_base) : 0,
ortalama_gun_docdate: m.weighted_base > 0 ? (m.weighted_gun_doc_sum / m.weighted_base) : 0 ortalama_gun_docdate: m.weighted_base > 0 ? (m.weighted_gun_doc_sum / m.weighted_base) : 0
})) }))
@@ -138,6 +143,7 @@ export const useStatementAgingStore = defineStore('statementAging', {
for (const c of Object.values(currencyMap)) { for (const c of Object.values(currencyMap)) {
const row = { const row = {
...c, ...c,
kur: Math.abs(c.toplam_usd) > 0 ? (c.toplam_tutar / c.toplam_usd) : 0,
ortalama_gun: c.weighted_base > 0 ? (c.weighted_gun_sum / c.weighted_base) : 0, ortalama_gun: c.weighted_base > 0 ? (c.weighted_gun_sum / c.weighted_base) : 0,
ortalama_gun_docdate: c.weighted_base > 0 ? (c.weighted_gun_doc_sum / c.weighted_base) : 0 ortalama_gun_docdate: c.weighted_base > 0 ? (c.weighted_gun_doc_sum / c.weighted_base) : 0
} }
@@ -187,6 +193,7 @@ function normalizeRowKeys(row) {
usd_tutar: Number(row.UsdTutar ?? row.usd_tutar ?? 0), usd_tutar: Number(row.UsdTutar ?? row.usd_tutar ?? 0),
gun_sayisi: Number(row.GunSayisi ?? row.gun_sayisi ?? 0), gun_sayisi: Number(row.GunSayisi ?? row.gun_sayisi ?? 0),
gun_sayisi_docdate: Number(row.GunSayisi_DocDate ?? row.gun_sayisi_docdate ?? 0), gun_sayisi_docdate: Number(row.GunSayisi_DocDate ?? row.gun_sayisi_docdate ?? 0),
currency_try_rate: Number(row.CurrencyTryRate ?? row.currency_try_rate ?? 0),
aciklama: row.Aciklama ?? row.aciklama ?? null, aciklama: row.Aciklama ?? row.aciklama ?? null,
doc_currency_code: row.DocCurrencyCode ?? row.doc_currency_code ?? null doc_currency_code: row.DocCurrencyCode ?? row.doc_currency_code ?? null
} }