diff --git a/app/static/css/custom-bootstrap.css b/app/static/css/custom-bootstrap.css index 3b84de3c5..c68890f41 100644 --- a/app/static/css/custom-bootstrap.css +++ b/app/static/css/custom-bootstrap.css @@ -817,7 +817,7 @@ a.btn.disabled,fieldset[disabled] a.btn{pointer-events:none} .btn-group-lg>.btn,.btn-lg{line-height:1.3333333;border-radius:8px} .btn-group-sm>.btn,.btn-sm{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:8px} .btn-group-xs>.btn,.btn-xs{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:8px} -.btn-block{display:block;width:100%} +.btn-block{display:block;width:100%;margin-top:5px} .btn-block+.btn-block{margin-top:5px} input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%} .fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear} diff --git a/applications/migrations/0058_auto_20250511_1425.py b/applications/migrations/0058_auto_20250511_1425.py new file mode 100644 index 000000000..1e7b7907e --- /dev/null +++ b/applications/migrations/0058_auto_20250511_1425.py @@ -0,0 +1,27 @@ +# Generated by Django 3.2.23 on 2025-05-11 14:25 + +from django.conf import settings +import django.core.validators +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('applications', '0057_auto_20250203_2145'), + ] + + operations = [ + migrations.AddField( + model_name='hackerapplication', + name='dubious_type', + field=models.CharField(choices=[('OK', 'Not dubious'), ('INVALID_CV', 'Invalid CV'), ('LATE_GRAD', 'Invalid graduation year'), ('NOT_STUDENT', 'Not a student'), ('INVALID_SCHOOL', 'Invalid school')], default='OK', max_length=300), + ), + migrations.AddField( + model_name='hackerapplication', + name='dubioused_by', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='dubioused_by', to=settings.AUTH_USER_MODEL), + ), + ] diff --git a/applications/migrations/0059_auto_20250511_1520.py b/applications/migrations/0059_auto_20250511_1520.py new file mode 100644 index 000000000..743bcf526 --- /dev/null +++ b/applications/migrations/0059_auto_20250511_1520.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.23 on 2025-05-11 15:20 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('applications', '0058_auto_20250511_1425'), + ] + + operations = [ + migrations.AddField( + model_name='hackerapplication', + name='dubious_comment', + field=models.TextField(blank=True, max_length=500, null=True), + ), + ] diff --git a/applications/migrations/0060_auto_20250511_1649.py b/applications/migrations/0060_auto_20250511_1649.py new file mode 100644 index 000000000..8f6dc6ab3 --- /dev/null +++ b/applications/migrations/0060_auto_20250511_1649.py @@ -0,0 +1,19 @@ +# Generated by Django 3.2.23 on 2025-05-11 16:49 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('applications', '0059_auto_20250511_1520'), + ] + + operations = [ + migrations.AlterField( + model_name='hackerapplication', + name='dubious_type', + field=models.CharField(choices=[('OK', 'Not dubious'), ('INVALID_CV', 'Invalid CV'), ('LATE_GRAD', 'Invalid graduation year'), ('NOT_STUDENT', 'Not a student'), ('INVALID_SCHOOL', 'Invalid school'), ('OTHER', 'Other')], default='OK', max_length=300), + ), + ] diff --git a/applications/models/constants.py b/applications/models/constants.py index dded778cb..b80ca7c9c 100644 --- a/applications/models/constants.py +++ b/applications/models/constants.py @@ -99,3 +99,19 @@ DEFAULT_YEAR = datetime.now().year + 1 ENGLISH_LEVEL = [(i, str(i)) for i in range(1, 5 + 1)] + +DUBIOUS_NONE = 'OK' +DUBIOUS_CV = 'INVALID_CV' +DUBIOUS_GRADUATION_YEAR = 'LATE_GRAD' +DUBIOUS_NOT_STUDENT = 'NOT_STUDENT' +DUBIOUS_SCHOOL = 'INVALID_SCHOOL' +DUBIOUS_OTHER = 'OTHER' + +DUBIOUS_TYPES = [ + (DUBIOUS_NONE, 'Not dubious'), + (DUBIOUS_CV, 'Invalid CV'), + (DUBIOUS_GRADUATION_YEAR, 'Invalid graduation year'), + (DUBIOUS_NOT_STUDENT, 'Not a student'), + (DUBIOUS_SCHOOL, 'Invalid school'), + (DUBIOUS_OTHER, 'Other') +] diff --git a/applications/models/hacker.py b/applications/models/hacker.py index 6e0a2dd99..4878f53a6 100644 --- a/applications/models/hacker.py +++ b/applications/models/hacker.py @@ -34,16 +34,13 @@ class HackerApplication(BaseApplication): projects = models.TextField(max_length=500, blank=True, null=True) # META - contacted = models.BooleanField( - default=False - ) # If a dubious application has been contacted yet - contacted_by = models.ForeignKey( - User, - related_name="contacted_by", - blank=True, - null=True, - on_delete=models.SET_NULL, - ) + dubious_type = models.CharField(max_length=300, choices=DUBIOUS_TYPES, default=DUBIOUS_NONE) # Type of dubious application + dubioused_by = models.ForeignKey(User, related_name='dubioused_by', blank=True, null=True, + on_delete=models.SET_NULL) # User who marked this application as dubious + dubious_comment = models.TextField(max_length=500, blank=True, null=True) # Comment for dubious application + contacted = models.BooleanField(default=False) # If a dubious application has been contacted yet + contacted_by = models.ForeignKey(User, related_name='contacted_by', blank=True, null=True, + on_delete=models.SET_NULL) reviewed = models.BooleanField( default=False @@ -100,10 +97,13 @@ def invalidate(self): team.delete() self.save() - def set_dubious(self): + def set_dubious(self, user, dubious_type, dubious_comment_text): self.status = APP_DUBIOUS self.contacted = False self.status_update_date = timezone.now() + self.dubioused_by = user + self.dubious_type = dubious_type + self.dubious_comment = dubious_comment_text self.vote_set.all().delete() if hasattr(self, "acceptedresume"): self.acceptedresume.delete() @@ -112,6 +112,9 @@ def set_dubious(self): def unset_dubious(self): self.status = APP_PENDING self.status_update_date = timezone.now() + self.dubioused_by = None + self.dubious_type = DUBIOUS_NONE + self.dubious_comment = None self.save() def set_flagged_cv(self): diff --git a/applications/templates/application.html b/applications/templates/application.html index 31ca5a8f0..e08d49786 100644 --- a/applications/templates/application.html +++ b/applications/templates/application.html @@ -24,16 +24,16 @@ {% endif %}
- {% if application.can_be_edit %} - - -

- Be careful, you can only edit the application until 2 hours after {{application.submission_date}}

+ {% if application.can_be_edit %} + + +

+ Be careful, you can only edit the application until 2 hours after {{application.submission_date}}

{% else %} -

Your application has been reviewed already. Editing has been disabled to make sure all reviewers get the +

Your application has been reviewed already. Editing has been disabled to make sure all reviewers get the same data. If you would like to change something important, please email us at {{ h_contact_email|urlize }}.

- {% endif %} + {% endif %}
{% include 'include/application_form.html' %} diff --git a/organizers/templates/application_detail.html b/organizers/templates/application_detail.html index 117c254f9..672a98afd 100644 --- a/organizers/templates/application_detail.html +++ b/organizers/templates/application_detail.html @@ -8,6 +8,30 @@ + + {% endblock %} {% block panel %} {% if app %} @@ -38,7 +62,7 @@

Personal

{% include 'include/field.html' with desc='Email' value=app.user.email %} {% include 'include/field.html' with desc='Travel reimbursement?' value=app.reimb|yesno:'Yes,No,Maybe' %} {% include 'include/field.html' with desc='Money needed' value=app.reimb_amount %} - {% include 'include/field.html' with desc='Origin' value=app.origin %} + {% include 'include/field.html' with desc='Origin' value=app.origin %} {% endif %} {% include 'include/field.html' with desc='Under age (-18)' value=app.under_age|yesno:'Yes,No,Maybe' %} {% if app.resume %} @@ -84,6 +108,27 @@

Background

Dubious info

+ {% include 'include/field.html' with desc='Sent to dubious by' value=app.dubioused_by %} + + {% if app.dubious_type == 'OK' %} + {% include 'include/field.html' with desc='Dubious reason' value='No reason selected' %} + {% elif app.dubious_type == 'INVALID_CV' %} + {% include 'include/field.html' with desc='Dubious reason' value='Invalid CV' %} + {% elif app.dubious_type == 'LATE_GRAD' %} + {% include 'include/field.html' with desc='Dubious reason' value='Wrong Graduation Date' %} + {% elif app.dubious_type == 'NOT_STUDENT' %} + {% include 'include/field.html' with desc='Dubious reason' value='Not a Student' %} + {% elif app.dubious_type == 'INVALID_SCHOOL' %} + {% include 'include/field.html' with desc='Dubious reason' value='Invalid School' %} + {% elif app.dubious_type == 'OTHER' %} + {% include 'include/field.html' with desc='Dubious reason' value='Other' %} + {% endif %} + + {% if app.dubious_comment %} + {% include 'include/field.html' with desc='Dubious Comment' value=app.dubious_comment %} + {% endif %} + +
{% include 'include/field.html' with desc='Contacted' value=app.contacted|yesno:'Yes,No,Maybe' %} {% include 'include/field.html' with desc='Contacted by' value=app.contacted_by %} {% endif %} @@ -145,7 +190,7 @@

{{ comment.text }}

- + @@ -209,10 +279,72 @@

Score

application {% if h_dubious_enabled %} - + + + + + + + + + + + {% endif %} {% if h_blacklist_enabled %} {% if h_dubious_enabled %} - + + + + + + + + + + + {% endif %} {% if h_blacklist_enabled %} + {% else%} + {% endif %} {% endblock %} diff --git a/organizers/views.py b/organizers/views.py index 996c78f27..01c6a18d0 100644 --- a/organizers/views.py +++ b/organizers/views.py @@ -359,9 +359,12 @@ def post(self, request, *args, **kwargs): id_ = request.POST.get("app_id") application = models.HackerApplication.objects.get(pk=id_) - comment_text = request.POST.get("comment_text", None) - motive_of_ban = request.POST.get("motive_of_ban", None) - if request.POST.get("add_comment"): + comment_text = request.POST.get('comment_text', None) + motive_of_ban = request.POST.get('motive_of_ban', None) + dubious_type = request.POST.get('dubious_type', None) + dubious_comment_text = request.POST.get('dubious_comment_text', None) + + if request.POST.get('add_comment'): add_comment(application, request.user, comment_text) elif request.POST.get("invite") and request.user.is_director: self.invite_application(application) @@ -373,8 +376,8 @@ def post(self, request, *args, **kwargs): self.waitlist_application(application) elif request.POST.get("slack") and request.user.is_organizer: self.slack_invite(application) - elif request.POST.get("set_dubious") and request.user.is_organizer: - application.set_dubious() + elif request.POST.get('set_dubious') and request.user.is_organizer: + application.set_dubious(request.user, dubious_type, dubious_comment_text) elif request.POST.get("set_flagged_cv") and request.user.is_organizer: application.set_flagged_cv() elif request.POST.get("unset_flagged_cv") and request.user.is_organizer: @@ -507,6 +510,8 @@ def post(self, request, *args, **kwargs): tech_vote = request.POST.get("tech_rat", None) pers_vote = request.POST.get("pers_rat", None) comment_text = request.POST.get("comment_text", None) + dubious_type = request.POST.get('dubious_type', None) + dubious_comment_text = request.POST.get('dubious_comment_text', None) application = models.HackerApplication.objects.get( pk=request.POST.get("app_id") @@ -520,7 +525,7 @@ def post(self, request, *args, **kwargs): "/applications/hacker/review/" + application.uuid_str ) elif request.POST.get("set_dubious"): - application.set_dubious() + application.set_dubious(request.user, dubious_type, dubious_comment_text) elif request.POST.get("unset_dubious"): application.unset_dubious() elif request.POST.get("set_flagged_cv") and request.user.is_organizer: @@ -610,6 +615,8 @@ def post(self, request, *args, **kwargs): tech_vote = request.POST.get("tech_rat", None) pers_vote = request.POST.get("pers_rat", None) comment_text = request.POST.get("comment_text", None) + dubious_type = request.POST.get('dubious_type', None) + dubious_comment_text = request.POST.get('dubious_comment_text', None) application = models.HackerApplication.objects.get( pk=request.POST.get("app_id") @@ -623,7 +630,7 @@ def post(self, request, *args, **kwargs): "/applications/hacker/review/" + application.uuid_str ) elif request.POST.get("set_dubious"): - application.set_dubious() + application.set_dubious(request.user, dubious_type, dubious_comment_text) elif request.POST.get("unset_dubious"): application.unset_dubious() elif request.POST.get("set_flagged_cv") and request.user.is_organizer: