From f869c551ca2a38f52d74b1cfe61cb215c522f722 Mon Sep 17 00:00:00 2001 From: eLBati Date: Fri, 17 Jan 2025 15:12:03 +0100 Subject: [PATCH] [MIG] l10n_it_account: Migration to 18.0 --- l10n_it_account/README.rst | 30 +- l10n_it_account/__init__.py | 12 - l10n_it_account/__manifest__.py | 9 +- .../16.0.1.0.0/post-migrate_balance_sign.py | 24 - .../migrations/18.0.1.0.0/post-migration.py | 178 ++ l10n_it_account/models/__init__.py | 3 - l10n_it_account/models/account_account.py | 94 -- l10n_it_account/models/account_group.py | 88 - l10n_it_account/models/res_lang.py | 35 - .../reports/account_reports_view.xml | 15 +- l10n_it_account/static/description/index.html | 6 +- l10n_it_account/tests/test_l10n_it_account.py | 54 +- l10n_it_account/tools/__init__.py | 1 - l10n_it_account/tools/account_tools.py | 116 -- l10n_it_account/tools/xsd/Schema_VFSM10.xsd | 553 ------- .../Schema_del_file_xml_FatturaPA_v1.2.2.xsd | 1454 ----------------- .../tools/xsd/xmldsig-core-schema.xsd | 318 ---- l10n_it_account/views/account_view.xml | 39 - l10n_it_account/views/product_view.xml | 16 - .../views/res_config_settings_views.xml | 4 +- l10n_it_account/wizards/__init__.py | 3 - .../wizards/base_language_install.py | 18 - requirements.txt | 2 +- 23 files changed, 211 insertions(+), 2861 deletions(-) delete mode 100644 l10n_it_account/migrations/16.0.1.0.0/post-migrate_balance_sign.py create mode 100644 l10n_it_account/migrations/18.0.1.0.0/post-migration.py delete mode 100644 l10n_it_account/models/account_account.py delete mode 100644 l10n_it_account/models/account_group.py delete mode 100644 l10n_it_account/models/res_lang.py delete mode 100644 l10n_it_account/tools/__init__.py delete mode 100644 l10n_it_account/tools/account_tools.py delete mode 100644 l10n_it_account/tools/xsd/Schema_VFSM10.xsd delete mode 100644 l10n_it_account/tools/xsd/Schema_del_file_xml_FatturaPA_v1.2.2.xsd delete mode 100644 l10n_it_account/tools/xsd/xmldsig-core-schema.xsd delete mode 100644 l10n_it_account/views/account_view.xml delete mode 100644 l10n_it_account/views/product_view.xml delete mode 100644 l10n_it_account/wizards/__init__.py delete mode 100644 l10n_it_account/wizards/base_language_install.py diff --git a/l10n_it_account/README.rst b/l10n_it_account/README.rst index b21148cc8db..fa13c020c62 100644 --- a/l10n_it_account/README.rst +++ b/l10n_it_account/README.rst @@ -17,13 +17,13 @@ ITA - Contabilità base :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fl10n--italy-lightgray.png?logo=github - :target: https://github.com/OCA/l10n-italy/tree/16.0/l10n_it_account + :target: https://github.com/OCA/l10n-italy/tree/18.0/l10n_it_account :alt: OCA/l10n-italy .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/l10n-italy-16-0/l10n-italy-16-0-l10n_it_account + :target: https://translation.odoo-community.org/projects/l10n-italy-18-0/l10n-italy-18-0-l10n_it_account :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-italy&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/l10n-italy&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -57,7 +57,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -73,23 +73,23 @@ Authors Contributors ------------ -- Davide Corio -- Lorenzo Battistini -- Alex Comba -- Sergio Zanchetta -- Gianmarco Conte - Dinamiche Aziendali Sr - -- Marco Colombo - Phi S.r.l. -- `TAKOBI `__: +- Davide Corio +- Lorenzo Battistini +- Alex Comba +- Sergio Zanchetta +- Gianmarco Conte - Dinamiche Aziendali Sr + +- Marco Colombo - Phi S.r.l. +- `TAKOBI `__: - - Simone Rubino + - Simone Rubino Other credits ------------- The development of this module has been financially supported by: -- Odoo Italia Network +- Odoo Italia Network Maintainers ----------- @@ -104,6 +104,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/l10n-italy `_ project on GitHub. +This module is part of the `OCA/l10n-italy `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/l10n_it_account/__init__.py b/l10n_it_account/__init__.py index 0a0612ae8e4..69f7babdfb1 100644 --- a/l10n_it_account/__init__.py +++ b/l10n_it_account/__init__.py @@ -1,15 +1,3 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import models -from . import wizards -from . import tools -from odoo import api, SUPERUSER_ID - - -def _l10n_it_account_post_init(cr, registry): - env = api.Environment(cr, SUPERUSER_ID, {}) - env["account.account"].set_account_types_negative_sign() - - lang = env["res.lang"] - if lang._lang_get("it_IT"): - lang.update_menu_finance_it_translation() diff --git a/l10n_it_account/__manifest__.py b/l10n_it_account/__manifest__.py index f292e49f23e..b04fbcc5671 100644 --- a/l10n_it_account/__manifest__.py +++ b/l10n_it_account/__manifest__.py @@ -10,7 +10,7 @@ { "name": "ITA - Contabilità base", "summary": "Modulo base usato come dipendenza di altri moduli contabili", - "version": "16.0.1.1.3", + "version": "18.0.1.0.0", "development_status": "Production/Stable", "category": "Hidden", "author": "Agile Business Group, Abstract, Odoo Community Association (OCA)", @@ -25,21 +25,18 @@ "data": [ "views/account_menuitem.xml", "views/partner_view.xml", - "views/product_view.xml", "views/res_config_settings_views.xml", "reports/account_reports_view.xml", - "views/account_view.xml", ], "assets": { "web.report_assets_common": [ "l10n_it_account/static/src/css/*.css", ] }, + "installable": True, "external_dependencies": { "python": [ - "xmlschema", + "openupgradelib", ], }, - "installable": True, - "post_init_hook": "_l10n_it_account_post_init", } diff --git a/l10n_it_account/migrations/16.0.1.0.0/post-migrate_balance_sign.py b/l10n_it_account/migrations/16.0.1.0.0/post-migrate_balance_sign.py deleted file mode 100644 index 280e54502c9..00000000000 --- a/l10n_it_account/migrations/16.0.1.0.0/post-migrate_balance_sign.py +++ /dev/null @@ -1,24 +0,0 @@ -# Copyright 2022 Simone Rubino - TAKOBI -# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). - -from openupgradelib import openupgrade - - -@openupgrade.migrate() -def migrate(env, installed_version): - # Assign the sign of the account type to the account - if openupgrade.table_exists(env.cr, "account_account_type"): - openupgrade.logged_query( - env.cr, - """ - UPDATE account_account - SET - account_balance_sign = aat.account_balance_sign - FROM - account_account_type aat - WHERE - aat.id = account_account.user_type_id - """, - ) - else: - env["account.account"].set_account_types_negative_sign() diff --git a/l10n_it_account/migrations/18.0.1.0.0/post-migration.py b/l10n_it_account/migrations/18.0.1.0.0/post-migration.py new file mode 100644 index 00000000000..d55c1efc145 --- /dev/null +++ b/l10n_it_account/migrations/18.0.1.0.0/post-migration.py @@ -0,0 +1,178 @@ +from openupgradelib import openupgrade +from psycopg2 import sql + +from odoo import SUPERUSER_ID, api + +OLD_MODULES = [ + "l10n_it_account_tax_kind", + "l10n_it_fatturapa", + "l10n_it_fiscalcode", + "l10n_it_ipa", + "l10n_it_rea", +] + + +def rename_fields(env, table, field_updates, condition=None): + """Generic function to rename fields.""" + set_clauses = sql.SQL(", ").join( + sql.SQL("{} = {}").format(sql.Identifier(target), sql.Identifier(source)) + for target, source in field_updates.items() + ) + query = sql.SQL(""" + UPDATE {table} + SET {set_clauses} + """).format(table=sql.Identifier(table), set_clauses=set_clauses) + if condition: + query += sql.SQL(" WHERE {} ").format(sql.SQL(condition)) + openupgrade.logged_query(env.cr, query) + + +def update_table(env, target_table, source_table, field_updates, condition): + """Generic function to update fields in a table based on a join.""" + set_clauses = sql.SQL(", ").join( + sql.SQL("{} = {}.{}").format( + sql.Identifier(target), sql.Identifier(source_table), sql.Identifier(source) + ) + for target, source in field_updates.items() + ) + query = sql.SQL(""" + UPDATE {target_table} + SET {set_clauses} + FROM {source_table} + """).format( + target_table=sql.Identifier(target_table), + set_clauses=set_clauses, + source_table=sql.Identifier(source_table), + ) + if condition: + query += sql.SQL(" WHERE {} ").format(sql.SQL(condition)) + openupgrade.logged_query(env.cr, query) + + +def add_field_if_not_exists(env, table, field_name, field_type, module): + """Helper function to add fields if they do not exist.""" + if not openupgrade.column_exists(env.cr, table, field_name): + sql_type_mapping = { + "binary": "bytea", + "boolean": "bool", + "char": "varchar", + "date": "date", + "datetime": "timestamp", + "float": "numeric", + "html": "text", + "integer": "int4", + "many2many": False, + "many2one": "int4", + "many2one_reference": "int4", + "monetary": "numeric", + "one2many": False, + "reference": "varchar", + "selection": "varchar", + "text": "text", + "serialized": "text", + } + openupgrade.add_fields( + env, + [ + ( + field_name, + table.replace("_", "."), + table, + field_type, + sql_type_mapping[field_type], + module, + ) + ], + ) + + +def _l10n_it_account_tax_kind_migration(env): + table = "account_tax" + add_field_if_not_exists(env, table, "l10n_it_law_reference", "char", "l10n_it") + rename_fields(env, table, {"l10n_it_law_reference": "law_reference"}) + + add_field_if_not_exists(env, table, "l10n_it_exempt_reason", "char", "l10n_it") + condition = "account_tax.kind_id = account_tax_kind.id" + condition += " AND account_tax.kind_id IS NOT NULL" + update_table( + env, table, "account_tax_kind", {"l10n_it_exempt_reason": "code"}, condition + ) + + +def _l10n_it_fatturapa_migration(env): + table = "res_partner" + add_field_if_not_exists(env, table, "l10n_it_pa_index", "char", "l10n_it_edi") + add_field_if_not_exists(env, table, "l10n_it_pec_email", "char", "l10n_it_edi") + rename_fields( + env, + table, + { + "l10n_it_pa_index": "codice_destinatario", + "l10n_it_pec_email": "pec_destinatario", + }, + ) + + table = "res_company" + add_field_if_not_exists( + env, table, "l10n_it_tax_representative_partner_id", "many2one", "l10n_it_edi" + ) + rename_fields( + env, + table, + {"l10n_it_tax_representative_partner_id": "fatturapa_tax_representative"}, + ) + + +def _l10n_it_fiscalcode_migration(env): + table = "res_partner" + add_field_if_not_exists(env, table, "l10n_it_codice_fiscale", "char", "l10n_it_edi") + rename_fields(env, table, {"l10n_it_codice_fiscale": "fiscalcode"}) + + +def _l10n_it_ipa_migration(env): + table = "res_partner" + add_field_if_not_exists(env, table, "l10n_it_pa_index", "char", "l10n_it_edi") + condition = "ipa_code IS NOT NULL" + rename_fields(env, table, {"l10n_it_pa_index": "ipa_code"}, condition=condition) + + +def _l10n_it_rea_migration(env): + table = "res_company" + add_field_if_not_exists( + env, table, "l10n_it_eco_index_office", "many2one", "l10n_it_edi" + ) + add_field_if_not_exists( + env, table, "l10n_it_eco_index_number", "char", "l10n_it_edi" + ) + add_field_if_not_exists( + env, table, "l10n_it_eco_index_share_capital", "float", "l10n_it_edi" + ) + add_field_if_not_exists( + env, table, "l10n_it_eco_index_sole_shareholder", "selection", "l10n_it_edi" + ) + add_field_if_not_exists( + env, table, "l10n_it_eco_index_liquidation_state", "selection", "l10n_it_edi" + ) + condition = "res_company.partner_id = res_partner.id" + condition += " AND res_partner.rea_office IS NOT NULL" + update_table( + env, + table, + "res_partner", + { + "l10n_it_eco_index_office": "rea_office", + "l10n_it_eco_index_number": "rea_code", + "l10n_it_eco_index_share_capital": "rea_capital", + "l10n_it_eco_index_sole_shareholder": "rea_member_type", + "l10n_it_eco_index_liquidation_state": "rea_liquidation_state", + }, + condition, + ) + + +def migrate(cr, version): + env = api.Environment(cr, SUPERUSER_ID, {}) + for module in OLD_MODULES: + migration_function = globals().get(f"_{module}_migration") + if openupgrade.is_module_installed(env.cr, module) and migration_function: + migration_function(env) diff --git a/l10n_it_account/models/__init__.py b/l10n_it_account/models/__init__.py index 46df1f7f948..bf09a2c3496 100644 --- a/l10n_it_account/models/__init__.py +++ b/l10n_it_account/models/__init__.py @@ -1,6 +1,3 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from . import account_account -from . import account_group from . import account_tax -from . import res_lang diff --git a/l10n_it_account/models/account_account.py b/l10n_it_account/models/account_account.py deleted file mode 100644 index f299c91bcc8..00000000000 --- a/l10n_it_account/models/account_account.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright 2022 Simone Rubino - TAKOBI -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - -ACCOUNT_TYPES_NEGATIVE_SIGN = [ - "equity_unaffected", - "equity", - "income", - "income_other", - "liability_payable", - "liability_credit_card", - "asset_prepayments", - "liability_current", - "liability_non_current", -] - - -class Account(models.Model): - _inherit = "account.account" - - account_balance_sign = fields.Integer( - default=1, - string="Balance sign", - ) - - @api.model_create_multi - def create(self, vals_list): - for vals in vals_list: - if "account_balance_sign" not in vals and "account_type" in vals: - if vals["account_type"] in ACCOUNT_TYPES_NEGATIVE_SIGN: - vals["account_balance_sign"] = -1 - return super().create(vals_list) - - @api.model - def set_account_types_negative_sign(self): - for account_type in ACCOUNT_TYPES_NEGATIVE_SIGN: - account_ids = self.env["account.account"].search( - [("account_type", "=", account_type)] - ) - for account_id in account_ids: - account_id.with_context( - skip_check_balance_sign_coherence=True - ).account_balance_sign = -1 - - def check_balance_sign_value(self): - """ - Checks whether `account_balance_sign` gets a correct value of +1 or -1. - """ - if any(t.account_balance_sign not in (-1, 1) for t in self): - raise ValidationError(_("Balance sign's value can only be 1 or -1.")) - - @api.constrains("account_balance_sign") - def check_balance_sign_coherence(self): - """ - Checks whether changes upon `account_balance_sign` create incoherencies - in account groups' balance signs. - """ - self.check_balance_sign_value() - - acc_obj = self.env["account.account"] - key_val_dict = dict(self._fields["account_type"].selection) - for key in key_val_dict: - accounts = acc_obj.search( - [("account_type", "=", key)], - ) - # Avoid check upon empty recordset to make it faster - if accounts: - accounts.check_balance_sign_coherence_group() - - @api.constrains("group_id") - def check_balance_sign_coherence_group(self): - """ - Checks whether adding an account to (or removing it from) a group - creates incoherencies in account groups' balance signs. - """ - groups = self.mapped("group_id") - # Avoid check upon empty recordset to make it faster - if groups: - groups.check_balance_sign_coherence() - - def have_same_sign(self): - """ - Checks account' signs. - :return: True if there's nothing to check or there's only one account - to check; else, returns True or False according to whether every - account has the same value for `account_balance_sign` (if it's not 0). - """ - to_check = self.filtered(lambda a: a.account_balance_sign) - if len(to_check) <= 1: - return True - benchmark = to_check[0].account_balance_sign - return all(a.account_balance_sign == benchmark for a in to_check) diff --git a/l10n_it_account/models/account_group.py b/l10n_it_account/models/account_group.py deleted file mode 100644 index 27d671b4503..00000000000 --- a/l10n_it_account/models/account_group.py +++ /dev/null @@ -1,88 +0,0 @@ -# Copyright 2022 Simone Rubino - TAKOBI -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import _, api, fields, models -from odoo.exceptions import ValidationError - - -class AccountGroup(models.Model): - _inherit = "account.group" - - account_ids = fields.One2many( - comodel_name="account.account", - inverse_name="group_id", - string="Accounts", - ) - account_balance_sign = fields.Integer( - compute="_compute_account_balance_sign", - string="Balance sign", - ) - - @api.constrains("account_ids", "parent_id") - def check_balance_sign_coherence(self): - """ - Checks whether every group (plus parents and subgroups) have the same - balance sign. This is done by first retrieving every group's progenitor - and then checking, for each of them, the account types' for accounts - linked to such progenitor group and its subgroups. - """ - if self.env.context.get("skip_check_balance_sign_coherence"): - return - done_group_ids, progenitor_ids = [], [] - for group in self: - if group.id in done_group_ids: - continue - progenitor = group.get_group_progenitor() - progenitor_ids.extend(progenitor.ids) - done_group_ids.extend(progenitor.get_group_subgroups().ids) - - progenitors = self.browse(tuple(set(progenitor_ids))) - for progenitor in progenitors: - accounts = progenitor.get_group_accounts() - if not accounts.have_same_sign(): - raise ValidationError( - _("Incoherent balance signs for '{}' and its subgroups.").format( - progenitor.name_get()[0][-1] - ) - ) - - def _compute_account_balance_sign(self): - for group in self: - group.account_balance_sign = group.get_account_balance_sign() - - def get_account_balance_sign(self): - self.ensure_one() - progenitor = self.get_group_progenitor() - accounts = progenitor.get_group_accounts() - if accounts: - return accounts[0].account_balance_sign - return 1 - - def get_group_accounts(self): - """Retrieves every account from `self` and `self`'s subgroups.""" - return (self + self.get_group_subgroups()).mapped("account_ids") - - def get_group_progenitor(self): - self.ensure_one() - if not self.parent_id: - return self - return self.get_group_parents().filtered(lambda g: not g.parent_id) - - def get_group_parents(self): - """ - Retrieves every parent for group `self`. - :return: group's parents as recordset, or empty recordset if `self` - has no parents. If a recursion is found, an error is raised. - """ - self.ensure_one() - parent_ids = [] - parent = self.parent_id - while parent: - parent_ids.append(parent.id) - parent = parent.parent_id - return self.browse(parent_ids) - - def get_group_subgroups(self): - """Retrieves every subgroup for groups `self`.""" - subgroups_ids = self.search([("id", "child_of", self.ids)]) - return subgroups_ids diff --git a/l10n_it_account/models/res_lang.py b/l10n_it_account/models/res_lang.py deleted file mode 100644 index cce2e4a9f20..00000000000 --- a/l10n_it_account/models/res_lang.py +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright 2024 Sergio Zanchetta (PNLUG APS - Gruppo Odoo) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from odoo import models - - -class Lang(models.Model): - _inherit = "res.lang" - - def toggle_active(self): - res = super().toggle_active() - - if "it_IT" in [lang.code for lang in self.filtered(lambda L: L.active)]: - self.update_menu_finance_it_translation() - - return res - - def update_menu_finance_it_translation(self): - """In Odoo the inheritance mechanism is not yet implemented for menus. - Changing a menu item name doesn't create a new string to be translated - but overwrites the source string of the original module to which the menu - belongs to. This is a workaround that allows the translated string to be - modified in the same way. - """ - menu_finance_id = self.env["ir.model.data"]._xmlid_to_res_id( - "account.menu_finance" - ) - menu_finance = self.env["ir.ui.menu"].browse(menu_finance_id) - - field_name = menu_finance._fields["name"] - translations = field_name._get_stored_translations(menu_finance) - - translations["it_IT"] = "Contabilità" - self.env.cache.update_raw(menu_finance, field_name, [translations], dirty=True) - menu_finance.modified(["name"]) diff --git a/l10n_it_account/reports/account_reports_view.xml b/l10n_it_account/reports/account_reports_view.xml index 8c4d27b4deb..634878bc23a 100644 --- a/l10n_it_account/reports/account_reports_view.xml +++ b/l10n_it_account/reports/account_reports_view.xml @@ -59,14 +59,11 @@
- - -
- TIN:
+ + - + -
+ TIN: +

@@ -107,7 +104,7 @@