# Odoo Update Capabilities from Portal

## Overview
Yes, the portal CAN update data in Odoo! The `OdooService` class provides a `write()` method that allows updating records in Odoo.

## How It Works

### The Write Method
```php
public function call($model, $method, $domain = [], $fields = [], $offset = 0, $limit = null)
{
    // ...
    if ($method === 'write') {
        $args[] = $domain; // ids (array of record IDs to update)
        $args[] = $fields; // data (array of field => value pairs)
    }
    // ...
}
```

### Usage Pattern
```php
$odooService->call('sale.order', 'write', [$orderId], ['state' => 'sale']);
```

## Currently Implemented Updates

### 1. Sales Orders (`sale.order`)

#### Convert Quotation to Sales Order
**Location:** `OdooService::convertQuotationToSalesOrder()`
```php
$this->call('sale.order', 'write', [$quotationId], ['state' => 'sale']);
```
**When:** When a quotation is accepted in the portal

#### Confirm Sales Order
**Location:** `OdooService::createSalesOrder()`
```php
$this->call('sale.order', 'write', [$orderId], ['state' => 'sale']);
```
**When:** After creating a new sales order

#### Update Order Status
**Location:** `OdooService::updateOrderStatus()`
```php
$this->call('sale.order', 'write', [$orderId], ['state' => $status]);
```
**When:** Order status changes in portal (e.g., cancelled, completed)

#### Update Order with Installation Details
**Location:** `OdooService::updateOrderWithInstallation()`
```php
$this->call('sale.order', 'write', [$orderId], [
    'commitment_date' => $installationDate,
    'note' => $notes,
    // ... other fields
]);
```
**When:** Installation is scheduled or completed

#### Mark Order as Subscription
**Location:** `OdooService::createSubscription()`
```php
$this->call('sale.order', 'write', [$salesOrderId], [
    'is_subscription' => true,
    'recurring_invoice' => true
]);
```
**When:** Creating a subscription from an order

### 2. Subscriptions (`sale.subscription`)

#### Pause Subscription
**Location:** `OdooService::pauseSubscription()`
```php
$this->call('sale.subscription', 'write', [$subscriptionId], [
    'state' => 'paused'
]);
```
**When:** User pauses their subscription in portal

#### Resume Subscription
**Location:** `OdooService::resumeSubscription()`
```php
$this->call('sale.subscription', 'write', [$subscriptionId], [
    'state' => 'in_progress'
]);
```
**When:** User resumes a paused subscription

### 3. Partners/Customers (`res.partner`)

While not explicitly shown in the search results, the portal can update partner records using:
```php
$this->call('res.partner', 'write', [$partnerId], [
    'email' => $newEmail,
    'phone' => $newPhone,
    'street' => $newAddress,
    // ... other fields
]);
```

## What CAN Be Updated

Based on the Odoo API capabilities, you can update:

### Sales Orders
- ✅ Order state (draft, sent, sale, done, cancel)
- ✅ Commitment date (installation date)
- ✅ Notes/special instructions
- ✅ Client order reference
- ✅ Payment terms
- ✅ Delivery status
- ✅ Subscription flags

### Subscriptions
- ✅ State (draft, in_progress, paused, closed)
- ✅ Next invoice date
- ✅ Recurring amount
- ✅ Payment method

### Partners/Customers
- ✅ Contact information (email, phone, address)
- ✅ Payment terms
- ✅ Credit limit
- ✅ Custom fields

### Invoices
- ✅ Payment status
- ✅ Payment date
- ✅ Payment reference

## What CANNOT Be Updated (Restrictions)

### Order Lines
- ❌ Cannot modify order lines after order is confirmed
- ❌ Odoo locks order lines once order is in 'sale' state
- **Workaround:** Create new orders or use Odoo UI directly

### Pricing
- ❌ Cannot change unit prices after confirmation
- ❌ Cannot modify taxes after confirmation
- **Workaround:** Cancel and recreate order, or use Odoo UI

### Accounting Records
- ❌ Cannot modify posted journal entries
- ❌ Cannot change invoice amounts after posting
- **Workaround:** Create credit notes or use Odoo UI

## Adding New Update Capabilities

To add a new update capability:

### 1. Add Method to OdooService
```php
public function updateCustomerProfile($partnerId, $data)
{
    try {
        $result = $this->call('res.partner', 'write', [$partnerId], $data);
        
        if ($result) {
            Log::info('Customer profile updated in Odoo', [
                'partner_id' => $partnerId,
                'updated_fields' => array_keys($data)
            ]);
            return true;
        }
        
        return false;
    } catch (\Exception $e) {
        Log::error('Failed to update customer profile in Odoo', [
            'partner_id' => $partnerId,
            'error' => $e->getMessage()
        ]);
        return false;
    }
}
```

### 2. Call from Controller
```php
public function updateProfile(Request $request)
{
    $user = $request->user();
    
    if ($user->odoo_partner_id) {
        $odooService = app(OdooService::class);
        $odooService->updateCustomerProfile($user->odoo_partner_id, [
            'email' => $request->email,
            'phone' => $request->phone,
            'street' => $request->address,
        ]);
    }
    
    // Update local database
    $user->update($request->validated());
    
    return response()->json(['success' => true]);
}
```

## Best Practices

### 1. Always Update Both Systems
```php
// Update Odoo first
$odooService->updateOrderStatus($odooOrderId, 'cancel');

// Then update local database
$order->update(['order_status' => 'cancelled']);
```

### 2. Handle Failures Gracefully
```php
try {
    $odooService->updateOrderStatus($odooOrderId, 'cancel');
} catch (\Exception $e) {
    Log::error('Odoo update failed, but local update succeeded', [
        'order_id' => $order->id,
        'error' => $e->getMessage()
    ]);
    // Continue - local database is updated
}
```

### 3. Log All Updates
```php
Log::info('Updating Odoo record', [
    'model' => 'sale.order',
    'record_id' => $orderId,
    'fields' => $updateData
]);
```

### 4. Validate Before Updating
```php
// Check if order can be cancelled in Odoo
if (!in_array($order->odoo_state, ['draft', 'sent'])) {
    throw new \Exception('Order cannot be cancelled in current state');
}
```

## Security Considerations

### 1. Authentication
- Portal uses API key authentication (stored in `.env`)
- Each request authenticates with Odoo
- UID is cached per request

### 2. Permissions
- Portal user has specific permissions in Odoo
- Cannot update records outside allowed scope
- Odoo enforces record rules and access rights

### 3. Validation
- Always validate data before sending to Odoo
- Check user permissions in portal before updating
- Verify record ownership

## Testing Updates

### Test Script Example
```php
// test-odoo-update.php
require __DIR__.'/vendor/autoload.php';

$app = require_once __DIR__.'/bootstrap/app.php';
$app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap();

$odooService = app(\App\Services\OdooService::class);

// Test updating a sales order
$orderId = 1234; // Replace with actual order ID
$result = $odooService->call('sale.order', 'write', [$orderId], [
    'note' => 'Updated from portal at ' . now()
]);

echo $result ? "✅ Update successful\n" : "❌ Update failed\n";
```

## Common Update Scenarios

### 1. Customer Updates Profile
```php
$odooService->call('res.partner', 'write', [$partnerId], [
    'email' => $newEmail,
    'phone' => $newPhone,
    'mobile' => $newMobile,
]);
```

### 2. Order Cancellation
```php
$odooService->call('sale.order', 'write', [$orderId], [
    'state' => 'cancel',
    'note' => 'Cancelled by customer: ' . $reason
]);
```

### 3. Installation Scheduled
```php
$odooService->call('sale.order', 'write', [$orderId], [
    'commitment_date' => $installationDate,
    'note' => 'Installation scheduled for ' . $installationDate
]);
```

### 4. Payment Received
```php
$odooService->call('account.move', 'write', [$invoiceId], [
    'payment_state' => 'paid',
    'payment_reference' => $paymentReference
]);
```

## Summary

✅ **Yes, the portal CAN update Odoo data**
✅ Currently updates: Orders, Subscriptions, Installation details
✅ Uses Odoo's XML-RPC API with `write` method
✅ Authenticated with API key
✅ Logs all operations
✅ Handles errors gracefully

The infrastructure is in place to update any Odoo model that the portal user has write permissions for. You just need to add the specific methods to `OdooService` and call them from your controllers.
