mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-25 07:45:44 +00:00
feat(BE-281): adjustment recording table with handhouse and deleting weight unfinished dto:standart fcr,hand house and others
This commit is contained in:
-1
@@ -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
|
||||||
|
|||||||
+1
-3
@@ -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;
|
||||||
|
|||||||
@@ -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"`
|
||||||
|
|||||||
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user