# Jira & Odoo API Endpoints - For Remaining Tasks

**Covers:** Dashboard gadgets (Week 3), Data import (Week 4), Workflows limitations

---

## WEEK 3: Dashboard Gadgets

### Sources
- https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-dashboards/
- https://stackoverflow.com/questions/72992053/jira-rest-api-for-configuring-dashboard-gadget

### Problem Summary
The REST API can **create empty gadgets** but **cannot configure them fully** (set saved filter, number of results, columns). You must use PUT with dashboard item properties.

---

### 1. Get Dashboard
```bash
GET /rest/api/3/dashboard/{dashboardId}
```

**Response includes:** gadgets list with their IDs and properties

---

### 2. Add Gadget to Dashboard
```bash
POST /rest/api/3/dashboard/{dashboardId}/gadget
```

**Request Body:**
```json
{
  "moduleKey": "com.atlassian.jira.gadgets:filter-results",
  "position": {
    "column": 1,
    "row": 0
  }
}
```

**Common Gadget Module Keys:**
- `com.atlassian.jira.gadgets:filter-results` - Issue filter list
- `com.atlassian.jira.gadgets:issue-statistics` - Issue statistics
- `com.atlassian.jira.gadgets:sprint-health` - Sprint health (Scrum)
- `com.atlassian.jira.gadgets:burndown` - Sprint burndown
- `com.atlassian.jira.gadgets:two-dimensional-statistics` - 2D stats
- `com.atlassian.jira.gadgets:average-time-in-status` - Average time
- `com.atlassian.jira.gadgets:pie-chart` - Pie chart by field
- `com.atlassian.jira.gadgets:recently-updated` - Recently updated issues
- `com.atlassian.jira.gadgets:twelve-mile-radius` - 12-Mile Radius
- `com.atlassian.jira.gadgets:time-tracking` - Time tracking
- `com.atlassian.jira.gadgets:created-vs-resolved` - Created vs Resolved

**Response:** Gadget object with `id`

---

### 3. Configure Gadget (SET SAVED FILTER)
```bash
PUT /rest/api/3/dashboard/{dashboardId}/items/{gadgetId}/properties/{propertyKey}
```

**For Filter Results gadget:**

```bash
PUT /rest/api/3/dashboard/{dashboardId}/items/{gadgetId}/properties/filterId
```

**Request Body:**
```json
{
  "value": "{filterId}"
}
```

**Other property keys to configure:**
- `filterId` - Which filter to display
- `num` - Number of results to show
- `columnNames` - Which columns to display (comma-separated field names)
- `refresh` - Auto-refresh interval in minutes
- `isConfigured` - Set to true when configured

---

### 4. Update Gadget Position
```bash
PUT /rest/api/3/dashboard/{dashboardId}/gadget/{gadgetId}
```

**Request Body:**
```json
{
  "position": {
    "column": 1,
    "row": 2
  }
}
```

---

### 5. Remove Gadget
```bash
DELETE /rest/api/3/dashboard/{dashboardId}/gadget/{gadgetId}
```

---

### 6. Update Dashboard
```bash
PUT /rest/api/3/dashboard/{dashboardId}
```

**Request Body:**
```json
{
  "name": "Updated Dashboard Name",
  "description": "New description"
}
```

---

## Example: Add & Configure Filter Results Gadget

### Step 1: Get Dashboard
```bash
curl -X GET "https://ai-impress.atlassian.net/rest/api/3/dashboard/10000" \
  -H "Authorization: Basic ${JIRA_AUTH}"
```

### Step 2: Create Gadget
```bash
curl -X POST "https://ai-impress.atlassian.net/rest/api/3/dashboard/10000/gadget" \
  -H "Authorization: Basic ${JIRA_AUTH}" \
  -d '{
    "moduleKey": "com.atlassian.jira.gadgets:filter-results",
    "position": {"column": 1, "row": 0}
  }'
```

**Response gives you `gadgetId`**

### Step 3: Set Filter
```bash
curl -X PUT "https://ai-impress.atlassian.net/rest/api/3/dashboard/10000/items/{gadgetId}/properties/filterId" \
  -H "Authorization: Basic ${JIRA_AUTH}" \
  -d '{"value": "10001"}'
```

### Step 4: Set Columns
```bash
curl -X PUT "https://ai-impress.atlassian.net/rest/api/3/dashboard/10000/items/{gadgetId}/properties/columnNames" \
  -H "Authorization: Basic ${JIRA_AUTH}" \
  -d '{"value": "key,summary,status,assignee"}'
```

### Step 5: Mark as Configured
```bash
curl -X PUT "https://ai-impress.atlassian.net/rest/api/3/dashboard/10000/items/{gadgetId}/properties/isConfigured" \
  -H "Authorization: Basic ${JIRA_AUTH}" \
  -d '{"value": "true"}'
```

---

## WEEK 3: Workflows - API Limitations

### ⚠️ Key Finding
**CANNOT create workflows for team-managed projects via API**

**From:** https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/

**What you CAN do:**
- `GET /rest/api/3/workflows` - List workflows (read-only)
- `GET /rest/api/3/workflow/search` - Search workflows
- `GET /rest/api/3/project/{projectKey}/workflows` - Get project workflows
- `GET /rest/api/3/issue/{issueKey}/transitions` - Get available transitions

**What you CANNOT do:**
- Create new workflows (team-managed projects)
- Modify workflow statuses
- Add workflow conditions/validators

### Workaround: Transition Issues Instead

You CAN transition issues programmatically:

```bash
POST /rest/api/3/issue/{issueKey}/transitions
```

**Request Body:**
```json
{
  "transition": {
    "id": "11"
  },
  "fields": {
    "resolution": {
      "name": "Done"
    }
  }
}
```

---

## WEEK 4: Data Import - Odoo API

### Sources
- https://www.odoo.com/documentation/18.0/developer/reference/external_api.html
- https://getknit.dev/blog/odoo-api-integration-guide-in-depth

### Authentication

Odoo uses username/password or Access Token:

```bash
# Option 1: Username/Password
curl -X POST https://odoo.ai-impress.com/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "method": "call",
    "params": {
      "login": "admin@example.com",
      "password": "password",
      "database": "production"
    }
  }'
```

```bash
# Option 2: Access Token (simpler)
curl -X GET https://odoo.ai-impress.com/api/res.partner \
  -H "Authorization: Bearer YOUR_ODOO_TOKEN"
```

---

### 1. Read Contacts (res.partner)

#### Method A: REST API (Modern)
```bash
GET https://odoo.ai-impress.com/api/res.partner
```

**Query Parameters:**
- `fields=name,email,phone,company_name` - Specific fields
- `limit=100` - Results per page
- `offset=0` - Pagination offset
- `filters=[["is_company", "=", false]]` - Filter to individuals only

**Response:**
```json
{
  "data": [
    {
      "id": 1,
      "name": "John Doe",
      "email": "john@example.com",
      "phone": "+44 20 7946 0958",
      "company_id": 2
    }
  ]
}
```

---

#### Method B: JSON-RPC (Classic)
```bash
POST https://odoo.ai-impress.com/jsonrpc
```

**Request:**
```json
{
  "jsonrpc": "2.0",
  "method": "call",
  "params": {
    "service": "object",
    "method": "execute_kw",
    "args": [
      "production",
      2,
      "password",
      "res.partner",
      "search_read",
      [[]],
      {"fields": ["name", "email", "phone", "company_name"]}
    ]
  }
}
```

---

### 2. Filter Contacts by Conditions

```bash
GET https://odoo.ai-impress.com/api/res.partner?filters=[["active","=",true],["is_company","=",false]]
```

---

### 3. Export to CSV

Use REST API to get data, then convert to CSV:

```python
import requests
import csv

response = requests.get(
    "https://odoo.ai-impress.com/api/res.partner",
    headers={"Authorization": "Bearer TOKEN"},
    params={
        "fields": "name,email,phone,company_name",
        "limit": 1000
    }
)

contacts = response.json()["data"]

with open("contacts.csv", "w") as f:
    writer = csv.DictWriter(f, fieldnames=["name", "email", "phone", "company_name"])
    writer.writeheader()
    writer.writerows(contacts)
```

---

## WEEK 4: Create Issues in Jira (From CSV)

### 1. Create Single Issue
```bash
POST /rest/api/3/issue
```

**Request:**
```json
{
  "fields": {
    "project": {
      "key": "MARK"
    },
    "summary": "Acme Corporation",
    "description": "Lead imported from Odoo",
    "issuetype": {
      "name": "Lead"
    },
    "customfield_10119": "contact@acme.com",
    "customfield_10120": "+44 20 7946 0958",
    "customfield_10118": "Acme Corp",
    "customfield_10111": {
      "value": "New"
    },
    "customfield_10110": {
      "value": "Referral"
    }
  }
}
```

---

### 2. Bulk Create Issues (79 contacts)
```bash
POST /rest/api/3/issue/bulk
```

**Request:**
```json
{
  "issues": [
    {
      "fields": {
        "project": {"key": "MARK"},
        "summary": "Contact 1",
        "issuetype": {"name": "Lead"},
        "customfield_10119": "contact1@example.com",
        "customfield_10120": "+44 123456789",
        "customfield_10118": "Company 1",
        "customfield_10111": {"value": "New"},
        "customfield_10110": {"value": "Referral"}
      }
    },
    {
      "fields": {
        "project": {"key": "MARK"},
        "summary": "Contact 2",
        "issuetype": {"name": "Lead"},
        "customfield_10119": "contact2@example.com",
        "customfield_10120": "+44 987654321",
        "customfield_10118": "Company 2",
        "customfield_10111": {"value": "New"},
        "customfield_10110": {"value": "Referral"}
      }
    }
  ]
}
```

---

### 3. Search Imported Issues (Verify)
```bash
GET /rest/api/3/search?jql=project=MARK AND type=Lead
```

---

### 4. Link Issues (Create relationships)

```bash
POST /rest/api/3/issueLink
```

**Request:**
```json
{
  "type": {
    "name": "relates to"
  },
  "inwardIssue": {
    "key": "MARK-101"
  },
  "outwardIssue": {
    "key": "MARK-102"
  }
}
```

---

## Complete API Summary Table

| Task | HTTP | Endpoint | Notes |
|------|------|----------|-------|
| **Dashboard** |
| Get dashboard | GET | `/rest/api/3/dashboard/{id}` | |
| Add gadget | POST | `/rest/api/3/dashboard/{id}/gadget` | Creates empty gadget |
| Configure gadget | PUT | `/rest/api/3/dashboard/{id}/items/{gadgetId}/properties/{key}` | Set filter, columns, refresh |
| Remove gadget | DELETE | `/rest/api/3/dashboard/{id}/gadget/{gadgetId}` | |
| Update dashboard | PUT | `/rest/api/3/dashboard/{id}` | Name, description |
| **Workflows** |
| List workflows | GET | `/rest/api/3/workflows` | **Read-only** |
| Get transitions | GET | `/rest/api/3/issue/{key}/transitions` | What transitions available |
| Transition issue | POST | `/rest/api/3/issue/{key}/transitions` | Move issue to new status |
| **Odoo** |
| Get contacts | GET | `/api/res.partner` | Needs auth token |
| Search contacts | GET | `/api/res.partner?filters=...` | Filter by conditions |
| **Jira Issues** |
| Create issue | POST | `/rest/api/3/issue` | Single lead |
| Bulk create | POST | `/rest/api/3/issue/bulk` | 79 contacts at once |
| Search issues | GET | `/rest/api/3/search?jql=...` | Verify import |
| Link issues | POST | `/rest/api/3/issueLink` | Create relationships |

---

## Key Takeaways

✅ **Can automate via API:**
- Create Confluence spaces & pages
- Create automation rules
- Add dashboard gadgets (though limited config)
- Bulk import contacts
- Link issues

❌ **Must do manually in UI:**
- Create/modify workflows (team-managed)
- Configure SLA policies (Service Desk)
- Assign project roles
- Set up email integration
- Configure board columns

---

**Documentation Links:**
- Jira Dashboards: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-dashboards/
- Jira Workflows: https://developer.atlassian.com/cloud/jira/platform/rest/v3/api-group-workflows/
- Odoo API: https://www.odoo.com/documentation/18.0/developer/reference/external_api.html
