# Patient Place Controller Documentation

**File**: `/controllers/patientPlace.php`  
**Purpose**: Patient location tracking integration with external OB/GY system  
**Last Updated**: December 20, 2024  
**Total Functions**: 2  
**Lines of Code**: ~39

---

## 📋 Overview

The Patient Place Controller provides integration with an external OB/GY (Obstetrics/Gynecology) system to track patient locations. It serves as a bridge between the ERP system and a specialized medical system. The controller provides:
- Patient location lookup integration
- External system communication via cURL
- Error handling for service unavailability
- Simple display interface for patient tracking

### Primary Functions
- [x] Patient place display interface
- [x] External system integration via cURL
- [x] Patient ID resolution from client records
- [x] Error handling and fallback responses

### Related Controllers
- [clientController.php](clientController.md) - Client/patient management
- External OB/GY System - Patient location tracking

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **client** | Client/patient master data | clientid, obygyPatientId |
| **programsettings** | System configuration | programsettingsid, obygyFolder |

---

## 🔑 Key Functions

### 1. **Default Display / Patient Place Interface** - Simple Display Page
**Location**: Line 7  
**Purpose**: Display basic patient place tracking interface

**Function Signature**:
```php
// Triggered when: empty($do) || $do == "show"
// Displays: Simple patient place interface
```

**Process Flow**:
1. Load system configuration
2. Set default days remaining value
3. Display patient place interface template

**Template Structure**:
```php
$smarty->display("header.html");
$smarty->display("patientPlace/show.html");
$smarty->display("footer.html");
```

---

### 2. **getPlaceForERP() / External System Integration** - Location Lookup
**Location**: Line 11  
**Purpose**: Retrieve patient location from external OB/GY system

**Function Signature**:
```php
// Triggered when: $do == "getPlaceForERP"
// POST Parameter: clientid - ERP client ID
// Returns: Patient location string or error code
```

**Process Flow**:
1. **Client Lookup**: Resolve ERP client ID to OB/GY patient ID
2. **Configuration Check**: Verify external system is configured
3. **cURL Request**: Make API call to external system
4. **Response Processing**: Parse JSON response and return location
5. **Error Handling**: Return -1 on failure

**Integration Logic**:
```php
$clientid = $_POST['clientid'];
$obygyPatientId = R::getCell("select obygyPatientId from client where clientid = $clientid");

if ($Programsettingdata['obygyFolder'] != "" && $obygyPatientId > 0) {
    $url = 'http://' . $_SERVER['HTTP_HOST'] . '/' . $Programsettingdata['obygyFolder'] . '/core/controllers/operationreport.php?ac=getPlaceForERP';
    
    $post = [
        'patient_id' => $obygyPatientId,
        'curlpost' => 1,
    ];
    
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
    
    $response = curl_exec($ch);
    $data = json_decode($response);
    curl_close($ch);
    
    echo $data->place;
}
```

---

## 🔄 Workflows

### Workflow 1: Patient Location Lookup
```
┌─────────────────────────────────────────────────────────────┐
│            START: Patient Location Request                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Receive Client ID                                       │
│     - Get clientid from POST data                          │
│     - Validate client exists in ERP system                 │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Resolve Patient ID                                      │
│     - Query client table for obygyPatientId                │
│     - Check if patient ID exists and is valid              │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Check System Configuration                             │
│     - Load programsettings for obygyFolder                 │
│     - Verify external system is configured                │
│     - Confirm patient ID is greater than 0                │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Prepare External System Request                        │
│     - Build external system URL                           │
│     - Prepare POST data with patient_id                   │
│     - Set cURL options for HTTP request                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Execute cURL Request                                    │
│     - Make HTTP POST to external OB/GY system             │
│     - Handle network timeouts and errors                  │
│     - Capture response data                               │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  6. Process Response                                        │
│     - Parse JSON response from external system             │
│     - Extract patient location/place information          │
│     - Handle parsing errors gracefully                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  7. Return Location Information                             │
│     - Echo patient place/location to caller               │
│     - Return -1 on any error condition                    │
│     - Close cURL connection                               │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) or `do=show` | Default display | Patient place interface |
| `do=getPlaceForERP` | External lookup | Retrieve patient location |

### Required Parameters by Action

**Default Display** (empty or `do=show`):
- No parameters required

**Location Lookup** (`do=getPlaceForERP`):
- `clientid` (POST) - ERP client ID to lookup

### Response Formats

**Location Lookup Success**:
```
[Patient Location String]
```

**Location Lookup Error**:
```
-1
```

---

## 🧮 Calculation Methods

### Patient ID Resolution
```php
$obygyPatientId = R::getCell("select obygyPatientId from client where clientid = $clientid");
```

### External System URL Construction
```php
$url = 'http://' . $_SERVER['HTTP_HOST'] . '/' . $Programsettingdata['obygyFolder'] . '/core/controllers/operationreport.php?ac=getPlaceForERP';
```

### Validation Logic
```php
if ($Programsettingdata['obygyFolder'] != "" && $obygyPatientId > 0) {
    // Proceed with external system call
} else {
    // Skip - system not configured or invalid patient ID
}
```

---

## 🔒 Security & Permissions

### Authentication
- No explicit authentication checks
- Relies on session-based security from framework
- Simple interface with minimal attack surface

### Input Validation
```php
$clientid = $_POST['clientid']; // Should be validated as integer
```

### Network Security
- cURL requests to same-host external system
- No external network calls outside server
- Basic POST parameter validation

### Data Privacy
- Minimal patient data exposure
- Only location information transmitted
- Error responses don't leak sensitive data

---

## 📊 Performance Considerations

### Network Performance
- cURL requests add latency
- No timeout configuration (potential hang risk)
- Single synchronous request model

### Database Performance
- Simple single-query patient lookup
- Minimal database impact
- No complex joins or aggregations

### Caching Opportunities
- No caching implemented
- Could cache location data for performance
- Real-time updates vs. performance trade-off

### Recommended Improvements
```php
// Add timeout to prevent hanging
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);

// Add error handling for network failures
if (curl_error($ch)) {
    error_log("Patient place lookup failed: " . curl_error($ch));
    echo -1;
}
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **External System Unavailable**
**Issue**: Returns -1 consistently  
**Cause**: OB/GY system down or misconfigured

**Debug**:
```php
// Check system configuration
$result = R::getRow('select * from programsettings where programsettingsid = 1');
var_dump($result['obygyFolder']);

// Test URL accessibility
$testUrl = 'http://' . $_SERVER['HTTP_HOST'] . '/' . $result['obygyFolder'] . '/';
echo "Testing: " . $testUrl;
```

### 2. **Patient ID Mapping Issues**
**Issue**: Valid clients return -1  
**Cause**: Missing obygyPatientId values

**Debug**:
```sql
-- Check patient ID mapping
SELECT clientid, obygyPatientId FROM client WHERE obygyPatientId IS NULL OR obygyPatientId = 0;

-- Verify specific client
SELECT * FROM client WHERE clientid = [CLIENT_ID];
```

### 3. **JSON Parsing Failures**
**Issue**: Unexpected response format  
**Cause**: External system API changes

**Debug**:
```php
// Add response logging
error_log("External system response: " . $response);
if (!$data = json_decode($response)) {
    error_log("JSON decode failed: " . json_last_error_msg());
}
```

### 4. **Network Timeout Issues**
**Issue**: Requests hang indefinitely  
**Cause**: No cURL timeout configuration

**Fix**:
```php
curl_setopt($ch, CURLOPT_TIMEOUT, 10);        // Total timeout
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);  // Connection timeout
```

---

## 🧪 Testing Scenarios

### Test Case 1: Basic Interface Display
```
1. Access patient place controller (empty do)
2. Verify page loads without errors
3. Check template rendering
4. Confirm navigation elements present
```

### Test Case 2: Valid Patient Location Lookup
```
1. Identify client with valid obygyPatientId
2. Make POST request to getPlaceForERP
3. Verify location string returned
4. Check response format and content
```

### Test Case 3: Invalid Patient Lookup
```
1. Test with non-existent clientid
2. Test with client having obygyPatientId = 0
3. Test with client having NULL obygyPatientId  
4. Verify proper error handling (no response or -1)
```

### Test Case 4: System Configuration Issues
```
1. Test with obygyFolder not configured
2. Test with invalid obygyFolder path
3. Test with external system unavailable
4. Verify graceful error handling
```

### Test Case 5: Network Error Handling
```
1. Simulate network timeout
2. Test with invalid external URL
3. Test with malformed JSON response
4. Verify error responses don't expose internals
```

### Debug Mode Enable
```php
// Add comprehensive logging
error_log("Patient Place Lookup - Client ID: " . $clientid);
error_log("OB/GY Patient ID: " . $obygyPatientId);
error_log("External URL: " . $url);
error_log("Response: " . $response);

// Add error tracking
if ($response === false) {
    error_log("cURL Error: " . curl_error($ch));
}
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [clientController.md](clientController.md) - Client management system
- External OB/GY System Documentation - API integration details
- [programsettingsController.md](programsettingsController.md) - System configuration

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When external system integration changes