Fix product performance grouped JSON build

This commit is contained in:
M_Kececi
2026-08-18 19:44:36 +03:00
parent 89df3d2d3d
commit 7b8f8905e5
9 changed files with 283 additions and 66 deletions
+2
View File
@@ -3,6 +3,8 @@ bssapp
# Env
.env
.env.local
.env.argebaggi.local
mail.env
# Runtime fonts
+39
View File
@@ -14,6 +14,7 @@ import (
var MssqlDB *sql.DB
var UretimDB *sql.DB
var ArgeBaggiDB *sql.DB
func envInt(name string, fallback int) int {
raw := strings.TrimSpace(os.Getenv(name))
@@ -158,3 +159,41 @@ func ConnectMSSQLUretim() error {
func GetUretimDB() *sql.DB {
return UretimDB
}
// ConnectMSSQLArgeBaggi initializes the optional ArgeBAGGI connection.
// Credentials must be supplied through ARGEBAGGI_MSSQL_CONN; never keep them
// in source control.
func ConnectMSSQLArgeBaggi() error {
connString := strings.TrimSpace(os.Getenv("ARGEBAGGI_MSSQL_CONN"))
if connString == "" {
return fmt.Errorf("ARGEBAGGI_MSSQL_CONN tanimli degil")
}
connectionTimeoutSec := envInt("ARGEBAGGI_MSSQL_CONNECTION_TIMEOUT_SEC", 10)
dialTimeoutSec := envInt("ARGEBAGGI_MSSQL_DIAL_TIMEOUT_SEC", connectionTimeoutSec)
connString = ensureMSSQLTimeouts(connString, connectionTimeoutSec, dialTimeoutSec)
var err error
ArgeBaggiDB, err = sql.Open("sqlserver", connString)
if err != nil {
return fmt.Errorf("ArgeBAGGI MSSQL baglanti hatasi: %w", err)
}
ArgeBaggiDB.SetMaxOpenConns(envInt("ARGEBAGGI_MSSQL_MAX_OPEN_CONNS", 10))
ArgeBaggiDB.SetMaxIdleConns(envInt("ARGEBAGGI_MSSQL_MAX_IDLE_CONNS", 5))
ArgeBaggiDB.SetConnMaxLifetime(time.Duration(envInt("ARGEBAGGI_MSSQL_CONN_MAX_LIFETIME_MIN", 30)) * time.Minute)
ArgeBaggiDB.SetConnMaxIdleTime(time.Duration(envInt("ARGEBAGGI_MSSQL_CONN_MAX_IDLE_MIN", 10)) * time.Minute)
if err = ArgeBaggiDB.Ping(); err != nil {
_ = ArgeBaggiDB.Close()
ArgeBaggiDB = nil
return fmt.Errorf("ArgeBAGGI MSSQL erisilemiyor: %w", err)
}
fmt.Printf("ArgeBAGGI MSSQL baglantisi basarili (connection timeout=%ds, dial timeout=%ds)\n", connectionTimeoutSec, dialTimeoutSec)
return nil
}
func GetArgeBaggiDB() *sql.DB {
return ArgeBaggiDB
}
+10
View File
@@ -1390,6 +1390,7 @@ func main() {
// (e.g. SSH-tunnel PostgreSQL on 127.0.0.1:15432).
if runtime.GOOS == "windows" {
_ = godotenv.Overload(".env.local")
_ = godotenv.Overload(".env.argebaggi.local")
}
jwtSecret := os.Getenv("JWT_SECRET")
@@ -1417,6 +1418,15 @@ func main() {
log.Fatal(err)
}
}
if err := db.ConnectMSSQLArgeBaggi(); err != nil {
if strings.Contains(err.Error(), "ARGEBAGGI_MSSQL_CONN tanimli degil") {
log.Println("ArgeBAGGI DB baglantisi atlandi: ARGEBAGGI_MSSQL_CONN tanimli degil")
} else {
// This source enriches one screen; a temporary outage must not stop
// the whole application from starting.
log.Println("ArgeBAGGI DB baglantisi basarisiz:", err)
}
}
pgDB, err := db.ConnectPostgres()
if err != nil {
+7
View File
@@ -12,11 +12,18 @@ type ProductionNoCostProductRow struct {
SKullaniciAdi string `json:"sKullaniciAdi"`
SKullaniciGunc string `json:"sKullaniciAdiGunc"`
MMiktarG float64 `json:"lMMiktar_G"`
CeketDepoGiris float64 `json:"ceketDepoGiris"`
PantolonDepoGiris float64 `json:"pantolonDepoGiris"`
YelekDepoGiris float64 `json:"yelekDepoGiris"`
MModelKodu string `json:"sMModelKodu"`
}
type ProductionHasCostProductRow struct {
UretimSekli string `json:"UretimSekli"`
UrtSiparisNo string `json:"nUrtSiparisNo"`
CeketDepoGiris float64 `json:"ceketDepoGiris"`
PantolonDepoGiris float64 `json:"pantolonDepoGiris"`
YelekDepoGiris float64 `json:"yelekDepoGiris"`
NOnMLNo string `json:"nOnMLNo"`
UrunKodu string `json:"UrunKodu"`
UrunAdi string `json:"UrunAdi"`
+92 -5
View File
@@ -793,6 +793,82 @@ ORDER BY SonIsEmri.dteIslemTarihi DESC, LTRIM(RTRIM(R.sMModelKodu)) ASC
return uretimDB.QueryContext(ctx, sqlText, fromDate, search)
}
type ArgeBaggiDepotEntryTotals struct {
Ceket float64
Pantolon float64
Yelek float64
}
// GetArgeBaggiDepotEntryTotals returns operation 985/986/987 quantities keyed
// by production work order. The requested work orders are queried in one batch
// to avoid an ArgeBAGGI round trip for every list row.
func GetArgeBaggiDepotEntryTotals(ctx context.Context, argeDB *sql.DB, workOrders []string) (map[string]ArgeBaggiDepotEntryTotals, error) {
out := make(map[string]ArgeBaggiDepotEntryTotals)
if argeDB == nil || len(workOrders) == 0 {
return out, nil
}
seen := make(map[string]struct{}, len(workOrders))
values := make([]string, 0, len(workOrders))
for _, raw := range workOrders {
value := strings.TrimSpace(raw)
if value == "" || value == "0" {
continue
}
if _, exists := seen[value]; exists {
continue
}
seen[value] = struct{}{}
values = append(values, value)
}
if len(values) == 0 {
return out, nil
}
placeholders := make([]string, 0, len(values))
args := make([]any, 0, len(values))
for i, value := range values {
placeholders = append(placeholders, fmt.Sprintf("@p%d", i+1))
args = append(args, value)
}
sqlText := fmt.Sprintf(`
SELECT
LTRIM(RTRIM(CONVERT(VARCHAR(64), MN.model_adi))) AS IsEmriNo,
SUM(CASE WHEN O.oper_num = 985 THEN CONVERT(float, B.adet) ELSE 0 END) AS CeketDepoGiris,
SUM(CASE WHEN O.oper_num = 986 THEN CONVERT(float, B.adet) ELSE 0 END) AS PantolonDepoGiris,
SUM(CASE WHEN O.oper_num = 987 THEN CONVERT(float, B.adet) ELSE 0 END) AS YelekDepoGiris
FROM dbo.is_acma_bar B
INNER JOIN dbo.is_acma I ON I.is_num = B.is_num
INNER JOIN dbo.model_def MD ON I.imdef_num = MD.mdef_num
INNER JOIN dbo.oper_urun_no O ON B.oper_num = O.oper_num
INNER JOIN dbo.model_num MN ON I.model_num = MN.model_num
INNER JOIN dbo.bant_no BN ON I.bant_num = BN.bant_no
INNER JOIN dbo.model_oper MO ON O.oper_num = MO.oper_num AND MD.mdef_num = MO.model_num
INNER JOIN dbo.model_oper_tkp_def TD ON MO.tkp_cik = TD.tkp_cik
WHERE B.tarih >= '2025-01-01'
AND TD.tkp_cik IN (1,2,3,4,5)
AND O.oper_num IN (985,986,987)
AND LTRIM(RTRIM(CONVERT(VARCHAR(64), MN.model_adi))) IN (%s)
GROUP BY LTRIM(RTRIM(CONVERT(VARCHAR(64), MN.model_adi)))
`, strings.Join(placeholders, ","))
rows, err := argeDB.QueryContext(ctx, sqlText, args...)
if err != nil {
return nil, err
}
defer rows.Close()
for rows.Next() {
var workOrder string
var totals ArgeBaggiDepotEntryTotals
if err := rows.Scan(&workOrder, &totals.Ceket, &totals.Pantolon, &totals.Yelek); err != nil {
return nil, err
}
out[strings.TrimSpace(workOrder)] = totals
}
return out, rows.Err()
}
func GetProductionHasCostProducts(
ctx context.Context,
uretimDB *sql.DB,
@@ -816,12 +892,22 @@ WITH SonOnMaliyet AS (
FROM dbo.spUrtOnMLMas M
WHERE LTRIM(RTRIM(M.UrunKodu)) <> ''
),
SonSiparis AS (
SonSiparisSirali AS (
SELECT
LTRIM(RTRIM(sMModelKodu)) AS UrunKodu,
MAX(dteIslemTarihi) AS SonSiparisTarihi
FROM dbo.spUrtSiparisDet
GROUP BY LTRIM(RTRIM(sMModelKodu))
LTRIM(RTRIM(SD.sMModelKodu)) AS UrunKodu,
SD.dteIslemTarihi AS SonSiparisTarihi,
SM.nUrtSiparisNo,
ROW_NUMBER() OVER (
PARTITION BY LTRIM(RTRIM(SD.sMModelKodu))
ORDER BY SD.dteIslemTarihi DESC, SD.nUrtSiparisID DESC
) AS rn
FROM dbo.spUrtSiparisDet SD
INNER JOIN dbo.spUrtSiparis SM ON SM.nUrtSiparisID = SD.nUrtSiparisID
),
SonSiparis AS (
SELECT UrunKodu, SonSiparisTarihi, nUrtSiparisNo
FROM SonSiparisSirali
WHERE rn = 1
)
SELECT
CASE
@@ -831,6 +917,7 @@ SELECT
THEN N'FASON ICIN URETILEN'
ELSE N'Tanimsiz'
END AS UretimSekli,
RTRIM(CONVERT(VARCHAR(32), ISNULL(SS.nUrtSiparisNo, 0))) AS nUrtSiparisNo,
RTRIM(CONVERT(VARCHAR(32), ISNULL(OM.nOnMLNo, 0))) AS nOnMLNo,
LTRIM(RTRIM(ISNULL(OM.UrunKodu, ''))) AS UrunKodu,
ISNULL(OM.UrunAdi, '') AS UrunAdi,
+41
View File
@@ -158,6 +158,26 @@ func GetProductionNoCostProductsHandler(w http.ResponseWriter, r *http.Request)
return
}
if argeDB := db.GetArgeBaggiDB(); argeDB != nil && len(list) > 0 {
workOrders := make([]string, 0, len(list))
for i := range list {
workOrders = append(workOrders, list[i].UrtSiparisNo)
}
argeCtx, cancelArge := context.WithTimeout(r.Context(), 15*time.Second)
totalsByWorkOrder, argeErr := queries.GetArgeBaggiDepotEntryTotals(argeCtx, argeDB, workOrders)
cancelArge()
if argeErr != nil {
log.Printf("[ProductionNoCost] ArgeBAGGI enrichment error: %v", argeErr)
} else {
for i := range list {
totals := totalsByWorkOrder[strings.TrimSpace(list[i].UrtSiparisNo)]
list[i].CeketDepoGiris = totals.Ceket
list[i].PantolonDepoGiris = totals.Pantolon
list[i].YelekDepoGiris = totals.Yelek
}
}
}
_ = json.NewEncoder(w).Encode(list)
}
@@ -191,6 +211,7 @@ func GetProductionHasCostProductsHandler(w http.ResponseWriter, r *http.Request)
var item models.ProductionHasCostProductRow
if err := rows.Scan(
&item.UretimSekli,
&item.UrtSiparisNo,
&item.NOnMLNo,
&item.UrunKodu,
&item.UrunAdi,
@@ -219,6 +240,26 @@ func GetProductionHasCostProductsHandler(w http.ResponseWriter, r *http.Request)
return
}
if argeDB := db.GetArgeBaggiDB(); argeDB != nil && len(list) > 0 {
workOrders := make([]string, 0, len(list))
for i := range list {
workOrders = append(workOrders, list[i].UrtSiparisNo)
}
argeCtx, cancelArge := context.WithTimeout(r.Context(), 15*time.Second)
totalsByWorkOrder, argeErr := queries.GetArgeBaggiDepotEntryTotals(argeCtx, argeDB, workOrders)
cancelArge()
if argeErr != nil {
log.Printf("[ProductionHasCost] ArgeBAGGI enrichment error: %v", argeErr)
} else {
for i := range list {
totals := totalsByWorkOrder[strings.TrimSpace(list[i].UrtSiparisNo)]
list[i].CeketDepoGiris = totals.Ceket
list[i].PantolonDepoGiris = totals.Pantolon
list[i].YelekDepoGiris = totals.Yelek
}
}
}
_ = json.NewEncoder(w).Encode(list)
}
@@ -176,6 +176,10 @@ const dateColumns = new Set(['Tarihi', 'dteKayitTarihi', 'dteGuncellemeTarihi',
const columns = [
{ name: 'open', label: '', field: 'open', align: 'center', sortable: false, style: 'width:3%', headerStyle: 'width:3%' },
{ name: 'UretimSekli', label: 'Uretim Sekli', field: 'UretimSekli', align: 'left', sortable: true, style: 'width:9%', headerStyle: 'width:9%' },
{ name: 'nUrtSiparisNo', label: 'Uretim Siparis No', field: 'nUrtSiparisNo', align: 'left', sortable: true, style: 'width:6%', headerStyle: 'width:6%' },
{ name: 'ceketDepoGiris', label: 'C-Ceket Depo Giris', field: 'ceketDepoGiris', align: 'right', sortable: true, format: val => formatMoney(val), style: 'width:6%', headerStyle: 'width:6%' },
{ name: 'pantolonDepoGiris', label: 'P-Pantolon Depo Giris', field: 'pantolonDepoGiris', align: 'right', sortable: true, format: val => formatMoney(val), style: 'width:6%', headerStyle: 'width:6%' },
{ name: 'yelekDepoGiris', label: 'Y-Yelek Depo Giris', field: 'yelekDepoGiris', align: 'right', sortable: true, format: val => formatMoney(val), style: 'width:6%', headerStyle: 'width:6%' },
{ name: 'nOnMLNo', label: 'nOnMLNo', field: 'nOnMLNo', align: 'left', sortable: true, style: 'width:6%', headerStyle: 'width:6%' },
{ name: 'UrunKodu', label: 'UrunKodu', field: 'UrunKodu', align: 'left', sortable: true, style: 'width:7%', headerStyle: 'width:7%' },
{ name: 'UrunAdi', label: 'UrunAdi', field: 'UrunAdi', align: 'left', sortable: true, style: 'width:8%', headerStyle: 'width:8%' },
@@ -389,7 +393,7 @@ function escapeExcelCsvCell (value) {
return `"${text.replace(/"/g, '""')}"`
}
const excelNumericColumns = new Set(['lTutarTL', 'lTutarUSD', 'lTutarEURO'])
const excelNumericColumns = new Set(['ceketDepoGiris', 'pantolonDepoGiris', 'yelekDepoGiris', 'lTutarTL', 'lTutarUSD', 'lTutarEURO'])
function formatExcelCsvCell (col, rawValue, displayValue) {
if (excelNumericColumns.has(col?.name)) {
@@ -5622,48 +5622,20 @@ watch(
}
.pcd-detail-table :deep(.q-table__middle) {
overflow-x: hidden !important;
width: 100% !important;
max-width: 100% !important;
overflow: visible !important;
}
.pcd-detail-table :deep(.q-table) {
table-layout: fixed !important;
width: 100% !important;
min-width: 0 !important;
table-layout: fixed;
width: 100%;
}
.pcd-detail-table :deep(.q-table th),
.pcd-detail-table :deep(.q-table td) {
overflow: hidden;
text-overflow: ellipsis;
min-width: 0 !important;
}
/* Fit every detail column into one desktop viewport. These percentages also
override the old pixel widths carried by a few editable columns. */
.pcd-detail-table :deep(.q-table th:nth-child(1)), .pcd-detail-table :deep(.q-table td:nth-child(1)) { width: 3.5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(2)), .pcd-detail-table :deep(.q-table td:nth-child(2)) { width: 3% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(3)), .pcd-detail-table :deep(.q-table td:nth-child(3)) { width: 5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(4)), .pcd-detail-table :deep(.q-table td:nth-child(4)) { width: 7% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(5)), .pcd-detail-table :deep(.q-table td:nth-child(5)) { width: 6% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(6)), .pcd-detail-table :deep(.q-table td:nth-child(6)) { width: 8% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(7)), .pcd-detail-table :deep(.q-table td:nth-child(7)) { width: 4.5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(8)), .pcd-detail-table :deep(.q-table td:nth-child(8)) { width: 4.5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(9)), .pcd-detail-table :deep(.q-table td:nth-child(9)) { width: 5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(10)), .pcd-detail-table :deep(.q-table td:nth-child(10)) { width: 4% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(11)), .pcd-detail-table :deep(.q-table td:nth-child(11)) { width: 3.5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(12)), .pcd-detail-table :deep(.q-table td:nth-child(12)) { width: 3% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(13)), .pcd-detail-table :deep(.q-table td:nth-child(13)) { width: 5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(14)), .pcd-detail-table :deep(.q-table td:nth-child(14)) { width: 5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(15)), .pcd-detail-table :deep(.q-table td:nth-child(15)) { width: 4% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(16)), .pcd-detail-table :deep(.q-table td:nth-child(16)) { width: 3.5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(17)), .pcd-detail-table :deep(.q-table td:nth-child(17)) { width: 4.5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(18)), .pcd-detail-table :deep(.q-table td:nth-child(18)) { width: 5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(19)), .pcd-detail-table :deep(.q-table td:nth-child(19)) { width: 4.5% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(20)), .pcd-detail-table :deep(.q-table td:nth-child(20)) { width: 6% !important; }
.pcd-detail-table :deep(.q-table th:nth-child(21)), .pcd-detail-table :deep(.q-table td:nth-child(21)) { width: 3% !important; }
.pcd-detail-table :deep(.q-table tbody td) {
white-space: normal;
word-break: break-word;
@@ -5682,8 +5654,8 @@ watch(
}
.pcd-detail-table :deep(.q-table thead th) {
font-size: 9px;
padding: 2px 2px;
font-size: 11px;
padding: 3px 4px;
white-space: normal;
line-height: 1.2;
vertical-align: bottom;
@@ -5691,8 +5663,8 @@ watch(
}
.pcd-detail-table :deep(.q-table tbody td) {
font-size: 9.5px;
padding: 1px 2px;
font-size: 11px;
padding: 2px 4px;
}
.pcd-detail-table :deep(.q-table tbody tr) {
@@ -5748,15 +5720,6 @@ watch(
.pcd-detail-table :deep(.pcd-inline-input .q-field__control) {
min-height: 30px;
min-width: 0 !important;
width: 100% !important;
}
.pcd-detail-table :deep(.pcd-inline-input),
.pcd-detail-table :deep(.pcd-inline-input .q-field__inner),
.pcd-detail-table :deep(.pcd-inline-input .q-field__control-container) {
min-width: 0 !important;
width: 100% !important;
}
.pcd-detail-table :deep(.pcd-inline-input .q-field__native),
@@ -5798,12 +5761,69 @@ watch(
}
.pcd-history-table :deep(.q-table thead th) {
font-size: 12px;
font-size: 9.5px;
line-height: 1.1;
white-space: normal;
padding: 3px 2px;
}
.pcd-history-table :deep(.q-table tbody td) {
font-size: 12px;
font-size: 9.5px;
vertical-align: top;
padding: 2px;
white-space: normal;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-word;
}
.pcd-history-table :deep(.q-table__middle) {
width: 100%;
max-width: 100%;
overflow-x: hidden;
}
.pcd-history-table :deep(.q-table) {
table-layout: fixed;
width: 100%;
min-width: 0;
}
.pcd-history-table :deep(.q-table th),
.pcd-history-table :deep(.q-table td) {
min-width: 0 !important;
}
.pcd-history-table :deep(.q-table th:nth-child(1)), .pcd-history-table :deep(.q-table td:nth-child(1)) { width: 5% !important; }
.pcd-history-table :deep(.q-table th:nth-child(2)), .pcd-history-table :deep(.q-table td:nth-child(2)) { width: 6% !important; }
.pcd-history-table :deep(.q-table th:nth-child(3)), .pcd-history-table :deep(.q-table td:nth-child(3)) { width: 7% !important; }
.pcd-history-table :deep(.q-table th:nth-child(4)), .pcd-history-table :deep(.q-table td:nth-child(4)) { width: 6% !important; }
.pcd-history-table :deep(.q-table th:nth-child(5)), .pcd-history-table :deep(.q-table td:nth-child(5)) { width: 8% !important; }
.pcd-history-table :deep(.q-table th:nth-child(6)), .pcd-history-table :deep(.q-table td:nth-child(6)) { width: 7% !important; }
.pcd-history-table :deep(.q-table th:nth-child(7)), .pcd-history-table :deep(.q-table td:nth-child(7)) { width: 10% !important; }
.pcd-history-table :deep(.q-table th:nth-child(8)), .pcd-history-table :deep(.q-table td:nth-child(8)) { width: 5% !important; }
.pcd-history-table :deep(.q-table th:nth-child(9)), .pcd-history-table :deep(.q-table td:nth-child(9)) { width: 7% !important; }
.pcd-history-table :deep(.q-table th:nth-child(10)), .pcd-history-table :deep(.q-table td:nth-child(10)) { width: 5% !important; }
.pcd-history-table :deep(.q-table th:nth-child(11)), .pcd-history-table :deep(.q-table td:nth-child(11)) { width: 7% !important; }
.pcd-history-table :deep(.q-table th:nth-child(12)), .pcd-history-table :deep(.q-table td:nth-child(12)) { width: 5% !important; }
.pcd-history-table :deep(.q-table th:nth-child(13)), .pcd-history-table :deep(.q-table td:nth-child(13)) { width: 3% !important; }
.pcd-history-table :deep(.q-table th:nth-child(14)), .pcd-history-table :deep(.q-table td:nth-child(14)) { width: 5% !important; }
.pcd-history-table :deep(.q-table th:nth-child(15)), .pcd-history-table :deep(.q-table td:nth-child(15)) { width: 6% !important; }
.pcd-history-table :deep(.q-table th:nth-child(16)), .pcd-history-table :deep(.q-table td:nth-child(16)) { width: 4% !important; }
.pcd-history-table :deep(.q-table th:nth-child(17)), .pcd-history-table :deep(.q-table td:nth-child(17)) { width: 4% !important; }
.pcd-history-table :deep(.pcd-history-source-chip) {
min-width: 0;
max-width: 100%;
padding: 2px 4px;
font-size: 9px;
}
.pcd-history-table :deep(.q-btn) {
min-width: 0;
padding-left: 5px;
padding-right: 5px;
font-size: 9px;
}
.pcd-history-table :deep(.pcd-history-row-purchase td) {
@@ -252,6 +252,9 @@ const columns = [
style: 'width:7%',
headerStyle: 'width:7%'
},
{ name: 'ceketDepoGiris', label: 'C-Ceket Depo Giris', field: 'ceketDepoGiris', align: 'right', sortable: true, format: val => formatQuantity(val), style: 'width:7%', headerStyle: 'width:7%' },
{ name: 'pantolonDepoGiris', label: 'P-Pantolon Depo Giris', field: 'pantolonDepoGiris', align: 'right', sortable: true, format: val => formatQuantity(val), style: 'width:7%', headerStyle: 'width:7%' },
{ name: 'yelekDepoGiris', label: 'Y-Yelek Depo Giris', field: 'yelekDepoGiris', align: 'right', sortable: true, format: val => formatQuantity(val), style: 'width:7%', headerStyle: 'width:7%' },
{
name: 'sMModelKodu',
label: 'Model Kodu',
@@ -312,7 +315,11 @@ function getColumnFilter (name) {
}
function isNumericColumn (name) {
return name === 'lMMiktar_G'
return ['lMMiktar_G', 'ceketDepoGiris', 'pantolonDepoGiris', 'yelekDepoGiris'].includes(name)
}
function formatQuantity (value) {
return Number(value || 0).toLocaleString('tr-TR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })
}
function parseNumberFilter (value) {
@@ -477,7 +484,7 @@ function escapeExcelCsvCell (value) {
}
function formatExcelCsvCell (col, rawValue, displayValue) {
if (col?.name === 'lMMiktar_G') {
if (isNumericColumn(col?.name)) {
const numericValue = Number(rawValue)
if (Number.isFinite(numericValue)) return String(numericValue).replace('.', ',')
}