fix: исправлен расчет общего процента выполнения в ежедневном отчете и унифицирована логика
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 46s
All checks were successful
Build and Push Docker Image / build-and-push (push) Successful in 46s
This commit is contained in:
@@ -2234,49 +2234,8 @@ func (a *App) getWeeklyStatsHandler(w http.ResponseWriter, r *http.Request) {
|
||||
projects = append(projects, project)
|
||||
}
|
||||
|
||||
// Находим среднее внутри каждой группы
|
||||
groupAverages := make([]float64, 0)
|
||||
for priorityVal, scores := range groups {
|
||||
if len(scores) > 0 {
|
||||
var avg float64
|
||||
|
||||
// Для приоритета 1 и 2 - обычное среднее (как было)
|
||||
if priorityVal == 1 || priorityVal == 2 {
|
||||
sum := 0.0
|
||||
for _, score := range scores {
|
||||
sum += score
|
||||
}
|
||||
avg = sum / float64(len(scores))
|
||||
} else {
|
||||
// Для проектов без приоритета (priorityVal == 0) - новая формула
|
||||
projectCount := float64(len(scores))
|
||||
multiplier := 100.0 / (projectCount * 0.8)
|
||||
|
||||
sum := 0.0
|
||||
for _, score := range scores {
|
||||
// score уже в процентах (например, 80.0), переводим в долю (0.8)
|
||||
scoreAsDecimal := score / 100.0
|
||||
sum += scoreAsDecimal * multiplier
|
||||
}
|
||||
|
||||
avg = math.Min(120.0, sum)
|
||||
}
|
||||
|
||||
groupAverages = append(groupAverages, avg)
|
||||
}
|
||||
}
|
||||
|
||||
// Находим среднее между всеми группами
|
||||
var total *float64
|
||||
if len(groupAverages) > 0 {
|
||||
sum := 0.0
|
||||
for _, avg := range groupAverages {
|
||||
sum += avg
|
||||
}
|
||||
overallProgress := sum / float64(len(groupAverages))
|
||||
overallProgressRounded := roundToFourDecimals(overallProgress)
|
||||
total = &overallProgressRounded
|
||||
}
|
||||
// Вычисляем общий процент выполнения
|
||||
total := calculateOverallProgress(groups)
|
||||
|
||||
response := WeeklyStatsResponse{
|
||||
Total: total,
|
||||
@@ -3034,49 +2993,8 @@ func (a *App) getWeeklyStatsData() (*WeeklyStatsResponse, error) {
|
||||
projects = append(projects, project)
|
||||
}
|
||||
|
||||
// Находим среднее внутри каждой группы
|
||||
groupAverages := make([]float64, 0)
|
||||
for priorityVal, scores := range groups {
|
||||
if len(scores) > 0 {
|
||||
var avg float64
|
||||
|
||||
// Для приоритета 1 и 2 - обычное среднее (как было)
|
||||
if priorityVal == 1 || priorityVal == 2 {
|
||||
sum := 0.0
|
||||
for _, score := range scores {
|
||||
sum += score
|
||||
}
|
||||
avg = sum / float64(len(scores))
|
||||
} else {
|
||||
// Для проектов без приоритета (priorityVal == 0) - новая формула
|
||||
projectCount := float64(len(scores))
|
||||
multiplier := 100.0 / (projectCount * 0.8)
|
||||
|
||||
sum := 0.0
|
||||
for _, score := range scores {
|
||||
// score уже в процентах (например, 80.0), переводим в долю (0.8)
|
||||
scoreAsDecimal := score / 100.0
|
||||
sum += scoreAsDecimal * multiplier
|
||||
}
|
||||
|
||||
avg = math.Min(120.0, sum)
|
||||
}
|
||||
|
||||
groupAverages = append(groupAverages, avg)
|
||||
}
|
||||
}
|
||||
|
||||
// Находим среднее между всеми группами
|
||||
var total *float64
|
||||
if len(groupAverages) > 0 {
|
||||
sum := 0.0
|
||||
for _, avg := range groupAverages {
|
||||
sum += avg
|
||||
}
|
||||
overallProgress := sum / float64(len(groupAverages))
|
||||
overallProgressRounded := roundToFourDecimals(overallProgress)
|
||||
total = &overallProgressRounded
|
||||
}
|
||||
// Вычисляем общий процент выполнения
|
||||
total := calculateOverallProgress(groups)
|
||||
|
||||
response := WeeklyStatsResponse{
|
||||
Total: total,
|
||||
@@ -3169,6 +3087,7 @@ func (a *App) getWeeklyStatsDataForUser(userID int) (*WeeklyStatsResponse, error
|
||||
maxGoalScoreVal = *project.MaxGoalScore
|
||||
}
|
||||
|
||||
// Параметры бонуса в зависимости от priority
|
||||
var extraBonusLimit float64 = 20
|
||||
if priorityVal == 1 {
|
||||
extraBonusLimit = 50
|
||||
@@ -3176,71 +3095,36 @@ func (a *App) getWeeklyStatsDataForUser(userID int) (*WeeklyStatsResponse, error
|
||||
extraBonusLimit = 35
|
||||
}
|
||||
|
||||
var calculatedScore float64
|
||||
// Расчет базового прогресса
|
||||
var baseProgress float64
|
||||
if minGoalScoreVal > 0 {
|
||||
percentage := (totalScore / minGoalScoreVal) * 100.0
|
||||
if maxGoalScoreVal > 0 {
|
||||
if totalScore >= maxGoalScoreVal {
|
||||
calculatedScore = 100.0 + math.Min(extraBonusLimit, ((totalScore-maxGoalScoreVal)/maxGoalScoreVal)*100.0)
|
||||
} else {
|
||||
calculatedScore = percentage
|
||||
}
|
||||
} else {
|
||||
calculatedScore = math.Min(100.0+extraBonusLimit, percentage)
|
||||
}
|
||||
} else {
|
||||
calculatedScore = 0.0
|
||||
baseProgress = (min(totalScore, minGoalScoreVal) / minGoalScoreVal) * 100.0
|
||||
}
|
||||
|
||||
project.CalculatedScore = roundToFourDecimals(calculatedScore)
|
||||
// Расчет экстра прогресса
|
||||
var extraProgress float64
|
||||
denominator := maxGoalScoreVal - minGoalScoreVal
|
||||
if denominator > 0 && totalScore > minGoalScoreVal {
|
||||
excess := min(totalScore, maxGoalScoreVal) - minGoalScoreVal
|
||||
extraProgress = (excess / denominator) * extraBonusLimit
|
||||
}
|
||||
|
||||
resultScore := baseProgress + extraProgress
|
||||
project.CalculatedScore = roundToTwoDecimals(resultScore)
|
||||
projects = append(projects, project)
|
||||
|
||||
if priorityVal > 0 {
|
||||
groups[priorityVal] = append(groups[priorityVal], project.CalculatedScore)
|
||||
} else {
|
||||
groups[0] = append(groups[0], project.CalculatedScore)
|
||||
}
|
||||
}
|
||||
|
||||
// Расчет средних по группам
|
||||
groupAverages := make([]float64, 0)
|
||||
for priorityVal, scores := range groups {
|
||||
if len(scores) > 0 {
|
||||
var avg float64
|
||||
|
||||
if priorityVal == 1 || priorityVal == 2 {
|
||||
sum := 0.0
|
||||
for _, score := range scores {
|
||||
sum += score
|
||||
}
|
||||
avg = sum / float64(len(scores))
|
||||
} else {
|
||||
projectCount := float64(len(scores))
|
||||
multiplier := 100.0 / (projectCount * 0.8)
|
||||
|
||||
sum := 0.0
|
||||
for _, score := range scores {
|
||||
scoreAsDecimal := score / 100.0
|
||||
sum += scoreAsDecimal * multiplier
|
||||
}
|
||||
|
||||
avg = math.Min(120.0, sum)
|
||||
// Группировка для итогового расчета
|
||||
// Проекты с minGoal = 0 или null не учитываются в общем проценте выполнения
|
||||
if minGoalScoreVal > 0 {
|
||||
if _, exists := groups[priorityVal]; !exists {
|
||||
groups[priorityVal] = make([]float64, 0)
|
||||
}
|
||||
|
||||
groupAverages = append(groupAverages, avg)
|
||||
groups[priorityVal] = append(groups[priorityVal], project.CalculatedScore)
|
||||
}
|
||||
}
|
||||
|
||||
var total *float64
|
||||
if len(groupAverages) > 0 {
|
||||
sum := 0.0
|
||||
for _, avg := range groupAverages {
|
||||
sum += avg
|
||||
}
|
||||
overallProgress := sum / float64(len(groupAverages))
|
||||
overallProgressRounded := roundToFourDecimals(overallProgress)
|
||||
total = &overallProgressRounded
|
||||
}
|
||||
// Вычисляем общий процент выполнения
|
||||
total := calculateOverallProgress(groups)
|
||||
|
||||
response := WeeklyStatsResponse{
|
||||
Total: total,
|
||||
@@ -3681,6 +3565,57 @@ func roundToFourDecimals(val float64) float64 {
|
||||
return float64(int(val*10000+0.5)) / 10000.0
|
||||
}
|
||||
|
||||
// calculateOverallProgress вычисляет общий процент выполнения на основе групп проектов по приоритетам
|
||||
// groups - карта приоритетов к спискам calculatedScore проектов
|
||||
// Возвращает указатель на float64 с общим процентом выполнения или nil, если нет данных
|
||||
func calculateOverallProgress(groups map[int][]float64) *float64 {
|
||||
// Находим среднее внутри каждой группы
|
||||
groupAverages := make([]float64, 0)
|
||||
for priorityVal, scores := range groups {
|
||||
if len(scores) > 0 {
|
||||
var avg float64
|
||||
|
||||
// Для приоритета 1 и 2 - обычное среднее (как было)
|
||||
if priorityVal == 1 || priorityVal == 2 {
|
||||
sum := 0.0
|
||||
for _, score := range scores {
|
||||
sum += score
|
||||
}
|
||||
avg = sum / float64(len(scores))
|
||||
} else {
|
||||
// Для проектов без приоритета (priorityVal == 0) - новая формула
|
||||
projectCount := float64(len(scores))
|
||||
multiplier := 100.0 / (projectCount * 0.8)
|
||||
|
||||
sum := 0.0
|
||||
for _, score := range scores {
|
||||
// score уже в процентах (например, 80.0), переводим в долю (0.8)
|
||||
scoreAsDecimal := score / 100.0
|
||||
sum += scoreAsDecimal * multiplier
|
||||
}
|
||||
|
||||
avg = math.Min(120.0, sum)
|
||||
}
|
||||
|
||||
groupAverages = append(groupAverages, avg)
|
||||
}
|
||||
}
|
||||
|
||||
// Находим среднее между всеми группами
|
||||
var total *float64
|
||||
if len(groupAverages) > 0 {
|
||||
sum := 0.0
|
||||
for _, avg := range groupAverages {
|
||||
sum += avg
|
||||
}
|
||||
overallProgress := sum / float64(len(groupAverages))
|
||||
overallProgressRounded := roundToFourDecimals(overallProgress)
|
||||
total = &overallProgressRounded
|
||||
}
|
||||
|
||||
return total
|
||||
}
|
||||
|
||||
// TelegramIntegration представляет запись из таблицы telegram_integrations
|
||||
type TelegramIntegration struct {
|
||||
ID int `json:"id"`
|
||||
|
||||
Reference in New Issue
Block a user