diff --git a/NorahUniversity/settings.py b/NorahUniversity/settings.py index 8da31e5..3381737 100644 --- a/NorahUniversity/settings.py +++ b/NorahUniversity/settings.py @@ -491,4 +491,43 @@ MESSAGE_TAGS = { AUTH_USER_MODEL = "recruitment.CustomUser" -ZOOM_WEBHOOK_API_KEY = "2GNDC5Rvyw9AHoGikHXsQB" \ No newline at end of file +ZOOM_WEBHOOK_API_KEY = "2GNDC5Rvyw9AHoGikHXsQB" + + + +#logger: +LOGGING={ + "version": 1, + "disable_existing_loggers": False, + "handlers": { + "file": { + "class": "logging.FileHandler", + "filename": os.path.join(BASE_DIR, "general.log"), + "level": "DEBUG", + "formatter": "verbose", + }, + "console":{ + "class": "logging.StreamHandler", + "level": "DEBUG", + "formatter": "simple" + } + + }, + "loggers": { + "": { + "handlers": ["file", "console"], + "level": "DEBUG", + "propagate": True, + }, + }, + "formatters": { + "verbose": { + "format": "[{asctime}] {levelname} [{name}:{lineno}] {message}", + "style": "{", + }, + "simple": { + "format": "{levelname} {message}", + "style": "{", + }, + } +} \ No newline at end of file diff --git a/recruitment/models.py b/recruitment/models.py index 1da11ba..46cc6f1 100644 --- a/recruitment/models.py +++ b/recruitment/models.py @@ -18,7 +18,7 @@ from .validators import validate_hash_tags, validate_image_size from django.contrib.auth.models import AbstractUser from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType -from django.db.models import F, Value, IntegerField, CharField +from django.db.models import F, Value, IntegerField, CharField,Q from django.db.models.functions import Coalesce, Cast from django.db.models.fields.json import KeyTransform, KeyTextTransform @@ -65,11 +65,20 @@ class CustomUser(AbstractUser): "unique": _("A user with this email already exists."), }, ) - + class Meta: verbose_name = _("User") verbose_name_plural = _("Users") + @property + def get_unread_message_count(self): + message_list = ( + Message.objects.filter(Q(sender=self) | Q(recipient=self), is_read=False) + ) + return message_list.count() or 0 + + + User = get_user_model() @@ -2108,6 +2117,7 @@ class HiringAgency(Base): # 2. Call the original delete method for the Agency instance super().delete(*args, **kwargs) + class AgencyJobAssignment(Base): @@ -2267,6 +2277,15 @@ class AgencyJobAssignment(Base): # self.save(update_fields=['status']) return True return False + @property + def applications_submited_count(self): + """Return the number of applications submitted by the agency for this job""" + return Application.objects.filter( + hiring_agency=self.agency, + job=self.job + ).count() + + def extend_deadline(self, new_deadline): """Extend the deadline for this assignment""" diff --git a/recruitment/views.py b/recruitment/views.py index fe75795..2b5f0d0 100644 --- a/recruitment/views.py +++ b/recruitment/views.py @@ -1,3 +1,7 @@ +#logger for recruitment views +import logging +logger = logging.getLogger(__name__) + import json import io import zipfile @@ -433,7 +437,7 @@ def create_job(request): job = form.save(commit=False) job.save() job_apply_url_relative = reverse( - "application_detail", kwargs={"slug": job.slug} + "job_application_detail", kwargs={"slug": job.slug} ) job_apply_url_absolute = request.build_absolute_uri( job_apply_url_relative @@ -712,7 +716,11 @@ def request_cvs_download(request, slug): """ View to initiate the background task. """ + job = get_object_or_404(JobPosting, slug=slug) + if job.status != 'CLOSED': + messages.info('request',_("You can request bulk CV dowload only if the job status is changed to CLOSED")) + return redirect('job_detail',kwargs={slug:job.slug}) job.zip_created = False job.save(update_fields=["zip_created"]) # Use async_task to run the function in the background @@ -732,6 +740,10 @@ def download_ready_cvs(request, slug): View to serve the file once it is ready. """ job = get_object_or_404(JobPosting, slug=slug) + if job.status != 'CLOSED': + messages.info('request',_("You can request bulk CV dowload only if the job status is changed to CLOSED")) + return redirect('job_detail',kwargs={slug:job.slug}) + if not job.applications.exists(): messages.warning(request, _("No applications found for this job. ZIP file download unavailable.")) return redirect('job_detail', slug=slug) @@ -3331,6 +3343,7 @@ def agency_detail(request, slug): hired_applications = applications.filter(stage="Hired").count() rejected_applications = applications.filter(stage="Rejected").count() job_assignments=AgencyJobAssignment.objects.filter(agency=agency) + total_job_assignments=job_assignments.count() print(job_assignments) context = { "agency": agency, @@ -3342,7 +3355,8 @@ def agency_detail(request, slug): "generated_password": agency.generated_password if agency.generated_password else None, - "job_assignments":job_assignments + "job_assignments":job_assignments, + "total_job_assignments":total_job_assignments, } return render(request, "recruitment/agency_detail.html", context) @@ -3747,7 +3761,8 @@ def agency_assignment_list(request): if search_query: assignments = assignments.filter( Q(agency__name__icontains=search_query) - | Q(job__title__icontains=search_query) + | Q(job__title__icontains=search_query)| + Q(agency__contact_person__icontains=search_query) ) if status_filter: diff --git a/templates/base.html b/templates/base.html index eeddbc3..a565230 100644 --- a/templates/base.html +++ b/templates/base.html @@ -20,6 +20,7 @@ + {% block customCSS %}{% endblock %} @@ -134,12 +135,23 @@ {% endif %} - - + {% endcomment %} + + +