# Saudi Electronic Invoice Controller Documentation

**File**: `/controllers/saudiElectronIcinvoiceController.php`  
**Purpose**: Manages ZATCA (Saudi Arabia Tax Authority) electronic invoice integration and compliance  
**Last Updated**: December 20, 2024  
**Total Functions**: 7 main actions + 3 utility functions  
**Lines of Code**: ~382

---

## 📋 Overview

The Saudi Electronic Invoice Controller implements the complete ZATCA (Zakat, Tax and Customs Authority) electronic invoicing system for Saudi Arabia tax compliance. This controller handles:

- ZATCA API authentication and token management
- Device registration and certification
- Electronic invoice submission and validation
- Compliance testing and production initialization
- Integration with existing sales bills
- UUID generation and QR code handling
- Multi-step setup process for ZATCA compliance

### Primary Functions
- [x] ZATCA device registration and setup
- [x] OTP validation for device activation
- [x] Compliance invoice testing (6 test invoices)
- [x] Production environment initialization
- [x] Sales bill electronic submission
- [x] Authentication token management
- [x] Invoice tracking and status management
- [x] QR code generation for invoices

### Related Controllers
- [sellbillController.php](sellbillController.md) - Sales bill creation
- [clientController.php](clientController.md) - Customer management
- [productController.php](productController.md) - Product management

---

## 🗄️ Database Tables

### Primary Tables (Direct Operations)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **saudielectronicinvoice** | ZATCA configuration and settings | id, tokenapi, urlapi, deviceuuid, deviceid, stepnow, endsetup |
| **esaudiclientsetting** | Client electronic invoice settings | clientid, licensetype, licensenumber, companyname |
| **etasellbillstatus** | Electronic invoice submission tracking | sellbillid, estatus, submissionid, accepteddocuments, errors |

### Integration Tables (Referenced)
| Table Name | Purpose | Key Columns |
|------------|---------|-------------|
| **sellbill** | Sales bills for electronic submission | sellbillid, sellbillclientid, sellbilldate, sellbilltotalPayed, visaPayed |
| **sellbilldetail** | Sales bill line items | sellbilldetailproductid, sellbilldetailquantity, sellbilldetailprice |
| **product** | Product information for invoices | productId, productName |

### Key Relationships
```sql
-- Electronic invoice settings
saudielectronicinvoice.id = 1 (single configuration record)

-- Client settings for electronic invoicing
esaudiclientsetting.clientid -> client.clientid

-- Invoice submission tracking
etasellbillstatus.sellbillid -> sellbill.sellbillid
```

---

## 🔑 Key Functions

### 1. **Default Action (empty $do)** - Configuration Display
**Location**: Lines 21-27  
**Purpose**: Display ZATCA configuration interface

**Process Flow**:
1. Load ZATCA configuration from database
2. Assign configuration to template
3. Display setup interface via `saudiElectronIcinvoiceView/saudielectronicinvoice.html`

---

### 2. **devices ($do == "devices")** - Device Management
**Location**: Lines 28-33  
**Purpose**: Display registered ZATCA devices

**Process Flow**:
1. Make API call to `/api/v1/zatca/devices`
2. Parse JSON response for device list
3. Display devices via template

**API Call**:
```php
$devices = json_decode(HTTPRequester::HTTPGet($urlapi.'/api/v1/zatca/devices', [], $headers), true);
```

---

### 3. **devicestatus ($do == "devicestatus")** - Device Status Check
**Location**: Lines 34-39  
**Purpose**: Check status of specific ZATCA device

**Parameters**:
- `deviceuuid` - UUID of device to check

**API Call**:
```php
$device = json_decode(HTTPRequester::HTTPGet($urlapi.'/api/v1/zatca/device-status/'.$_GET['deviceuuid'], [], $headers), true);
```

---

### 4. **getallinvoices ($do == "getallinvoices")** - Invoice Listing
**Location**: Lines 40-51  
**Purpose**: Retrieve submitted invoices from ZATCA

**Parameters**:
- `status` - Invoice status filter (default: 'accepted')
- `limit` - Number of invoices to retrieve (default: 50)
- `offset` - Pagination offset (default: 0)

**API Call**:
```php
$data = [
    'device_uuid' => $saudielectronicinvoice->deviceuuid,
    'status' => isset($_POST['status']) ? trim($_POST['status']) : 'accepted',
    'limit' => isset($_POST['limit']) ? trim($_POST['limit']) : 50,
    'offset' => isset($_POST['offset']) ? trim($_POST['offset']) : 0,
];
$getallinvoices = json_decode(HTTPRequester::HTTPGet($urlapi.'/api/v1/zatca/invoices', $data, $headers), true);
```

---

### 5. **detail ($do == "detail")** - Invoice Detail View
**Location**: Lines 52-57  
**Purpose**: Display detailed invoice information including XML

**Parameters**:
- `uuid` - Invoice UUID to display

**API Call**:
```php
$invoice = json_decode(HTTPRequester::HTTPGet($urlapi.'/api/v1/zatca/invoice/'.$_GET['uuid'].'?include_xml=true', [], $headers), true);
```

---

### 6. **update ($do == "update")** - Multi-Step ZATCA Setup
**Location**: Lines 58-203  
**Purpose**: Handle 4-step ZATCA device setup and compliance process

**Step 1: Device Registration**
- Authenticate with ZATCA API
- Submit company and device information
- Generate CSR (Certificate Signing Request)
- Store device UUID and ID

**Step 2: OTP Validation**
- Submit OTP received from ZATCA
- Validate device registration

**Step 3: Compliance Testing**
- Submit 6 compliance test invoices
- Track progress until all 6 are accepted

**Step 4: Production Initialization**
- Initialize production environment
- Mark setup as complete

**Process Flow for Each Step**:
```php
switch($step){
    case 1: // Device Registration
        // Authenticate and register device
        $result = json_decode(HTTPRequester::HTTPPost($urlapi.'/api/auth/login', $data, $headers), true);
        // Generate CSR
        $result = json_decode(HTTPRequester::HTTPPost($urlapi.'/api/v1/zatca/generate-csr', $data, $headers), true);
        break;
        
    case 2: // OTP Validation
        $result = json_decode(HTTPRequester::HTTPPost($urlapi.'/api/v1/zatca/validate-otp', $data, $headers), true);
        break;
        
    case 3: // Compliance Testing
        $result = json_decode(HTTPRequester::HTTPPost($urlapi.'/api/v1/zatca/send-compliance-invoice', $data, $headers), true);
        break;
        
    case 4: // Production Initialization
        $result = json_decode(HTTPRequester::HTTPPost($urlapi.'/api/v1/zatca/initialize-production', $data, $headers), true);
        break;
}
```

---

### 7. **etsellbill ($do == "etsellbill")** - Electronic Bill Submission
**Location**: Lines 204-340  
**Purpose**: Submit sales bill to ZATCA for electronic invoicing

**Parameters**:
- `sellbillid` - Sales bill ID to submit

**Process Flow**:
1. Load sales bill and detail data
2. Load client electronic settings
3. Determine payment method based on bill payments
4. Build invoice line items from bill details
5. Generate invoice data structure
6. Submit to ZATCA API
7. Update bill with submission status and QR code
8. Log submission status

**Payment Method Mapping**:
```php
if($sellbill['isBankAccountTransfer'] > 0){
    $payment_method = 42; // Bank transfer
}else if($sellbill['sellbilltotalPayed'] == 0 && $sellbill['visaPayed'] == 0){
    $payment_method = 30; // Credit
}else if($sellbill['visaPayed'] > 0 && $sellbill['sellbilltotalPayed'] > 0){
    $payment_method = 1; // Mixed payment
}else if($sellbill['visaPayed'] > 0){
    $payment_method = 48; // Card payment
}else{
    $payment_method = 10; // Cash payment
}
```

**Invoice Data Structure**:
```php
$data = [
    "device_uuid" => $saudielectronicinvoice->deviceuuid,
    "invoice_type_code" => "0200000",
    "invoice_subtype_code" => "388",
    "invoice_number" => "INV-" . $sellbill['sellbillid'],
    "invoice_uuid" => makeUuidFromHex($sellbill['sellbillserial']),
    "invoice_counter" => $saudielectronicinvoice->invoicecounter,
    "previous_invoice_hash" => $saudielectronicinvoice->previousinvoicehash,
    "issue_date" => date("Y-m-d", strtotime($sellbill['sellbilldate'])),
    "issue_time" => date("H:i:s", strtotime($sellbill['sellbilldate'])),
    "seller_data" => [...], // Company information
    "customer_data" => [...], // Customer information (if applicable)
    "payment_method" => $payment_method,
    "products" => $invoiceLines // Product line items
];
```

---

## 🔄 Workflows

### Workflow 1: ZATCA Device Setup (4-Step Process)
```
┌─────────────────────────────────────────────────────────────┐
│                START: ZATCA Setup Process                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 1: Device Registration                               │
│     ├─→ Authenticate with ZATCA API                        │
│     ├─→ Submit company information                         │
│     ├─→ Generate CSR (Certificate Signing Request)         │
│     └─→ Store device UUID and ID                           │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 2: OTP Validation                                    │
│     ├─→ Receive OTP from ZATCA                             │
│     ├─→ Submit OTP for device validation                   │
│     └─→ Confirm device activation                          │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 3: Compliance Testing                                │
│     ├─→ Submit 6 test compliance invoices                  │
│     ├─→ Monitor submission progress                        │
│     ├─→ Wait for all 6 invoices to be accepted             │
│     └─→ Verify compliance approval                         │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  Step 4: Production Initialization                         │
│     ├─→ Initialize production environment                  │
│     ├─→ Mark setup as complete (endsetup = 1)              │
│     └─→ Ready for live invoice submission                  │
└─────────────────────────────────────────────────────────────┘
```

---

### Workflow 2: Electronic Invoice Submission
```
┌─────────────────────────────────────────────────────────────┐
│              START: Submit Sales Bill to ZATCA             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  1. Load Sales Bill Data                                    │
│     ├─→ Get bill header information                         │
│     ├─→ Load bill detail line items                         │
│     └─→ Load customer electronic settings                  │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  2. Determine Payment Method                                │
│     ├─→ Check for bank transfers                            │
│     ├─→ Check for credit terms                              │
│     ├─→ Check for card payments                             │
│     └─→ Default to cash payment                             │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  3. Build Invoice Structure                                 │
│     ├─→ Generate invoice UUID                               │
│     ├─→ Build seller data (company info)                   │
│     ├─→ Build customer data (if not cash customer)         │
│     ├─→ Build product line items with tax                  │
│     └─→ Set invoice counters and hashes                    │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  4. Submit to ZATCA API                                     │
│     ├─→ POST invoice data to /api/v1/zatca/submit-invoice   │
│     ├─→ Check response status                               │
│     └─→ Handle success/failure scenarios                   │
└────────────────────┬────────────────────────────────────────┘
                     │
                     ▼
┌─────────────────────────────────────────────────────────────┐
│  5. Update Bill Status                                      │
│     ├─→ Success: Update with UUID and QR code              │
│     ├─→ Failure: Mark as rejected with error details       │
│     ├─→ Update invoice counter and previous hash           │
│     └─→ Log submission status in etasellbillstatus         │
└─────────────────────────────────────────────────────────────┘
```

---

## 🌐 URL Routes & Actions

| URL Parameter | Function Called | Description |
|---------------|----------------|-------------|
| `do=` (empty) | Default action | Display ZATCA configuration interface |
| `do=devices` | Device listing | Show registered ZATCA devices |
| `do=devicestatus` | Device status | Check specific device status |
| `do=getallinvoices` | Invoice listing | List submitted invoices |
| `do=detail` | Invoice detail | Show detailed invoice information |
| `do=update` | Setup process | Handle 4-step ZATCA setup |
| `do=etsellbill` | Invoice submission | Submit sales bill to ZATCA |

### Required Parameters by Action

**Device Status** (`do=devicestatus`):
- `deviceuuid` - Device UUID to check

**Invoice Detail** (`do=detail`):
- `uuid` - Invoice UUID to display

**Setup Process** (`do=update`):
- `step` - Setup step number (1-4)
- Various configuration parameters based on step

**Invoice Submission** (`do=etsellbill`):
- `sellbillid` - Sales bill ID to submit

---

## 🧮 Calculation Methods

### Tax Calculation (15% VAT)
```php
// Applied to all product lines
$array = array(
    "tax_percentage" => 15.0,
    "tax_code" => "S" // Standard rate
);
```

### UUID Generation
```php
function makeUuidFromHex($hex) {
    // Convert to hex if not already
    if (!ctype_xdigit($hex)) {
        $hex = bin2hex($hex);
    }
    
    // Pad to 32 characters (128 bits)
    $hex = str_pad($hex, 32, "0");
    
    // Format as UUID
    return substr($hex, 0, 8) . "-" .
           substr($hex, 8, 4) . "-" .
           substr($hex, 12, 4) . "-" .
           substr($hex, 16, 4) . "-" .
           substr($hex, 20, 12);
}
```

### Token Expiration Check
```php
function istokenexpired() {
    if (empty($_SESSION['auth_token']) || empty($_SESSION['auth_token_exp'])) 
        return true;
    return (time() >= $_SESSION['auth_token_exp']);
}
```

---

## 🔒 Security & Permissions

### Authentication & Authorization
- **API Token Authentication**: Uses bearer token for ZATCA API access
- **Session Management**: Maintains authentication tokens in session
- **Token Refresh**: Automatic token refresh when expired

```php
// Authentication headers for ZATCA API
$headers = array(
    'Accept: application/json', 
    'Content-Type: application/json', 
    "Authorization: Bearer $saudielectronicinvoice->tokenapi", 
    "token: $saudielectronicinvoice->logintoken"
);

// Auto-refresh expired tokens
if (istokenexpired() && $_SESSION['auth_token']) {
    $result = refreshtoken();
    $authtoken = $_SESSION['auth_token'] = $result['data']['auth_token'];
    $_SESSION['auth_token_exp'] = time() + (int)$result['data']['expires_in'];
}
```

### Input Validation
- **Email validation**: `filter_input(INPUT_POST,"loginemail",FILTER_VALIDATE_EMAIL)`
- **Parameter sanitization**: `trim()` applied to user inputs
- **Step validation**: Numeric step validation for setup process

---

## 📊 Performance Considerations

### API Rate Limiting
1. **Token Management**: Reuse tokens until expiration to avoid excessive authentication
2. **Batch Operations**: Consider batching multiple invoice submissions
3. **Error Handling**: Implement proper retry logic for API failures

### Database Optimization
```sql
-- Recommended indexes
CREATE INDEX idx_sellbill_client_date ON sellbill(sellbillclientid, sellbilldate);
CREATE INDEX idx_sellbilldetail_bill ON sellbilldetail(sellbillid);
CREATE INDEX idx_etasellbillstatus_bill ON etasellbillstatus(sellbillid);
```

---

## 🐛 Common Issues & Troubleshooting

### 1. **Setup Step Failures**
**Issue**: Setup process fails at any step  
**Cause**: API connectivity, invalid data, or ZATCA service issues

**Debug**:
```php
// Check stored responses
SELECT responsestepone, responsesteptwo, responsestepthree, responsestepfour 
FROM saudielectronicinvoice WHERE id = 1;

// Check current step status
SELECT stepnow, endsetup FROM saudielectronicinvoice WHERE id = 1;
```

### 2. **Token Expiration Issues**
**Issue**: API calls fail with authentication errors  
**Cause**: Expired authentication tokens

**Fix**:
```php
// Manual token refresh
if (istokenexpired()) {
    $result = refreshtoken();
    // Update stored token
}
```

### 3. **Invoice Submission Failures**
**Issue**: Sales bills not accepted by ZATCA  
**Cause**: Invalid customer data, missing fields, or format errors

**Debug**:
```sql
-- Check submission status
SELECT * FROM etasellbillstatus WHERE sellbillid = [BILL_ID];

-- Check bill electronic status
SELECT estatus, ereason, qrerpids FROM sellbill WHERE sellbillid = [BILL_ID];
```

### 4. **Missing Client Electronic Settings**
**Issue**: Customer invoices fail due to missing settings  
**Cause**: No electronic settings configured for B2B customers

**Fix**:
```sql
-- Check client settings
SELECT * FROM esaudiclientsetting WHERE clientid = [CLIENT_ID];

-- Add required settings for B2B customers
INSERT INTO esaudiclientsetting (clientid, licensetype, licensenumber, companyname, ...) VALUES (...);
```

---

## 🧪 Testing Scenarios

### Test Case 1: Complete Setup Process
```
1. Start fresh ZATCA setup (stepnow = 0)
2. Complete Step 1 with valid company data
3. Validate OTP in Step 2
4. Monitor compliance testing in Step 3
5. Initialize production in Step 4
6. Verify endsetup = 1
```

### Test Case 2: Invoice Submission
```
1. Create test sales bill
2. Configure customer electronic settings (if B2B)
3. Submit bill via etsellbill action
4. Verify ZATCA acceptance
5. Check QR code generation
6. Confirm bill status update
```

### Test Case 3: Error Handling
```
1. Submit invoice with invalid data
2. Check error logging in etasellbillstatus
3. Verify bill marked with error status
4. Test retry functionality
```

---

## 📚 Related Documentation

- [CLAUDE.md](/Applications/AMPPS/www/erp19/CLAUDE.md) - PHP 8.2 migration guide
- [sellbillController.md](sellbillController.md) - Sales bill creation
- [ZATCA API Documentation](https://zatca.gov.sa) - Official ZATCA integration guide
- [Electronic Invoicing Requirements](https://zatca.gov.sa) - Saudi Arabia e-invoicing rules

---

**Documented By**: AI Assistant  
**Review Status**: ✅ Complete  
**Next Review**: When ZATCA requirements change