# Updating records in Odoo

Looking up sale orders and other records with search and modifying them in place with write.

Updates in Odoo's external API are a two-step operation - first, **search** finds the IDs of the records to change, then **write** applies the same set of new values to all of them. This chapter uses the Odoo.Sample connection defined in the [main Odoo chapter](https://zato.io/docs/dev/odoo/index.html).

## Looking up and updating a sale order {#looking-up-and-updating-a-sale-order}

The service below receives an order reference from another system, e.g. a shipping platform, finds the matching **sale.order** and updates its delivery information:

```python
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class UpdateOrder(Service):
    name = 'demo.odoo.update-order'

    input = 'order_ref', 'tracking_ref'

    def handle(self) -> 'None':

        # Connection to use
        conn_name = 'Odoo.Sample'

        # Local alias for readability
        request = self.request.input

        # Obtain a client connected to the system
        with self.outgoing.odoo.get(conn_name).conn.client() as client:

            # Point the client to the model we want to update
            model = client.get_model('sale.order')

            # Find the order by its reference, e.g. SO0042
            order_ids = model.search([('name', '=', request.order_ref)])

            # Tell the caller if there is no such order
            if not order_ids:
                self.response.payload = {'found': False}
                return

            # Apply the new values to the order
            model.write(order_ids, {
                'client_order_ref': request.tracking_ref,
            })

            # Confirm the update to the caller
            self.response.payload = {'found': True, 'order_ids': order_ids}
```

The **write** method accepts a list of IDs, so the result of **search** can be passed to it directly - if the domain matches multiple records, all of them receive the same new values in one call.

To delete records, pass the same list of IDs to **unlink**:

```python
model.unlink(order_ids)
```

## Learn more {#learn-more}

- [Odoo integrations](https://zato.io/docs/dev/odoo/) - Odoo models from Python services, over XML-RPC and JSON-RPC
- [Reading data](https://zato.io/docs/dev/odoo/reading-data/) - Searching, reading and field lists against any Odoo model
- [Creating records](https://zato.io/docs/dev/odoo/creating-records/) - New partners, leads and orders, with their related records
- [Odoo calls Zato](https://zato.io/docs/dev/odoo/odoo-calls-zato/) - Automation rules and webhooks that invoke your services
- [Odoo Online](https://zato.io/docs/dev/odoo/odoo-online/) - What differs when the instance is hosted by Odoo
