406 lines
13 KiB
Markdown
406 lines
13 KiB
Markdown
# Package Appointments - Current vs Required Workflow Explanation
|
|
|
|
## Date: November 18, 2025
|
|
|
|
---
|
|
|
|
## 🔍 HOW IT WORKS NOW (After My Fixes)
|
|
|
|
### **Current Workflow:**
|
|
|
|
#### **Step 1: Package Purchase (Finance Module)**
|
|
```
|
|
1. Patient goes to Finance module
|
|
2. Staff creates an Invoice with a Package
|
|
3. Patient pays the invoice
|
|
4. System creates PackagePurchase record:
|
|
- patient = Patient A
|
|
- package = "10 SLP Sessions"
|
|
- total_sessions = 10
|
|
- sessions_used = 0
|
|
- status = ACTIVE
|
|
- expiry_date = purchase_date + 90 days
|
|
```
|
|
|
|
#### **Step 2: Booking Appointment (Appointments Module)**
|
|
```
|
|
1. Staff goes to Appointments → Create Appointment
|
|
2. Selects Patient A
|
|
3. Form loads with:
|
|
- Patient: Patient A (selected)
|
|
- Appointment Type: Radio buttons
|
|
○ Single Session (default)
|
|
○ Use Package
|
|
4. If "Use Package" selected:
|
|
- Package dropdown shows ONLY PackagePurchases for Patient A
|
|
- Shows: "10 SLP Sessions (5/10 used, 5 remaining)"
|
|
5. Staff selects package
|
|
6. Manually enters:
|
|
- Clinic
|
|
- Provider
|
|
- Service Type
|
|
- Date
|
|
- Time
|
|
7. Clicks "Book Appointment"
|
|
8. System creates Appointment:
|
|
- Links to PackagePurchase
|
|
- Sets session_number_in_package = 6 (next available)
|
|
```
|
|
|
|
#### **Step 3: Auto-Schedule (Optional)**
|
|
```
|
|
1. Staff goes to /appointments/packages/<package_purchase_id>/schedule/
|
|
2. Selects:
|
|
- Provider (single)
|
|
- Start date
|
|
- End date
|
|
- Preferred days
|
|
3. Clicks "Auto-Schedule All Sessions"
|
|
4. System creates all remaining appointments automatically
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 HOW IT SHOULD WORK (Your Requirements)
|
|
|
|
### **Required Workflow:**
|
|
|
|
#### **Step 1: Package Creation (Admin Panel)** ✅ Same
|
|
```
|
|
Admin creates Package templates:
|
|
- "10 SLP Sessions Package"
|
|
- "5 OT Assessment Package"
|
|
- "20 ABA Therapy Package"
|
|
```
|
|
|
|
#### **Step 2: Booking Appointment with Package** 🆕 DIFFERENT
|
|
|
|
```
|
|
1. Staff clicks "Book Appointment"
|
|
2. Selects "Use Package" option
|
|
3. MODAL OPENS showing:
|
|
|
|
┌─────────────────────────────────────────┐
|
|
│ Select Package for Patient │
|
|
├─────────────────────────────────────────┤
|
|
│ Patient: [Dropdown - Select Patient] │
|
|
│ │
|
|
│ 📦 ASSIGNED PACKAGES (for this patient)│
|
|
│ ✓ 10 SLP Sessions (5/10 used) │
|
|
│ ✓ 5 OT Assessment (2/5 used) │
|
|
│ │
|
|
│ 📦 AVAILABLE PACKAGES (not assigned) │
|
|
│ ○ 10 SLP Sessions Package │
|
|
│ ○ 20 ABA Therapy Package │
|
|
│ ○ 5 OT Assessment Package │
|
|
│ │
|
|
│ [Select Package] [Cancel] │
|
|
└─────────────────────────────────────────┘
|
|
|
|
4. User selects a package:
|
|
|
|
Option A: Selects ASSIGNED package
|
|
- Uses existing PackagePurchase
|
|
- Continues to appointment booking
|
|
|
|
Option B: Selects AVAILABLE package
|
|
- System creates NEW PackagePurchase
|
|
- Assigns package to patient
|
|
- Sets purchase_date = today
|
|
- Sets expiry_date = today + validity_days
|
|
- Continues to appointment booking
|
|
|
|
5. After package selected, system:
|
|
- Extracts services from package
|
|
- Filters clinics by these services
|
|
- Auto-populates clinic dropdown
|
|
|
|
6. User selects clinic(s)
|
|
7. System filters providers by clinic + services
|
|
8. User selects provider(s) - MULTI-SELECT
|
|
9. User clicks "Auto Schedule"
|
|
10. System creates all appointments
|
|
```
|
|
|
|
---
|
|
|
|
## 🔄 KEY DIFFERENCES
|
|
|
|
### **Package Selection:**
|
|
|
|
**Current (My Fix):**
|
|
```python
|
|
# Only shows PackagePurchases for patient
|
|
queryset = PackagePurchase.objects.filter(
|
|
patient=patient,
|
|
status='ACTIVE'
|
|
)
|
|
```
|
|
|
|
**Required:**
|
|
```python
|
|
# Should show BOTH:
|
|
# 1. Existing PackagePurchases for patient
|
|
existing_purchases = PackagePurchase.objects.filter(
|
|
patient=patient,
|
|
status='ACTIVE'
|
|
)
|
|
|
|
# 2. ALL available Packages
|
|
available_packages = Package.objects.filter(
|
|
is_active=True
|
|
)
|
|
|
|
# Combine and show in modal with visual distinction
|
|
```
|
|
|
|
### **Package Assignment:**
|
|
|
|
**Current:**
|
|
- Packages must be purchased in Finance module first
|
|
- Creates invoice, payment, then PackagePurchase
|
|
|
|
**Required:**
|
|
- Packages can be assigned during appointment booking
|
|
- No invoice/payment required upfront
|
|
- PackagePurchase created on-the-fly
|
|
|
|
### **Clinic Filtering:**
|
|
|
|
**Current:**
|
|
- User manually selects clinic
|
|
- No filtering based on package
|
|
|
|
**Required:**
|
|
- System auto-filters clinics based on package services
|
|
- Only shows clinics that can perform package services
|
|
|
|
### **Provider Selection:**
|
|
|
|
**Current:**
|
|
- Single provider dropdown
|
|
- One provider for all sessions
|
|
|
|
**Required:**
|
|
- Multi-select dropdown
|
|
- Can assign different providers to different sessions
|
|
|
|
---
|
|
|
|
## 📋 WHAT NEEDS TO CHANGE
|
|
|
|
### **1. Form Structure** 🔄
|
|
|
|
**Current:**
|
|
```python
|
|
class AppointmentBookingForm:
|
|
appointment_type = RadioField(['single', 'package'])
|
|
package_purchase = ModelChoiceField(PackagePurchase) # Only purchases
|
|
```
|
|
|
|
**Required:**
|
|
```python
|
|
class AppointmentBookingForm:
|
|
appointment_type = RadioField(['single', 'package'])
|
|
# Remove package_purchase field - will use modal instead
|
|
|
|
class PackageSelectionForm: # NEW FORM
|
|
patient = ModelChoiceField(Patient)
|
|
package_type = RadioField(['existing', 'new'])
|
|
existing_package = ModelChoiceField(PackagePurchase) # For patient
|
|
new_package = ModelChoiceField(Package) # All packages
|
|
```
|
|
|
|
### **2. Modal UI** 🆕 NEW
|
|
|
|
**Need to Create:**
|
|
```html
|
|
<!-- package_selection_modal.html -->
|
|
<div class="modal">
|
|
<h5>Select Package for Patient</h5>
|
|
|
|
<!-- Patient Selection -->
|
|
<select id="patient">...</select>
|
|
|
|
<!-- Assigned Packages Section -->
|
|
<h6>Assigned Packages</h6>
|
|
<div id="assignedPackages">
|
|
<!-- List of PackagePurchases for patient -->
|
|
</div>
|
|
|
|
<!-- Available Packages Section -->
|
|
<h6>Available Packages</h6>
|
|
<div id="availablePackages">
|
|
<!-- List of all Packages -->
|
|
</div>
|
|
|
|
<button>Select Package</button>
|
|
</div>
|
|
```
|
|
|
|
### **3. Package Assignment View** 🆕 NEW
|
|
|
|
**Need to Create:**
|
|
```python
|
|
@login_required
|
|
def assign_package_to_patient(request):
|
|
"""
|
|
Assign a package to a patient (create PackagePurchase).
|
|
Called when user selects an unassigned package.
|
|
"""
|
|
if request.method == 'POST':
|
|
package_id = request.POST.get('package_id')
|
|
patient_id = request.POST.get('patient_id')
|
|
|
|
package = Package.objects.get(id=package_id)
|
|
patient = Patient.objects.get(id=patient_id)
|
|
|
|
# Create PackagePurchase
|
|
package_purchase = PackagePurchase.objects.create(
|
|
tenant=request.user.tenant,
|
|
patient=patient,
|
|
package=package,
|
|
purchase_date=date.today(),
|
|
expiry_date=date.today() + timedelta(days=package.validity_days),
|
|
total_sessions=package.total_sessions,
|
|
sessions_used=0,
|
|
status='ACTIVE',
|
|
invoice=None # No invoice for now
|
|
)
|
|
|
|
return JsonResponse({
|
|
'success': True,
|
|
'package_purchase_id': str(package_purchase.id),
|
|
'message': 'Package assigned successfully'
|
|
})
|
|
```
|
|
|
|
### **4. Dynamic Clinic Filtering** 🆕 NEW
|
|
|
|
**Need to Add:**
|
|
```python
|
|
def get_clinics_for_package(request):
|
|
"""
|
|
Get clinics that can perform services in the package.
|
|
"""
|
|
package_id = request.GET.get('package_id')
|
|
package = Package.objects.get(id=package_id)
|
|
|
|
# Get all services in package
|
|
services = package.services.all()
|
|
|
|
# Get clinics for these services
|
|
clinic_ids = services.values_list('clinic_id', flat=True).distinct()
|
|
clinics = Clinic.objects.filter(id__in=clinic_ids)
|
|
|
|
return JsonResponse({
|
|
'clinics': [{'id': c.id, 'name': c.name_en} for c in clinics]
|
|
})
|
|
```
|
|
|
|
### **5. Multi-Provider Selection** 🆕 NEW
|
|
|
|
**Need to Add:**
|
|
```html
|
|
<!-- Multi-select for providers -->
|
|
<select id="providers" multiple class="form-select">
|
|
<option value="provider1">Dr. Smith</option>
|
|
<option value="provider2">Dr. Jones</option>
|
|
</select>
|
|
```
|
|
|
|
---
|
|
|
|
## 🎨 UI MOCKUP
|
|
|
|
### **Package Selection Modal:**
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────┐
|
|
│ 📦 Select Package [X] │
|
|
├──────────────────────────────────────────────────────┤
|
|
│ │
|
|
│ Patient: [Ahmed Al-Rashid ▼] │
|
|
│ │
|
|
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
│ │
|
|
│ ✅ ASSIGNED PACKAGES (2) │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────┐ │
|
|
│ │ ✓ 10 SLP Sessions Package │ │
|
|
│ │ Sessions: 5/10 used (5 remaining) │ │
|
|
│ │ Expires: 2025-12-31 │ │
|
|
│ │ [Select This Package] │ │
|
|
│ └─────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────┐ │
|
|
│ │ ✓ 5 OT Assessment Package │ │
|
|
│ │ Sessions: 2/5 used (3 remaining) │ │
|
|
│ │ Expires: 2026-01-15 │ │
|
|
│ │ [Select This Package] │ │
|
|
│ └─────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ │
|
|
│ │
|
|
│ 📦 AVAILABLE PACKAGES (3) │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────┐ │
|
|
│ │ ○ 20 ABA Therapy Package │ │
|
|
│ │ Total Sessions: 20 │ │
|
|
│ │ Price: 5,000 SAR │ │
|
|
│ │ Validity: 90 days │ │
|
|
│ │ [Assign & Use] │ │
|
|
│ └─────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ ┌─────────────────────────────────────────────┐ │
|
|
│ │ ○ 10 SLP Sessions Package │ │
|
|
│ │ Total Sessions: 10 │ │
|
|
│ │ Price: 3,000 SAR │ │
|
|
│ │ [Assign & Use] │ │
|
|
│ └─────────────────────────────────────────────┘ │
|
|
│ │
|
|
│ [Cancel] │
|
|
└──────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## 💡 SUMMARY
|
|
|
|
### **What I Fixed (Was Partially Correct):**
|
|
✅ Fixed form field name mismatch
|
|
✅ Added atomic transactions for session numbers
|
|
✅ Improved security with validation
|
|
|
|
### **What I Got Wrong:**
|
|
❌ Filtered packages by patient only
|
|
❌ Assumed packages are pre-purchased
|
|
❌ Didn't implement modal UI
|
|
❌ Didn't implement package assignment logic
|
|
|
|
### **What Needs to Be Done:**
|
|
1. ⚠️ Revert patient-only filtering
|
|
2. 🆕 Show ALL packages + existing PackagePurchases
|
|
3. 🆕 Create modal UI for package selection
|
|
4. 🆕 Implement package assignment (create PackagePurchase on-the-fly)
|
|
5. 🆕 Dynamic clinic filtering based on package services
|
|
6. 🆕 Multi-provider selection
|
|
7. 🔄 Enhanced auto-scheduling
|
|
|
|
---
|
|
|
|
## 🚀 READY TO PROCEED
|
|
|
|
I now understand the complete workflow. Shall I proceed with implementing:
|
|
|
|
1. **First:** Revert the patient-only filtering
|
|
2. **Second:** Implement modal-based package selection
|
|
3. **Third:** Add package assignment logic
|
|
4. **Fourth:** Dynamic filtering and multi-provider support
|
|
|
|
Please confirm and I'll start implementation!
|
|
|
|
---
|
|
|
|
**Status:** READY TO IMPLEMENT CORRECT WORKFLOW
|