Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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",
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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,
|
||||||
)
|
)
|
||||||
|
|||||||
302
svc/routes/statement_aging_screen_pdf.go
Normal file
302
svc/routes/statement_aging_screen_pdf.go
Normal 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
|
||||||
|
}
|
||||||
@@ -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">Açık Kalem</div>
|
<div class="cgh-cell cgh-num">Açı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>
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user