mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
feat[BE}: change get penjualan repport dto an add more params
This commit is contained in:
@@ -31,6 +31,7 @@ type ClosingService interface {
|
||||
GetClosingSummary(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error)
|
||||
GetOverhead(ctx *fiber.Ctx, projectFlockID uint) (*dto.OverheadListDTO, error)
|
||||
GetClosingSapronak(ctx *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error)
|
||||
GetClosingKeuangan(ctx *fiber.Ctx, projectFlockID uint) (*dto.ReportResponse, error)
|
||||
}
|
||||
|
||||
type closingService struct {
|
||||
@@ -379,3 +380,237 @@ func (s closingService) GetOverhead(c *fiber.Ctx, projectFlockID uint) (*dto.Ove
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
func (s closingService) GetClosingKeuangan(c *fiber.Ctx, projectFlockID uint) (*dto.ReportResponse, error) {
|
||||
if projectFlockID == 0 {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
||||
}
|
||||
|
||||
_, err := s.Repository.GetByID(c.Context(), projectFlockID, nil)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock not found")
|
||||
}
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to get project flock %d for closing keuangan: %+v", projectFlockID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock")
|
||||
}
|
||||
|
||||
budgets, err := s.ProjectBudgetRepo.GetByProjectFlockID(c.Context(), projectFlockID)
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to get budgets for project flock %d: %+v", projectFlockID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch budgets")
|
||||
}
|
||||
|
||||
realizations, err := s.ExpenseRealizationRepo.GetByProjectFlockID(c.Context(), projectFlockID)
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to get realizations for project flock %d: %+v", projectFlockID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch realizations")
|
||||
}
|
||||
|
||||
deliveryProducts, err := s.MarketingDeliveryProductRepo.GetDeliveryProductsByProjectFlockID(c.Context(), projectFlockID, func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("MarketingProduct").
|
||||
Preload("MarketingProduct.ProductWarehouse").
|
||||
Preload("MarketingProduct.ProductWarehouse.Product")
|
||||
})
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
s.Log.Errorf("Failed to get delivery products for project flock %d: %+v", projectFlockID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch delivery products")
|
||||
}
|
||||
|
||||
chickins, err := s.ChickinRepo.GetByProjectFlockID(c.Context(), projectFlockID)
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to get chickins for project flock %d: %+v", projectFlockID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch chickins")
|
||||
}
|
||||
|
||||
var totalPopulation float64
|
||||
for _, chickin := range chickins {
|
||||
totalPopulation += chickin.UsageQty
|
||||
}
|
||||
|
||||
var totalWeightSold float64
|
||||
for _, delivery := range deliveryProducts {
|
||||
totalWeightSold += delivery.TotalWeight
|
||||
}
|
||||
|
||||
hppItems := s.buildHppItems(budgets, realizations, totalWeightSold, totalPopulation)
|
||||
hppGroups := []dto.HppGroup{
|
||||
dto.ToHppGroup("Input Produksi", hppItems),
|
||||
}
|
||||
|
||||
summaryHpp := s.calculateHppSummary(budgets, realizations, totalWeightSold, totalPopulation)
|
||||
|
||||
penjualanItems := s.buildPenjualanItems(deliveryProducts, totalPopulation, totalWeightSold)
|
||||
pembelianItems := s.buildPembelianItems(budgets, realizations, totalPopulation, totalWeightSold)
|
||||
plSummary := s.calculatePLSummary(penjualanItems, pembelianItems)
|
||||
|
||||
hppSection := dto.ToHppPurchasesSection("HPP Pembelian", hppGroups, summaryHpp)
|
||||
plSection := dto.ToProfitLossSection("Laporan Laba Rugi", dto.ToProfitLossData(penjualanItems, pembelianItems, plSummary))
|
||||
|
||||
report := dto.ToReportResponse(hppSection, plSection)
|
||||
|
||||
return &report, nil
|
||||
}
|
||||
|
||||
func (s closingService) buildHppItems(budgets []entity.ProjectBudget, realizations []entity.ExpenseRealization, totalWeightSold, totalPopulation float64) []dto.HppItem {
|
||||
var totalBudgetAmount float64
|
||||
var totalRealizationAmount float64
|
||||
|
||||
for _, budget := range budgets {
|
||||
totalBudgetAmount += budget.Price * budget.Qty
|
||||
}
|
||||
|
||||
for _, realization := range realizations {
|
||||
totalRealizationAmount += realization.Price * realization.Qty
|
||||
}
|
||||
|
||||
budgetRpPerBird := 0.0
|
||||
budgetRpPerKg := 0.0
|
||||
if totalPopulation > 0 {
|
||||
budgetRpPerBird = totalBudgetAmount / totalPopulation
|
||||
}
|
||||
if totalWeightSold > 0 {
|
||||
budgetRpPerKg = totalBudgetAmount / totalWeightSold
|
||||
}
|
||||
|
||||
realizationRpPerBird := 0.0
|
||||
realizationRpPerKg := 0.0
|
||||
if totalPopulation > 0 {
|
||||
realizationRpPerBird = totalRealizationAmount / totalPopulation
|
||||
}
|
||||
if totalWeightSold > 0 {
|
||||
realizationRpPerKg = totalRealizationAmount / totalWeightSold
|
||||
}
|
||||
|
||||
items := []dto.HppItem{
|
||||
dto.ToHppItem("Total HPP Produksi", dto.ToComparison(
|
||||
dto.ToFinancialMetrics(budgetRpPerBird, budgetRpPerKg, totalBudgetAmount),
|
||||
dto.ToFinancialMetrics(realizationRpPerBird, realizationRpPerKg, totalRealizationAmount),
|
||||
)),
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func (s closingService) calculateHppSummary(budgets []entity.ProjectBudget, realizations []entity.ExpenseRealization, totalWeightSold, totalPopulation float64) dto.SummaryHpp {
|
||||
var totalBudget float64
|
||||
var totalRealization float64
|
||||
|
||||
for _, budget := range budgets {
|
||||
totalBudget += budget.Price * budget.Qty
|
||||
}
|
||||
|
||||
for _, realization := range realizations {
|
||||
totalRealization += realization.Price * realization.Qty
|
||||
}
|
||||
|
||||
budgetRpPerBird := 0.0
|
||||
budgetRpPerKg := 0.0
|
||||
if totalPopulation > 0 {
|
||||
budgetRpPerBird = totalBudget / totalPopulation
|
||||
}
|
||||
if totalWeightSold > 0 {
|
||||
budgetRpPerKg = totalBudget / totalWeightSold
|
||||
}
|
||||
|
||||
realizationRpPerBird := 0.0
|
||||
realizationRpPerKg := 0.0
|
||||
if totalPopulation > 0 {
|
||||
realizationRpPerBird = totalRealization / totalPopulation
|
||||
}
|
||||
if totalWeightSold > 0 {
|
||||
realizationRpPerKg = totalRealization / totalWeightSold
|
||||
}
|
||||
|
||||
return dto.ToSummaryHpp("Total HPP", dto.ToComparison(
|
||||
dto.ToFinancialMetrics(budgetRpPerBird, budgetRpPerKg, totalBudget),
|
||||
dto.ToFinancialMetrics(realizationRpPerBird, realizationRpPerKg, totalRealization),
|
||||
))
|
||||
}
|
||||
|
||||
func (s closingService) buildPenjualanItems(deliveryProducts []entity.MarketingDeliveryProduct, totalPopulation, totalWeightSold float64) []dto.PLItem {
|
||||
var totalAmount float64
|
||||
|
||||
for _, delivery := range deliveryProducts {
|
||||
totalAmount += delivery.TotalPrice
|
||||
}
|
||||
|
||||
rpPerBird := 0.0
|
||||
rpPerKg := 0.0
|
||||
if totalPopulation > 0 {
|
||||
rpPerBird = totalAmount / totalPopulation
|
||||
}
|
||||
if totalWeightSold > 0 {
|
||||
rpPerKg = totalAmount / totalWeightSold
|
||||
}
|
||||
|
||||
items := []dto.PLItem{
|
||||
dto.ToPLItem("Penjualan", dto.ToFinancialMetrics(rpPerBird, rpPerKg, totalAmount)),
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func (s closingService) buildPembelianItems(budgets []entity.ProjectBudget, realizations []entity.ExpenseRealization, totalPopulation, totalWeightSold float64) []dto.PLItem {
|
||||
var totalBudget float64
|
||||
var totalRealization float64
|
||||
|
||||
for _, budget := range budgets {
|
||||
totalBudget += budget.Price * budget.Qty
|
||||
}
|
||||
|
||||
for _, realization := range realizations {
|
||||
totalRealization += realization.Price * realization.Qty
|
||||
}
|
||||
|
||||
budgetRpPerBird := 0.0
|
||||
budgetRpPerKg := 0.0
|
||||
if totalPopulation > 0 {
|
||||
budgetRpPerBird = totalBudget / totalPopulation
|
||||
}
|
||||
if totalWeightSold > 0 {
|
||||
budgetRpPerKg = totalBudget / totalWeightSold
|
||||
}
|
||||
|
||||
realizationRpPerBird := 0.0
|
||||
realizationRpPerKg := 0.0
|
||||
if totalPopulation > 0 {
|
||||
realizationRpPerBird = totalRealization / totalPopulation
|
||||
}
|
||||
if totalWeightSold > 0 {
|
||||
realizationRpPerKg = totalRealization / totalWeightSold
|
||||
}
|
||||
|
||||
items := []dto.PLItem{
|
||||
dto.ToPLItem("Beban Pokok Produksi", dto.ToFinancialMetrics(budgetRpPerBird, budgetRpPerKg, totalBudget)),
|
||||
dto.ToPLItem("Realisasi Beban Pokok", dto.ToFinancialMetrics(realizationRpPerBird, realizationRpPerKg, totalRealization)),
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
|
||||
func (s closingService) calculatePLSummary(penjualanItems, pembelianItems []dto.PLItem) dto.PLSummaryGroup {
|
||||
var totalPenjualan float64
|
||||
var totalPenjualanPerBird float64
|
||||
var totalPembelian float64
|
||||
var totalPembelianPerBird float64
|
||||
|
||||
for _, item := range penjualanItems {
|
||||
totalPenjualan += item.Amount
|
||||
totalPenjualanPerBird += item.RpPerBird
|
||||
}
|
||||
|
||||
for _, item := range pembelianItems {
|
||||
totalPembelian += item.Amount
|
||||
totalPembelianPerBird += item.RpPerBird
|
||||
}
|
||||
|
||||
grossProfit := totalPenjualan - totalPembelian
|
||||
grossProfitPerBird := totalPenjualanPerBird - totalPembelianPerBird
|
||||
|
||||
return dto.ToPLSummaryGroup(
|
||||
dto.ToPLSummaryItem("Laba Kotor", dto.ToFinancialMetrics(grossProfitPerBird, 0, grossProfit)),
|
||||
dto.ToPLSummaryItem("Sub Total", dto.ToFinancialMetrics(grossProfitPerBird, 0, grossProfit)),
|
||||
dto.ToPLSummaryItem("Laba Bersih", dto.ToFinancialMetrics(grossProfitPerBird, 0, grossProfit)),
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user