mirror of
https://gitlab.crans.org/bde/nk20
synced 2025-08-14 09:56:38 +02:00
Achievement unicity && management pop-up behaviour
This commit is contained in:
@@ -75,13 +75,24 @@ class BatchAchievementsAPIView(APIView):
|
||||
challenge_ids = request.data.get('challenges')
|
||||
families = Family.objects.filter(id__in=family_ids)
|
||||
challenges = Challenge.objects.filter(id__in=challenge_ids)
|
||||
results = []
|
||||
for family in families:
|
||||
for challenge in challenges:
|
||||
a = Achievement(family=family, challenge=challenge)
|
||||
a.save(update_score=False)
|
||||
|
||||
a, created = Achievement.objects.get_or_create(family=family, challenge=challenge)
|
||||
if created:
|
||||
results.append({
|
||||
'family': family.name,
|
||||
'challenge': challenge.name,
|
||||
'status': 'created'
|
||||
})
|
||||
else:
|
||||
results.append({
|
||||
'family': family.name,
|
||||
'challenge': challenge.name,
|
||||
'status': 'error',
|
||||
})
|
||||
for family in families:
|
||||
family.update_score()
|
||||
Family.update_ranking()
|
||||
|
||||
return Response({'status': 'ok'}, status=status.HTTP_201_CREATED)
|
||||
return Response({'results': results}, status=status.HTTP_201_CREATED)
|
||||
|
@@ -0,0 +1,17 @@
|
||||
# Generated by Django 5.2.4 on 2025-08-13 20:26
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('family', '0004_remove_challenge_obtained'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterUniqueTogether(
|
||||
name='achievement',
|
||||
unique_together={('challenge', 'family')},
|
||||
),
|
||||
]
|
@@ -170,6 +170,7 @@ class Achievement(models.Model):
|
||||
)
|
||||
|
||||
class Meta:
|
||||
unique_together = ('challenge', 'family',)
|
||||
verbose_name = _('achievement')
|
||||
verbose_name_plural = _('achievements')
|
||||
|
||||
|
@@ -25,11 +25,6 @@ $(document).ready(function () {
|
||||
location.hash = this.getAttribute('href')
|
||||
})
|
||||
|
||||
|
||||
// Ensure we begin in single consumption. Fix issue with TurboLinks and BootstrapJS
|
||||
|
||||
|
||||
document.getElementById("consume_all").addEventListener('click', consumeAll)
|
||||
})
|
||||
|
||||
notes = []
|
||||
@@ -140,13 +135,25 @@ function consumeAll () {
|
||||
headers: {
|
||||
'X-CSRFToken': CSRF_TOKEN
|
||||
},
|
||||
success: function () {
|
||||
success: function (data) {
|
||||
reset()
|
||||
addMsg("Défis validés pour les familles !", 'success', 5000)
|
||||
},
|
||||
error: function (e) {
|
||||
reset()
|
||||
addMsg("Erreur lors de la création des achievements.",'danger',5000)
|
||||
data.results.forEach(function (result) {
|
||||
if (result.status === 'created') {
|
||||
addMsg(
|
||||
interpolate(gettext('Invalid achievement for challenge %s ' +
|
||||
'and family %s created.'), [result.challenge, result.family]),
|
||||
'success',
|
||||
5000
|
||||
)
|
||||
} else {
|
||||
addMsg(
|
||||
interpolate(gettext('An achievement for challenge %s ' +
|
||||
'and family %s already exists.'), [result.challenge, result.family]),
|
||||
'danger',
|
||||
8000
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -177,24 +177,26 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
<div class="modal-dialog modal-dialog-centered" role="document">
|
||||
<div class="modal-content border-success">
|
||||
<div class="modal-header bg-success text-white">
|
||||
<h5 class="modal-title" id="validationModalLabel">{% trans "Challenge validated" %}</h5>
|
||||
<h5 class="modal-title" id="validationModalLabel">{% trans "Confirmation" %}</h5>
|
||||
<button type="button" class="close text-white" data-dismiss="modal" aria-label="Close">
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<p><strong>Are you sure you want to validate this challenge?</strong></p>
|
||||
<p>To have your challenge officially validated, please send a message with:</p>
|
||||
<p><strong>{% trans "Are you sure you want to validate this challenge?" %}</strong></p>
|
||||
<p>{% trans "To have your challenge officially validated, please send a message with:" %}</p>
|
||||
<ul>
|
||||
<li>The name of the family</li>
|
||||
<li>The name of the challenge</li>
|
||||
<li>A photo or video as proof</li>
|
||||
<li>{% trans "The name of the family" %}</li>
|
||||
<li>{% trans "The name of the challenge" %}</li>
|
||||
<li>{% trans "A photo or video as proof" %}</li>
|
||||
</ul>
|
||||
<p>
|
||||
<strong>Send it via WhatsApp to:
|
||||
<strong>{% trans "Send it via WhatsApp to:" %}</strong>
|
||||
{% if phone_numbers %}"
|
||||
{% for num in phone_numbers %}
|
||||
<a href="https://wa.me/{{ num }}" target="_blank">{{ num }}</a>{% if not forloop.last %}, {% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</p>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
@@ -228,6 +230,10 @@ SPDX-License-Identifier: GPL-3.0-or-later
|
||||
$('#validationModal').modal('show');
|
||||
});
|
||||
|
||||
$('#validationModal .btn-primary').on('click', function () {
|
||||
consumeAll();
|
||||
});
|
||||
|
||||
{% if user_family %}
|
||||
document.getElementById("select_my_family").addEventListener("click", function () {
|
||||
// Simulate selecting the user's family
|
||||
|
@@ -7,7 +7,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2025-08-13 16:21+0200\n"
|
||||
"POT-Creation-Date: 2025-08-13 23:48+0200\n"
|
||||
"PO-Revision-Date: 2022-04-11 22:05+0200\n"
|
||||
"Last-Translator: ehouarn <ehouarn@crans.org>\n"
|
||||
"Language-Team: French <http://translate.ynerant.fr/projects/nk20/nk20/fr/>\n"
|
||||
@@ -589,7 +589,6 @@ msgstr "adhésions"
|
||||
|
||||
#: apps/family/models.py:108
|
||||
#, python-brace-format
|
||||
#| msgid "Membership of {user} for the club {club}"
|
||||
msgid "Family membership of {user} to {family}"
|
||||
msgstr "Adhésion de {user} à la famille {family}"
|
||||
|
||||
@@ -610,15 +609,15 @@ msgstr "défis"
|
||||
msgid "obtained at"
|
||||
msgstr "réalisé le"
|
||||
|
||||
#: apps/family/models.py:173
|
||||
#: apps/family/models.py:174
|
||||
msgid "achievement"
|
||||
msgstr "succès"
|
||||
|
||||
#: apps/family/models.py:174
|
||||
#: apps/family/models.py:175
|
||||
msgid "achievements"
|
||||
msgstr "succès"
|
||||
|
||||
#: apps/family/models.py:177
|
||||
#: apps/family/models.py:178
|
||||
#, python-brace-format
|
||||
msgid "Challenge {challenge} carried out by Family {family}"
|
||||
msgstr "Défi {challenge} réalisé par la famille {family}"
|
||||
@@ -655,15 +654,12 @@ msgid "Delete achievement"
|
||||
msgstr "Supprimer le succès"
|
||||
|
||||
#: apps/family/templates/family/achievement_confirm_delete.html:14
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Are you sure you want to delete this invoice? This action can't be undone."
|
||||
msgid ""
|
||||
"Are you sure you want to delete this achievement? This action can't be "
|
||||
"undone."
|
||||
msgstr ""
|
||||
"Êtes-vous sûr⋅e de vouloir supprimer cette facture ? Cette action ne pourra "
|
||||
"pas être annulée."
|
||||
"Êtes-vous sûr⋅e de vouloir supprimer ce succès ? Cette action ne pourra pas "
|
||||
"être annulée."
|
||||
|
||||
#: apps/family/templates/family/achievement_confirm_delete.html:20
|
||||
#: apps/family/templates/family/achievement_confirm_validate.html:20
|
||||
@@ -675,15 +671,12 @@ msgid "Validate achievement"
|
||||
msgstr "Valider le succès"
|
||||
|
||||
#: apps/family/templates/family/achievement_confirm_validate.html:14
|
||||
#, fuzzy
|
||||
#| msgid ""
|
||||
#| "Are you sure you want to delete this invoice? This action can't be undone."
|
||||
msgid ""
|
||||
"Are you sure you want to validate this achievement? This action can't be "
|
||||
"undone."
|
||||
msgstr ""
|
||||
"Êtes-vous sûr⋅e de vouloir supprimer cette facture ? Cette action ne pourra "
|
||||
"pas être annulée."
|
||||
"Êtes-vous sûr⋅e de vouloir valider ce succès ? Cette action ne pourra pas "
|
||||
"être annulée."
|
||||
|
||||
#: apps/family/templates/family/achievement_list.html:13
|
||||
msgid "Invalid achievements history"
|
||||
@@ -801,10 +794,36 @@ msgid "Recent achievements history"
|
||||
msgstr "Historique des derniers succès"
|
||||
|
||||
#: apps/family/templates/family/manage.html:180
|
||||
msgid "Challenge validated"
|
||||
msgstr "Défi validé"
|
||||
msgid "Confirmation"
|
||||
msgstr "Confirmation"
|
||||
|
||||
#: apps/family/templates/family/manage.html:201
|
||||
#: apps/family/templates/family/manage.html:186
|
||||
msgid "Are you sure you want to validate this challenge?"
|
||||
msgstr "Êtes-vous sûr⋅e de vouloir valider ce défi ?"
|
||||
|
||||
#: apps/family/templates/family/manage.html:187
|
||||
msgid ""
|
||||
"To have your challenge officially validated, please send a message with:"
|
||||
msgstr ""
|
||||
"Pour que le défi soit officiellement validé, envoyez un message contenant :"
|
||||
|
||||
#: apps/family/templates/family/manage.html:189
|
||||
msgid "The name of the family"
|
||||
msgstr "Le nom de la famille"
|
||||
|
||||
#: apps/family/templates/family/manage.html:190
|
||||
msgid "The name of the challenge"
|
||||
msgstr "Le nom du défi"
|
||||
|
||||
#: apps/family/templates/family/manage.html:191
|
||||
msgid "A photo or video as proof"
|
||||
msgstr "Une preuve photo ou vidéo"
|
||||
|
||||
#: apps/family/templates/family/manage.html:194
|
||||
msgid "Send it via WhatsApp to:"
|
||||
msgstr "Envoyez le via WhasApp au :"
|
||||
|
||||
#: apps/family/templates/family/manage.html:202
|
||||
msgid "OK"
|
||||
msgstr "OK"
|
||||
|
||||
@@ -4641,6 +4660,9 @@ msgstr ""
|
||||
"d'adhésion. Vous devez également valider votre adresse email en suivant le "
|
||||
"lien que vous avez reçu."
|
||||
|
||||
#~ msgid "Challenge validated"
|
||||
#~ msgstr "Défi validé"
|
||||
|
||||
#~ msgid "Deposit amount"
|
||||
#~ msgstr "Caution"
|
||||
|
||||
|
Reference in New Issue
Block a user