From adeae4235da4a254c99f32f7eef04ec6480b312e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phan=20Sainl=C3=A9ger?= Date: Tue, 4 Aug 2026 10:29:46 +0200 Subject: [PATCH] [MIG] account_mooncard_receipt_lost_transfer: migrate to 18.0 --- .../README.md | 32 ++++ .../__init__.py | 2 + .../__manifest__.py | 21 +++ .../models/__init__.py | 3 + .../models/account_move.py | 15 ++ .../models/newgen_payment_card_transaction.py | 31 ++++ .../tests/__init__.py | 1 + .../tests/test_receipt_lost_transfer.py | 144 ++++++++++++++++++ .../views/account_move_views.xml | 28 ++++ 9 files changed, 277 insertions(+) create mode 100644 account_mooncard_receipt_lost_transfer/README.md create mode 100644 account_mooncard_receipt_lost_transfer/__init__.py create mode 100644 account_mooncard_receipt_lost_transfer/__manifest__.py create mode 100644 account_mooncard_receipt_lost_transfer/models/__init__.py create mode 100644 account_mooncard_receipt_lost_transfer/models/account_move.py create mode 100644 account_mooncard_receipt_lost_transfer/models/newgen_payment_card_transaction.py create mode 100644 account_mooncard_receipt_lost_transfer/tests/__init__.py create mode 100644 account_mooncard_receipt_lost_transfer/tests/test_receipt_lost_transfer.py create mode 100644 account_mooncard_receipt_lost_transfer/views/account_move_views.xml diff --git a/account_mooncard_receipt_lost_transfer/README.md b/account_mooncard_receipt_lost_transfer/README.md new file mode 100644 index 0000000..ef57371 --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/README.md @@ -0,0 +1,32 @@ +# account_mooncard_receipt_lost_transfer + +Propagates the **Receipt Lost** value of Mooncard payment transactions (`newgen.payment.card.transaction`) onto the related invoices and account move lines. + +Adds `receipt_lost` and `mooncard_record` boolean fields on `account.move` and `account.move.line`, and exposes them in the invoice and move line forms (only visible on records originating from a Mooncard transaction). + +## Installation + +Make sure the addons of the [Odoo Mooncard Connector](https://github.com/akretion/odoo-mooncard-connector) repository (in particular `base_newgen_payment_card`) are available in your Odoo, then use the standard Odoo module installation procedure to install `account_mooncard_receipt_lost_transfer`. + +## Known issues / Roadmap + +None yet. + +## Bug Tracker + +Bugs are tracked on [our issues website](https://git.elabore.coop/Elabore/account-tools/issues). In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback. + +## Credits + +### Contributors + +* Stéphan Sainléger - [Github](https://github.com/stephansainleger) + +### Funders + +The development of this module has been financially supported by: +* [Elabore](https://elabore.coop) + +### Maintainer + +This module is maintained by Elabore. diff --git a/account_mooncard_receipt_lost_transfer/__init__.py b/account_mooncard_receipt_lost_transfer/__init__.py new file mode 100644 index 0000000..a9e3372 --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/__init__.py @@ -0,0 +1,2 @@ + +from . import models diff --git a/account_mooncard_receipt_lost_transfer/__manifest__.py b/account_mooncard_receipt_lost_transfer/__manifest__.py new file mode 100644 index 0000000..872c667 --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/__manifest__.py @@ -0,0 +1,21 @@ +{ + "name": "Account Mooncard Receipt Lost Transfer", + "category": "Account", + "version": "18.0.1.0.0", + "license": "AGPL-3", + "summary": "Transfer the Receipt Lost value in invoices and account move lines", + "author": "Elabore", + "website": "https://elabore.coop/", + "installable": True, + "application": False, + "auto_install": False, + "depends": [ + "base", + "account", + "base_newgen_payment_card", + ], + "data": [ + "views/account_move_views.xml", + ], + "qweb": [], +} diff --git a/account_mooncard_receipt_lost_transfer/models/__init__.py b/account_mooncard_receipt_lost_transfer/models/__init__.py new file mode 100644 index 0000000..b601f7a --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/models/__init__.py @@ -0,0 +1,3 @@ + +from . import account_move +from . import newgen_payment_card_transaction diff --git a/account_mooncard_receipt_lost_transfer/models/account_move.py b/account_mooncard_receipt_lost_transfer/models/account_move.py new file mode 100644 index 0000000..5b46503 --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/models/account_move.py @@ -0,0 +1,15 @@ +from odoo import fields, models, _ + + +class AccountMove(models.Model): + _inherit = "account.move" + + receipt_lost = fields.Boolean(string=_("Receipt lost"), store=True) + mooncard_record = fields.Boolean(store=True) + + +class AccountMoveLine(models.Model): + _inherit = "account.move.line" + + receipt_lost = fields.Boolean(string=_("Receipt lost"), store=True) + mooncard_record = fields.Boolean(store=True) diff --git a/account_mooncard_receipt_lost_transfer/models/newgen_payment_card_transaction.py b/account_mooncard_receipt_lost_transfer/models/newgen_payment_card_transaction.py new file mode 100644 index 0000000..993093a --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/models/newgen_payment_card_transaction.py @@ -0,0 +1,31 @@ +from odoo import models + + +class NewgenPaymentCardTransaction(models.Model): + _inherit = "newgen.payment.card.transaction" + + def process_line(self): + res = super(NewgenPaymentCardTransaction, self).process_line() + if res: + for line in self: + if line.invoice_id: + line.invoice_id.receipt_lost = line.receipt_lost + line.invoice_id.mooncard_record = True + move_lines = line.invoice_id.line_ids + for move_line in move_lines: + move_line.receipt_lost = line.receipt_lost + move_line.mooncard_record = True + + return res + + def generate_bank_journal_move(self): + bank_move = super( + NewgenPaymentCardTransaction, self + ).generate_bank_journal_move() + if bank_move: + bank_move.receipt_lost = self.receipt_lost + bank_move.mooncard_record = True + for line in bank_move.line_ids: + line.receipt_lost = self.receipt_lost + line.mooncard_record = True + return bank_move diff --git a/account_mooncard_receipt_lost_transfer/tests/__init__.py b/account_mooncard_receipt_lost_transfer/tests/__init__.py new file mode 100644 index 0000000..a815560 --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/tests/__init__.py @@ -0,0 +1 @@ +from . import test_receipt_lost_transfer \ No newline at end of file diff --git a/account_mooncard_receipt_lost_transfer/tests/test_receipt_lost_transfer.py b/account_mooncard_receipt_lost_transfer/tests/test_receipt_lost_transfer.py new file mode 100644 index 0000000..44c821f --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/tests/test_receipt_lost_transfer.py @@ -0,0 +1,144 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo import fields +from odoo.tests.common import TransactionCase +import random + + +class TestReceiptLostTransfer(TransactionCase): + + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True)) + cls.company = cls.env.ref('base.main_company') + cls.euro = cls.env.ref('base.EUR') + cls.country = cls.env.ref('base.fr') + cls.company.write({ + 'currency_id': cls.euro.id, + 'country_id': cls.country.id, + }) + cls.card_bank_account = cls.env['account.account'].create({ + 'code': '512199', + 'name': 'Card prepaid account', + 'account_type': 'asset_cash', + }) + cls.expense_account = cls.env['account.account'].create({ + 'code': '6TESTXXX', + 'name': 'Test Expense Account', + 'account_type': 'expense', + }) + cls.card_bank_journal = cls.env['account.journal'].create({ + 'type': 'bank', + 'name': 'Card Test', + 'code': 'CARD', + 'default_account_id': cls.card_bank_account.id, + }) + cls.card = cls.env['newgen.payment.card'].create({ + 'name': 'TESTCARD987', + 'code': 'TST', + 'company_id': cls.company.id, + 'journal_id': cls.card_bank_journal.id, + }) + + def _create_transaction(self, values): + defaults = { + 'company_id': self.company.id, + 'card_id': self.card.id, + 'date': fields.Datetime.now(), + 'currency_id': self.euro.id, + 'country_id': self.country.id, + 'unique_import_id': 'TEST%s' % random.randrange(100000000), + 'transaction_type': 'expense', + 'expense_account_id': self.expense_account.id, + 'description': 'Test transaction', + 'vendor': 'Test vendor', + 'vat_company_currency': 0, + 'vat_rate': 0, + 'total_company_currency': -100, + 'receipt_lost': True, + } + defaults.update(values) + return self.env['newgen.payment.card.transaction'].create(defaults) + + def _assert_receipt_lost(self, move, expected_receipt_lost): + self.assertEqual( + move.receipt_lost, expected_receipt_lost, + "%s: wrong receipt_lost" % move._name) + self.assertTrue( + move.mooncard_record, + "%s: mooncard_record should be True" % move._name) + for line in move.line_ids: + self.assertEqual( + line.receipt_lost, expected_receipt_lost, + "move line %s: wrong receipt_lost" % line.display_name) + self.assertTrue( + line.mooncard_record, + "move line %s: mooncard_record should be True" % line.display_name) + + def test_expense_receipt_lost_true(self): + trans = self._create_transaction({ + 'receipt_lost': True, + }) + trans.process_line() + self.assertEqual(trans.state, 'done') + invoice = trans.invoice_id + self.assertTrue(invoice, "Invoice should be generated") + self._assert_receipt_lost(invoice, True) + self._assert_receipt_lost(trans.bank_move_id, True) + + def test_expense_receipt_lost_false(self): + trans = self._create_transaction({ + 'receipt_lost': False, + }) + self.env['ir.attachment'].create({ + 'name': 'test_receipt.pdf', + 'res_model': 'newgen.payment.card.transaction', + 'res_id': trans.id, + 'raw': b'test attachment content', + }) + trans.process_line() + self.assertEqual(trans.state, 'done') + invoice = trans.invoice_id + self.assertTrue(invoice, "Invoice should be generated") + self._assert_receipt_lost(invoice, False) + self._assert_receipt_lost(trans.bank_move_id, False) + + def test_bank_move_only_receipt_lost_true(self): + trans = self._create_transaction({ + 'receipt_lost': True, + 'bank_move_only': True, + }) + trans.process_line() + self.assertEqual(trans.state, 'done') + self.assertFalse(trans.invoice_id, "No invoice when bank_move_only") + bank_move = trans.bank_move_id + self.assertTrue(bank_move, "Bank move should be generated") + self._assert_receipt_lost(bank_move, True) + + def test_bank_move_only_receipt_lost_false(self): + trans = self._create_transaction({ + 'receipt_lost': False, + 'bank_move_only': True, + }) + trans.process_line() + self.assertEqual(trans.state, 'done') + self.assertFalse(trans.invoice_id, "No invoice when bank_move_only") + bank_move = trans.bank_move_id + self.assertTrue(bank_move, "Bank move should be generated") + self._assert_receipt_lost(bank_move, False) + + def test_load_receipt_lost_true(self): + self.company.transfer_account_id = self.card_bank_account.id + trans = self._create_transaction({ + 'transaction_type': 'load', + 'receipt_lost': True, + 'total_company_currency': 1000, + 'expense_account_id': False, + }) + trans.process_line() + self.assertEqual(trans.state, 'done') + self.assertFalse(trans.invoice_id, "Load should not generate an invoice") + bank_move = trans.bank_move_id + self.assertTrue(bank_move, "Bank move should be generated") + self._assert_receipt_lost(bank_move, True) diff --git a/account_mooncard_receipt_lost_transfer/views/account_move_views.xml b/account_mooncard_receipt_lost_transfer/views/account_move_views.xml new file mode 100644 index 0000000..e50ffb5 --- /dev/null +++ b/account_mooncard_receipt_lost_transfer/views/account_move_views.xml @@ -0,0 +1,28 @@ + + + + view.move.form.receipt.lost + account.move + + +
+ + +
+
+
+ + + view.move.line.form.recipt.lost + account.move.line + + + + + + + + + + +
\ No newline at end of file