From 3052497fc0538c17123c599d32bb6ad2471b07b0 Mon Sep 17 00:00:00 2001 From: giovanni Date: Mon, 19 Jan 2026 17:05:43 +0700 Subject: [PATCH] adjust grouping by project flock kandang --- .../modules/repports/dto/repportHpp.dto.go | 1 + .../hpp_per_kandang.repository.go | 112 +++++++++--------- .../repports/services/repport.service.go | 29 +++-- 3 files changed, 74 insertions(+), 68 deletions(-) diff --git a/internal/modules/repports/dto/repportHpp.dto.go b/internal/modules/repports/dto/repportHpp.dto.go index 15b6d51b..dc0b81d4 100644 --- a/internal/modules/repports/dto/repportHpp.dto.go +++ b/internal/modules/repports/dto/repportHpp.dto.go @@ -27,6 +27,7 @@ type HppPerKandangResponseData struct { type HppPerKandangRowDTO struct { ID int `json:"id"` Kandang HppPerKandangRowKandangDTO `json:"kandang"` + NameWithPeriode string `json:"name_with_periode"` WeightRange HppPerKandangWeightRangeDTO `json:"weight_range"` AvgWeightKg float64 `json:"avg_weight_kg"` EggProductionPieces int64 `json:"egg_production_pieces"` diff --git a/internal/modules/repports/repositories/hpp_per_kandang.repository.go b/internal/modules/repports/repositories/hpp_per_kandang.repository.go index 37a37d45..1135efbf 100644 --- a/internal/modules/repports/repositories/hpp_per_kandang.repository.go +++ b/internal/modules/repports/repositories/hpp_per_kandang.repository.go @@ -12,6 +12,7 @@ import ( type HppPerKandangRow struct { ProjectFlockKandangID uint + ProjectFlockPeriod int KandangID uint KandangName string KandangStatus string @@ -29,21 +30,21 @@ type HppPerKandangRow struct { } type HppPerKandangCostRow struct { - KandangID uint - FeedCost float64 - OvkCost float64 - DocCost float64 - DocQty float64 - BudgetCost float64 - ExpenseCost float64 + ProjectFlockKandangID uint + FeedCost float64 + OvkCost float64 + DocCost float64 + DocQty float64 + BudgetCost float64 + ExpenseCost float64 } type HppPerKandangSupplierRow struct { - KandangID uint - SupplierID uint - SupplierName string - SupplierAlias string - Category string + ProjectFlockKandangID uint + SupplierID uint + SupplierName string + SupplierAlias string + Category string } type HppPerKandangRepository interface { @@ -88,6 +89,7 @@ func (r *hppPerKandangRepository) GetRowsByPeriod(ctx context.Context, start, en Table("project_flocks AS pf"). Select(` pfk.id AS project_flock_kandang_id, + pfk.period AS project_flock_period, k.id AS kandang_id, k.name AS kandang_name, k.status AS kandang_status, @@ -118,8 +120,8 @@ func (r *hppPerKandangRepository) GetRowsByPeriod(ctx context.Context, start, en query = applyLocationFilters(query, areaIDs, locationIDs, kandangIDs) - query = query.Group("pfk.id, k.id, k.name, k.status, loc.id, loc.name, pic.id, pic.name"). - Order("k.id ASC") + query = query.Group("pfk.id, pfk.period, k.id, k.name, k.status, loc.id, loc.name, pic.id, pic.name"). + Order("pfk.id ASC") if err := query.Scan(&rows).Error; err != nil { return nil, err @@ -150,7 +152,7 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, query := r.db.WithContext(ctx). Table("recordings AS r"). Select(` - k.id AS kandang_id, + pfk.id AS project_flock_kandang_id, COALESCE(SUM(CASE WHEN f.name = ? THEN COALESCE(sa.qty, 0) * COALESCE(pi.price, 0) WHEN sa.stockable_type = ? AND tf.name = ? THEN COALESCE(std.total_qty, 0) * COALESCE(tpi.price, 0) @@ -179,25 +181,25 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, Where("r.deleted_at IS NULL"). Where("(la.action IS NULL OR la.action != ?)", string(entity.ApprovalActionRejected)) - query = query.Group("k.id").Order("k.id ASC") + query = query.Group("pfk.id").Order("pfk.id ASC") if err := query.Scan(&rows).Error; err != nil { return nil, nil, err } docRows := make([]struct { - KandangID uint - DocCost float64 - DocQty float64 - SupplierID *uint - SupplierName *string - SupplierAlias *string + ProjectFlockKandangID uint + DocCost float64 + DocQty float64 + SupplierID *uint + SupplierName *string + SupplierAlias *string }, 0) docQuery := r.db.WithContext(ctx). Table("project_chickins AS pc"). Select(` - pfk.kandang_id AS kandang_id, + pfk.id AS project_flock_kandang_id, COALESCE(SUM(pc.usage_qty * COALESCE(pi.price, 0)), 0) AS doc_cost, COALESCE(SUM(pc.usage_qty), 0) AS doc_qty, s.id AS supplier_id, @@ -210,7 +212,7 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, Joins("LEFT JOIN purchases AS pur ON pur.id = pi.purchase_id"). Joins("LEFT JOIN suppliers AS s ON s.id = pur.supplier_id"). Where("pc.project_flock_kandang_id IN ?", projectFlockKandangIDs). - Group("pfk.kandang_id, s.id, s.name, s.alias") + Group("pfk.id, s.id, s.name, s.alias") if err := docQuery.Scan(&docRows).Error; err != nil { return nil, nil, err @@ -219,28 +221,28 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, costMap := make(map[uint]*HppPerKandangCostRow, len(rows)) for i := range rows { row := rows[i] - costMap[row.KandangID] = &rows[i] + costMap[row.ProjectFlockKandangID] = &rows[i] } docSuppliers := make([]HppPerKandangSupplierRow, 0) docSeen := make(map[uint]map[uint]bool) for _, doc := range docRows { - entry, ok := costMap[doc.KandangID] + entry, ok := costMap[doc.ProjectFlockKandangID] if !ok { rows = append(rows, HppPerKandangCostRow{ - KandangID: doc.KandangID, + ProjectFlockKandangID: doc.ProjectFlockKandangID, }) entry = &rows[len(rows)-1] - costMap[doc.KandangID] = entry + costMap[doc.ProjectFlockKandangID] = entry } entry.DocCost += doc.DocCost entry.DocQty += doc.DocQty if doc.SupplierID != nil { - if docSeen[doc.KandangID] == nil { - docSeen[doc.KandangID] = make(map[uint]bool) + if docSeen[doc.ProjectFlockKandangID] == nil { + docSeen[doc.ProjectFlockKandangID] = make(map[uint]bool) } - if !docSeen[doc.KandangID][*doc.SupplierID] { - docSeen[doc.KandangID][*doc.SupplierID] = true + if !docSeen[doc.ProjectFlockKandangID][*doc.SupplierID] { + docSeen[doc.ProjectFlockKandangID][*doc.SupplierID] = true supplierName := "" if doc.SupplierName != nil { supplierName = *doc.SupplierName @@ -250,19 +252,19 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, supplierAlias = *doc.SupplierAlias } docSuppliers = append(docSuppliers, HppPerKandangSupplierRow{ - KandangID: doc.KandangID, - SupplierID: *doc.SupplierID, - SupplierName: supplierName, - SupplierAlias: supplierAlias, - Category: "DOC", + ProjectFlockKandangID: doc.ProjectFlockKandangID, + SupplierID: *doc.SupplierID, + SupplierName: supplierName, + SupplierAlias: supplierAlias, + Category: "DOC", }) } } } budgetRows := make([]struct { - KandangID uint - BudgetCost float64 + ProjectFlockKandangID uint + BudgetCost float64 }, 0) pfkUsageSub := r.db. @@ -283,7 +285,7 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, budgetQuery := r.db.WithContext(ctx). Table("project_flock_kandangs AS pfk"). Select(` - k.id AS kandang_id, + pfk.id AS project_flock_kandang_id, COALESCE(SUM((pb.qty * pb.price) * COALESCE(k_usage.kandang_usage_qty, 0) / NULLIF(p_usage.project_usage_qty, 0)), 0) AS budget_cost`). Joins("JOIN kandangs AS k ON k.id = pfk.kandang_id"). Joins("JOIN locations AS loc ON loc.id = k.location_id"). @@ -291,7 +293,7 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, Joins("LEFT JOIN (?) AS k_usage ON k_usage.project_flock_kandang_id = pfk.id", pfkUsageSub). Joins("LEFT JOIN (?) AS p_usage ON p_usage.project_flock_id = pfk.project_flock_id", projectUsageSub). Where("pfk.id IN (?)", projectFlockKandangIDs). - Group("k.id") + Group("pfk.id") // budgetQuery = applyLocationFilters(budgetQuery, areaIDs, locationIDs, kandangIDs) if err := budgetQuery.Scan(&budgetRows).Error; err != nil { @@ -299,33 +301,33 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, } for _, budget := range budgetRows { - entry, ok := costMap[budget.KandangID] + entry, ok := costMap[budget.ProjectFlockKandangID] if !ok { rows = append(rows, HppPerKandangCostRow{ - KandangID: budget.KandangID, + ProjectFlockKandangID: budget.ProjectFlockKandangID, }) entry = &rows[len(rows)-1] - costMap[budget.KandangID] = entry + costMap[budget.ProjectFlockKandangID] = entry } entry.BudgetCost += budget.BudgetCost } expenseRows := make([]struct { - KandangID uint - ExpenseCost float64 + ProjectFlockKandangID uint + ExpenseCost float64 }, 0) expenseQuery := r.db.WithContext(ctx). Table("project_flock_kandangs AS pfk"). Select(` - k.id AS kandang_id, + pfk.id AS project_flock_kandang_id, COALESCE(SUM(er.qty * er.price), 0) AS expense_cost`). Joins("JOIN kandangs AS k ON k.id = pfk.kandang_id"). Joins("JOIN locations AS loc ON loc.id = k.location_id"). Joins("JOIN expense_nonstocks AS en ON en.project_flock_kandang_id = pfk.id"). Joins("JOIN expense_realizations AS er ON er.expense_nonstock_id = en.id"). Where("pfk.id IN (?)", projectFlockKandangIDs). - Group("k.id") + Group("pfk.id") // expenseQuery = applyLocationFilters(expenseQuery, areaIDs, locationIDs, kandangIDs) if err := expenseQuery.Scan(&expenseRows).Error; err != nil { @@ -333,13 +335,13 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, } for _, exp := range expenseRows { - entry, ok := costMap[exp.KandangID] + entry, ok := costMap[exp.ProjectFlockKandangID] if !ok { rows = append(rows, HppPerKandangCostRow{ - KandangID: exp.KandangID, + ProjectFlockKandangID: exp.ProjectFlockKandangID, }) entry = &rows[len(rows)-1] - costMap[exp.KandangID] = entry + costMap[exp.ProjectFlockKandangID] = entry } entry.ExpenseCost += exp.ExpenseCost } @@ -348,7 +350,7 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, feedQuery := r.db.WithContext(ctx). Table("recordings AS r"). - Select("DISTINCT k.id AS kandang_id, s.id AS supplier_id, s.name AS supplier_name, s.alias AS supplier_alias"). + Select("DISTINCT pfk.id AS project_flock_kandang_id, s.id AS supplier_id, s.name AS supplier_name, s.alias AS supplier_alias"). Joins("JOIN project_flock_kandangs AS pfk ON pfk.id = r.project_flock_kandangs_id"). Joins("JOIN kandangs AS k ON k.id = pfk.kandang_id"). Joins("JOIN locations AS loc ON loc.id = k.location_id"). @@ -369,11 +371,11 @@ func (r *hppPerKandangRepository) GetFeedOvkDocCostByPeriod(ctx context.Context, } for i := range feedSuppliers { - if _, exists := costMap[feedSuppliers[i].KandangID]; !exists { + if _, exists := costMap[feedSuppliers[i].ProjectFlockKandangID]; !exists { rows = append(rows, HppPerKandangCostRow{ - KandangID: feedSuppliers[i].KandangID, + ProjectFlockKandangID: feedSuppliers[i].ProjectFlockKandangID, }) - costMap[feedSuppliers[i].KandangID] = &rows[len(rows)-1] + costMap[feedSuppliers[i].ProjectFlockKandangID] = &rows[len(rows)-1] } feedSuppliers[i].Category = "FEED" } diff --git a/internal/modules/repports/services/repport.service.go b/internal/modules/repports/services/repport.service.go index 9c0c600f..452d46b6 100644 --- a/internal/modules/repports/services/repport.service.go +++ b/internal/modules/repports/services/repport.service.go @@ -1380,7 +1380,7 @@ func (s *repportService) GetHppPerKandang(ctx *fiber.Ctx) (*dto.HppPerKandangRes costMap := make(map[uint]HppCostAggregate, len(costRows)) for _, row := range costRows { - costMap[row.KandangID] = HppCostAggregate{ + costMap[row.ProjectFlockKandangID] = HppCostAggregate{ FeedCost: row.FeedCost, OvkCost: row.OvkCost, DocCost: row.DocCost, @@ -1409,15 +1409,15 @@ func (s *repportService) GetHppPerKandang(ctx *fiber.Ctx) (*dto.HppPerKandangRes category = "DOC" } - if seen[sup.KandangID] == nil { - seen[sup.KandangID] = make(map[uint]bool) + if seen[sup.ProjectFlockKandangID] == nil { + seen[sup.ProjectFlockKandangID] = make(map[uint]bool) } - if seen[sup.KandangID][sup.SupplierID] { + if seen[sup.ProjectFlockKandangID][sup.SupplierID] { continue } - seen[sup.KandangID][sup.SupplierID] = true + seen[sup.ProjectFlockKandangID][sup.SupplierID] = true - targetMap[sup.KandangID] = append(targetMap[sup.KandangID], dto.HppPerKandangSupplierDTO{ + targetMap[sup.ProjectFlockKandangID] = append(targetMap[sup.ProjectFlockKandangID], dto.HppPerKandangSupplierDTO{ ID: int64(sup.SupplierID), Name: sup.SupplierName, Alias: sup.SupplierAlias, @@ -1507,7 +1507,7 @@ func (s *repportService) GetHppPerKandang(ctx *fiber.Ctx) (*dto.HppPerKandangRes rangeKey := weightRangeKey{Min: weightMin, Max: weightMax} // rowBirds := int64(math.Round(birdsFloat)) - costEntry := costMap[row.KandangID] + costEntry := costMap[row.ProjectFlockKandangID] totalCost := costEntry.FeedCost + costEntry.OvkCost + costEntry.DocCost + costEntry.BudgetCost + costEntry.ExpenseCost // hppRp := 0.0 // if weightFloat > 0 { @@ -1526,8 +1526,10 @@ func (s *repportService) GetHppPerKandang(ctx *fiber.Ctx) (*dto.HppPerKandangRes avgDocPrice = int64(math.Round(costEntry.DocCost / costEntry.DocQty)) } + nameWithPeriod := fmt.Sprintf("%s Period %d", row.KandangName, row.ProjectFlockPeriod) + dataRows = append(dataRows, dto.HppPerKandangRowDTO{ - ID: int(row.KandangID), + ID: int(row.ProjectFlockKandangID), Kandang: dto.HppPerKandangRowKandangDTO{ ID: int64(row.KandangID), Name: row.KandangName, @@ -1545,11 +1547,12 @@ func (s *repportService) GetHppPerKandang(ctx *fiber.Ctx) (*dto.HppPerKandangRes WeightMin: weightMin, WeightMax: weightMax, }, - AvgWeightKg: avgWeight, + AvgWeightKg: avgWeight, + NameWithPeriode: nameWithPeriod, // FeedCostRp: costEntry.FeedCost, // OvkCostRp: costEntry.OvkCost, - DocSuppliers: docSupplierMap[row.KandangID], - FeedSuppliers: feedSupplierMap[row.KandangID], + DocSuppliers: docSupplierMap[row.ProjectFlockKandangID], + FeedSuppliers: feedSupplierMap[row.ProjectFlockKandangID], EggProductionPieces: int64(math.Round(eggPiecesFloatRemaining)), EggProductionKg: eggRemainingWeightFloatRemaining, // EggProductionTotalWeightKg: eggWeightFloat, @@ -1603,12 +1606,12 @@ func (s *repportService) GetHppPerKandang(ctx *fiber.Ctx) (*dto.HppPerKandangRes // rangeAgg.RemainingWeightKg += row.RemainingChickenWeight rangeAgg.AvgWeightSum += avgWeight rangeAgg.AvgWeightCount++ - for _, supplier := range feedSupplierMap[row.KandangID] { + for _, supplier := range feedSupplierMap[row.ProjectFlockKandangID] { if _, ok := rangeAgg.FeedSuppliers[supplier.ID]; !ok { rangeAgg.FeedSuppliers[supplier.ID] = supplier } } - for _, supplier := range docSupplierMap[row.KandangID] { + for _, supplier := range docSupplierMap[row.ProjectFlockKandangID] { if _, ok := rangeAgg.DocSuppliers[supplier.ID]; !ok { rangeAgg.DocSuppliers[supplier.ID] = supplier }