3 Commits

Author SHA1 Message Date
Stéphan Sainléger
96d11768b6 [MIG] partner_gogocarto_export_api: migrate to 18.0 2025-12-16 23:07:32 +01:00
Stéphan Sainléger
2dcd4c0f61 [MIG] partner_favorite: migrate to 18.0 2025-12-16 23:05:48 +01:00
Stéphan Sainléger
eaff63affa [MIG] partner_geolocalize_usability: migrate to 18.0 2025-12-16 23:04:56 +01:00
138 changed files with 6275 additions and 399 deletions

View File

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

View File

@@ -0,0 +1,20 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Partner Comcom',
'summary': "Ajoute la communauté de commune commme champ du partnenaire",
'version': "16.0.1.0.0",
'author': "Elabore",
'license': "AGPL-3",
'maintainer': 'Clément Thomas',
'category': 'Extra Tools',
'website': 'https://odoo-community.org/',
'depends': ['contacts'],
'data': [
'security/ir.model.access.csv',
'views/res_partner_views.xml',
'views/res_country_comcom_views.xml',
],
'auto_install': False,
'installable': True,
}

View File

@@ -0,0 +1,2 @@
from . import res_partner
from . import res_country_comcom

View File

@@ -0,0 +1,12 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import fields, models
_logger = logging.getLogger(__name__)
class ResCountryComcom(models.Model):
_name = 'res.country.comcom'
name = fields.Text('Nom')

View File

@@ -0,0 +1,12 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import fields, models
_logger = logging.getLogger(__name__)
class ResPartner(models.Model):
_inherit = 'res.partner'
comcom_id = fields.Many2one('res.country.comcom', string="Communauté de commune")

View File

@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
"access_res_country_comcom_group_user","res_country_comcom group_user","model_res_country_comcom",base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_res_country_comcom_group_user res_country_comcom group_user model_res_country_comcom base.group_user 1 1 1 1

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_country_comcom_tree" model="ir.ui.view">
<field name="name">Comcom tree</field>
<field name="model">res.country.comcom</field>
<field name="arch" type="xml">
<tree string="Communautés de communes" editable="bottom">
<field name="name" />
</tree>
</field>
</record>
<record id="action_country_comcom" model="ir.actions.act_window">
<field name="name">Communautés de commune</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">res.country.comcom</field>
</record>
<menuitem id="menu_country_comcom"
action="action_country_comcom"
name="Communautés de communes"
sequence="1" parent="contacts.menu_localisation"/>
</odoo>

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partner_form_comcom" model="ir.ui.view">
<field name="name">Partner Form: add comcom</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<data>
<field name="city" position="after">
<field name="comcom_id" class="o_address_street" placeholder="Communauté de communes" />
</field>
</data>
</field>
</record>
<record id="view_partner_search_comcom" model="ir.ui.view">
<field name="name">Partner search: add comcom</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field name="arch" type="xml">
<data>
<field name="user_id" position="after">
<separator />
<field name="comcom_id" />
</field>
</data>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,18 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Partner Complementary Contact Data View",
"summary": "Add extra_contact_ids in dedicated notebook page",
"version": "16.0.1.0.1",
"author": "Stéphan Sainléger",
"license": "AGPL-3",
"maintainer": "Elabore",
"category": "Partner Tools",
"website": "https://odoo-community.org/",
"depends": ["complementary_contact_data"],
"data": [
"views/res_partner_views.xml",
],
"auto_install": False,
"installable": True,
}

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partner_form_skills" model="ir.ui.view">
<field name="name">Add extra_contact_ids in dedicated notebook page</field>
<field name="model">res.partner</field>
<field name="priority">99</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='extra_contact_ids']" position="replace" />
<xpath expr="//notebook/page[1]" position="before">
<!-- page Social Networks -->
<page name="social" string="Social networks">
<field name="extra_contact_ids" widget="contactInfoWidget" nolabel="True"
colspan="1" />
</page>
</xpath>
</field>
</record>
</odoo>

View File

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

View File

@@ -0,0 +1,21 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Partner Favorite',
'summary': "Add favorite star on Partner, and filter for favorite",
'version': "18.0.1.0.0",
'author': "Nicolas JEUDY, "
"Myceliandre, "
"Lokavaluto, "
"Odoo Community Association (OCA)",
'license': "AGPL-3",
'maintainer': 'Nicolas JEUDY',
'category': 'Extra Tools',
'website': 'https://odoo-community.org/',
'depends': ['base'],
'data': [
'views/res_partner.xml',
],
'auto_install': False,
'installable': True,
}

View File

@@ -0,0 +1,45 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_favorite
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2021-05-10 20:53+0000\n"
"PO-Revision-Date: 2021-05-10 20:53+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_favorite
#: model:ir.model,name:partner_favorite.model_res_partner
msgid "Contact"
msgstr "Contact"
#. module: partner_favorite
#: model:ir.model.fields,help:partner_favorite.field_res_partner__is_favorite
#: model:ir.model.fields,help:partner_favorite.field_res_users__is_favorite
msgid "Display this partner with favorite filter"
msgstr "Afficher les partenaires favoris"
#. module: partner_favorite
#: model:ir.model.fields,field_description:partner_favorite.field_res_partner__favorite_user_ids
#: model:ir.model.fields,field_description:partner_favorite.field_res_users__favorite_user_ids
msgid "Members"
msgstr "Membres"
#. module: partner_favorite
#: model_terms:ir.ui.view,arch_db:partner_favorite.view_partner_search_favorite
msgid "My Favorites"
msgstr "Mes favoris"
#. module: partner_favorite
#: model:ir.model.fields,field_description:partner_favorite.field_res_partner__is_favorite
#: model:ir.model.fields,field_description:partner_favorite.field_res_users__is_favorite
msgid "Show Favorite Partner"
msgstr "Afficher les partenaire favoris"

View File

@@ -0,0 +1 @@
from . import res_partner

View File

@@ -0,0 +1,39 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo import fields, models
_logger = logging.getLogger(__name__)
class ResPartner(models.Model):
"""Adds last name and first name; name becomes a stored function field."""
_inherit = 'res.partner'
def _compute_is_favorite(self):
for partner in self:
partner.is_favorite = self.env.user in partner.favorite_user_ids
def _inverse_is_favorite(self):
favorite_partners = not_fav_partners = self.env['res.partner']
for partner in self:
if self.env.user in partner.favorite_user_ids:
favorite_partners |= partner
else:
not_fav_partners |= partner
# partner User has no write access for partner.
not_fav_partners.write({'favorite_user_ids': [(4, self.env.uid)]})
favorite_partners.write({'favorite_user_ids': [(3, self.env.uid)]})
def _get_default_favorite_user_ids(self):
return [(6, 0, [self.env.uid])]
favorite_user_ids = fields.Many2many(
'res.users', 'partner_favorite_user_rel', 'partner_id', 'user_id',
default=_get_default_favorite_user_ids,
string='Members')
is_favorite = fields.Boolean(
compute='_compute_is_favorite',
inverse='_inverse_is_favorite',
string='Show Favorite Partner',
help="Display this partner with favorite filter")

View File

@@ -0,0 +1 @@
N/A

View File

@@ -0,0 +1 @@
* Nicolas JEUDY <https://github.com/njeudy>

View File

@@ -0,0 +1,2 @@
This module was written to extend the functionality of contacts to support
having favorite mechanism.

View File

@@ -0,0 +1 @@
* add filters

View File

@@ -0,0 +1 @@
After installing this module you can select a partner as favorite and filter on "My favorite".

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partner_form_favorite" model="ir.ui.view">
<field name="name">Add favorite star</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.res_partner_kanban_view"/>
<field name="arch" type="xml">
<data>
<field name="type" position="after">
<field name="is_favorite"/>
</field>
<xpath expr="//strong/field[@name='display_name']" position="before">
<span class="o_right"><field name="is_favorite" widget="boolean_favorite" nolabel="1" force_save="1" /></span>
</xpath>
</data>
</field>
</record>
<record id="view_partner_search_favorite" model="ir.ui.view">
<field name="name">Add favorite star</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter"/>
<field name="arch" type="xml">
<data>
<filter name="type_person" position="before">
<filter string="My Favorites" name="my_partners" domain="[('favorite_user_ids', 'in', uid)]"/>
<separator />
</filter>
</data>
</field>
</record>
</odoo>

View File

@@ -25,9 +25,9 @@
name="geo_localize"
colspan="2"
icon="fa-check"
type="object" invisible="manual_geolocate == True" />
<field name="partner_latitude" readonly="manual_geolocate == False" />
<field name="partner_longitude" readonly="manual_geolocate == False" />
type="object" attrs="{'invisible':[('manual_geolocate', '=', True)]}" />
<field name="partner_latitude" attrs="{'readonly':[('manual_geolocate', '=', False)]}" />
<field name="partner_longitude" attrs="{'readonly':[('manual_geolocate', '=', False)]}" />
</group>
</page>
</xpath>

View File

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

View File

@@ -0,0 +1,66 @@
============================
partner_gogocarto_export_api
============================
Gogocarto Export module, to export the partner data needed for a Gogocarto map.
This module allow the users to decide:
* the partners to be exported
* the fields exported for each partner (*name*, *partner_longitude* and *partner_lattitude* automatically exported)
Installation
============
Use Odoo normal module installation procedure to install
``partner_gogocarto_export_api``, all dependencies will be installed by default.
Configuration
=============
To export partners data:
#. Set the fields you want to export in Settings / Gogocarto.
#. Check the field *"Export to Gogocarto"* in the partner form view.
And use the link *https://yourodoo.com/web/<company_id>/get_http_gogocarto_elements* in Gogocarto server import configuration (*https://video.colibris-outilslibres.org/videos/watch/c74fc469-c822-4ab8-82a7-a2555e49e576*)
Known issues / Roadmap
======================
None yet.
Bug Tracker
===========
Bugs are tracked on `our issues website <https://github.com/elabore-coop/partner-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 SAINLEGER <https://github.com/stephansainleger>
* Chloé Migayrou <https://github.com/MigayrouChloe>
* Nicolas Jeudy <https://github.com/njeudy>
* Lokavaluto Teams <https://lokavaluto.fr>
Funders
-------
The development of this module has been financially supported by:
* Lokavaluto (https://lokavaluto.fr)
* Mycéliandre (https://myceliandre.fr)
* Elabore (https://elabore.coop)
Maintainer
----------
This module is maintained by Elabore and Lokavaluto.

View File

@@ -0,0 +1,2 @@
from . import controllers
from . import models

View File

@@ -0,0 +1,28 @@
{
'name': 'partner_gogocarto_export_api',
'summary': '''HTTP JSON api to send partner data for Gogocarto import''',
'license': 'AGPL-3',
'author': (
'Lokavaluto',
'Elabore'
),
'website': 'https://lokavaluto.fr',
'category': 'Localization',
'version': "18.0.1.0.0",
'depends': [
'base',
'contacts',
'base_geolocalize',
'partner_geolocalize_usability',
'jsonifier',
'server_action_mass_edit',
],
'data': [
'views/gogocarto_partner.xml',
'views/gogocarto_config_settings_view.xml',
'views/res_company_view.xml',
],
'demo': [],
'installable': True,
'auto_install': False,
}

View File

@@ -0,0 +1 @@
from . import main

View File

@@ -0,0 +1,29 @@
import json
import logging
from odoo import http
from odoo.http import Response, request
_logger = logging.getLogger(__name__)
class PartnerGogocartojs(http.Controller):
@http.route(
'/web/<company_id>/get_http_gogocarto_elements',
methods=['GET'],
type='http',
csrf=False,
auth="public",
website=True)
def get_gogocarto_elements_http(self, company_id):
data = self._jsonify_get_partner(company_id)
return Response(json.dumps(data))
def _jsonify_get_partner(self, company_id):
PartnerSudo = request.env['res.partner'].sudo()
parser = PartnerSudo._get_gogocarto_parser(company_id)
partners = PartnerSudo.with_context(force_company=company_id).search(
PartnerSudo._get_gogocarto_domain(company_id)
)
return partners.jsonify(parser)

View File

@@ -0,0 +1,77 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_gogocarto_export_api
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2024-11-21 08:46+0000\n"
"PO-Revision-Date: 2024-11-21 08:46+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_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_config_settings_view_form_gogocarto
msgid "Check the export on /web/{COMPANY_ID}/get_http_gogocarto_elements."
msgstr "Vérifiez l'export sur /web/{COMPANY_ID}/get_http_gogocarto_elements.\""
#. module: partner_gogocarto_export_api
#: model:ir.model,name:partner_gogocarto_export_api.model_res_company
msgid "Companies"
msgstr "Sociétés"
#. module: partner_gogocarto_export_api
#: model:ir.model,name:partner_gogocarto_export_api.model_res_config_settings
msgid "Config Settings"
msgstr "Paramètres de configuration"
#. module: partner_gogocarto_export_api
#: model:ir.model,name:partner_gogocarto_export_api.model_res_partner
msgid "Contact"
msgstr ""
#. module: partner_gogocarto_export_api
#: model:ir.model.fields,field_description:partner_gogocarto_export_api.field_res_company__export_gogocarto_fields
msgid "Export Gogocarto Fields"
msgstr "Champs exportés dans Gogocarto"
#. module: partner_gogocarto_export_api
#: model:ir.model.fields,field_description:partner_gogocarto_export_api.field_res_partner__in_gogocarto
#: model:ir.model.fields,field_description:partner_gogocarto_export_api.field_res_users__in_gogocarto
msgid "Export to Gogocarto"
msgstr "Exporter dans Gogocarto"
#. module: partner_gogocarto_export_api
#: model:ir.model.fields,field_description:partner_gogocarto_export_api.field_res_config_settings__export_gogocarto_fields
msgid "GogoCarto Exported fields"
msgstr "Champs exportés dans Gogocarto"
#. module: partner_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_company_gogocarto_form_view
msgid "GogoCarto Setup"
msgstr "Gogocarto"
#. module: partner_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_config_settings_view_form_gogocarto
msgid "Gogocarto"
msgstr ""
#. module: partner_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_config_settings_view_form_gogocarto
msgid "Gogocarto export configuration"
msgstr "Configuration de l'export Gogocarto"
#. module: partner_gogocarto_export_api
#: model:ir.actions.server,name:partner_gogocarto_export_api.mass_editing_partner
msgid "Mass Edit In Gogocarto Field"
msgstr "Exporter dans Gogocarto"
#. module: partner_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_config_settings_view_form_gogocarto
msgid "Partner fields to export for Gogocarto map."
msgstr "Champs de contact à exporter vers Gogocarto."

View File

@@ -0,0 +1,73 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_gogocarto_export_api
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-12 14:00+0000\n"
"PO-Revision-Date: 2023-09-12 14:00+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_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_config_settings_view_form_gogocarto
msgid "Check the export on /web/{COMPANY_ID}/get_http_gogocarto_elements."
msgstr ""
#. module: partner_gogocarto_export_api
#: model:ir.model,name:partner_gogocarto_export_api.model_res_company
msgid "Companies"
msgstr ""
#. module: partner_gogocarto_export_api
#: model:ir.model,name:partner_gogocarto_export_api.model_res_config_settings
msgid "Config Settings"
msgstr ""
#. module: partner_gogocarto_export_api
#: model:ir.model,name:partner_gogocarto_export_api.model_res_partner
msgid "Contact"
msgstr ""
#. module: partner_gogocarto_export_api
#: model:ir.model.fields,field_description:partner_gogocarto_export_api.field_res_company__export_gogocarto_fields
msgid "Export Gogocarto Fields"
msgstr ""
#. module: partner_gogocarto_export_api
#: model:ir.model.fields,field_description:partner_gogocarto_export_api.field_res_partner__in_gogocarto
#: model:ir.model.fields,field_description:partner_gogocarto_export_api.field_res_users__in_gogocarto
msgid "Export to Gogocarto"
msgstr ""
#. module: partner_gogocarto_export_api
#: model:ir.model.fields,field_description:partner_gogocarto_export_api.field_res_config_settings__export_gogocarto_fields
msgid "GogoCarto Exported fields"
msgstr ""
#. module: partner_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_company_gogocarto_form_view
msgid "GogoCarto Setup"
msgstr ""
#. module: partner_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_config_settings_view_form_gogocarto
msgid "Gogocarto"
msgstr ""
#. module: partner_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_config_settings_view_form_gogocarto
msgid "Gogocarto export configuration"
msgstr ""
#. module: partner_gogocarto_export_api
#: model_terms:ir.ui.view,arch_db:partner_gogocarto_export_api.res_config_settings_view_form_gogocarto
msgid "Partner fields to export for Gogocarto map."
msgstr ""

View File

@@ -0,0 +1,3 @@
from . import res_partner
from . import res_config_settings
from . import company

View File

@@ -0,0 +1,13 @@
from odoo import models, fields
class Company(models.Model):
_inherit = "res.company"
export_gogocarto_fields = fields.Many2many(
'ir.model.fields',
domain=[
('model_id', '=', 'res.partner'),
('name', 'not in', ['id', 'name', 'partner_longitude', 'partner_latitude'])
]
)

View File

@@ -0,0 +1,23 @@
import logging
from odoo import fields, models
_logger = logging.getLogger(__name__)
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
export_gogocarto_fields = fields.Many2many(
related='company_id.export_gogocarto_fields',
relation='ir.model.fields',
string='GogoCarto Exported fields',
readonly=False,
domain=[
('model_id', '=', 'res.partner'),
('name', 'not in', ['name',
'partner_longitude',
'partner_latitude',
'id'])
]
)

View File

@@ -0,0 +1,49 @@
from odoo import models, fields
class ResPartner(models.Model):
""" Inherits partner, adds Gogocarto fields in the partner form, and functions"""
_inherit = 'res.partner'
in_gogocarto = fields.Boolean('Export to Gogocarto')
def _get_gogocarto_domain(self, company_id):
# To OVERRIDE in sub_modules to customize the partner selection
return [('in_gogocarto', '=', True)]
def _get_generic_parser(self, fields):
parser = []
for field in fields:
if field.ttype in [
"boolean",
"char",
"integer",
"monetary",
"text",
"selection",
"float",
"date_time",
"date",
"html"]:
parser.append(field.name)
elif field.ttype in ["many2one", "one2many", "many2many"]:
parser.append((field.name, ['id', 'name']))
elif field.ttype == "binary":
continue
else:
continue
return parser
def _get_gogocarto_parser(self, company_id):
fields = self._get_export_fields(company_id)
parser = self._get_generic_parser(fields)
return parser
def _get_export_fields(self, company_id):
CompanySudo = self.env['res.company'].sudo().search([('id', '=', company_id)])
default_fields = self.env['ir.model.fields'].sudo().search([
('model_id', '=', 'res.partner'),
('name', 'in', ['id', 'name', 'partner_longitude', 'partner_latitude'])])
company_fields = CompanySudo.export_gogocarto_fields
export_fields = default_fields | company_fields
return export_fields

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="res_config_settings_view_form_gogocarto" model="ir.ui.view">
<field name="name">res.config.settings.view.form.inherit.gogocarto</field>
<field name="model">res.config.settings</field>
<field name="priority" eval="99" />
<field name="inherit_id" ref="base.res_config_settings_view_form" />
<field name="arch" type="xml">
<xpath expr="//div[hasclass('settings')]" position="inside">
<div class="app_settings_block" data-string="Gogocarto" string="Gogocarto"
data-key="partner_gogocarto_export_api">
<h2>Gogocarto export configuration</h2>
<div class="text-muted mt16 o_settings_container">
Check the export on /web/{COMPANY_ID}/get_http_gogocarto_elements.
</div>
<div class="row mt16 o_settings_container" id="gogocarto_selection_settings">
<div class="col-12 col-lg-6 o_setting_box" id="gogocarto_fields">
<div class="o_setting_right_pane">
<div class="text-muted">
Partner fields to export for Gogocarto map.
</div>
<div class="content-group">
<div class="mt16">
<field name="export_gogocarto_fields"
widget="many2many_tags"
options="{'no_create': True, 'no_open': True}" />
</div>
</div>
</div>
</div>
</div>
</div>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record model="ir.ui.view" id="partner_gogocarto_form_view">
<field name="name">partner.gogocarto.form</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="partner_geolocalize_usability.partner_geolocalize_form_view" />
<field name='priority'>99</field>
<field name="arch" type="xml">
<xpath expr="//page[@name='geolocalize']/group" position="inside">
<field name="in_gogocarto" />
</xpath>
</field>
</record>
<!-- Mass Edit Partner field in_gogocarto -->
<record id="mass_editing_partner" model="ir.actions.server">
<field name="state">mass_edit</field>
<field name="name">Mass Edit In Gogocarto Field</field>
<field name="model_id" ref="base.model_res_partner" />
</record>
<record id="mass_editing_partner_in_gogocarto" model="ir.actions.server.mass.edit.line" >
<field name="server_action_id" ref="mass_editing_partner" />
<field name="field_id" ref="partner_gogocarto_export_api.field_res_partner__in_gogocarto" />
</record>
<!-- Add context actions -->
<function model="ir.actions.server" name="create_action">
<value eval="[ref('mass_editing_partner')]" />
</function>
</odoo>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record model="ir.ui.view" id="res_company_gogocarto_form_view">
<field name="name">res_company.gogocarto.form</field>
<field name="model">res.company</field>
<field name="inherit_id" ref="base.view_company_form"/>
<field name='priority'>99</field>
<field name="arch" type="xml">
<xpath expr="//notebook" posiion="inside">
<page string="GogoCarto Setup" name="gogocarto">
<group>
<field name="export_gogocarto_fields"/>
</group>
</page>
</xpath>
</field>
</record>
</odoo>

View File

@@ -1,150 +0,0 @@
================================
Partner Phone Country Validation
================================
This module enhances phone number handling on partners by adding automatic
country detection from phone numbers and enforcing country consistency.
It extends the standard ``phone_validation`` module and the OCA ``base_phone``
module to provide additional features for phone number management.
**Table of contents**
.. contents::
:local:
Features
========
Automatic Phone Number Normalization
------------------------------------
When entering a phone number, the module automatically converts numbers
starting with ``00`` to the international ``+`` format:
* ``0033 6 12 34 56 78````+33 6 12 34 56 78``
* ``0041 76 123 45 67````+41 76 123 45 67``
This normalization happens before the standard formatting, ensuring
compatibility with the ``phonenumbers`` library.
Automatic Country Detection
---------------------------
When a phone number with an international prefix (``+xx``) is entered and
the partner has no country set, the module automatically detects and sets
the country based on the phone number prefix:
* Enter ``+33 6 12 34 56 78`` → Country is set to **France**
* Enter ``+32 4 123 45 67`` → Country is set to **Belgium**
* Enter ``+41 76 123 45 67`` → Country is set to **Switzerland**
This works for both ``phone`` and ``mobile`` fields.
Country Validation Constraint
-----------------------------
The module enforces that a country must be set on the partner if a phone
or mobile number is present. This ensures data consistency and allows
proper phone number formatting.
If you try to save a partner with a phone number but no country, a
validation error will be raised.
How It Works
============
The module overrides the ``_onchange_phone_validation`` and
``_onchange_mobile_validation`` methods from the standard ``phone_validation``
module. The processing order is:
1. **Normalize**: Convert ``00xx`` format to ``+xx`` international format
2. **Detect country**: If no country is set, detect it from the phone prefix
3. **Format**: Call the standard formatting (via ``super()``) which formats
the number according to the partner's country
When the country is changed on a partner, both phone and mobile numbers
are automatically reformatted to match the new country's format.
Dependencies
============
This module depends on:
* ``base``: Odoo base module
* ``base_phone``: OCA module providing the ``phone.validation.mixin``
(from `connector-telephony <https://github.com/OCA/connector-telephony>`_)
The ``base_phone`` module itself depends on the standard ``phone_validation``
module which uses the `phonenumbers <https://github.com/daviddrysdale/python-phonenumbers>`_
Python library.
Installation
============
1. Install the ``base_phone`` module from the OCA ``connector-telephony`` repository
2. Install this module using the standard Odoo module installation procedure
Configuration
=============
No configuration is required. The module works automatically once installed.
Known Issues / Limitations
==========================
National Numbers Without International Prefix
---------------------------------------------
When changing a partner's country, phone numbers in **national format**
(without international prefix) may not be reformatted if they are not
valid for the new country.
For example:
* A French mobile ``06 12 34 56 78`` (without ``+33``) cannot be reformatted
to a Belgian format because ``06`` is not a valid Belgian mobile prefix.
* The ``phonenumbers`` library validates numbers and will keep the original
format if the number is invalid for the target country.
**Recommendation**: Always use international format (``+xx``) for phone numbers
to ensure proper handling when countries change.
Bug Tracker
===========
Bugs are tracked on `Elabore Git Issues <https://git.elabore.coop/Elabore/partner-tools/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smash it by providing a detailed and welcomed
feedback.
Credits
=======
Authors
-------
* `Elabore <https://elabore.coop>`_
Contributors
------------
* Boris Gallet <boris.gallet@elabore.coop> (`GitHub <https://github.com/b0g>`_)
* Stéphan Sainléger <stephan.sainleger@elabore.coop>
Funders
-------
The development of this module has been financially supported by:
* `Elabore <https://elabore.coop>`_
Maintainer
----------
.. image:: https://elabore.coop/logo.png
:alt: Elabore
:target: https://elabore.coop
This module is maintained by Elabore.

View File

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

View File

@@ -1,54 +0,0 @@
from odoo import api, models, _
from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import (
get_country_from_phone_number,
)
from odoo.exceptions import ValidationError
class Partner(models.Model):
_name = "res.partner"
_inherit = ["res.partner", "phone.validation.mixin"]
@api.constrains("country_id", "phone", "mobile")
def _check_country_id(self):
for partner in self:
if not partner.country_id and (partner.phone or partner.mobile):
raise ValidationError(_("You must set a country for the phone number"))
def _normalize_phone_number(self, number):
"""Convert 00xx format to +xx international format."""
if number and number.startswith("00"):
return "+" + number[2:]
return number
def _set_country_from_phone_number(self, phone_number):
"""Auto-detect and set country from phone number prefix if not already set."""
if not phone_number or self.country_id:
return
country_code = get_country_from_phone_number(phone_number)
if country_code:
country = self.env["res.country"].search(
[("code", "=", country_code)], limit=1
)
if country:
self.country_id = country
@api.onchange("phone", "country_id", "company_id")
def _onchange_phone_validation(self):
# Normalize 00xx → +xx before standard processing
if self.phone:
self.phone = self._normalize_phone_number(self.phone)
# Auto-detect country if not set
self._set_country_from_phone_number(self.phone)
# Let standard module do the formatting
super()._onchange_phone_validation()
@api.onchange("mobile", "country_id", "company_id")
def _onchange_mobile_validation(self):
# Normalize 00xx → +xx before standard processing
if self.mobile:
self.mobile = self._normalize_phone_number(self.mobile)
# Auto-detect country if not set
self._set_country_from_phone_number(self.mobile)
# Let standard module do the formatting
super()._onchange_mobile_validation()

View File

@@ -1,4 +0,0 @@
# Copyright 2024 Elabore (https://elabore.coop)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import test_partner_phone_country_validation

View File

@@ -1,149 +0,0 @@
# Copyright 2024 Elabore (https://elabore.coop)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.exceptions import ValidationError
from odoo.tests import Form, TransactionCase
class TestPartnerPhoneCountryValidation(TransactionCase):
"""Tests for partner phone country validation module.
Note on testing @api.onchange methods:
--------------------------------------
In Odoo, @api.onchange methods are only triggered by the web UI, not by
direct field assignment in Python code.
- `partner.phone = "xxx"` → triggers write() → validates constraints
BEFORE any onchange can run → fails if constraint not met
- `Form(partner)` → simulates web UI behavior → triggers onchange methods
when field values change → onchange can set country BEFORE save
We use Form() for tests that need onchange behavior (auto-detection of
country from phone prefix), and direct create/write for constraint tests.
"""
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.env = cls.env(context=dict(cls.env.context, tracking_disable=True))
cls.country_fr = cls.env.ref("base.fr")
cls.country_be = cls.env.ref("base.be")
# Set company country to France for default formatting
cls.env.company.country_id = cls.country_fr
def test_normalize_00_to_plus(self):
"""Test conversion of 00xx format to +xx format."""
partner = self.env["res.partner"].create(
{"name": "Test Partner", "country_id": self.country_fr.id}
)
# 00 → + conversion
self.assertEqual(
partner._normalize_phone_number("0033612345678"), "+33612345678"
)
# + numbers unchanged
self.assertEqual(
partner._normalize_phone_number("+33612345678"), "+33612345678"
)
# National numbers unchanged
self.assertEqual(partner._normalize_phone_number("0612345678"), "0612345678")
# Edge cases
self.assertIsNone(partner._normalize_phone_number(None))
self.assertEqual(partner._normalize_phone_number(""), "")
def test_auto_country_detection(self):
"""Test automatic country detection from phone prefix."""
partner = self.env["res.partner"].create({"name": "Test Partner"})
self.assertFalse(partner.country_id)
partner._set_country_from_phone_number("+33612345678")
self.assertEqual(partner.country_id, self.country_fr)
def test_auto_country_detection_does_not_override(self):
"""Test that auto-detection does not override existing country."""
partner = self.env["res.partner"].create(
{"name": "Test Partner", "country_id": self.country_be.id}
)
partner._set_country_from_phone_number("+33612345678")
# Country should remain Belgium
self.assertEqual(partner.country_id, self.country_be)
def test_onchange_phone_full_flow(self):
"""Test complete onchange flow: 00→+ normalization, country detection, formatting.
Use Form to simulate UI behavior where onchange triggers before save.
"""
with Form(self.env["res.partner"]) as partner_form:
partner_form.name = "Test Partner"
partner_form.phone = "0033612345678"
# Onchange should have normalized and detected country
self.assertIn("+33", partner_form.phone)
self.assertEqual(partner_form.country_id, self.country_fr)
def test_onchange_mobile_full_flow(self):
"""Test complete onchange flow for mobile field."""
with Form(self.env["res.partner"]) as partner_form:
partner_form.name = "Test Partner"
partner_form.mobile = "0032475123456"
# Onchange should have normalized and detected country
self.assertIn("+32", partner_form.mobile)
self.assertEqual(partner_form.country_id, self.country_be)
def test_onchange_with_existing_country(self):
"""Test formatting with existing country uses that country."""
with Form(self.env["res.partner"]) as partner_form:
partner_form.name = "Test Partner"
partner_form.country_id = self.country_fr
partner_form.phone = "06 12 34 56 78"
# Should be formatted with French prefix
self.assertIn("+33", partner_form.phone)
def test_constraint_country_required_with_phone(self):
"""Test that country is required when phone/mobile is set."""
with self.assertRaises(ValidationError):
self.env["res.partner"].create(
{"name": "Test Partner", "phone": "0612345678"}
)
with self.assertRaises(ValidationError):
self.env["res.partner"].create(
{"name": "Test Partner", "mobile": "0612345678"}
)
def test_constraint_passes_without_phone(self):
"""Test that partner without phone doesn't require country."""
partner = self.env["res.partner"].create({"name": "Test Partner"})
self.assertTrue(partner.id)
self.assertFalse(partner.country_id)
class TestGetCountryFromPhoneNumber(TransactionCase):
"""Test the utility function for country detection."""
def test_valid_international_number(self):
"""Test detection from valid international number."""
from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import (
get_country_from_phone_number,
)
self.assertEqual(get_country_from_phone_number("+33612345678"), "FR")
def test_invalid_number_returns_false(self):
"""Test that invalid numbers return False."""
from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import (
get_country_from_phone_number,
)
self.assertFalse(get_country_from_phone_number("invalid"))
self.assertFalse(get_country_from_phone_number("0612345678"))
def test_national_number_without_prefix(self):
"""Test handling of national number without international prefix."""
from odoo.addons.partner_phone_country_validation.tools.get_country_from_phone_number import (
get_country_from_phone_number,
)
# National numbers without + cannot be reliably detected
result = get_country_from_phone_number("0612345678")
# phonenumbers cannot determine country without prefix
self.assertFalse(result)

View File

@@ -1 +0,0 @@
from . import get_country_from_phone_number

View File

@@ -1,25 +0,0 @@
import logging
_logger = logging.getLogger(__name__)
try:
import phonenumbers
def get_country_from_phone_number(number):
try:
number = phonenumbers.parse(number)
return phonenumbers.region_code_for_number(number)
except phonenumbers.phonenumberutil.NumberParseException:
return False
except ImportError:
def get_country_from_phone_number(number):
global _phonenumbers_lib_warning
if not _phonenumbers_lib_warning:
_logger.info(
"The `phonenumbers` Python module is not installed, contact numbers will not be "
"verified. Please install the `phonenumbers` Python module."
)
_phonenumbers_lib_warning = True
return number

View File

@@ -0,0 +1,18 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
"name": "Partner Phone and Email form widget",
"summary": "Add widget button for phone and email fields in partner form view",
"version": "16.0.1.0.0",
"author": "Stéphan Sainléger",
"license": "AGPL-3",
"maintainer": "Elabore",
"category": "Partner Tools",
"website": "https://odoo-community.org/",
"depends": ["contacts"],
"data": [
"views/res_partner_views.xml",
],
"auto_install": False,
"installable": True,
}

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_partner_form_phone_email_widgets" model="ir.ui.view">
<field name="name">Add phone and email widgets</field>
<field name="model">res.partner</field>
<field name="priority">99</field>
<field name="inherit_id" ref="base.view_partner_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='phone']" position="replace">
<label for="phone" />
<div class="o_row">
<field name="phone" widget="phone" />
<button type="action" name="137"
class="btn-sm btn-link mb4 fa fa-envelope-o" aria-label="Send SMS"
title="Send SMS" attrs="{'invisible':[('phone', '=', False)]}"
context="{'field_name': 'phone'}" />
</div>
</xpath>
<xpath expr="//field[@name='mobile']" position="replace">
<label for="mobile" />
<div class="o_row">
<field name="mobile" widget="phone" />
<button type="action" name="137"
class="btn-sm btn-link mb4 fa fa-envelope-o" aria-label="Send SMS"
title="Send SMS" attrs="{'invisible':[('mobile', '=', False)]}"
context="{'field_name': 'mobile'}" />
</div>
</xpath>
</field>
</record>
</odoo>

View File

@@ -0,0 +1,44 @@
=========================
partner_portal_visio_url
=========================
add visio url to user portal view
Installation
============
Use Odoo normal module installation procedure to install
``partner_portal_visio_url``.
Known issues / Roadmap
======================
None yet.
Bug Tracker
===========
Bugs are tracked on `our issues website <https://github.com/elabore-coop/partner-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
------------
* `Boris Gallet <mailto:boris.gallet@elabore.coop>`
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 @@
from . import models

View File

@@ -1,31 +1,25 @@
# Copyright 2024 Boris Gallet ()
# Copyright 2025 Boris Gallet ()
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "partner_phone_country_validation",
"version": "18.0.1.0.0",
"name": "partner_portal_extra_links",
"version": "16.0.1.0.0",
"author": "Elabore",
"website": "https://elabore.coop",
"maintainer": "Boris Gallet",
"license": "AGPL-3",
"category": "Tools",
"summary": "Format phone number according with country and select good country depending on phone if country empty",
"summary": "add extra links to user portal as visio url and wiki url",
# any module necessary for this one to work correctly
"depends": [
"base",
"base_phone"
],
"qweb": [],
"external_dependencies": {
"python": [],
},
# always loaded
"data": [
# "security/security.xml",
# "security/ir.model.access.csv",
# "views/menu.xml",
# "data/data.xml",
],
"data": ["views/res_partner_views.xml", "views/portal_my_home_template.xml"],
# only loaded in demonstration mode
"demo": [],
"js": [],
@@ -35,4 +29,4 @@
# and independently installed. Used for synergetic or glue modules.
"auto_install": False,
"application": False,
}
}

View File

@@ -0,0 +1,55 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_portal_extra_links
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 16.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2025-10-21 14:18+0000\n"
"PO-Revision-Date: 2025-10-21 14:18+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_portal_extra_links
#: model:ir.model,name:partner_portal_extra_links.model_res_partner
msgid "Contact"
msgstr ""
#. module: partner_portal_extra_links
#: model_terms:ir.ui.view,arch_db:partner_portal_extra_links.portal_my_home_partner_extra_links
msgid "Gare centrale :"
msgstr ""
#. module: partner_portal_extra_links
#: model_terms:ir.ui.view,arch_db:partner_portal_extra_links.portal_my_home_partner_extra_links
msgid "Salle de visio :"
msgstr ""
#. module: partner_portal_extra_links
#: model:ir.model.fields,help:partner_portal_extra_links.field_res_partner__visio_url
#: model:ir.model.fields,help:partner_portal_extra_links.field_res_users__visio_url
msgid "URL for Visio meetings associated with this company."
msgstr "URLpour les réunions en visio associé à cette société"
#. module: partner_portal_extra_links
#: model:ir.model.fields,help:partner_portal_extra_links.field_res_partner__wiki_homepage_url
#: model:ir.model.fields,help:partner_portal_extra_links.field_res_users__wiki_homepage_url
msgid "URL for the Wiki homepage associated with this company."
msgstr "URL pour le lien vers la Gare centrale (wiki)"
#. module: partner_portal_extra_links
#: model:ir.model.fields,field_description:partner_portal_extra_links.field_res_partner__visio_url
#: model:ir.model.fields,field_description:partner_portal_extra_links.field_res_users__visio_url
msgid "Visio URL"
msgstr "URL visio"
#. module: partner_portal_extra_links
#: model:ir.model.fields,field_description:partner_portal_extra_links.field_res_partner__wiki_homepage_url
#: model:ir.model.fields,field_description:partner_portal_extra_links.field_res_users__wiki_homepage_url
msgid "Wiki Homepage URL"
msgstr "URL gare centrale"

View File

@@ -0,0 +1 @@
from . import res_partner

View File

@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
from odoo import fields, models, api
class ResPartner(models.Model):
_inherit = "res.partner"
visio_url = fields.Char(
string="Visio URL",
help="URL for Visio meetings associated with this company.",
)
wiki_homepage_url = fields.Char(
string="Wiki Homepage URL",
help="URL for the Wiki homepage associated with this company.",
)

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<!-- Template /my/home -->
<template id="portal_my_home_partner_extra_links" name="Portal My Home: extra links" inherit_id="portal.portal_layout" priority="40">
<xpath expr="//div[hasclass('o_portal_my_details')]" position="inside">
<t t-if="user_id.partner_id.parent_id">
<t t-if="user_id.partner_id.parent_id.visio_url">
<hr class="mt-1 mb-0"/>
<div>
Salle de visio : <br/>
<a t-att-href="user_id.partner_id.parent_id.visio_url" target="_blank">
<b><t t-out="user_id.partner_id.parent_id.visio_url" /></b>
</a>
</div>
</t>
</t>
<t t-if="user_id.partner_id.parent_id">
<t t-if="user_id.partner_id.parent_id.wiki_homepage_url">
<hr class="mt-1 mb-0"/>
<div>
Gare centrale : <br/>
<a t-att-href="user_id.partner_id.parent_id.wiki_homepage_url" target="_blank">
<b><t t-out="user_id.partner_id.parent_id.wiki_homepage_url" /></b>
</a>
</div>
</t>
</t>
</xpath>
</template>
</odoo>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="view_partner_form" model="ir.ui.view">
<field name="name">res.partner.form.heldesk.extra.fields</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<field name="category_id" position="after">
<field name="visio_url" attrs="{'invisible': [('is_company', '=', False)]}"/>
<field name="wiki_homepage_url" attrs="{'invisible': [('is_company', '=', False)]}"/>
</field>
</field>
</record>
</odoo>

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.1.2",
"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.

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

@@ -0,0 +1,402 @@
# 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"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.view_res_partner_filter_profiles
msgid "Main Profile"
msgstr "Fiches administratives"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.view_res_partner_filter_profiles
msgid "Public Profile"
msgstr "Fiches publiques"
#. module: partner_profiles
#: model_terms:ir.ui.view,arch_db:partner_profiles.view_res_partner_filter_profiles
msgid "Position Profile"
msgstr "Fiches fonctions"

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,462 @@
# 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
from odoo.osv import expression
_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,
"is_company": partner.is_company,
}
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
@api.model
def read_group(self, domain, fields, groupby, offset=0, limit=None, orderby=False, lazy=True):
#TODO: should be moved in partner_contact_in_several_companies module
"""Display only standalone contact in domain or having attached contact in domain"""
ctx = self.env.context
if (
ctx.get("search_show_all_positions", {}).get("is_set")
and not ctx["search_show_all_positions"]["set_value"]
):
domain = expression.normalize_domain(domain)
attached_contact_domain = expression.AND(
(domain, [("contact_type", "=", "attached")])
)
attached_contacts = self.search(attached_contact_domain)
domain = expression.OR(
(
expression.AND(([("contact_type", "=", "standalone")], domain)),
[("other_contact_ids", "in", attached_contacts.ids)],
)
)
return super().read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)

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,290 @@
<?xml version="1.0"?>
<odoo>
<data>
<record id="view_res_partner_filter_profiles" model="ir.ui.view">
<field name="name">res.partner.select.contact</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="base.view_res_partner_filter" />
<field name="arch" type="xml">
<filter name="type_otherpositions" position="after">
<separator />
<filter
string="Main Profile"
name="type_admin"
context="{'search_show_all_positions': {'is_set': True, 'set_value': True}}"
domain="[('is_main_profile', '=', True)]"
/>
<filter
string="Public Profile"
name="type_public"
context="{'search_show_all_positions': {'is_set': True, 'set_value': True}}"
domain="[('is_public_profile', '=', True)]"
/>
<filter
string="Position Profile"
name="type_position"
context="{'search_show_all_positions': {'is_set': True, 'set_value': True}}"
domain="[('is_position_profile', '=', True)]"
/>
</filter>
</field>
</record>
<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 mb24" attrs="{'invisible': [('type','!=', 'contact')]}">
<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="binding_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>

View File

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

View File

@@ -0,0 +1,53 @@
======================================
partner_profiles_geolocalize_usability
======================================
Adapt geolocalize usability to partner profiles logic
Installation
============
Use Odoo normal module installation procedure to install
``partner_profiles_geolocalize_usability``.
Description
===========
This module adds the geolocation data in the form view of public profiles.
Configuration
=============
No configuration needed.
Known issues / Roadmap
======================
None yet.
Bug Tracker
===========
Bugs are tracked on `our issues website <https://github.com/elabore-coop/partner-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,4 @@
from . import models
# from . import controllers
# from . import wizard

View File

@@ -0,0 +1,38 @@
# Copyright 2023 Stéphan Sainléger (Elabore)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "partner_profiles_geolocalize_usability",
"version": "16.0.1.0.0",
"author": "Elabore",
"website": "https://elabore.coop",
"maintainer": "Stéphan Sainléger",
"license": "AGPL-3",
"category": "Tools",
"summary": "Adapt geolocalize usability to partner profiles logic",
# any module necessary for this one to work correctly
"depends": [
"base",
"partner_geolocalize_usability",
"partner_profiles",
],
"qweb": [
# "static/src/xml/*.xml",
],
"external_dependencies": {
"python": [],
},
# always loaded
"data": [
"views/res_partner.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 @@
This directory should contain the *.po for Odoo translation.

View File

@@ -0,0 +1,22 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_profiles_geolocalize_usability
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-12 13:52+0000\n"
"PO-Revision-Date: 2023-09-12 13:52+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_geolocalize_usability
#: model_terms:ir.ui.view,arch_db:partner_profiles_geolocalize_usability.partner_geolocalize_form_view_public
msgid "Geolocate"
msgstr "Géolocaliser"

View File

@@ -0,0 +1,22 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_profiles_geolocalize_usability
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-12 13:51+0000\n"
"PO-Revision-Date: 2023-09-12 13:51+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_geolocalize_usability
#: model_terms:ir.ui.view,arch_db:partner_profiles_geolocalize_usability.partner_geolocalize_form_view_public
msgid "Geolocate"
msgstr ""

View File

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

View File

@@ -0,0 +1,22 @@
from odoo import models, api
class ResPartner(models.Model):
_inherit = 'res.partner'
def sync_admin_and_public_data(self):
super(ResPartner, self).sync_admin_and_public_data()
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
values = {
"manual_geolocate": main_partner.manual_geolocate,
"partner_latitude": main_partner.partner_latitude,
"partner_longitude": main_partner.partner_longitude,
}
public_partner.write(values)

View File

@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<record model="ir.ui.view" id="partner_geolocalize_form_view_public">
<field name="name">partner.gogocarto.form.public</field>
<field name="model">res.partner</field>
<field name="inherit_id" ref="partner_profiles.partner_profiles_form_view" />
<field name='priority'>99</field>
<field name="arch" type="xml">
<xpath expr="//group[@id='public_data']" position="after">
<group attrs="{'invisible':[('is_public_profile', '=', False)]}">
<field name="manual_geolocate" />
<button
string="Geolocate"
name="geo_localize"
colspan="2"
icon="fa-check"
type="object" attrs="{'invisible':[('manual_geolocate', '=', True)]}" />
<field name="partner_latitude" attrs="{'readonly':[('manual_geolocate', '=', False)]}" />
<field name="partner_longitude" attrs="{'readonly':[('manual_geolocate', '=', False)]}" />
</group>
</xpath>
</field>
</record>
</odoo>

View File

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

View File

@@ -0,0 +1,56 @@
================================
partner_profiles_gogocarto_export
================================
Adapt data export for gogocarto to partner profiles logic
Installation
============
Use Odoo normal module installation procedure to install
``partner_profiles_gogocarto_export``.
Configuration
=============
To export public partners data:
#. Set the fields you want to export in Settings / Gogocarto, in the dedicated parameter for public profiles.
#. Check the field *"Export to Gogocarto"* in the partner form view of the main profile.
And use the link *https://yourodoo.com/web/<company_id>/get_http_gogocarto_elements* in Gogocarto server import configuration (*https://video.colibris-outilslibres.org/videos/watch/c74fc469-c822-4ab8-82a7-a2555e49e576*)
Known issues / Roadmap
======================
None yet.
Bug Tracker
===========
Bugs are tracked on `our issues website <https://github.com/elabore-coop/partner-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)
* Lokavaluto (https://lokavaluto.fr)
Maintainer
----------
This module is maintained by Elabore and Lokavaluto.

View File

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

View File

@@ -0,0 +1,40 @@
# Copyright 2023 Stéphan Sainléger (Elabore)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{
"name": "partner_profiles_gogocarto_export",
"version": "16.0.1.0.0",
"author": "Elabore",
"website": "https://elabore.coop",
"maintainer": "Stéphan Sainléger",
"license": "AGPL-3",
"category": "Tools",
"summary": "Adapt data export for gogocarto to partner profiles logic",
# any module necessary for this one to work correctly
"depends": [
"base",
"partner_gogocarto_export_api",
"partner_profiles",
"partner_profiles_geolocalize_usability",
],
"qweb": [
# "static/src/xml/*.xml",
],
"external_dependencies": {
"python": [],
},
# always loaded
"data": [
"views/config_settings_view.xml",
"views/res_company_view.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 @@
This directory should contain the *.po for Odoo translation.

View File

@@ -0,0 +1,46 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_profiles_gogocarto_export
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-12 14:02+0000\n"
"PO-Revision-Date: 2023-09-12 14: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_gogocarto_export
#: model:ir.model,name:partner_profiles_gogocarto_export.model_res_company
msgid "Companies"
msgstr "Sociétés"
#. module: partner_profiles_gogocarto_export
#: model:ir.model,name:partner_profiles_gogocarto_export.model_res_config_settings
msgid "Config Settings"
msgstr "Paramètres de config"
#. module: partner_profiles_gogocarto_export
#: model:ir.model,name:partner_profiles_gogocarto_export.model_res_partner
msgid "Contact"
msgstr "Contact"
#. module: partner_profiles_gogocarto_export
#: model:ir.model.fields,field_description:partner_profiles_gogocarto_export.field_res_company__export_gogocarto_public_fields
msgid "Export Gogocarto Public Fields"
msgstr "Export Gogocarto des champs publics"
#. module: partner_profiles_gogocarto_export
#: model:ir.model.fields,field_description:partner_profiles_gogocarto_export.field_res_config_settings__export_gogocarto_public_fields
msgid "GogoCarto Exported Public fields"
msgstr "Champs publics exportés dans Gogocarto"
#. module: partner_profiles_gogocarto_export
#: model_terms:ir.ui.view,arch_db:partner_profiles_gogocarto_export.res_config_settings_view_form_gogocarto_public
msgid "Partner public fields to export for Gogocarto map."
msgstr "Champs publics à exporter dans Gogocarto"

View File

@@ -0,0 +1,47 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * partner_profiles_gogocarto_export
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 12.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2023-09-12 14:08+0000\n"
"PO-Revision-Date: 2023-09-12 14:08+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_gogocarto_export
#: model:ir.model,name:partner_profiles_gogocarto_export.model_res_company
msgid "Companies"
msgstr ""
#. module: partner_profiles_gogocarto_export
#: model:ir.model,name:partner_profiles_gogocarto_export.model_res_config_settings
msgid "Config Settings"
msgstr ""
#. module: partner_profiles_gogocarto_export
#: model:ir.model,name:partner_profiles_gogocarto_export.model_res_partner
msgid "Contact"
msgstr ""
#. module: partner_profiles_gogocarto_export
#: model:ir.model.fields,field_description:partner_profiles_gogocarto_export.field_res_company__export_gogocarto_public_fields
msgid "Export Gogocarto Public Fields"
msgstr ""
#. module: partner_profiles_gogocarto_export
#: model:ir.model.fields,field_description:partner_profiles_gogocarto_export.field_res_config_settings__export_gogocarto_public_fields
msgid "GogoCarto Exported Public fields"
msgstr ""
#. module: partner_profiles_gogocarto_export
#: model_terms:ir.ui.view,arch_db:partner_profiles_gogocarto_export.res_config_settings_view_form_gogocarto_public
msgid "Partner public fields to export for Gogocarto map."
msgstr ""

View File

@@ -0,0 +1,3 @@
from . import res_config_settings
from . import company
from . import res_partner

View File

@@ -0,0 +1,14 @@
from odoo import models, fields
class Company(models.Model):
_inherit = "res.company"
export_gogocarto_public_fields = fields.Many2many(
'ir.model.fields',
relation='ir_model_fields_gogocarto_public',
domain=[
('model_id', '=', 'res.partner'),
('name', 'not in', ['id', 'name', 'partner_longitude', 'partner_latitude'])
]
)

View File

@@ -0,0 +1,23 @@
import logging
from odoo import fields, models
_logger = logging.getLogger(__name__)
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
export_gogocarto_public_fields = fields.Many2many(
related='company_id.export_gogocarto_public_fields',
relation='ir.model.fields',
string='GogoCarto Exported Public fields',
readonly=False,
domain=[
('model_id', '=', 'res.partner'),
('name', 'not in', ['name',
'partner_longitude',
'partner_latitude',
'id'])
]
)

Some files were not shown because too many files have changed in this diff Show More