From 4e40d564127bf65c62a938480c03f92393ae92ce Mon Sep 17 00:00:00 2001 From: ismail Date: Mon, 24 Nov 2025 14:46:20 +0300 Subject: [PATCH] add job_internal id to integration --- recruitment/erp_integration_service.py | 2 ++ recruitment/views.py | 6 ++---- recruitment/views_frontend.py | 17 ++++++++++------- recruitment/views_integration.py | 13 ++++++++++++- 4 files changed, 26 insertions(+), 12 deletions(-) diff --git a/recruitment/erp_integration_service.py b/recruitment/erp_integration_service.py index 5a5978f..9e0f3fa 100644 --- a/recruitment/erp_integration_service.py +++ b/recruitment/erp_integration_service.py @@ -25,6 +25,7 @@ class ERPIntegrationService: Validate the incoming request from ERP system Returns: (is_valid, error_message) """ + # Check if source is active if not self.source.is_active: return False, "Source is not active" @@ -70,6 +71,7 @@ class ERPIntegrationService: try: # Map ERP fields to JobPosting fields job_data = { + 'internal_job_id': request_data.get('job_id', '').strip(), 'title': request_data.get('title', '').strip(), 'department': request_data.get('department', '').strip(), 'job_type': self.map_job_type(request_data.get('job_type', 'FULL_TIME')), diff --git a/recruitment/views.py b/recruitment/views.py index b8df4f1..eb00fdb 100644 --- a/recruitment/views.py +++ b/recruitment/views.py @@ -187,7 +187,6 @@ class PersonCreateView(CreateView): template_name = "people/create_person.html" form_class = PersonForm success_url = reverse_lazy("person_list") - print("from agency") def form_valid(self, form): if "HX-Request" in self.request.headers: instance = form.save() @@ -196,7 +195,6 @@ class PersonCreateView(CreateView): slug = self.request.POST.get("agency") if slug: agency = HiringAgency.objects.get(slug=slug) - print(agency) instance.agency = agency instance.save() return redirect("agency_portal_persons_list") @@ -806,11 +804,11 @@ def kaauh_career(request): selected_job_type = request.GET.get("employment_type", "") job_type_keys = active_jobs.order_by("job_type").distinct("job_type").values_list("job_type", flat=True) - + workplace_type_keys = active_jobs.order_by("workplace_type").distinct("workplace_type").values_list( "workplace_type", flat=True ).distinct() - + if selected_job_type and selected_job_type in job_type_keys: active_jobs = active_jobs.filter(job_type=selected_job_type) if selected_workplace_type and selected_workplace_type in workplace_type_keys: diff --git a/recruitment/views_frontend.py b/recruitment/views_frontend.py index e9c4fb7..a03857a 100644 --- a/recruitment/views_frontend.py +++ b/recruitment/views_frontend.py @@ -162,7 +162,7 @@ class ApplicationListView(LoginRequiredMixin, StaffRequiredMixin, ListView): Q(person__first_name__icontains=search_query) | Q(person__last_name__icontains=search_query) | Q(person__email__icontains=search_query) | - Q(person__phone__icontains=search_query) + Q(person__phone__icontains=search_query) ) if job: queryset = queryset.filter(job__slug=job) @@ -202,11 +202,14 @@ class ApplicationCreateView(LoginRequiredMixin, StaffRequiredMixin, SuccessMessa job = get_object_or_404(models.JobPosting, slug=self.kwargs['slug']) form.instance.job = job return super().form_valid(form) + def form_invalid(self, form): + messages.error(self.request, f"{form.errors.as_text()}") + return super().form_invalid(form) def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) - if self.request.method == 'GET': - context['person_form'] = forms.PersonForm() + # if self.request.method == 'GET': + context['person_form'] = forms.PersonForm() return context class ApplicationUpdateView(LoginRequiredMixin, StaffRequiredMixin, SuccessMessageMixin, UpdateView): @@ -459,9 +462,9 @@ def dashboard_view(request): # NullIf( # # 2. Use Replace to remove the literal double quotes (") that might be present. # Replace( - # # 1. Use the double-underscore path (which uses the ->> operator for the final value) + # # 1. Use the double-underscore path (which uses the ->> operator for the final value) # # and cast to CharField for text-based cleanup functions. - # Cast(SCORE_PATH, output_field=CharField()), + # Cast(SCORE_PATH, output_field=CharField()), # Value('"'), Value('') # Replace the double quote character with an empty string # ), # Value('') # Value to check for (empty string) @@ -469,10 +472,10 @@ def dashboard_view(request): # output_field=IntegerField() # 4. Cast the clean, non-empty string (or NULL) to an integer. # ) - + # candidates_with_score_query= candidate_queryset.filter(is_resume_parsed=True).annotate( # # The Coalesce handles NULL values (from missing data, non-numeric data, or NullIf) and sets them to 0. - # annotated_match_score=Coalesce(safe_match_score_cast, Value(0)) + # annotated_match_score=Coalesce(safe_match_score_cast, Value(0)) # ) diff --git a/recruitment/views_integration.py b/recruitment/views_integration.py index 82b6aa6..91451e8 100644 --- a/recruitment/views_integration.py +++ b/recruitment/views_integration.py @@ -81,6 +81,17 @@ class ERPIntegrationView(View): 'message': 'Source not found' }, status=404) + job_id = data.get('job_id') + if not job_id: + return JsonResponse({ + 'status': 'error', + 'message': 'Job ID is required and must be unique' + }) + if JobPosting.objects.filter(internal_job_id=job_id).exists(): + return JsonResponse({ + 'status': 'error', + 'message': 'Job with this ID already exists' + }, status=400) # Create integration service service = ERPIntegrationService(source) @@ -144,6 +155,7 @@ class ERPIntegrationView(View): def _create_job(self, service: ERPIntegrationService, data: Dict[str, Any]) -> tuple[Dict[str, Any], str]: """Create a new job from ERP data""" # Validate ERP data + # print(data) is_valid, error_msg = service.validate_erp_data(data) if not is_valid: return None, error_msg @@ -152,7 +164,6 @@ class ERPIntegrationView(View): job, error_msg = service.create_job_from_erp(data) if error_msg: return None, error_msg - # Prepare response data response_data = { 'job_id': job.internal_job_id,