From 98e13df2f6749d4acd2fdac35ff8b79068da41bd Mon Sep 17 00:00:00 2001 From: Marwan Alwali Date: Thu, 6 Nov 2025 14:52:40 +0300 Subject: [PATCH] update --- .../availability_service.cpython-312.pyc | Bin 0 -> 12253 bytes core/__pycache__/services.cpython-312.pyc | Bin 0 -> 21935 bytes core/__pycache__/signals.cpython-312.pyc | Bin 14779 -> 15049 bytes core/signals.py | 18 +- db.sqlite3 | Bin 8687616 -> 8691712 bytes logs/django.log | 553 ++++++++++++++++++ referrals/__pycache__/views.cpython-312.pyc | Bin 30354 -> 31310 bytes .../referrals/external_referral_form.html | 316 +++++----- .../referrals/external_referral_success.html | 42 +- referrals/views.py | 97 +-- 10 files changed, 818 insertions(+), 208 deletions(-) create mode 100644 appointments/__pycache__/availability_service.cpython-312.pyc create mode 100644 core/__pycache__/services.cpython-312.pyc diff --git a/appointments/__pycache__/availability_service.cpython-312.pyc b/appointments/__pycache__/availability_service.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..afa241f280a7b0deaf258dab5b6c98480e36f3fd GIT binary patch literal 12253 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 literal 0 HcmV?d00001 diff --git a/core/__pycache__/services.cpython-312.pyc b/core/__pycache__/services.cpython-312.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ac55a7dd5cbb204124d975f668c95e14cd66c2e9 GIT binary patch literal 21935 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 delta 2059 zcmah~Uu;uV81HF&+tIFnM!R)m>vq}L)(*;uV+~2$!xsD;?eK_--q1 z#LUGYkock}{y|M3(FgZpT&hosi6lOVFA`!PH~Oj}#`p&k6JPZEPP=YHi8tvl-~G;a zf9Lo8Ij3LeKQp}Fcswo(KBq2LrWd;xy{ByjYsDmEqvC?ncl=p=Vx#hLsrW2dO-GLF zaXn}H6Tss+p48$wO`G9y_{$wzcHRFQpZg4nP1}}j$!H~1NL$aIH|-QHypGUtMHZ4A zwDB2JnMi|?Gi_6#o3=F4yN<>)c|HV?1=F=pPx2R}9aSJeM3sp=0M~PJXQ4YHih^!c zyyF;DB52i#%Pw_uu>P(7*ZS`UqPGLld%o&>b*;ZCmSD#Ni!JE*(_wM?=FePy@s1;W zjbG*OrbNWqT=5~?ZhYd-x~|vVhie|JMW!z|g$Dwbn}Mo<4%^Kr8|WxJbbij}fYzXz zpoSnsP>WDX73#>bj=)V&PtZURCTK)3-4p2y*Yy0Mp_C`IplzcU#wQXqp9p+H14yr{_JUHlYdB zgkq~4nQSV>!L+CKiR^+6wu_&=jSW(>e>$E^Qx~U!YexKe4*mGqDbecN&3XzGzJ$U8 z;#QEeCb6Zuo&^dAs>fKEgrhV$esT-wrOlosXc9MSB5X+fShI)i7agI^BgfFapul!o z-GyK}OH&Gcb!FCKePd9`qVo&U+xQXd5%YC*1#8m@Hb8xq!vI@X zQ~Wzu|I(C{(*^wGdvQ%Yi0S^Kp0utnri)&juye#GWlCnLa7vtQiOfAVQ5wqs%yu=G z>D1#>T;n?YPufUlR+UvRHQNn&T)2-v<5SV!sES=1u3`drH>@r7Yp?jVt#)n%17@oZ z6(?9t@(jn@uvdkr(LWmXz+FlnjiU?8R36+F^GavW zQ969Dw%01N_-+#m?N?A{SLBL~9Tqn>UJZ|-d)E7m!9gv}e6KodRU;;g!ZBfN`oNvQ z2=EgmMRTmPZTTQ^a?;s}I#x(Xk+)BrkF~6m2iTiOa&3C4a&QsXn+u=B&e1Vx>(uN_ z7q4_pvZLbnt}#@#ck9u)Bg7%4`S)aX1CPIIq*FT8ZZul8JfwKX7nil%%rsw~Wphn2 z9RGMgs=P#mK7u5{@)@8CnzbpO(^fEv`fgWmId9WjA{(F4XlPayyqGPLti0^B?vNtT zccgHk`)y291bcoOF4t|r0zD)`R>z0i>O6s02<8{h81N=8y^Mc~Mim+_SswZ=iu=;Y z{K&Wd$anTA^oW7&U!9g*^7@olj68sJEdt#^KsN}`Nd-Dwa#DfXFG~+3Ozr}2khLtO fV&_ygna}V(xGqvV29*$N`eSS1;~mw^PC@?w?8x#J diff --git a/core/signals.py b/core/signals.py index be80cfb5..d3981078 100644 --- a/core/signals.py +++ b/core/signals.py @@ -25,26 +25,28 @@ logger = logging.getLogger(__name__) def generate_mrn(tenant): """ Generate unique Medical Record Number (MRN). - Format: YYYY-NNNNNN + Format: NNNNNN (6 digits) """ - current_year = timezone.now().year - - # Get last patient for this tenant in current year + # Get the highest MRN number for this tenant last_patient = Patient.objects.filter( tenant=tenant, - created_at__year=current_year - ).order_by('-created_at').first() + mrn__isnull=False + ).exclude(mrn='').order_by('-mrn').first() if last_patient and last_patient.mrn: # Extract number from last MRN try: - last_number = int(last_patient.mrn[-1]) + last_number = int(last_patient.mrn) new_number = last_number + 1 - except (ValueError, IndexError): + except (ValueError, TypeError): new_number = 1 else: new_number = 1 + # Ensure uniqueness by checking if MRN already exists + while Patient.objects.filter(tenant=tenant, mrn=f"{new_number:06d}").exists(): + new_number += 1 + return f"{new_number:06d}" diff --git a/db.sqlite3 b/db.sqlite3 index ac411fef196b080caa081e4a4568c40a0a80bd3f..be4b60755c80da58742ac1b8cf876207174117c8 100644 GIT binary patch delta 4872 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 delta 2252 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%0DC#kz| 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 b@`dMf#u&3*b3V|~{|93RXdZKA(7gT!k {% trans "External Referral" %} - {% if tenant %}{{ tenant.name }}{% else %}Agdar Centre{% endif %} - {% load static i18n %} - - + + + {% if LANGUAGE_CODE == 'ar' %} + + + {% else %} + + {% endif %} + + +
-
-
-

{% trans "External Referral Form" %}

-

{% if tenant %}{{ tenant.name }}{% else %}{% trans "Agdar Centre" %}{% endif %}

-
- -
-
- - {% trans "Welcome!" %} {% trans "Please fill out this form to refer a patient to our center. We will review your referral and contact you within 24-48 hours with next steps." %} + + + + +
+ + {% trans "Welcome!" %} {% trans "Please fill out this form to refer a patient to our center. We will review your referral and contact you within 24-48 hours with next steps." %} +
+ + + {% if messages %} + {% for message in messages %} + + {% endfor %} + {% endif %} - {% if messages %} - {% for message in messages %} - - {% endfor %} - {% endif %} - -
- {% csrf_token %} - - -
-

{% trans "Referring Center Information" %}

-
-
- + + {% csrf_token %} + + +
+
+
+
+ {% trans "Referring Center Information" %} +
+
+
+
+
+ {{ form.referring_center_name }} {% if form.referring_center_name.errors %}
{{ form.referring_center_name.errors }}
{% endif %}
-
- +
+ {{ form.referring_doctor_name }} {% if form.referring_doctor_name.errors %}
{{ form.referring_doctor_name.errors }}
{% endif %}
-
- +
+ {{ form.referring_contact_phone }} {% if form.referring_contact_phone.errors %}
{{ form.referring_contact_phone.errors }}
{% endif %}
-
- +
+ {{ form.referring_contact_email }} {% if form.referring_contact_email.errors %}
{{ form.referring_contact_email.errors }}
@@ -160,41 +141,49 @@
+
+
- -
-

{% trans "Patient Information" %}

-
-
- + +
+
+
+
+ {% trans "Patient Information" %} +
+
+
+
+
+ {{ form.patient_first_name }} {% if form.patient_first_name.errors %}
{{ form.patient_first_name.errors }}
{% endif %}
-
- +
+ {{ form.patient_last_name }} {% if form.patient_last_name.errors %}
{{ form.patient_last_name.errors }}
{% endif %}
-
- +
+ {{ form.patient_date_of_birth }} {% if form.patient_date_of_birth.errors %}
{{ form.patient_date_of_birth.errors }}
{% endif %}
-
- +
+ {{ form.patient_sex }} {% if form.patient_sex.errors %}
{{ form.patient_sex.errors }}
{% endif %}
-
- +
+ {{ form.patient_national_id }} {% if form.patient_national_id.errors %}
{{ form.patient_national_id.errors }}
@@ -202,27 +191,35 @@
+
+
- -
-

{% trans "Parent/Guardian Information" %}

-
-
- + +
+
+
+
+ {% trans "Parent/Guardian Information" %} +
+
+
+
+
+ {{ form.caregiver_name }} {% if form.caregiver_name.errors %}
{{ form.caregiver_name.errors }}
{% endif %}
-
- +
+ {{ form.caregiver_phone }} {% if form.caregiver_phone.errors %}
{{ form.caregiver_phone.errors }}
{% endif %}
-
- +
+ {{ form.caregiver_relationship }} {% if form.caregiver_relationship.errors %}
{{ form.caregiver_relationship.errors }}
@@ -230,34 +227,42 @@
+
+
- -
-

{% trans "Referral Details" %}

-
-
- + +
+
+
+
+ {% trans "Referral Details" %} +
+
+
+
+
+ {{ form.urgency }} {% if form.urgency.errors %}
{{ form.urgency.errors }}
{% endif %}
-
- +
+ {{ form.requested_specialty }} {% if form.requested_specialty.errors %}
{{ form.requested_specialty.errors }}
{% endif %}
-
- +
+ {{ form.reason }} {% if form.reason.errors %}
{{ form.reason.errors }}
{% endif %}
-
- +
+ {{ form.clinical_summary }} {% trans "Include diagnosis, current treatment, medications, etc." %} {% if form.clinical_summary.errors %} @@ -266,25 +271,32 @@
- - {% if form.non_field_errors %} -
- {{ form.non_field_errors }} -
- {% endif %} - - - +
-
- -
+ + + {% if form.non_field_errors %} +
+ {{ form.non_field_errors }} +
+ {% endif %} + + +
+ +
+ + + +
- + + + diff --git a/referrals/templates/referrals/external_referral_success.html b/referrals/templates/referrals/external_referral_success.html index 0370f113..c71ae77b 100644 --- a/referrals/templates/referrals/external_referral_success.html +++ b/referrals/templates/referrals/external_referral_success.html @@ -1,15 +1,24 @@ +{% load i18n static %} - {% trans "Referral Submitted Successfully" %} - {% trans "Agdar Centre" %} - {% load static i18n %} - - + {% trans "Referral Submitted Successfully" %} - {% if tenant %}{{ tenant.name }}{% else %}Agdar Centre{% endif %} + + + {% if LANGUAGE_CODE == 'ar' %} + + + {% else %} + + {% endif %} + + + @@ -144,11 +158,13 @@
-
-

© 2025 {% trans "Agdar Centre" %}. {% trans "All rights reserved." %}

+
- + + + diff --git a/referrals/views.py b/referrals/views.py index abc04b61..f24d8994 100644 --- a/referrals/views.py +++ b/referrals/views.py @@ -55,10 +55,13 @@ class ReferralListView(LoginRequiredMixin, TenantFilterMixin, PaginationMixin, # Role-based filtering if user.role in [User.Role.DOCTOR, User.Role.NURSE, User.Role.OT, User.Role.SLP, User.Role.ABA]: - # Clinical staff see referrals from or to them + # Clinical staff see referrals from or to them, plus external referrals to their clinic queryset = queryset.filter( - Q(from_provider=user) | Q(to_provider=user) + Q(from_provider=user) | + Q(to_provider=user) | + Q(from_discipline=Referral.Discipline.EXTERNAL, to_clinic__isnull=False) ) + # Admins and other roles see all referrals (no additional filtering needed) # Apply search search_query = self.request.GET.get('search', '').strip() @@ -123,12 +126,29 @@ class ReferralListView(LoginRequiredMixin, TenantFilterMixin, PaginationMixin, 'date_to': self.request.GET.get('date_to', ''), } - # Add statistics + # Get all referrals queryset = self.get_queryset() + + # Split into sent and received + user = self.request.user + if user.role == User.Role.ADMIN: + # Admins see all referrals in both tabs + context['sent_referrals'] = queryset.filter(from_provider__isnull=False) + context['received_referrals'] = queryset + else: + # Clinical staff see their sent and received referrals + context['sent_referrals'] = queryset.filter(from_provider=user) + context['received_referrals'] = queryset.filter( + Q(to_provider=user) | + Q(from_discipline=Referral.Discipline.EXTERNAL, to_clinic__isnull=False) + ) + + # Add statistics context['stats'] = { 'total_referrals': queryset.count(), 'pending': queryset.filter(status=Referral.Status.PENDING).count(), 'accepted': queryset.filter(status=Referral.Status.ACCEPTED).count(), + 'completed': queryset.filter(status=Referral.Status.COMPLETED).count(), 'urgent': queryset.filter(urgency=Referral.Urgency.URGENT).count(), } @@ -507,53 +527,60 @@ class ExternalReferralCreateView(FormView): ).first() if not patient: - # Generate MRN for new patient - from core.services import generate_mrn - patient_data['mrn'] = generate_mrn(tenant) + # Create new patient (MRN will be auto-generated by signal) patient = Patient.objects.create(**patient_data) - # Create referral - referral = form.instance - referral.tenant = tenant - referral.patient = patient - - # Set external provider information - referral.external_provider_name = form.cleaned_data['referring_center_name'] - referral.external_provider_contact = ( - f"Doctor: {form.cleaned_data['referring_doctor_name']}\n" - f"Phone: {form.cleaned_data['referring_contact_phone']}\n" - f"Email: {form.cleaned_data['referring_contact_email']}" + # Get or create an "External" clinic for external referrals + from core.models import Clinic + from_clinic, _ = Clinic.objects.get_or_create( + tenant=tenant, + code='EXT', + defaults={ + 'name_en': 'External Referrals', + 'name_ar': 'الإحالات الخارجية', + 'specialty': 'EXTERNAL', + 'is_active': True, + } ) - # Set referral details - referral.reason = form.cleaned_data['reason'] - referral.urgency = form.cleaned_data['urgency'] - referral.clinical_summary = form.cleaned_data.get('clinical_summary', '') - referral.from_discipline = Referral.Discipline.EXTERNAL - referral.status = Referral.Status.PENDING - - # Map requested specialty to clinic + # Map requested specialty to target clinic + to_clinic = None + to_discipline = None requested_specialty = form.cleaned_data.get('requested_specialty') if requested_specialty: - from core.models import Clinic to_clinic = Clinic.objects.filter( tenant=tenant, specialty=requested_specialty, is_active=True ).first() if to_clinic: - referral.to_clinic = to_clinic - referral.to_discipline = requested_specialty + to_discipline = requested_specialty - # Store referring center contact info in notes - referral.notes = ( - f"External Referral from: {form.cleaned_data['referring_center_name']}\n" - f"Referring Doctor: {form.cleaned_data['referring_doctor_name']}\n" - f"Contact: {form.cleaned_data['referring_contact_phone']} / {form.cleaned_data['referring_contact_email']}" + # Create referral object + referral = Referral.objects.create( + tenant=tenant, + patient=patient, + from_clinic=from_clinic, + external_provider_name=form.cleaned_data['referring_center_name'], + external_provider_contact=( + f"Doctor: {form.cleaned_data['referring_doctor_name']}\n" + f"Phone: {form.cleaned_data['referring_contact_phone']}\n" + f"Email: {form.cleaned_data['referring_contact_email']}" + ), + reason=form.cleaned_data['reason'], + urgency=form.cleaned_data['urgency'], + clinical_summary=form.cleaned_data.get('clinical_summary', ''), + from_discipline=Referral.Discipline.EXTERNAL, + status=Referral.Status.PENDING, + to_clinic=to_clinic, + to_discipline=to_discipline, + notes=( + f"External Referral from: {form.cleaned_data['referring_center_name']}\n" + f"Referring Doctor: {form.cleaned_data['referring_doctor_name']}\n" + f"Contact: {form.cleaned_data['referring_contact_phone']} / {form.cleaned_data['referring_contact_email']}" + ) ) - referral.save() - # Send notification to staff (TODO: implement) self._send_staff_notification(referral, form.cleaned_data)