feat: doc direct purchase cost

This commit is contained in:
Adnan Zahir
2026-04-19 14:52:01 +07:00
parent 58fbceea24
commit a2ae139fae
7 changed files with 718 additions and 108 deletions
@@ -473,11 +473,11 @@ func (s *repportService) computeExpenseDepreciationSnapshots(
for _, row := range inputRows {
groupedByFarm[row.ProjectFlockID] = append(groupedByFarm[row.ProjectFlockID], row)
dayN := depreciationDayNumber(row.TransferDate, periodDate)
dayN := approvalService.DepreciationScheduleDay(row.TransferDate, periodDate, valueOrEmptyString(row.HouseType))
if dayN > maxDay {
maxDay = dayN
}
houseType := strings.TrimSpace(strings.ToLower(valueOrEmptyString(row.HouseType)))
houseType := approvalService.NormalizeDepreciationHouseType(valueOrEmptyString(row.HouseType))
if houseType != "" {
houseTypeSet[houseType] = struct{}{}
}
@@ -511,8 +511,8 @@ func (s *repportService) computeExpenseDepreciationSnapshots(
totalDepreciationValue := 0.0
totalPulletCostDayN := 0.0
for _, row := range farmRows {
dayN := depreciationDayNumber(row.TransferDate, periodDate)
houseType := strings.TrimSpace(strings.ToLower(valueOrEmptyString(row.HouseType)))
dayN := approvalService.DepreciationScheduleDay(row.TransferDate, periodDate, valueOrEmptyString(row.HouseType))
houseType := approvalService.NormalizeDepreciationHouseType(valueOrEmptyString(row.HouseType))
transferDateKey := row.TransferDate.Format("2006-01-02")
cacheKey := fmt.Sprintf("%d|%s", row.SourceProjectFlockID, transferDateKey)
@@ -550,7 +550,7 @@ func (s *repportService) computeExpenseDepreciationSnapshots(
initialPulletCost = (cached.totalDepCost * row.TransferQty) / sourcePopulation
}
pulletCostDayN, depreciationValue, depreciationPercent := calculateDepreciationAtDayN(
pulletCostDayN, depreciationValue, depreciationPercent := approvalService.CalculateDepreciationAtDayN(
initialPulletCost,
dayN,
houseType,
@@ -576,8 +576,7 @@ func (s *repportService) computeExpenseDepreciationSnapshots(
})
}
effectivePercent := 0.0
effectivePercent = calculateEffectiveDepreciationPercent(totalDepreciationValue, totalPulletCostDayN)
effectivePercent := approvalService.CalculateEffectiveDepreciationPercent(totalDepreciationValue, totalPulletCostDayN)
componentsJSON, marshalErr := json.Marshal(components)
if marshalErr != nil {
@@ -597,57 +596,6 @@ func (s *repportService) computeExpenseDepreciationSnapshots(
return result, nil
}
func depreciationDayNumber(transferDate time.Time, periodDate time.Time) int {
transfer := time.Date(transferDate.Year(), transferDate.Month(), transferDate.Day(), 0, 0, 0, 0, transferDate.Location())
period := time.Date(periodDate.Year(), periodDate.Month(), periodDate.Day(), 0, 0, 0, 0, periodDate.Location())
if period.Before(transfer) {
return 0
}
return int(period.Sub(transfer).Hours()/24) + 1
}
func calculateDepreciationAtDayN(
initialPulletCost float64,
dayN int,
houseType string,
percentByHouseType map[string]map[int]float64,
) (float64, float64, float64) {
if initialPulletCost <= 0 || dayN <= 0 || houseType == "" {
return 0, 0, 0
}
housePercent, exists := percentByHouseType[houseType]
if !exists {
return 0, 0, 0
}
current := initialPulletCost
pulletCostDayN := 0.0
depreciationValue := 0.0
depreciationPercent := 0.0
for day := 1; day <= dayN; day++ {
pct := housePercent[day]
dep := current * (pct / 100)
if day == dayN {
pulletCostDayN = current
depreciationValue = dep
depreciationPercent = pct
}
current -= dep
if current < 0 {
current = 0
}
}
return pulletCostDayN, depreciationValue, depreciationPercent
}
func calculateEffectiveDepreciationPercent(totalDepreciationValue, totalPulletCostDayN float64) float64 {
if totalPulletCostDayN <= 0 {
return 0
}
return (totalDepreciationValue / totalPulletCostDayN) * 100
}
func parseSnapshotComponents(raw []byte) any {
if len(raw) == 0 {
return map[string]any{}