> This page is for version V1 (default).
> For other versions, use one of these documentation indexes:
> - V1 (default): https://docs.ottimate.com/v-1/llms.txt

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.ottimate.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.ottimate.com/_mcp/server.

# Catalog

This section explains how to interact with catalog entries using the Ottimate SDK.

### Fetching Catalog Entries

You can retrieve a list of catalog entries for a specific company. It's also possible to filter these entries, for example, by `vendor_name`.

```python
# Fetch catalog entries for a company
catalog_entries = client.catalog.get_catalog_entries(
    ottimate_company_id=ottimate_company_id
)

print(f"Fetched {len(catalog_entries.results)} catalog entries.")
for entry in catalog_entries.results:
    print(f" - Catalog Entry: Ottimate ID: {entry.id} | Name: {entry.description}")
```

### Creating a Catalog Entry

This example shows how to create a new catalog entry.

```python
new_catalog_entry = client.catalog.post_catalog_entries(
    ottimate_company_id=ottimate_company_id,
    description=f"SDK Catalog Item {time_now}",            
    price=10.99,
    erp_vendor_name="AWG"
)

print(f"✅ Created catalog entry with ID: {new_catalog_entry.id}")
```

### Fetching a Single Catalog Entry

You can retrieve a specific catalog entry by its ID.

```python
fetched_entry = client.catalog.get_catalog_entries_id(
    id=catalog_entry_id
)
print(f"✅ Fetched catalog entry: {fetched_entry}")
```

### Updating a Catalog Entry

This shows how to update an existing catalog entry, for example, to change its price.

```python
updated_entry = client.catalog.patch_catalog_entries_id(
    id=catalog_entry_id,
    price=11
)
print(f"✅ Updated catalog entry price to: {updated_entry.price}")
```

### Bulk Creating Catalog Entries

You can also create multiple catalog entries in a single request.

```python
bulk_entries = [
    {"description": f"Bulk Item 1 {time_now}", "code": f"SDK-BULK1-{time_now}", "price": 5.99, "unit": "EACH", "erp_vendor_name":  "AWG"},
    {"description": f"Bulk Item 2 {time_now}", "code": f"SDK-BULK2-{time_now}", "price": 7.49, "unit": "EACH", "erp_vendor_name":  "AWG"},
]
bulk_response = client.catalog.post_catalog_entries_bulk(
    ottimate_company_id=ottimate_company_id,
    entries=bulk_entries
)
# Print summary of bulk creation
print(f"✅ Bulk created {bulk_response.success_count} catalog entries.")
# Print details of created entries
if hasattr(bulk_response, "created") and bulk_response.created:
    print("Created entries:")
    for entry in bulk_response.created:
        print(f"  - ID: {entry.get('id')}, Description: {entry.get('description')}")
# Print details of updated entries
if hasattr(bulk_response, "updated") and bulk_response.updated:
    print("Updated entries:")
    for entry in bulk_response.updated:
        print(f"  - ID: {entry.get('id')}, Description: {entry.get('description')}")
# Print details of errors
if hasattr(bulk_response, "errors") and bulk_response.errors:
    print("Failed entries:")
    for error in bulk_response.errors:
        print(f"  - Error: {error}")
else:
    print("No failures in bulk creation.")
```

## Catalog Allowances

This section covers managing catalog allowances.

### Fetching Catalog Allowances

You can retrieve all allowances for a company, with optional filters.

```python
catalog_allowances = client.catalog.get_catalog_allowances(
    ottimate_company_id=ottimate_company_id,
)
print(f"✅ Fetched {len(catalog_allowances.results)} catalog allowances.")
for allowance in catalog_allowances.results:
    print(f" - Allowance ID: {allowance.id}, Amount: {allowance.amount}, Catalog Entry: {allowance.catalog_entry_id}")
```

### Creating a Catalog Allowance

This example shows how to create a new allowance for a catalog entry.

```python
start_date = datetime.now()
end_date = start_date + timedelta(days=30)
new_allowance = client.catalog.post_catalog_allowances(
    ottimate_company_id=ottimate_company_id,
    catalog_entry_id=catalog_entry_id,
    amount=8.50,
    start_date=start_date,
    end_date=end_date
)
print(f"✅ Created catalog allowance with ID {new_allowance}")
```

### Updating a Catalog Allowance

You can update an existing allowance by its ID.

```python
allowance_id = "cta_2_RQGdxm~4z2"
updated_allowance = client.catalog.patch_catalog_allowances_id(
    id=allowance_id,
    amount=3.00
)
print(f"✅ Updated catalog allowance ID {allowance_id} to new amount: {updated_allowance.amount}")
```

### Bulk Creating Catalog Allowances

This example demonstrates how to create multiple allowances in a single API call.

```python
bulk_response = client.catalog.post_catalog_allowances_bulk(
    ottimate_company_id=ottimate_company_id,
        allowances=[{
        "catalog_entry_id": "cte_jgNeV9o_h0Tj",
        "allowance_type": "rebate",
        "amount": 999,
        "start_date": "2025-12-01"                
    }]
)
print(f"✅ Bulk created {bulk_response.success_count} catalog allowances.")
if hasattr(bulk_response, "created") and bulk_response.created:
    print("Created allowances:")
    for allowance in bulk_response.created:
        print(f"  - ID: {allowance.get('id')}, Catalog Entry: {allowance.get('catalog_entry_id')}, Amount: {allowance.get('amount')}")
if hasattr(bulk_response, "updated") and bulk_response.updated:
    print("Updated allowances:")
    for allowance in bulk_response.updated:
        print(f"  - ID: {allowance.get('id')}, Catalog Entry: {allowance.get('catalog_entry_id')}, Amount: {allowance.get('amount')}")
if hasattr(bulk_response, "errors") and bulk_response.errors:
    print("Failed allowances:")
    for error in bulk_response.errors:
        print(f"  - Error: {error}")
else:
    print("No failures in bulk creation.")
```

## Catalog Variances

This section explains how to work with catalog variances.

### Fetching Catalog Variances

You can retrieve a list of catalog variances for a given company.

```python
# Fetching catalog variances for company
variances_response = client.catalog.get_catalog_variances(
    ottimate_company_id=ottimate_company_id,
    limit=5
)

for variance in variances_response.results:
    print(f" - Catalog Entry ID: {variance.id}, Invoice Item ID: {variance.last_invoice_item.id}")
```

### Fetching Invoice Items for a Variance

You can fetch the invoice items associated with a specific catalog variance by its ID.

```python
invoice_items = client.catalog.get_catalog_variances_id_invoice_items(id=catalog_entry_id)
print(f"✅ Fetched variance details for catalog entry ID {catalog_entry_id}: {invoice_items.results}")
```