# Quotation Pricing Fix Summary

## Problem Identified

When customers request quotations for packages with `pricing_model = 'custom'`:

1. Portal creates quotation with **$0 pricing** (correct - requires manual pricing)
2. Quotation sent to Odoo for sales team to add products and pricing
3. Sales team prices quotation in Odoo and sends to customer
4. Quotation confirmed → becomes Sales Order in Odoo
5. **ISSUE:** Portal quotation never updated with real pricing from Odoo
6. Customer only sees real price when invoice is generated

## Root Cause

The portal was syncing sales orders and invoices from Odoo with correct pricing, but was NOT updating the original quotation record with the real prices. This created a disconnect where:

- Quotation shows: $0 (or placeholder)
- Sales Order shows: Real price from Odoo ✓
- Invoice shows: Real price from Odoo ✓

## Fixes Implemented

### Fix 1: Update Quotation Pricing When Sales Order Syncs

**File:** `afinet-portal-backend/app/Http/Controllers/API/OdooController.php`

**Method:** `syncSalesOrder()`

**Change:** When a sales order is synced from Odoo, now also updates the linked quotation with real pricing:

```php
// Update quotation status and pricing if linked
if ($quotation) {
    $quotation->update([
        'status' => 'accepted',
        'responded_at' => now(),
        // NEW: Update pricing from sales order (real prices from Odoo)
        'total_amount' => $orderData['amount_total'] ?? $quotation->total_amount,
        'monthly_price' => $orderData['monthly_subscription'] ?? $quotation->monthly_price,
        'installation_fee' => $orderData['installation_fee'] ?? $quotation->installation_fee,
        'equipment_cost' => $orderData['equipment_cost'] ?? $quotation->equipment_cost,
        'extension_cost' => $orderData['extension_cost'] ?? $quotation->extension_cost,
    ]);
    
    Log::info('Quotation pricing updated from sales order', [
        'quotation_id' => $quotation->id,
        'old_total' => $quotation->getOriginal('total_amount'),
        'new_total' => $orderData['amount_total'] ?? 0,
    ]);
}
```

### Fix 2: Enhanced Quotation Sync with Pricing Notifications

**File:** `afinet-portal-backend/app/Http/Controllers/API/OdooController.php`

**Method:** `syncQuotation()`

**Changes:**

1. **Track pricing changes:** Compares old and new pricing when quotation is updated
2. **Send notification:** When quotation status changes to 'sent' with pricing > $0, sends email to customer
3. **Log pricing updates:** Logs when pricing changes significantly

```php
// Track old values
$existingQuotation = Quotation::where('odoo_quotation_id', $quotationData['id'])->first();
$oldStatus = $existingQuotation ? $existingQuotation->status : null;
$oldTotal = $existingQuotation ? $existingQuotation->total_amount : 0;

// ... update quotation ...

// Send notification if quotation was priced and sent
if ($oldStatus !== 'sent' && $newStatus === 'sent' && $newTotal > 0) {
    Mail::to($customer->email)->send(
        new QuotationStatusChanged($quotation, $oldStatus, $newStatus)
    );
}

// Log pricing update if amount changed
if ($existingQuotation && abs($newTotal - $oldTotal) > 0.01) {
    Log::info('Quotation pricing updated from Odoo', [
        'quotation_id' => $quotation->id,
        'old_total' => $oldTotal,
        'new_total' => $newTotal,
    ]);
}
```

## How It Works Now

### Complete Flow for Custom Pricing Quotations

1. **Customer Requests Quotation (Portal)**
   - Package with `pricing_model = 'custom'`
   - Portal creates quotation with $0 pricing
   - Status: `pending_review`
   - Sent to Odoo as draft sale.order

2. **Sales Team Prices in Odoo**
   - Adds products/services to quotation
   - Sets pricing based on requirements
   - Sends quotation to customer (state: 'sent')
   - **Webhook:** `quotation.updated` → Portal syncs pricing
   - **Email:** Customer notified quotation is ready

3. **Customer Reviews Quotation (Portal)**
   - Quotation now shows real pricing from Odoo ✓
   - Customer can accept or request revision
   - Status: `sent`

4. **Customer Accepts Quotation**
   - Portal sends acceptance to Odoo
   - Odoo confirms quotation → Sales Order (state: 'sale')
   - **Webhook:** `sale.order.confirmed` → Portal syncs
   - Portal updates quotation pricing again (if changed)
   - Status: `accepted`

5. **Invoice Generated**
   - Odoo generates invoice from sales order
   - **Webhook:** `invoice.created` → Portal syncs
   - Customer sees invoice with same pricing as quotation ✓

6. **Customer Pays**
   - Payment made for invoice amount
   - Payment recorded in both systems

## Benefits

1. **Price Transparency:** Customers see approved pricing before invoice
2. **Consistent Pricing:** Quotation → Order → Invoice all show same price
3. **Better UX:** Customer knows what they're committing to when accepting quotation
4. **Audit Trail:** All pricing changes logged
5. **Notifications:** Customer notified when quotation is priced and ready

## Webhook Events Handled

- `quotation.created` → Creates quotation in portal
- `quotation.updated` → Updates quotation pricing and status
- `sale.order.confirmed` → Creates sales order and updates quotation pricing
- `invoice.created` → Creates invoice with final pricing

## Testing Recommendations

1. **Create custom pricing quotation in portal**
   - Verify quotation created with $0
   - Verify sent to Odoo

2. **Price quotation in Odoo**
   - Add products and pricing
   - Send to customer (state: 'sent')
   - Verify portal quotation updated with pricing
   - Verify customer receives email notification

3. **Confirm quotation in Odoo**
   - Confirm to sales order (state: 'sale')
   - Verify portal creates sales order
   - Verify quotation pricing updated (if changed)
   - Verify quotation status = 'accepted'

4. **Generate invoice in Odoo**
   - Create invoice from sales order
   - Verify portal creates invoice
   - Verify pricing matches quotation

5. **Make payment**
   - Pay invoice in portal
   - Verify payment recorded in both systems

## Files Modified

1. `afinet-portal-backend/app/Http/Controllers/API/OdooController.php`
   - Enhanced `syncSalesOrder()` method
   - Enhanced `syncQuotation()` method
   - Added Mail facade import
   - Added QuotationStatusChanged mail import

## Documentation Created

1. `info/QUOTATION_PRICING_FLOW_ANALYSIS.md` - Detailed analysis of the issue
2. `info/QUOTATION_PRICING_FIX_SUMMARY.md` - This file

## Next Steps (Optional Enhancements)

1. **Frontend Updates:**
   - Show quotation status timeline (Pending → Priced → Sent → Accepted → Order)
   - Display pricing breakdown when available
   - Show "Waiting for pricing" message for $0 quotations

2. **Additional Notifications:**
   - Notify sales team when customer accepts quotation
   - Remind customer if quotation expires soon

3. **Pricing History:**
   - Track all pricing changes in separate table
   - Show pricing revision history to customer

4. **Automated Tests:**
   - Test quotation pricing sync
   - Test sales order to quotation pricing update
   - Test notification sending
