From 5c5e8d8bae9639900e07c451b9aa7404b5c17399 Mon Sep 17 00:00:00 2001 From: Morita Shinnosuke Date: Fri, 10 Jul 2026 03:15:49 +0000 Subject: [PATCH] [6980][IMP] l10n_jp_summary_invoice: prevent deletion of a printed billing --- l10n_jp_summary_invoice/README.rst | 49 ++++++----- l10n_jp_summary_invoice/__manifest__.py | 2 +- l10n_jp_summary_invoice/i18n/ja.po | 29 ++++++- .../i18n/l10n_jp_summary_invoice.pot | 29 ++++++- l10n_jp_summary_invoice/models/__init__.py | 1 + .../models/account_billing.py | 21 ++++- .../models/ir_actions_report.py | 18 ++++ l10n_jp_summary_invoice/readme/USAGE.md | 6 ++ .../static/description/index.html | 53 +++++++----- .../tests/test_l10n_jp_summary_invoice.py | 83 ++++++++++++++++++- .../views/account_billing_views.xml | 1 + 11 files changed, 242 insertions(+), 50 deletions(-) create mode 100644 l10n_jp_summary_invoice/models/ir_actions_report.py diff --git a/l10n_jp_summary_invoice/README.rst b/l10n_jp_summary_invoice/README.rst index 230aae73..76a4cd6a 100644 --- a/l10n_jp_summary_invoice/README.rst +++ b/l10n_jp_summary_invoice/README.rst @@ -7,7 +7,7 @@ Japan Summary Invoice !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e6e9907d975dd745a0204630a2c47c0952c4dde7c5df8e7f06ee5fc94e1d361b + !! source digest: sha256:8831370ba65f37ea216dfbf0ad4b43591fd0b06f0ed37d4ec9a1285386f81314 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png @@ -52,19 +52,19 @@ Configuration Go to *Invoicing/Accounting > Configuration > Settings* and update the following settings as necessary: -- **Summary Invoice Remark**: The remark that shows in the header part - of the summary invoice, such as '下記の通り御請求申し上げます。'. -- **Show Sales Order Number**: If selected, the sales order number will - be shown for each line in the summary invoice. -- **Show Invoice Narration**: If selected, the narration will appear - for each invoice in the summary invoice report. -- **Show Invoice Total Amount**: If selected, the total amount per - invoice will appear in the summary invoice report. +- **Summary Invoice Remark**: The remark that shows in the header part + of the summary invoice, such as '下記の通り御請求申し上げます。'. +- **Show Sales Order Number**: If selected, the sales order number will + be shown for each line in the summary invoice. +- **Show Invoice Narration**: If selected, the narration will appear for + each invoice in the summary invoice report. +- **Show Invoice Total Amount**: If selected, the total amount per + invoice will appear in the summary invoice report. To exclude billing for invoices created for a particular partner: -- Go to Contacts and select the partner. -- In the Invoicing (or Accounting) tab, enable 'Is Not For Billing'. +- Go to Contacts and select the partner. +- In the Invoicing (or Accounting) tab, enable 'Is Not For Billing'. Usage ===== @@ -72,18 +72,27 @@ Usage 1. Create a billing for customer invoices using the functionality of the account_billing module, and make adjustments as necessary. - - **Remit-to Bank**: If not selected, the bank account related to - the company with the smallest sequence will show in the printed - document. - - **Due Date**: The earliest due date among the selected invoices - will be proposed. Adjust this as necessary as it will show in the - printed document. + - **Remit-to Bank**: If not selected, the bank account related to the + company with the smallest sequence will show in the printed + document. + - **Due Date**: The earliest due date among the selected invoices + will be proposed. Adjust this as necessary as it will show in the + printed document. + - **Exclude invoices from billing**: On each invoice form, you can + check the "Is not for billing" field in the Billing tab to exclude + specific invoices from the billing process. 2. Validate the billing. An invoice for tax adjustment will be created automatically in case the recalculated tax amount is different from the summary of the tax amounts in the selected invoices. 3. Print the summary invoice report (合計請求書) from *Print > JP Summary Invoice* of the billing. +4. Once a validated summary invoice has been printed or sent at least + once, the **Printed/Sent** field is checked automatically, and trying + to delete the billing raises an error, so that its sequence number is + never orphaned from accounting reports. Cancel it instead if it is no + longer valid. If you still need to delete it, uncheck the + **Printed/Sent** field manually first. Bug Tracker =========== @@ -106,10 +115,10 @@ Authors Contributors ------------ -- `Quartile `__: +- `Quartile `__: - - Aung Ko Ko Lin - - Yoshi Tashiro + - Aung Ko Ko Lin + - Yoshi Tashiro Maintainers ----------- diff --git a/l10n_jp_summary_invoice/__manifest__.py b/l10n_jp_summary_invoice/__manifest__.py index 980247e2..942c597b 100644 --- a/l10n_jp_summary_invoice/__manifest__.py +++ b/l10n_jp_summary_invoice/__manifest__.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). { "name": "Japan Summary Invoice", - "version": "18.0.1.1.1", + "version": "18.0.1.2.0", "category": "Japanese Localization", "author": "Quartile, Odoo Community Association (OCA)", "website": "https://github.com/OCA/l10n-japan", diff --git a/l10n_jp_summary_invoice/i18n/ja.po b/l10n_jp_summary_invoice/i18n/ja.po index ae371dfa..5e05d069 100644 --- a/l10n_jp_summary_invoice/i18n/ja.po +++ b/l10n_jp_summary_invoice/i18n/ja.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 18.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-09 10:03+0000\n" -"PO-Revision-Date: 2026-04-09 10:03+0000\n" +"POT-Creation-Date: 2026-07-10 03:01+0000\n" +"PO-Revision-Date: 2026-07-10 03:01+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -211,6 +211,13 @@ msgstr "選択した場合、請求書は合計請求書への追加対象外と msgid "Is Not For Billing" msgstr "合計請求書対象外" +#. module: l10n_jp_summary_invoice +#: model:ir.model.fields,help:l10n_jp_summary_invoice.field_account_billing__is_billing_sent +msgid "" +"It indicates that the summary invoice has been sent or its PDF has been " +"generated." +msgstr "合計請求書が送信されたか、そのPDFが生成されたことを示します。" + #. module: l10n_jp_summary_invoice #: model:ir.actions.report,name:l10n_jp_summary_invoice.report_jp_summary_invoice msgid "JP Summary Invoice" @@ -242,6 +249,11 @@ msgstr "振込先が同じ請求書を選択してください。" msgid "Print Summary Invoice" msgstr "合計請求書を印刷" +#. module: l10n_jp_summary_invoice +#: model:ir.model.fields,field_description:l10n_jp_summary_invoice.field_account_billing__is_billing_sent +msgid "Printed/Sent" +msgstr "印刷/送信済" + #. module: l10n_jp_summary_invoice #: model_terms:ir.ui.view,arch_db:l10n_jp_summary_invoice.bill_line_section_layout msgid "Quantity" @@ -257,6 +269,11 @@ msgstr "参照" msgid "Remit-to Bank" msgstr "振込先銀行" +#. module: l10n_jp_summary_invoice +#: model:ir.model,name:l10n_jp_summary_invoice.model_ir_actions_report +msgid "Report Action" +msgstr "レポートアクション" + #. module: l10n_jp_summary_invoice #: model:ir.model.fields,field_description:l10n_jp_summary_invoice.field_account_billing__report_subtitle msgid "Report Subtitle" @@ -423,3 +440,11 @@ msgstr "単価" #: model:ir.model.fields,field_description:l10n_jp_summary_invoice.field_account_billing__amount_untaxed msgid "Untaxed Amount" msgstr "税抜金額" + +#. module: l10n_jp_summary_invoice +#. odoo-python +#: code:addons/l10n_jp_summary_invoice/models/account_billing.py:0 +msgid "" +"You cannot delete the following summary invoice(s) because they have already" +" been printed or sent: %s" +msgstr "以下の合計請求書は既に印刷または送信されているため、削除できません: %s" diff --git a/l10n_jp_summary_invoice/i18n/l10n_jp_summary_invoice.pot b/l10n_jp_summary_invoice/i18n/l10n_jp_summary_invoice.pot index 9e7a389e..3fb9625c 100644 --- a/l10n_jp_summary_invoice/i18n/l10n_jp_summary_invoice.pot +++ b/l10n_jp_summary_invoice/i18n/l10n_jp_summary_invoice.pot @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 18.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2026-04-09 10:06+0000\n" -"PO-Revision-Date: 2026-04-09 10:06+0000\n" +"POT-Creation-Date: 2026-07-10 03:01+0000\n" +"PO-Revision-Date: 2026-07-10 03:01+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -210,6 +210,13 @@ msgstr "" msgid "Is Not For Billing" msgstr "" +#. module: l10n_jp_summary_invoice +#: model:ir.model.fields,help:l10n_jp_summary_invoice.field_account_billing__is_billing_sent +msgid "" +"It indicates that the summary invoice has been sent or its PDF has been " +"generated." +msgstr "" + #. module: l10n_jp_summary_invoice #: model:ir.actions.report,name:l10n_jp_summary_invoice.report_jp_summary_invoice msgid "JP Summary Invoice" @@ -241,6 +248,11 @@ msgstr "" msgid "Print Summary Invoice" msgstr "" +#. module: l10n_jp_summary_invoice +#: model:ir.model.fields,field_description:l10n_jp_summary_invoice.field_account_billing__is_billing_sent +msgid "Printed/Sent" +msgstr "" + #. module: l10n_jp_summary_invoice #: model_terms:ir.ui.view,arch_db:l10n_jp_summary_invoice.bill_line_section_layout msgid "Quantity" @@ -256,6 +268,11 @@ msgstr "" msgid "Remit-to Bank" msgstr "" +#. module: l10n_jp_summary_invoice +#: model:ir.model,name:l10n_jp_summary_invoice.model_ir_actions_report +msgid "Report Action" +msgstr "" + #. module: l10n_jp_summary_invoice #: model:ir.model.fields,field_description:l10n_jp_summary_invoice.field_account_billing__report_subtitle msgid "Report Subtitle" @@ -422,3 +439,11 @@ msgstr "" #: model:ir.model.fields,field_description:l10n_jp_summary_invoice.field_account_billing__amount_untaxed msgid "Untaxed Amount" msgstr "" + +#. module: l10n_jp_summary_invoice +#. odoo-python +#: code:addons/l10n_jp_summary_invoice/models/account_billing.py:0 +msgid "" +"You cannot delete the following summary invoice(s) because they have already" +" been printed or sent: %s" +msgstr "" diff --git a/l10n_jp_summary_invoice/models/__init__.py b/l10n_jp_summary_invoice/models/__init__.py index 267b4f8c..c1178a63 100644 --- a/l10n_jp_summary_invoice/models/__init__.py +++ b/l10n_jp_summary_invoice/models/__init__.py @@ -1,4 +1,5 @@ from . import account_billing +from . import ir_actions_report from . import account_move_line from . import account_move from . import account_tax_group diff --git a/l10n_jp_summary_invoice/models/account_billing.py b/l10n_jp_summary_invoice/models/account_billing.py index cd3dde7b..090ff54a 100644 --- a/l10n_jp_summary_invoice/models/account_billing.py +++ b/l10n_jp_summary_invoice/models/account_billing.py @@ -2,7 +2,7 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from odoo import Command, _, api, fields, models -from odoo.exceptions import ValidationError +from odoo.exceptions import UserError, ValidationError class AccountBilling(models.Model): @@ -52,6 +52,25 @@ class AccountBilling(models.Model): report_subtitle = fields.Char( help="Subtitle to be printed below the title of the summary invoice report.", ) + is_billing_sent = fields.Boolean( + string="Printed/Sent", + copy=False, + tracking=True, + help="It indicates that the summary invoice has been sent or its PDF " + "has been generated.", + ) + + @api.ondelete(at_uninstall=False) + def _unlink_except_billing_sent(self): + sent_billings = self.filtered("is_billing_sent") + if sent_billings: + raise UserError( + _( + "You cannot delete the following summary invoice(s) " + "because they have already been printed or sent: %s" + ) + % ", ".join(sent_billings.mapped("display_name")) + ) @api.constrains("state", "billing_line_ids") def _check_account_move_billability(self): diff --git a/l10n_jp_summary_invoice/models/ir_actions_report.py b/l10n_jp_summary_invoice/models/ir_actions_report.py new file mode 100644 index 00000000..daa0fc2a --- /dev/null +++ b/l10n_jp_summary_invoice/models/ir_actions_report.py @@ -0,0 +1,18 @@ +# Copyright 2026 Quartile (https://www.quartile.co) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class IrActionsReport(models.Model): + _inherit = "ir.actions.report" + + def _render_qweb_pdf(self, report_ref, res_ids=None, data=None): + result = super()._render_qweb_pdf(report_ref, res_ids, data) + report = self._get_report(report_ref) + if report.model == "account.billing" and res_ids: + if isinstance(res_ids, int): + res_ids = [res_ids] + billings = self.env["account.billing"].sudo().browse(res_ids) + billings.filtered("name").write({"is_billing_sent": True}) + return result diff --git a/l10n_jp_summary_invoice/readme/USAGE.md b/l10n_jp_summary_invoice/readme/USAGE.md index de4759b8..a101c735 100644 --- a/l10n_jp_summary_invoice/readme/USAGE.md +++ b/l10n_jp_summary_invoice/readme/USAGE.md @@ -14,3 +14,9 @@ the summary of the tax amounts in the selected invoices. 3. Print the summary invoice report (合計請求書) from *Print \> JP Summary Invoice* of the billing. +4. Once a validated summary invoice has been printed or sent at least + once, the **Printed/Sent** field is checked automatically, and + trying to delete the billing raises an error, so that its sequence + number is never orphaned from accounting reports. Cancel it instead + if it is no longer valid. If you still need to delete it, uncheck + the **Printed/Sent** field manually first. diff --git a/l10n_jp_summary_invoice/static/description/index.html b/l10n_jp_summary_invoice/static/description/index.html index 06dc97d5..7a6aa3df 100644 --- a/l10n_jp_summary_invoice/static/description/index.html +++ b/l10n_jp_summary_invoice/static/description/index.html @@ -1,19 +1,20 @@ + - + Japan Summary Invoice