diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 732d0c4a644eb444d6b4385643ff32fab19fab52..4acca684ec8c5cda7b3ecd21b9e568ab03d57e8c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -6,6 +6,8 @@ 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 @@ -25,8 +27,13 @@ repos: entry: found forbidden files; remove them language: fail files: "\\.rej$" + - id: en-po-files + name: en.po files cannot exist + entry: found a en.po file + language: fail + files: '[a-zA-Z0-9_]*/i18n/en\.po$' - repo: https://github.com/oca/maintainer-tools - rev: 7d8a9f9ad73db0976fb03cbee43d953bc29b89e9 + rev: ab1d7f6 hooks: # update the NOT INSTALLABLE ADDONS section above - id: oca-update-pre-commit-excluded-addons @@ -48,7 +55,7 @@ repos: hooks: - id: black - repo: https://github.com/pre-commit/mirrors-prettier - rev: v2.6.2 + rev: v2.1.2 hooks: - id: prettier name: prettier (with plugin-xml) @@ -59,7 +66,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: v8.15.0 + rev: v7.8.1 hooks: - id: eslint verbose: true @@ -67,7 +74,7 @@ repos: - --color - --fix - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.2.0 + rev: v3.2.0 hooks: - id: trailing-whitespace # exclude autogenerated files @@ -89,37 +96,33 @@ repos: - id: mixed-line-ending args: ["--fix=lf"] - repo: https://github.com/asottile/pyupgrade - rev: v2.32.1 + rev: v2.7.2 hooks: - id: pyupgrade args: ["--keep-percent-format"] - repo: https://github.com/PyCQA/isort - rev: 5.10.1 + rev: 5.12.0 hooks: - id: isort name: isort except __init__.py args: - --settings=. exclude: /__init__\.py$ - - repo: https://gitlab.com/PyCQA/flake8 - rev: 3.9.2 + - repo: https://github.com/PyCQA/flake8 + rev: 3.8.3 hooks: - id: flake8 name: flake8 additional_dependencies: ["flake8-bugbear==20.1.4"] - - repo: https://github.com/PyCQA/pylint - rev: v2.11.1 + - repo: https://github.com/OCA/pylint-odoo + rev: 7.0.2 hooks: - - id: pylint + - id: pylint_odoo name: pylint with optional checks args: - --rcfile=.pylintrc - --exit-zero verbose: true - additional_dependencies: &pylint_deps - - pylint-odoo==5.0.5 - - id: pylint - name: pylint with mandatory checks + - id: pylint_odoo args: - --rcfile=.pylintrc-mandatory - additional_dependencies: *pylint_deps diff --git a/__manifest__.py b/__manifest__.py index fa2f244435ac1a9354f48f45eebb10158d35a641..7e660652182e816d37ed3fb123d18d687be18b75 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -10,6 +10,8 @@ "depends": [ "account", "cgscop_partner", + "cgscop_cotisation_cg", + "cgscop_extranet", "cgscop_liste_ministere", ], "data": [ @@ -19,6 +21,12 @@ "datas/mail_data.xml", "datas/mail_message_subtype.xml", "datas/scop_adhesion_file_data.xml", + # wizard + "wizard/scop_compulsory_fields_suivi_wizard.xml", + "wizard/scop_membership_liasse_wizard.xml", + "wizard/scop_membership_staff_wizard.xml", + "wizard/scop_membership_submit_wizard.xml", + "wizard/scop_registration_wizard.xml", # views "views/assets.xml", "views/res_config_settings.xml", @@ -27,8 +35,5 @@ "views/scop_adhesion_file.xml", # report "report/report_scop_adhesion.xml", - # wizard - "wizard/scop_adhesion_year_wizard.xml", - "wizard/scop_compulsory_fields_suivi_wizard.xml", ], } diff --git a/models/res_partner.py b/models/res_partner.py index 84bfe8724b9674803492189df108df28073e5677..0cc8d73d4282eb59f019228745cd6581438c6c9c 100644 --- a/models/res_partner.py +++ b/models/res_partner.py @@ -1,10 +1,8 @@ # © 2022 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from pytz import timezone - from odoo import _, api, fields, models -from odoo.exceptions import ValidationError +from odoo.exceptions import UserError, ValidationError class ScopPartner(models.Model): @@ -56,12 +54,6 @@ class ScopPartner(models.Model): date_transmission_cg = fields.Date("Date de transmission du dossier à la CG") date_bureau_validation = fields.Date("Date du bureau de validation") - lm_adhesion_id = fields.Many2one( - comodel_name="scop.liste.ministere", string="Liste Ministère adhésion" - ) - lm_adhesion_year = fields.Integer( - string="Année dossier adhésion", related="lm_adhesion_id.year" - ) invoice_adhesion_id = fields.Many2one( comodel_name="account.move", string="Facture d'adhésion" ) @@ -84,6 +76,9 @@ class ScopPartner(models.Model): string="Nb de statuts de facturation", compute="_compute_project_invoicing_status_nb", ) + liasse_membership_id = fields.Many2one( + comodel_name="scop.liasse.fiscale", string="Liasse fiscale adhésion" + ) # Changement de statuts list_logs = fields.Text("Liste des erreurs") @@ -110,204 +105,83 @@ class ScopPartner(models.Model): # ------------------------------------------------------ @api.onchange("project_status") def _onchange_project_status(self): - if self.project_status != "7_abandonne": + if self.project_status != "5_abandonne": self.date_abort = None # ------------------------------------------------------ # Actions / Buttons # ------------------------------------------------------ - def scop_lm_adhesion(self): - """ - Display liste ministere form used for adhesion - :return: Form View LM - """ + def fill_membership_staff(self): self.ensure_one() - if not self.lm_adhesion_id: - self.lm_adhesion_id = self.get_lm_adhesion() - form_id = self.env.ref("cgscop_liste_ministere.view_liste_ministere_form") - action = { - "name": "Dossier d'adhésion", + staff_id = self.env["scop.partner.staff"].search( + [ + ("partner_id", "=", self.id), + ("type_entry", "=", "membership"), + ( + "effective_date", + ">", + fields.Date.subtract(fields.Date.today(), years=1), + ), + ], + limit=1, + ) + + wizard = self.env["scop.membership.staff.wizard"].create( + { + "partner_id": self.id, + "staff_id": staff_id.id if staff_id else None, + "effective_date": fields.Date.today() + if not staff_id + else staff_id.effective_date, + } + ) + return { + "name": "Effectifs à l'adhésion", "type": "ir.actions.act_window", - "res_model": "scop.liste.ministere", "view_mode": "form", - "views": [[form_id.id, "form"]], - "res_id": self.lm_adhesion_id.id, - "context": {"create": False, "edit": True, "delete": False}, + "res_model": "scop.membership.staff.wizard", + "res_id": wizard.id, + "target": "new", } - return action - def scop_liasse_adhesion(self): - """ - Display liasse fiscale used for adhesion : - :return LF attached to LM adhesion or create new one type prévi - """ + def fill_membership_liasse(self): self.ensure_one() - if not self.lm_adhesion_id: - self.lm_adhesion_id = self.get_lm_adhesion() - liasse_adhesion = self.get_liasse_adhesion(self.lm_adhesion_id) - year_adhesion = self.lm_adhesion_year - if not liasse_adhesion.year == year_adhesion: - liasse_adhesion.update({"year": year_adhesion}) - action = self.env["ir.actions.actions"]._for_xml_id( - "cgscop_liasse_fiscale.scop_liasse_fiscale_previsionnelle_act_window" - ) - action.update( + wizard = self.env["scop.membership.liasse.wizard"].create( { - "name": "Données financières", - "res_id": liasse_adhesion.id, - "context": {"create": False, "edit": True, "delete": False}, + "partner_id": self.id, + "liasse_id": self.liasse_membership_id.id, } ) - return action + return { + "name": "Données financières", + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "scop.membership.liasse.wizard", + "res_id": wizard.id, + "target": "new", + } - def scop_change_year_dossier(self): - """ - Open wizard to change year dossier adhesion - :return: - """ - wizard = self.env["scop.adhesion.year.wizard"].create( - {"lm_adhesion_id": self.lm_adhesion_id.id} + def set_registration(self): + self.ensure_one() + wizard = self.env["scop.registration.wizard"].create( + {"partner_id": self.id,} ) return { - "name": "Modifier l'année du dossier", + "name": "Immatriculation", "type": "ir.actions.act_window", "view_mode": "form", - "res_model": "scop.adhesion.year.wizard", + "res_model": "scop.registration.wizard", "res_id": wizard.id, "target": "new", } + def scop_cancel_membership(self): + for partner in self: + partner.update({"membership_status": "not_member"}) + # ------------------------------------------------------ # Business methods # ------------------------------------------------------ - def get_lm_adhesion(self, year=False): - """ - - LM renouvellement existante en année N → on rattache à cette LM - - Pas de LM existante en année N - - LM connue dans l’historique → on crée une LM renouvellement - pour l’année N - - Pas de LM connue → on créée une LM inscription - """ - self.ensure_one() - - lm_adhesion = self.lm_adhesion_id - - if not lm_adhesion: - last_lm_ids = self.get_last_lm() - year = fields.Date.today().year if not year else year - if last_lm_ids: - lm_adhesion = last_lm_ids.filtered(lambda lm: lm.year == year) - - if not lm_adhesion: - if not last_lm_ids: - type_lm = "subscribe" - else: - type_lm = "renew" - ListeMinistere = self.env["scop.liste.ministere"] - lm_adhesion_id = ListeMinistere.sudo().create_folder( - self, year, type_lm - ) - lm_adhesion = ListeMinistere.browse(lm_adhesion_id) - lm_adhesion.update_data_lm() - lm_adhesion.status = "2_publie" - self.lm_adhesion_id = lm_adhesion.id - else: - if not lm_adhesion.active: - lm_adhesion.write({"active": True}) - - return lm_adhesion - - def get_last_lm(self): - """ - Return last known lm for partner - """ - self.ensure_one() - lm_ids = self.env["scop.liste.ministere"].search( - [("partner_id", "=", self.id), ("active", "in", [True, False])], - order="year desc", - ) - return lm_ids - - def get_liasse_adhesion(self, lm): - """ - Return liasse linked to LM or create a new one - :param lm: - :return: - """ - liasse_type_previ = "forecast" - liasse_adhesion = lm.sudo().create_liasse_fiscale(liasse_type_previ) - if not liasse_adhesion.L2052_FL: - liasse_adhesion.update({"L2052_FL": self.ca_previsionnel}) - liasse_adhesion.is_qualified = True - return liasse_adhesion - - def is_project_complete(self): - """ - Check if project is complete : check fields LM-LF and docs - :return: Logs of errors if needed - """ - self.ensure_one() - lm_adhesion = self.get_lm_adhesion() - - errors = str() - errors_complete_fields = self.check_compulsory_fields(lm_adhesion) - if errors_complete_fields: - errors += errors_complete_fields - errors_complete_docs = self.check_compulsory_docs() - if errors_complete_docs: - errors_str = str() - for error in errors_complete_docs: - errors_str += "<li>" + error + "</li>" - errors += ( - "<hr/><strong>Documents manquants :</strong><ul>" + errors_str + "</ul>" - ) - if errors: - local_tz = timezone("Europe/Paris") - utc_tz = timezone("UTC") - self.list_logs = ( - "<strong>" - + utc_tz.localize(fields.Datetime.now()) - .astimezone(local_tz) - .strftime("%d/%m/%Y - %-H:%M") - + "</strong> - Impossible de soumettre le dossier à la CG Scop" - + errors - ) - return False - else: - self.list_logs = False - return True - - def check_compulsory_fields(self, lm): - """ - Vérification des champs de la liste ministère et de la liasse fiscale - :param lm: - :return: - """ - res = "" - errors_lm = lm.check_compulsory_fields_lm() - if errors_lm: - res += ( - "<hr/><strong>Dossier d'Adhésion : </strong><ul>" + errors_lm + "</ul>" - ) - liasse_adhesion = self.get_liasse_adhesion(lm) - errors_lf = liasse_adhesion.check_compulsory_fields_lf() - if errors_lf: - res += ( - "<hr/><strong>Données financières :</strong><ul>" + errors_lf + "</ul>" - ) - return res - - def check_compulsory_docs(self): - """ - Vérification de la présence des docs obligatoires - :return: - """ - errors = list() - if errors: - return errors - else: - return False - def create_num_adherent(self): """ Generate new num adherent with sequence @@ -383,7 +257,7 @@ class ScopPartner(models.Model): } ) - def create_invoice_adhesion(self, lm): + def create_invoice_adhesion(self): """ Crée une facture d'adhésion avec l'article et le journal configurés ‐ Moins de 11 salariés (ou effectif inconnu) : 80€ @@ -400,8 +274,11 @@ class ScopPartner(models.Model): _("Vous devez configurer un article et un journal d'adhésion !") ) else: - effectif = lm.eff_tt - amount_adhesion = self.get_amount_adhesion(effectif) + staff_line = self.staff_ids.filtered( + lambda s: s.type_entry == "membership" + ).sorted(key="effective_date", reverse=True) + staff_number = staff_line[0].staff_count if staff_line else 0 + amount_adhesion = self.get_amount_adhesion(staff_number) Invoice = self.env["account.move"] @@ -449,29 +326,52 @@ class ScopPartner(models.Model): # ------------------------------------------------------ # Override parent / Change of status # ------------------------------------------------------ + def scop_sumbit_cg(self): + """ + Ouvre le wizard + """ + wizard = self.env["scop.membership.submit.wizard"].create( + { + "partner_id": self.id, + "list_logs": self.list_logs, + } + ) + return { + "name": "Confirmation de l'adhésion", + "type": "ir.actions.act_window", + "view_mode": "form", + "res_model": "scop.membership.submit.wizard", + "res_id": wizard.id, + "target": "new", + } + def scop_send_to_cg(self): - """Hérite la fonction d'envoi de l'organisme à la CG - pour validation afin de : - - vérifier si le dossier d'adhésion est complet + """ + Modifie le statut de la coopérative pour transmission du dossier à la CG - positionner la date_transmission_cg avec la date du jour - - affecter la coop à sa DIRECCTE - - mettre à jour les lignes d'effectifs sur la fiche coop @return : True """ - if self.is_project_complete(): - super(ScopPartner, self).scop_send_to_cg() - self.date_transmission_cg = fields.Date.today() - self.lm_adhesion_id.maj_effectif_coop() - self.lm_adhesion_id.status = "3_complet" - message = "Le dossier d'adhésion a été transmis à la CG Scop" - else: - message = self.list_logs - return { - "type": "ir.actions.act_window.message", - "title": _("Transmission du dossier d'Adhésion"), - "is_html_message": True, - "message": _(message), - } + # Check Staff + staff_line = self.get_last_membership_staff() + if not (staff_line or staff_line.staff_count > 0): + raise UserError(_("Les effectifs à l'adhésion ne sont pas renseignés.")) + # Check financial datas + if not self.liasse_membership_id: + raise UserError( + _( + "Il est nécessaire de renseigner les données financières pour valider" + ) + ) + if self.liasse_membership_id.check_compulsory_fields_lf(): + raise UserError(_("Les données financières ne peuvent pas être nulles.")) + + self.update( + { + "membership_status": "soumis_cg", + "date_transmission_cg": fields.Date.today(), + "list_logs": False, + } + ) def scop_abandonne(self): """ @@ -483,13 +383,15 @@ class ScopPartner(models.Model): self.date_abort = fields.Date.today() return True - def scop_suivi_non_adhesion(self): + def scop_suivi_adhesion(self): """ - Passe la coop en statut suivi sans devenir adhérente + Shows validation wizard """ wizard = self.env["scop.compulsory.fields.suivi.wizard"].create( { "partner_id": self.id, + "list_logs": self.list_logs, + "with_adhesion": self.env.context.get("default_with_adhesion", False), } ) return { @@ -501,6 +403,10 @@ class ScopPartner(models.Model): "target": "new", } + def scop_valid_cg_button(self): + self.ensure_one() + self.scop_valid_cg() + def scop_valid_cg(self): """ Inherit function to : @@ -509,14 +415,6 @@ class ScopPartner(models.Model): - create invoice adhesion - set liasse_fiscale_adhesion as qualified """ - - if not self.lm_adhesion_id: - raise ValidationError( - _("Cette coopérative n'a pas de dossier d'inscription") - ) - - res = super(ScopPartner, self).scop_valid_cg() - # Create period adhésions with num adherent num_adherent = self.member_number_int or self.create_num_adherent() self.create_period_adhesion_cg(num_adherent) @@ -524,13 +422,23 @@ class ScopPartner(models.Model): # TODO : check pour fede CAE si coop is CAE ? # Create invoice adhésion - invoice = self.create_invoice_adhesion(self.lm_adhesion_id) + invoice = self.create_invoice_adhesion() self.invoice_adhesion_id = invoice + self.update( + { + "membership_status": "member", + "extranet_update_company": True, + "extranet_service_access": True, + } + ) + return True - # set liasse_fiscale_adhesion as qualified - self.lm_adhesion_id.scop_liasse_fiscale_id.write({"is_qualified": True}) - - return res + def get_last_membership_staff(self): + self.ensure_one() + staff_line = self.staff_ids.filtered( + lambda s: s.type_entry == "membership" + ).sorted(key="effective_date", reverse=True) + return staff_line[0] if staff_line else False class ResPartnerPrescriberCanal(models.Model): diff --git a/models/scop_adhesion_file.py b/models/scop_adhesion_file.py index 9567c168a5be04bc45965ddca6b4abd7e99ab2d4..ba8881526803ecf6044b7e90e6af8f7a485cd480 100644 --- a/models/scop_adhesion_file.py +++ b/models/scop_adhesion_file.py @@ -8,9 +8,14 @@ class ScopAdhesionFiles(models.Model): _name = "scop.adhesion.file" _description = "Documents pour adhésion des coops" - name = fields.Char("Nom du fichier") + name = fields.Char("Nom du fichier", required=True) coop_type_id = fields.Many2one( comodel_name="res.partner.cooperative.form", string="Type de coopérative", + required=True, ) is_compulsory = fields.Boolean("Obligatoire") + type_process = fields.Selection( + [("project", "Projet de création"), ("adhesion", "Processus d'adhésion")], + string="Type de process", + ) diff --git a/models/scop_liasse_fiscale.py b/models/scop_liasse_fiscale.py index c44f1473ce54cbb7066b133b47e16fc667ab1bc7..8f1ced22b012675890374906cae5e866aa10ab21 100644 --- a/models/scop_liasse_fiscale.py +++ b/models/scop_liasse_fiscale.py @@ -25,4 +25,4 @@ class ScopAdhesionLiasseFiscale(models.Model): "(CA ou VA obligatoire)</li>" ) else: - return str() + return False diff --git a/report/report_scop_adhesion.xml b/report/report_scop_adhesion.xml index 9c894dfdd513d4d15790f6f38bccdf2e8eeb3f5c..89f1e1ee41c3af95388193e1a56ee38cf0b31280 100644 --- a/report/report_scop_adhesion.xml +++ b/report/report_scop_adhesion.xml @@ -8,9 +8,7 @@ <div class="page" style="font-size: 16px;"> <div class="row"> <div class="col-6 offset-6"> - <span - t-field="o.name" - /><br /> + <span t-field="o.name" /><br /> <span t-field="o.street" /><br /> <t t-if="o.street2"><span t-field="o.street2" /><br /></t> <t t-if="o.street3"><span t-field="o.street3" /><br /></t> diff --git a/security/ir.model.access.csv b/security/ir.model.access.csv index b5dc77e4c9811328765060a95fb640f54cedee54..f776029d3426388b5454906c456bf581bd58970a 100644 --- a/security/ir.model.access.csv +++ b/security/ir.model.access.csv @@ -6,4 +6,7 @@ admin_res_partner_project_invoicing_status,admin_res_partner_project_invoicing_s access_scop_adhesion_file,access_scop_adhesion_file,model_scop_adhesion_file,base.group_user,1,0,0,0 admin_scop_adhesion_file,admin_scop_adhesion_file,model_scop_adhesion_file,cgscop_partner.group_cg_administrator,1,1,1,1 cg_access_compulsory_fields_suivi_wizard,cg_access_compulsory_fields_suivi_wizard,model_scop_compulsory_fields_suivi_wizard,base.group_user,1,1,1,0 -cg_access_adhesion_year_wizard,cg_access_adhesion_year_wizard,model_scop_adhesion_year_wizard,cgscop_partner.group_cg_administrative,1,1,1,0 +access_scop_membership_liasse_wizard,access_scop_membership_liasse_wizard,model_scop_membership_liasse_wizard,base.group_user,1,1,1,1 +access_scop_membership_staff_wizard,access_scop_membership_staff_wizard,model_scop_membership_staff_wizard,base.group_user,1,1,1,1 +access_scop_membership_submit_wizard,access_scop_membership_submit_wizard,model_scop_membership_submit_wizard,base.group_user,1,1,1,1 +access_scop_registration_wizard,access_scop_registration_wizard,model_scop_registration_wizard,base.group_user,1,1,1,1 \ No newline at end of file diff --git a/views/res_partner.xml b/views/res_partner.xml index 0455b7a3a64109ccc9349b3e51adbfea35da2fae..3ff1457d10cb38bdf756934d19766a3aa3e2e380 100644 --- a/views/res_partner.xml +++ b/views/res_partner.xml @@ -32,54 +32,116 @@ </field> </record> + <!-- + Inherited Scop Partner Form + --> <record id="view_partner_cooperative_adhesion_form" model="ir.ui.view"> <field name="name">cooperative.adhesion.form</field> <field name="model">res.partner</field> <field name="inherit_id" ref="cgscop_partner.scop_contact_view_form" /> - <field name="priority" eval="1" /> <field name="arch" type="xml"> + <!-- Boutons de validation --> + <xpath expr="//button[@name='scop_abandonne']" position="before"> + <button + string="Projet d'adhésion" + class="oe_read_only" + type="object" + name="scop_prj_adhesion" + attrs="{'invisible':['|', ('project_status','!=','4_suivi'), ('membership_status','not in',('out', 'not_member'))]}" + confirm="Êtes-vous sûr de vouloir rebasculer cette coopérative dans le processus d'adhésion ?" + /> + <button + string="Envoyer Dossier CG" + type="object" + name="scop_sumbit_cg" + class="btn-primary" + attrs="{'invisible': [('membership_status', '!=', 'adhesion')]}" + /> + <button + string="Dossier créé CG" + type="object" + name="scop_valid_cg_button" + class="btn-primary" + attrs="{'invisible': [('membership_status', '!=', 'soumis_cg')]}" + groups="cgscop_partner.group_cg_administrator" + /> + <button + string="Projet d'adhésion abandonné" + type="object" + name="scop_cancel_membership" + attrs="{'invisible': [('membership_status', '!=', 'adhesion')]}" + confirm="Valider l'abandon du projet d'adhésion ?" + /> + <button + string="Retour phase d'adhésion" + class="oe_read_only" + type="object" + name="scop_prj_adhesion" + groups="cgscop_partner.group_cg_administrative" + attrs="{'invisible':['|', ('project_status','!=','4_suivi'), ('membership_status','!=','soumis_cg')]}" + confirm="Êtes-vous sûr de vouloir basculer cette coopérative en phase d'adhésion ?" + /> + <button + string="Immatriculation" + type="object" + name="set_registration" + attrs="{'invisible': [('is_registration_in_progress', '!=', True)]}" + /> + </xpath> + + <!-- Alert pour les données du process d'adhésion --> + <xpath expr="//group[@name='scop_general_infos']" position="before"> + <div + attrs="{'invisible': [('membership_status', '!=', 'adhesion')]}" + role="alert" + class="alert alert-warning" + >Il est nécessaire de renseigner <button + class="btn btn-info btn-sm" + name="fill_membership_staff" + type="object" + >les effectifs</button> et <button + class="btn btn-info btn-sm" + name="fill_membership_liasse" + type="object" + >les données financières</button> pour valider l'adhésion. + </div> + </xpath> + + <!-- Alert warning pour Statuts et JO --> + <xpath expr="//field[@name='date_1st_sign']" position="after"> + <div + attrs="{'invisible': ['|', ('date_1st_sign', '=', False), ('project_status', '!=', '3_accompagnement')]}" + role="alert" + class="alert alert-warning" + colspan="2" + > + Charger les <strong>Statuts</strong> et <strong + >la publication au JO</strong> dans l'onglet <i>Documents</i>. + </div> + </xpath> + <!-- Alert warning pour le KBis --> + <xpath expr="//field[@name='social_object']" position="before"> + <div + attrs="{'invisible': ['|', ('registration_date', '=', False), ('project_status', '!=', '3_accompagnement')]}" + role="alert" + class="alert alert-warning" + colspan="2" + > + Charger le <strong>KBIS</strong> dans l'onglet <i>Documents</i>. + </div> + </xpath> <page name='scop_contacts' position="before"> + <!-- Processus de création --> <page - name="adhesion_processus1" - string="Processus d'Adhésion" - attrs="{'invisible': ['|', ('is_cooperative', '!=', True), ('project_status','=','6_suivi')]}" + name="creation_process" + string="Processus de création" + attrs="{'invisible': ['|', ('is_cooperative', '!=', True), ('project_status','=','4_suivi')]}" > - <header> - <button - string="Dossier d'adhésion" - type="object" - name="scop_lm_adhesion" - class="btn-info" - attrs="{'invisible': ['|', ('project_status', '!=', '4_adhesion'), ('cooperative_form_id', 'in', (%(cgscop_partner.form_scic)d, %(cgscop_partner.form_coop47)d))]}" - /> - <button - string="Dossier d'inscription" - type="object" - name="scop_lm_adhesion" - class="btn-info" - attrs="{'invisible': ['|', ('project_status', '!=', '4_adhesion'), ('cooperative_form_id', 'not in', (%(cgscop_partner.form_scic)d, %(cgscop_partner.form_coop47)d))]}" - /> - <button - string="Données financières" - type="object" - name="scop_liasse_adhesion" - class="btn-info" - attrs="{'invisible': [('project_status', '!=', '4_adhesion')]}" - /> - <button - string="Modifier l'année du dossier" - type="object" - name="scop_change_year_dossier" - class="btn-warning" - attrs="{'invisible': ['|', ('project_status', '!=', '4_adhesion'), ('lm_adhesion_id', '=', False)]}" - groups="cgscop_partner.group_cg_administrator" - /> - </header> <div class="alert alert-danger" role="alert" - attrs="{'invisible':['|', '|', ('write_date', '=', False), ('list_logs', '=', False), ('project_status', 'not in', ('4_adhesion', '5_cg'))]}" + attrs="{'invisible':['|', '|', ('write_date', '=', False), ('list_logs', '=', False), ('project_status', '!=', '3_accompagnement')]}" > <field class="o_field_header" @@ -107,11 +169,11 @@ <field name="ca_previsionnel" widget="monetary" /> <field name="date_abort" - attrs="{'invisible':[('project_status','!=','7_abandonne')], 'required':[('project_status','=','7_abandonne')]}" + attrs="{'invisible':[('project_status','!=','5_abandonne')], 'required':[('project_status','=','5_abandonne')]}" /> <field name="abort_comments" - attrs="{'invisible':[('project_status','!=','7_abandonne')], 'required':[('project_status','=','7_abandonne')]}" + attrs="{'invisible':[('project_status','!=','5_abandonne')], 'required':[('project_status','=','5_abandonne')]}" /> </group> <group string="Dossier UE"> @@ -161,12 +223,48 @@ <field name="date_convention" /> <field name="amount_convention" widget="monetary" /> </group> + </group> + </page> + + <!-- Processus d'adhésion --> + <page + name="membership_process" + string="Processus d'adhésion" + attrs="{'invisible': ['|', '|', ('is_cooperative', '!=', True), ('project_status','!=','4_suivi'), ('membership_status', 'not in', ('adhesion', 'soumis_cg'))]}" + > + <header> + <button + string="Effectifs à l'adhésion" + type="object" + name="fill_membership_staff" + class="btn-info" + /> + <button + string="Données financières" + type="object" + name="fill_membership_liasse" + class="btn-info" + attrs="{'invisible': [('membership_status', '!=', 'adhesion')]}" + /> + </header> + <div + class="alert alert-danger" + role="alert" + attrs="{'invisible':['|', '|', ('write_date', '=', False), ('list_logs', '=', False), ('project_status', '!=', '3_accompagnement')]}" + > + <field + class="o_field_header" + name="list_logs" + readonly="1" + widget="html" + /> + </div> + <field name="project_invoicing_status_nb" invisible="1" /> + <group col="3"> <group string="Phase d'adhésion" attrs="{'invisible':[('project_status','in',('1_information','2_pre-diagnostic','3_accompagnement'))]}" > - <field name="lm_adhesion_id" invisible="1" /> - <field name="lm_adhesion_year" /> <field name="file_full" widget="boolean_toggle" /> <field name="date_transmission_cg" /> <field name="date_bureau_validation" /> @@ -175,11 +273,12 @@ </page> </page> + <!-- Onglet 2 processus création --> <page name='scop_staff' position="after"> <page - name="adhesion_processus2" - string="Processus d'Adhésion" - attrs="{'invisible': ['|', ('is_cooperative', '!=', True), ('project_status','!=','6_suivi')]}" + name="creation_process_tab" + string="Processus de création" + attrs="{'invisible': ['|', ('is_cooperative', '!=', True), ('project_status','!=','4_suivi')]}" > <field name="project_invoicing_status_nb" invisible="1" /> <group col="3"> @@ -197,7 +296,7 @@ /> <field name="creation_delegate_id" - attrs="{'required':[('project_status','in',('3_accompagnement','4_adhesion', '5_cg'))]}" + attrs="{'required':['|', ('project_status','=','3_accompagnement'), ('membership_status','in',('adhesion', 'soumis_cg'))]}" options="{'no_create': True}" domain="[('ur_id', '=', ur_id)]" /> @@ -247,28 +346,29 @@ <field name="date_convention" /> <field name="amount_convention" widget="monetary" /> </group> - <group - string="Phase d'adhésion" - attrs="{'invisible':[('project_status','in',('1_information','2_pre-diagnostic','3_accompagnement'))]}" - > - <field name="file_full" widget="boolean_toggle" /> - <field name="date_transmission_cg" /> - <field name="date_bureau_validation" /> - </group> </group> </page> </page> <xpath expr="//button[@name='scop_abandonne']" position="after"> <button - string="Suivi sans adhésion" + string="Création sans adhésion" type="object" - name="scop_suivi_non_adhesion" - attrs="{'invisible':[('project_status','in',('5_cg', '6_suivi', '7_abandonne'))]}" + name="scop_suivi_adhesion" + attrs="{'invisible':[('project_status','!=','3_accompagnement')]}" + /> + <button + string="Création avec adhésion" + type="object" + name="scop_suivi_adhesion" + class="oe_highlight" + attrs="{'invisible':[('project_status','!=','3_accompagnement')]}" + context="{'default_with_adhesion': True}" /> </xpath> </field> + <field name="priority" eval="1" /> </record> <record id="view_partner_prospect_adhesion_tree" model="ir.ui.view"> diff --git a/views/scop_adhesion_file.xml b/views/scop_adhesion_file.xml index b4562fa0a453985616566d5dff63008169b9eb59..15d92b7b54e1a7514086ea5be896800e73609bab 100644 --- a/views/scop_adhesion_file.xml +++ b/views/scop_adhesion_file.xml @@ -3,7 +3,28 @@ License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> <odoo> <data> - <!-- Questionnaire Type --> + + <record id="scop_adhesion_file_search" model="ir.ui.view"> + <field name="name">scop.adhesion.file.search</field> + <field name="model">scop.adhesion.file</field> + <field name="arch" type="xml"> + <search string="Recherche Documents"> + <field name="name" /> + <filter + string="Projets de création" + name="project" + domain="[('type_process','=', 'project')]" + /> + <filter + string="Adhésion" + name="adh" + domain="[('type_process','=', 'adhesion')]" + /> + </search> + </field> + </record> + + <!-- Documents --> <record id="scop_adhesion_file_tree" model="ir.ui.view"> <field name="name">scop.adhesion.file.tree</field> <field name="model">scop.adhesion.file</field> @@ -11,16 +32,20 @@ <tree string="Document" editable="top"> <field name="name" /> <field name="coop_type_id" /> + <field name="type_process" /> <field name="is_compulsory" /> </tree> </field> </record> <record id="action_scop_adhesion_file_tree" model="ir.actions.act_window"> - <field name="name">Documents adhésion</field> + <field name="name">Documents</field> <field name="res_model">scop.adhesion.file</field> <field name="view_mode">tree</field> - <field name="help">Liste des documents pour l'adhésion.</field> + <field name="search_view_id" ref="scop_adhesion_file_search" /> + <field + name="help" + >Liste des documents pour l'adhésion et les projets de création</field> </record> <!-- MENUS --> diff --git a/wizard/__init__.py b/wizard/__init__.py index 637e9b26ef8125d9925d2a78e66641b643f2bf49..05afc06b01d4d802c1e682b2da4b78cc9868fa1e 100644 --- a/wizard/__init__.py +++ b/wizard/__init__.py @@ -1,5 +1,8 @@ # © 2021 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from . import scop_adhesion_year_wizard from . import scop_compulsory_fields_suivi_wizard +from . import scop_membership_liasse_wizard +from . import scop_membership_staff_wizard +from . import scop_membership_submit_wizard +from . import scop_registration_wizard diff --git a/wizard/scop_adhesion_year_wizard.py b/wizard/scop_adhesion_year_wizard.py deleted file mode 100644 index b542d5a3a086970d806653cfd97f6afca48a9663..0000000000000000000000000000000000000000 --- a/wizard/scop_adhesion_year_wizard.py +++ /dev/null @@ -1,37 +0,0 @@ -# © 2022 Le Filament (<http://www.le-filament.com>) -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). - -from odoo import fields, models - - -class ScopAdhesionYearWizard(models.TransientModel): - _name = "scop.adhesion.year.wizard" - _description = "Wizard: Changer l'année du dossier d'adhésion" - - lm_adhesion_id = fields.Many2one( - comodel_name="scop.liste.ministere", string="Lm_adhesion_id", required=False - ) - current_year = fields.Integer( - string="Année actuelle", related="lm_adhesion_id.year" - ) - choosen_year = fields.Selection( - [ - (str(year), str(year)) - for year in range( - fields.Date.today().year - 3, fields.Date.today().year + 2 - ) - ], - string="Année choisie", - ) - - # ------------------------------------------------------ - # Actions / Buttons - # ------------------------------------------------------ - def change_year(self): - """ - Change l'année du dossier d'adhésion pour le partner - :return: - """ - partner = self.lm_adhesion_id.partner_id - partner.lm_adhesion_id = partner.get_lm_adhesion(int(self.choosen_year)) - return {"type": "ir.actions.act_window_close"} diff --git a/wizard/scop_adhesion_year_wizard.xml b/wizard/scop_adhesion_year_wizard.xml deleted file mode 100644 index 1405f19cadf2b1723c27c9ef11c896854ae158c7..0000000000000000000000000000000000000000 --- a/wizard/scop_adhesion_year_wizard.xml +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" ?> -<!-- Copyright 2021 Le Filament - License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> -<odoo> - <data> - - <record model="ir.ui.view" id="scop_adhesion_year_wizard_form_view"> - <field name="name">scop.adhesion.year.wizard.form</field> - <field name="model">scop.adhesion.year.wizard</field> - <field name="arch" type="xml"> - <form string="Changer l'année du dossier d'adhésion"> - <group> - <field name="current_year" /> - <field name="choosen_year" required="1" /> - </group> - <footer> - <button - name="change_year" - type="object" - string="Valider" - class="oe_highlight" - /> - <button special="cancel" string="Annuler" /> - </footer> - </form> - </field> - </record> - - </data> -</odoo> diff --git a/wizard/scop_compulsory_fields_suivi_wizard.py b/wizard/scop_compulsory_fields_suivi_wizard.py index 59e7e4c1348977d6ab273ef5f94ea0c349911975..7a5f049ecdfcbff932ecd6e6788619156d9801e9 100644 --- a/wizard/scop_compulsory_fields_suivi_wizard.py +++ b/wizard/scop_compulsory_fields_suivi_wizard.py @@ -1,7 +1,8 @@ # © 2021 Le Filament (<http://www.le-filament.com>) # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -from odoo import fields, models +from odoo import _, fields, models +from odoo.exceptions import UserError class ScopCompulsoryFieldsSuiviWizard(models.TransientModel): @@ -13,6 +14,8 @@ class ScopCompulsoryFieldsSuiviWizard(models.TransientModel): ) ur_id = fields.Many2one(related="partner_id.ur_id", readonly=False) + email = fields.Char(related="partner_id.email", readonly=False) + is_scop = fields.Boolean(compute="_compute_is_scop") creation_origin_id = fields.Many2one( related="partner_id.creation_origin_id", readonly=False ) @@ -23,13 +26,96 @@ class ScopCompulsoryFieldsSuiviWizard(models.TransientModel): closeout_month = fields.Selection( related="partner_id.closeout_month", readonly=False ) + is_registration_in_progress = fields.Boolean( + related="partner_id.is_registration_in_progress", readonly=False + ) + naf_id = fields.Many2one(related="partner_id.naf_id", readonly=False) + registration_date = fields.Date( + related="partner_id.registration_date", readonly=False + ) + siret = fields.Char(related="partner_id.siret", readonly=False) + with_adhesion = fields.Boolean("Avec adhésion") + list_logs = fields.Text("Liste des erreurs") + + # ------------------------------------------------------ + # Compute + # ------------------------------------------------------ + def _compute_is_scop(self): + form_id = self.partner_id.cooperative_form_id + if form_id in form_id._get_lm_form(): + self.is_scop = True + else: + self.is_scop = True # ------------------------------------------------------ # Actions / Buttons # ------------------------------------------------------ def confirm(self): """ - Passe la coop en statut "6_suivi" + Passe la coop en statut "4_suivi" + """ + self.partner_id.write({"project_status": "4_suivi", "list_logs": False}) + form_id = self.partner_id.cooperative_form_id + if self.with_adhesion: + self.partner_id.write({"membership_status": "adhesion"}) + + if form_id in form_id._get_lm_form(): + # Create extranet access + self.partner_id.write({"extranet_service_access": True}) + if not self.partner_id.director_ids: + raise UserError( + _("Il est nécessaire de renseigner les mandataires pour valider") + ) + for director in self.partner_id.director_ids: + director.update( + { + "extranet_access": True, + "extranet_update_company": True, + "category_id": [ + ( + 4, + self.env.ref( + "__export__.res_partner_category_6_a5b5dca7" + ).id, + 0, + ), + ], + } + ) + # Create LM + self.env["scop.liste.ministere"].sudo().create_folder( + self.partner_id, self.date_1st_sign.year, "subscribe" + ) + # Set DDETS + self.partner_id.affectation_contact_ministere() + + if self.with_adhesion: + for director in self.partner_id.director_ids: + director.update( + { + "category_id": [ + ( + 4, + self.env.ref( + "__export__.res_partner_category_4_eb133182" + ).id, + 0, + ), + ( + 4, + self.env.ref( + "__export__.res_partner_category_6_a5b5dca7" + ).id, + 0, + ), + ] + } + ) + + return {"type": "ir.actions.act_window_close"} + + def save_data(self): + """ + Sauvegarder les données même avec erreurs """ - self.partner_id.write({"project_status": "6_suivi"}) return {"type": "ir.actions.act_window_close"} diff --git a/wizard/scop_compulsory_fields_suivi_wizard.xml b/wizard/scop_compulsory_fields_suivi_wizard.xml index f2a3c47f19b86d81c0a7431e87b8c6d4197ea7b1..296f26a341d546bd176b491e481b74a3b85db37d 100644 --- a/wizard/scop_compulsory_fields_suivi_wizard.xml +++ b/wizard/scop_compulsory_fields_suivi_wizard.xml @@ -9,15 +9,43 @@ id="scop_adhesion_compulsory_fields_suivi_wizard_form" > <field name="name">scop.adhesion.compulsory.fields.suivi.wizard.form</field> - <field name="model">scop.compulsory.fields.suivi.wizard</field> + <field name="model">scop.compulsory.fields.suivi.wizard</field> <field name="arch" type="xml"> <form string="Confirmer les champs obligatoires"> + <div class="alert alert-warning" role="alert"> + <p> + Il est nécessaire de charger les <strong + >statuts</strong><span + attrs="{'invisible': [('is_registration_in_progress', '=', True)]}" + >, le <strong>KBIS</strong></span> et <strong + >l'annonce de publication au JO</strong> dans l'onglet <i + >Documents</i> de la coopérative pour valider sa création. + </p> + </div> + <div + class="alert alert-danger" + role="alert" + attrs="{'invisible':[('list_logs', '=', False)]}" + > + <field + class="o_field_header" + name="list_logs" + readonly="1" + widget="html" + /> + </div> <group> + <field name="is_scop" invisible="1" /> + <field name="with_adhesion" invisible="1" /> <field name="ur_id" required="1" options="{'no_create': True, 'no_edit': True}" /> + <field + name="email" + attrs="{'required': ['|', ('is_scop', '=', True), ('with_adhesion', '=', True)]}" + /> <field name="creation_origin_id" required="1" @@ -28,13 +56,42 @@ <field name="capital" required="1" /> <field name="first_closeout" required="1" /> <field name="closeout_month" required="1" /> + <field name="is_registration_in_progress" /> + <field + name="registration_date" + attrs="{'required': [('is_registration_in_progress', '!=', True)]}" + /> + <field + name="siret" + attrs="{'required': [('is_registration_in_progress', '!=', True)]}" + /> + <field + name="naf_id" + options="{'no_create': 1, 'no_edit': 1}" + attrs="{'required': [('is_registration_in_progress', '!=', True)]}" + /> </group> <footer> <button name="confirm" type="object" - string="Valider" + string="Valider sans adhésion" + class="oe_highlight" + attrs="{'invisible':['|', ('with_adhesion','=',True),('list_logs', '!=', False)]}" + /> + <button + name="confirm" + type="object" + string="Valider avec adhésion" + class="oe_highlight" + attrs="{'invisible':['|', ('with_adhesion','=',False), ('list_logs', '!=', False)]}" + /> + <button + name="save_data" + type="object" + string="Sauvegarder" class="oe_highlight" + attrs="{'invisible':[('list_logs', '=', False)]}" /> <button special="cancel" string="Annuler" /> </footer> diff --git a/wizard/scop_membership_liasse_wizard.py b/wizard/scop_membership_liasse_wizard.py new file mode 100644 index 0000000000000000000000000000000000000000..17fdf6a99c35397ce09c2d928033ae10a4ae3a6a --- /dev/null +++ b/wizard/scop_membership_liasse_wizard.py @@ -0,0 +1,120 @@ +# © 2022 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 ScopMembershipLiasseWizard(models.TransientModel): + _name = "scop.membership.liasse.wizard" + _description = "Wizard: Données financières d'adhésion" + + # ------------------------------------------------------ + # Field declaration + # ------------------------------------------------------ + partner_id = fields.Many2one( + comodel_name="res.partner", string="Coopérative", required=True + ) + liasse_id = fields.Many2one( + comodel_name="scop.liasse.fiscale", + string="Liasse existante", + ) + is_financial_data = fields.Boolean(compute="_compute_is_financial_data") + is_editable = fields.Boolean(compute="_compute_is_editable") + + # Related fields + is_qualified = fields.Boolean(related="liasse_id.is_qualified") + year = fields.Integer(related="liasse_id.year") + type_id = fields.Selection(related="liasse_id.type_id") + source = fields.Selection(related="liasse_id.source") + dureeExercice = fields.Integer(related="liasse_id.dureeExercice") + L2050_DCLO = fields.Date(related="liasse_id.L2050_DCLO") + currency_id = fields.Many2one(related="liasse_id.currency_id") + L2052_FL = fields.Monetary(related="liasse_id.L2052_FL") + av_cg = fields.Monetary(related="liasse_id.av_cg") + av_lf = fields.Monetary(related="liasse_id.av_lf") + L2052_FY = fields.Monetary(related="liasse_id.L2052_FY") + L2053_HN = fields.Float(related="liasse_id.L2053_HN") + contribution_base_type = fields.Selection( + related="liasse_id.contribution_base_type" + ) + contribution_base_amount = fields.Integer( + related="liasse_id.contribution_base_amount" + ) + contribution_cg = fields.Float(related="liasse_id.contribution_cg") + contribution_hdf = fields.Float( + related="liasse_id.contribution_hdf" + ) + contribution_med = fields.Float( + related="liasse_id.contribution_med" + ) + contribution_com = fields.Float( + related="liasse_id.contribution_com" + ) + contribution_cae = fields.Float( + related="liasse_id.contribution_cae" + ) + contribution_indus = fields.Float( + related="liasse_id.contribution_indus" + ) + + # ------------------------------------------------------ + # Compute + # ------------------------------------------------------ + def _compute_is_financial_data(self): + for wizard in self: + liasse_ids = self.env["scop.liasse.fiscale"].search( + [("partner_id", "=", wizard.partner_id.id)] + ) + wizard.is_financial_data = True if liasse_ids else False + + @api.depends("liasse_id") + def _compute_is_editable(self): + for wizard in self: + if wizard.liasse_id.type_id == "forecast": + wizard.is_editable = True + else: + wizard.is_editable = False + + # ------------------------------------------------------ + # Actions / Buttons + # ------------------------------------------------------ + def save_data(self): + """ + Sauvegarder les données même avec erreurs + """ + self.partner_id.liasse_membership_id = self.liasse_id + return {"type": "ir.actions.act_window_close"} + + def new_forecast(self): + liasse_values = { + "partner_id": self.partner_id.id, + "year": fields.Date.today().year, + "effective_date": fields.Date.today(), + "source": "manual", + "type_id": "forecast", + "is_qualified": True, + } + liasse_id = self.env["scop.liasse.fiscale"].create(liasse_values) + self.partner_id.liasse_membership_id = liasse_id + + return self.open_forecast(liasse_id) + + def update_forecast(self): + return self.open_forecast(self.liasse_id) + + # ------------------------------------------------------ + # Business function + # ------------------------------------------------------ + def open_forecast(self, liasse_id): + action = self.env["ir.actions.actions"]._for_xml_id( + "cgscop_liasse_fiscale.scop_liasse_fiscale_previsionnelle_act_window" + ) + self.partner_id.liasse_membership_id = liasse_id + action.update( + { + "target": "new", + "res_id": liasse_id.id, + "flags": {"action_buttons": False}, + } + ) + return action diff --git a/wizard/scop_membership_liasse_wizard.xml b/wizard/scop_membership_liasse_wizard.xml new file mode 100644 index 0000000000000000000000000000000000000000..8fd49cf9ea01b922dd6215c835def5b8360cf846 --- /dev/null +++ b/wizard/scop_membership_liasse_wizard.xml @@ -0,0 +1,199 @@ +<?xml version="1.0" ?> +<!-- Copyright 2021 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> +<odoo> + <data> + + <record model="ir.ui.view" id="scop_membership_liasse_wizard_form"> + <field name="name">scop.membership.liasse.wizard.form</field> + <field name="model">scop.membership.liasse.wizard</field> + <field name="arch" type="xml"> + <form string="Effectifs à l'adhésion"> + <h3><field + name="partner_id" + readonly="1" + options="{'no_open': True}" + /></h3> + <!-- Liasse existante --> + <div + role="alert" + class="alert alert-warning" + colspan="2" + attrs="{'invisible': [('is_financial_data', '=', False)]}" + > + Veuillez sélectionner une liasse existante pour voir les données financières rattachées. + Si une liasse parmi les liasses déjà présentes vous semble valide pour le calcul des cotisations, vous n'avez pas d'action supplémentaire à effectuer. + </div> + <group> + <field name="is_financial_data" invisible="1" /> + <group> + <field + name="liasse_id" + domain="[('partner_id', '=', partner_id)]" + attrs="{'invisible': [('is_financial_data', '=', False)]}" + options="{'no_open': True, 'no_create': True}" + /> + </group> + <group> + + </group> + <group attrs="{'invisible': [('liasse_id', '=', False)]}"> + <div colspan="2"> + <field name="is_qualified" invisible="1" /> + <span + class="badge badge-pill badge-success" + attrs="{'invisible': [('is_qualified', '=', False)]}" + >Eligible cotisations</span> + </div> + <field name="year" readonly="1" /> + <field name="type_id" readonly="1" /> + <field name="source" readonly="1" /> + <field name="dureeExercice" readonly="1" /> + <field name="L2050_DCLO" readonly="1" /> + </group> + <group attrs="{'invisible': [('liasse_id', '=', False)]}"> + <field name="currency_id" invisible="1" /> + <field name="L2052_FL" string="CA" readonly="1" /> + <field name="av_cg" readonly="1" /> + <field name="av_lf" readonly="1" /> + <field + name="L2052_FY" + readonly="1" + string="Masse Salariale" + widget="monetary" + /> + <field + name="L2053_HN" + readonly="1" + string="Bénéfice/Perte" + widget="monetary" + /> + </group> + <group + string="Simulation cotisations" + attrs="{'invisible': [('liasse_id', '=', False)]}" + > + <field + name="contribution_base_type" + string="Type Assiette" + /> + <field + name="contribution_base_amount" + string="Montant Assiette" + /> + <field name="contribution_cg" string="Cotisation CG Scop" /> + <field + name="contribution_hdf" + string="UR HDF" + attrs="{'invisible': [('contribution_hdf', '<=', 0)]}" + /> + <field + name="contribution_med" + string="UR Occitanie Méditerranée" + attrs="{'invisible': [('contribution_med', '<=', 0)]}" + /> + <field + name="contribution_com" + string="Fédération de la Com" + attrs="{'invisible': [('contribution_com', '<=', 0)]}" + /> + <field + name="contribution_cae" + string="Fédération des CAE" + attrs="{'invisible': [('contribution_cae', '<=', 0)]}" + /> + <field + name="contribution_indus" + string="Fédération de l'Industrie'" + attrs="{'invisible': [('contribution_indus', '<=', 0)]}" + /> + </group> + <group attrs="{'invisible': [('liasse_id', '=', False)]}"> + <field name="is_editable" invisible="1" /> + <div + class="text-center" + colspan="2" + attrs="{'invisible': [('is_editable', '=', False)]}" + > + <button + string="Modifier la liasse prévisionnelle" + name="update_forecast" + type="object" + class="btn btn-outline-info btn-lg" + style="width: 250px;" + /> + </div> + <div + class="text-center" + colspan="2" + attrs="{'invisible': [('is_editable', '=', True)]}" + > + <button + type="action" + name="%(cgscop_liasse_fiscale.scop_load_liasse_act_window)d" + class="btn btn-outline-info btn-lg" + style="width: 250px;" + > + Importer une nouvelle liasse + </button> + </div> + </group> + </group> + <!-- Pas de liasse --> + <div + role="alert" + class="alert alert-warning" + attrs="{'invisible': [('is_financial_data', '=', True)]}" + > + Aucune donnée financière n'est à ce jour associée à cette coopérative. Pour poursuivre l'adhésion, il est nécessaire de créer une liasse prévisionnelle ou de saisir une liasse existante. + </div> + <div + class="text-center" + attrs="{'invisible': [('is_financial_data', '=', True)]}" + > + <div + class="btn-group" + role="group" + aria-label="Liasse Fiscales" + style="padding-top: 15px; padding-bottom: 15px;" + > + <button + string="Saisir une liasse prévisionnelle" + name="new_forecast" + type="object" + class="btn btn-outline-info btn-lg" + style="width: 250px;" + /> + <button + type="action" + name="%(cgscop_liasse_fiscale.scop_load_liasse_act_window)d" + context="{'membership': True}" + class="btn btn-outline-info btn-lg" + style="width: 250px;" + > + Importer une liasse + </button> + </div> + </div> + <footer> + <button + name="save_data" + type="object" + string="Sauvegarder" + class="oe_highlight" + /> + <button + type="action" + name="%(cgscop_liasse_fiscale.scop_load_liasse_act_window)d" + class="btn btn-outline-info" + > + Importer une nouvelle liasse + </button> + <button special="cancel" string="Annuler" /> + </footer> + </form> + </field> + </record> + + </data> +</odoo> diff --git a/wizard/scop_membership_staff_wizard.py b/wizard/scop_membership_staff_wizard.py new file mode 100644 index 0000000000000000000000000000000000000000..21c4d4d742444215fd26ff68cc840fc4570babf8 --- /dev/null +++ b/wizard/scop_membership_staff_wizard.py @@ -0,0 +1,56 @@ +# © 2022 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ScopMembershipStaffWizard(models.TransientModel): + _name = "scop.membership.staff.wizard" + _description = "Wizard: création modification de l'effectif d'adhésion" + + # ------------------------------------------------------ + # Field declaration + # ------------------------------------------------------ + partner_id = fields.Many2one(comodel_name="res.partner", required=True) + staff_id = fields.Many2one( + comodel_name="scop.partner.staff", + ) + effective_date = fields.Date( + related="staff_id.effective_date", readonly=False, store=True + ) + staff_count = fields.Integer( + related="staff_id.staff_count", readonly=False, store=True + ) + staff_shareholder_count = fields.Integer( + related="staff_id.staff_shareholder_count", readonly=False, store=True + ) + staff_shareholder_total = fields.Integer( + related="staff_id.staff_shareholder_total", readonly=False, store=True + ) + staff_average = fields.Float( + related="staff_id.staff_average", readonly=False, store=True + ) + comment = fields.Char(related="staff_id.comment", readonly=False, store=True) + + # ------------------------------------------------------ + # Actions / Buttons + # ------------------------------------------------------ + def save_data(self): + """ + Sauvegarder les données même avec erreurs + """ + if self.staff_id: + return {"type": "ir.actions.act_window_close"} + else: + return self.staff_id.create( + { + "partner_id": self.partner_id.id, + "type_entry": "membership", + "effective_date": self.effective_date, + "staff_count": self.staff_count, + "staff_shareholder_count": self.staff_shareholder_count, + "staff_shareholder_total": self.staff_shareholder_total, + "staff_average": self.staff_average, + "comment": self.comment, + } + ) diff --git a/wizard/scop_membership_staff_wizard.xml b/wizard/scop_membership_staff_wizard.xml new file mode 100644 index 0000000000000000000000000000000000000000..eb9135db20d63452fb2019bdeb27ecc152cec994 --- /dev/null +++ b/wizard/scop_membership_staff_wizard.xml @@ -0,0 +1,61 @@ +<?xml version="1.0" ?> +<!-- Copyright 2021 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> +<odoo> + <data> + + <record model="ir.ui.view" id="scop_membership_staff_wizard_form"> + <field name="name">scop.membership.staff.wizard.form</field> + <field name="model">scop.membership.staff.wizard</field> + <field name="arch" type="xml"> + <form string="Effectifs à l'adhésion"> + <h5><field + name="partner_id" + readonly="1" + string="Coopérative" + options="{'no_open': True}" + /></h5> + <group> + <field name="staff_id" readonly="1" invisible="1" /> + <field + name="effective_date" + required="1" + string="Date effective de l'information" + /> + <field + name="staff_count" + required="1" + string="Effectif total" + /> + <field name="staff_shareholder_count" required="1" /> + <field + name="staff_shareholder_total" + required="1" + string="Total associés y compris non salariés" + /> + <field name="staff_average" required="1" /> + <field name="comment" /> + </group> + <footer> + <button + name="save_data" + type="object" + string="Sauvegarder" + class="oe_highlight" + /> + <button special="cancel" string="Annuler" /> + </footer> + </form> + </field> + </record> + + <record id="scop_membership_staff_wizard_action" model="ir.actions.act_window"> + <field name="name">Effectifs à l'adhésion</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">scop.membership.staff.wizard</field> + <field name="view_mode">form</field> + <field name="target">new</field> + </record> + + </data> +</odoo> diff --git a/wizard/scop_membership_submit_wizard.py b/wizard/scop_membership_submit_wizard.py new file mode 100644 index 0000000000000000000000000000000000000000..59f311edbe2b65f736ce4170ad3d5747260e4f30 --- /dev/null +++ b/wizard/scop_membership_submit_wizard.py @@ -0,0 +1,34 @@ +# © 2021 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ScopMembershipSubmitWizard(models.TransientModel): + _name = "scop.membership.submit.wizard" + _description = "Wizard: Confirmer les champs obligatoires l'adhésion" + + partner_id = fields.Many2one( + comodel_name="res.partner", string="Coop", required=True + ) + ur_id = fields.Many2one(related="partner_id.ur_id", readonly=False) + list_logs = fields.Text("Liste des erreurs", compute="_compute_list_logs") + + # ------------------------------------------------------ + # Compute + # ------------------------------------------------------ + def _compute_list_logs(self): + self.list_logs = ( + self.partner_id.liasse_membership_id.check_compulsory_fields_lf() + ) + + # ------------------------------------------------------ + # Actions / Buttons + # ------------------------------------------------------ + def confirm(self): + """ + Passe la coop en statut "soumis_cg" + """ + self.partner_id.scop_send_to_cg() + + return {"type": "ir.actions.act_window_close"} diff --git a/wizard/scop_membership_submit_wizard.xml b/wizard/scop_membership_submit_wizard.xml new file mode 100644 index 0000000000000000000000000000000000000000..9e9b76cb8ed7e190bf3987aba83387cf4eb85f17 --- /dev/null +++ b/wizard/scop_membership_submit_wizard.xml @@ -0,0 +1,42 @@ +<?xml version="1.0" ?> +<!-- Copyright 2021 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> +<odoo> + <data> + + <record model="ir.ui.view" id="scop_membership_submit_wizard_form"> + <field name="name">scop.membership.submit.wizard.form</field> + <field name="model">scop.membership.submit.wizard</field> + <field name="arch" type="xml"> + <form string="Confirmer les champs obligatoires"> + <div + class="alert alert-danger" + role="alert" + attrs="{'invisible':[('list_logs', '=', False)]}" + > + <field + class="o_field_header" + name="list_logs" + readonly="1" + widget="html" + /> + </div> + <group> + <field name="partner_id" readonly="1" /> + </group> + <footer> + <button + name="confirm" + type="object" + string="Soumettre l'adhésion à la CG" + class="oe_highlight" + attrs="{'invisible':[('list_logs', '!=', False)]}" + /> + <button special="cancel" string="Fermer" /> + </footer> + </form> + </field> + </record> + + </data> +</odoo> diff --git a/wizard/scop_registration_wizard.py b/wizard/scop_registration_wizard.py new file mode 100644 index 0000000000000000000000000000000000000000..4f38283d07f6ba025960167fc49ea353104819f8 --- /dev/null +++ b/wizard/scop_registration_wizard.py @@ -0,0 +1,36 @@ +# © 2021 Le Filament (<http://www.le-filament.com>) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import fields, models + + +class ScopRegistrationWizard(models.TransientModel): + _name = "scop.registration.wizard" + _description = "Wizard: Immatriculation coop" + + partner_id = fields.Many2one( + comodel_name="res.partner", string="Coop", required=True + ) + naf_id = fields.Many2one(related="partner_id.naf_id", readonly=False) + registration_date = fields.Date( + related="partner_id.registration_date", readonly=False + ) + siret = fields.Char(related="partner_id.siret", readonly=False) + + # ------------------------------------------------------ + # Actions / Buttons + # ------------------------------------------------------ + def confirm_registration(self): + """ + Passe la coop en statut "4_suivi" + """ + last_period = self.partner_id.scop_period_ids.filtered(lambda p: not p.end) + if last_period: + last_period.ensure_one() + last_period.update({ + "end": self.registration_date, + "end_reason": "registration", + }) + self.partner_id.sudo()._add_period(self.partner_id) + self.partner_id.update({"is_registration_in_progress": False}) + return {"type": "ir.actions.act_window_close"} diff --git a/wizard/scop_registration_wizard.xml b/wizard/scop_registration_wizard.xml new file mode 100644 index 0000000000000000000000000000000000000000..a111fe4bc6e92c15bbac7d35335e84be9aca8ba1 --- /dev/null +++ b/wizard/scop_registration_wizard.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" ?> +<!-- Copyright 2021 Le Filament + License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). --> +<odoo> + <data> + + <record model="ir.ui.view" id="scop_registration_wizard_form"> + <field name="name">scop.registration.wizard.form</field> + <field name="model">scop.registration.wizard</field> + <field name="arch" type="xml"> + <form string="Immatriculation"> + <group> + <field + name="partner_id" + readonly="1" + options="{'no_create': True, 'no_edit': True}" + /> + <field name="registration_date" required="1" /> + <field name="siret" required="1" /> + <field name="naf_id" required="1" /> + </group> + <footer> + <button + name="confirm_registration" + type="object" + string="Valider" + class="oe_highlight" + /> + <button special="cancel" string="Annuler" /> + </footer> + </form> + </field> + </record> + + </data> +</odoo>