diff --git a/ffck_commons/__manifest__.py b/ffck_commons/__manifest__.py index e4fd078..b6bbe42 100644 --- a/ffck_commons/__manifest__.py +++ b/ffck_commons/__manifest__.py @@ -15,6 +15,7 @@ "l10n_fr_association", "partner_contact_age_range", "partner_contact_birthdate", + "partner_contact_birthplace", "partner_contact_gender", "partner_contact_email2", "partner_contact_nationality", @@ -26,6 +27,7 @@ # Base data "data/ffck_structure_type.xml", "data/res_partner.xml", + "data/res_partner_age_range.xml", # Security "security/ir.model.access.csv", # Views diff --git a/ffck_commons/data/res_partner_age_range.xml b/ffck_commons/data/res_partner_age_range.xml new file mode 100644 index 0000000..87d66c8 --- /dev/null +++ b/ffck_commons/data/res_partner_age_range.xml @@ -0,0 +1,78 @@ + + + + + + Microbe + 0 + 8 + + + + Poussin + 9 + 10 + + + + Benjamin + 11 + 12 + + + + Minime + 13 + 14 + + + + Cadet + 15 + 16 + + + + Junior + 17 + 18 + + + + Sénior + 19 + 34 + + + + Vétéran 1 + 35 + 44 + + + + Vétéran 2 + 45 + 54 + + + + Vétéran 3 + 55 + 64 + + + + Vétéran 4 + 65 + 74 + + + + Vétéran 5 + 75 + 100 + + + + \ No newline at end of file diff --git a/ffck_commons/i18n/fr.po b/ffck_commons/i18n/fr.po index 59fd25f..880b1b5 100644 --- a/ffck_commons/i18n/fr.po +++ b/ffck_commons/i18n/fr.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0-20230613\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-05-27 16:36+0000\n" -"PO-Revision-Date: 2024-05-27 16:36+0000\n" +"POT-Creation-Date: 2024-05-27 21:44+0000\n" +"PO-Revision-Date: 2024-05-27 21:44+0000\n" "Last-Translator: \n" "Language-Team: \n" "MIME-Version: 1.0\n" @@ -17,6 +17,9 @@ msgstr "" #. module: ffck_commons #: model:ir.model.fields,field_description:ffck_commons.field_ffck_structure_type__active +#: model:ir.model.fields,field_description:ffck_commons.field_res_partner_age_range__active +#: model:ir.model.fields,field_description:ffck_commons.field_res_partner_hierarchy__active +#: model_terms:ir.ui.view,arch_db:ffck_commons.view_res_partner_filter_inherit_base msgid "Active" msgstr "Actif" @@ -25,6 +28,16 @@ msgstr "Actif" msgid "Affiliate member" msgstr "Membre affilié" +#. module: ffck_commons +#: model_terms:ir.ui.view,arch_db:ffck_commons.view_res_partner_filter_inherit_base +msgid "Age range" +msgstr "Tranche d'âges" + +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_benjamin +msgid "Benjamin" +msgstr "" + #. module: ffck_commons #: model:ir.model.fields,field_description:ffck_commons.field_res_partner__cdck_partner_id #: model:ir.model.fields,field_description:ffck_commons.field_res_users__cdck_partner_id @@ -37,6 +50,11 @@ msgstr "CDCK" msgid "CRCK partner" msgstr "CRCK" +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_cadet +msgid "Cadet" +msgstr "" + #. module: ffck_commons #: model:ir.model,name:ffck_commons.model_res_partner msgid "Contact" @@ -47,6 +65,11 @@ msgstr "" msgid "Conventioned member" msgstr "Membre conventionné" +#. module: ffck_commons +#: model_terms:ir.actions.act_window,help:ffck_commons.action_persons +msgid "Create a Contact in your address book" +msgstr "Créer un contact dans votre annuaire" + #. module: ffck_commons #: model:ir.model.fields,field_description:ffck_commons.field_ffck_structure_type__create_uid msgid "Created by" @@ -108,6 +131,7 @@ msgstr "Code FFCK éditable" #. module: ffck_commons #: model:ir.model.fields,field_description:ffck_commons.field_res_partner__ffck_network #: model:ir.model.fields,field_description:ffck_commons.field_res_users__ffck_network +#: model_terms:ir.ui.view,arch_db:ffck_commons.view_res_partner_filter_inherit_base msgid "FFCK network" msgstr "Réseau FFCK" @@ -154,6 +178,11 @@ msgstr "Hiérarchie" msgid "ID" msgstr "" +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_junior +msgid "Junior" +msgstr "" + #. module: ffck_commons #: model:ir.model.fields,field_description:ffck_commons.field_ffck_structure_type____last_update #: model:ir.model.fields,field_description:ffck_commons.field_res_partner_hierarchy____last_update @@ -204,8 +233,24 @@ msgstr "Structure locale" msgid "Local structures" msgstr "Structures locales" +#. module: ffck_commons +#: model_terms:ir.ui.view,arch_db:ffck_commons.view_partner_form_inherit_base +msgid "Lock partner code" +msgstr "Verrouiller le code" + +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_microbe +msgid "Microbe" +msgstr "" + +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_minime +msgid "Minime" +msgstr "" + #. module: ffck_commons #: model:ir.model.fields,field_description:ffck_commons.field_ffck_structure_type__name +#: model:ir.model.fields,field_description:ffck_commons.field_res_partner_age_range__name #: model:ir.model.fields,field_description:ffck_commons.field_res_partner_hierarchy__name msgid "Name" msgstr "Nom" @@ -221,12 +266,22 @@ msgstr "Nationale" msgid "Network" msgstr "Réseau fédéral" +#. module: ffck_commons +#: model_terms:ir.actions.act_window,help:ffck_commons.action_persons +msgid "Odoo helps you track all activities related to your contacts." +msgstr "Odoo vous aide à suivre les activités liées à vos contacts" + #. module: ffck_commons #: model:ir.model.fields,field_description:ffck_commons.field_ffck_structure_type__parent_id #: model:ir.model.fields,field_description:ffck_commons.field_res_partner_hierarchy__parent_id msgid "Parent" msgstr "" +#. module: ffck_commons +#: model:ir.model,name:ffck_commons.model_res_partner_age_range +msgid "Partner Age Range" +msgstr "Tranche d'âges du partenaire" + #. module: ffck_commons #: model_terms:ir.ui.view,arch_db:ffck_commons.view_res_partner_filter_inherit_base msgid "Partner scale" @@ -238,10 +293,17 @@ msgid "Partners hierarchy" msgstr "Hiérarchie des partenaires" #. module: ffck_commons +#: model:ir.actions.act_window,name:ffck_commons.action_persons +#: model:ir.ui.menu,name:ffck_commons.res_partner_menu_persons #: model_terms:ir.ui.view,arch_db:ffck_commons.view_res_partner_filter_inherit_base msgid "Persons" msgstr "Personnes" +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_poussin +msgid "Poussin" +msgstr "" + #. module: ffck_commons #: model:ir.model.fields.selection,name:ffck_commons.selection__ffck_structure_type__scale__2 #: model:ir.model.fields.selection,name:ffck_commons.selection__res_partner__partner_scale__2 @@ -266,6 +328,11 @@ msgstr "Comité Régional" msgid "Scale" msgstr "Échelle" +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_senior +msgid "Senior" +msgstr "" + #. module: ffck_commons #: model:ir.model.fields,field_description:ffck_commons.field_ffck_structure_type__short msgid "Short" @@ -318,3 +385,28 @@ msgstr "Membre agréé Type A" #: model:ffck.structure.type,name:ffck_commons.ffck_structure_type_agrb msgid "Type B agreed member" msgstr "Membre agréé Type B" + +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_veteran1 +msgid "Vétéran 1" +msgstr "" + +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_veteran2 +msgid "Vétéran 2" +msgstr "" + +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_veteran3 +msgid "Vétéran 3" +msgstr "" + +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_veteran4 +msgid "Vétéran 4" +msgstr "" + +#. module: ffck_commons +#: model:res.partner.age.range,name:ffck_commons.age_range_veteran5 +msgid "Vétéran 5" +msgstr "" diff --git a/ffck_commons/models/__init__.py b/ffck_commons/models/__init__.py index ce38023..7c2c57a 100644 --- a/ffck_commons/models/__init__.py +++ b/ffck_commons/models/__init__.py @@ -1,4 +1,7 @@ # -*- coding: utf-8 -*- from . import ffck_structure_type from . import res_partner +from . import res_partner_age_range + +# IMPORT hierarchy AFTER res_partner from . import res_partner_hierarchy diff --git a/ffck_commons/models/res_partner.py b/ffck_commons/models/res_partner.py index 4339219..bbdf3dd 100644 --- a/ffck_commons/models/res_partner.py +++ b/ffck_commons/models/res_partner.py @@ -6,6 +6,7 @@ from .ffck_structure_type import SCALES class ResPartner(models.Model): _inherit = "res.partner" + _rec_names_search = ["display_name", "ref", "partner_code", "email"] # Partner fields ffck_network = fields.Boolean(string="FFCK network") @@ -22,7 +23,9 @@ class ResPartner(models.Model): string="Structure type", ) partner_code = fields.Char(string="FFCK code", size=6, index=True) - partner_code_editable = fields.Boolean(string="FFCK code editable", default=True) + partner_code_editable = fields.Boolean( + string="FFCK code editable", default=True, readonly=True + ) # FFCK ffck_partner_id = fields.Many2one( comodel_name="res.partner", @@ -80,7 +83,7 @@ class ResPartner(models.Model): domain=[("partner_scale", "=", "4")], string="Local structures", ) - # Compute hierarchy for searchpanel + # Compute hierarchy for searchpanel TODO : move to standalone module hierarchy_id = fields.Many2one( comodel_name="res.partner.hierarchy", string="Hierarchy element", @@ -88,66 +91,54 @@ class ResPartner(models.Model): store=True, ) - @api.depends("ffck_network", "partner_scale", "partner_code") + @api.depends( + "ffck_network", + "partner_scale", + "partner_code", + "local_partner_id", + "cdck_partner_id", + "crck_partner_id", + "ffck_partner_id", + ) def _compute_partner_hierarchy(self): for partner in self: partner.hierarchy_id = ( partner.id if partner.ffck_network - and int(partner.partner_scale) in range(1, 5) + and int(partner.partner_scale) in range(1, 4) and partner.partner_code - else False + else partner.local_partner_id.id + or partner.cdck_partner_id.id + or partner.crck_partner_id.id + or partner.ffck_partner_id.id ) - @api.model - def name_search(self, name="", args=None, operator="ilike", limit=100): - """Allow searching by sequence code by default.""" - # Do not add any domain when user just clicked on search widget - if not (name == "" and operator == "ilike"): - # The dangling | is needed to combine with the domain added by super() - args = OR( - [ - [ - "&", - ("ffck_network", "=", True), - ("partner_code", "=like", name + "%"), - ], - args or [], - ] - ) - return super().name_search(name, args, operator, limit) - - @api.depends("name", "ref", "partner_code") - def name_get(self): - result = [] - ffck_partners = self.filtered("ffck_network") - others = self - ffck_partners - for record in ffck_partners: - code = record.partner_code - ref = record.ref - result.append( - ( - record.id, - "{}{}{}".format( - code and code + " - " or "", - ref and record.is_company and ref + " - " or "", - super(ResPartner, record).name_get()[0][1], - ), - ) - ) - result += super(ResPartner, others).name_get() - return result - # COMPUTES - @api.depends("company_type", "ffck_structure_type_id") + @api.depends( + "is_company", + "ffck_network", + "ffck_structure_type_id", + "ffck_structure_type_id.scale", + ) def _get_partner_scale(self): - for partner in self: - if partner.company_type == "individual": + ffck_partners = self.filtered("ffck_network") + for partner in ffck_partners: + if not partner.is_company: partner.partner_scale = "5" else: - partner.partner_scale = partner.ffck_structure_type_id.scale + partner.partner_scale = ( + partner.ffck_structure_type_id.scale + if partner.ffck_structure_type_id + else False + ) + for partner in self - ffck_partners: + partner.partner_scale = False + def lock_partner_code(self): + self.write({"partner_code_editable": False}) + + @api.depends("ffck_network") def _get_ffck_partner(self): ffck = self.env.ref("ffck_commons.res_partner_ffck", raise_if_not_found=False) main = self.env.ref("base.main_partner") @@ -159,29 +150,39 @@ class ResPartner(models.Model): else: partner.ffck_partner_id = ffck - @api.depends("state_id", "ffck_network", "partner_scale") + @api.depends( + "state_id", + "ffck_network", + "partner_scale", + "cdck_partner_id", + ) def _get_crck_partner(self): - states = self.mapped("state_id") - crck_ok = self.with_context(active_test=False).search( - [ - ("ffck_network", "=", True), - ("partner_scale", "=", "2"), - ("state_id", "in", states.ids), - ] - ) - crck_by_state = {crck.state_id: crck for crck in crck_ok} - states_ok = states & crck_ok.mapped("state_id") - concerned = self.filtered( - lambda rp: rp.ffck_network - and int(rp.partner_scale) >= 2 - and rp.state_id in states_ok - ) - for partner in concerned: - state = partner.state_id - partner.crck_partner_id = crck_by_state[state] - # treat unconcerned - for partner in self - concerned: - partner.crck_partner_id = False + cdck_ok = self.filtered("cdck_partner_id") + for partner in cdck_ok: + partner.crck_partner_id = partner.cdck_partner_id.crck_partner_id + todo = self - cdck_ok + if todo: + states = todo.mapped("state_id") + crck_ok = self.with_context(active_test=False).search( + [ + ("ffck_network", "=", True), + ("partner_scale", "=", "2"), + ("state_id", "in", states.ids), + ] + ) + states_ok = states & crck_ok.mapped("state_id") + crck_by_state = {crck.state_id: crck for crck in crck_ok} + concerned = todo.filtered( + lambda rp: rp.ffck_network + and int(rp.partner_scale) >= 2 + and rp.state_id in states_ok + ) + for partner in concerned: + state = partner.state_id + partner.crck_partner_id = crck_by_state[state] + # treat unconcerned + for partner in todo - concerned: + partner.crck_partner_id = False @api.depends( "is_company", @@ -189,56 +190,70 @@ class ResPartner(models.Model): "partner_code", "partner_scale", "local_partner_id", + "local_partner_id", "local_partner_id.partner_code", "country_department_id", "country_department_id.code", ) def _get_cdck_partner(self): - structures = self.filtered( - lambda rp: rp.is_company - and rp.ffck_network - and rp.partner_code - and len(rp.partner_code) >= 2 - and int(rp.partner_scale) in (3, 4) - ) - licensees = self.filtered( - lambda rp: not rp.is_company - and rp.ffck_network - and int(rp.partner_scale) == 5 - and ( - rp.local_partner_id - and rp.local_partner_id.cdck_partner_id - or rp.country_department_id + local_ok = self.filtered("local_partner_id") + for partner in local_ok: + partner.cdck_partner_id = partner.local_partner_id.cdck_partner_id + todo = self - local_ok + if todo: + structures = todo.filtered( + lambda rp: rp.is_company + and rp.ffck_network + and rp.partner_code + and len(rp.partner_code) >= 2 + and int(rp.partner_scale) in (3, 4) + ) + licensees = todo.filtered( + lambda rp: not rp.is_company + and rp.ffck_network + and int(rp.partner_scale) == 5 + and rp.country_department_id ) - ) - dept_codes = self.mapped( - lambda rp: rp.partner_code - and len(rp.partner_code) >= 2 - and int(rp.partner_scale) in (3, 4) - and rp.partner_code[:2] - ) - cdck_ok = self.with_context(active_test=False).search( - [ - ("ffck_network", "=", True), - ("partner_scale", "=", "3"), - ("partner_code", "in", ["{}00".format(code) for code in dept_codes]), - ] - ) - cdck_by_code = {cdck.partner_code[:2]: cdck for cdck in cdck_ok} - # Treat structures - for partner in structures: - partner.cdck_partner_id = cdck_by_code[partner.partner_code[:2]] - # Treat licensees - for partner in licensees: - dept = partner.country_department_id - local = partner.local_partner_id - local_cd = local.cdck_partner_id - partner.cdck_partner_id = ( - local_cd if local and local_cd else cdck_by_code[dept.code] + dept_codes = todo.mapped( + lambda rp: rp.ffck_network + and ( + rp.is_company + and rp.partner_code + and len(rp.partner_code) >= 2 + and int(rp.partner_scale) in (3, 4) + and rp.partner_code[:2] + or not rp.is_company + and rp.country_department_id + and rp.country_department_id.code + ) + ) + cdck_ok = self.with_context(active_test=False).search( + [ + ("is_company", "=", True), + ("ffck_network", "=", True), + ("partner_scale", "=", "3"), + ( + "partner_code", + "in", + ["{}00".format(code) for code in dept_codes], + ), + ] ) - # treat others - for partner in self - (structures | licensees): - partner.cdck_partner_id = False + cdck_by_code = {cdck.partner_code[:2]: cdck for cdck in cdck_ok} + # Treat structures + for partner in structures: + partner.cdck_partner_id = cdck_by_code[partner.partner_code[:2]] + # Treat licensees + for partner in licensees: + dept = partner.country_department_id + local = partner.local_partner_id + local_cd = local.cdck_partner_id + partner.cdck_partner_id = ( + local_cd if local and local_cd else cdck_by_code[dept.code] + ) + # treat others + for partner in todo - (structures | licensees): + partner.cdck_partner_id = False @api.depends( "ffck_network", @@ -263,6 +278,59 @@ class ResPartner(models.Model): else: partner.ffck_parent_id = False + # INHERITANCE + + # @api.model + # def name_search(self, name="", args=None, operator="ilike", limit=100): + # """Allow searching by sequence code by default.""" + # # Do not add any domain when user just clicked on search widget + # if not (name == "" and operator == "ilike"): + # # The dangling | is needed to combine with the domain added by super() + # args = OR( + # [ + # [ + # "&", + # ("ffck_network", "=", True), + # ("partner_code", "=like", name + "%"), + # ], + # args or [], + # ] + # ) + # return super().name_search(name, args, operator, limit) + + @api.depends( + "is_company", + "name", + "parent_id.display_name", + "type", + "company_name", + "commercial_company_name", + "ref", + "partner_code", + ) + def _compute_display_name(self): + return super()._compute_display_name() + + def name_get(self): + res = [] + ffck_partners = self.filtered("ffck_network") + others = self - ffck_partners + for record in ffck_partners: + code = record.partner_code + ref = record.ref + res.append( + ( + record.id, + "{}{}{}".format( + code and code + " - " or "", + ref and record.is_company and ref + " - " or "", + super(ResPartner, record).name_get()[0][1], + ), + ) + ) + res += super(ResPartner, others).name_get() + return res + # ONCHANGES @api.onchange("partner_code", "company_type", "ffck_network") @@ -276,8 +344,8 @@ class ResPartner(models.Model): # CRUD - @api.model_create_multi - def create(self, vals_list): - for vals in vals_list: - vals.update({"partner_code_editable": False}) - return super().create(vals_list) + # @api.model_create_multi + # def create(self, vals_list): + # for vals in vals_list: + # vals.update({"partner_code_editable": False}) + # return super().create(vals_list) diff --git a/ffck_commons/models/res_partner_age_range.py b/ffck_commons/models/res_partner_age_range.py new file mode 100644 index 0000000..abee99a --- /dev/null +++ b/ffck_commons/models/res_partner_age_range.py @@ -0,0 +1,12 @@ +# Copyright 2019-2020: Druidoo () +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). + +from odoo import _, api, fields, models +from odoo.exceptions import ValidationError + + +class ResPartnerAgeRange(models.Model): + _inherit = "res.partner.age.range" + + name = fields.Char(translate=True) + active = fields.Boolean(string="Active", default=True) diff --git a/ffck_commons/views/res_partner.xml b/ffck_commons/views/res_partner.xml index 0d0496b..3716955 100644 --- a/ffck_commons/views/res_partner.xml +++ b/ffck_commons/views/res_partner.xml @@ -24,17 +24,18 @@