Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -6,6 +6,8 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"sort"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -29,11 +31,21 @@ type orderListPDFRow struct {
|
|||||||
Description string
|
Description string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type pdfColumn struct {
|
||||||
|
Header string
|
||||||
|
Width float64
|
||||||
|
Align string
|
||||||
|
Wrap bool
|
||||||
|
MaxLines int
|
||||||
|
}
|
||||||
|
|
||||||
func OrderListPDFRoute(db *sql.DB) http.Handler {
|
func OrderListPDFRoute(db *sql.DB) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
search := strings.TrimSpace(r.URL.Query().Get("search"))
|
search := strings.TrimSpace(r.URL.Query().Get("search"))
|
||||||
currAcc := strings.TrimSpace(r.URL.Query().Get("CurrAccCode"))
|
currAcc := strings.TrimSpace(r.URL.Query().Get("CurrAccCode"))
|
||||||
orderDate := strings.TrimSpace(r.URL.Query().Get("OrderDate"))
|
orderDate := strings.TrimSpace(r.URL.Query().Get("OrderDate"))
|
||||||
|
sortBy := strings.TrimSpace(r.URL.Query().Get("sort_by"))
|
||||||
|
descending := parseBool(r.URL.Query().Get("descending"))
|
||||||
|
|
||||||
rows, err := queries.GetOrderListExcel(db, search, currAcc, orderDate)
|
rows, err := queries.GetOrderListExcel(db, search, currAcc, orderDate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -58,28 +70,14 @@ func OrderListPDFRoute(db *sql.DB) http.Handler {
|
|||||||
)
|
)
|
||||||
|
|
||||||
if err := rows.Scan(
|
if err := rows.Scan(
|
||||||
&id,
|
&id, &no, &date, &termin, &code, &name, &rep, &piyasa, &cur,
|
||||||
&no,
|
&total, &totalUSD, &packedAmount, &packedUSD, &packedRatePct,
|
||||||
&date,
|
&hasUretim, &desc, &usdRate,
|
||||||
&termin,
|
|
||||||
&code,
|
|
||||||
&name,
|
|
||||||
&rep,
|
|
||||||
&piyasa,
|
|
||||||
&cur,
|
|
||||||
&total,
|
|
||||||
&totalUSD,
|
|
||||||
&packedAmount,
|
|
||||||
&packedUSD,
|
|
||||||
&packedRatePct,
|
|
||||||
&hasUretim,
|
|
||||||
&desc,
|
|
||||||
&usdRate,
|
|
||||||
); err != nil {
|
); err != nil {
|
||||||
http.Error(w, "scan error: "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "scan error: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
_ = id
|
||||||
_ = packedAmount
|
_ = packedAmount
|
||||||
_ = usdRate
|
_ = usdRate
|
||||||
|
|
||||||
@@ -101,15 +99,17 @@ func OrderListPDFRoute(db *sql.DB) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
applyOrderListSort(out, sortBy, descending)
|
||||||
|
|
||||||
pdf := gofpdf.New("L", "mm", "A4", "")
|
pdf := gofpdf.New("L", "mm", "A4", "")
|
||||||
pdf.SetMargins(8, 8, 8)
|
pdf.SetMargins(8, 8, 8)
|
||||||
pdf.SetAutoPageBreak(true, 10)
|
pdf.SetAutoPageBreak(false, 10)
|
||||||
if err := registerDejavuFonts(pdf, "dejavu"); err != nil {
|
if err := registerDejavuFonts(pdf, "dejavu"); err != nil {
|
||||||
http.Error(w, "pdf font error: "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "pdf font error: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
drawOrderListPDF(pdf, out, search, currAcc, orderDate)
|
drawOrderListPDF(pdf, out, search, currAcc, orderDate, sortBy, descending)
|
||||||
if err := pdf.Error(); err != nil {
|
if err := pdf.Error(); err != nil {
|
||||||
http.Error(w, "pdf render error: "+err.Error(), http.StatusInternalServerError)
|
http.Error(w, "pdf render error: "+err.Error(), http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
@@ -127,68 +127,234 @@ func OrderListPDFRoute(db *sql.DB) http.Handler {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func drawOrderListPDF(pdf *gofpdf.Fpdf, rows []orderListPDFRow, search, currAcc, orderDate string) {
|
func drawOrderListPDF(
|
||||||
headers := []string{
|
pdf *gofpdf.Fpdf,
|
||||||
"Siparis No", "Tarih", "Termin", "Cari Kod", "Cari Adi", "Temsilci", "Piyasa",
|
rows []orderListPDFRow,
|
||||||
"PB", "Tutar", "USD", "Paket USD", "%", "Uretim", "Aciklama",
|
search, currAcc, orderDate, sortBy string,
|
||||||
|
desc bool,
|
||||||
|
) {
|
||||||
|
cols := []pdfColumn{
|
||||||
|
{Header: "Siparis No", Width: 20, Align: "L", Wrap: false, MaxLines: 1},
|
||||||
|
{Header: "Tarih", Width: 12, Align: "C", Wrap: false, MaxLines: 1},
|
||||||
|
{Header: "Termin", Width: 12, Align: "C", Wrap: false, MaxLines: 1},
|
||||||
|
{Header: "Cari Kod", Width: 15, Align: "L", Wrap: true, MaxLines: 2},
|
||||||
|
{Header: "Cari Adi", Width: 27, Align: "L", Wrap: true, MaxLines: 3},
|
||||||
|
{Header: "Temsilci", Width: 18, Align: "L", Wrap: true, MaxLines: 2},
|
||||||
|
{Header: "Piyasa", Width: 13, Align: "L", Wrap: true, MaxLines: 2},
|
||||||
|
{Header: "PB", Width: 8, Align: "C", Wrap: false, MaxLines: 1},
|
||||||
|
{Header: "Tutar", Width: 15, Align: "R", Wrap: false, MaxLines: 1},
|
||||||
|
{Header: "USD", Width: 15, Align: "R", Wrap: false, MaxLines: 1},
|
||||||
|
{Header: "Paket USD", Width: 15, Align: "R", Wrap: false, MaxLines: 1},
|
||||||
|
{Header: "%", Width: 8, Align: "R", Wrap: false, MaxLines: 1},
|
||||||
|
{Header: "Uretim", Width: 24, Align: "L", Wrap: true, MaxLines: 3},
|
||||||
|
{Header: "Aciklama", Width: 52, Align: "L", Wrap: true, MaxLines: 3},
|
||||||
}
|
}
|
||||||
widths := []float64{24, 14, 14, 18, 34, 16, 12, 8, 18, 18, 18, 10, 14, 43}
|
|
||||||
|
|
||||||
|
pageW, pageH := pdf.GetPageSize()
|
||||||
|
marginL, marginT, marginR := 8.0, 8.0, 8.0
|
||||||
|
bottomLimit := pageH - 10.0
|
||||||
|
lineH := 3.8
|
||||||
|
cellPadX := 1.1
|
||||||
|
cellPadY := 0.6
|
||||||
|
|
||||||
|
drawHeader := func() {
|
||||||
pdf.AddPage()
|
pdf.AddPage()
|
||||||
pdf.SetFont("dejavu", "B", 12)
|
pdf.SetFont("dejavu", "B", 12)
|
||||||
pdf.CellFormat(0, 7, "Siparis Listesi", "", 1, "L", false, 0, "")
|
pdf.CellFormat(0, 7, "Siparis Listesi", "", 1, "L", false, 0, "")
|
||||||
|
|
||||||
pdf.SetFont("dejavu", "", 8)
|
pdf.SetFont("dejavu", "", 8)
|
||||||
|
sortText := "TotalAmountUSD DESC (varsayilan)"
|
||||||
|
if sortBy != "" {
|
||||||
|
dir := "ASC"
|
||||||
|
if desc {
|
||||||
|
dir = "DESC"
|
||||||
|
}
|
||||||
|
sortText = fmt.Sprintf("%s %s", sortBy, dir)
|
||||||
|
}
|
||||||
filterLine := fmt.Sprintf(
|
filterLine := fmt.Sprintf(
|
||||||
"Filtreler -> Arama: %s | Cari: %s | Siparis Tarihi: %s | Uretim: %s",
|
"Filtreler -> Arama: %s | Cari: %s | Siparis Tarihi: %s | Siralama: %s | Olusturma: %s",
|
||||||
emptyDash(search), emptyDash(currAcc), emptyDash(orderDate), time.Now().Format("2006-01-02 15:04"),
|
emptyDash(search),
|
||||||
|
emptyDash(currAcc),
|
||||||
|
emptyDash(orderDate),
|
||||||
|
sortText,
|
||||||
|
time.Now().Format("2006-01-02 15:04"),
|
||||||
)
|
)
|
||||||
pdf.CellFormat(0, 5, filterLine, "", 1, "L", false, 0, "")
|
pdf.CellFormat(0, 5, filterLine, "", 1, "L", false, 0, "")
|
||||||
pdf.Ln(1)
|
pdf.Ln(1)
|
||||||
|
|
||||||
pdf.SetFont("dejavu", "B", 8)
|
pdf.SetFont("dejavu", "B", 8)
|
||||||
pdf.SetFillColor(240, 240, 240)
|
pdf.SetFillColor(240, 240, 240)
|
||||||
for i, h := range headers {
|
for _, c := range cols {
|
||||||
pdf.CellFormat(widths[i], 6, h, "1", 0, "C", true, 0, "")
|
pdf.CellFormat(c.Width, 6, c.Header, "1", 0, "C", true, 0, "")
|
||||||
}
|
}
|
||||||
pdf.Ln(-1)
|
pdf.Ln(-1)
|
||||||
|
|
||||||
pdf.SetFont("dejavu", "", 7)
|
pdf.SetFont("dejavu", "", 7)
|
||||||
for _, row := range rows {
|
|
||||||
uretim := ""
|
|
||||||
if row.HasUretimUrunu {
|
|
||||||
uretim = "VAR"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cells := []string{
|
buildCells := func(row orderListPDFRow) []string {
|
||||||
|
uretim := ""
|
||||||
|
if row.HasUretimUrunu {
|
||||||
|
uretim = "Uretime Verilecek Urunu Var"
|
||||||
|
}
|
||||||
|
return []string{
|
||||||
row.OrderNumber,
|
row.OrderNumber,
|
||||||
row.OrderDate,
|
row.OrderDate,
|
||||||
row.TerminTarihi,
|
row.TerminTarihi,
|
||||||
row.CurrAccCode,
|
row.CurrAccCode,
|
||||||
shorten(row.CurrAccDescription, 24),
|
row.CurrAccDescription,
|
||||||
shorten(row.MusteriTemsilcisi, 12),
|
row.MusteriTemsilcisi,
|
||||||
shorten(row.Piyasa, 10),
|
row.Piyasa,
|
||||||
row.DocCurrencyCode,
|
row.DocCurrencyCode,
|
||||||
fmt.Sprintf("%.2f", row.TotalAmount),
|
fmt.Sprintf("%.2f", row.TotalAmount),
|
||||||
fmt.Sprintf("%.2f", row.TotalAmountUSD),
|
fmt.Sprintf("%.2f", row.TotalAmountUSD),
|
||||||
fmt.Sprintf("%.2f", row.PackedUSD),
|
fmt.Sprintf("%.2f", row.PackedUSD),
|
||||||
fmt.Sprintf("%.2f", row.PackedRatePct),
|
fmt.Sprintf("%.2f", row.PackedRatePct),
|
||||||
uretim,
|
uretim,
|
||||||
shorten(row.Description, 34),
|
row.Description,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, v := range cells {
|
calcLineCount := func(col pdfColumn, text string) int {
|
||||||
align := "L"
|
if !col.Wrap {
|
||||||
if i >= 8 && i <= 11 {
|
return 1
|
||||||
align = "R"
|
|
||||||
}
|
}
|
||||||
if i == 1 || i == 2 || i == 7 || i == 12 {
|
lines := pdf.SplitLines([]byte(strings.TrimSpace(text)), col.Width-(cellPadX*2))
|
||||||
align = "C"
|
n := len(lines)
|
||||||
|
if n < 1 {
|
||||||
|
n = 1
|
||||||
}
|
}
|
||||||
pdf.CellFormat(widths[i], 5, v, "1", 0, align, false, 0, "")
|
if col.MaxLines > 0 && n > col.MaxLines {
|
||||||
|
n = col.MaxLines
|
||||||
}
|
}
|
||||||
pdf.Ln(-1)
|
return n
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drawWrappedCell := func(x, y, w, h float64, text, align string, maxLines int) {
|
||||||
|
pdf.Rect(x, y, w, h, "D")
|
||||||
|
lines := pdf.SplitLines([]byte(strings.TrimSpace(text)), w-(cellPadX*2))
|
||||||
|
if len(lines) == 0 {
|
||||||
|
lines = [][]byte{[]byte("")}
|
||||||
|
}
|
||||||
|
if maxLines > 0 && len(lines) > maxLines {
|
||||||
|
lines = lines[:maxLines]
|
||||||
|
}
|
||||||
|
ty := y + cellPadY + 2.8
|
||||||
|
for _, ln := range lines {
|
||||||
|
pdf.SetXY(x+cellPadX, ty-2.8)
|
||||||
|
pdf.CellFormat(w-(cellPadX*2), 3.8, string(ln), "", 0, align, false, 0, "")
|
||||||
|
ty += 3.8
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
drawHeader()
|
||||||
|
|
||||||
|
for _, row := range rows {
|
||||||
|
cells := buildCells(row)
|
||||||
|
maxLines := 1
|
||||||
|
for i, c := range cols {
|
||||||
|
n := calcLineCount(c, cells[i])
|
||||||
|
if n > maxLines {
|
||||||
|
maxLines = n
|
||||||
|
}
|
||||||
|
}
|
||||||
|
rowH := (float64(maxLines) * lineH) + (cellPadY * 2)
|
||||||
|
|
||||||
|
if pdf.GetY()+rowH > bottomLimit {
|
||||||
|
drawHeader()
|
||||||
|
}
|
||||||
|
|
||||||
|
x := marginL
|
||||||
|
y := pdf.GetY()
|
||||||
|
for i, c := range cols {
|
||||||
|
if c.Wrap {
|
||||||
|
drawWrappedCell(x, y, c.Width, rowH, cells[i], c.Align, c.MaxLines)
|
||||||
|
} else {
|
||||||
|
pdf.SetXY(x, y)
|
||||||
|
pdf.CellFormat(c.Width, rowH, cells[i], "1", 0, c.Align, false, 0, "")
|
||||||
|
}
|
||||||
|
x += c.Width
|
||||||
|
}
|
||||||
|
pdf.SetXY(marginL, y+rowH)
|
||||||
|
}
|
||||||
|
|
||||||
|
_ = pageW
|
||||||
|
_ = marginT
|
||||||
|
_ = marginR
|
||||||
|
}
|
||||||
|
|
||||||
|
func applyOrderListSort(rows []orderListPDFRow, sortBy string, desc bool) {
|
||||||
|
if len(rows) <= 1 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
field := strings.TrimSpace(sortBy)
|
||||||
|
if field == "" {
|
||||||
|
field = "TotalAmountUSD"
|
||||||
|
desc = true
|
||||||
|
}
|
||||||
|
|
||||||
|
lessText := func(a, b string) bool {
|
||||||
|
aa := strings.ToLower(strings.TrimSpace(a))
|
||||||
|
bb := strings.ToLower(strings.TrimSpace(b))
|
||||||
|
if desc {
|
||||||
|
return aa > bb
|
||||||
|
}
|
||||||
|
return aa < bb
|
||||||
|
}
|
||||||
|
lessNum := func(a, b float64) bool {
|
||||||
|
if desc {
|
||||||
|
return a > b
|
||||||
|
}
|
||||||
|
return a < b
|
||||||
|
}
|
||||||
|
lessBool := func(a, b bool) bool {
|
||||||
|
av, bv := 0, 0
|
||||||
|
if a {
|
||||||
|
av = 1
|
||||||
|
}
|
||||||
|
if b {
|
||||||
|
bv = 1
|
||||||
|
}
|
||||||
|
if desc {
|
||||||
|
return av > bv
|
||||||
|
}
|
||||||
|
return av < bv
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.SliceStable(rows, func(i, j int) bool {
|
||||||
|
a := rows[i]
|
||||||
|
b := rows[j]
|
||||||
|
switch field {
|
||||||
|
case "OrderNumber":
|
||||||
|
return lessText(a.OrderNumber, b.OrderNumber)
|
||||||
|
case "OrderDate":
|
||||||
|
return lessText(a.OrderDate, b.OrderDate)
|
||||||
|
case "TerminTarihi":
|
||||||
|
return lessText(a.TerminTarihi, b.TerminTarihi)
|
||||||
|
case "CurrAccCode":
|
||||||
|
return lessText(a.CurrAccCode, b.CurrAccCode)
|
||||||
|
case "CurrAccDescription":
|
||||||
|
return lessText(a.CurrAccDescription, b.CurrAccDescription)
|
||||||
|
case "MusteriTemsilcisi":
|
||||||
|
return lessText(a.MusteriTemsilcisi, b.MusteriTemsilcisi)
|
||||||
|
case "Piyasa":
|
||||||
|
return lessText(a.Piyasa, b.Piyasa)
|
||||||
|
case "DocCurrencyCode":
|
||||||
|
return lessText(a.DocCurrencyCode, b.DocCurrencyCode)
|
||||||
|
case "TotalAmount":
|
||||||
|
return lessNum(a.TotalAmount, b.TotalAmount)
|
||||||
|
case "PackedUSD":
|
||||||
|
return lessNum(a.PackedUSD, b.PackedUSD)
|
||||||
|
case "PackedRatePct":
|
||||||
|
return lessNum(a.PackedRatePct, b.PackedRatePct)
|
||||||
|
case "HasUretimUrunu":
|
||||||
|
return lessBool(a.HasUretimUrunu, b.HasUretimUrunu)
|
||||||
|
case "Description":
|
||||||
|
return lessText(a.Description, b.Description)
|
||||||
|
default:
|
||||||
|
return lessNum(a.TotalAmountUSD, b.TotalAmountUSD)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func emptyDash(v string) string {
|
func emptyDash(v string) string {
|
||||||
@@ -198,14 +364,15 @@ func emptyDash(v string) string {
|
|||||||
return v
|
return v
|
||||||
}
|
}
|
||||||
|
|
||||||
func shorten(v string, max int) string {
|
func parseBool(v string) bool {
|
||||||
s := strings.TrimSpace(v)
|
b, err := strconv.ParseBool(strings.TrimSpace(v))
|
||||||
if len([]rune(s)) <= max {
|
if err == nil {
|
||||||
return s
|
return b
|
||||||
}
|
}
|
||||||
r := []rune(s)
|
switch strings.TrimSpace(strings.ToLower(v)) {
|
||||||
if max <= 1 {
|
case "1", "yes", "on":
|
||||||
return string(r[:1])
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
return string(r[:max-1]) + "…"
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,6 +109,7 @@
|
|||||||
:loading="store.loading"
|
:loading="store.loading"
|
||||||
no-data-label="Sipariş bulunamadı"
|
no-data-label="Sipariş bulunamadı"
|
||||||
:rows-per-page-options="[0]"
|
:rows-per-page-options="[0]"
|
||||||
|
v-model:pagination="pagination"
|
||||||
hide-bottom
|
hide-bottom
|
||||||
>
|
>
|
||||||
<template #body-cell-IsCreditableConfirmed="props">
|
<template #body-cell-IsCreditableConfirmed="props">
|
||||||
@@ -252,7 +253,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { onMounted, watch } from 'vue'
|
import { onMounted, ref, watch } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { useQuasar } from 'quasar'
|
import { useQuasar } from 'quasar'
|
||||||
import { useOrderListStore } from 'src/stores/OrdernewListStore'
|
import { useOrderListStore } from 'src/stores/OrdernewListStore'
|
||||||
@@ -266,6 +267,11 @@ const canReadOrder = canRead('order')
|
|||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const $q = useQuasar()
|
const $q = useQuasar()
|
||||||
const store = useOrderListStore()
|
const store = useOrderListStore()
|
||||||
|
const pagination = ref({
|
||||||
|
sortBy: 'TotalAmountUSD',
|
||||||
|
descending: true,
|
||||||
|
rowsPerPage: 0
|
||||||
|
})
|
||||||
|
|
||||||
let searchTimer = null
|
let searchTimer = null
|
||||||
watch(
|
watch(
|
||||||
@@ -320,7 +326,9 @@ async function exportListPdf () {
|
|||||||
const blob = await download('/orders/export-pdf', {
|
const blob = await download('/orders/export-pdf', {
|
||||||
search: store.filters.search || '',
|
search: store.filters.search || '',
|
||||||
CurrAccCode: store.filters.CurrAccCode || '',
|
CurrAccCode: store.filters.CurrAccCode || '',
|
||||||
OrderDate: store.filters.OrderDate || ''
|
OrderDate: store.filters.OrderDate || '',
|
||||||
|
sort_by: pagination.value?.sortBy || 'TotalAmountUSD',
|
||||||
|
descending: String(pagination.value?.descending ?? true)
|
||||||
})
|
})
|
||||||
|
|
||||||
const blobUrl = URL.createObjectURL(blob)
|
const blobUrl = URL.createObjectURL(blob)
|
||||||
|
|||||||
Reference in New Issue
Block a user