# Provider Negotiation System Guide

## Overview
The negotiation system allows providers to negotiate the price of service orders with clients before accepting the order. This guide covers how providers interact with the negotiation flow, respond to offers, and manage their service orders during negotiation.

---

## Table of Contents
1. [Introduction to Negotiation](#introduction-to-negotiation)
2. [Negotiation Flow](#negotiation-flow)
3. [Provider Actions](#provider-actions)
4. [API Endpoints](#api-endpoints)
5. [Response Structures](#response-structures)
6. [Notifications](#notifications)
7. [Best Practices](#best-practices)

---

## Introduction to Negotiation

### What is Order Negotiation?
When a client creates a service order, they submit an initial price offer. Instead of immediately accepting or rejecting, providers can:
- ✅ **Accept** the client's offer
- ❌ **Reject** the offer (order cancelled)
- 🔄 **Counter** with a different price

The negotiation continues in rounds until:
1. One party accepts (order becomes active after payment)
2. One party rejects (order cancelled)
3. Maximum rounds reached (must accept or reject)
4. Timeout expires (order auto-cancelled)

### System Limits
- **Max Rounds**: Configured by admin (typically 3-5 rounds). Both parties' counters count toward this limit.
- **Timeout**: Each party has a time limit to respond (typically 60 minutes). If you don't respond in time, the order is automatically cancelled.
- **Price Range**: All offers must be within the service's min/max price range.

---

## Negotiation Flow

### Order Status & Negotiation Block
When an order is in negotiation:
- `status`: `'pending_negotiation'`
- `is_negotiated`: `true`
- `negotiation` (or `negotiation_data`): Details regarding the negotiation status, rounds, action capabilities, and offer history.

| Key | Type | Description |
|-----|------|-------------|
| `original_price` | `float` | Original catalog / service base price |
| `negotiated_price` | `float` | Current price offer on the table |
| `price_difference` | `float` | Difference between original price and negotiated price |
| `negotiation_turn` | `string` | Whose turn it is: `'provider'` or `'client'` |
| `round` | `int` | Current negotiation round number (starts at 1) |
| `max_rounds` | `int` | Maximum allowed rounds (from system setting `negotiation_max_rounds`, 0 = unlimited) |
| `can_accept` | `bool` | `true` if it is your turn to accept the offer |
| `can_reject` | `bool` | `true` if it is your turn to reject the offer |
| `can_counter` | `bool` | `true` if it is your turn **AND** `round < max_rounds` (allows counter-offer button) |
| `accepted_at` | `int\|null` | Unix timestamp when offer was accepted, or `null` if still negotiating |
| `offers` | `array` | Complete negotiation history log (list of offers) |

### Visual Workflow

```
Client Creates Order
    Offer: 800 SAR
         ↓
  [YOUR TURN - Round 1]
         ↓
    You have 3 options:
    
┌──────────┬──────────┬──────────┐
│  Accept  │  Counter │  Reject  │
│  800 SAR │  750 SAR │          │
└──────────┴──────────┴──────────┘
     ↓          ↓          ↓
  Client    [CLIENT's   Order
   Pays      TURN]    Cancelled
     ↓        Round 2      
  Order         ↓
 Active    Client Options:
           Accept/Counter/Reject
                ↓
         (Continues until
          resolution)
```

### Round Counting
- Round 1: Client's initial offer → Your first response
- Round 2: Your counter → Client's response
- Round 3: Client's counter → Your response
- etc.

Each counter-offer from either party increments the round counter.

---

## Provider Actions

### 1. Accept Client's Offer

**When to use**: The client's current offer price is acceptable.

**What happens**:
1. Order status remains `pending_negotiation`
2. `negotiation_turn` changes to `'client'`
3. `negotiation_accepted_at` timestamp is set
4. Client is notified to complete payment
5. Client has limited time to pay (based on timeout setting)
6. Once paid, order status becomes `active` and you can start work

**Endpoint**: `POST /provider/service-orders/{id}/negotiation/accept`

**Request**: No body required

**Example**:
```bash
POST /provider/service-orders/123/negotiation/accept
Authorization: Bearer {your_token}
```

**Success Response** (200):
```json
{
  "status": true,
  "message": "Offer accepted. Waiting for client payment.",
  "data": {
    "id": 123,
    "order_number": "ORD-2026-001234",
    "status": "pending_negotiation",
    "is_negotiated": true,
    "negotiation": {
      "original_price": 800.00,
      "negotiated_price": 800.00,
      "price_difference": 0.00,
      "negotiation_turn": "client",
      "round": 1,
      "max_rounds": 3,
      "can_accept": false,
      "can_reject": false,
      "can_counter": false,
      "accepted_at": 1730113800,
      "offers": [
        {
          "id": 1,
          "made_by": "client",
          "price": 800.00,
          "round": 1,
          "created_at": 1730112000
        }
      ]
    }
  }
}
```

---

### 2. Reject Offer

**When to use**: You cannot or do not want to accept the order at the current terms.

**What happens**:
1. Order status changes to `cancelled`
2. `cancelled_at` timestamp is set
3. Client is notified of rejection
4. Order is permanently closed
5. No further actions possible

**Endpoint**: `POST /provider/service-orders/{id}/negotiation/reject`

**Request**: No body required

**Example**:
```bash
POST /provider/service-orders/123/negotiation/reject
Authorization: Bearer {your_token}
```

**Success Response** (200):
```json
{
  "success": true,
  "message": "Order rejected and cancelled.",
  "data": {
    "id": 123,
    "status": "cancelled",
    "cancelled_at": "2026-10-28T10:32:00Z",
    ...
  }
}
```

---

### 3. Make Counter-Offer

**When to use**: You want to propose a different price.

**What happens**:
1. `negotiation_round` increments by 1
2. `negotiation_price` updates to your counter price
3. `negotiation_turn` changes to `'client'`
4. Offer is logged in negotiation history
5. Client is notified to respond
6. Client's timeout window resets

**Validation**:
- Counter price must be within service's price range
- Cannot counter if max rounds reached (must accept or reject instead)
- Must provide a valid positive price

**Endpoint**: `POST /provider/service-orders/{id}/negotiation/counter`

**Request Body**:
```json
{
  "counter_price": 750.00
}
```

**Example**:
```bash
POST /provider/service-orders/123/negotiation/counter
Authorization: Bearer {your_token}
Content-Type: application/json

{
  "counter_price": 750.00
}
```

**Success Response** (200):
```json
{
  "status": true,
  "message": "Offer countered successfully. Waiting for client response.",
  "data": {
    "id": 123,
    "order_number": "ORD-2026-001234",
    "status": "pending_negotiation",
    "is_negotiated": true,
    "negotiation": {
      "original_price": 800.00,
      "negotiated_price": 750.00,
      "price_difference": 50.00,
      "negotiation_turn": "client",
      "round": 2,
      "max_rounds": 3,
      "can_accept": false,
      "can_reject": false,
      "can_counter": false,
      "accepted_at": null,
      "offers": [
        {
          "id": 1,
          "made_by": "client",
          "price": 800.00,
          "round": 1,
          "created_at": 1730112000
        },
        {
          "id": 2,
          "made_by": "provider",
          "price": 750.00,
          "round": 2,
          "created_at": 1730113800
        }
      ]
    }
  }
}
```

**Error Responses**:

Max rounds reached (422):
```json
{
  "success": false,
  "message": "Maximum negotiation rounds reached. You must accept or reject the current offer."
}
```

Price out of range (422):
```json
{
  "success": false,
  "message": "The agreed price must be at least 500.00 SAR for this service."
}
```

Not your turn (422):
```json
{
  "success": false,
  "message": "This order is not awaiting your response."
}
```

---

## API Endpoints

### Base URL
```
/provider/service-orders/{order_id}/negotiation
```

### Available Actions

| Method | Endpoint | Action | Body |
|--------|----------|--------|------|
| POST | `/accept` | Accept client's offer | None |
| POST | `/reject` | Reject offer and cancel order | None |
| POST | `/counter` | Make counter-offer | `{ "counter_price": number }` |

### Authentication
All endpoints require:
- **Header**: `Authorization: Bearer {token}`
- **Middleware**: `auth:api`, `provider`, `active`, `provider.permission`

---

## Response Structures

### Order Object During Negotiation (`ServiceOrderResource`)
```json
{
  "id": 123,
  "order_number": "ORD-2026-001234",
  "status": "pending_negotiation",
  "status_trans": "في انتظار التفاوض",
  "order_type": "individual",
  "is_team_leader": true,
  "scheduled_date": "2026-10-30",
  "scheduled_time": "14:00",
  "is_negotiated": true,
  "negotiation": {
    "original_price": 800.00,
    "negotiated_price": 750.00,
    "price_difference": 50.00,
    "negotiation_turn": "provider",
    "round": 1,
    "max_rounds": 3,
    "can_accept": true,
    "can_reject": true,
    "can_counter": true,
    "accepted_at": null,
    "offers": [
      {
        "id": 1,
        "made_by": "client",
        "price": 800.00,
        "round": 1,
        "created_at": 1730112000
      }
    ]
  },
  "negotiation_data": {
    "/* alias of negotiation for frontend consistency */": null
  },
  "service_price": 750.00,
  "total_price": 750.00,
  "net_provider_earnings": 712.50,
  "client_data": {
    "id": 42,
    "full_name": "Ahmed Ali"
  }
}
```

### Negotiation Offer Object (`NegotiationOfferResource`)
```json
{
  "id": 2,
  "made_by": "provider",
  "price": 750.00,
  "round": 2,
  "created_at": 1730113800
}
```

---

## Notifications

You will receive real-time notifications throughout the negotiation process. All notifications are categorized under **ORDERS** type.

### Notification Types

#### 1. New Order Received (negotiation required)
```
Title (AR): طلب خدمة جديد يحتاج تفاوض
Title (EN): New Service Order Requires Negotiation
Body (AR): لديك طلب خدمة جديد. يرجى مراجعة التفاصيل والرد على العرض المقدم.
Body (EN): You have received a new service order. Please review the details and respond to the offer.

notify_type: service_order
notify_id: 123
```

#### 2. Client Accepted Your Counter-Offer
```
Title (AR): العميل وافق على عرضك
Title (EN): Client Accepted Your Offer
Body (AR): وافق العميل على عرضك المقدم. في انتظار إتمام الدفع لتأكيد الطلب.
Body (EN): The client accepted your submitted offer. Awaiting their payment to confirm the order.

notify_type: service_order
notify_id: 123
```

#### 3. Client Made Counter-Offer
```
Title (AR): عرض مضاد من العميل
Title (EN): Client Counter-Offer
Body (AR): قدم العميل عرضاً مضاداً للطلب. يمكنك مراجعته والرد عليه من تفاصيل الطلب.
Body (EN): The client submitted a counter-offer for the order. You can review and respond to it from the order details.

notify_type: service_order
notify_id: 123
```

#### 4. Client Rejected Your Counter-Offer
```
Title (AR): العميل لم يقبل عرضك
Title (EN): Client Did Not Accept Offer
Body (AR): لم يقبل العميل عرضك المقدم في هذا الوقت. يمكنه تقديم طلب جديد بشروط مختلفة في أي وقت.
Body (EN): The client did not accept your submitted offer at this time. They may place a new order with different terms whenever they are ready.

notify_type: service_order
notify_id: 123
```

#### 5. Auto-Cancelled (You Didn't Respond in Time)
```
Title (AR): انتهت مهلة الرد على العرض
Title (EN): Response Time Expired
Body (AR): لم ترد على عرض العميل خلال المهلة المحددة، لذا تم إلغاء الطلب تلقائياً.
Body (EN): You did not respond to the client's offer within the allowed time, so the order was automatically cancelled.

notify_type: service_order
notify_id: 123
```

#### 6. Auto-Cancelled (Client Didn't Respond)
```
Title (AR): لم يرد العميل في الوقت المحدد
Title (EN): Client Did Not Respond in Time
Body (AR): لم يرد العميل على عرضك خلال المهلة المحددة، لذا تم إلغاء الطلب تلقائياً.
Body (EN): The client did not respond to your offer within the allowed time, so the order was automatically cancelled.

notify_type: service_order
notify_id: 123
```

### Filtering Notifications
Use the notifications API with type filter:
```bash
GET /provider/notifications?type=orders
```

---

## Best Practices

### Strategic Negotiation
1. **Review Service Price Range**: Check `service.price_from` and `service.price_to` before countering
2. **Consider Order Details**: Review the order's scope, requirements, and timeline
3. **Be Reasonable**: Multiple counter-offers may frustrate clients
4. **Respond Promptly**: Don't wait until timeout to avoid auto-cancellation
5. **Final Round Strategy**: If at max rounds, carefully decide to accept or reject

### Price Calculation Tips
- Consider your actual costs (materials, time, travel)
- Factor in platform fees (VAT, app commission)
- Check your service pricing configuration in your profile
- Review client's order stats (reliable clients may warrant flexibility)

### Communication
- Use the order chat feature (opens after order is active) to clarify requirements
- If clarification is needed before accepting, use contact/support channels
- Be professional in all interactions

### Managing Your Time
- Check orders regularly to avoid missing timeout windows
- Enable push notifications for order updates
- Set realistic availability in your schedule
- Don't accept orders you cannot fulfill within negotiated terms

### Common Mistakes to Avoid
❌ Not responding before timeout  
❌ Countering outside service price range  
❌ Accepting orders you cannot complete  
❌ Making too many counter-offers  
❌ Not reviewing order details thoroughly  

---

## Provider Contracts (Separate System)

**Note**: Provider contracts (admin-sent employment contracts) are a **separate system** from order negotiation.

### Provider Contract Notifications
You will also receive notifications about provider contracts:

- **Contract Sent**: Admin sends you a contract to review and sign
- **Contract Reminder**: Reminder to review pending contract
- **Contract Expired**: Your contract has expired

### Contract Endpoints
- `GET /provider/contracts` - View all your contracts
- `GET /provider/contracts/{id}` - View specific contract details
- `POST /provider/contracts/{id}/accept` - Accept a contract
- `POST /provider/contracts/{id}/reject` - Reject a contract

### Contract vs. Order Negotiation
| Feature | Provider Contract | Order Negotiation |
|---------|------------------|-------------------|
| **Initiated by** | Admin | Client |
| **Purpose** | Employment agreement | Service order pricing |
| **Notification Type** | SYSTEM | ORDERS |
| **Can negotiate** | No (accept/reject only) | Yes (accept/counter/reject) |
| **Affects** | Your employment status | Individual order |

---

## Related Documentation
- [Provider Service Order Flow](./PROVIDER_SERVICE_ORDER_FLOW.md)
- [Provider API Reference](./PROVIDER_API_REFERENCE_UPDATED.md)
- [Notification System](./NOTIFICATION_SYSTEM.md)
- [Provider Dashboard Features](./PROVIDER_DASHBOARD_NEW_FEATURES.md)

---

## Troubleshooting

### "This order is not awaiting your response"
- The order is currently the client's turn
- Check `negotiation_turn` field - it must be `'provider'` for you to respond
- Wait for client to respond before taking action

### "Maximum negotiation rounds reached"
- You've hit the admin-configured round limit
- You can only accept or reject at this point
- Cannot make another counter-offer

### "The agreed price must be at least X SAR"
- Your counter-offer is below the service's minimum price
- Check `service.price_from` value
- Adjust your counter-offer to be within range

### "The agreed price cannot exceed X SAR"
- Your counter-offer is above the service's maximum price
- Check `service.price_to` value
- Adjust your counter-offer to be within range

### Order automatically cancelled
- Either you or the client didn't respond within the timeout window
- Check your notification history for timeout warnings
- Enable real-time notifications to avoid missing deadlines

---

**Document Version**: 1.0  
**Last Updated**: October 28, 2026  
**Feature Status**: ✅ Implemented
