diff --git a/svc/main.go b/svc/main.go
index 558db79..3c4d306 100644
--- a/svc/main.go
+++ b/svc/main.go
@@ -508,6 +508,7 @@ func InitRoutes(pgDB *sql.DB, mssql *sql.DB, ml *mailer.GraphMailer) *mux.Router
{"/api/orders/close-ready", "GET", "update", routes.OrderCloseReadyListRoute(mssql)},
{"/api/orders/bulk-close", "POST", "update", routes.OrderBulkCloseRoute(mssql)},
{"/api/orders/export", "GET", "export", routes.OrderListExcelRoute(mssql)},
+ {"/api/orders/export-pdf", "GET", "export", routes.OrderListPDFRoute(mssql)},
{"/api/order/check/{id}", "GET", "view", routes.OrderExistsHandler(mssql)},
{"/api/order/validate", "POST", "insert", routes.ValidateOrderHandler(mssql)},
{"/api/order/pdf/{id}", "GET", "export", routes.OrderPDFHandler(mssql)},
diff --git a/svc/models/orderlist.go b/svc/models/orderlist.go
index 7e19fd5..6ded8da 100644
--- a/svc/models/orderlist.go
+++ b/svc/models/orderlist.go
@@ -9,6 +9,7 @@ type OrderList struct {
OrderHeaderID string `json:"OrderHeaderID"`
OrderNumber string `json:"OrderNumber"`
OrderDate string `json:"OrderDate"`
+ TerminTarihi string `json:"TerminTarihi"`
// 🧾 Cari Bilgileri
CurrAccCode string `json:"CurrAccCode"`
diff --git a/svc/queries/get_order_list_excel.go b/svc/queries/get_order_list_excel.go
index b66d4fa..285d2bb 100644
--- a/svc/queries/get_order_list_excel.go
+++ b/svc/queries/get_order_list_excel.go
@@ -17,6 +17,7 @@ SELECT
CAST(h.OrderHeaderID AS NVARCHAR(50)) AS OrderHeaderID,
ISNULL(h.OrderNumber,'') AS OrderNumber,
CONVERT(varchar,h.OrderDate,23) AS OrderDate,
+ CONVERT(varchar,h.AverageDueDate,23) AS TerminTarihi,
ISNULL(h.CurrAccCode,'') AS CurrAccCode,
ISNULL(ca.CurrAccDescription,'') AS CurrAccDescription,
@@ -73,6 +74,17 @@ SELECT
ELSE 0
END AS PackedRatePct,
+ CASE
+ WHEN EXISTS (
+ SELECT 1
+ FROM dbo.trOrderLine l2
+ WHERE l2.OrderHeaderID = h.OrderHeaderID
+ AND ISNULL(l2.ItemCode,'') LIKE 'U%%'
+ )
+ THEN CAST(1 AS bit)
+ ELSE CAST(0 AS bit)
+ END AS HasUretimUrunu,
+
ISNULL(h.Description,'') AS Description,
usd.Rate AS ExchangeRateUSD
diff --git a/svc/queries/orderlist.go b/svc/queries/orderlist.go
index b9af840..b6e27fb 100644
--- a/svc/queries/orderlist.go
+++ b/svc/queries/orderlist.go
@@ -57,6 +57,7 @@ SELECT
CAST(h.OrderHeaderID AS NVARCHAR(50)) AS OrderHeaderID,
ISNULL(h.OrderNumber, '') AS OrderNumber,
CONVERT(varchar, h.OrderDate, 23) AS OrderDate,
+ CONVERT(varchar, h.AverageDueDate, 23) AS TerminTarihi,
ISNULL(h.CurrAccCode, '') AS CurrAccCode,
ISNULL(ca.CurrAccDescription, '') AS CurrAccDescription,
diff --git a/svc/routes/order_list_excel.go b/svc/routes/order_list_excel.go
index e27abdf..99007c7 100644
--- a/svc/routes/order_list_excel.go
+++ b/svc/routes/order_list_excel.go
@@ -12,41 +12,29 @@ import (
func OrderListExcelRoute(db *sql.DB) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
-
w.Header().Set("Cache-Control", "no-store")
- // ======================
- // PARAMS
- // ======================
search := r.URL.Query().Get("search")
currAcc := r.URL.Query().Get("CurrAccCode")
orderDate := r.URL.Query().Get("OrderDate")
- // ======================
- // QUERY
- // ======================
rows, err := queries.GetOrderListExcel(db, search, currAcc, orderDate)
if err != nil {
- http.Error(w, err.Error(), 500)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
defer rows.Close()
- // ======================
- // EXCEL INIT
- // ======================
f := excelize.NewFile()
sheet := "Orders"
f.SetSheetName("Sheet1", sheet)
- // ======================
- // HEADERS
- // ======================
headers := []string{
- "Sipariş No",
+ "Siparis No",
"Tarih",
+ "Termin Tarihi",
"Cari Kod",
- "Cari Adı",
+ "Cari Adi",
"Temsilci",
"Piyasa",
"PB",
@@ -55,8 +43,9 @@ func OrderListExcelRoute(db *sql.DB) http.Handler {
"Paketlenen Tutar",
"Paketlenen (USD)",
"Paketlenme (%)",
+ "Uretim",
"USD Kur",
- "Açıklama",
+ "Aciklama",
}
for i, h := range headers {
@@ -64,58 +53,55 @@ func OrderListExcelRoute(db *sql.DB) http.Handler {
f.SetCellValue(sheet, cell, h)
}
- // ======================
- // ROWS
- // ======================
row := 2
-
for rows.Next() {
-
- // 🔴 15 KOLON = 15 DEĞİŞKEN
var (
- id, no, date, code, name string
- rep, piyasa, cur string
+ id, no, date, termin, code, name string
+ rep, piyasa, cur string
total float64
totalUSD float64
packedAmount float64
packedUSD float64
packedRatePct float64
+ hasUretim bool
+ desc string
usdRate float64
-
- desc string
)
- // 🔴 SELECT SIRASIYLA BİREBİR
err := rows.Scan(
&id, // 1
&no, // 2
&date, // 3
- &code, // 4
- &name, // 5
- &rep, // 6
- &piyasa, // 7
- &cur, // 8
- &total, // 9
- &totalUSD, // 10
- &packedAmount, // 11
- &packedUSD, // 12
- &packedRatePct, // 13
- &desc, // 14
- &usdRate, // 15
+ &termin, // 4
+ &code, // 5
+ &name, // 6
+ &rep, // 7
+ &piyasa, // 8
+ &cur, // 9
+ &total, // 10
+ &totalUSD, // 11
+ &packedAmount, // 12
+ &packedUSD, // 13
+ &packedRatePct, // 14
+ &hasUretim, // 15
+ &desc, // 16
+ &usdRate, // 17
)
-
if err != nil {
- http.Error(w, "Scan error: "+err.Error(), 500)
+ http.Error(w, "Scan error: "+err.Error(), http.StatusInternalServerError)
return
}
- // ======================
- // WRITE ROW
- // ======================
+ uretim := ""
+ if hasUretim {
+ uretim = "VAR"
+ }
+
f.SetSheetRow(sheet, fmt.Sprintf("A%d", row), &[]any{
no,
date,
+ termin,
code,
name,
rep,
@@ -126,6 +112,7 @@ func OrderListExcelRoute(db *sql.DB) http.Handler {
packedAmount,
packedUSD,
packedRatePct,
+ uretim,
usdRate,
desc,
})
@@ -133,38 +120,17 @@ func OrderListExcelRoute(db *sql.DB) http.Handler {
row++
}
- // ======================
- // BUFFER WRITE
- // ======================
buf, err := f.WriteToBuffer()
if err != nil {
- http.Error(w, err.Error(), 500)
+ http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
- filename := fmt.Sprintf(
- "siparis_listesi_%s.xlsx",
- time.Now().Format("20060102_150405"),
- )
-
- // ======================
- // RESPONSE
- // ======================
- w.Header().Set(
- "Content-Type",
- "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
- )
-
- w.Header().Set(
- "Content-Disposition",
- "attachment; filename=\""+filename+"\"",
- )
-
- w.Header().Set(
- "Content-Length",
- fmt.Sprint(len(buf.Bytes())),
- )
+ filename := fmt.Sprintf("siparis_listesi_%s.xlsx", time.Now().Format("20060102_150405"))
+ w.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
+ w.Header().Set("Content-Disposition", "attachment; filename=\""+filename+"\"")
+ w.Header().Set("Content-Length", fmt.Sprint(len(buf.Bytes())))
w.WriteHeader(http.StatusOK)
_, _ = w.Write(buf.Bytes())
})
diff --git a/svc/routes/order_list_pdf.go b/svc/routes/order_list_pdf.go
new file mode 100644
index 0000000..de45dd1
--- /dev/null
+++ b/svc/routes/order_list_pdf.go
@@ -0,0 +1,211 @@
+package routes
+
+import (
+ "bssapp-backend/queries"
+ "bytes"
+ "database/sql"
+ "fmt"
+ "net/http"
+ "strings"
+ "time"
+
+ "github.com/jung-kurt/gofpdf"
+)
+
+type orderListPDFRow struct {
+ OrderNumber string
+ OrderDate string
+ TerminTarihi string
+ CurrAccCode string
+ CurrAccDescription string
+ MusteriTemsilcisi string
+ Piyasa string
+ DocCurrencyCode string
+ TotalAmount float64
+ TotalAmountUSD float64
+ PackedUSD float64
+ PackedRatePct float64
+ HasUretimUrunu bool
+ Description string
+}
+
+func OrderListPDFRoute(db *sql.DB) http.Handler {
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ search := strings.TrimSpace(r.URL.Query().Get("search"))
+ currAcc := strings.TrimSpace(r.URL.Query().Get("CurrAccCode"))
+ orderDate := strings.TrimSpace(r.URL.Query().Get("OrderDate"))
+
+ rows, err := queries.GetOrderListExcel(db, search, currAcc, orderDate)
+ if err != nil {
+ http.Error(w, "db error: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+ defer rows.Close()
+
+ out := make([]orderListPDFRow, 0, 256)
+ for rows.Next() {
+ var (
+ id, no, date, termin, code, name string
+ rep, piyasa, cur string
+ total float64
+ totalUSD float64
+ packedAmount float64
+ packedUSD float64
+ packedRatePct float64
+ hasUretim bool
+ desc string
+ usdRate float64
+ )
+
+ if err := rows.Scan(
+ &id,
+ &no,
+ &date,
+ &termin,
+ &code,
+ &name,
+ &rep,
+ &piyasa,
+ &cur,
+ &total,
+ &totalUSD,
+ &packedAmount,
+ &packedUSD,
+ &packedRatePct,
+ &hasUretim,
+ &desc,
+ &usdRate,
+ ); err != nil {
+ http.Error(w, "scan error: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ _ = packedAmount
+ _ = usdRate
+
+ out = append(out, orderListPDFRow{
+ OrderNumber: no,
+ OrderDate: date,
+ TerminTarihi: termin,
+ CurrAccCode: code,
+ CurrAccDescription: name,
+ MusteriTemsilcisi: rep,
+ Piyasa: piyasa,
+ DocCurrencyCode: cur,
+ TotalAmount: total,
+ TotalAmountUSD: totalUSD,
+ PackedUSD: packedUSD,
+ PackedRatePct: packedRatePct,
+ HasUretimUrunu: hasUretim,
+ Description: desc,
+ })
+ }
+
+ pdf := gofpdf.New("L", "mm", "A4", "")
+ pdf.SetMargins(8, 8, 8)
+ pdf.SetAutoPageBreak(true, 10)
+ if err := registerDejavuFonts(pdf, "dejavu"); err != nil {
+ http.Error(w, "pdf font error: "+err.Error(), http.StatusInternalServerError)
+ return
+ }
+
+ drawOrderListPDF(pdf, out, search, currAcc, orderDate)
+ 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=\"siparis-listesi.pdf\"")
+ _, _ = w.Write(buf.Bytes())
+ })
+}
+
+func drawOrderListPDF(pdf *gofpdf.Fpdf, rows []orderListPDFRow, search, currAcc, orderDate string) {
+ headers := []string{
+ "Siparis No", "Tarih", "Termin", "Cari Kod", "Cari Adi", "Temsilci", "Piyasa",
+ "PB", "Tutar", "USD", "Paket USD", "%", "Uretim", "Aciklama",
+ }
+ widths := []float64{24, 14, 14, 18, 34, 16, 12, 8, 18, 18, 18, 10, 14, 43}
+
+ pdf.AddPage()
+ pdf.SetFont("dejavu", "B", 12)
+ pdf.CellFormat(0, 7, "Siparis Listesi", "", 1, "L", false, 0, "")
+
+ pdf.SetFont("dejavu", "", 8)
+ filterLine := fmt.Sprintf(
+ "Filtreler -> Arama: %s | Cari: %s | Siparis Tarihi: %s | Uretim: %s",
+ emptyDash(search), emptyDash(currAcc), emptyDash(orderDate), time.Now().Format("2006-01-02 15:04"),
+ )
+ pdf.CellFormat(0, 5, filterLine, "", 1, "L", false, 0, "")
+ pdf.Ln(1)
+
+ pdf.SetFont("dejavu", "B", 8)
+ pdf.SetFillColor(240, 240, 240)
+ for i, h := range headers {
+ pdf.CellFormat(widths[i], 6, h, "1", 0, "C", true, 0, "")
+ }
+ pdf.Ln(-1)
+
+ pdf.SetFont("dejavu", "", 7)
+ for _, row := range rows {
+ uretim := ""
+ if row.HasUretimUrunu {
+ uretim = "VAR"
+ }
+
+ cells := []string{
+ row.OrderNumber,
+ row.OrderDate,
+ row.TerminTarihi,
+ row.CurrAccCode,
+ shorten(row.CurrAccDescription, 24),
+ shorten(row.MusteriTemsilcisi, 12),
+ shorten(row.Piyasa, 10),
+ row.DocCurrencyCode,
+ fmt.Sprintf("%.2f", row.TotalAmount),
+ fmt.Sprintf("%.2f", row.TotalAmountUSD),
+ fmt.Sprintf("%.2f", row.PackedUSD),
+ fmt.Sprintf("%.2f", row.PackedRatePct),
+ uretim,
+ shorten(row.Description, 34),
+ }
+
+ for i, v := range cells {
+ align := "L"
+ if i >= 8 && i <= 11 {
+ align = "R"
+ }
+ if i == 1 || i == 2 || i == 7 || i == 12 {
+ align = "C"
+ }
+ pdf.CellFormat(widths[i], 5, v, "1", 0, align, false, 0, "")
+ }
+ pdf.Ln(-1)
+ }
+}
+
+func emptyDash(v string) string {
+ if strings.TrimSpace(v) == "" {
+ return "-"
+ }
+ return v
+}
+
+func shorten(v string, max int) string {
+ s := strings.TrimSpace(v)
+ if len([]rune(s)) <= max {
+ return s
+ }
+ r := []rune(s)
+ if max <= 1 {
+ return string(r[:1])
+ }
+ return string(r[:max-1]) + "…"
+}
diff --git a/svc/routes/orderlist.go b/svc/routes/orderlist.go
index bf74494..1c1dd21 100644
--- a/svc/routes/orderlist.go
+++ b/svc/routes/orderlist.go
@@ -68,27 +68,28 @@ func OrderListRoute(mssql *sql.DB) http.Handler {
&o.OrderHeaderID, // 1
&o.OrderNumber, // 2
&o.OrderDate, // 3
+ &o.TerminTarihi, // 4
- &o.CurrAccCode, // 4
- &o.CurrAccDescription, // 5
+ &o.CurrAccCode, // 5
+ &o.CurrAccDescription, // 6
- &o.MusteriTemsilcisi, // 6
- &o.Piyasa, // 7
+ &o.MusteriTemsilcisi, // 7
+ &o.Piyasa, // 8
- &o.CreditableConfirmedDate, // 8
- &o.DocCurrencyCode, // 9
+ &o.CreditableConfirmedDate, // 9
+ &o.DocCurrencyCode, // 10
- &o.TotalAmount, // 10
- &o.TotalAmountUSD, // 11
- &o.PackedAmount, // 12
- &o.PackedUSD, // 13
- &o.PackedRatePct, // 14
+ &o.TotalAmount, // 11
+ &o.TotalAmountUSD, // 12
+ &o.PackedAmount, // 13
+ &o.PackedUSD, // 14
+ &o.PackedRatePct, // 15
- &o.IsCreditableConfirmed, // 15
- &o.HasUretimUrunu, // 16
- &o.Description, // 17
+ &o.IsCreditableConfirmed, // 16
+ &o.HasUretimUrunu, // 17
+ &o.Description, // 18
- &o.ExchangeRateUSD, // 18
+ &o.ExchangeRateUSD, // 19
)
if err != nil {
diff --git a/ui/quasar.config.js.temporary.compiled.1772692887548.mjs b/ui/quasar.config.js.temporary.compiled.1772696562168.mjs
similarity index 100%
rename from ui/quasar.config.js.temporary.compiled.1772692887548.mjs
rename to ui/quasar.config.js.temporary.compiled.1772696562168.mjs
diff --git a/ui/src/pages/OrderList.vue b/ui/src/pages/OrderList.vue
index 21ab9b9..584bd11 100644
--- a/ui/src/pages/OrderList.vue
+++ b/ui/src/pages/OrderList.vue
@@ -62,6 +62,15 @@
:disable="store.loading || store.filteredOrders.length === 0"
@click="exportExcel"
/>
+
+