[MIG] partner_profiles: Migration to 16.0 #10

Merged
b0g merged 1 commits from 16.0-partner_profiles into 16.0 2024-03-21 15:12:57 +00:00
18 changed files with 1766 additions and 0 deletions

2
partner_profiles/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*.*~
*pyc

View File

@@ -0,0 +1,43 @@
================
partner_profiles
================
Provide several profiles for one person.
Installation
============
Use Odoo normal module installation procedure to install
``partner_profiles``.
Known issues / Roadmap
======================
None yet.
Bug Tracker
===========
Bugs are tracked on `our issues website <https://github.com/elabore-coop/member-tools/issues>`_. In case of
trouble, please check there if your issue has already been
reported. If you spotted it first, help us smashing it by providing a
detailed and welcomed feedback.
Credits
=======
Contributors
------------
* Stéphan Sainléger
Funders
-------
The development of this module has been financially supported by:
* Elabore (https://elabore.coop)
Maintainer
----------
This module is maintained by Elabore.

View File

@@ -0,0 +1,3 @@
from . import models
from . import wizard

View File

@@ -0,0 +1,44 @@
# Copyright 2022 Stéphan Sainléger (Elabore)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "partner_profiles",
"version": "16.0.1.0.0",
"author": "Elabore",
"website": "https://elabore.coop",
"maintainer": "Stéphan Sainléger",
"license": "AGPL-3",
"category": "Tools",
"summary": "Provide several profiles for one person.",
# any module necessary for this one to work correctly
"depends": [
"base",
"calendar",
"contacts",
"partner_contact_in_several_companies",
],
"qweb": [
# "static/src/xml/*.xml",
],
"external_dependencies": {
"python": [],
},
# always loaded
"data": [
"security/ir.model.access.csv",
"wizard/create_position_profile.xml",
"views/res_partner_view.xml",
"views/partner_profile_view.xml",
"data/partner_profile_data.xml",
"data/res_partner_data.xml",
],
# only loaded in demonstration mode
"demo": [],
"js": [],
"css": [],
"installable": True,
# Install this module automatically if all dependency have been previously
# and independently installed. Used for synergetic or glue modules.
"auto_install": False,
"application": False,
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="partner_profile_main" model="partner.profile">
<field name="name">Main Profile</field>
<field name="ref">partner_profile_main</field>
</record>
<record id="partner_profile_public" model="partner.profile">
<field name="name">Public Profile</field>
<field name="ref">partner_profile_public</field>
</record>
<record id="partner_profile_position" model="partner.profile">
<field name="name">Position Profile</field>
<field name="ref">partner_profile_position</field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data noupdate="1">
<record id="ir_cron_generate_missing_public_profiles" model="ir.cron">
<field name="name">Partner: generate missing public profiles</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="state">code</field>
<field name="code">model._cron_generate_missing_public_profiles()</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="active">0</field>
</record>
<record id="ir_cron_migration_partner_profiles" model="ir.cron">
<field name="name">Partner: Migration Standard Partners to Partners with Profiles</field>
<field name="model_id" ref="base.model_res_partner" />
<field name="state">code</field>
<field name="code">
model._migration_create_pro_profiles(limit=200)
model._migration_person_without_parent(limit=200)
model._migration_person_with_parent_and_existing_main(limit=200)
model._migration_person_with_parent_not_existing_main(limit=200)
</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="active">0</field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1 @@
This directory should contain the *.po for Odoo translation.

388
partner_profiles/i18n/fr.po Normal file
View File

@@ -0,0 +1,388 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_profiles
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-12 15:03+0000\n"
"PO-Revision-Date: 2023-09-12 15:03+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_kanban_view
msgid "<span attrs=\"{'invisible': [('is_main_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Main profile</b>\n"
" </span>\n"
" <span attrs=\"{'invisible': [('is_public_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Public profile</b>\n"
" </span>\n"
" <span attrs=\"{'invisible': [('is_position_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Position profile</b>\n"
" </span>"
msgstr "<span attrs=\"{'invisible': [('is_main_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Fiche administrative</b>\n"
" </span>\n"
" <span attrs=\"{'invisible': [('is_public_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Coordonnées publiques</b>\n"
" </span>\n"
" <span attrs=\"{'invisible': [('is_position_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Fiche fonction</b>\n"
" </span>"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "<span>Please find here <strong>all the position profiles</strong> linked\n"
" to this main profile.</span>"
msgstr "<span>Vous trouverez ici <strong>toutes les fiches Fonction</strong> liés\n"
" à cette fiche administrative</span>"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "<span>Please find here <strong>all the position profiles</strong> linked to\n"
" this main profile.</span>"
msgstr "<span>Vous trouverez ici <strong>toutes les fiches Fonction</strong> liés à\n"
" cette fiche administrative</span>"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "<span>Please find here <strong>all</strong> the addresses linked with this\n"
" main profile. Adress creation from this tab <strong>only\n"
" generates new main profiles</strong>.</span>"
msgstr "<span>Vous trouverez ici <strong>toutes</strong> les adresses liées avec cette\n"
" fiche administrative. La création d'adresse depuis cet onglet <strong>génère\n"
" uniquement des profils principaux</strong>.</span>"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "<span>Please find here <strong>all</strong> the addresses/contacts linked to\n"
" this main profile. Contact creation from this tab <strong>only\n"
" generates new main profiles</strong>.</span>"
msgstr "<span>Vous trouverez ici <strong>tou(te)s</strong> les adresses/contacts lié(e)s avec cette\n"
" fiche administrative. La création de contact depuis cet onglet <strong>génère\n"
" uniquement des profils principaux</strong>.</span>"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.create_position_wizard_view_form
msgid "<span>You are about to create a <strong>Position Profile</strong> which\n"
" represents the role or the job of a person in a structure.</span>"
msgstr "<span>Vous allez créer une <strong>fiche Fonction</strong> qui\n"
" représente le rôle que tient une personne au sein d'une structure.</span>\""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Address"
msgstr "Adresse"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.create_position_wizard_view_form
msgid "Cancel"
msgstr "Annuler"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "City"
msgstr "Ville"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Company"
msgstr "Société"
#. module: partner_profiles
#: model:ir.model,name:partner_profiles.model_res_partner
msgid "Contact"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__child_ids
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__child_ids
msgid "Contacts"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Country"
msgstr "Pays"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.create_position_wizard_view_form
msgid "Create"
msgstr "Créer"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Create New Position"
msgstr "Créer une nouvelle fonction"
#. module: partner_profiles
#: model:ir.actions.act_window,name:partner_profiles.action_create_position_profile_wizard
msgid "Create Position Profile"
msgstr "Créer une fiche Fonction"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Create Public Profile"
msgstr "Ajouter des coordonnées publiques"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.create_position_wizard_view_form
msgid "Create a position profile"
msgstr "Créer une fiche Fonction"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__create_uid
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__create_uid
msgid "Created by"
msgstr "Créé par"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__create_date
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__create_date
msgid "Created on"
msgstr "Créé le"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__display_name
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__display_name
msgid "Display Name"
msgstr "Nom affiché"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__email
msgid "Email"
msgstr "Courriel"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__function
msgid "Function"
msgstr "Fonction"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__has_position
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__has_position
msgid "Has Position"
msgstr "A une fonction"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__id
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__id
msgid "ID"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__is_company
msgid "Is Company"
msgstr "Est une société"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__is_main_profile
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__is_main_profile
msgid "Is Main Profile"
msgstr "Est une fiche administrative"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__is_position_profile
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__is_position_profile
msgid "Is Position Profile"
msgstr "Est une fiche fontion"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__is_public_profile
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__is_public_profile
msgid "Is Public Profile"
msgstr "Est un fiche de coordonnées publiques"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile____last_update
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile____last_update
msgid "Last Modified on"
msgstr "Dernière modification le"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__write_uid
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__write_uid
msgid "Last Updated by"
msgstr "Dernière mise à jour par"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__write_date
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__write_date
msgid "Last Updated on"
msgstr "Dernière mise à jour le"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__contact_id
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__contact_id
msgid "Main Contact"
msgstr "Fiche administrative"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
#: model:partner.profile,name:partner_profiles.partner_profile_main
msgid "Main Profile"
msgstr "Fiche administrative"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Mobile:"
msgstr "Mobile :"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__name
msgid "Name"
msgstr "Nom"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__comment
msgid "Notes"
msgstr "Commentaires"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__other_contact_ids
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__other_contact_ids
msgid "Others Positions"
msgstr "Autres fonctions"
#. module: partner_profiles
#: model:ir.actions.act_window,name:partner_profiles.partner_profile_action
msgid "Partner Profiles"
msgstr "Profiles de contact"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__partner_profile
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__partner_profile
msgid "Partner profile"
msgstr "Profil de contact"
#. module: partner_profiles
#: model:ir.model,name:partner_profiles.model_partner_profile
msgid "Partner profile to differentiate the attached partner entries"
msgstr "Profil de contact pour différentier les champs du contact"
#. module: partner_profiles
#: model:ir.ui.menu,name:partner_profiles.menu_partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profile_view_tree
msgid "Partner profiles"
msgstr "Profiles de contact"
#. module: partner_profiles
#: model:ir.actions.server,name:partner_profiles.ir_cron_migration_partner_profiles_ir_actions_server
#: model:ir.cron,cron_name:partner_profiles.ir_cron_migration_partner_profiles
#: model:ir.cron,name:partner_profiles.ir_cron_migration_partner_profiles
msgid "Partner: Migration Standard Partners to Partners with Profiles"
msgstr "Contact : Migration des Contacts standards aux Conctacts à profile"
#. module: partner_profiles
#: model:ir.actions.server,name:partner_profiles.ir_cron_generate_missing_public_profiles_ir_actions_server
#: model:ir.cron,cron_name:partner_profiles.ir_cron_generate_missing_public_profiles
#: model:ir.cron,name:partner_profiles.ir_cron_generate_missing_public_profiles
msgid "Partner: generate missing public profiles"
msgstr "Contact : Générer les fiches de coordonnées publiques manquantes"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__partner_id
msgid "Person"
msgstr "Personne"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__phone
msgid "Phone"
msgstr "Téléphone"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Phone:"
msgstr "Téléphone :"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
#: model:partner.profile,name:partner_profiles.partner_profile_position
msgid "Position Profile"
msgstr "Fiche fonction"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Positions"
msgstr "Fonctions"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
#: model:partner.profile,name:partner_profiles.partner_profile_public
msgid "Public Profile"
msgstr "Coordonnées publiques"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__public_profile_id
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__public_profile_id
msgid "Public profile"
msgstr "Coordonnées publiques"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__ref
msgid "Ref"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "State"
msgstr "État"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Street 2..."
msgstr "Rue 2..."
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Street..."
msgstr "Rue..."
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__structure_id
msgid "Structure"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__structure_position_ids
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__structure_position_ids
msgid "Structure's positions"
msgstr "Fonctions occupées dans la structures"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Sync data"
msgstr "Synchroniser"
#. module: partner_profiles
#: model:ir.actions.server,name:partner_profiles.sync_public_data_action_server
msgid "Synchronize main and public data"
msgstr "Synchroniser les données publiques"
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__to_migrate
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__to_migrate
msgid "To Migrate"
msgstr "A migrer"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "ZIP"
msgstr "Code postal"
#. module: partner_profiles
#: model:ir.model,name:partner_profiles.model_create_position_profile
msgid "create Position Profile"
msgstr "créer une fiche fonction"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "e.g. https://www.odoo.com"
msgstr "e.x. https://www.odoo.com"

View File

@@ -0,0 +1,373 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_profiles
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-12 15:02+0000\n"
"PO-Revision-Date: 2023-09-12 15:02+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_kanban_view
msgid "<span attrs=\"{'invisible': [('is_main_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Main profile</b>\n"
" </span>\n"
" <span attrs=\"{'invisible': [('is_public_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Public profile</b>\n"
" </span>\n"
" <span attrs=\"{'invisible': [('is_position_profile','=',False)]}\" style=\"color:#7c7bad;\">\n"
" <b>Position profile</b>\n"
" </span>"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "<span>Please find here <strong>all the position profiles</strong> linked\n"
" to this main profile.</span>"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "<span>Please find here <strong>all the position profiles</strong> linked to\n"
" this main profile.</span>"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "<span>Please find here <strong>all</strong> the addresses linked with this\n"
" main profile. Adress creation from this tab <strong>only\n"
" generates new main profiles</strong>.</span>"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "<span>Please find here <strong>all</strong> the addresses/contacts linked to\n"
" this main profile. Contact creation from this tab <strong>only\n"
" generates new main profiles</strong>.</span>"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.create_position_wizard_view_form
msgid "<span>You are about to create a <strong>Position Profile</strong> which\n"
" represents the role or the job of a person in a structure.</span>"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Address"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.create_position_wizard_view_form
msgid "Cancel"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "City"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Company"
msgstr ""
#. module: partner_profiles
#: model:ir.model,name:partner_profiles.model_res_partner
msgid "Contact"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__child_ids
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__child_ids
msgid "Contacts"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Country"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.create_position_wizard_view_form
msgid "Create"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Create New Position"
msgstr ""
#. module: partner_profiles
#: model:ir.actions.act_window,name:partner_profiles.action_create_position_profile_wizard
msgid "Create Position Profile"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Create Public Profile"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.create_position_wizard_view_form
msgid "Create a position profile"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__create_uid
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__create_uid
msgid "Created by"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__create_date
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__create_date
msgid "Created on"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__display_name
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__display_name
msgid "Display Name"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__email
msgid "Email"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__function
msgid "Function"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__has_position
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__has_position
msgid "Has Position"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__id
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__id
msgid "ID"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__is_company
msgid "Is Company"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__is_main_profile
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__is_main_profile
msgid "Is Main Profile"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__is_position_profile
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__is_position_profile
msgid "Is Position Profile"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__is_public_profile
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__is_public_profile
msgid "Is Public Profile"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile____last_update
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile____last_update
msgid "Last Modified on"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__write_uid
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__write_uid
msgid "Last Updated by"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__write_date
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__write_date
msgid "Last Updated on"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__contact_id
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__contact_id
msgid "Main Contact"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
#: model:partner.profile,name:partner_profiles.partner_profile_main
msgid "Main Profile"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Mobile:"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__name
msgid "Name"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__comment
msgid "Notes"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__other_contact_ids
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__other_contact_ids
msgid "Others Positions"
msgstr ""
#. module: partner_profiles
#: model:ir.actions.act_window,name:partner_profiles.partner_profile_action
msgid "Partner Profiles"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__partner_profile
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__partner_profile
msgid "Partner profile"
msgstr ""
#. module: partner_profiles
#: model:ir.model,name:partner_profiles.model_partner_profile
msgid "Partner profile to differentiate the attached partner entries"
msgstr ""
#. module: partner_profiles
#: model:ir.ui.menu,name:partner_profiles.menu_partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profile_view_tree
msgid "Partner profiles"
msgstr ""
#. module: partner_profiles
#: model:ir.actions.server,name:partner_profiles.ir_cron_migration_partner_profiles_ir_actions_server
#: model:ir.cron,cron_name:partner_profiles.ir_cron_migration_partner_profiles
#: model:ir.cron,name:partner_profiles.ir_cron_migration_partner_profiles
msgid "Partner: Migration Standard Partners to Partners with Profiles"
msgstr ""
#. module: partner_profiles
#: model:ir.actions.server,name:partner_profiles.ir_cron_generate_missing_public_profiles_ir_actions_server
#: model:ir.cron,cron_name:partner_profiles.ir_cron_generate_missing_public_profiles
#: model:ir.cron,name:partner_profiles.ir_cron_generate_missing_public_profiles
msgid "Partner: generate missing public profiles"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__partner_id
msgid "Person"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__phone
msgid "Phone"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Phone:"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
#: model:partner.profile,name:partner_profiles.partner_profile_position
msgid "Position Profile"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Positions"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
#: model:partner.profile,name:partner_profiles.partner_profile_public
msgid "Public Profile"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__public_profile_id
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__public_profile_id
msgid "Public profile"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_partner_profile__ref
msgid "Ref"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "State"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Street 2..."
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Street..."
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_create_position_profile__structure_id
msgid "Structure"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__structure_position_ids
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__structure_position_ids
msgid "Structure's positions"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "Sync data"
msgstr ""
#. module: partner_profiles
#: model:ir.actions.server,name:partner_profiles.sync_public_data_action_server
msgid "Synchronize main and public data"
msgstr ""
#. module: partner_profiles
#: model:ir.model.fields,field_description:partner_profiles.field_res_partner__to_migrate
#: model:ir.model.fields,field_description:partner_profiles.field_res_users__to_migrate
msgid "To Migrate"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "ZIP"
msgstr ""
#. module: partner_profiles
#: model:ir.model,name:partner_profiles.model_create_position_profile
msgid "create Position Profile"
msgstr ""
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.partner_profiles_form_view
msgid "e.g. https://www.odoo.com"
msgstr ""

View File

@@ -0,0 +1,5 @@
# Copyright 2020 Elabore (https://elabore.coop)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import partner_profile
from . import res_partner

View File

@@ -0,0 +1,14 @@
# Copyright 2022 Elabore (https://elabore.coop)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import models, fields
class PartnerProfile(models.Model):
_name = "partner.profile"
_description = "Partner profile to differentiate the attached partner entries"
name = fields.Char(string="Name", required=True, translate=True, readonly=False)
ref = fields.Char(string="Ref", required=True, translate=False, readonly=False)
# TODO: block unlink method.

View File

@@ -0,0 +1,439 @@
# Copyright 2022 Elabore (https://elabore.coop)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging
from odoo import _, api, fields, models
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class res_partner(models.Model):
_inherit = "res.partner"
partner_profile = fields.Many2one(
"partner.profile",
string="Partner profile",
required=False,
translate=False,
readonly=False,
)
contact_id = fields.Many2one(ondelete="cascade")
is_main_profile = fields.Boolean(compute="_compute_profile_booleans", store=True)
is_public_profile = fields.Boolean(compute="_compute_profile_booleans", store=True)
is_position_profile = fields.Boolean(
compute="_compute_profile_booleans", store=True
)
has_position = fields.Boolean(compute="_compute_has_position", store=True)
# If current partner is Main partner, this field indicates what its public profile is.
public_profile_id = fields.Many2one(
"res.partner",
compute="_compute_public_profile_id",
string="Public profile",
store=True,
)
# If current partner is Main partner, this field indicates what its position profiles are.
other_contact_ids = fields.One2many(
domain=[("is_position_profile", "=", True)]
)
child_ids = fields.One2many(
domain=[("is_position_profile", "=", False)]
)
structure_position_ids = fields.One2many('res.partner', 'parent_id', string="Structure's positions", domain=[('active', '=', True), ('is_position_profile', '=', True)])
@api.depends("partner_profile", "other_contact_ids")
def _compute_profile_booleans(self):
for partner in self:
partner.is_main_profile = (
partner.partner_profile.ref == "partner_profile_main"
)
partner.is_public_profile = (
partner.partner_profile.ref == "partner_profile_public"
)
partner.is_position_profile = (
partner.partner_profile.ref == "partner_profile_position"
)
@api.depends("other_contact_ids")
def _compute_has_position(self):
for partner in self:
partner.has_position = len(partner.other_contact_ids) > 0
@api.depends("partner_profile", "contact_id")
def _compute_public_profile_id(self):
for partner in self:
if partner.is_main_profile:
partner.public_profile_id = self.env["res.partner"].search(
[
("contact_id", "=", partner.id),
("is_public_profile", "=", True),
],
limit=1,
)
@api.onchange("type")
def _onchange_type(self):
self.contact_type = "standalone"
self.partner_profile = False
if self.type == "contact" and self.parent_id:
_logger.debug("Contact type: attached")
# A contact with parent_id is partner_profile=Position, and contact_type=attached
position_profile = self.env.ref("partner_profiles.partner_profile_position")
self.contact_type = "attached"
self.partner_profile = position_profile.id
@api.onchange("is_company")
def _onchange_is_company(self):
for partner in self:
if partner.is_main_profile:
if partner.has_position or partner.structure_position_ids.filtered(lambda c: c.is_position_profile):
raise UserError("You can not modify the partner company type when the parner has postion profiles associated. Please remove the position profiles before retrying.")
if partner.public_profile_id:
# public_partner = self.env["res.partner"].browse(partner.public_profile_id)[0]
values = {
"is_company": partner.is_company,
}
partner.public_profile_id.sudo().write(values)
@api.model
def create(self, vals):
"""Assume if not type, default is contact"""
vals["type"] = vals.get("type", "contact")
profile_position = self.env.ref("partner_profiles.partner_profile_position").id
profile_main = self.env.ref("partner_profiles.partner_profile_main").id
if vals["type"] == "contact":
"""When creating, if partner_profile is not defined by a previous process, the defaut value is Main"""
if not vals.get("partner_profile"):
vals["partner_profile"] = profile_main
# If we create a partner type position search if one main exist (via email matching) else create one.
if vals["partner_profile"] == profile_position and not vals.get("contact_id"):
existing_main = self.env["res.partner"].search([('is_company', '=', False),('partner_profile', '=', profile_main),('email', '=', vals["email"])])
if existing_main:
vals["contact_id"] = existing_main.id
else:
main_vals = vals.copy()
main_vals["partner_profile"] = profile_main
main_vals["parent_id"] = False
main_res = super(res_partner, self).create(main_vals)
main_res.create_public_profile()
vals["contact_id"] = main_res.id
res = super(res_partner, self).create(vals)
# Creation of the public profile
if (
res.partner_profile.ref == "partner_profile_main" #TODO: replace by check on boolean is_main_profile ? Is this boolean computed at this step of the process?
and not res.public_profile_id
):
res.create_public_profile()
if res.partner_profile.ref == "partner_profile_public": #TODO: replace by check on boolean is_public_profile ? Is this boolean computed at this step of the process?
# Public profile can't be customer or supplier. Only main or position profiles can
res.customer = False
res.supplier = False
else:
res = super(res_partner, self).create(vals)
return res
def unlink(self):
for partner in self:
if partner.is_company:
# Delete position profiles linked to the company main profile
for position in partner.structure_position_ids:
position.unlink()
return super(res_partner, self).unlink()
def write(self, vals):
sync_active = vals.get("sync_active", False)
vals.pop("sync_active", False)
super(res_partner, self).write(vals)
if "active" in vals and not sync_active:
self._sync_active_profiles()
def _sync_active_profiles(self):
"""Synchronize the active fields values between all the profiles of a partner.
Change in main profile is synchronized in public and position profiles.
Change in public profile is NOT synchronized in main and public profiles.
Change in position profile is NOT synchronized in main and public profiles."""
for partner in self:
if partner.is_main_profile:
# Sync public profile active value with main one
public_profile = partner.public_profile_id
if public_profile and (public_profile.active != partner.active):
public_profile.write({"active": partner.active, "sync_active": True})
# Sync position profiles active value with main one
positions = self.env["res.partner"].search(
[
("is_position_profile", "=", True),
("active", "!=", partner.active),
'|',
("contact_id", "=", partner.id),
("parent_id", "=", partner.id)
]
)
if len(positions) > 0:
for position in positions:
position.write({"active": partner.active, "sync_active": True})
@api.model
def search_position_partners(self, profile):
if profile:
position_partners = self.env["res.partner"].search(
[("contact_id", "=", self.id), ("partner_profile", "=", profile)]
)
else:
position_partners = self.env["res.partner"].search(
[("contact_id", "=", self.id)]
)
return position_partners
def _get_field_value(self, fname):
field = self._fields[fname]
if field.type == "many2one":
return self[fname].id
elif field.type == "one2many":
return None
elif field.type == "many2many":
return [(6, 0, self[fname].ids)]
else:
return self[fname]
def _get_public_profile_fields(self):
# Return the fields to copy in the public profile when it is created.
# The data copied depend on the partner's type: we consider the company data as public,
# whereas the personal data shouldn't be public by default.
if self.is_company:
fields = [
"name",
"phone",
"mobile",
"email",
"website",
"street",
"street2",
"city",
"country_id",
"zip",
"is_company",
]
else:
fields = ["name"]
return fields
def create_public_profile(self):
profile = self.env.ref("partner_profiles.partner_profile_public")
for partner in self:
_logger.debug("Create public profile [%s] %s" % (partner.id, partner.name))
# Check if a public partner already exists
partner._compute_public_profile_id()
if not partner.public_profile_id:
values = {
"type": "other",
"contact_id": partner.id,
"partner_profile": profile.id,
"company_id": partner.company_id.id,
}
public_fields = partner._get_public_profile_fields()
for field_name in public_fields:
values[field_name] = partner._get_field_value(field_name)
partner.create(values)
partner._compute_public_profile_id()
def _contact_fields(self):
""" Returns the list of contact fields that are synced from the parent
when a partner is attached to him. """
return ['title']
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
""" Remove public profile partners from the name_search results"""
if not args:
args = [("is_public_profile", "=", False)]
else:
args.append(("is_public_profile", "=", False))
return super(res_partner, self).name_search(name, args, operator, limit)
def sync_admin_and_public_data(self):
for partner in self:
if partner.is_main_profile and partner.public_profile_id:
main_partner = partner
public_partner = partner.public_profile_id
elif partner.is_public_profile and partner.contact_id:
main_partner = partner.contact_id
public_partner = partner
public_fields = partner._get_public_profile_fields()
values = {}
for field_name in public_fields:
values[field_name] = main_partner._get_field_value(field_name)
public_partner.write(values)
##################################################################################
## Planned actions
##################################################################################
@api.model
def _cron_generate_missing_public_profiles(self):
partners = self.search(
[("is_main_profile", "=", True), ("public_profile_id", "=", False), ("type", "=", "contact")]
)
for partner in partners:
partner.create_public_profile()
def _get_concerned_partners_search_values(
self,
id=False,
is_company=False,
active=True,
with_parent=False,
):
search_values = [
("is_company", "=", is_company),
("active", "=", active),
("partner_profile", "=", False),
("type", "=", "contact")
]
if id:
search_values.append(("id", "=", id))
if with_parent and not is_company:
search_values.append(("parent_id", "!=", False))
elif not is_company:
search_values.append(("parent_id", "=", False))
return search_values
@api.model
def _migration_create_pro_profiles(self, limit=None, id=False):
partner_profile_main = self.env.ref("partner_profiles.partner_profile_main")
# Company migration
search_values = self._get_concerned_partners_search_values(
id,
is_company=True,
)
partners = self.env["res.partner"].search(search_values, limit=limit)
_logger.debug("Company migration count: %s" % len(partners))
if partners:
partners.write(
{
"partner_profile": partner_profile_main.id,
}
)
partners.create_public_profile()
_logger.debug("### End migration ###")
@api.model
def _migration_person_without_parent(self, limit=None, id=False):
partner_profile_main = self.env.ref("partner_profiles.partner_profile_main")
# Person migration without parent_id
search_values = self._get_concerned_partners_search_values(id)
partners = self.env["res.partner"].search(search_values, limit=limit)
_logger.debug("Person without parent migration count: %s" % len(partners))
if partners:
partners.write(
{
"partner_profile": partner_profile_main.id,
}
)
_logger.debug("Create public profiles")
partners.create_public_profile()
_logger.debug("### End migration ###")
def _get_main_partner_search_values(self, partner):
return [
("active", "=", True),
("type", "=", "contact"),
("is_main_profile", "=", True),
("is_company", "=", False),
"|",
("name", "=", partner.name),
"&",
("email", "!=", False),
("email", "=", partner.email),
]
@api.model
def _migration_person_with_parent_and_existing_main(
self, limit=None, id=False
):
partner_profile_position = self.env.ref("partner_profiles.partner_profile_position")
# Person migration with parent_id
search_values = self._get_concerned_partners_search_values(
id,
with_parent=True,
)
partners = self.env["res.partner"].search(search_values, limit=limit)
_logger.debug("Person migration with parent_id - migration count: %s" % len(partners))
count = 0
for partner in partners:
_logger.debug("count: [%s] : %s" % (count, partner.name))
existing_main_partner = self.env["res.partner"].search(
self._get_main_partner_search_values(partner),
limit=1,
)
if existing_main_partner:
_logger.debug("UPDATE Position")
partner.write(
{
"contact_id": existing_main_partner.id,
"partner_profile": partner_profile_position.id,
}
)
count += 1
_logger.debug("### End migration ###")
def _get_create_main_partner_values(self, partner):
partner_profile_main = self.env.ref("partner_profiles.partner_profile_main")
return {
"partner_profile": partner_profile_main.id,
"company_id": partner.company_id.id,
"parent_id": False,
"name": partner.name,
}
@api.model
def _migration_person_with_parent_not_existing_main(
self, limit=None, id=False
):
partners = self.env["res.partner"]
partner_profile_position = self.env.ref("partner_profiles.partner_profile_position")
# Person migration with parent_id
search_values = self._get_concerned_partners_search_values(
id,
with_parent=True,
)
partners = self.env["res.partner"].search(search_values, limit=limit)
_logger.debug("Person migration with parent_id - migration count: %s" % len(partners))
count = 0
for partner in partners:
_logger.debug("count: [%s] : %s" % (count, partner.name))
existing_main_partner = self.env["res.partner"].search(
self._get_main_partner_search_values(partner),
limit=1,
)
if not existing_main_partner:
default_values = self._get_create_main_partner_values(partner)
try:
main_partner = partner.copy(default=default_values)
except Exception as e:
_logger.debug("Email exist ! try with empty email")
default_values["email"] = ""
main_partner = partner.copy(default=default_values)
_logger.debug(
"count: [%s] %s -> [%s] %s "
% (partner.id, partner.name, main_partner.id, main_partner.name)
)
partner.write(
{
"partner_profile": partner_profile_position.id,
"contact_id": main_partner.id,
"type": "other",
}
)
count += 1
_logger.debug("Last clean")

View File

@@ -0,0 +1,4 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_partner_profile_public,partner_profile_public,model_partner_profile,,1,0,0,0
access_partner_profile_admin,partner_profile_admin,model_partner_profile,base.group_partner_manager,1,1,1,1
access_create_position_profile,create_position_profile_admin,model_create_position_profile,base.group_partner_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_partner_profile_public partner_profile_public model_partner_profile 1 0 0 0
3 access_partner_profile_admin partner_profile_admin model_partner_profile base.group_partner_manager 1 1 1 1
4 access_create_position_profile create_position_profile_admin model_create_position_profile base.group_partner_manager 1 1 1 1

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="partner_profile_view_tree" model="ir.ui.view">
<field name="name">partner.profile.view.tree</field>
<field name="model">partner.profile</field>
<field name="arch" type="xml">
<tree string="Partner profiles">
<field name="name" />
<field name="ref" />
</tree>
</field>
</record>
<record id="partner_profile_action" model="ir.actions.act_window">
<field name="name">Partner Profiles</field>
<field name="res_model">partner.profile</field>
<field name="view_mode">tree</field>
</record>
<menuitem id="menu_partner_profiles" action="partner_profile_action"
parent="contacts.res_partner_menu_config" sequence="1" name="Partner profiles"
groups="base.group_no_one" />
</odoo>

View File

@@ -0,0 +1,261 @@
<?xml version="1.0"?>
<odoo>
<data>
<record id="partner_profiles_form_view" model="ir.ui.view">
<field name="name">Partner Profiles Form View</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="priority" eval="99" />
<field name="arch" type="xml">
<!-- ################### -->
<!-- MAIN DISPLAY UPDATE -->
<!-- ################### -->
<xpath expr="//field[@name='name']" position="after">
<p class="oe_read_only" style="font-size:small; font-style:italic"
attrs="{'invisible': [('is_main_profile','=',False)]}">Main Profile</p>
<p class="oe_read_only" style="font-size:small; font-style:italic"
attrs="{'invisible': [('is_public_profile','=',False)]}">Public Profile</p>
<p class="oe_read_only" style="font-size:small; font-style:italic"
attrs="{'invisible': [('is_position_profile','=',False)]}">Position Profile</p>
</xpath>
<xpath expr="//field[@name='parent_id']" position="replace" />
<xpath expr="//field[@name='is_company']/.." position="after">
<group name="profile_data" class="bg-200">
<field name="partner_profile" readonly="1" invisible="1" />
<field name="is_main_profile" readonly="1" invisible="1" />
<field name="is_public_profile" readonly="1" invisible="1" />
<field name="is_position_profile" readonly="1" invisible="1" />
<group name="profile_status">
<field name="contact_id" widget="res_partner_many2one"
string="Main Profile" readonly="1"
attrs="{'invisible': [('is_main_profile','=',True)]}" />
<field name="parent_id" widget="res_partner_many2one"
placeholder="Company" domain="[('is_company', '=', True)]"
context="{'default_is_company': True, 'show_vat': True}"
attrs="{'invisible': ['|',('is_company', '=', True),'|',('contact_type','=','standalone'),('is_public_profile','=',True)]}"
readonly="1" />
<label for="public_profile_id"
attrs="{'invisible': [('is_main_profile','=',False)]}" />
<div class="o_row"
attrs="{'invisible': [('is_main_profile','=',False)]}">
<field name="public_profile_id" readonly="1" />
<button type="object" name="create_public_profile"
string="Create Public Profile"
attrs="{'invisible': [('public_profile_id','!=',False)]}" />
<button string="Sync data"
name="sync_admin_and_public_data" type="object"
icon="fa-refresh"
attrs="{'invisible': [('public_profile_id','=',False)]}" />
</div>
</group>
</group>
</xpath>
<!-- page Contacts & Adresses -->
<xpath
expr="//field[@name='child_ids']/form/sheet/group/group/field[@name='contact_type']"
position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath
expr="//field[@name='child_ids']" position="before">
<div class="alert alert-info" role="alert" style="margin-bottom:0px;"
attrs="{'invisible': [('is_company','=', False)]}">
<span>Please find here <strong>all</strong> the addresses/contacts linked to
this main profile. Contact creation from this tab <strong>only
generates new main profiles</strong>.</span>
</div>
<div class="alert alert-info" role="alert" style="margin-bottom:0px;"
attrs="{'invisible': [('is_company','=', True)]}">
<span>Please find here <strong>all</strong> the addresses linked with this
main profile. Adress creation from this tab <strong>only
generates new main profiles</strong>.</span>
</div>
</xpath>
<!-- page Structure's position -->
<xpath expr="//page[@name='other_position']" position="after">
<page name="structure_positions" string="Positions"
attrs="{'invisible': [('is_company','=', False)]}">
<div class="alert alert-info" role="alert" style="margin-bottom:0px;">
<span>Please find here <strong>all the position profiles</strong> linked
to this main profile.</span>
</div>
<field name="structure_position_ids" mode="kanban"
domain="[('is_position_profile', '=', True)]">
<kanban create="false">
<field name="id" />
<field name="color" />
<field name="name" />
<field name="title" />
<field name="email" />
<field name="function" />
<field name="phone" />
<field name="mobile" />
<field name="avatar_128" />
<templates>
<t t-name="kanban-box">
<t t-set="color"
t-value="kanban_color(record.color.raw_value)" />
<div
t-att-class="color + (record.title.raw_value == 1 ? ' oe_kanban_color_alert' : '') + ' oe_kanban_global_click'">
<div class="o_kanban_image">
<img alt="" t-if="record.avatar_128.raw_value"
t-att-src="kanban_image('res.partner', 'avatar_128', record.id.raw_value)" />
</div>
<div class="oe_kanban_details">
<field name="name" />
<div t-if="record.function.raw_value">
<field name="function" />
</div>
<div t-if="record.email.raw_value">
<field name="email" widget="email" />
</div>
<div t-if="record.phone.raw_value">Phone: <field
name="phone" widget="phone" /></div>
<div t-if="record.mobile.raw_value">Mobile: <field
name="mobile" widget="phone" /></div>
</div>
</div>
</t>
</templates>
</kanban>
</field>
<button name="%(action_create_position_profile_wizard)d"
string="Create New Position"
class="oe_highlight" type="action"
attrs="{'invisible': [('is_main_profile','=',False)]}" />
</page>
</xpath>
<!-- page Other Positions -->
<xpath expr="//page[@name='other_position']" position="attributes">
<attribute name="attrs">{'invisible': [('is_company','=',True)]}</attribute>
</xpath>
<xpath expr="//page[@name='other_position']" position="attributes">
<attribute name="string">Positions</attribute>
</xpath>
<xpath expr="//page[@name='other_position']/field[@name='other_contact_ids']/form"
position="replace" />
<xpath expr="//field[@name='other_contact_ids']" position="before">
<div class="alert alert-info" role="alert" style="margin-bottom:0px;">
<span>Please find here <strong>all the position profiles</strong> linked to
this main profile.</span>
</div>
</xpath>
<xpath expr="//field[@name='other_contact_ids']" position="after">
<button name="%(action_create_position_profile_wizard)d"
string="Create New Position"
class="oe_highlight" type="action"
attrs="{'invisible': [('is_main_profile','=',False)]}" />
</xpath>
<!-- #################################### -->
<!-- PUBLIC AND POSITION PROFILES DISPLAY -->
<!-- #################################### -->
<xpath expr="//div[@name='button_box']" position="attributes">
<attribute name="attrs">{'invisible': ['|', ('is_public_profile','=', True),
('is_position_profile','=', True)]}</attribute>
</xpath>
<xpath expr="//field[@name='company_type']" position="attributes">
<attribute name="attrs">{'invisible': ['|', ('is_public_profile','=', True),
('is_position_profile','=', True)]}</attribute>
</xpath>
<xpath expr="//field[@name='avatar_128']" position="attributes">
<attribute name="attrs">{'invisible': ['|', ('is_public_profile','=', True),
('is_position_profile','=', True)]}</attribute>
</xpath>
<xpath expr="//notebook" position="attributes">
<attribute name="attrs">{'invisible': ['|', ('is_public_profile','=', True),
('is_position_profile','=', True)]}</attribute>
</xpath>
<xpath expr="//field[@name='type']/../.." position="attributes">
<attribute name="attrs">{'invisible': ['|', ('is_public_profile','=', True),
('is_position_profile','=', True)]}</attribute>
</xpath>
<!-- ###################### -->
<!-- PUBLIC PROFILE DISPLAY -->
<!-- ###################### -->
<xpath expr="//field[@name='type']/../.." position="after">
<group id="public_data" attrs="{'invisible': [('is_public_profile','=',False)]}">
<group>
<label for="street" string="Address" />
<div class="o_address_format">
<field name="street" placeholder="Street..."
class="o_address_street"
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}" />
<field name="street2" placeholder="Street 2..."
class="o_address_street"
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}" />
<field name="city" placeholder="City" class="o_address_city"
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}" />
<field name="state_id" class="o_address_state" placeholder="State"
options='{"no_open": True}'
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}"
context="{'country_id': country_id, 'zip': zip}" />
<field name="zip" placeholder="ZIP" class="o_address_zip"
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}" />
<field name="country_id" placeholder="Country"
class="o_address_country"
options='{"no_open": True, "no_create": True}'
attrs="{'readonly': [('type', '=', 'contact'),('parent_id', '!=', False)]}" />
</div>
</group>
</group>
</xpath>
<!-- ######################## -->
<!-- POSITION PROFILE DISPLAY -->
<!-- ######################## -->
<xpath expr="//field[@name='category_id']/../.." position="after">
<group id="position_data"
attrs="{'invisible': [('is_position_profile','=',False)]}">
<group>
<field name="comment" />
</group>
</group>
</xpath>
</field>
</record>
<record id="partner_profiles_kanban_view" model="ir.ui.view">
<field name="name">Partner Profiles Kanban View</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.res_partner_kanban_view" />
<field name="priority" eval="99" />
<field name="arch" type="xml">
<xpath expr="//kanban" position="inside">
<field name="is_main_profile" />
<field name="is_public_profile" />
<field name="is_position_profile" />
</xpath>
<xpath
expr="//div[hasclass('oe_kanban_details')]/div/div[hasclass('o_kanban_tags_section')]"
position="before">
<div>
<span attrs="{'invisible': [('is_main_profile','=',False)]}"
style="color:#7c7bad;">
<b>Main profile</b>
</span>
<span attrs="{'invisible': [('is_public_profile','=',False)]}"
style="color:#7c7bad;">
<b>Public profile</b>
</span>
<span attrs="{'invisible': [('is_position_profile','=',False)]}"
style="color:#7c7bad;">
<b>Position profile</b>
</span>
</div>
</xpath>
</field>
</record>
<record id="sync_public_data_action_server" model="ir.actions.server">
<field name="name">Synchronize main and public data</field>
<field name="model_id" ref="model_res_partner" />
<field name="groups_id" eval="[(4,ref('base.group_no_one'))]" />
<field name="state">code</field>
<field name="code">records.sync_admin_and_public_data() </field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,2 @@
from . import create_position_profile

View File

@@ -0,0 +1,65 @@
# Copyright 2022 Elabore (https://elabore.coop)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class CreatePositionProfile(models.TransientModel):
_name = "create.position.profile"
_description = "create Position Profile"
@api.model
def _default_is_company(self):
return self.env['res.partner'].browse(self._context.get('active_ids')).is_company
@api.model
def _default_structure_id(self):
current_partner_id = self.env['res.partner'].browse(self._context.get('active_ids'))
if current_partner_id.is_company:
return current_partner_id.id
else:
return None
@api.model
def _default_partner_id(self):
current_partner_id = self.env['res.partner'].browse(self._context.get('active_ids'))
if not current_partner_id.is_company:
return current_partner_id.id
else:
return None
is_company = fields.Boolean('Is Company', default=_default_is_company)
structure_id = fields.Many2one('res.partner', string='Structure', domain="[('is_company', '=', True), ('is_main_profile', '=', True)]", default=_default_structure_id )
partner_id = fields.Many2one('res.partner', string='Person', domain="[('is_company', '=', False), ('is_main_profile', '=', True)]", default=_default_partner_id)
function = fields.Char('Function')
phone = fields.Char('Phone')
email = fields.Char('Email')
comment = fields.Text('Notes')
def _compute_position_profile_values(self):
values= {
"contact_id": self.partner_id.id,
"parent_id": self.structure_id.id,
"function": self.function,
"name": self.partner_id.name,
"phone": self.phone,
"email": self.email,
"comment" : self.comment,
"partner_profile": self.env.ref("partner_profiles.partner_profile_position").id
}
return values
def create_position_profile(self):
values = self._compute_position_profile_values()
position_partner_id = self.env["res.partner"].create(values)
view = self.env.ref("base.view_partner_form")
return {
"name": "Position Partner created",
"view_type": "form",
"view_mode": "form",
"view_id": view.id,
"res_model": "res.partner",
"type": "ir.actions.act_window",
"res_id": position_partner_id.id,
"context": self.env.context,
}

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="create_position_wizard_view_form" model="ir.ui.view">
<field name="name">create.position.wizard.view.form</field>
<field name="model">create.position.profile</field>
<field name="arch" type="xml">
<form string="Create a position profile">
<sheet>
<div class="alert alert-info" role="alert" style="margin-bottom:0px;">
<span>You are about to create a <strong>Position Profile</strong> which
represents the role or the job of a person in a structure.</span>
</div>
<group>
<field name="is_company" invisible="1" />
<field name="structure_id"
attrs="{'readonly': [('is_company','=',True)], 'required': [('is_company','=',False)]}" />
<field name="partner_id"
attrs="{'readonly': [('is_company','=',False)], 'required': [('is_company','=',True)]}" />
<field name="function" />
<field name="email" />
<field name="phone" />
<field name="comment" />
</group>
</sheet>
<footer>
<button string="Create" name="create_position_profile" type="object"
class="btn-primary" />
<button string="Cancel" class="btn-secondary" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_create_position_profile_wizard" model="ir.actions.act_window">
<field name="name">Create Position Profile</field>
<field name="res_model">create.position.profile</field>
<field name="view_mode">form</field>
<field name="view_id" ref="create_position_wizard_view_form" />
<field name="target">new</field>
</record>
<record id="action_create_position_profile_wizard" model="ir.actions.act_window">
<field name="name">Create Position Profile</field>
<field name="res_model">create.position.profile</field>
<field name="binding_model_id" ref="base.model_res_partner"/>
<field name="binding_view_types">list</field>
<field name="view_mode">form</field>
</record>
</odoo>