From ce108da847b163b7f6e6b2d29395c47146cc8914 Mon Sep 17 00:00:00 2001 From: aguhh18 Date: Mon, 2 Feb 2026 15:36:06 +0700 Subject: [PATCH] FEAT[BE] :enhance production data calculations by adding TotalBirdSold and refining profit/loss metrics --- .../services/closingKeuangan.service.go | 85 +++++++++++++------ 1 file changed, 59 insertions(+), 26 deletions(-) diff --git a/internal/modules/closings/services/closingKeuangan.service.go b/internal/modules/closings/services/closingKeuangan.service.go index ca76c67e..804ca023 100644 --- a/internal/modules/closings/services/closingKeuangan.service.go +++ b/internal/modules/closings/services/closingKeuangan.service.go @@ -41,6 +41,7 @@ type ProductionData struct { TotalWeightProduced float64 TotalEggWeightKg float64 TotalWeightSold float64 + TotalBirdSold float64 TotalSalesAmount float64 } @@ -283,6 +284,7 @@ func (s closingKeuanganService) calculateProductionData(c *fiber.Ctx, projectFlo continue } data.TotalWeightSold += delivery.TotalWeight + data.TotalBirdSold += delivery.UsageQty data.TotalSalesAmount += delivery.TotalPrice } @@ -383,46 +385,77 @@ func (s closingKeuanganService) buildHPPSection(c *fiber.Ctx, projectFlock *enti func (s closingKeuanganService) buildProfitLossSection(projectFlock *entity.ProjectFlock, costs *CostData, production *ProductionData) dto.ProfitLossSection { - totalPopulationIn := production.TotalPopulationIn totalWeightProduced := production.TotalWeightProduced totalEggWeightKg := production.TotalEggWeightKg totalSalesAmount := production.TotalSalesAmount totalWeightSold := production.TotalWeightSold + totalBirdSold := production.TotalBirdSold + actualPopulation := production.TotalPopulationIn - production.TotalDepletion - weightForSales := totalWeightSold - weightForCalculation := totalWeightProduced - if projectFlock.Category == string(utils.ProjectFlockCategoryLaying) { - weightForSales = totalWeightSold - weightForCalculation = totalEggWeightKg - } + isLaying := projectFlock.Category == string(utils.ProjectFlockCategoryLaying) - calculateProfitLossMetrics := func(amount float64) (rpPerBird, rpPerKg float64) { - if totalPopulationIn > 0 { - rpPerBird = amount / totalPopulationIn - } - if weightForSales > 0 { - rpPerKg = amount / weightForSales + // Fungsi untuk sales: LAYING = populasi aktual, GROWING = ekor terjual + calculateSalesMetrics := func(amount float64) (rpPerBird, rpPerKg float64) { + if isLaying { + if actualPopulation > 0 { + rpPerBird = amount / actualPopulation + } + if totalWeightSold > 0 { + rpPerKg = amount / totalWeightSold + } + } else { + if totalBirdSold > 0 { + rpPerBird = amount / totalBirdSold + } + if totalWeightSold > 0 { + rpPerKg = amount / totalWeightSold + } } return } - actualPopulation := production.TotalPopulationIn - production.TotalDepletion - - calculateMetrics := func(amount float64) (rpPerBird, rpPerKg float64) { + // Fungsi untuk cost: per ekor = populasi aktual, per kg = LAYING telur produksi / GROWING ayam produksi + calculateCostMetrics := func(amount float64) (rpPerBird, rpPerKg float64) { if actualPopulation > 0 { rpPerBird = amount / actualPopulation } - if weightForCalculation > 0 { - rpPerKg = amount / weightForCalculation + if isLaying { + if totalEggWeightKg > 0 { + rpPerKg = amount / totalEggWeightKg + } + } else { + if totalWeightProduced > 0 { + rpPerKg = amount / totalWeightProduced + } + } + return + } + + // Fungsi untuk overhead/ekspedisi: LAYING = populasi aktual, GROWING = ekor terjual + calculateOverheadMetrics := func(amount float64) (rpPerBird, rpPerKg float64) { + if isLaying { + if actualPopulation > 0 { + rpPerBird = amount / actualPopulation + } + if totalWeightSold > 0 { + rpPerKg = amount / totalWeightSold + } + } else { + if totalBirdSold > 0 { + rpPerBird = amount / totalBirdSold + } + if totalWeightSold > 0 { + rpPerKg = amount / totalWeightSold + } } return } plItems := []dto.ProfitLossItem{} - salesRpPerBird, salesRpPerKg := calculateProfitLossMetrics(totalSalesAmount) + salesRpPerBird, salesRpPerKg := calculateSalesMetrics(totalSalesAmount) salesLabel := "Penjualan Ayam" - if projectFlock.Category == string(utils.ProjectFlockCategoryLaying) { + if isLaying { salesLabel = "Penjualan Telur" } plItems = append(plItems, dto.ToProfitLossItem( @@ -435,23 +468,23 @@ func (s closingKeuanganService) buildProfitLossSection(projectFlock *entity.Proj )) totalSapronakAmount := costs.ChickenCost + costs.FeedCost + costs.OvkCost - _, sapronakRpPerKg := calculateMetrics(totalSapronakAmount) sapronakRpPerBird := 0.0 + sapronakRpPerKg := 0.0 for _, amount := range []float64{costs.ChickenCost, costs.FeedCost, costs.OvkCost} { - rpPerBird, _ := calculateMetrics(amount) + rpPerBird, rpPerKg := calculateCostMetrics(amount) sapronakRpPerBird += rpPerBird + sapronakRpPerKg += rpPerKg } - sapronakLabel := "Pengeluaran Sapronak" plItems = append(plItems, dto.ToProfitLossItem( string(dto.PLCodeSapronak), - sapronakLabel, + "Pengeluaran Sapronak", "purchase", sapronakRpPerBird, sapronakRpPerKg, totalSapronakAmount, )) - overheadRpPerBird, overheadRpPerKg := calculateProfitLossMetrics(costs.RealizationOperational) + overheadRpPerBird, overheadRpPerKg := calculateOverheadMetrics(costs.RealizationOperational) plItems = append(plItems, dto.ToProfitLossItem( string(dto.PLCodeOverhead), "Overhead", @@ -461,7 +494,7 @@ func (s closingKeuanganService) buildProfitLossSection(projectFlock *entity.Proj costs.RealizationOperational, )) - ekspedisiRpPerBird, ekspedisiRpPerKg := calculateProfitLossMetrics(costs.ExpeditionCost) + ekspedisiRpPerBird, ekspedisiRpPerKg := calculateOverheadMetrics(costs.ExpeditionCost) plItems = append(plItems, dto.ToProfitLossItem( string(dto.PLCodeEkspedisi), "Ekspedisi",