Skip to content

Commit df2067a

Browse files
author
Callum Dickinson
committed
Add support for managing attachments
Add a new manager for attachment records (`ir.attachment`) in Odoo. These are intended to be used for uploading/downloading attachments to/from invoices. Invoice attachments will then be attached to invoice emails sent out to customers. The contents of the attachments won't be fetched when querying them from Odoo by default; instead it is intended that the separate `download` method be used to download the attachment contents separately. An `upload` method is also available, to provide an easier to use interface for uploading attachments.
1 parent a033bdb commit df2067a

File tree

8 files changed

+361
-0
lines changed

8 files changed

+361
-0
lines changed

_typos.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[default.extend-words]
2+
datas = "datas"

changelog.d/7.added.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Add support for managing attachments

openstack_odooclient/base/client.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,12 @@ def __init__(
167167
opener=opener,
168168
)
169169
self._odoo.login(database, username, password)
170+
self._env_manager_mapping: dict[str, RecordManagerBase] = {}
171+
"""An internal mapping between env (model) names and their managers.
172+
173+
This is populated by the manager classes themselves when created,
174+
and used by the ``Attachment.res_model_manager`` field.
175+
"""
170176
self._record_manager_mapping: dict[
171177
Type[RecordBase],
172178
RecordManagerBase,

openstack_odooclient/base/record_manager.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ def __init__(self, client: ClientBase) -> None:
109109
"""The Odoo client object the manager uses."""
110110
# Assign this record manager object as the manager
111111
# responsible for the configured record class in the client.
112+
self._client._env_manager_mapping[self.env_name] = self
112113
self._client._record_manager_mapping[self.record_class] = self
113114
self._record_type_hints = MappingProxyType(
114115
get_type_hints(
@@ -964,3 +965,6 @@ def _encode_value(self, type_hint: Any, value: Any) -> Any:
964965
v_type = get_type_args(type_hint)[0]
965966
return [self._encode_value(v_type, v) for v in value]
966967
return value
968+
969+
970+
RecordManager = RecordManagerBase[RecordBase["RecordManager"]]

openstack_odooclient/client.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
from .base.client import ClientBase
1919
from .managers.account_move import AccountMoveManager
2020
from .managers.account_move_line import AccountMoveLineManager
21+
from .managers.attachment import AttachmentManager
2122
from .managers.company import CompanyManager
2223
from .managers.credit import CreditManager
2324
from .managers.credit_transaction import CreditTransactionManager
@@ -90,6 +91,9 @@ class Client(ClientBase):
9091
account_move_lines: AccountMoveLineManager
9192
"""Account move (invoice) line manager."""
9293

94+
attachments: AttachmentManager
95+
"""Attachment manager."""
96+
9397
companies: CompanyManager
9498
"""Company manager."""
9599

openstack_odooclient/managers/account_move.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,28 @@ class AccountMove(RecordBase["AccountMoveManager"]):
7373
is_move_sent: bool
7474
"""Whether or not the account move (invoice) has been sent."""
7575

76+
message_main_attachment_id: Annotated[
77+
int,
78+
ModelRef("message_main_attachment_id", Attachment),
79+
]
80+
"""The ID of the main attachment on the invoice, if there is one."""
81+
82+
message_main_attachment_name: Annotated[
83+
str,
84+
ModelRef("message_main_attachment_name", Attachment),
85+
]
86+
"""The name of the main attachment on the invoice, if there is one."""
87+
88+
message_main_attachment: Annotated[
89+
Attachment,
90+
ModelRef("message_main_attachment", Attachment),
91+
]
92+
"""The main attachment on the invoice, if there is one.
93+
94+
This fetches the full record from Odoo once,
95+
and caches it for subsequent accesses.
96+
"""
97+
7698
move_type: Literal[
7799
"entry",
78100
"out_invoice",
@@ -237,5 +259,6 @@ def send_openstack_invoice_email(
237259

238260
# NOTE(callumdickinson): Import here to make sure circular imports work.
239261
from .account_move_line import AccountMoveLine # noqa: E402
262+
from .attachment import Attachment # noqa: E402
240263
from .currency import Currency # noqa: E402
241264
from .project import Project # noqa: E402

0 commit comments

Comments
 (0)