From 7b8f8905e5499f3f5e290fd793d811e2947f0c2b Mon Sep 17 00:00:00 2001 From: M_Kececi Date: Tue, 18 Aug 2026 19:44:26 +0300 Subject: [PATCH] Fix product performance grouped JSON build --- svc/.gitignore | 2 + svc/db/mssql.go | 39 ++++++ svc/main.go | 10 ++ svc/models/production_product_costing.go | 31 +++-- svc/queries/production_product_costing.go | 97 ++++++++++++++- svc/routes/production_product_costing.go | 41 +++++++ .../pages/ProductionProductCostingHasCost.vue | 6 +- .../ProductionProductCostingHasCostDetail.vue | 112 +++++++++++------- .../pages/ProductionProductCostingNoCost.vue | 11 +- 9 files changed, 283 insertions(+), 66 deletions(-) diff --git a/svc/.gitignore b/svc/.gitignore index e73754f..f6fd5f6 100644 --- a/svc/.gitignore +++ b/svc/.gitignore @@ -3,6 +3,8 @@ bssapp # Env .env +.env.local +.env.argebaggi.local mail.env # Runtime fonts diff --git a/svc/db/mssql.go b/svc/db/mssql.go index 494b208..efc1d02 100644 --- a/svc/db/mssql.go +++ b/svc/db/mssql.go @@ -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 +} diff --git a/svc/main.go b/svc/main.go index 246b119..fff5352 100644 --- a/svc/main.go +++ b/svc/main.go @@ -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 { diff --git a/svc/models/production_product_costing.go b/svc/models/production_product_costing.go index a691294..6935adf 100644 --- a/svc/models/production_product_costing.go +++ b/svc/models/production_product_costing.go @@ -1,22 +1,29 @@ package models type ProductionNoCostProductRow struct { - UretimSekli string `json:"UretimSekli"` - UrtSiparisNo string `json:"nUrtSiparisNo"` - IslemTarihi string `json:"dteIslemTarihi"` - FirmaKodu string `json:"FirmaKodu"` - FirmaAdi string `json:"FirmaAdi"` - SonIsEmriVeren string `json:"SonIsEmriVeren"` - ModelAdi string `json:"sAdi"` - Kodu string `json:"sKodu"` - SKullaniciAdi string `json:"sKullaniciAdi"` - SKullaniciGunc string `json:"sKullaniciAdiGunc"` - MMiktarG float64 `json:"lMMiktar_G"` - MModelKodu string `json:"sMModelKodu"` + UretimSekli string `json:"UretimSekli"` + UrtSiparisNo string `json:"nUrtSiparisNo"` + IslemTarihi string `json:"dteIslemTarihi"` + FirmaKodu string `json:"FirmaKodu"` + FirmaAdi string `json:"FirmaAdi"` + SonIsEmriVeren string `json:"SonIsEmriVeren"` + ModelAdi string `json:"sAdi"` + Kodu string `json:"sKodu"` + 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"` diff --git a/svc/queries/production_product_costing.go b/svc/queries/production_product_costing.go index c56d3d9..9864f3b 100644 --- a/svc/queries/production_product_costing.go +++ b/svc/queries/production_product_costing.go @@ -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, diff --git a/svc/routes/production_product_costing.go b/svc/routes/production_product_costing.go index 1626b87..4000c04 100644 --- a/svc/routes/production_product_costing.go +++ b/svc/routes/production_product_costing.go @@ -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) } diff --git a/ui/src/pages/ProductionProductCostingHasCost.vue b/ui/src/pages/ProductionProductCostingHasCost.vue index b8afefd..9bc92a4 100644 --- a/ui/src/pages/ProductionProductCostingHasCost.vue +++ b/ui/src/pages/ProductionProductCostingHasCost.vue @@ -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)) { diff --git a/ui/src/pages/ProductionProductCostingHasCostDetail.vue b/ui/src/pages/ProductionProductCostingHasCostDetail.vue index 9ce3d1d..5e54211 100644 --- a/ui/src/pages/ProductionProductCostingHasCostDetail.vue +++ b/ui/src/pages/ProductionProductCostingHasCostDetail.vue @@ -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) { diff --git a/ui/src/pages/ProductionProductCostingNoCost.vue b/ui/src/pages/ProductionProductCostingNoCost.vue index 85b94dd..aa2a983 100644 --- a/ui/src/pages/ProductionProductCostingNoCost.vue +++ b/ui/src/pages/ProductionProductCostingNoCost.vue @@ -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('.', ',') }