feat(BE-281): adjustment recording table with handhouse and deleting weight unfinished dto:standart fcr,hand house and others

This commit is contained in:
ragilap
2025-12-29 16:25:08 +07:00
parent 411d6fe6a9
commit 8e7e976946
7 changed files with 165 additions and 158 deletions
@@ -44,7 +44,6 @@ ALTER TABLE recording_eggs
DROP CONSTRAINT IF EXISTS chk_recording_eggs_qty; DROP CONSTRAINT IF EXISTS chk_recording_eggs_qty;
ALTER TABLE recording_eggs ALTER TABLE recording_eggs
DROP COLUMN IF EXISTS fcr_value,
ALTER COLUMN weight TYPE NUMERIC(10,3) USING weight::NUMERIC(10,3); ALTER COLUMN weight TYPE NUMERIC(10,3) USING weight::NUMERIC(10,3);
ALTER TABLE recording_eggs ALTER TABLE recording_eggs
@@ -27,7 +27,6 @@ ALTER TABLE recordings
); );
ALTER TABLE recording_eggs ALTER TABLE recording_eggs
ADD COLUMN IF NOT EXISTS fcr_value NUMERIC(15,3),
ALTER COLUMN weight TYPE NUMERIC(15,3) USING weight::NUMERIC(15,3); ALTER COLUMN weight TYPE NUMERIC(15,3) USING weight::NUMERIC(15,3);
ALTER TABLE recording_eggs ALTER TABLE recording_eggs
@@ -36,8 +35,7 @@ ALTER TABLE recording_eggs
ALTER TABLE recording_eggs ALTER TABLE recording_eggs
ADD CONSTRAINT chk_recording_eggs_qty CHECK ( ADD CONSTRAINT chk_recording_eggs_qty CHECK (
qty >= 0 AND qty >= 0 AND
(weight IS NULL OR weight >= 0) AND (weight IS NULL OR weight >= 0)
(fcr_value IS NULL OR fcr_value >= 0)
); );
DROP INDEX IF EXISTS idx_recording_bws_recording; DROP INDEX IF EXISTS idx_recording_bws_recording;
+5 -2
View File
@@ -13,11 +13,14 @@ type Recording struct {
Day *int `gorm:"column:day"` Day *int `gorm:"column:day"`
TotalDepletionQty *float64 `gorm:"column:total_depletion_qty"` TotalDepletionQty *float64 `gorm:"column:total_depletion_qty"`
CumDepletionRate *float64 `gorm:"column:cum_depletion_rate"` CumDepletionRate *float64 `gorm:"column:cum_depletion_rate"`
DailyGain *float64 `gorm:"column:daily_gain"`
AvgDailyGain *float64 `gorm:"column:avg_daily_gain"`
CumIntake *int `gorm:"column:cum_intake"` CumIntake *int `gorm:"column:cum_intake"`
FcrValue *float64 `gorm:"column:fcr_value"` FcrValue *float64 `gorm:"column:fcr_value"`
TotalChickQty *float64 `gorm:"column:total_chick_qty"` TotalChickQty *float64 `gorm:"column:total_chick_qty"`
HandDay *float64 `gorm:"column:hand_day"`
HandHouse *float64 `gorm:"column:hand_house"`
FeedIntake *float64 `gorm:"column:feed_intake"`
EggMesh *float64 `gorm:"column:egg_mesh"`
EggWeight *float64 `gorm:"column:egg_weight"`
CreatedBy uint `gorm:"column:created_by"` CreatedBy uint `gorm:"column:created_by"`
CreatedAt time.Time `gorm:"autoCreateTime"` CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"` UpdatedAt time.Time `gorm:"autoUpdateTime"`
-15
View File
@@ -1,15 +0,0 @@
package entities
import "time"
type RecordingBW struct {
Id uint `gorm:"primaryKey"`
RecordingId uint `gorm:"column:recording_id;not null;index"`
AvgWeight float64 `gorm:"column:avg_weight;not null"`
Qty float64 `gorm:"column:qty;not null"`
TotalWeight float64 `gorm:"column:total_weight;not null"`
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
Recording Recording `gorm:"foreignKey:RecordingId;references:Id"`
}
@@ -22,11 +22,14 @@ type RecordingRelationDTO struct {
ProjectFlockCategory string `json:"project_flock_category"` ProjectFlockCategory string `json:"project_flock_category"`
TotalDepletionQty float64 `json:"total_depletion_qty"` TotalDepletionQty float64 `json:"total_depletion_qty"`
CumDepletionRate float64 `json:"cum_depletion_rate"` CumDepletionRate float64 `json:"cum_depletion_rate"`
DailyGain float64 `json:"daily_gain"`
AvgDailyGain float64 `json:"avg_daily_gain"`
CumIntake int `json:"cum_intake"` CumIntake int `json:"cum_intake"`
FcrValue float64 `json:"fcr_value"` FcrValue float64 `json:"fcr_value"`
TotalChickQty float64 `json:"total_chick_qty"` TotalChickQty float64 `json:"total_chick_qty"`
HandDay float64 `json:"hand_day"`
HandHouse float64 `json:"hand_house"`
FeedIntake float64 `json:"feed_intake"`
EggMesh float64 `json:"egg_mesh"`
EggWeight float64 `json:"egg_weight"`
Approval approvalDTO.ApprovalRelationDTO `json:"approval"` Approval approvalDTO.ApprovalRelationDTO `json:"approval"`
} }
@@ -39,9 +42,9 @@ type RecordingListDTO struct {
type RecordingDetailDTO struct { type RecordingDetailDTO struct {
RecordingListDTO RecordingListDTO
Depletions []RecordingDepletionDTO `json:"depletions"` Depletions []RecordingDepletionDTO `json:"depletions"`
Stocks []RecordingStockDTO `json:"stocks"` Stocks []RecordingStockDTO `json:"stocks"`
Eggs []RecordingEggDTO `json:"eggs"` Eggs []RecordingEggDTO `json:"eggs"`
} }
type RecordingDepletionDTO struct { type RecordingDepletionDTO struct {
@@ -81,11 +84,14 @@ func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO {
day int day int
totalDepletionQty float64 totalDepletionQty float64
cumDepletionRate float64 cumDepletionRate float64
dailyGain float64
avgDailyGain float64
cumIntake int cumIntake int
fcrValue float64 fcrValue float64
totalChickQty float64 totalChickQty float64
handDay float64
handHouse float64
feedIntake float64
eggMesh float64
eggWeight float64
) )
if e.Day != nil { if e.Day != nil {
@@ -97,12 +103,6 @@ func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO {
if e.CumDepletionRate != nil { if e.CumDepletionRate != nil {
cumDepletionRate = *e.CumDepletionRate cumDepletionRate = *e.CumDepletionRate
} }
if e.DailyGain != nil {
dailyGain = *e.DailyGain
}
if e.AvgDailyGain != nil {
avgDailyGain = *e.AvgDailyGain
}
if e.CumIntake != nil { if e.CumIntake != nil {
cumIntake = *e.CumIntake cumIntake = *e.CumIntake
} }
@@ -112,6 +112,21 @@ func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO {
if e.TotalChickQty != nil { if e.TotalChickQty != nil {
totalChickQty = *e.TotalChickQty totalChickQty = *e.TotalChickQty
} }
if e.HandDay != nil {
handDay = *e.HandDay
}
if e.HandHouse != nil {
handHouse = *e.HandHouse
}
if e.FeedIntake != nil {
feedIntake = *e.FeedIntake
}
if e.EggMesh != nil {
eggMesh = *e.EggMesh
}
if e.EggWeight != nil {
eggWeight = *e.EggWeight
}
if e.ProjectFlockKandang != nil && e.ProjectFlockKandang.ProjectFlock.Id != 0 { if e.ProjectFlockKandang != nil && e.ProjectFlockKandang.ProjectFlock.Id != 0 {
category := e.ProjectFlockKandang.ProjectFlock.Category category := e.ProjectFlockKandang.ProjectFlock.Category
@@ -132,11 +147,14 @@ func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO {
ProjectFlockCategory: projectFlockCategory, ProjectFlockCategory: projectFlockCategory,
TotalDepletionQty: totalDepletionQty, TotalDepletionQty: totalDepletionQty,
CumDepletionRate: cumDepletionRate, CumDepletionRate: cumDepletionRate,
DailyGain: dailyGain,
AvgDailyGain: avgDailyGain,
CumIntake: cumIntake, CumIntake: cumIntake,
FcrValue: fcrValue, FcrValue: fcrValue,
TotalChickQty: totalChickQty, TotalChickQty: totalChickQty,
HandDay: handDay,
HandHouse: handHouse,
FeedIntake: feedIntake,
EggMesh: eggMesh,
EggWeight: eggWeight,
Approval: latestApproval, Approval: latestApproval,
} }
} }
@@ -19,9 +19,6 @@ type RecordingRepository interface {
WithRelations(db *gorm.DB) *gorm.DB WithRelations(db *gorm.DB) *gorm.DB
GenerateNextDay(tx *gorm.DB, projectFlockKandangId uint) (int, error) GenerateNextDay(tx *gorm.DB, projectFlockKandangId uint) (int, error)
CreateBodyWeights(tx *gorm.DB, bodyWeights []entity.RecordingBW) error
DeleteBodyWeights(tx *gorm.DB, recordingID uint) error
CreateStocks(tx *gorm.DB, stocks []entity.RecordingStock) error CreateStocks(tx *gorm.DB, stocks []entity.RecordingStock) error
DeleteStocks(tx *gorm.DB, recordingID uint) error DeleteStocks(tx *gorm.DB, recordingID uint) error
ListStocks(tx *gorm.DB, recordingID uint) ([]entity.RecordingStock, error) ListStocks(tx *gorm.DB, recordingID uint) ([]entity.RecordingStock, error)
@@ -41,10 +38,10 @@ type RecordingRepository interface {
SumRecordingDepletions(tx *gorm.DB, recordingID uint) (float64, error) SumRecordingDepletions(tx *gorm.DB, recordingID uint) (float64, error)
FindPreviousRecording(tx *gorm.DB, projectFlockKandangId uint, currentDay int) (*entity.Recording, error) FindPreviousRecording(tx *gorm.DB, projectFlockKandangId uint, currentDay int) (*entity.Recording, error)
GetTotalChick(tx *gorm.DB, projectFlockKandangId uint) (int64, error) GetTotalChick(tx *gorm.DB, projectFlockKandangId uint) (int64, error)
GetAverageBodyWeight(tx *gorm.DB, recordingID uint) (float64, error) GetTotalChickinByProjectFlockKandang(tx *gorm.DB, projectFlockKandangId uint) (float64, error)
GetFeedUsageInGrams(tx *gorm.DB, recordingID uint) (float64, error) GetFeedUsageInGrams(tx *gorm.DB, recordingID uint) (float64, error)
GetFcrID(tx *gorm.DB, projectFlockKandangId uint) (uint, error) GetEggSummaryByRecording(tx *gorm.DB, recordingID uint) (totalQty float64, totalWeightGrams float64, err error)
GetFcrStandardWeightKg(tx *gorm.DB, fcrId uint, currentWeightKg float64) (float64, bool, error) GetCumulativeEggQtyByProjectFlockKandang(tx *gorm.DB, projectFlockKandangId uint, recordTime time.Time) (float64, error)
GetProductionWeightAndQtyByProjectFlockID(ctx context.Context, projectFlockID uint) (totalWeight float64, totalQty float64, err error) GetProductionWeightAndQtyByProjectFlockID(ctx context.Context, projectFlockID uint) (totalWeight float64, totalQty float64, err error)
GetTotalDepletionByProjectFlockID(ctx context.Context, projectFlockID uint) (totalDepletion float64, err error) GetTotalDepletionByProjectFlockID(ctx context.Context, projectFlockID uint) (totalDepletion float64, err error)
GetLatestAvgWeightByProjectFlockID(ctx context.Context, projectFlockID uint) (avgWeight float64, err error) GetLatestAvgWeightByProjectFlockID(ctx context.Context, projectFlockID uint) (avgWeight float64, err error)
@@ -91,17 +88,6 @@ func (r *RecordingRepositoryImpl) GenerateNextDay(tx *gorm.DB, projectFlockKanda
return nextRecordingDay(days), nil return nextRecordingDay(days), nil
} }
func (r *RecordingRepositoryImpl) CreateBodyWeights(tx *gorm.DB, bodyWeights []entity.RecordingBW) error {
if len(bodyWeights) == 0 {
return nil
}
return tx.Create(&bodyWeights).Error
}
func (r *RecordingRepositoryImpl) DeleteBodyWeights(tx *gorm.DB, recordingID uint) error {
return tx.Where("recording_id = ?", recordingID).Delete(&entity.RecordingBW{}).Error
}
func (r *RecordingRepositoryImpl) CreateStocks(tx *gorm.DB, stocks []entity.RecordingStock) error { func (r *RecordingRepositoryImpl) CreateStocks(tx *gorm.DB, stocks []entity.RecordingStock) error {
if len(stocks) == 0 { if len(stocks) == 0 {
return nil return nil
@@ -270,21 +256,18 @@ func (r *RecordingRepositoryImpl) GetTotalChick(tx *gorm.DB, projectFlockKandang
return int64(math.Round(total)), nil return int64(math.Round(total)), nil
} }
func (r *RecordingRepositoryImpl) GetAverageBodyWeight(tx *gorm.DB, recordingID uint) (float64, error) { func (r *RecordingRepositoryImpl) GetTotalChickinByProjectFlockKandang(tx *gorm.DB, projectFlockKandangId uint) (float64, error) {
var result struct { if projectFlockKandangId == 0 {
TotalWeight float64
TotalQty float64
}
if err := tx.Model(&entity.RecordingBW{}).
Select("COALESCE(SUM(total_weight), 0) AS total_weight, COALESCE(SUM(qty), 0) AS total_qty").
Where("recording_id = ?", recordingID).
Scan(&result).Error; err != nil {
return 0, err
}
if result.TotalQty == 0 {
return 0, nil return 0, nil
} }
return result.TotalWeight / result.TotalQty, nil
var result float64
err := tx.
Table("project_chickins").
Select("COALESCE(SUM(project_chickins.usage_qty), 0)").
Where("project_chickins.project_flock_kandang_id = ?", projectFlockKandangId).
Scan(&result).Error
return result, err
} }
func (r *RecordingRepositoryImpl) GetFeedUsageInGrams(tx *gorm.DB, recordingID uint) (float64, error) { func (r *RecordingRepositoryImpl) GetFeedUsageInGrams(tx *gorm.DB, recordingID uint) (float64, error) {
@@ -321,89 +304,52 @@ func (r *RecordingRepositoryImpl) GetFeedUsageInGrams(tx *gorm.DB, recordingID u
return total, nil return total, nil
} }
func (r *RecordingRepositoryImpl) GetFcrID(tx *gorm.DB, projectFlockKandangId uint) (uint, error) { func (r *RecordingRepositoryImpl) GetEggSummaryByRecording(tx *gorm.DB, recordingID uint) (totalQty float64, totalWeightGrams float64, err error) {
var result struct { if recordingID == 0 {
FcrID uint
}
if err := tx.Table("project_flock_kandangs").
Select("project_flocks.fcr_id AS fcr_id").
Joins("JOIN project_flocks ON project_flocks.id = project_flock_kandangs.project_flock_id").
Where("project_flock_kandangs.id = ?", projectFlockKandangId).
Scan(&result).Error; err != nil {
return 0, err
}
return result.FcrID, nil
}
func (r *RecordingRepositoryImpl) GetFcrStandardWeightKg(tx *gorm.DB, fcrId uint, currentWeightKg float64) (float64, bool, error) {
if fcrId == 0 {
return 0, false, nil
}
var standard entity.FcrStandard
err := tx.
Where("fcr_id = ? AND weight >= ?", fcrId, currentWeightKg).
Order("weight ASC").
First(&standard).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
err = tx.
Where("fcr_id = ?", fcrId).
Order("weight DESC").
First(&standard).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
return 0, false, nil
}
}
if err != nil {
return 0, false, err
}
weight := standard.Weight
if weight > 10 {
return weight / 1000, true, nil
}
return weight, true, nil
}
func (r *RecordingRepositoryImpl) GetProductionWeightAndQtyByProjectFlockID(ctx context.Context, projectFlockID uint) (totalWeight float64, totalQty float64, err error) {
if projectFlockID == 0 {
return 0, 0, nil return 0, 0, nil
} }
totalChickinQty, err := r.getTotalChickinQtyByProjectFlockID(ctx, projectFlockID) var result struct {
TotalQty float64
TotalWeightGrams float64
}
err = tx.
Table("recording_eggs").
Select("COALESCE(SUM(recording_eggs.qty), 0) AS total_qty, COALESCE(SUM(recording_eggs.qty * COALESCE(recording_eggs.weight, 0)), 0) AS total_weight_grams").
Where("recording_eggs.recording_id = ?", recordingID).
Scan(&result).Error
if err != nil { if err != nil {
return 0, 0, err return 0, 0, err
} }
return result.TotalQty, result.TotalWeightGrams, nil
totalDepletion, err := r.GetTotalDepletionByProjectFlockID(ctx, projectFlockID)
if err != nil {
return 0, 0, err
}
actualQty := totalChickinQty - totalDepletion
avgWeight, err := r.GetLatestAvgWeightByProjectFlockID(ctx, projectFlockID)
if err != nil {
return 0, 0, err
}
totalWeight = actualQty * avgWeight
return totalWeight, actualQty, nil
} }
func (r *RecordingRepositoryImpl) getTotalChickinQtyByProjectFlockID(ctx context.Context, projectFlockID uint) (float64, error) { func (r *RecordingRepositoryImpl) GetCumulativeEggQtyByProjectFlockKandang(
tx *gorm.DB,
projectFlockKandangId uint,
recordTime time.Time,
) (float64, error) {
if projectFlockKandangId == 0 {
return 0, nil
}
var result float64 var result float64
err := r.DB().WithContext(ctx). err := tx.
Table("project_chickins"). Table("recording_eggs").
Select("COALESCE(SUM(project_chickins.usage_qty), 0)"). Select("COALESCE(SUM(recording_eggs.qty), 0)").
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = project_chickins.project_flock_kandang_id"). Joins("JOIN recordings ON recordings.id = recording_eggs.recording_id").
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID). Where("recordings.project_flock_kandangs_id = ?", projectFlockKandangId).
Where("recordings.record_datetime <= ?", recordTime).
Scan(&result).Error Scan(&result).Error
return result, err return result, err
} }
func (r *RecordingRepositoryImpl) GetProductionWeightAndQtyByProjectFlockID(ctx context.Context, projectFlockID uint) (totalWeight float64, totalQty float64, err error) {
// Body-weight tracking is removed; keep stub for report compatibility.
return 0, 0, nil
}
func (r *RecordingRepositoryImpl) GetTotalDepletionByProjectFlockID(ctx context.Context, projectFlockID uint) (float64, error) { func (r *RecordingRepositoryImpl) GetTotalDepletionByProjectFlockID(ctx context.Context, projectFlockID uint) (float64, error) {
var result float64 var result float64
err := r.DB().WithContext(ctx). err := r.DB().WithContext(ctx).
@@ -417,16 +363,8 @@ func (r *RecordingRepositoryImpl) GetTotalDepletionByProjectFlockID(ctx context.
} }
func (r *RecordingRepositoryImpl) GetLatestAvgWeightByProjectFlockID(ctx context.Context, projectFlockID uint) (float64, error) { func (r *RecordingRepositoryImpl) GetLatestAvgWeightByProjectFlockID(ctx context.Context, projectFlockID uint) (float64, error) {
var result float64 // Body-weight tracking is removed; keep stub for report compatibility.
err := r.DB().WithContext(ctx). return 0, nil
Table("recording_bws").
Select("COALESCE(AVG(recording_bws.avg_weight), 0)").
Joins("JOIN recordings ON recordings.id = recording_bws.recording_id").
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = recordings.project_flock_kandangs_id").
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
Where("recordings.record_datetime = (SELECT MAX(record_datetime) FROM recordings r2 WHERE r2.project_flock_kandangs_id IN (SELECT id FROM project_flock_kandangs WHERE project_flock_id = ?))", projectFlockID).
Scan(&result).Error
return result, err
} }
func (r *RecordingRepositoryImpl) GetTotalEggProductionWeightByProjectFlockID(ctx context.Context, projectFlockID uint) (float64, error) { func (r *RecordingRepositoryImpl) GetTotalEggProductionWeightByProjectFlockID(ctx context.Context, projectFlockID uint) (float64, error) {
@@ -255,7 +255,7 @@ func (s *recordingService) CreateOne(c *fiber.Ctx, req *validation.Create) (*ent
return err return err
} }
if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, mappedDepletions, nil, nil, nil, mappedEggs)); err != nil { if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, mappedDepletions, nil, mappedEggs)); err != nil {
s.Log.Errorf("Failed to adjust product warehouses: %+v", err) s.Log.Errorf("Failed to adjust product warehouses: %+v", err)
return err return err
} }
@@ -384,7 +384,7 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
return err return err
} }
if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(existingDepletions, mappedDepletions, nil, nil, nil, nil)); err != nil { if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(existingDepletions, mappedDepletions, nil, nil)); err != nil {
s.Log.Errorf("Failed to adjust product warehouses for depletions: %+v", err) s.Log.Errorf("Failed to adjust product warehouses for depletions: %+v", err)
return err return err
} }
@@ -408,7 +408,7 @@ func (s recordingService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uin
return err return err
} }
if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, nil, nil, nil, existingEggs, mappedEggs)); err != nil { if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(nil, nil, existingEggs, mappedEggs)); err != nil {
s.Log.Errorf("Failed to adjust product warehouses for eggs: %+v", err) s.Log.Errorf("Failed to adjust product warehouses for eggs: %+v", err)
return err return err
} }
@@ -578,7 +578,7 @@ func (s recordingService) DeleteOne(c *fiber.Ctx, id uint) error {
return err return err
} }
if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(oldDepletions, nil, nil, nil, oldEggs, nil)); err != nil { if err := s.adjustProductWarehouseQuantities(ctx, tx, buildWarehouseDeltas(oldDepletions, nil, oldEggs, nil)); err != nil {
return err return err
} }
@@ -706,7 +706,6 @@ func (s *recordingService) ReleaseRecordingStocks(ctx context.Context, tx *gorm.
func buildWarehouseDeltas( func buildWarehouseDeltas(
oldDepletions, newDepletions []entity.RecordingDepletion, oldDepletions, newDepletions []entity.RecordingDepletion,
oldStocks, newStocks []entity.RecordingStock,
oldEggs, newEggs []entity.RecordingEgg, oldEggs, newEggs []entity.RecordingEgg,
) map[uint]float64 { ) map[uint]float64 {
deltas := make(map[uint]float64) deltas := make(map[uint]float64)
@@ -776,6 +775,21 @@ func (s *recordingService) computeAndUpdateMetrics(ctx context.Context, tx *gorm
return fmt.Errorf("getFeedUsageInGrams: %w", err) return fmt.Errorf("getFeedUsageInGrams: %w", err)
} }
totalEggQty, totalEggWeightGrams, err := s.Repository.GetEggSummaryByRecording(tx, recording.Id)
if err != nil {
return fmt.Errorf("getEggSummaryByRecording: %w", err)
}
cumulativeEggQty, err := s.Repository.GetCumulativeEggQtyByProjectFlockKandang(tx, recording.ProjectFlockKandangId, recording.RecordDatetime)
if err != nil {
return fmt.Errorf("getCumulativeEggQtyByProjectFlockKandang: %w", err)
}
initialChickin, err := s.Repository.GetTotalChickinByProjectFlockKandang(tx, recording.ProjectFlockKandangId)
if err != nil {
return fmt.Errorf("getTotalChickinByProjectFlockKandang: %w", err)
}
currentDepletion := float64(totalDepletionQty) currentDepletion := float64(totalDepletionQty)
cumDepletionQty := prevCumDepletionQty + currentDepletion cumDepletionQty := prevCumDepletionQty + currentDepletion
@@ -807,10 +821,65 @@ func (s *recordingService) computeAndUpdateMetrics(ctx context.Context, tx *gorm
recording.CumDepletionRate = nil recording.CumDepletionRate = nil
} }
updates["daily_gain"] = gorm.Expr("NULL") var feedIntake float64
updates["avg_daily_gain"] = gorm.Expr("NULL") if remainingChick > 0 && usageInGrams > 0 {
recording.DailyGain = nil feedIntake = (usageInGrams / remainingChick) * 1000
recording.AvgDailyGain = nil updates["feed_intake"] = feedIntake
recording.FeedIntake = &feedIntake
} else {
updates["feed_intake"] = gorm.Expr("NULL")
recording.FeedIntake = nil
}
var handDay float64
if remainingChick > 0 && totalEggQty >= 0 {
handDay = (totalEggQty / remainingChick) * 100
updates["hand_day"] = handDay
recording.HandDay = &handDay
} else {
updates["hand_day"] = gorm.Expr("NULL")
recording.HandDay = nil
}
var handHouse float64
if initialChickin > 0 && cumulativeEggQty >= 0 {
handHouse = cumulativeEggQty / initialChickin
updates["hand_house"] = handHouse
recording.HandHouse = &handHouse
} else {
updates["hand_house"] = gorm.Expr("NULL")
recording.HandHouse = nil
}
var eggMesh float64
if remainingChick > 0 && totalEggWeightGrams > 0 {
eggMesh = (totalEggWeightGrams / remainingChick) * 1000
updates["egg_mesh"] = eggMesh
recording.EggMesh = &eggMesh
} else {
updates["egg_mesh"] = gorm.Expr("NULL")
recording.EggMesh = nil
}
var eggWeight float64
if totalEggQty > 0 && totalEggWeightGrams > 0 {
eggWeight = (totalEggWeightGrams / totalEggQty) * 1000
updates["egg_weight"] = eggWeight
recording.EggWeight = &eggWeight
} else {
updates["egg_weight"] = gorm.Expr("NULL")
recording.EggWeight = nil
}
var fcrValue float64
if usageInGrams > 0 && totalEggWeightGrams > 0 {
fcrValue = totalEggWeightGrams / usageInGrams
updates["fcr_value"] = fcrValue
recording.FcrValue = &fcrValue
} else {
updates["fcr_value"] = gorm.Expr("NULL")
recording.FcrValue = nil
}
if usageInGrams > 0 && totalChick > 0 { if usageInGrams > 0 && totalChick > 0 {
var cumIntakeValue float64 var cumIntakeValue float64
@@ -834,9 +903,6 @@ func (s *recordingService) computeAndUpdateMetrics(ctx context.Context, tx *gorm
recording.CumIntake = nil recording.CumIntake = nil
} }
updates["fcr_value"] = gorm.Expr("NULL")
recording.FcrValue = nil
if err := s.Repository.WithTx(tx).PatchOne(ctx, recording.Id, updates, nil); err != nil { if err := s.Repository.WithTx(tx).PatchOne(ctx, recording.Id, updates, nil); err != nil {
return err return err
} }