Browse Source
Merge pull request #437 from Tecnativa/10.0-partner_second_lastname
Merge pull request #437 from Tecnativa/10.0-partner_second_lastname
[10.0][MIG] partner_second_lastname: Migration to 10.0pull/445/head
committed by
GitHub
18 changed files with 1191 additions and 0 deletions
-
100partner_second_lastname/README.rst
-
5partner_second_lastname/__init__.py
-
24partner_second_lastname/__manifest__.py
-
69partner_second_lastname/i18n/de.po
-
32partner_second_lastname/i18n/es.po
-
69partner_second_lastname/i18n/eu.po
-
68partner_second_lastname/i18n/fi.po
-
69partner_second_lastname/i18n/it.po
-
69partner_second_lastname/i18n/sl.po
-
6partner_second_lastname/models/__init__.py
-
29partner_second_lastname/models/base_config_settings.py
-
112partner_second_lastname/models/res_partner.py
-
7partner_second_lastname/tests/__init__.py
-
35partner_second_lastname/tests/test_config.py
-
192partner_second_lastname/tests/test_name.py
-
221partner_second_lastname/tests/test_onchange.py
-
54partner_second_lastname/views/res_partner.xml
-
30partner_second_lastname/views/res_user.xml
@ -0,0 +1,100 @@ |
|||||
|
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg |
||||
|
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html |
||||
|
:alt: License: AGPL-3 |
||||
|
|
||||
|
======================= |
||||
|
Partner second lastname |
||||
|
======================= |
||||
|
|
||||
|
This module was written to extend the functionality of ``partner_firstname`` to |
||||
|
support having a second lastname for contact partners. |
||||
|
|
||||
|
In some countries, it's important to have a second last name for contacts. |
||||
|
|
||||
|
Contact partners will need to fill at least one of the name fields |
||||
|
(*First name*, *First last name* or *Second last name*). |
||||
|
|
||||
|
Configuration |
||||
|
============= |
||||
|
|
||||
|
You can configure some common name patterns for the inverse function |
||||
|
in Settings > Configuration > General settings: |
||||
|
|
||||
|
* Lastname SecondLastname Firstname: For example 'Anderson Lavarge Robert' |
||||
|
* Lastname SecondLastname, Firstname: For example 'Anderson Lavarge, Robert' |
||||
|
* Firstname Lastname SecondLastname: For example 'Robert Anderson Lavarge' |
||||
|
|
||||
|
After applying the changes, you can recalculate all partners name clicking |
||||
|
"Recalculate names" button. Note: This process could take so much time depending |
||||
|
how many partners there are in database. |
||||
|
|
||||
|
You can use *_get_inverse_name* method to get firstname, lastname and |
||||
|
second lastname from a simple string and also *_get_computed_name* to get a |
||||
|
name form the firstname, lastname and second lastname. |
||||
|
These methods can be overridden to change the format specified above. |
||||
|
|
||||
|
|
||||
|
Usage |
||||
|
===== |
||||
|
|
||||
|
To use this module, you need to: |
||||
|
|
||||
|
* Edit any partner's form. |
||||
|
* Make sure the partner is not a company. |
||||
|
* Enter firstname and lastnames. |
||||
|
|
||||
|
If you directly enter the full name instead of entering the other fields |
||||
|
separately (maybe from other form), this module will try to guess the best |
||||
|
match for your input and split it between firstname, lastname and second |
||||
|
lastname using an inverse function. |
||||
|
|
||||
|
If you can, always enter it manually please. Automatic guessing could fail for |
||||
|
you easily in some corner cases. |
||||
|
|
||||
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas |
||||
|
:alt: Try me on Runbot |
||||
|
:target: https://runbot.odoo-community.org/runbot/134/10.0 |
||||
|
|
||||
|
|
||||
|
Known issues / Roadmap |
||||
|
====================== |
||||
|
|
||||
|
Patterns for the inverse function are configurable only at system level. Maybe |
||||
|
this configuration could depend on partner language, country or company, |
||||
|
as discussed at `this OCA issue <https://github.com/OCA/partner-contact/issues/210>`_ |
||||
|
|
||||
|
|
||||
|
Bug Tracker |
||||
|
=========== |
||||
|
|
||||
|
Bugs are tracked on `GitHub Issues |
||||
|
<https://github.com/OCA/partner-contact/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 `here |
||||
|
<https://github.com/OCA/partner-contact/issues/new>`_. |
||||
|
|
||||
|
|
||||
|
Credits |
||||
|
======= |
||||
|
|
||||
|
Contributors |
||||
|
------------ |
||||
|
|
||||
|
* Jairo Llopis <jairo.llopis@tecnativa.com>. |
||||
|
* Antonio Espinosa. |
||||
|
* Pedro M. Baeza <pedro.baeza@tecnativa.com>. |
||||
|
|
||||
|
Maintainer |
||||
|
---------- |
||||
|
|
||||
|
.. image:: https://odoo-community.org/logo.png |
||||
|
:alt: Odoo Community Association |
||||
|
:target: https://odoo-community.org |
||||
|
|
||||
|
This module is maintained by the OCA. |
||||
|
|
||||
|
OCA, or the Odoo Community Association, is a nonprofit organization whose |
||||
|
mission is to support the collaborative development of Odoo features and |
||||
|
promote its widespread use. |
||||
|
|
||||
|
To contribute to this module, please visit https://odoo-community.org. |
@ -0,0 +1,5 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
# © 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. |
||||
|
|
||||
|
from . import models |
@ -0,0 +1,24 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis |
||||
|
# Copyright 2015 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
# Copyright 2017 Tecnativa - Pedro M. Baeza |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
{ |
||||
|
"name": "Partner second last name", |
||||
|
"summary": "Have split first and second lastnames", |
||||
|
"version": "10.0.1.0.0", |
||||
|
"license": "AGPL-3", |
||||
|
"website": "https://www.tecnativa.com", |
||||
|
"author": "Tecnativa, " |
||||
|
"Odoo Community Association (OCA)", |
||||
|
"category": "Partner Management", |
||||
|
"depends": [ |
||||
|
"partner_firstname", |
||||
|
], |
||||
|
"data": [ |
||||
|
"views/res_partner.xml", |
||||
|
"views/res_user.xml", |
||||
|
], |
||||
|
"installable": True, |
||||
|
} |
@ -0,0 +1,69 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * partner_second_lastname |
||||
|
# |
||||
|
# Translators: |
||||
|
# Rudolf Schnapka <rs@techno-flex.de>, 2016-2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: partner-contact (8.0)\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-02-21 16:57+0000\n" |
||||
|
"PO-Revision-Date: 2017-02-24 22:09+0000\n" |
||||
|
"Last-Translator: Rudolf Schnapka <rs@techno-flex.de>\n" |
||||
|
"Language-Team: German (http://www.transifex.com/oca/OCA-partner-contact-8-0/language/de/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: de\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: model:ir.model,name:partner_second_lastname.model_res_partner |
||||
|
msgid "Partner" |
||||
|
msgstr "Partner" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: field:res.partner,lastname2:0 |
||||
|
msgid "Second last name" |
||||
|
msgstr "Zweiter Nachname" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "{\n 'required': [('firstname', '=', False),\n ('lastname2', '=', False),\n ('is_company', '=', False)]\n }" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "{\n 'required': [('firstname', '=', False),\n ('lastname2', '=', False)]\n }" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "{\n 'required': [('lastname', '=', False),\n ('lastname2', '=', False),\n ('is_company', '=', False)]\n }" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "{\n 'required': [('lastname', '=', False),\n ('lastname2', '=', False)]\n }" |
@ -0,0 +1,32 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * partner_second_lastname |
||||
|
# |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: Odoo Server 10.0\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-06-22 00:28+0000\n" |
||||
|
"PO-Revision-Date: 2017-06-22 00:28+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_second_lastname |
||||
|
#: model:ir.model,name:partner_second_lastname.model_res_partner |
||||
|
msgid "Partner" |
||||
|
msgstr "Empresa" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: model:ir.model.fields,field_description:partner_second_lastname.field_res_partner_lastname2 |
||||
|
msgid "Second last name" |
||||
|
msgstr "Segundo apellido" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: model:ir.model,name:partner_second_lastname.model_base_config_settings |
||||
|
msgid "base.config.settings" |
||||
|
msgstr "base.config.settings" |
||||
|
|
@ -0,0 +1,69 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * partner_second_lastname |
||||
|
# |
||||
|
# Translators: |
||||
|
# Esther Martín Menéndez <esthermartin001@gmail.com>, 2017 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: partner-contact (8.0)\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2017-02-21 16:57+0000\n" |
||||
|
"PO-Revision-Date: 2017-02-23 15:55+0000\n" |
||||
|
"Last-Translator: Esther Martín Menéndez <esthermartin001@gmail.com>\n" |
||||
|
"Language-Team: Basque (http://www.transifex.com/oca/OCA-partner-contact-8-0/language/eu/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: eu\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: model:ir.model,name:partner_second_lastname.model_res_partner |
||||
|
msgid "Partner" |
||||
|
msgstr "Kidea" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: field:res.partner,lastname2:0 |
||||
|
msgid "Second last name" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
@ -0,0 +1,68 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * partner_second_lastname |
||||
|
# |
||||
|
# Translators: |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: partner-contact (8.0)\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2016-01-19 01:46+0000\n" |
||||
|
"PO-Revision-Date: 2015-10-29 13:08+0000\n" |
||||
|
"Last-Translator: <>\n" |
||||
|
"Language-Team: Finnish (http://www.transifex.com/oca/OCA-partner-contact-8-0/language/fi/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: fi\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: model:ir.model,name:partner_second_lastname.model_res_partner |
||||
|
msgid "Partner" |
||||
|
msgstr "Kumppani" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: field:res.partner,lastname2:0 |
||||
|
msgid "Second last name" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
@ -0,0 +1,69 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * partner_second_lastname |
||||
|
# |
||||
|
# Translators: |
||||
|
# Paolo Valier, 2016 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: partner-contact (8.0)\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2016-03-13 00:57+0000\n" |
||||
|
"PO-Revision-Date: 2016-03-13 12:57+0000\n" |
||||
|
"Last-Translator: Paolo Valier\n" |
||||
|
"Language-Team: Italian (http://www.transifex.com/oca/OCA-partner-contact-8-0/language/it/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: it\n" |
||||
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: model:ir.model,name:partner_second_lastname.model_res_partner |
||||
|
msgid "Partner" |
||||
|
msgstr "Partner" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: field:res.partner,lastname2:0 |
||||
|
msgid "Second last name" |
||||
|
msgstr "Secondo cognome" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "" |
@ -0,0 +1,69 @@ |
|||||
|
# Translation of Odoo Server. |
||||
|
# This file contains the translation of the following modules: |
||||
|
# * partner_second_lastname |
||||
|
# |
||||
|
# Translators: |
||||
|
# Matjaž Mozetič <m.mozetic@matmoz.si>, 2015 |
||||
|
msgid "" |
||||
|
msgstr "" |
||||
|
"Project-Id-Version: partner-contact (8.0)\n" |
||||
|
"Report-Msgid-Bugs-To: \n" |
||||
|
"POT-Creation-Date: 2015-10-31 10:35+0000\n" |
||||
|
"PO-Revision-Date: 2015-10-29 13:41+0000\n" |
||||
|
"Last-Translator: Matjaž Mozetič <m.mozetic@matmoz.si>\n" |
||||
|
"Language-Team: Slovenian (http://www.transifex.com/oca/OCA-partner-contact-8-0/language/sl/)\n" |
||||
|
"MIME-Version: 1.0\n" |
||||
|
"Content-Type: text/plain; charset=UTF-8\n" |
||||
|
"Content-Transfer-Encoding: \n" |
||||
|
"Language: sl\n" |
||||
|
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: model:ir.model,name:partner_second_lastname.model_res_partner |
||||
|
msgid "Partner" |
||||
|
msgstr "Partner" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: field:res.partner,lastname2:0 |
||||
|
msgid "Second last name" |
||||
|
msgstr "Drugi priimek" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "{\n 'required': [('firstname', '=', False),\n ('lastname2', '=', False),\n ('is_company', '=', False)]\n }" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('firstname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "{\n 'required': [('firstname', '=', False),\n ('lastname2', '=', False)]\n }" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.partner:partner_second_lastname.partner_form |
||||
|
#: view:res.partner:partner_second_lastname.partner_simple_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False),\n" |
||||
|
" ('is_company', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "{\n 'required': [('lastname', '=', False),\n ('lastname2', '=', False),\n ('is_company', '=', False)]\n }" |
||||
|
|
||||
|
#. module: partner_second_lastname |
||||
|
#: view:res.users:partner_second_lastname.users_form |
||||
|
msgid "" |
||||
|
"{\n" |
||||
|
" 'required': [('lastname', '=', False),\n" |
||||
|
" ('lastname2', '=', False)]\n" |
||||
|
" }" |
||||
|
msgstr "{\n 'required': [('lastname', '=', False),\n ('lastname2', '=', False)]\n }" |
@ -0,0 +1,6 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import base_config_settings |
||||
|
from . import res_partner |
@ -0,0 +1,29 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo import models, api |
||||
|
|
||||
|
|
||||
|
class BaseConfigSettings(models.TransientModel): |
||||
|
_inherit = 'base.config.settings' |
||||
|
|
||||
|
def _partner_names_order_selection(self): |
||||
|
options = super( |
||||
|
BaseConfigSettings, self)._partner_names_order_selection() |
||||
|
new_labels = { |
||||
|
'last_first': 'Lastname SecondLastname Firstname', |
||||
|
'last_first_comma': 'Lastname SecondLastname, Firstname', |
||||
|
'first_last': 'Firstname Lastname SecondLastname', |
||||
|
} |
||||
|
return [(k, new_labels[k]) if k in new_labels else (k, v) |
||||
|
for k, v in options] |
||||
|
|
||||
|
@api.multi |
||||
|
def _partners_for_recalculating(self): |
||||
|
return self.env['res.partner'].search([ |
||||
|
('is_company', '=', False), |
||||
|
'|', '&', ('firstname', '!=', False), ('lastname', '!=', False), |
||||
|
'|', '&', ('firstname', '!=', False), ('lastname2', '!=', False), |
||||
|
'&', ('lastname', '!=', False), ('lastname2', '!=', False), |
||||
|
]) |
@ -0,0 +1,112 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis |
||||
|
# Copyright 2015 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
# Copyright 2017 Tecnativa - Pedro M. Baeza |
||||
|
|
||||
|
from odoo import api, fields, models |
||||
|
from odoo.addons.partner_firstname import exceptions |
||||
|
|
||||
|
|
||||
|
class ResPartner(models.Model): |
||||
|
"""Adds a second last name.""" |
||||
|
_inherit = "res.partner" |
||||
|
|
||||
|
lastname2 = fields.Char("Second last name", oldname="lastname_second") |
||||
|
|
||||
|
@api.model |
||||
|
def _get_computed_name(self, lastname, firstname, lastname2=None): |
||||
|
"""Compute the name combined with the second lastname too. |
||||
|
|
||||
|
We have 2 lastnames, so lastnames and firstname will be separated by a |
||||
|
comma. |
||||
|
""" |
||||
|
order = self._get_names_order() |
||||
|
names = list() |
||||
|
if order == 'first_last': |
||||
|
if firstname: |
||||
|
names.append(firstname) |
||||
|
if lastname: |
||||
|
names.append(lastname) |
||||
|
if lastname2: |
||||
|
names.append(lastname2) |
||||
|
else: |
||||
|
if lastname: |
||||
|
names.append(lastname) |
||||
|
if lastname2: |
||||
|
names.append(lastname2) |
||||
|
if names and firstname and order == 'last_first_comma': |
||||
|
names[-1] = names[-1] + "," |
||||
|
if firstname: |
||||
|
names.append(firstname) |
||||
|
return u" ".join(names) |
||||
|
|
||||
|
@api.depends("firstname", "lastname", "lastname2") |
||||
|
def _compute_name(self): |
||||
|
"""Write :attr:`~.name` according to splitted data.""" |
||||
|
for partner in self: |
||||
|
partner.name = self._get_computed_name( |
||||
|
partner.lastname, partner.firstname, partner.lastname2, |
||||
|
) |
||||
|
|
||||
|
@api.one |
||||
|
def _inverse_name(self): |
||||
|
"""Try to revert the effect of :meth:`._compute_name`.""" |
||||
|
parts = self._get_inverse_name(self.name, self.is_company) |
||||
|
# Avoid to hit :meth:`~._check_name` with all 3 fields being ``False`` |
||||
|
before, after = {}, {} |
||||
|
for key, value in parts.iteritems(): |
||||
|
(before if value else after)[key] = value |
||||
|
if any([before[k] != self[k] for k in before.keys()]): |
||||
|
self.update(before) |
||||
|
if any([after[k] != self[k] for k in after.keys()]): |
||||
|
self.update(after) |
||||
|
|
||||
|
@api.model |
||||
|
def _get_inverse_name(self, name, is_company=False): |
||||
|
"""Compute the inverted name. |
||||
|
|
||||
|
- If the partner is a company, save it in the lastname. |
||||
|
- Otherwise, make a guess. |
||||
|
""" |
||||
|
# Company name goes to the lastname |
||||
|
result = { |
||||
|
'firstname': False, |
||||
|
'lastname': name or False, |
||||
|
'lastname2': False, |
||||
|
} |
||||
|
if not is_company and name: |
||||
|
order = self._get_names_order() |
||||
|
result = super(ResPartner, self)._get_inverse_name( |
||||
|
name, is_company) |
||||
|
parts = [] |
||||
|
if order == 'last_first': |
||||
|
if result['firstname']: |
||||
|
parts = result['firstname'].split(" ", 1) |
||||
|
while len(parts) < 2: |
||||
|
parts.append(False) |
||||
|
result['lastname2'] = parts[0] |
||||
|
result['firstname'] = parts[1] |
||||
|
else: |
||||
|
if result['lastname']: |
||||
|
parts = result['lastname'].split(" ", 1) |
||||
|
while len(parts) < 2: |
||||
|
parts.append(False) |
||||
|
result['lastname'] = parts[0] |
||||
|
result['lastname2'] = parts[1] |
||||
|
return result |
||||
|
|
||||
|
@api.constrains("firstname", "lastname", "lastname2") |
||||
|
def _check_name(self): |
||||
|
"""Ensure at least one name is set.""" |
||||
|
try: |
||||
|
super(ResPartner, self)._check_name() |
||||
|
except exceptions.EmptyNamesError: |
||||
|
for partner in self: |
||||
|
if not partner.lastname2: |
||||
|
raise |
||||
|
|
||||
|
@api.onchange("firstname", "lastname", "lastname2") |
||||
|
def _onchange_subnames(self): |
||||
|
"""Trigger onchange with :attr:`~.lastname2` too.""" |
||||
|
super(ResPartner, self)._onchange_subnames() |
@ -0,0 +1,7 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from . import test_name |
||||
|
from . import test_onchange |
||||
|
from . import test_config |
||||
|
from odoo.addons.partner_firstname.tests import test_empty |
@ -0,0 +1,35 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# Copyright 2017 Tecnativa - Pedro M. Baeza |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
|
||||
|
from odoo.tests import common |
||||
|
|
||||
|
|
||||
|
class TestConfig(common.SavepointCase): |
||||
|
@classmethod |
||||
|
def setUpClass(cls): |
||||
|
super(TestConfig, cls).setUpClass() |
||||
|
cls.wizard = cls.env['base.config.settings'].create({}) |
||||
|
cls.partner = cls.env['res.partner'].create({ |
||||
|
'firstname': "First", |
||||
|
'lastname': "Last", |
||||
|
'lastname2': "Second", |
||||
|
}) |
||||
|
|
||||
|
def test_last_first(self): |
||||
|
self.wizard.partner_names_order = 'last_first' |
||||
|
self.wizard.set_partner_names_order() |
||||
|
self.wizard.action_recalculate_partners_name() |
||||
|
self.assertEqual(self.partner.name, "Last Second First") |
||||
|
|
||||
|
def test_last_first_comma(self): |
||||
|
self.wizard.partner_names_order = 'last_first_comma' |
||||
|
self.wizard.set_partner_names_order() |
||||
|
self.wizard.action_recalculate_partners_name() |
||||
|
self.assertEqual(self.partner.name, "Last Second, First") |
||||
|
|
||||
|
def test_first_last(self): |
||||
|
self.wizard.partner_names_order = 'first_last' |
||||
|
self.wizard.set_partner_names_order() |
||||
|
self.wizard.action_recalculate_partners_name() |
||||
|
self.assertEqual(self.partner.name, "First Last Second") |
@ -0,0 +1,192 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
# © 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. |
||||
|
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
|
||||
|
from odoo.tests.common import TransactionCase |
||||
|
from odoo.addons.partner_firstname.tests.base import MailInstalled |
||||
|
|
||||
|
|
||||
|
class CompanyCase(TransactionCase): |
||||
|
"""Test ``res.partner`` when it is a company.""" |
||||
|
def setUp(self): |
||||
|
super(CompanyCase, self).setUp() |
||||
|
self.env['ir.config_parameter'].set_param( |
||||
|
'partner_names_order', 'first_last') |
||||
|
|
||||
|
def tearDown(self): |
||||
|
try: |
||||
|
new = self.env["res.partner"].create({ |
||||
|
"is_company": True, |
||||
|
"name": self.name, |
||||
|
}) |
||||
|
|
||||
|
# Name should be cleaned of unneeded whitespace |
||||
|
clean_name = u" ".join(self.name.split(None)) |
||||
|
|
||||
|
# Check it's saved OK |
||||
|
self.assertEqual( |
||||
|
new.name, |
||||
|
clean_name, |
||||
|
"Saved company name is wrong.") |
||||
|
|
||||
|
# Check it's saved in the lastname |
||||
|
self.assertEqual( |
||||
|
new.lastname, |
||||
|
clean_name, |
||||
|
"Company name should be saved in the lastname field.") |
||||
|
|
||||
|
# Check that other fields are empty |
||||
|
self.assertEqual( |
||||
|
new.firstname, |
||||
|
False, |
||||
|
"Company first name must always be empty.") |
||||
|
self.assertEqual( |
||||
|
new.lastname2, |
||||
|
False, |
||||
|
"Company last name 2 must always be empty.") |
||||
|
|
||||
|
finally: |
||||
|
super(CompanyCase, self).tearDown() |
||||
|
|
||||
|
def test_long_name(self): |
||||
|
"""Create a company with a long name.""" |
||||
|
self.name = u"Söme very lóng nâme" |
||||
|
|
||||
|
def test_short_name(self): |
||||
|
"""Create a company with a short name.""" |
||||
|
self.name = u"Shoŕt" |
||||
|
|
||||
|
def test_whitespace_before(self): |
||||
|
"""Create a company with name prefixed with whitespace.""" |
||||
|
self.name = u" Wĥitespace befòre" |
||||
|
|
||||
|
def test_whitespace_after(self): |
||||
|
"""Create a company with name suffixed with whitespace.""" |
||||
|
self.name = u"Whitespâce aftér " |
||||
|
|
||||
|
def test_whitespace_inside(self): |
||||
|
"""Create a company with whitespace inside the name.""" |
||||
|
self.name = u"Whitespacé ïnside" |
||||
|
|
||||
|
def test_whitespace_everywhere(self): |
||||
|
"""Create a company with whitespace everywhere in the name.""" |
||||
|
self.name = u" A lot öf whitespace " |
||||
|
|
||||
|
|
||||
|
class PersonCase(TransactionCase): |
||||
|
"""Test ``res.partner`` when it is a person.""" |
||||
|
model = "res.partner" |
||||
|
context = dict() |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(PersonCase, self).setUp() |
||||
|
self.env['ir.config_parameter'].set_param( |
||||
|
'partner_names_order', 'last_first_comma') |
||||
|
|
||||
|
self.firstname = u"Fírstname" |
||||
|
self.lastname = u"Làstname1" |
||||
|
self.lastname2 = u"Lâstname2" |
||||
|
self.template = u"%(last1)s %(last2)s, %(first)s" |
||||
|
|
||||
|
def tearDown(self): |
||||
|
try: |
||||
|
new = (self.env[self.model].with_context(self.context) |
||||
|
.create(self.params)) |
||||
|
|
||||
|
# Check that each individual field matches |
||||
|
self.assertEqual( |
||||
|
self.firstname, |
||||
|
new.firstname, |
||||
|
"First name saved badly.") |
||||
|
self.assertEqual( |
||||
|
self.lastname, |
||||
|
new.lastname, |
||||
|
"Last name 1 saved badly.") |
||||
|
self.assertEqual( |
||||
|
self.lastname2, |
||||
|
new.lastname2, |
||||
|
"Last name 2 saved badly.") |
||||
|
|
||||
|
# Check that name gets saved fine |
||||
|
self.assertEqual( |
||||
|
self.template % ({"last1": self.lastname, |
||||
|
"last2": self.lastname2, |
||||
|
"first": self.firstname}), |
||||
|
new.name, |
||||
|
"Name saved badly.") |
||||
|
|
||||
|
finally: |
||||
|
super(PersonCase, self).tearDown() |
||||
|
|
||||
|
def test_firstname_first(self): |
||||
|
"""Create a person setting his first name first.""" |
||||
|
self.env['ir.config_parameter'].set_param( |
||||
|
'partner_names_order', 'first_last') |
||||
|
self.template = "%(first)s %(last1)s %(last2)s" |
||||
|
self.params = { |
||||
|
"is_company": False, |
||||
|
"name": "%s %s %s" % (self.firstname, |
||||
|
self.lastname, |
||||
|
self.lastname2), |
||||
|
} |
||||
|
|
||||
|
def test_firstname_last(self): |
||||
|
"""Create a person setting his first name last.""" |
||||
|
self.params = { |
||||
|
"is_company": False, |
||||
|
"name": "%s %s, %s" % (self.lastname, |
||||
|
self.lastname2, |
||||
|
self.firstname), |
||||
|
} |
||||
|
|
||||
|
def test_firstname_only(self): |
||||
|
"""Create a person setting his first name only.""" |
||||
|
self.env['ir.config_parameter'].set_param( |
||||
|
'partner_names_order', 'first_last') |
||||
|
self.firstname = self.lastname2 = False |
||||
|
self.template = "%(last1)s" |
||||
|
self.params = { |
||||
|
"is_company": False, |
||||
|
"name": self.lastname, |
||||
|
} |
||||
|
|
||||
|
def test_firstname_lastname_only(self): |
||||
|
"""Create a person setting his first name and last name 1 only.""" |
||||
|
self.env['ir.config_parameter'].set_param( |
||||
|
'partner_names_order', 'first_last') |
||||
|
self.lastname2 = False |
||||
|
self.template = "%(first)s %(last1)s" |
||||
|
self.params = { |
||||
|
"is_company": False, |
||||
|
"name": "%s %s" % (self.firstname, self.lastname), |
||||
|
} |
||||
|
|
||||
|
def test_lastname_firstname_only(self): |
||||
|
"""Create a person setting his last name 1 and first name only.""" |
||||
|
self.lastname2 = False |
||||
|
self.template = "%(last1)s, %(first)s" |
||||
|
self.params = { |
||||
|
"is_company": False, |
||||
|
"name": "%s, %s" % (self.lastname, self.firstname), |
||||
|
} |
||||
|
|
||||
|
def test_separately(self): |
||||
|
"""Create a person setting separately all fields.""" |
||||
|
self.params = { |
||||
|
"is_company": False, |
||||
|
"firstname": self.firstname, |
||||
|
"lastname": self.lastname, |
||||
|
"lastname2": self.lastname2, |
||||
|
} |
||||
|
|
||||
|
|
||||
|
class UserCase(PersonCase, MailInstalled): |
||||
|
"""Test ``res.users``.""" |
||||
|
model = "res.users" |
||||
|
context = {"default_login": "user@example.com"} |
||||
|
|
||||
|
def tearDown(self): |
||||
|
# Skip if ``mail`` is installed |
||||
|
if not self.mail_installed(): |
||||
|
super(UserCase, self).tearDown() |
@ -0,0 +1,221 @@ |
|||||
|
# -*- coding: utf-8 -*- |
||||
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). |
||||
|
# © 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. |
||||
|
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa |
||||
|
|
||||
|
"""These tests try to mimic the behavior of the UI form. |
||||
|
|
||||
|
The form operates in onchange mode, with its limitations. |
||||
|
""" |
||||
|
|
||||
|
from odoo.tests.common import TransactionCase |
||||
|
|
||||
|
|
||||
|
class OnChangeCase(TransactionCase): |
||||
|
is_company = False |
||||
|
|
||||
|
def setUp(self): |
||||
|
super(OnChangeCase, self).setUp() |
||||
|
self.env['ir.config_parameter'].set_param( |
||||
|
'partner_names_order', 'last_first_comma') |
||||
|
|
||||
|
def new_partner(self): |
||||
|
"""Create an empty partner. Ensure it is (or not) a company.""" |
||||
|
new = self.env["res.partner"].new() |
||||
|
new.is_company = self.is_company |
||||
|
return new |
||||
|
|
||||
|
|
||||
|
class PartnerCompanyCase(OnChangeCase): |
||||
|
is_company = True |
||||
|
|
||||
|
def tearDown(self): |
||||
|
"""Companies never have ``firstname`` nor ``lastname2``.""" |
||||
|
super(PartnerCompanyCase, self).tearDown() |
||||
|
self.assertEqual(self.partner.firstname, False) |
||||
|
self.assertEqual(self.partner.lastname2, False) |
||||
|
|
||||
|
def set_name(self, value): |
||||
|
self.partner.name = value |
||||
|
|
||||
|
# It triggers onchange |
||||
|
self.partner._onchange_name() |
||||
|
|
||||
|
# Ensure it's properly set |
||||
|
self.assertEqual(self.partner.name, value) |
||||
|
|
||||
|
def test_create_from_form(self): |
||||
|
"""A user creates a company from the form.""" |
||||
|
name = u"Sôme company" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_name(name) |
||||
|
|
||||
|
self.assertEqual(self.partner.lastname, name) |
||||
|
|
||||
|
def test_empty_name_and_subnames(self): |
||||
|
"""If the user empties ``name``, subnames must be ``False``. |
||||
|
|
||||
|
Otherwise, the ``required`` attr will not work as expected. |
||||
|
""" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_name(u"Fóo") |
||||
|
self.set_name(u"") |
||||
|
|
||||
|
self.assertEqual(self.partner.lastname, False) |
||||
|
|
||||
|
|
||||
|
class PartnerContactCase(OnChangeCase): |
||||
|
def set_field(self, field, value): |
||||
|
# Changes the field |
||||
|
setattr(self.partner, field, value) |
||||
|
|
||||
|
if field in ("firstname", "lastname", "lastname2"): |
||||
|
# Trigger onchanges |
||||
|
self.partner._onchange_subnames() |
||||
|
self.partner._onchange_name() |
||||
|
|
||||
|
# Check it's set OK |
||||
|
self.assertEqual(getattr(self.partner, field), value) |
||||
|
|
||||
|
def test_create_from_form_empty(self): |
||||
|
"""A user creates a contact from the form. |
||||
|
|
||||
|
All subfields must be false, or the ``required`` attr will not work as |
||||
|
expected. |
||||
|
""" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# Odoo tries to compute the name |
||||
|
self.partner._compute_name() |
||||
|
|
||||
|
# This is then triggered |
||||
|
self.partner._onchange_name() |
||||
|
|
||||
|
# Subnames must start as False to make the UI work fine |
||||
|
self.assertEqual(self.partner.firstname, False) |
||||
|
self.assertEqual(self.partner.lastname, False) |
||||
|
self.assertEqual(self.partner.lastname2, False) |
||||
|
|
||||
|
# ``name`` cannot be False, or upstream Odoo will fail |
||||
|
self.assertEqual(self.partner.name, u"") |
||||
|
|
||||
|
def test_create_from_form_only_firstname(self): |
||||
|
"""A user creates a contact with only the firstname from the form.""" |
||||
|
firstname = u"Fïrst" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_field("firstname", firstname) |
||||
|
|
||||
|
self.assertEqual(self.partner.lastname, False) |
||||
|
self.assertEqual(self.partner.lastname2, False) |
||||
|
self.assertEqual(self.partner.name, firstname) |
||||
|
|
||||
|
def test_create_from_form_only_lastname(self): |
||||
|
"""A user creates a contact with only the lastname from the form.""" |
||||
|
lastname = u"Läst" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_field("lastname", lastname) |
||||
|
|
||||
|
self.assertEqual(self.partner.firstname, False) |
||||
|
self.assertEqual(self.partner.lastname2, False) |
||||
|
self.assertEqual(self.partner.name, lastname) |
||||
|
|
||||
|
def test_create_from_form_only_lastname2(self): |
||||
|
"""A user creates a contact with only the lastname2 from the form.""" |
||||
|
lastname2 = u"Läst2" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_field("lastname2", lastname2) |
||||
|
|
||||
|
self.assertEqual(self.partner.firstname, False) |
||||
|
self.assertEqual(self.partner.lastname, False) |
||||
|
self.assertEqual(self.partner.name, lastname2) |
||||
|
|
||||
|
def test_create_from_without_firstname(self): |
||||
|
"""A user creates a contact without firstname from the form.""" |
||||
|
lastname = u"Läst" |
||||
|
lastname2 = u"Läst2" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_field("lastname", lastname) |
||||
|
self.set_field("lastname2", lastname2) |
||||
|
|
||||
|
self.assertEqual(self.partner.firstname, False) |
||||
|
self.assertEqual( |
||||
|
self.partner.name, |
||||
|
u"%s %s" % (lastname, lastname2)) |
||||
|
|
||||
|
def test_create_from_without_lastname(self): |
||||
|
"""A user creates a contact without lastname from the form.""" |
||||
|
firstname = u"Fïrst" |
||||
|
lastname2 = u"Läst2" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_field("firstname", firstname) |
||||
|
self.set_field("lastname2", lastname2) |
||||
|
|
||||
|
self.assertEqual(self.partner.lastname, False) |
||||
|
self.assertEqual( |
||||
|
self.partner.name, |
||||
|
u"%s, %s" % (lastname2, firstname)) |
||||
|
|
||||
|
def test_create_from_without_lastname2(self): |
||||
|
"""A user creates a contact without lastname2 from the form.""" |
||||
|
firstname = u"Fïrst" |
||||
|
lastname = u"Läst" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_field("firstname", firstname) |
||||
|
self.set_field("lastname", lastname) |
||||
|
|
||||
|
self.assertEqual(self.partner.lastname2, False) |
||||
|
self.assertEqual( |
||||
|
self.partner.name, |
||||
|
u"%s, %s" % (lastname, firstname)) |
||||
|
|
||||
|
def test_create_from_form_all(self): |
||||
|
"""A user creates a contact with all names from the form.""" |
||||
|
firstname = u"Fïrst" |
||||
|
lastname = u"Läst" |
||||
|
lastname2 = u"Läst2" |
||||
|
with self.env.do_in_onchange(): |
||||
|
# User presses ``new`` |
||||
|
self.partner = self.new_partner() |
||||
|
|
||||
|
# User changes fields |
||||
|
self.set_field("firstname", firstname) |
||||
|
self.set_field("lastname", lastname) |
||||
|
self.set_field("lastname2", lastname2) |
||||
|
|
||||
|
self.assertEqual( |
||||
|
self.partner.name, |
||||
|
u"%s %s, %s" % (lastname, lastname2, firstname)) |
@ -0,0 +1,54 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- Copyright 2015 Tecnativa - Jairo Llopis |
||||
|
Copyright 2017 Tecnativa - Pedro M. Baeza |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
||||
|
<odoo> |
||||
|
<record id="partner_simple_form" model="ir.ui.view"> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="partner_firstname.view_partner_simple_form_firstname"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<data> |
||||
|
<xpath expr="//field[@name='firstname']" position="attributes"> |
||||
|
<attribute name="attrs">{'required': [('lastname', '=', False), ('lastname2', '=', False), ('is_company', '=', False)]}</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//field[@name='lastname']" position="attributes"> |
||||
|
<attribute name="attrs">{'required': [('firstname', '=', False), ('lastname2', '=', False), ('is_company', '=', False)]}</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//field[@name='lastname']" position="after"> |
||||
|
<field name="lastname2" attrs="{'required': [('firstname', '=', False), ('lastname', '=', False), ('is_company', '=', False)]}"/> |
||||
|
</xpath> |
||||
|
</data> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
<record id="partner_form" model="ir.ui.view"> |
||||
|
<field name="model">res.partner</field> |
||||
|
<field name="inherit_id" ref="partner_firstname.view_partner_form_firstname"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<data> |
||||
|
<!-- Main form --> |
||||
|
<xpath expr="//field[@name='firstname']" position="attributes"> |
||||
|
<attribute name="attrs">{'required': [('lastname', '=', False), ('lastname2', '=', False), ('is_company', '=', False)]}</attribute> |
||||
|
</xpath> |
||||
|
|
||||
|
<xpath expr="//field[@name='lastname']" position="attributes"> |
||||
|
<attribute name="attrs">{'required': [('firstname', '=', False), ('lastname2', '=', False), ('is_company', '=', False)]}</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//field[@name='lastname']" position="after"> |
||||
|
<field name="lastname2" attrs="{'required': [('firstname', '=', False), ('lastname', '=', False), ('is_company', '=', False)]}"/> |
||||
|
</xpath> |
||||
|
<!-- Inner contact form of child_ids --> |
||||
|
<xpath expr="//field[@name='child_ids']/form//field[@name='firstname']" position="attributes"> |
||||
|
<attribute name="attrs">{'required': [('lastname', '=', False), ('lastname2', '=', False), ('is_company', '=', False)]}</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//field[@name='child_ids']/form//field[@name='lastname']" position="attributes"> |
||||
|
<attribute name="attrs">{'required': [('firstname', '=', False), ('lastname2', '=', False), ('is_company', '=', False)]}</attribute> |
||||
|
</xpath> |
||||
|
<xpath expr="//field[@name='child_ids']/form//field[@name='lastname']" position="after"> |
||||
|
<field name="lastname2" attrs="{'required': [('firstname', '=', False), ('lastname', '=', False), ('is_company', '=', False)]}"/> |
||||
|
</xpath> |
||||
|
</data> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<!-- Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L.U. - Jairo Llopis |
||||
|
Copyright 2017 Tecnativa - Pedro M. Baeza |
||||
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). --> |
||||
|
<odoo> |
||||
|
|
||||
|
<record id="users_form" model="ir.ui.view"> |
||||
|
<field name="name">Add second last name</field> |
||||
|
<field name="model">res.users</field> |
||||
|
<field name="inherit_id" ref="partner_firstname.view_users_form"/> |
||||
|
<field name="arch" type="xml"> |
||||
|
<data> |
||||
|
<xpath expr="//field[@name='firstname']" position="attributes"> |
||||
|
<attribute name="attrs">{'required': [('lastname', '=', False), ('lastname2', '=', False)]}</attribute> |
||||
|
</xpath> |
||||
|
|
||||
|
<xpath expr="//field[@name='lastname']" position="attributes"> |
||||
|
<attribute name="attrs">{'required': [('firstname', '=', False), ('lastname2', '=', False)]}</attribute> |
||||
|
</xpath> |
||||
|
|
||||
|
<xpath expr="//field[@name='lastname']" position="after"> |
||||
|
<field name="lastname2" |
||||
|
attrs="{'required': [('firstname', '=', False), ('lastname', '=', False)]}" |
||||
|
/> |
||||
|
</xpath> |
||||
|
</data> |
||||
|
</field> |
||||
|
</record> |
||||
|
|
||||
|
</odoo> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue