rinogeek's picture
first commit
fafd0bb
# ============================================
# apps/gamification/services.py
# ============================================
from django.conf import settings
from apps.gamification.models import Badge, UserBadge, BadgeCriteria
class BadgeService:
"""Service pour gérer l'attribution automatique des badges"""
@staticmethod
def check_and_award_badges(user):
"""Vérifier et attribuer les badges gagnés"""
awarded_badges = []
# Récupérer tous les badges actifs
badges = Badge.objects.filter(is_active=True)
for badge in badges:
# Vérifier si l'utilisateur a déjà ce badge
if UserBadge.objects.filter(
user=user,
badge=badge,
is_active=True
).exists():
continue
# Vérifier les critères
if BadgeService._check_badge_criteria(user, badge):
user_badge = UserBadge.objects.create(
user=user,
badge=badge
)
awarded_badges.append(user_badge)
# Créer notification
from apps.notifications.services import NotificationService
NotificationService.create_badge_notification(user_badge)
return awarded_badges
@staticmethod
def _check_badge_criteria(user, badge):
"""Vérifier si l'utilisateur remplit les critères du badge"""
criteria = badge.criteria.filter(is_active=True)
for criterion in criteria:
criteria_type = criterion.criteria_type
criteria_value = criterion.criteria_value
if criteria_type == 'POINTS_THRESHOLD':
required_points = criteria_value.get('points', 0)
if user.points >= required_points:
return True
elif criteria_type == 'FIRST_ACTION':
action = criteria_value.get('action')
if action == 'first_question':
if user.questions.filter(is_active=True).exists():
return True
elif action == 'first_answer':
if user.answers.filter(is_active=True).exists():
return True
elif action == 'become_mentor':
if hasattr(user, 'mentor_profile') and user.mentor_profile.is_active:
return True
elif criteria_type == 'ACTION_COUNT':
action = criteria_value.get('action')
count = criteria_value.get('count', 0)
if action == 'questions_posted':
if user.questions.filter(is_active=True).count() >= count:
return True
elif action == 'answers_posted':
if user.answers.filter(is_active=True).count() >= count:
return True
return False
@staticmethod
def initialize_default_badges():
"""Créer les badges par défaut"""
from apps.gamification.models import (
BadgeName, BadgeDescription, BadgeIcon, BadgeColor
)
default_badges = [
{
'code': 'first_step',
'name': 'Premier Pas',
'description': 'Posez votre première question',
'icon': '🌱',
'color': 'green',
'criteria': {'type': 'FIRST_ACTION', 'value': {'action': 'first_question'}}
},
{
'code': 'curious',
'name': 'Curieux',
'description': 'Atteignez 100 points',
'icon': '🔍',
'color': 'blue',
'criteria': {'type': 'POINTS_THRESHOLD', 'value': {'points': 100}}
},
{
'code': 'engaged',
'name': 'Engagé',
'description': 'Atteignez 500 points',
'icon': '⭐',
'color': 'yellow',
'criteria': {'type': 'POINTS_THRESHOLD', 'value': {'points': 500}}
},
{
'code': 'expert',
'name': 'Expert',
'description': 'Atteignez 1000 points',
'icon': '🏆',
'color': 'gold',
'criteria': {'type': 'POINTS_THRESHOLD', 'value': {'points': 1000}}
},
{
'code': 'master',
'name': 'Maître',
'description': 'Atteignez 2500 points',
'icon': '👑',
'color': 'purple',
'criteria': {'type': 'POINTS_THRESHOLD', 'value': {'points': 2500}}
},
{
'code': 'legend',
'name': 'Légende',
'description': 'Atteignez 5000 points',
'icon': '💎',
'color': 'diamond',
'criteria': {'type': 'POINTS_THRESHOLD', 'value': {'points': 5000}}
},
]
for badge_data in default_badges:
badge, created = Badge.objects.get_or_create(
code=badge_data['code']
)
if created:
BadgeName.objects.create(badge=badge, name=badge_data['name'])
BadgeDescription.objects.create(badge=badge, description=badge_data['description'])
BadgeIcon.objects.create(badge=badge, icon=badge_data['icon'])
BadgeColor.objects.create(badge=badge, color=badge_data['color'])
BadgeCriteria.objects.create(
badge=badge,
criteria_type=badge_data['criteria']['type'],
criteria_value=badge_data['criteria']['value']
)