mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
feat[BE-384]: enhance reporting by adding chickin quantity and egg production weight calculations; refactor HPP calculations to consider product categories
This commit is contained in:
@@ -3,7 +3,6 @@ package service
|
||||
import (
|
||||
"context"
|
||||
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/modules/repports/dto"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/repports/validations"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
@@ -12,6 +11,7 @@ import (
|
||||
approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto"
|
||||
expenseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/repositories"
|
||||
marketingRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/repositories"
|
||||
chickinRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/chickins/repositories"
|
||||
recordingRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/repositories"
|
||||
purchaseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/repositories"
|
||||
|
||||
@@ -32,17 +32,19 @@ type repportService struct {
|
||||
ExpenseRealizationRepo expenseRepo.ExpenseRealizationRepository
|
||||
MarketingDeliveryRepo marketingRepo.MarketingDeliveryProductRepository
|
||||
PurchaseRepo purchaseRepo.PurchaseRepository
|
||||
ChickinRepo chickinRepo.ProjectChickinRepository
|
||||
RecordingRepo recordingRepo.RecordingRepository
|
||||
ApprovalSvc approvalService.ApprovalService
|
||||
}
|
||||
|
||||
func NewRepportService(validate *validator.Validate, expenseRealizationRepo expenseRepo.ExpenseRealizationRepository, marketingDeliveryRepo marketingRepo.MarketingDeliveryProductRepository, purchaseRepo purchaseRepo.PurchaseRepository, recordingRepo recordingRepo.RecordingRepository, approvalSvc approvalService.ApprovalService) RepportService {
|
||||
func NewRepportService(validate *validator.Validate, expenseRealizationRepo expenseRepo.ExpenseRealizationRepository, marketingDeliveryRepo marketingRepo.MarketingDeliveryProductRepository, purchaseRepo purchaseRepo.PurchaseRepository, chickinRepo chickinRepo.ProjectChickinRepository, recordingRepo recordingRepo.RecordingRepository, approvalSvc approvalService.ApprovalService) RepportService {
|
||||
return &repportService{
|
||||
Log: utils.Log,
|
||||
Validate: validate,
|
||||
ExpenseRealizationRepo: expenseRealizationRepo,
|
||||
MarketingDeliveryRepo: marketingDeliveryRepo,
|
||||
PurchaseRepo: purchaseRepo,
|
||||
ChickinRepo: chickinRepo,
|
||||
RecordingRepo: recordingRepo,
|
||||
ApprovalSvc: approvalSvc,
|
||||
}
|
||||
@@ -98,74 +100,63 @@ func (s *repportService) GetMarketing(c *fiber.Ctx, params *validation.Marketing
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
projectFlockIDs := s.collectProjectFlockIDs(deliveryProducts)
|
||||
hppMap := s.buildHppMap(c.Context(), projectFlockIDs, deliveryProducts)
|
||||
items := dto.ToRepportMarketingItemDTOsWithHppMap(deliveryProducts, hppMap)
|
||||
projectFlockIDMap := make(map[uint]bool)
|
||||
hppMap := make(map[uint]float64)
|
||||
|
||||
for _, dp := range deliveryProducts {
|
||||
if projectFlockKandang := dp.MarketingProduct.ProductWarehouse.ProjectFlockKandang; projectFlockKandang != nil {
|
||||
projectFlockID := projectFlockKandang.ProjectFlockId
|
||||
if projectFlockID > 0 && !projectFlockIDMap[projectFlockID] {
|
||||
projectFlockIDMap[projectFlockID] = true
|
||||
|
||||
category := projectFlockKandang.ProjectFlock.Category
|
||||
hppPerKg := s.calculateHppPricePerKg(c.Context(), projectFlockID, category)
|
||||
hppMap[projectFlockID] = hppPerKg
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
items := dto.ToRepportMarketingItemDTOsWithHppMap(deliveryProducts, hppMap)
|
||||
return items, total, nil
|
||||
}
|
||||
|
||||
func (s *repportService) collectProjectFlockIDs(deliveryProducts []entity.MarketingDeliveryProduct) []uint {
|
||||
projectFlockIDMap := make(map[uint]bool)
|
||||
projectFlockIDs := make([]uint, 0)
|
||||
|
||||
for _, dp := range deliveryProducts {
|
||||
if projectFlockKandang := dp.MarketingProduct.ProductWarehouse.ProjectFlockKandang; projectFlockKandang != nil {
|
||||
if projectFlockKandang.ProjectFlockId > 0 && !projectFlockIDMap[projectFlockKandang.ProjectFlockId] {
|
||||
projectFlockIDs = append(projectFlockIDs, projectFlockKandang.ProjectFlockId)
|
||||
projectFlockIDMap[projectFlockKandang.ProjectFlockId] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return projectFlockIDs
|
||||
}
|
||||
|
||||
func (s *repportService) buildHppMap(ctx context.Context, projectFlockIDs []uint, deliveryProducts []entity.MarketingDeliveryProduct) map[uint]float64 {
|
||||
hppMap := make(map[uint]float64)
|
||||
for _, projectFlockID := range projectFlockIDs {
|
||||
category := s.getProjectFlockCategory(deliveryProducts, projectFlockID)
|
||||
hppPerKg := s.calculateHppByCategory(ctx, category, projectFlockID, deliveryProducts)
|
||||
hppMap[projectFlockID] = hppPerKg
|
||||
}
|
||||
return hppMap
|
||||
}
|
||||
|
||||
func (s *repportService) calculateHppByCategory(ctx context.Context, category string, projectFlockID uint, deliveryProducts []entity.MarketingDeliveryProduct) float64 {
|
||||
switch utils.ProjectFlockCategory(category) {
|
||||
case utils.ProjectFlockCategoryGrowing:
|
||||
return s.calculateHppPricePerKg(ctx, projectFlockID, deliveryProducts)
|
||||
case utils.ProjectFlockCategoryLaying:
|
||||
return 0
|
||||
default:
|
||||
func (s *repportService) calculateHppPricePerKg(ctx context.Context, projectFlockID uint, category string) float64 {
|
||||
totalCost := s.getTotalProjectCost(ctx, projectFlockID)
|
||||
if totalCost == 0 {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *repportService) getProjectFlockCategory(deliveryProducts []entity.MarketingDeliveryProduct, projectFlockID uint) string {
|
||||
for _, dp := range deliveryProducts {
|
||||
if projectFlockKandang := dp.MarketingProduct.ProductWarehouse.ProjectFlockKandang; projectFlockKandang != nil {
|
||||
if projectFlockKandang.ProjectFlockId == projectFlockID {
|
||||
return projectFlockKandang.ProjectFlock.Category
|
||||
}
|
||||
}
|
||||
chickinQty, _ := s.ChickinRepo.GetTotalChickinQtyByProjectFlockID(ctx, projectFlockID)
|
||||
depletion, _ := s.RecordingRepo.GetTotalDepletionByProjectFlockID(ctx, projectFlockID)
|
||||
avgWeight, _ := s.RecordingRepo.GetLatestAvgWeightByProjectFlockID(ctx, projectFlockID)
|
||||
|
||||
var totalWeight float64
|
||||
if utils.ProjectFlockCategory(category) == utils.ProjectFlockCategoryGrowing {
|
||||
totalWeight = (chickinQty - depletion) * avgWeight
|
||||
} else {
|
||||
eggWeight, _ := s.RecordingRepo.GetTotalEggProductionWeightByProjectFlockID(ctx, projectFlockID)
|
||||
totalWeight = (chickinQty-depletion)*avgWeight + eggWeight
|
||||
}
|
||||
return ""
|
||||
|
||||
if totalWeight == 0 {
|
||||
return 0
|
||||
}
|
||||
return totalCost / totalWeight
|
||||
}
|
||||
|
||||
func (s *repportService) calculateHppPricePerKg(ctx context.Context, projectFlockID uint, deliveryProducts []entity.MarketingDeliveryProduct) float64 {
|
||||
func (s *repportService) getTotalProjectCost(ctx context.Context, projectFlockID uint) float64 {
|
||||
if projectFlockID == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
purchaseItems, err := s.PurchaseRepo.GetItemsByProjectFlockID(ctx, projectFlockID)
|
||||
purchases, err := s.PurchaseRepo.GetItemsByProjectFlockID(ctx, projectFlockID)
|
||||
if err != nil {
|
||||
s.Log.Warnf("GetItemsByProjectFlockID error: %v", err)
|
||||
}
|
||||
|
||||
costPurchase := float64(0)
|
||||
for _, item := range purchaseItems {
|
||||
costPurchase += item.TotalPrice
|
||||
cost := float64(0)
|
||||
for _, p := range purchases {
|
||||
cost += p.TotalPrice
|
||||
}
|
||||
|
||||
realizations, err := s.ExpenseRealizationRepo.GetByProjectFlockID(ctx, projectFlockID)
|
||||
@@ -173,34 +164,11 @@ func (s *repportService) calculateHppPricePerKg(ctx context.Context, projectFloc
|
||||
s.Log.Warnf("GetByProjectFlockID error: %v", err)
|
||||
}
|
||||
|
||||
costBop := float64(0)
|
||||
for _, realization := range realizations {
|
||||
cost := realization.Price * realization.Qty
|
||||
category := ""
|
||||
if realization.ExpenseNonstock != nil && realization.ExpenseNonstock.Expense != nil {
|
||||
category = realization.ExpenseNonstock.Expense.Category
|
||||
}
|
||||
|
||||
if category == "BOP" {
|
||||
costBop += cost
|
||||
for _, r := range realizations {
|
||||
if r.ExpenseNonstock != nil && r.ExpenseNonstock.Expense != nil &&
|
||||
r.ExpenseNonstock.Expense.Category == string(utils.ExpenseCategoryBOP) {
|
||||
cost += r.Price * r.Qty
|
||||
}
|
||||
}
|
||||
|
||||
totalActualCost := costPurchase + costBop
|
||||
|
||||
if totalActualCost == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
totalWeightProduced, _, err := s.RecordingRepo.GetProductionWeightAndQtyByProjectFlockID(ctx, projectFlockID)
|
||||
if err != nil {
|
||||
s.Log.Warnf("GetProductionWeightAndQtyByProjectFlockID error: %v", err)
|
||||
}
|
||||
|
||||
if totalWeightProduced == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
hppPerKg := totalActualCost / totalWeightProduced
|
||||
return hppPerKg
|
||||
return cost
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user