agdar/PACKAGE_APPOINTMENTS_CURRENT_VS_REQUIRED_EXPLANATION.md
Marwan Alwali a4665842c9 update
2025-11-23 10:58:07 +03:00

13 KiB

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):

# Only shows PackagePurchases for patient
queryset = PackagePurchase.objects.filter(
    patient=patient,
    status='ACTIVE'
)

Required:

# 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:

class AppointmentBookingForm:
    appointment_type = RadioField(['single', 'package'])
    package_purchase = ModelChoiceField(PackagePurchase)  # Only purchases

Required:

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:

<!-- 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:

@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:

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:

<!-- 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