mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 21:41:55 +00:00
feat[BE]: add overhead and ekspedisi items to profit loss report; include total depletion in closing report calculation
This commit is contained in:
@@ -60,6 +60,8 @@ type PLSummaryGroup struct {
|
||||
type ProfitLossData struct {
|
||||
Penjualan []PLItem `json:"penjualan"`
|
||||
Pembelian []PLItem `json:"pembelian"`
|
||||
Overhead PLItem `json:"overhead"`
|
||||
Ekspedisi PLItem `json:"ekspedisi"`
|
||||
Summary PLSummaryGroup `json:"summary"`
|
||||
}
|
||||
|
||||
@@ -167,15 +169,13 @@ func ToHppBahanBakuGroup(budgets []entities.ProjectBudget, realizations []entiti
|
||||
ekspedisiAmount := sumRealizationsByFilter(realizations, filterRealizationByNonstockFlag(utils.FlagEkspedisi))
|
||||
ekspedisiRpPerBird, ekspedisiRpPerKg := calculatePerUnitMetrics(ekspedisiAmount, totalPopulation, totalWeightProduced)
|
||||
|
||||
if ekspedisiAmount > 0 {
|
||||
items = append(items, HppItem{
|
||||
Type: "Beban Ekspedisi",
|
||||
Comparison: ToComparison(
|
||||
ToFinancialMetrics(ekspedisiRpPerBird, ekspedisiRpPerKg, ekspedisiAmount),
|
||||
ToFinancialMetrics(ekspedisiRpPerBird, ekspedisiRpPerKg, ekspedisiAmount), // Same as realization
|
||||
),
|
||||
})
|
||||
}
|
||||
items = append(items, HppItem{
|
||||
Type: "Beban Ekspedisi",
|
||||
Comparison: ToComparison(
|
||||
ToFinancialMetrics(ekspedisiRpPerBird, ekspedisiRpPerKg, ekspedisiAmount),
|
||||
ToFinancialMetrics(ekspedisiRpPerBird, ekspedisiRpPerKg, ekspedisiAmount), // Same as realization
|
||||
),
|
||||
})
|
||||
|
||||
return HppGroup{
|
||||
GroupName: "HPP dan Bahan Baku",
|
||||
@@ -248,19 +248,28 @@ func sumPLItems(items []PLItem) (totalAmount, totalPerBird float64) {
|
||||
}
|
||||
|
||||
func ToPenjualanItems(projectFlockCategory string, deliveryProducts []entities.MarketingDeliveryProduct, totalPopulation, totalWeightSold float64) []PLItem {
|
||||
items := []PLItem{}
|
||||
|
||||
// Categorize deliveries by sales type based on Product flags
|
||||
categorized := categorizeDeliveriesBySalesType(deliveryProducts)
|
||||
|
||||
items := []PLItem{}
|
||||
if projectFlockCategory == string(utils.ProjectFlockCategoryLaying) {
|
||||
// For LAYING: show both Penjualan Ayam Besar and Penjualan Telur (even if 0)
|
||||
ayamAmount := sumDeliveriesByCategory(categorized["Penjualan Ayam Besar"])
|
||||
telurAmount := sumDeliveriesByCategory(categorized["Penjualan Telur"])
|
||||
|
||||
// Process each sales category
|
||||
for salesType, deliveries := range categorized {
|
||||
amount := sumDeliveriesByCategory(deliveries)
|
||||
// Penjualan Ayam Besar
|
||||
rpPerBird, rpPerKg := calculatePerUnitMetrics(ayamAmount, totalPopulation, totalWeightSold)
|
||||
items = append(items, ToPLItem("Penjualan Ayam Besar", ToFinancialMetrics(rpPerBird, rpPerKg, ayamAmount)))
|
||||
|
||||
// Use totalPopulation and totalWeightSold for per-unit calculations
|
||||
rpPerBird, rpPerKg := calculatePerUnitMetrics(amount, totalPopulation, totalWeightSold)
|
||||
|
||||
items = append(items, ToPLItem(salesType, ToFinancialMetrics(rpPerBird, rpPerKg, amount)))
|
||||
// Penjualan Telur
|
||||
rpPerBird, rpPerKg = calculatePerUnitMetrics(telurAmount, totalPopulation, totalWeightSold)
|
||||
items = append(items, ToPLItem("Penjualan Telur", ToFinancialMetrics(rpPerBird, rpPerKg, telurAmount)))
|
||||
} else {
|
||||
// For GROWING: show only Penjualan Ayam Besar
|
||||
ayamAmount := sumDeliveriesByCategory(categorized["Penjualan Ayam Besar"])
|
||||
rpPerBird, rpPerKg := calculatePerUnitMetrics(ayamAmount, totalPopulation, totalWeightSold)
|
||||
items = append(items, ToPLItem("Penjualan Ayam Besar", ToFinancialMetrics(rpPerBird, rpPerKg, ayamAmount)))
|
||||
}
|
||||
|
||||
return items
|
||||
@@ -278,7 +287,7 @@ func ToPembelianItems(purchases []entities.PurchaseItem, budgets []entities.Proj
|
||||
|
||||
rpPerBird, rpPerKg := calculatePerUnitMetrics(totalCost, totalPopulation, totalWeightProduced)
|
||||
return []PLItem{
|
||||
ToPLItem("Harga Pokok Penjualan (HPP)", ToFinancialMetrics(rpPerBird, rpPerKg, totalCost)),
|
||||
ToPLItem("Pembelian Sapronak", ToFinancialMetrics(rpPerBird, rpPerKg, totalCost)),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,20 +310,21 @@ func ToEkspedisiItems(realizations []entities.ExpenseRealization, totalPopulatio
|
||||
func ToPLSummaryGroup(penjualanItems, pembelianItems, overheadItems, ekspedisiItems []PLItem) PLSummaryGroup {
|
||||
totalPenjualan, totalPenjualanPerBird := sumPLItems(penjualanItems)
|
||||
totalPembelian, totalPembelianPerBird := sumPLItems(pembelianItems)
|
||||
totalOverhead, _ := sumPLItems(overheadItems)
|
||||
totalEkspedisi, _ := sumPLItems(ekspedisiItems)
|
||||
totalOverhead, totalOverheadPerBird := sumPLItems(overheadItems)
|
||||
totalEkspedisi, totalEkspedisiPerBird := sumPLItems(ekspedisiItems)
|
||||
|
||||
grossProfit := totalPenjualan - totalPembelian
|
||||
grossProfitPerBird := totalPenjualanPerBird - totalPembelianPerBird
|
||||
|
||||
totalOtherExpenses := totalOverhead + totalEkspedisi
|
||||
totalOtherExpensesPerBird := totalOverheadPerBird + totalEkspedisiPerBird
|
||||
|
||||
netProfit := grossProfit - totalOtherExpenses
|
||||
netProfitPerBird := grossProfitPerBird - 0.0
|
||||
netProfitPerBird := grossProfitPerBird - totalOtherExpensesPerBird
|
||||
|
||||
return PLSummaryGroup{
|
||||
GrossProfit: ToPLSummaryItem("LABA RUGI BRUTTO", ToFinancialMetrics(grossProfitPerBird, 0, grossProfit)),
|
||||
SubTotal: ToPLSummaryItem("SUB TOTAL", ToFinancialMetrics(0, 0, totalOtherExpenses)),
|
||||
SubTotal: ToPLSummaryItem("SUB TOTAL", ToFinancialMetrics(totalOtherExpensesPerBird, 0, totalOtherExpenses)),
|
||||
NetProfit: ToPLSummaryItem("LABA RUGI NETTO", ToFinancialMetrics(netProfitPerBird, 0, netProfit)),
|
||||
}
|
||||
}
|
||||
@@ -322,9 +332,15 @@ func ToPLSummaryGroup(penjualanItems, pembelianItems, overheadItems, ekspedisiIt
|
||||
func ToProfitLossData(penjualanItems, pembelianItems, overheadItems, ekspedisiItems []PLItem) ProfitLossData {
|
||||
summary := ToPLSummaryGroup(penjualanItems, pembelianItems, overheadItems, ekspedisiItems)
|
||||
|
||||
// Get total overhead and ekspedisi as single items
|
||||
totalOverhead := aggregatePLItems(overheadItems, "Pengeluaran Overhead")
|
||||
totalEkspedisi := aggregatePLItems(ekspedisiItems, "Beban Ekspedisi")
|
||||
|
||||
return ProfitLossData{
|
||||
Penjualan: penjualanItems,
|
||||
Pembelian: pembelianItems,
|
||||
Overhead: totalOverhead,
|
||||
Ekspedisi: totalEkspedisi,
|
||||
Summary: summary,
|
||||
}
|
||||
}
|
||||
@@ -335,6 +351,11 @@ func ToProfitLossSection(penjualanItems, pembelianItems, overheadItems, ekspedis
|
||||
}
|
||||
}
|
||||
|
||||
func aggregatePLItems(items []PLItem, label string) PLItem {
|
||||
totalAmount, totalPerBird := sumPLItems(items)
|
||||
return ToPLItem(label, ToFinancialMetrics(totalPerBird, 0, totalAmount))
|
||||
}
|
||||
|
||||
func ToReportResponse(hppPurchases HppPurchasesSection, profitLoss ProfitLossSection) ReportResponse {
|
||||
return ReportResponse{
|
||||
HppPurchases: hppPurchases,
|
||||
@@ -342,9 +363,7 @@ func ToReportResponse(hppPurchases HppPurchasesSection, profitLoss ProfitLossSec
|
||||
}
|
||||
}
|
||||
|
||||
// === MAIN BUILDER ===
|
||||
|
||||
func ToClosingKeuanganReport(projectFlockCategory string, purchaseItems []entities.PurchaseItem, budgets []entities.ProjectBudget, realizations []entities.ExpenseRealization, deliveryProducts []entities.MarketingDeliveryProduct, chickins []entities.ProjectChickin, totalWeightProduced float64) ReportResponse {
|
||||
func ToClosingKeuanganReport(projectFlockCategory string, purchaseItems []entities.PurchaseItem, budgets []entities.ProjectBudget, realizations []entities.ExpenseRealization, deliveryProducts []entities.MarketingDeliveryProduct, chickins []entities.ProjectChickin, totalWeightProduced, totalDepletion float64) ReportResponse {
|
||||
var totalPopulation float64
|
||||
var totalWeightSold float64
|
||||
|
||||
@@ -356,13 +375,16 @@ func ToClosingKeuanganReport(projectFlockCategory string, purchaseItems []entiti
|
||||
totalWeightSold += delivery.TotalWeight
|
||||
}
|
||||
|
||||
// Calculate actual population (chickin - depletion) for cost allocation
|
||||
actualPopulation := totalPopulation - totalDepletion
|
||||
|
||||
// Use totalWeightProduced for HPP calculation (not totalWeightSold)
|
||||
hppSection := ToHppPurchasesSection(purchaseItems, budgets, realizations, totalWeightProduced, totalPopulation)
|
||||
|
||||
penjualanItems := ToPenjualanItems(projectFlockCategory, deliveryProducts, totalPopulation, totalWeightSold)
|
||||
pembelianItems := ToPembelianItems(purchaseItems, budgets, realizations, totalPopulation, totalWeightProduced)
|
||||
overheadItems := ToOverheadItems(budgets, realizations, totalPopulation, totalWeightProduced)
|
||||
ekspedisiItems := ToEkspedisiItems(realizations, totalPopulation, totalWeightProduced)
|
||||
pembelianItems := ToPembelianItems(purchaseItems, budgets, realizations, actualPopulation, totalWeightProduced)
|
||||
overheadItems := ToOverheadItems(budgets, realizations, actualPopulation, totalWeightProduced)
|
||||
ekspedisiItems := ToEkspedisiItems(realizations, actualPopulation, totalWeightProduced)
|
||||
plSection := ToProfitLossSection(penjualanItems, pembelianItems, overheadItems, ekspedisiItems)
|
||||
|
||||
return ToReportResponse(hppSection, plSection)
|
||||
|
||||
Reference in New Issue
Block a user