Files
kra-new/internal/biz/business/goal_metrics.go
T

90 lines
2.2 KiB
Go

package business
import (
"math/big"
"time"
)
func GoalMetric(goal *PerformanceGoal, key string) *int64 {
if goal == nil {
return nil
}
switch key {
case "open":
return goal.Open
case "effective":
return goal.Effective
case "pay":
return goal.Amount
}
return nil
}
func GoalPeriodTarget(goal *PerformanceGoal, key, period, grain string) *string {
if len(period) < 7 {
return nil
}
value := GoalMetric(goal, key)
if value == nil {
return nil
}
target := big.NewRat(*value, 1)
if grain == "day" {
month, err := time.Parse("2006-01", period[:7])
if err != nil {
return nil
}
target.Quo(target, big.NewRat(int64(month.AddDate(0, 1, -1).Day()), 1))
}
return stringPointer(portraitDecimal(target, 2))
}
func GoalCompletion(periods map[string]PerformanceMetrics, goals map[string]*PerformanceGoal, key string) *string {
actual, target := new(big.Rat), new(big.Rat)
months := map[string]bool{}
for period, value := range periods {
if len(period) < 7 {
continue
}
month := period[:7]
goal := GoalMetric(goals[month], key)
if goal == nil {
continue
}
if !months[month] {
target.Add(target, big.NewRat(*goal, 1))
months[month] = true
}
switch key {
case "open":
actual.Add(actual, big.NewRat(value.Open, 1))
case "effective":
actual.Add(actual, big.NewRat(value.Effective, 1))
case "pay":
amount, err := portraitNumber(value.Pay)
if err == nil {
actual.Add(actual, amount)
}
}
}
if target.Sign() <= 0 {
return nil
}
return stringPointer(portraitDecimal(actual.Quo(actual, target).Mul(actual, big.NewRat(100, 1)), 1))
}
func PerformanceChange(current, previous PerformanceMetrics, key string) *string {
var a, b *big.Rat
switch key {
case "open":
a, b = big.NewRat(current.Open, 1), big.NewRat(previous.Open, 1)
case "effective":
a, b = big.NewRat(current.Effective, 1), big.NewRat(previous.Effective, 1)
case "pay":
a, _ = portraitNumber(current.Pay)
b, _ = portraitNumber(previous.Pay)
}
if a == nil || b == nil || b.Sign() == 0 {
return nil
}
return stringPointer(portraitDecimal(a.Sub(a, b).Quo(a, b).Mul(a, big.NewRat(100, 1)), 1))
}
func PerformanceRate(value PerformanceMetrics) *string { return performanceRate(value) }