diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1c6434bfc2274c73d98dbf62b6de9baccdc353ce..732d0c4a644eb444d6b4385643ff32fab19fab52 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,8 +6,6 @@ exclude: | ^setup/|/static/description/index\.html$| # We don't want to mess with tool-generated files .svg$|/tests/([^/]+/)?cassettes/|^.copier-answers.yml$|^.github/| - # Maybe reactivate this when all README files include prettier ignore tags? - ^README\.md$| # Library files can have extraneous formatting (even minimized) /static/(src/)?lib/| # Repos using Sphinx to generate docs don't need prettying @@ -28,7 +26,7 @@ repos: language: fail files: "\\.rej$" - repo: https://github.com/oca/maintainer-tools - rev: ab1d7f6 + rev: 7d8a9f9ad73db0976fb03cbee43d953bc29b89e9 hooks: # update the NOT INSTALLABLE ADDONS section above - id: oca-update-pre-commit-excluded-addons @@ -46,11 +44,11 @@ repos: - --remove-duplicate-keys - --remove-unused-variables - repo: https://github.com/psf/black - rev: 20.8b1 + rev: 22.3.0 hooks: - id: black - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.1.2 + rev: v2.6.2 hooks: - id: prettier name: prettier (with plugin-xml) @@ -61,7 +59,7 @@ repos: - --plugin=@prettier/plugin-xml files: \.(css|htm|html|js|json|jsx|less|md|scss|toml|ts|xml|yaml|yml)$ - repo: https://github.com/pre-commit/mirrors-eslint - rev: v7.8.1 + rev: v8.15.0 hooks: - id: eslint verbose: true @@ -69,7 +67,7 @@ repos: - --color - --fix - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v3.2.0 + rev: v4.2.0 hooks: - id: trailing-whitespace # exclude autogenerated files @@ -91,12 +89,12 @@ repos: - id: mixed-line-ending args: ["--fix=lf"] - repo: https://github.com/asottile/pyupgrade - rev: v2.7.2 + rev: v2.32.1 hooks: - id: pyupgrade args: ["--keep-percent-format"] - repo: https://github.com/PyCQA/isort - rev: 5.5.1 + rev: 5.10.1 hooks: - id: isort name: isort except __init__.py @@ -104,13 +102,13 @@ repos: - --settings=. exclude: /__init__\.py$ - repo: https://gitlab.com/PyCQA/flake8 - rev: 3.8.3 + rev: 3.9.2 hooks: - id: flake8 name: flake8 additional_dependencies: ["flake8-bugbear==20.1.4"] - repo: https://github.com/PyCQA/pylint - rev: pylint-2.5.3 + rev: v2.11.1 hooks: - id: pylint name: pylint with optional checks @@ -119,7 +117,7 @@ repos: - --exit-zero verbose: true additional_dependencies: &pylint_deps - - pylint-odoo==3.5.0 + - pylint-odoo==5.0.5 - id: pylint name: pylint with mandatory checks args: diff --git a/__init__.py b/__init__.py index d997a09cbd2254168ef48fc13bf9789e2d3242ac..e3bc617b1241f1778644d22df337206bd4c8f6fd 100644 --- a/__init__.py +++ b/__init__.py @@ -1,4 +1,4 @@ # © 2019 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from . import models +from . import models, wizard diff --git a/__manifest__.py b/__manifest__.py index 440fd18d5235062a6a3fdfa798fabe22c03d46b7..0d523e710d1d8650b439af5fbf05c02e5110c28c 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -9,10 +9,13 @@ "application": False, "depends": [ "cgscop_inovatic", - "cgscop_liste_ministere_alfodoo", + "cgscop_liasse_fiscale", + "cgscop_liste_ministere", ], "data": [ + "security/ir.model.access.csv", "datas/cron_inovatic.xml", + "wizard/load_xml_liasse.xml", "views/scop_liste_ministere.xml", ], "installable": True, diff --git a/models/inovatic_job_queue.py b/models/inovatic_job_queue.py index 01aaf793d373187dfea92d28fac845b47cca3f9f..44ae3c36c05e6c7e4f1c5d4d3085da664116693e 100644 --- a/models/inovatic_job_queue.py +++ b/models/inovatic_job_queue.py @@ -32,26 +32,38 @@ class InovaticJobQueue(models.Model): # Internal function # ------------------------------------------------------ def _get_cmis_file(self): - if not self.liasse_fiscale_id.liste_ministere_id: + if ( + not self.liasse_fiscale_id.node_ref + or not self.liasse_fiscale_id.liste_ministere_id + ): raise UserError( _( - "Rechargement impossible : il n'y a pas de " - "Liste Ministère associée à cette liasse" + "Rechargement impossible : il n'y a pas de fichier ou de " + "Liste Ministère associé à cette liasse" ) ) backend = self.env["cmis.backend"].search([]) backend.ensure_one() cmis_client = backend.get_cmis_client() - query = """ - SELECT * FROM crm:document as d - JOIN crm:organisme as o ON d.cmis:objectId = o.cmis:objectId - WHERE d.crm:type='LFI' - AND d.crm:annee = '%s' - AND d.crm:contexte = 'LM' - AND o.crm:id = '%s'""" % ( - str(self.liasse_fiscale_id.liste_ministere_id.year), - str(self.liasse_fiscale_id.partner_id.id), - ) + if self.liasse_fiscale_id.node_ref: + ref = self.liasse.node_ref.split(";") + query = """ + SELECT * FROM crm:document + WHERE cmis:objectId = '%s' + """ % ( + ref[0], + ) + else: + query = """ + SELECT * FROM crm:document as d + JOIN crm:organisme as o ON d.cmis:objectId = o.cmis:objectId + WHERE d.crm:type='LFI' + AND d.crm:annee = '%s' + AND d.crm:contexte = 'LM' + AND o.crm:id = '%s'""" % ( + str(self.liasse_fiscale_id.liste_ministere_id.year), + str(self.liasse_fiscale_id.partner_id.id), + ) doc = cmis_client.getDefaultRepository().query(query) if not doc: raise exceptions.UserError( diff --git a/models/scop_liste_ministere.py b/models/scop_liste_ministere.py index ea9622ef22ec873a226f1de664b52692901b6582..310b8a5a203705d2f435c0d9d717c8615e5b7967 100644 --- a/models/scop_liste_ministere.py +++ b/models/scop_liste_ministere.py @@ -1,8 +1,12 @@ # © 2020 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). +import logging + from odoo import _, exceptions, fields, models +_logger = logging.getLogger(__name__) + class ListeMinistereInovatic(models.Model): _inherit = "scop.liste.ministere" @@ -14,7 +18,7 @@ class ListeMinistereInovatic(models.Model): last_job_queue_date_sync = fields.Datetime(related="last_job_queue.date_sync") # ------------------------------------------------------ - # BUTTON functions + # Button functions # ------------------------------------------------------ def inovatic_treatment(self): liasse_id = self.create_liasse_fiscale() @@ -47,3 +51,24 @@ class ListeMinistereInovatic(models.Model): raise exceptions.UserError( _("Il n'y a pas de Liasse correspondante dans Alfresco") ) + + # ------------------------------------------------------ + # Inherit parent + # ------------------------------------------------------ + def action_completed(self): + """ + Hérite la fonction parente pour envoyer autmatiquement la liasse à Inovatic + si cette liasse existe et si elle n'a pas déjà été chargée lorsque la coop + valide le dossier + """ + if not self.scop_liasse_fiscale_id: + self.create_liasse_fiscale() + if ( + self.scop_liasse_fiscale_id + and not self.scop_liasse_fiscale_id.source == "inovatic_api" + ): + try: + self.scop_liasse_ficale_id.inovatic_treatment() + except Exception as e: + _logger.error(e) + super().action_completed() diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv new file mode 100644 index 0000000000000000000000000000000000000000..7392305e8485fe895e2349905505ba939473630b --- /dev/null +++ b/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_load_xml_liasse,access_load_xml_liasse,model_load_xml_liasse,base.group_user,1,1,1,1 diff --git a/views/scop_liste_ministere.xml b/views/scop_liste_ministere.xml index 1df79cf26a42c12146993da78c6962749bee7c84..2d7d515056e94a9cd92537cab820aacadcb9e253 100644 --- a/views/scop_liste_ministere.xml +++ b/views/scop_liste_ministere.xml @@ -23,7 +23,7 @@ /> <button string="Charger un XML" - name="%(cgscop_inovatic.load_xml_liasse_act_window)d" + name="%(cgscop_inovatic_lm.load_xml_liasse_act_window)d" type="action" class="m-3" attrs="{'invisible':[('status_liasse_fiscale', '=', 'valide')]}" diff --git a/wizard/__init__.py b/wizard/__init__.py new file mode 100644 index 0000000000000000000000000000000000000000..1587528ca966cca01d5370853f7a4d48c6ff6ce0 --- /dev/null +++ b/wizard/__init__.py @@ -0,0 +1,5 @@ +# © 2020 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from . import load_xml_liasse +from . import scop_load_liasse_wizard diff --git a/wizard/load_xml_liasse.py b/wizard/load_xml_liasse.py new file mode 100644 index 0000000000000000000000000000000000000000..d0ac295e53f4ad9961be272a448af0fe1856cc4f --- /dev/null +++ b/wizard/load_xml_liasse.py @@ -0,0 +1,44 @@ +# © 2020 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import api, fields, models + + +class LoadXmlLiasseWizard(models.TransientModel): + _name = "load.xml.liasse" + _description = "Load XML Liasse Wizard" + _rec_name = "liasse_id" + + @api.model + def _default_lm_id(self): + return self.env.context.get("active_id") + + @api.model + def _default_liasse_id(self): + lm = self.env.context.get("active_id") + return ( + self.env["scop.liasse.fiscale"].search([("liste_ministere_id", "=", lm)]).id + ) + + lm_id = fields.Many2one( + comodel_name="scop.liste.ministere", + string="Liste Ministere", + default=_default_lm_id, + ) + liasse_id = fields.Many2one( + comodel_name="scop.liasse.fiscale", + string="Liasse Fiscale", + default=_default_liasse_id, + ) + file = fields.Binary("Fichier") + filename = fields.Char("Nom") + + def load_liasse(self): + """ + Charge les valeurs du XML de la liasse dans l'objet + :return: + """ + if not self.liasse_id: + self.liasse_id = self.lm_id.create_liasse_fiscale() + data = self.liasse_id.parse_xml_liasse(self.file) + return self.liasse_id.json_matching(data, "xml") diff --git a/wizard/load_xml_liasse.xml b/wizard/load_xml_liasse.xml new file mode 100644 index 0000000000000000000000000000000000000000..dd1d92b7418751fcad26c26f3991fd9ec5204db6 --- /dev/null +++ b/wizard/load_xml_liasse.xml @@ -0,0 +1,45 @@ +<?xml version="1.0" encoding="utf-8" ?> +<odoo> + <data> + <!-- FORM View--> + <record id="load_xml_liasse_form_view" model="ir.ui.view"> + <field name="name">load.xml.liasse.form</field> + <field name="model">load.xml.liasse</field> + <field name="arch" type="xml"> + <form string="Charger une Liasse"> + <group name="infos"> + <field name="liasse_id" readonly="1" /> + </group> + <group> + <field name="filename" invisible="1" /> + <field name="file" filename="filename" required="1" /> + </group> + <footer> + <button + class="btn btn-sm btn-primary" + name="load_liasse" + string="Charger une liasse XML" + type="object" + confirm="Êtes-vous sûr(e) de vouloir charger ce fichier ?" + /> + <button + class="btn btn-sm btn-default" + special="cancel" + string="Fermer" + /> + </footer> + </form> + </field> + </record> + + <!--ACTION view--> + <record id="load_xml_liasse_act_window" model="ir.actions.act_window"> + <field name="name">Charger une Liasse XML</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">load.xml.liasse</field> + <field name="view_mode">form</field> + <field name="target">new</field> + </record> + + </data> +</odoo> diff --git a/wizard/scop_load_liasse_wizard.py b/wizard/scop_load_liasse_wizard.py new file mode 100644 index 0000000000000000000000000000000000000000..e9b5aae0073f7f653605110855bc2b8f68e20901 --- /dev/null +++ b/wizard/scop_load_liasse_wizard.py @@ -0,0 +1,47 @@ +# © 2021 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class ScopLoadLiasseWizard(models.TransientModel): + _inherit = "scop.load.liasse.wizard" + + # ------------------------------------------------------ + # Inherit parent + # ------------------------------------------------------ + def load_liasse(self): + super().load_liasse() + if not self.liasse_id.liste_ministere_id: + # LM d'inscription ou de renouvellement liées à la coop + lm_ids = self.liasse_id.partner_id.liste_ministere_ids.filtered( + lambda lm: lm.type_lm != "survey_adjust" + ) + if lm_ids: + lm_type = "renew" + else: + lm_type = "subscribe" + # LM sur l'année N+1 de la liasse + lm_id = lm_ids.filtered(lambda lm: lm.year == self.liasse_id.year + 1) + if not lm_id: + # Création de la LM si elle n'existe pas + new_lm = lm_id.create_folder( + partner_id=self.liasse_id.partner_id, + year=self.liasse_id.year + 1, + lm_type=lm_type, + ) + lm_id = lm_id.browse(new_lm) + # Mise à jour de la LM avec les valeurs de la liasse et de la file d'attente + lm_id.update( + { + "scop_liasse_fiscale_id": self.liasse_id.id, + "last_job_queue": self.job_queue_id.id, + } + ) + else: + self.liasse_id.liste_ministere_id.update( + { + "scop_liasse_fiscale_id": self.liasse_id.id, + "last_job_queue": self.job_queue_id.id, + } + )