Skip to content

Commit

Permalink
[CHG] account_payment_method_or_mode_fs_storage: export file to stora…
Browse files Browse the repository at this point in the history
…ge as late as possible
  • Loading branch information
AnizR committed Feb 17, 2025
1 parent 786b357 commit 7732a10
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 11 deletions.
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Copyright 2024 ACSONE SA/NV
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
import base64
import logging

from odoo import _, models
from odoo import _, api, models, registry
from odoo.exceptions import UserError

_logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -41,28 +42,58 @@ def _export_to_storage(self, file_content, filename):
) from e
return True

Check warning on line 43 in account_payment_method_or_mode_fs_storage/models/account_payment_order.py

View check run for this annotation

Codecov / codecov/patch

account_payment_method_or_mode_fs_storage/models/account_payment_order.py#L43

Added line #L43 was not covered by tests

def generate_payment_file(self):
def _get_payment_attachment_to_export(self):
"""
Inherit to catch file generation and put it on the storage (if necessary)
Return attachment linked to payment order that should be exported
"""
file_content, filename = super().generate_payment_file()
if self._must_be_exported_to_storage():
self._export_to_storage(file_content, filename)
return file_content, filename
self.ensure_one()

return self.env["ir.attachment"].search(
[("res_model", "=", "account.payment.order"), ("res_id", "=", self.id)],
limit=1,
order="create_date DESC",
)

def open2generated(self):
self.ensure_one()
action = super().open2generated()
if self._must_be_exported_to_storage():
self.generated2uploaded()

# exporting to storage should be done as late as possible
# since it may be unreversible
@self.env.cr.postcommit.add
def export_attachment():
db_registry = registry(self.env.cr.dbname)
with db_registry.cursor() as cr:
context = self.env.context
uid = self.env.uid

env = api.Environment(cr, uid, context)
order = self.with_env(env)

try:
attachment = order._get_payment_attachment_to_export()
if not attachment:
raise UserError(_("Attachment to upload not found!"))
content = base64.b64decode(attachment.datas)
order._export_to_storage(content, attachment.name)

Check warning on line 80 in account_payment_method_or_mode_fs_storage/models/account_payment_order.py

View check run for this annotation

Codecov / codecov/patch

account_payment_method_or_mode_fs_storage/models/account_payment_order.py#L79-L80

Added lines #L79 - L80 were not covered by tests
except UserError:
self.action_uploaded_cancel()
self.message_post(
body=_(
"Order set to canceled due to Error while uploading file"
)
)

action = {
"type": "ir.actions.client",
"tag": "display_notification",
"params": {
"type": "success",
"title": _("Generate and export"),
"message": _(
"The file has been generated and dropped on the storage."
"The file has been scheduled to be dropped on the storage."
),
"sticky": True,
"next": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from datetime import date
from unittest.mock import patch

from odoo import _
from odoo.exceptions import UserError
from odoo.tests import tagged

Expand Down Expand Up @@ -70,6 +71,18 @@ def with_custom_method(self):
):
yield

@contextmanager
def with_raise_error_while_exporting(self):
def dummy_raise():
raise UserError(_("Error"))

Check warning on line 77 in account_payment_method_or_mode_fs_storage/tests/test_account_payment_method_or_mode_fs_storage.py

View check run for this annotation

Codecov / codecov/patch

account_payment_method_or_mode_fs_storage/tests/test_account_payment_method_or_mode_fs_storage.py#L77

Added line #L77 was not covered by tests

path = (
"odoo.addons.account_payment_method_or_mode_fs_storage.models"
".account_payment_order.AccountPaymentOrder._export_to_storage"
)
with patch(path, new=dummy_raise, create=True):
yield

def test_payment_method_fs_storage(self):
self.env.user.company_id = self.company.id
self.company.update(
Expand Down Expand Up @@ -104,6 +117,9 @@ def test_payment_method_fs_storage(self):
with self.with_custom_method():
action = order.open2generated()

# trigger postcommit without actually commiting transaction
self.env.cr.postcommit.run()

self.assertDictEqual(
action,
{
Expand All @@ -112,7 +128,7 @@ def test_payment_method_fs_storage(self):
"params": {
"type": "success",
"title": "Generate and export",
"message": "The file has been generated and dropped on the storage.",
"message": "The file has been scheduled to be dropped on the storage.",
"sticky": True,
"next": {
"type": "ir.actions.client",
Expand Down Expand Up @@ -186,6 +202,9 @@ def test_method_fs_storage_other_company(self):
with self.with_custom_method():
action = order.open2generated()

# trigger postcommit without actually commiting transaction
self.env.cr.postcommit.run()

self.assertDictEqual(
action,
{
Expand All @@ -194,7 +213,7 @@ def test_method_fs_storage_other_company(self):
"params": {
"type": "success",
"title": "Generate and export",
"message": "The file has been generated and dropped on the storage.",
"message": "The file has been scheduled to be dropped on the storage.",
"sticky": True,
"next": {
"type": "ir.actions.client",
Expand Down Expand Up @@ -244,6 +263,9 @@ def test_payment_mode_fs_storage(self):
with self.with_custom_method():
action = order.open2generated()

# trigger postcommit without actually commiting transaction
self.env.cr.postcommit.run()

self.assertDictEqual(
action,
{
Expand All @@ -252,7 +274,7 @@ def test_payment_mode_fs_storage(self):
"params": {
"type": "success",
"title": "Generate and export",
"message": "The file has been generated and dropped on the storage.",
"message": "The file has been scheduled to be dropped on the storage.",
"sticky": True,
"next": {
"type": "ir.actions.client",
Expand Down Expand Up @@ -291,3 +313,45 @@ def test_check_use_on_payment_mode(self):

self.creation_mode.write({"storage": False})
mode_config.fs_storage_ids = False

def test_error_while_uploading(self):
self.env.user.company_id = self.company.id
self.company.update(
{
"fs_storage_source_payment": "mode",
}
)

self.env["ir.config_parameter"].sudo().set_param(
f"account_payment_method_or_mode_fs_storage.fs_storage_ids_{self.company.id}",
[self.fs_storage_mode.id],
)
self.creation_mode.storage = str(self.fs_storage_mode.id)

order_vals = {
"payment_type": "outbound",
"payment_mode_id": self.creation_mode.id,
"journal_id": self.bank_journal.id,
}

order = self.env["account.payment.order"].create(order_vals)

vals = {
"order_id": order.id,
"partner_id": self.partner.id,
"communication": "manual line and manual date",
"currency_id": order.payment_mode_id.company_id.currency_id.id,
"amount_currency": 200,
"date": date.today(),
}
self.env["account.payment.line"].create(vals)

order.draft2open()
with self.with_custom_method():
order.open2generated()

with self.with_raise_error_while_exporting():
# trigger postcommit without actually commiting transaction
self.env.cr.postcommit.run()

self.assertEqual(order.state, "cancel")

0 comments on commit 7732a10

Please sign in to comment.