mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
feat[BE]: membetulkan perhitungan hpp di module penjualan harian
This commit is contained in:
@@ -96,28 +96,8 @@ func (c *RepportController) GetMarketing(ctx *fiber.Ctx) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Calculate total summary from result items
|
||||
var total *dto.Summary
|
||||
if len(result) > 0 {
|
||||
totalQty := 0
|
||||
totalWeightKg := 0.0
|
||||
totalSalesAmount := int64(0)
|
||||
totalHppAmount := int64(0)
|
||||
|
||||
for _, item := range result {
|
||||
totalQty += int(item.Qty)
|
||||
totalWeightKg += item.TotalWeightKg
|
||||
totalSalesAmount += int64(item.SalesAmount)
|
||||
totalHppAmount += int64(item.HppAmount)
|
||||
}
|
||||
|
||||
total = &dto.Summary{
|
||||
TotalQty: totalQty,
|
||||
TotalWeightKg: totalWeightKg,
|
||||
TotalSalesAmount: totalSalesAmount,
|
||||
TotalHppAmount: totalHppAmount,
|
||||
}
|
||||
}
|
||||
|
||||
total := dto.ToSummaryFromDTOItems(result)
|
||||
|
||||
return ctx.Status(fiber.StatusOK).
|
||||
JSON(MarketingReportResponse{
|
||||
|
||||
@@ -50,7 +50,7 @@ func ToRepportMarketingItemDTO(mdp entity.MarketingDeliveryProduct, hppPricePerK
|
||||
agingDays := 0
|
||||
if mdp.MarketingProduct.Marketing.SoDate.Year() > 1 {
|
||||
soDate = mdp.MarketingProduct.Marketing.SoDate
|
||||
agingDays = int(time.Now().Sub(soDate).Hours() / 24)
|
||||
agingDays = int(time.Since(soDate).Hours() / 24)
|
||||
}
|
||||
|
||||
realizationDate := time.Time{}
|
||||
@@ -113,6 +113,20 @@ func ToRepportMarketingItemDTOs(mdps []entity.MarketingDeliveryProduct, hppPrice
|
||||
return items
|
||||
}
|
||||
|
||||
func ToRepportMarketingItemDTOsWithHppMap(mdps []entity.MarketingDeliveryProduct, hppMap map[uint]float64) []RepportMarketingItemDTO {
|
||||
items := make([]RepportMarketingItemDTO, 0, len(mdps))
|
||||
for _, mdp := range mdps {
|
||||
hppPerKg := float64(0)
|
||||
if projectFlockKandang := mdp.MarketingProduct.ProductWarehouse.ProjectFlockKandang; projectFlockKandang != nil {
|
||||
if hpp, exists := hppMap[projectFlockKandang.ProjectFlockId]; exists {
|
||||
hppPerKg = hpp
|
||||
}
|
||||
}
|
||||
items = append(items, ToRepportMarketingItemDTO(mdp, hppPerKg))
|
||||
}
|
||||
return items
|
||||
}
|
||||
|
||||
func ToSummary(mdps []entity.MarketingDeliveryProduct, hppPricePerKg float64) *Summary {
|
||||
if len(mdps) == 0 {
|
||||
return nil
|
||||
@@ -153,6 +167,37 @@ func generateDoNumber(soNumber string, deliveryDate *time.Time, warehouseId uint
|
||||
return fmt.Sprintf("%s-%s-%d", soNumber, dateStr, warehouseId)
|
||||
}
|
||||
|
||||
func ToSummaryFromDTOItems(items []RepportMarketingItemDTO) *Summary {
|
||||
if len(items) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
totalQty := 0
|
||||
totalWeightKg := 0.0
|
||||
totalSalesAmount := int64(0)
|
||||
totalHppAmount := int64(0)
|
||||
|
||||
for _, item := range items {
|
||||
totalQty += int(item.Qty)
|
||||
totalWeightKg += item.TotalWeightKg
|
||||
totalSalesAmount += int64(item.SalesAmount)
|
||||
totalHppAmount += int64(item.HppAmount)
|
||||
}
|
||||
|
||||
totalHppPricePerKg := float64(0)
|
||||
if totalWeightKg > 0 {
|
||||
totalHppPricePerKg = float64(totalHppAmount) / totalWeightKg
|
||||
}
|
||||
|
||||
return &Summary{
|
||||
TotalQty: totalQty,
|
||||
TotalWeightKg: totalWeightKg,
|
||||
TotalSalesAmount: totalSalesAmount,
|
||||
TotalHppAmount: totalHppAmount,
|
||||
TotalHppPricePerKg: totalHppPricePerKg,
|
||||
}
|
||||
}
|
||||
|
||||
func ToRepportMarketingResponseDTO(mdps []entity.MarketingDeliveryProduct, hppPricePerKg float64) RepportMarketingResponseDTO {
|
||||
items := ToRepportMarketingItemDTOs(mdps, hppPricePerKg)
|
||||
total := ToSummary(mdps, hppPricePerKg)
|
||||
|
||||
@@ -11,6 +11,8 @@ import (
|
||||
|
||||
expenseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/repositories"
|
||||
marketingRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/repositories"
|
||||
recordingRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/repositories"
|
||||
purchaseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/repositories"
|
||||
)
|
||||
|
||||
type RepportModule struct{}
|
||||
@@ -19,10 +21,12 @@ func (RepportModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *
|
||||
|
||||
expenseRealizationRepository := expenseRepo.NewExpenseRealizationRepository(db)
|
||||
marketingDeliveryProductRepository := marketingRepo.NewMarketingDeliveryProductRepository(db)
|
||||
purchaseRepository := purchaseRepo.NewPurchaseRepository(db)
|
||||
recordingRepository := recordingRepo.NewRecordingRepository(db)
|
||||
approvalRepository := commonRepo.NewApprovalRepository(db)
|
||||
|
||||
approvalSvc := approvalService.NewApprovalService(approvalRepository)
|
||||
repportService := sRepport.NewRepportService(validate, expenseRealizationRepository, marketingDeliveryProductRepository, approvalSvc)
|
||||
repportService := sRepport.NewRepportService(validate, expenseRealizationRepository, marketingDeliveryProductRepository, purchaseRepository, recordingRepository, approvalSvc)
|
||||
|
||||
RepportRoutes(router, repportService)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@ 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"
|
||||
recordingRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/repositories"
|
||||
purchaseRepo "gitlab.com/mbugroup/lti-api.git/internal/modules/purchases/repositories"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
@@ -29,15 +31,19 @@ type repportService struct {
|
||||
Validate *validator.Validate
|
||||
ExpenseRealizationRepo expenseRepo.ExpenseRealizationRepository
|
||||
MarketingDeliveryRepo marketingRepo.MarketingDeliveryProductRepository
|
||||
PurchaseRepo purchaseRepo.PurchaseRepository
|
||||
RecordingRepo recordingRepo.RecordingRepository
|
||||
ApprovalSvc approvalService.ApprovalService
|
||||
}
|
||||
|
||||
func NewRepportService(validate *validator.Validate, expenseRealizationRepo expenseRepo.ExpenseRealizationRepository, marketingDeliveryRepo marketingRepo.MarketingDeliveryProductRepository, approvalSvc approvalService.ApprovalService) RepportService {
|
||||
func NewRepportService(validate *validator.Validate, expenseRealizationRepo expenseRepo.ExpenseRealizationRepository, marketingDeliveryRepo marketingRepo.MarketingDeliveryProductRepository, purchaseRepo purchaseRepo.PurchaseRepository, recordingRepo recordingRepo.RecordingRepository, approvalSvc approvalService.ApprovalService) RepportService {
|
||||
return &repportService{
|
||||
Log: utils.Log,
|
||||
Validate: validate,
|
||||
ExpenseRealizationRepo: expenseRealizationRepo,
|
||||
MarketingDeliveryRepo: marketingDeliveryRepo,
|
||||
PurchaseRepo: purchaseRepo,
|
||||
RecordingRepo: recordingRepo,
|
||||
ApprovalSvc: approvalSvc,
|
||||
}
|
||||
}
|
||||
@@ -94,7 +100,7 @@ func (s *repportService) GetMarketing(c *fiber.Ctx, params *validation.Marketing
|
||||
|
||||
projectFlockIDs := s.collectProjectFlockIDs(deliveryProducts)
|
||||
hppMap := s.buildHppMap(c.Context(), projectFlockIDs, deliveryProducts)
|
||||
items := s.mapDeliveryProductsToDTOs(deliveryProducts, hppMap)
|
||||
items := dto.ToRepportMarketingItemDTOsWithHppMap(deliveryProducts, hppMap)
|
||||
|
||||
return items, total, nil
|
||||
}
|
||||
@@ -118,24 +124,33 @@ func (s *repportService) collectProjectFlockIDs(deliveryProducts []entity.Market
|
||||
func (s *repportService) buildHppMap(ctx context.Context, projectFlockIDs []uint, deliveryProducts []entity.MarketingDeliveryProduct) map[uint]float64 {
|
||||
hppMap := make(map[uint]float64)
|
||||
for _, projectFlockID := range projectFlockIDs {
|
||||
hppPerKg := s.calculateHppPricePerKg(ctx, projectFlockID, deliveryProducts)
|
||||
category := s.getProjectFlockCategory(deliveryProducts, projectFlockID)
|
||||
hppPerKg := s.calculateHppByCategory(ctx, category, projectFlockID, deliveryProducts)
|
||||
hppMap[projectFlockID] = hppPerKg
|
||||
}
|
||||
return hppMap
|
||||
}
|
||||
|
||||
func (s *repportService) mapDeliveryProductsToDTOs(deliveryProducts []entity.MarketingDeliveryProduct, hppMap map[uint]float64) []dto.RepportMarketingItemDTO {
|
||||
items := make([]dto.RepportMarketingItemDTO, 0, len(deliveryProducts))
|
||||
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:
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
func (s *repportService) getProjectFlockCategory(deliveryProducts []entity.MarketingDeliveryProduct, projectFlockID uint) string {
|
||||
for _, dp := range deliveryProducts {
|
||||
hppPerKg := float64(0)
|
||||
if projectFlockKandang := dp.MarketingProduct.ProductWarehouse.ProjectFlockKandang; projectFlockKandang != nil {
|
||||
if hpp, exists := hppMap[projectFlockKandang.ProjectFlockId]; exists {
|
||||
hppPerKg = hpp
|
||||
if projectFlockKandang.ProjectFlockId == projectFlockID {
|
||||
return projectFlockKandang.ProjectFlock.Category
|
||||
}
|
||||
}
|
||||
items = append(items, dto.ToRepportMarketingItemDTO(dp, hppPerKg))
|
||||
}
|
||||
return items
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *repportService) calculateHppPricePerKg(ctx context.Context, projectFlockID uint, deliveryProducts []entity.MarketingDeliveryProduct) float64 {
|
||||
@@ -143,17 +158,22 @@ func (s *repportService) calculateHppPricePerKg(ctx context.Context, projectFloc
|
||||
return 0
|
||||
}
|
||||
|
||||
realizations, err := s.ExpenseRealizationRepo.GetByProjectFlockID(ctx, projectFlockID)
|
||||
purchaseItems, err := s.PurchaseRepo.GetItemsByProjectFlockID(ctx, projectFlockID)
|
||||
if err != nil {
|
||||
return 0
|
||||
s.Log.Warnf("GetItemsByProjectFlockID error: %v", err)
|
||||
}
|
||||
|
||||
if len(realizations) == 0 {
|
||||
return 0
|
||||
costPurchase := float64(0)
|
||||
for _, item := range purchaseItems {
|
||||
costPurchase += item.TotalPrice
|
||||
}
|
||||
|
||||
realizations, err := s.ExpenseRealizationRepo.GetByProjectFlockID(ctx, projectFlockID)
|
||||
if err != nil {
|
||||
s.Log.Warnf("GetByProjectFlockID error: %v", err)
|
||||
}
|
||||
|
||||
costBop := float64(0)
|
||||
|
||||
for _, realization := range realizations {
|
||||
cost := realization.Price * realization.Qty
|
||||
category := ""
|
||||
@@ -166,24 +186,21 @@ func (s *repportService) calculateHppPricePerKg(ctx context.Context, projectFloc
|
||||
}
|
||||
}
|
||||
|
||||
totalActualCost := costBop
|
||||
totalActualCost := costPurchase + costBop
|
||||
|
||||
if totalActualCost == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
totalWeightSold := float64(0)
|
||||
for _, dp := range deliveryProducts {
|
||||
if dp.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil &&
|
||||
dp.MarketingProduct.ProductWarehouse.ProjectFlockKandang.ProjectFlockId == projectFlockID {
|
||||
totalWeightSold += dp.TotalWeight
|
||||
}
|
||||
totalWeightProduced, _, err := s.RecordingRepo.GetProductionWeightAndQtyByProjectFlockID(ctx, projectFlockID)
|
||||
if err != nil {
|
||||
s.Log.Warnf("GetProductionWeightAndQtyByProjectFlockID error: %v", err)
|
||||
}
|
||||
|
||||
if totalWeightSold == 0 {
|
||||
if totalWeightProduced == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
hppPerKg := totalActualCost / totalWeightSold
|
||||
hppPerKg := totalActualCost / totalWeightProduced
|
||||
return hppPerKg
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user