mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
381 lines
9.2 KiB
Go
381 lines
9.2 KiB
Go
package service
|
|
|
|
import (
|
|
"context"
|
|
"math"
|
|
"time"
|
|
|
|
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
|
)
|
|
|
|
type HppService interface {
|
|
CalculateHppCost(projectFlockKandangId uint, date *time.Time) (*HppCostResponse, error)
|
|
GetTotalDepresiasiFlockGrowing(sourceProjectFlockID uint, date *time.Time) (float64, error)
|
|
GetTotalProductionCost(projectFlockKandangId uint, endDate *time.Time, depresiasiTransfer float64) (float64, error)
|
|
GetBudgetKandangLaying(projectFlockKandangId uint, endDate *time.Time) (float64, error)
|
|
GetDepresiasiTransfer(projectFlockKandangId uint, date *time.Time) (float64, error)
|
|
GetHppEstimationDanRealisasi(totalProductionCost float64, projectFlockKandangId uint, startDate *time.Time, endDate *time.Time) (*HppCostResponse, error)
|
|
}
|
|
|
|
type HppCostResponse struct {
|
|
Estimation HppCostDetail `json:"estimation"`
|
|
Real HppCostDetail `json:"real"`
|
|
}
|
|
|
|
type HppCostDetail struct {
|
|
HargaKg float64 `json:"harga_kg"`
|
|
HargaButir float64 `json:"harga_butir"`
|
|
Total float64 `json:"total"`
|
|
Kg float64 `json:"kg"`
|
|
Butir float64 `json:"butir"`
|
|
}
|
|
|
|
type hppService struct {
|
|
hppRepo commonRepo.HppCostRepository
|
|
}
|
|
|
|
func NewHppService(hppRepo commonRepo.HppCostRepository) HppService {
|
|
return &hppService{hppRepo: hppRepo}
|
|
}
|
|
|
|
func (s *hppService) CalculateHppCost(projectFlockKandangId uint, date *time.Time) (*HppCostResponse, error) {
|
|
if date == nil {
|
|
now := time.Now()
|
|
date = &now
|
|
}
|
|
|
|
location, err := time.LoadLocation("Asia/Jakarta")
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
}
|
|
|
|
startOfDay := time.Date(date.Year(), date.Month(), date.Day(), 0, 0, 0, 0, location)
|
|
endOfDay := startOfDay.Add(24 * time.Hour)
|
|
|
|
depresiasiTransfer, err := s.GetDepresiasiTransfer(projectFlockKandangId, &endOfDay)
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
}
|
|
|
|
totalProductionCost, err := s.GetTotalProductionCost(projectFlockKandangId, &endOfDay, depresiasiTransfer)
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
}
|
|
result, err := s.GetHppEstimationDanRealisasi(totalProductionCost, projectFlockKandangId, &startOfDay, &endOfDay)
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (s *hppService) GetTotalDepresiasiFlockGrowing(sourceProjectFlockID uint, date *time.Time) (float64, error) {
|
|
if date == nil {
|
|
now := time.Now()
|
|
date = &now
|
|
}
|
|
|
|
if s.hppRepo == nil {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
kandangIDs, err := s.hppRepo.GetProjectFlockKandangIDs(context.Background(), sourceProjectFlockID)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
docCost, err := s.hppRepo.GetDocCost(context.Background(), kandangIDs)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
budgetCost, err := s.hppRepo.GetBudgetCostByProjectFlockId(context.Background(), sourceProjectFlockID)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
expedisionCost, err := s.hppRepo.GetExpedisionCost(context.Background(), kandangIDs)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
feedCost, err := s.hppRepo.GetFeedUsageCost(context.Background(), kandangIDs, date)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
ovkCost, err := s.hppRepo.GetOvkUsageCost(context.Background(), kandangIDs, date)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
total := docCost + budgetCost + expedisionCost + feedCost + ovkCost
|
|
return total, nil
|
|
}
|
|
|
|
func (s *hppService) GetTotalProductionCost(projectFlockKandangId uint, endDate *time.Time, depresiasiTransfer float64) (float64, error) {
|
|
// if date == nil {
|
|
// now := time.Now()
|
|
// date = &now
|
|
// }
|
|
|
|
costPullet, err := s.hppRepo.GetPulletCost(context.Background(), projectFlockKandangId)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
costFeed, err := s.hppRepo.GetFeedUsageCost(context.Background(), []uint{projectFlockKandangId}, endDate)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
costOvk, err := s.hppRepo.GetOvkUsageCost(context.Background(), []uint{projectFlockKandangId}, endDate)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
costExpedision, err := s.hppRepo.GetExpedisionCost(context.Background(), []uint{projectFlockKandangId})
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
costBudget, err := s.GetBudgetKandangLaying(projectFlockKandangId, endDate)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
// fmt.Println(costBudget, costExpedision, costOvk, costFeed, costPullet, depresiasiTransfer)
|
|
|
|
// depresiasiTransfer = 0
|
|
|
|
total := depresiasiTransfer + costPullet + costFeed + costOvk + costExpedision + costBudget
|
|
return total, nil
|
|
}
|
|
|
|
func (s *hppService) GetBudgetKandangLaying(projectFlockKandangId uint, endDate *time.Time) (float64, error) {
|
|
// if date == nil {
|
|
// now := time.Now()
|
|
// date = &now
|
|
// }
|
|
|
|
if s.hppRepo == nil {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
projectFlockId, err := s.hppRepo.GetProjectFlockIDByProjectFlockKandangID(context.Background(), projectFlockKandangId)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
projectFlockKandangIds, err := s.hppRepo.GetProjectFlockKandangIDs(context.Background(), projectFlockId)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
eggProduksiPiecesFlock, _, err := s.hppRepo.GetEggProduksiPiecesAndWeightKgByProjectFlockKandangIds(context.Background(), projectFlockKandangIds, endDate)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
eggProduksiPiecesKandang, _, err := s.hppRepo.GetEggProduksiPiecesAndWeightKgByProjectFlockKandangIds(context.Background(), []uint{projectFlockKandangId}, endDate)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
totalBudgetCost, err := s.hppRepo.GetBudgetCostByProjectFlockId(context.Background(), projectFlockId)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
|
|
if eggProduksiPiecesFlock == 0 {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
result := (totalBudgetCost * eggProduksiPiecesKandang) / eggProduksiPiecesFlock
|
|
return result, nil
|
|
}
|
|
|
|
func (s *hppService) GetDepresiasiTransfer(projectFlockKandangId uint, endDate *time.Time) (float64, error) {
|
|
if endDate == nil {
|
|
now := time.Now()
|
|
endDate = &now
|
|
}
|
|
|
|
if s.hppRepo == nil {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
sourceProjectFlockID, transferTotalQty, err := s.hppRepo.GetTransferSourceSummary(context.Background(), projectFlockKandangId)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if sourceProjectFlockID == 0 || transferTotalQty <= 0 {
|
|
result, fallbackErr := s.getManualDepresiasiTransferFallback(projectFlockKandangId)
|
|
if fallbackErr != nil {
|
|
return 0, fallbackErr
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
kandangIDsGrowing, err := s.hppRepo.GetProjectFlockKandangIDs(context.Background(), sourceProjectFlockID)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
totalPopulationFlockGrowing, err := s.hppRepo.GetTotalPopulation(context.Background(), kandangIDsGrowing)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
if totalPopulationFlockGrowing == 0 {
|
|
return 0, nil
|
|
}
|
|
|
|
totalDepresiasiFlockGrowing, err := s.GetTotalDepresiasiFlockGrowing(sourceProjectFlockID, endDate)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
result := (totalDepresiasiFlockGrowing * transferTotalQty) / totalPopulationFlockGrowing
|
|
return result, nil
|
|
}
|
|
|
|
func (s *hppService) getManualDepresiasiTransferFallback(projectFlockKandangId uint) (float64, error) {
|
|
projectFlockID, err := s.hppRepo.GetProjectFlockIDByProjectFlockKandangID(context.Background(), projectFlockKandangId)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
if projectFlockID == 0 {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
manualCost, err := s.hppRepo.GetManualDepreciationCostByProjectFlockID(context.Background(), projectFlockID)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
if manualCost <= 0 {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
kandangIDs, err := s.hppRepo.GetProjectFlockKandangIDs(context.Background(), projectFlockID)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
if len(kandangIDs) == 0 {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
totalUsageQty, err := s.hppRepo.GetTotalPopulation(context.Background(), kandangIDs)
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
if totalUsageQty <= 0 {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
kandangUsageQty, err := s.hppRepo.GetTotalPopulation(context.Background(), []uint{projectFlockKandangId})
|
|
if err != nil {
|
|
|
|
return 0, err
|
|
}
|
|
if kandangUsageQty <= 0 {
|
|
|
|
return 0, nil
|
|
}
|
|
|
|
result := manualCost * (kandangUsageQty / totalUsageQty)
|
|
return result, nil
|
|
}
|
|
|
|
func (s *hppService) GetHppEstimationDanRealisasi(totalProductionCost float64, projectFlockKandangId uint, startDate *time.Time, endDate *time.Time) (*HppCostResponse, error) {
|
|
|
|
if s.hppRepo == nil {
|
|
|
|
return &HppCostResponse{}, nil
|
|
}
|
|
|
|
estimPieces, estimWeightKg, err := s.hppRepo.GetEggProduksiPiecesAndWeightKgByProjectFlockKandangIds(context.Background(), []uint{projectFlockKandangId}, endDate)
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
}
|
|
|
|
realPieces, realWeightKg, err := s.hppRepo.GetEggTerjualPiecesAndWeightKgByProjectFlockKandangIds(context.Background(), []uint{projectFlockKandangId}, startDate, endDate)
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
}
|
|
|
|
estimation := HppCostDetail{
|
|
Total: totalProductionCost,
|
|
Kg: estimWeightKg,
|
|
Butir: estimPieces,
|
|
}
|
|
if estimWeightKg > 0 {
|
|
estimation.HargaKg = roundToTwoDecimals(totalProductionCost / estimWeightKg)
|
|
}
|
|
if estimPieces > 0 {
|
|
estimation.HargaButir = roundToTwoDecimals(totalProductionCost / estimPieces)
|
|
}
|
|
|
|
real := HppCostDetail{
|
|
Total: totalProductionCost,
|
|
Kg: realWeightKg,
|
|
Butir: realPieces,
|
|
}
|
|
if realWeightKg > 0 {
|
|
real.HargaKg = roundToTwoDecimals(totalProductionCost / realWeightKg)
|
|
}
|
|
if realPieces > 0 {
|
|
real.HargaButir = roundToTwoDecimals(totalProductionCost / realPieces)
|
|
}
|
|
|
|
result := &HppCostResponse{
|
|
Estimation: estimation,
|
|
Real: real,
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func roundToTwoDecimals(value float64) float64 {
|
|
result := math.Round(value*100) / 100
|
|
return result
|
|
}
|
|
|
|
func formatTimePtr(value *time.Time) string {
|
|
if value == nil {
|
|
return "<nil>"
|
|
}
|
|
return value.Format(time.RFC3339)
|
|
}
|