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)
|
projects = append(projects, project)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Находим среднее внутри каждой группы
|
// Вычисляем общий процент выполнения
|
||||||
groupAverages := make([]float64, 0)
|
total := calculateOverallProgress(groups)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
response := WeeklyStatsResponse{
|
response := WeeklyStatsResponse{
|
||||||
Total: total,
|
Total: total,
|
||||||
@@ -3034,49 +2993,8 @@ func (a *App) getWeeklyStatsData() (*WeeklyStatsResponse, error) {
|
|||||||
projects = append(projects, project)
|
projects = append(projects, project)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Находим среднее внутри каждой группы
|
// Вычисляем общий процент выполнения
|
||||||
groupAverages := make([]float64, 0)
|
total := calculateOverallProgress(groups)
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
response := WeeklyStatsResponse{
|
response := WeeklyStatsResponse{
|
||||||
Total: total,
|
Total: total,
|
||||||
@@ -3169,6 +3087,7 @@ func (a *App) getWeeklyStatsDataForUser(userID int) (*WeeklyStatsResponse, error
|
|||||||
maxGoalScoreVal = *project.MaxGoalScore
|
maxGoalScoreVal = *project.MaxGoalScore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Параметры бонуса в зависимости от priority
|
||||||
var extraBonusLimit float64 = 20
|
var extraBonusLimit float64 = 20
|
||||||
if priorityVal == 1 {
|
if priorityVal == 1 {
|
||||||
extraBonusLimit = 50
|
extraBonusLimit = 50
|
||||||
@@ -3176,71 +3095,36 @@ func (a *App) getWeeklyStatsDataForUser(userID int) (*WeeklyStatsResponse, error
|
|||||||
extraBonusLimit = 35
|
extraBonusLimit = 35
|
||||||
}
|
}
|
||||||
|
|
||||||
var calculatedScore float64
|
// Расчет базового прогресса
|
||||||
|
var baseProgress float64
|
||||||
if minGoalScoreVal > 0 {
|
if minGoalScoreVal > 0 {
|
||||||
percentage := (totalScore / minGoalScoreVal) * 100.0
|
baseProgress = (min(totalScore, minGoalScoreVal) / 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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
projects = append(projects, project)
|
||||||
|
|
||||||
if priorityVal > 0 {
|
// Группировка для итогового расчета
|
||||||
groups[priorityVal] = append(groups[priorityVal], project.CalculatedScore)
|
// Проекты с minGoal = 0 или null не учитываются в общем проценте выполнения
|
||||||
} else {
|
if minGoalScoreVal > 0 {
|
||||||
groups[0] = append(groups[0], project.CalculatedScore)
|
if _, exists := groups[priorityVal]; !exists {
|
||||||
}
|
groups[priorityVal] = make([]float64, 0)
|
||||||
}
|
|
||||||
|
|
||||||
// Расчет средних по группам
|
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
|
groups[priorityVal] = append(groups[priorityVal], project.CalculatedScore)
|
||||||
groupAverages = append(groupAverages, avg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var total *float64
|
// Вычисляем общий процент выполнения
|
||||||
if len(groupAverages) > 0 {
|
total := calculateOverallProgress(groups)
|
||||||
sum := 0.0
|
|
||||||
for _, avg := range groupAverages {
|
|
||||||
sum += avg
|
|
||||||
}
|
|
||||||
overallProgress := sum / float64(len(groupAverages))
|
|
||||||
overallProgressRounded := roundToFourDecimals(overallProgress)
|
|
||||||
total = &overallProgressRounded
|
|
||||||
}
|
|
||||||
|
|
||||||
response := WeeklyStatsResponse{
|
response := WeeklyStatsResponse{
|
||||||
Total: total,
|
Total: total,
|
||||||
@@ -3681,6 +3565,57 @@ func roundToFourDecimals(val float64) float64 {
|
|||||||
return float64(int(val*10000+0.5)) / 10000.0
|
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
|
// TelegramIntegration представляет запись из таблицы telegram_integrations
|
||||||
type TelegramIntegration struct {
|
type TelegramIntegration struct {
|
||||||
ID int `json:"id"`
|
ID int `json:"id"`
|
||||||
|
|||||||
Reference in New Issue
Block a user