package service import ( "strings" "time" ) const ( depreciationStartAgeDayCloseHouse = 175 depreciationStartAgeDayOpenHouse = 175 ) func NormalizeDepreciationHouseType(raw string) string { return strings.TrimSpace(strings.ToLower(raw)) } func DepreciationStartAgeDay(houseType string) int { switch NormalizeDepreciationHouseType(houseType) { case "close_house": return depreciationStartAgeDayCloseHouse case "open_house": return depreciationStartAgeDayOpenHouse default: return 0 } } func FlockAgeDay(originDate time.Time, periodDate time.Time) int { origin := time.Date(originDate.Year(), originDate.Month(), originDate.Day(), 0, 0, 0, 0, time.UTC) period := time.Date(periodDate.Year(), periodDate.Month(), periodDate.Day(), 0, 0, 0, 0, time.UTC) if period.Before(origin) { return 0 } return int(period.Sub(origin).Hours() / 24) } func DepreciationScheduleDay(originDate time.Time, periodDate time.Time, houseType string) int { ageDay := FlockAgeDay(originDate, periodDate) startAgeDay := DepreciationStartAgeDay(houseType) if ageDay <= 0 || startAgeDay <= 0 || ageDay < startAgeDay { return 0 } return ageDay - startAgeDay + 1 } func CalculateDepreciationAtDayN( initialPulletCost float64, dayN int, houseType string, multiplicationByHouseType map[string]map[int]float64, ) (float64, float64, float64) { return CalculateDepreciationFromDayRange(initialPulletCost, 1, dayN, houseType, multiplicationByHouseType) } func CalculateDepreciationFromDayRange( initialPulletCost float64, startDay int, endDay int, houseType string, multiplicationByHouseType map[string]map[int]float64, ) (pulletCostDayN, depreciationValue, multiplicationPercentage float64) { if initialPulletCost <= 0 || endDay <= 0 { return 0, 0, 0 } if startDay <= 0 { startDay = 1 } if endDay < startDay { return 0, 0, 0 } normalizedHouseType := NormalizeDepreciationHouseType(houseType) houseMult, exists := multiplicationByHouseType[normalizedHouseType] if !exists { return 0, 0, 0 } current := initialPulletCost for day := startDay; day <= endDay; day++ { mult, ok := houseMult[day] if !ok { // No standard for this day → assume no depreciation (mult=1). mult = 1.0 } if day == endDay { pulletCostDayN = current multiplicationPercentage = mult depreciationValue = current * (1.0 - mult) } current = current * mult if current < 0 { current = 0 } } return pulletCostDayN, depreciationValue, multiplicationPercentage } func CalculateEffectiveDepreciationPercent(totalDepreciationValue, totalPulletCostDayN float64) float64 { if totalPulletCostDayN <= 0 { return 0 } return (totalDepreciationValue / totalPulletCostDayN) * 100 }