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/forms/base.py b/applications/forms/base.py index c79835cd0..4659731cf 100644 --- a/applications/forms/base.py +++ b/applications/forms/base.py @@ -39,6 +39,7 @@ def get_exclude_fields(): "status_update_date", "status", "contacted_by", + "dubious_type", "blacklisted_by", ] diff --git a/applications/migrations/0063_auto_20251228_1841.py b/applications/migrations/0063_auto_20251228_1841.py new file mode 100644 index 000000000..e5672efb6 --- /dev/null +++ b/applications/migrations/0063_auto_20251228_1841.py @@ -0,0 +1,31 @@ +# Generated by Django 3.2.23 on 2025-12-28 18:41 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('applications', '0062_auto_20251228_1817'), + ] + + operations = [ + migrations.AddField( + model_name='hackerapplication', + name='dubious_comment', + field=models.TextField(blank=True, max_length=500, null=True), + ), + 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'), ('OTHER', 'Other')], 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/models/constants.py b/applications/models/constants.py index 1e967e275..bb4affc02 100644 --- a/applications/models/constants.py +++ b/applications/models/constants.py @@ -110,3 +110,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 facece336..f2170a5ba 100644 --- a/applications/models/hacker.py +++ b/applications/models/hacker.py @@ -35,16 +35,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 @@ -101,10 +98,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() @@ -113,6 +113,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: