Fix product performance grouped JSON build
This commit is contained in:
@@ -799,42 +799,68 @@ type ArgeBaggiDepotEntryTotals struct {
|
|||||||
Yelek float64
|
Yelek float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ArgeBaggiDepotEntryLookup struct {
|
||||||
|
WorkOrder string
|
||||||
|
ModelCode string
|
||||||
|
}
|
||||||
|
|
||||||
|
func ArgeBaggiDepotEntryKey(workOrder string, modelCode string) string {
|
||||||
|
return strings.TrimSpace(workOrder) + "\x1f" + normalizeArgeBaggiModelCode(modelCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
func normalizeArgeBaggiModelCode(modelCode string) string {
|
||||||
|
normalizedModelCode := strings.ToUpper(strings.TrimSpace(modelCode))
|
||||||
|
if separatorIndex := strings.LastIndex(normalizedModelCode, "-"); separatorIndex >= 0 && separatorIndex+1 < len(normalizedModelCode) {
|
||||||
|
return strings.TrimSpace(normalizedModelCode[separatorIndex+1:])
|
||||||
|
}
|
||||||
|
return normalizedModelCode
|
||||||
|
}
|
||||||
|
|
||||||
// GetArgeBaggiDepotEntryTotals returns operation 985/986/987 quantities keyed
|
// GetArgeBaggiDepotEntryTotals returns operation 985/986/987 quantities keyed
|
||||||
// by production work order. The requested work orders are queried in one batch
|
// by production work order AND product model. A row contributes only when both
|
||||||
// to avoid an ArgeBAGGI round trip for every list row.
|
// MN.model_adi (work order) and MD.model_code (model) match the requested pair.
|
||||||
func GetArgeBaggiDepotEntryTotals(ctx context.Context, argeDB *sql.DB, workOrders []string) (map[string]ArgeBaggiDepotEntryTotals, error) {
|
func GetArgeBaggiDepotEntryTotals(ctx context.Context, argeDB *sql.DB, lookups []ArgeBaggiDepotEntryLookup) (map[string]ArgeBaggiDepotEntryTotals, error) {
|
||||||
out := make(map[string]ArgeBaggiDepotEntryTotals)
|
out := make(map[string]ArgeBaggiDepotEntryTotals)
|
||||||
if argeDB == nil || len(workOrders) == 0 {
|
if argeDB == nil || len(lookups) == 0 {
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
seen := make(map[string]struct{}, len(workOrders))
|
seen := make(map[string]struct{}, len(lookups))
|
||||||
values := make([]string, 0, len(workOrders))
|
values := make([]ArgeBaggiDepotEntryLookup, 0, len(lookups))
|
||||||
for _, raw := range workOrders {
|
for _, lookup := range lookups {
|
||||||
value := strings.TrimSpace(raw)
|
workOrder := strings.TrimSpace(lookup.WorkOrder)
|
||||||
if value == "" || value == "0" {
|
modelCode := normalizeArgeBaggiModelCode(lookup.ModelCode)
|
||||||
|
if workOrder == "" || workOrder == "0" || modelCode == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if _, exists := seen[value]; exists {
|
key := ArgeBaggiDepotEntryKey(workOrder, modelCode)
|
||||||
|
if _, exists := seen[key]; exists {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
seen[value] = struct{}{}
|
seen[key] = struct{}{}
|
||||||
values = append(values, value)
|
values = append(values, ArgeBaggiDepotEntryLookup{WorkOrder: workOrder, ModelCode: modelCode})
|
||||||
}
|
}
|
||||||
if len(values) == 0 {
|
if len(values) == 0 {
|
||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
placeholders := make([]string, 0, len(values))
|
valueRows := make([]string, 0, len(values))
|
||||||
args := make([]any, 0, len(values))
|
args := make([]any, 0, len(values)*2)
|
||||||
for i, value := range values {
|
for i, value := range values {
|
||||||
placeholders = append(placeholders, fmt.Sprintf("@p%d", i+1))
|
workOrderParam := i*2 + 1
|
||||||
args = append(args, value)
|
modelCodeParam := workOrderParam + 1
|
||||||
|
valueRows = append(valueRows, fmt.Sprintf("(@p%d, @p%d)", workOrderParam, modelCodeParam))
|
||||||
|
args = append(args, value.WorkOrder, value.ModelCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
sqlText := fmt.Sprintf(`
|
sqlText := fmt.Sprintf(`
|
||||||
|
WITH RequestedPairs (IsEmriNo, ModelKodu) AS (
|
||||||
|
SELECT V.IsEmriNo, V.ModelKodu
|
||||||
|
FROM (VALUES %s) V (IsEmriNo, ModelKodu)
|
||||||
|
)
|
||||||
SELECT
|
SELECT
|
||||||
LTRIM(RTRIM(CONVERT(VARCHAR(64), MN.model_adi))) AS IsEmriNo,
|
RP.IsEmriNo,
|
||||||
|
RP.ModelKodu,
|
||||||
SUM(CASE WHEN O.oper_num = 985 THEN CONVERT(float, B.adet) ELSE 0 END) AS CeketDepoGiris,
|
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 = 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
|
SUM(CASE WHEN O.oper_num = 987 THEN CONVERT(float, B.adet) ELSE 0 END) AS YelekDepoGiris
|
||||||
@@ -846,12 +872,14 @@ 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.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 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
|
INNER JOIN dbo.model_oper_tkp_def TD ON MO.tkp_cik = TD.tkp_cik
|
||||||
|
INNER JOIN RequestedPairs RP
|
||||||
|
ON RP.IsEmriNo = LTRIM(RTRIM(CONVERT(VARCHAR(64), MN.model_adi)))
|
||||||
|
AND RP.ModelKodu = UPPER(LTRIM(RTRIM(CONVERT(VARCHAR(64), MD.model_code))))
|
||||||
WHERE B.tarih >= '2025-01-01'
|
WHERE B.tarih >= '2025-01-01'
|
||||||
AND TD.tkp_cik IN (1,2,3,4,5)
|
AND TD.tkp_cik IN (1,2,3,4,5)
|
||||||
AND O.oper_num IN (985,986,987)
|
AND O.oper_num IN (985,986,987)
|
||||||
AND LTRIM(RTRIM(CONVERT(VARCHAR(64), MN.model_adi))) IN (%s)
|
GROUP BY RP.IsEmriNo, RP.ModelKodu
|
||||||
GROUP BY LTRIM(RTRIM(CONVERT(VARCHAR(64), MN.model_adi)))
|
`, strings.Join(valueRows, ","))
|
||||||
`, strings.Join(placeholders, ","))
|
|
||||||
|
|
||||||
rows, err := argeDB.QueryContext(ctx, sqlText, args...)
|
rows, err := argeDB.QueryContext(ctx, sqlText, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -860,13 +888,18 @@ GROUP BY LTRIM(RTRIM(CONVERT(VARCHAR(64), MN.model_adi)))
|
|||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var workOrder string
|
var workOrder string
|
||||||
|
var modelCode string
|
||||||
var totals ArgeBaggiDepotEntryTotals
|
var totals ArgeBaggiDepotEntryTotals
|
||||||
if err := rows.Scan(&workOrder, &totals.Ceket, &totals.Pantolon, &totals.Yelek); err != nil {
|
if err := rows.Scan(&workOrder, &modelCode, &totals.Ceket, &totals.Pantolon, &totals.Yelek); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
out[strings.TrimSpace(workOrder)] = totals
|
out[ArgeBaggiDepotEntryKey(workOrder, modelCode)] = totals
|
||||||
}
|
}
|
||||||
return out, rows.Err()
|
if err := rows.Err(); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProductionHasCostProducts(
|
func GetProductionHasCostProducts(
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
package queries
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestNormalizeArgeBaggiModelCode(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
modelCode string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{name: "tam urun kodu", modelCode: "M038-TKX60788", want: "TKX60788"},
|
||||||
|
{name: "arge model kodu", modelCode: "TKX60788", want: "TKX60788"},
|
||||||
|
{name: "bosluk ve kucuk harf", modelCode: " m038-tkx60788 ", want: "TKX60788"},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got := normalizeArgeBaggiModelCode(tt.modelCode)
|
||||||
|
if got != tt.want {
|
||||||
|
t.Fatalf("normalizeArgeBaggiModelCode(%q) = %q, want %q", tt.modelCode, got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestArgeBaggiDepotEntryKeyNormalizesPair(t *testing.T) {
|
||||||
|
got := ArgeBaggiDepotEntryKey(" 217655 ", " m038-ckk60281 ")
|
||||||
|
want := "217655\x1fCKK60281"
|
||||||
|
if got != want {
|
||||||
|
t.Fatalf("ArgeBaggiDepotEntryKey() = %q, want %q", got, want)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -159,18 +159,21 @@ func GetProductionNoCostProductsHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if argeDB := db.GetArgeBaggiDB(); argeDB != nil && len(list) > 0 {
|
if argeDB := db.GetArgeBaggiDB(); argeDB != nil && len(list) > 0 {
|
||||||
workOrders := make([]string, 0, len(list))
|
lookups := make([]queries.ArgeBaggiDepotEntryLookup, 0, len(list))
|
||||||
for i := range list {
|
for i := range list {
|
||||||
workOrders = append(workOrders, list[i].UrtSiparisNo)
|
lookups = append(lookups, queries.ArgeBaggiDepotEntryLookup{
|
||||||
|
WorkOrder: list[i].UrtSiparisNo,
|
||||||
|
ModelCode: list[i].MModelKodu,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
argeCtx, cancelArge := context.WithTimeout(r.Context(), 15*time.Second)
|
argeCtx, cancelArge := context.WithTimeout(r.Context(), 15*time.Second)
|
||||||
totalsByWorkOrder, argeErr := queries.GetArgeBaggiDepotEntryTotals(argeCtx, argeDB, workOrders)
|
totalsByWorkOrderModel, argeErr := queries.GetArgeBaggiDepotEntryTotals(argeCtx, argeDB, lookups)
|
||||||
cancelArge()
|
cancelArge()
|
||||||
if argeErr != nil {
|
if argeErr != nil {
|
||||||
log.Printf("[ProductionNoCost] ArgeBAGGI enrichment error: %v", argeErr)
|
log.Printf("[ProductionNoCost] ArgeBAGGI enrichment error: %v", argeErr)
|
||||||
} else {
|
} else {
|
||||||
for i := range list {
|
for i := range list {
|
||||||
totals := totalsByWorkOrder[strings.TrimSpace(list[i].UrtSiparisNo)]
|
totals := totalsByWorkOrderModel[queries.ArgeBaggiDepotEntryKey(list[i].UrtSiparisNo, list[i].MModelKodu)]
|
||||||
list[i].CeketDepoGiris = totals.Ceket
|
list[i].CeketDepoGiris = totals.Ceket
|
||||||
list[i].PantolonDepoGiris = totals.Pantolon
|
list[i].PantolonDepoGiris = totals.Pantolon
|
||||||
list[i].YelekDepoGiris = totals.Yelek
|
list[i].YelekDepoGiris = totals.Yelek
|
||||||
@@ -244,18 +247,21 @@ func GetProductionHasCostProductsHandler(w http.ResponseWriter, r *http.Request)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if argeDB := db.GetArgeBaggiDB(); argeDB != nil && len(list) > 0 {
|
if argeDB := db.GetArgeBaggiDB(); argeDB != nil && len(list) > 0 {
|
||||||
workOrders := make([]string, 0, len(list))
|
lookups := make([]queries.ArgeBaggiDepotEntryLookup, 0, len(list))
|
||||||
for i := range list {
|
for i := range list {
|
||||||
workOrders = append(workOrders, list[i].UrtSiparisNo)
|
lookups = append(lookups, queries.ArgeBaggiDepotEntryLookup{
|
||||||
|
WorkOrder: list[i].UrtSiparisNo,
|
||||||
|
ModelCode: list[i].UrunKodu,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
argeCtx, cancelArge := context.WithTimeout(r.Context(), 15*time.Second)
|
argeCtx, cancelArge := context.WithTimeout(r.Context(), 15*time.Second)
|
||||||
totalsByWorkOrder, argeErr := queries.GetArgeBaggiDepotEntryTotals(argeCtx, argeDB, workOrders)
|
totalsByWorkOrderModel, argeErr := queries.GetArgeBaggiDepotEntryTotals(argeCtx, argeDB, lookups)
|
||||||
cancelArge()
|
cancelArge()
|
||||||
if argeErr != nil {
|
if argeErr != nil {
|
||||||
log.Printf("[ProductionHasCost] ArgeBAGGI enrichment error: %v", argeErr)
|
log.Printf("[ProductionHasCost] ArgeBAGGI enrichment error: %v", argeErr)
|
||||||
} else {
|
} else {
|
||||||
for i := range list {
|
for i := range list {
|
||||||
totals := totalsByWorkOrder[strings.TrimSpace(list[i].UrtSiparisNo)]
|
totals := totalsByWorkOrderModel[queries.ArgeBaggiDepotEntryKey(list[i].UrtSiparisNo, list[i].UrunKodu)]
|
||||||
list[i].CeketDepoGiris = totals.Ceket
|
list[i].CeketDepoGiris = totals.Ceket
|
||||||
list[i].PantolonDepoGiris = totals.Pantolon
|
list[i].PantolonDepoGiris = totals.Pantolon
|
||||||
list[i].YelekDepoGiris = totals.Yelek
|
list[i].YelekDepoGiris = totals.Yelek
|
||||||
|
|||||||
Reference in New Issue
Block a user