Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/8.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add support for updating records
2 changes: 1 addition & 1 deletion docs/managers/account-move.md
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ Values:
* ``reversed`` - Reversed
* ``invoicing_legacy`` - Invoicing App Legacy

### state
### `state`

```python
state: Literal["draft", "posted", "cancel"]
Expand Down
86 changes: 83 additions & 3 deletions docs/managers/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -770,14 +770,55 @@ pass the returned IDs to the [``list``](#list) method.
|-------------|--------------------------------------|
| `list[int]` | The IDs of the newly created records |

### `update`

```python
def update(record: int | Record, **fields: Any) -> None
```

Update one or more fields on this record in place.

```python
>>> from openstack_odooclient import Client as OdooClient
>>> odoo_client = OdooClient(
... hostname="localhost",
... port=8069,
... protocol="jsonrpc",
... database="odoodb",
... user="test-user",
... password="<password>",
... )
>>> odoo_client.users.get(1234)
User(record={'id': 1234, 'name': 'Old Name', ...}, fields=None)
>>> odoo_client.users.update(1234, name="New Name")
>>> odoo_client.users.get(1234)
User(record={'id': 1234, 'name': 'New Name', ...}, fields=None)
```

Field names are passed as keyword arguments.
This method has the same flexibility with regards to what
field names are used as when [creating records](#create);
for example, when updating a model ref, either its ID
(e.g. ``user_id``) or object (e.g. ``user``) field names
can be used.

*Added in version 0.2.0.*

#### Parameters

| Name | Type | Description | Default |
|------------|----------------|-----------------------------------------|------------|
| `record` | `int | Record` | The record to update (object or ID) | (required) |
| `**fields` | `Any` | Record field values (keyword arguments) | (required) |

### `unlink`/`delete`

```python
unlink(*records: Record | int | Iterable[Record | int]) -> None
unlink(*records: int | Record | Iterable[int | Record]) -> None
```

```python
delete(*records: Record | int | Iterable[Record | int]) -> None
delete(*records: int | Record | Iterable[int | Record]) -> None
```

Delete one or more records from Odoo.
Expand Down Expand Up @@ -1357,6 +1398,44 @@ User(record={'id': 1234, ...}, fields=None)
|------------------|-------------------|
| `dict[str, Any]` | Record dictionary |

#### `update`

```python
def update(**fields: Any) -> None
```

Update one or more fields on this record in place.

```python
>>> user
User(record={'id': 1234, 'name': 'Old Name', ...}, fields=None)
>>> user.update(name="New Name")
>>> user.refresh()
User(record={'id': 1234, 'name': 'New Name', ...}, fields=None)
```

Field names are passed as keyword arguments.
This method has the same flexibility with regards to what
field names are used as when [creating records](#create);
for example, when updating a model ref, either its ID
(e.g. ``user_id``) or object (e.g. ``user``) field names
can be used.

!!! note

This record object is not updated in place by this method.

If you need an updated version of the record object,
use the [`refresh`](#refresh) method to fetch the latest version.

*Added in version 0.2.0.*

##### Parameters

| Name | Type | Description | Default |
|------------|-------|-----------------------------------------|------------|
| `**fields` | `Any` | Record field values (keyword arguments) | (required) |

#### `refresh`

```python
Expand Down Expand Up @@ -1395,9 +1474,10 @@ Delete this record from Odoo.

```python
>>> user
User(record={'id': 1234, 'name': 'Old Name', ...}, fields=None)
User(record={'id': 1234, ...}, fields=None)
>>> user.unlink()
>>> user.refresh()
Traceback (most recent call last):
...
openstack_odooclient.exceptions.RecordNotFoundError: User record not found with ID: 1234
```
Expand Down
17 changes: 17 additions & 0 deletions openstack_odooclient/base/record.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,6 +266,23 @@ def as_dict(self, raw: bool = False) -> dict[str, Any]:
}
)

def update(self, **fields: Any) -> None:
"""Update one or more fields on this record in place.

Field names are passed as keyword arguments.
This method has the same flexibility with regards to what
field names are used as when creating records; for example,
when updating a model ref, either its ID (e.g. ``user_id``)
or object (e.g. ``user``) field names can be used.

Note that this record object is not updated in place by
this method. If you need an updated version of the record
object, use the `refresh` method to fetch the latest version.

*Added in version 0.2.0.*
"""
self._manager.update(self.id, **fields)

def refresh(self) -> Self:
"""Fetch the latest version of this record from Odoo.

Expand Down
21 changes: 20 additions & 1 deletion openstack_odooclient/base/record_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,7 @@ def _encode_filter_field(self, field: str) -> tuple[Any, str]:
type_hint = self._record_type_hints[local_field]
return (type_hint, remote_field)

def create(self, **fields) -> int:
def create(self, **fields: Any) -> int:
"""Create a new record, using the specified keyword arguments
as input fields.

Expand Down Expand Up @@ -808,6 +808,25 @@ def _encode_create_field(
self._encode_value(type_hint=type_hint, value=value),
)

def update(self, record: int | Record, **fields: Any) -> None:
"""Update one or more fields on the given record in place.

Field names are passed as keyword arguments.
This method has the same flexibility with regards to what
field names are used as when creating records; for example,
when updating a model ref, either its ID (e.g. ``user_id``)
or object (e.g. ``user``) field names can be used.

*Added in version 0.2.0.*

:param record: The record to update (object or ID)
:type record: int | Record
"""
self._env.update(
record.id if isinstance(record, RecordBase) else record,
self._encode_create_fields(fields),
)

def unlink(
self,
*records: int | Record | Iterable[int | Record],
Expand Down
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ packages = ["openstack_odooclient"]
[tool.poe.tasks]
lint = "ruff check"
format = "ruff format"
type-check = "mypy openstack_odooclient"

[tool.ruff]
fix = true
Expand Down