mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'fix/week-record' into 'development'
[FIX][BE]: adjust calculate for week at recording list See merge request mbugroup/lti-api!520
This commit is contained in:
@@ -43,6 +43,7 @@ type Recording struct {
|
|||||||
StandardEggMass *float64 `gorm:"-"`
|
StandardEggMass *float64 `gorm:"-"`
|
||||||
StandardEggWeight *float64 `gorm:"-"`
|
StandardEggWeight *float64 `gorm:"-"`
|
||||||
StandardFcr *float64 `gorm:"-"`
|
StandardFcr *float64 `gorm:"-"`
|
||||||
|
StandardWeek *int `gorm:"-"`
|
||||||
PopulationCanChange *bool `gorm:"-"`
|
PopulationCanChange *bool `gorm:"-"`
|
||||||
TransferExecuted *bool `gorm:"-"`
|
TransferExecuted *bool `gorm:"-"`
|
||||||
IsTransition *bool `gorm:"-"`
|
IsTransition *bool `gorm:"-"`
|
||||||
|
|||||||
@@ -314,9 +314,13 @@ func toRecordingProjectFlockDTO(e entity.Recording) RecordingProjectFlockDTO {
|
|||||||
result.Period = pfk.Period
|
result.Period = pfk.Period
|
||||||
|
|
||||||
if pfk.ProjectFlock.ProductionStandard.Id != 0 {
|
if pfk.ProjectFlock.ProductionStandard.Id != 0 {
|
||||||
|
week := recordingWeekValue(e)
|
||||||
|
if e.StandardWeek != nil && *e.StandardWeek > 0 {
|
||||||
|
week = *e.StandardWeek
|
||||||
|
}
|
||||||
result.ProductionStandart = &RecordingProductionStandardDTO{
|
result.ProductionStandart = &RecordingProductionStandardDTO{
|
||||||
Id: pfk.ProjectFlock.ProductionStandard.Id,
|
Id: pfk.ProjectFlock.ProductionStandard.Id,
|
||||||
Week: recordingWeekValue(e),
|
Week: week,
|
||||||
Name: pfk.ProjectFlock.ProductionStandard.Name,
|
Name: pfk.ProjectFlock.ProductionStandard.Name,
|
||||||
HenDayStd: floatValue(e.StandardHenDay),
|
HenDayStd: floatValue(e.StandardHenDay),
|
||||||
HenHouseStd: floatValue(e.StandardHenHouse),
|
HenHouseStd: floatValue(e.StandardHenHouse),
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||||
"gitlab.com/mbugroup/lti-api.git/internal/config"
|
"gitlab.com/mbugroup/lti-api.git/internal/config"
|
||||||
@@ -243,6 +244,31 @@ func AttachProductionStandards(ctx context.Context, db *gorm.DB, warnOnly bool,
|
|||||||
growthDetailByStd[standardID] = growthMap
|
growthDetailByStd[standardID] = growthMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Batch-load laying transfer targets → source PFK chick_in_dates
|
||||||
|
// untuk menentukan actual chicken week (bukan hardcode LayingWeekStart offset)
|
||||||
|
type transferChickIn struct {
|
||||||
|
TargetPFKID uint
|
||||||
|
ChickInDate time.Time
|
||||||
|
}
|
||||||
|
layingPFKIDs := collectLayingPFKIDs(items)
|
||||||
|
sourceChickInByTarget := make(map[uint]time.Time, len(layingPFKIDs))
|
||||||
|
if len(layingPFKIDs) > 0 {
|
||||||
|
var results []transferChickIn
|
||||||
|
db.Raw(`
|
||||||
|
SELECT ltt.target_project_flock_kandang_id AS target_pfk_id, pc.chick_in_date
|
||||||
|
FROM laying_transfer_targets ltt
|
||||||
|
JOIN laying_transfer_sources lts ON lts.laying_transfer_id = ltt.laying_transfer_id
|
||||||
|
JOIN project_chickins pc ON pc.project_flock_kandang_id = lts.source_project_flock_kandang_id
|
||||||
|
WHERE ltt.target_project_flock_kandang_id IN ?
|
||||||
|
AND ltt.deleted_at IS NULL
|
||||||
|
AND lts.deleted_at IS NULL
|
||||||
|
AND pc.deleted_at IS NULL
|
||||||
|
`, layingPFKIDs).Scan(&results)
|
||||||
|
for _, r := range results {
|
||||||
|
sourceChickInByTarget[r.TargetPFKID] = r.ChickInDate
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for _, item := range items {
|
for _, item := range items {
|
||||||
if item == nil || item.ProjectFlockKandang == nil || item.ProjectFlockKandang.ProjectFlock.Id == 0 {
|
if item == nil || item.ProjectFlockKandang == nil || item.ProjectFlockKandang.ProjectFlock.Id == 0 {
|
||||||
continue
|
continue
|
||||||
@@ -251,7 +277,8 @@ func AttachProductionStandards(ctx context.Context, db *gorm.DB, warnOnly bool,
|
|||||||
if standardID == 0 {
|
if standardID == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
week := RecordingWeekValue(*item)
|
week := computeTransferAwareWeek(item, sourceChickInByTarget)
|
||||||
|
item.StandardWeek = &week
|
||||||
cacheKey := standardKey{standardID: standardID, week: week}
|
cacheKey := standardKey{standardID: standardID, week: week}
|
||||||
if cached, ok := cache[cacheKey]; ok {
|
if cached, ok := cache[cacheKey]; ok {
|
||||||
applyProductionStandardValues(item, cached.values, cached.fcr)
|
applyProductionStandardValues(item, cached.values, cached.fcr)
|
||||||
@@ -291,6 +318,65 @@ func applyProductionStandardValues(item *entity.Recording, values productionStan
|
|||||||
item.StandardFcr = fcr
|
item.StandardFcr = fcr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collectLayingPFKIDs mengumpulkan semua project_flock_kandang_id dari recording laying
|
||||||
|
func collectLayingPFKIDs(items []*entity.Recording) []uint {
|
||||||
|
seen := make(map[uint]struct{})
|
||||||
|
var ids []uint
|
||||||
|
for _, item := range items {
|
||||||
|
if item == nil || item.ProjectFlockKandang == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if strings.EqualFold(item.ProjectFlockKandang.ProjectFlock.Category, string(utils.ProjectFlockCategoryLaying)) {
|
||||||
|
id := item.ProjectFlockKandang.Id
|
||||||
|
if _, ok := seen[id]; !ok {
|
||||||
|
seen[id] = struct{}{}
|
||||||
|
ids = append(ids, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ids
|
||||||
|
}
|
||||||
|
|
||||||
|
// computeTransferAwareWeek menghitung production standard week untuk recording.
|
||||||
|
// Laying dengan transfer: actual chicken age dari source PFK chick_in_date.
|
||||||
|
// Laying cut-over (tanpa transfer): langsung dari recording.day (tanpa offset LayingWeekStart).
|
||||||
|
// Non-laying: ((day-1)/7) + 1.
|
||||||
|
func computeTransferAwareWeek(item *entity.Recording, sourceChickInByTarget map[uint]time.Time) int {
|
||||||
|
day := intValue(item.Day)
|
||||||
|
if item == nil || item.ProjectFlockKandang == nil {
|
||||||
|
if day > 0 {
|
||||||
|
return ((day - 1) / 7) + 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
isLaying := strings.EqualFold(item.ProjectFlockKandang.ProjectFlock.Category, string(utils.ProjectFlockCategoryLaying))
|
||||||
|
if !isLaying {
|
||||||
|
if day > 0 {
|
||||||
|
return ((day - 1) / 7) + 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Laying recording — cek apakah PFK ini adalah target dari laying transfer
|
||||||
|
if sourceChickIn, ok := sourceChickInByTarget[item.ProjectFlockKandang.Id]; ok && !sourceChickIn.IsZero() {
|
||||||
|
// Ada laying transfer: hitung umur aktual dari source PFK chick_in_date
|
||||||
|
rDate := time.Date(item.RecordDatetime.Year(), item.RecordDatetime.Month(), item.RecordDatetime.Day(), 0, 0, 0, 0, item.RecordDatetime.Location())
|
||||||
|
sDate := time.Date(sourceChickIn.Year(), sourceChickIn.Month(), sourceChickIn.Day(), 0, 0, 0, 0, sourceChickIn.Location())
|
||||||
|
actualDay := int(rDate.Sub(sDate).Hours() / 24)
|
||||||
|
if actualDay > 0 {
|
||||||
|
return ((actualDay - 1) / 7) + 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cut-over laying (tanpa transfer): chick_in_date di PFK sudah umur asli DOC
|
||||||
|
if day > 0 {
|
||||||
|
return ((day - 1) / 7) + 1
|
||||||
|
}
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
func RecordingWeekValue(e entity.Recording) int {
|
func RecordingWeekValue(e entity.Recording) int {
|
||||||
day := intValue(e.Day)
|
day := intValue(e.Day)
|
||||||
if day <= 0 {
|
if day <= 0 {
|
||||||
|
|||||||
Reference in New Issue
Block a user