|
|
|
@@ -16,6 +16,7 @@ import (
|
|
|
|
|
expenseRealizationRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/repositories"
|
|
|
|
|
marketingDeliveryProductRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/repositories"
|
|
|
|
|
marketingRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/repositories"
|
|
|
|
|
productionStandardRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/repositories"
|
|
|
|
|
chickinRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/chickins/repositories"
|
|
|
|
|
projectflockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
|
|
|
|
recordingRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/recordings/repositories"
|
|
|
|
@@ -35,7 +36,7 @@ type ClosingService interface {
|
|
|
|
|
GetPenjualan(ctx *fiber.Ctx, projectFlockID uint) ([]entity.MarketingDeliveryProduct, error)
|
|
|
|
|
GetClosingSummary(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error)
|
|
|
|
|
GetOverhead(ctx *fiber.Ctx, projectFlockID uint) (*dto.OverheadListDTO, error)
|
|
|
|
|
GetClosingDataProduksi(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingProductionReportDTO, error)
|
|
|
|
|
GetClosingDataProduksi(ctx *fiber.Ctx, projectFlockID uint, kandangID *uint) (*dto.ClosingProductionReportDTO, error)
|
|
|
|
|
GetClosingSapronak(ctx *fiber.Ctx, projectFlockID uint, params *validation.ClosingSapronakQuery) ([]dto.ClosingSapronakItemDTO, int64, error)
|
|
|
|
|
GetClosingKeuangan(ctx *fiber.Ctx, projectFlockID uint) (*dto.ReportResponse, error)
|
|
|
|
|
GetExpeditionHPP(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) (*dto.ExpeditionHPPDTO, error)
|
|
|
|
@@ -54,9 +55,11 @@ type closingService struct {
|
|
|
|
|
ChickinRepo chickinRepository.ProjectChickinRepository
|
|
|
|
|
PurchaseRepo purchaseRepository.PurchaseRepository
|
|
|
|
|
RecordingRepo recordingRepository.RecordingRepository
|
|
|
|
|
StandardGrowthDetailRepo productionStandardRepository.StandardGrowthDetailRepository
|
|
|
|
|
ProductionStandardDetailRepo productionStandardRepository.ProductionStandardDetailRepository
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewClosingService(repo repository.ClosingRepository, projectFlockRepo projectflockRepository.ProjectflockRepository, marketingRepo marketingRepository.MarketingRepository, marketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository, approvalSvc commonSvc.ApprovalService, expenseRealizationRepo expenseRealizationRepository.ExpenseRealizationRepository, projectBudgetRepo projectflockRepository.ProjectBudgetRepository, chickinRepo chickinRepository.ProjectChickinRepository, purchaseRepo purchaseRepository.PurchaseRepository, recordingRepo recordingRepository.RecordingRepository, validate *validator.Validate) ClosingService {
|
|
|
|
|
func NewClosingService(repo repository.ClosingRepository, projectFlockRepo projectflockRepository.ProjectflockRepository, marketingRepo marketingRepository.MarketingRepository, marketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository, approvalSvc commonSvc.ApprovalService, expenseRealizationRepo expenseRealizationRepository.ExpenseRealizationRepository, projectBudgetRepo projectflockRepository.ProjectBudgetRepository, chickinRepo chickinRepository.ProjectChickinRepository, purchaseRepo purchaseRepository.PurchaseRepository, recordingRepo recordingRepository.RecordingRepository, standardGrowthDetailRepo productionStandardRepository.StandardGrowthDetailRepository, productionStandardDetailRepo productionStandardRepository.ProductionStandardDetailRepository, validate *validator.Validate) ClosingService {
|
|
|
|
|
return &closingService{
|
|
|
|
|
Log: utils.Log,
|
|
|
|
|
Validate: validate,
|
|
|
|
@@ -70,6 +73,8 @@ func NewClosingService(repo repository.ClosingRepository, projectFlockRepo proje
|
|
|
|
|
ChickinRepo: chickinRepo,
|
|
|
|
|
PurchaseRepo: purchaseRepo,
|
|
|
|
|
RecordingRepo: recordingRepo,
|
|
|
|
|
StandardGrowthDetailRepo: standardGrowthDetailRepo,
|
|
|
|
|
ProductionStandardDetailRepo: productionStandardDetailRepo,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -231,7 +236,7 @@ func (s closingService) GetClosingSapronak(c *fiber.Ctx, projectFlockID uint, pa
|
|
|
|
|
|
|
|
|
|
var projectFlockKandangIDs []uint
|
|
|
|
|
if params.Type == validation.SapronakTypeOutgoing {
|
|
|
|
|
projectFlockKandangIDs, err = s.getProjectFlockKandangIDs(c.Context(), projectFlockID)
|
|
|
|
|
projectFlockKandangIDs, err = s.getProjectFlockKandangIDs(c.Context(), projectFlockID, nil)
|
|
|
|
|
if err != nil {
|
|
|
|
|
s.Log.Errorf("Failed to fetch project flock kandang IDs for project flock %d: %+v", projectFlockID, err)
|
|
|
|
|
return nil, 0, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock kandang")
|
|
|
|
@@ -311,12 +316,15 @@ func (s closingService) getWarehouseIDsByProjectFlock(ctx context.Context, proje
|
|
|
|
|
return ids, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s closingService) getProjectFlockKandangIDs(ctx context.Context, projectFlockID uint) ([]uint, error) {
|
|
|
|
|
func (s closingService) getProjectFlockKandangIDs(ctx context.Context, projectFlockID uint, kandangID *uint) ([]uint, error) {
|
|
|
|
|
var ids []uint
|
|
|
|
|
err := s.Repository.DB().WithContext(ctx).
|
|
|
|
|
query := s.Repository.DB().WithContext(ctx).
|
|
|
|
|
Model(&entity.ProjectFlockKandang{}).
|
|
|
|
|
Where("project_flock_id = ?", projectFlockID).
|
|
|
|
|
Pluck("id", &ids).Error
|
|
|
|
|
Where("project_flock_id = ?", projectFlockID)
|
|
|
|
|
if kandangID != nil {
|
|
|
|
|
query = query.Where("kandang_id = ?", *kandangID)
|
|
|
|
|
}
|
|
|
|
|
err := query.Order("id ASC").Pluck("id", &ids).Error
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
@@ -520,12 +528,22 @@ func (s closingService) GetExpeditionHPP(c *fiber.Ctx, projectFlockID uint, proj
|
|
|
|
|
return result, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint) (*dto.ClosingProductionReportDTO, error) {
|
|
|
|
|
func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint, kandangID *uint) (*dto.ClosingProductionReportDTO, error) {
|
|
|
|
|
if projectFlockID == 0 {
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid project flock id")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project, err := s.Repository.GetByID(c.Context(), projectFlockID, s.withClosingRelations)
|
|
|
|
|
projectFlockKandangIDs, err := s.getProjectFlockKandangIDs(c.Context(), projectFlockID, kandangID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
s.Log.Errorf("Failed to fetch project flock kandangs for %d: %+v", projectFlockID, err)
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock kandangs")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(projectFlockKandangIDs) == 0 {
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusNotFound, "No project flock kandang found")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
project, err := s.Repository.GetByID(c.Context(), projectFlockID, s.withRelations)
|
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock not found")
|
|
|
|
|
}
|
|
|
|
@@ -534,19 +552,29 @@ func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var population float64
|
|
|
|
|
for _, history := range project.KandangHistory {
|
|
|
|
|
for _, chickin := range history.Chickins {
|
|
|
|
|
population += chickin.UsageQty
|
|
|
|
|
}
|
|
|
|
|
population, err := s.Repository.SumProjectChickinUsageByProjectFlockKandangIDs(c.Context(), projectFlockKandangIDs)
|
|
|
|
|
if err != nil {
|
|
|
|
|
s.Log.Errorf("Failed to sum population for project flock %d: %+v", projectFlockID, err)
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch population data")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
isGrowing := strings.EqualFold(project.Category, string(utils.ProjectFlockCategoryGrowing))
|
|
|
|
|
|
|
|
|
|
projectFlockKandangIDs, err := s.getProjectFlockKandangIDs(c.Context(), projectFlockID)
|
|
|
|
|
currentWeek, err := s.determineProductionWeek(c.Context(), projectFlockKandangIDs)
|
|
|
|
|
if err != nil {
|
|
|
|
|
s.Log.Errorf("Failed to fetch project flock kandangs for %d: %+v", projectFlockID, err)
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock kandangs")
|
|
|
|
|
s.Log.Errorf("Failed to determine production week for project flock %d: %+v", projectFlockID, err)
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to determine production week")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
targetAverages, err := s.RecordingRepo.GetAverageTargetMetricsByProjectFlockKandangID(c.Context(), projectFlockKandangIDs[0], !isGrowing)
|
|
|
|
|
if err != nil {
|
|
|
|
|
s.Log.Errorf("Failed to calculate target metrics for project flock %d: %+v", projectFlockID, err)
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch target metrics data")
|
|
|
|
|
}
|
|
|
|
|
var fcrActFromRecording *float64
|
|
|
|
|
if targetAverages.FcrCount > 0 {
|
|
|
|
|
fcrAvg := targetAverages.FcrAvg
|
|
|
|
|
fcrActFromRecording = &fcrAvg
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
feedIn, feedUsed, err := s.Repository.SumFeedPurchaseAndUsedByProjectFlockKandangIDs(c.Context(), projectFlockKandangIDs)
|
|
|
|
@@ -555,6 +583,30 @@ func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch feed purchase data")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
averageFeedIntake := targetAverages.FeedIntakeAvg
|
|
|
|
|
|
|
|
|
|
feedIntakeStd := 0.0
|
|
|
|
|
if project.ProductionStandardId > 0 && currentWeek > 0 && s.StandardGrowthDetailRepo != nil {
|
|
|
|
|
feedIntakeStd, err = s.calculateFeedIntakeStd(c.Context(), project.ProductionStandardId, currentWeek)
|
|
|
|
|
if err != nil {
|
|
|
|
|
s.Log.Errorf("Failed to compute feed intake std for project flock %d: %+v", projectFlockID, err)
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch feed intake standard data")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var productionStandardDetail *entity.ProductionStandardDetail
|
|
|
|
|
if project.ProductionStandardId > 0 && currentWeek > 0 && s.ProductionStandardDetailRepo != nil {
|
|
|
|
|
productionStandardDetail, err = s.ProductionStandardDetailRepo.GetByStandardIDAndWeek(c.Context(), project.ProductionStandardId, currentWeek)
|
|
|
|
|
if err != nil {
|
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
|
productionStandardDetail = nil
|
|
|
|
|
} else {
|
|
|
|
|
s.Log.Errorf("Failed to fetch production standard detail for project flock %d: %+v", projectFlockID, err)
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch production standard detail data")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
claimCulling, err := s.Repository.SumClaimCullingByProjectFlockKandangIDs(c.Context(), projectFlockKandangIDs)
|
|
|
|
|
if err != nil {
|
|
|
|
|
s.Log.Errorf("Failed to sum claim culling for project flock %d: %+v", projectFlockID, err)
|
|
|
|
@@ -577,10 +629,10 @@ func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint
|
|
|
|
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch sales age data")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
feedUsedPerHead := 0.0
|
|
|
|
|
if population > 0 {
|
|
|
|
|
feedUsedPerHead = feedUsed / population
|
|
|
|
|
}
|
|
|
|
|
// feedUsedPerHead := 0.0
|
|
|
|
|
// if population > 0 {
|
|
|
|
|
// feedUsedPerHead = feedUsed / population
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
purchase := dto.ClosingPurchaseDTO{
|
|
|
|
|
InitialPopulation: int(population),
|
|
|
|
@@ -588,7 +640,7 @@ func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint
|
|
|
|
|
FinalPopulation: int(finalPopulation),
|
|
|
|
|
FeedIn: feedIn,
|
|
|
|
|
FeedUsed: feedUsed,
|
|
|
|
|
FeedUsedPerHead: feedUsedPerHead,
|
|
|
|
|
// FeedUsedPerHead: feedUsedPerHead,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chickenFlagNames := []string{string(utils.FlagPullet)}
|
|
|
|
@@ -621,6 +673,9 @@ func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
chickenPerformance := calculatePerformanceMetrics(chickenAverageWeight, chickenSalesWeight, feedUsed, population, chickenDepletion, age, standards)
|
|
|
|
|
if fcrActFromRecording != nil {
|
|
|
|
|
chickenPerformance.FcrAct = *fcrActFromRecording
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var eggSales *dto.ClosingEggSalesDTO
|
|
|
|
|
var eggPerformance *dto.ClosingPerformanceDTO
|
|
|
|
@@ -668,6 +723,9 @@ func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eggPerf := calculatePerformanceMetrics(averageEggWeight, eggSalesWeight, feedUsed, harvestEggQty, eggDepletion, age, standards)
|
|
|
|
|
if fcrActFromRecording != nil {
|
|
|
|
|
eggPerf.FcrAct = *fcrActFromRecording
|
|
|
|
|
}
|
|
|
|
|
eggPerformance = &eggPerf
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -684,15 +742,55 @@ func (s closingService) GetClosingDataProduksi(c *fiber.Ctx, projectFlockID uint
|
|
|
|
|
DeffMortality: chickenPerformance.DeffMortality,
|
|
|
|
|
}
|
|
|
|
|
if eggPerformance != nil {
|
|
|
|
|
performance.FcrStd = eggPerformance.FcrStd
|
|
|
|
|
// performance.FcrStd = eggPerformance.FcrStd
|
|
|
|
|
performance.FcrAct = eggPerformance.FcrAct
|
|
|
|
|
performance.DeffFcr = eggPerformance.DeffFcr
|
|
|
|
|
performance.Awg = eggPerformance.Awg
|
|
|
|
|
// performance.DeffFcr = eggPerformance.DeffFcr
|
|
|
|
|
performance.AwgAct = eggPerformance.AwgAct
|
|
|
|
|
} else {
|
|
|
|
|
performance.FcrStd = chickenPerformance.FcrStd
|
|
|
|
|
// performance.FcrStd = chickenPerformance.FcrStd
|
|
|
|
|
performance.FcrAct = chickenPerformance.FcrAct
|
|
|
|
|
performance.DeffFcr = chickenPerformance.DeffFcr
|
|
|
|
|
performance.Awg = chickenPerformance.Awg
|
|
|
|
|
// performance.DeffFcr = chickenPerformance.DeffFcr
|
|
|
|
|
performance.AwgAct = chickenPerformance.AwgAct
|
|
|
|
|
}
|
|
|
|
|
performance.FeedIntake = averageFeedIntake
|
|
|
|
|
performance.FeedIntakeStd = feedIntakeStd
|
|
|
|
|
if !isGrowing {
|
|
|
|
|
if targetAverages.HenDayCount > 0 {
|
|
|
|
|
henDayAct := targetAverages.HenDayAvg
|
|
|
|
|
performance.HenDayAct = &henDayAct
|
|
|
|
|
}
|
|
|
|
|
if targetAverages.HenHouseCount > 0 {
|
|
|
|
|
henHouseAct := targetAverages.HenHouseAvg
|
|
|
|
|
performance.HenHouseAct = &henHouseAct
|
|
|
|
|
}
|
|
|
|
|
if targetAverages.EggWeightCount > 0 {
|
|
|
|
|
eggWeight := targetAverages.EggWeightAvg
|
|
|
|
|
performance.EggWeight = &eggWeight
|
|
|
|
|
}
|
|
|
|
|
if targetAverages.EggMassCount > 0 {
|
|
|
|
|
eggMass := targetAverages.EggMassAvg
|
|
|
|
|
performance.EggMass = &eggMass
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
performance.DeffFcr = performance.FcrStd - performance.FcrAct
|
|
|
|
|
if productionStandardDetail != nil {
|
|
|
|
|
if productionStandardDetail.StandardFCR != nil {
|
|
|
|
|
performance.FcrStd = *productionStandardDetail.StandardFCR
|
|
|
|
|
}
|
|
|
|
|
if !isGrowing {
|
|
|
|
|
if productionStandardDetail.TargetHenDayProduction != nil {
|
|
|
|
|
performance.HendayStd = productionStandardDetail.TargetHenDayProduction
|
|
|
|
|
}
|
|
|
|
|
if productionStandardDetail.TargetHenHouseProduction != nil {
|
|
|
|
|
performance.HenHouseStd = productionStandardDetail.TargetHenHouseProduction
|
|
|
|
|
}
|
|
|
|
|
if productionStandardDetail.TargetEggWeight != nil {
|
|
|
|
|
performance.EggWeightStd = productionStandardDetail.TargetEggWeight
|
|
|
|
|
}
|
|
|
|
|
if productionStandardDetail.TargetEggMass != nil {
|
|
|
|
|
performance.EggMassStd = productionStandardDetail.TargetEggMass
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
result := dto.ClosingProductionReportDTO{
|
|
|
|
@@ -738,6 +836,64 @@ func (s closingService) calculateAverageSalesAge(ctx context.Context, projectFlo
|
|
|
|
|
return totalAgeWeeks / totalQty, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s closingService) determineProductionWeek(ctx context.Context, projectFlockKandangIDs []uint) (int, error) {
|
|
|
|
|
if len(projectFlockKandangIDs) == 0 {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
firstKandangID := projectFlockKandangIDs[0]
|
|
|
|
|
|
|
|
|
|
var chickin entity.ProjectChickin
|
|
|
|
|
if err := s.Repository.DB().WithContext(ctx).
|
|
|
|
|
Where("project_flock_kandang_id = ?", firstKandangID).
|
|
|
|
|
Order("chick_in_date ASC").
|
|
|
|
|
First(&chickin).Error; err != nil {
|
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recording, err := s.RecordingRepo.GetLatestByProjectFlockKandangID(ctx, firstKandangID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
if recording == nil {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if recording.RecordDatetime.Before(chickin.ChickInDate) {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
elapsed := recording.RecordDatetime.Sub(chickin.ChickInDate)
|
|
|
|
|
weekFloat := elapsed.Hours() / (24 * 7)
|
|
|
|
|
week := int(math.Ceil(weekFloat))
|
|
|
|
|
if week <= 0 {
|
|
|
|
|
week = 1
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return week, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (s closingService) calculateFeedIntakeStd(ctx context.Context, productionStandardID uint, week int) (float64, error) {
|
|
|
|
|
if productionStandardID == 0 || week <= 0 || s.StandardGrowthDetailRepo == nil {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
detail, err := s.StandardGrowthDetailRepo.GetByStandardIDAndWeek(ctx, productionStandardID, week)
|
|
|
|
|
if err != nil {
|
|
|
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
return 0, err
|
|
|
|
|
}
|
|
|
|
|
if detail == nil || detail.FeedIntake == nil {
|
|
|
|
|
return 0, nil
|
|
|
|
|
}
|
|
|
|
|
return *detail.FeedIntake, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func calculatePerformanceMetrics(averageWeight, totalWeight, feedUsed, basePopulation, depletion, age float64, standards []entity.FcrStandard) dto.ClosingPerformanceDTO {
|
|
|
|
|
mortalityStd, fcrStd := closestFcrValues(standards, averageWeight)
|
|
|
|
|
|
|
|
|
@@ -768,7 +924,7 @@ func calculatePerformanceMetrics(averageWeight, totalWeight, feedUsed, basePopul
|
|
|
|
|
FcrStd: fcrStd,
|
|
|
|
|
FcrAct: fcrAct,
|
|
|
|
|
DeffFcr: deffFcr,
|
|
|
|
|
Awg: awg,
|
|
|
|
|
AwgAct: awg,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|