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) }