Browse Source

Migrate to V12

pull/663/head
Graeme Gellatly 6 years ago
committed by Jairo Llopis
parent
commit
abe891084a
  1. 83
      partner_firstname/README.rst
  2. 4
      partner_firstname/__init__.py
  3. 9
      partner_firstname/__manifest__.py
  4. 3
      partner_firstname/exceptions.py
  5. 1
      partner_firstname/hooks.py
  6. 14
      partner_firstname/migrations/12.0.1.0.0/pre-ir_config_param.py
  7. 4
      partner_firstname/models/__init__.py
  8. 6
      partner_firstname/models/base_config_settings.py
  9. 10
      partner_firstname/models/res_partner.py
  10. 20
      partner_firstname/models/res_users.py
  11. 14
      partner_firstname/readme/CONFIGURE.rst
  12. 18
      partner_firstname/readme/CONTRIBUTORS.rst
  13. 2
      partner_firstname/readme/DESCRIPTION.rst
  14. 3
      partner_firstname/readme/ROADMAP.rst
  15. 13
      partner_firstname/readme/USAGE.rst
  16. 480
      partner_firstname/static/description/index.html
  17. 4
      partner_firstname/tests/__init__.py
  18. 12
      partner_firstname/tests/base.py
  19. 7
      partner_firstname/tests/test_create.py
  20. 7
      partner_firstname/tests/test_defaults.py
  21. 3
      partner_firstname/tests/test_delete.py
  22. 5
      partner_firstname/tests/test_empty.py
  23. 6
      partner_firstname/tests/test_name.py
  24. 5
      partner_firstname/tests/test_onchange.py
  25. 3
      partner_firstname/tests/test_order.py
  26. 5
      partner_firstname/tests/test_user_onchange.py
  27. 4
      partner_firstname/views/base_config_view.xml

83
partner_firstname/README.rst

@ -1,14 +1,38 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: https://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
================================ ================================
Partner first name and last name Partner first name and last name
================================ ================================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fpartner--contact-lightgray.png?logo=github
:target: https://github.com/OCA/partner-contact/tree/12.0/partner_firstname
:alt: OCA/partner-contact
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/partner-contact-12-0/partner-contact-12-0-partner_firstname
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/134/12.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4| |badge5|
This module was written to extend the functionality of contacts to support This module was written to extend the functionality of contacts to support
having separate last name and first name. having separate last name and first name.
**Table of contents**
.. contents::
:local:
Configuration Configuration
============= =============
@ -27,7 +51,6 @@ You can use *_get_inverse_name* method to get lastname and firstname from a simp
and also *_get_computed_name* to get a name form the lastname and firstname. and also *_get_computed_name* to get a name form the lastname and firstname.
These methods can be overridden to change the format specified above. These methods can be overridden to change the format specified above.
Usage Usage
===== =====
@ -45,15 +68,6 @@ For the same reason, after installing, previous names for contacts will stay in
the *name* field, and the first time you edit any of them you will be asked to the *name* field, and the first time you edit any of them you will be asked to
supply the *last name* and *first name* (just once per contact). supply the *last name* and *first name* (just once per contact).
.. 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/11.0
For further information, please visit:
* https://www.odoo.com/forum/help-1
Known issues / Roadmap Known issues / Roadmap
====================== ======================
@ -61,20 +75,30 @@ Patterns for the inverse function are configurable only at system level. Maybe
this configuration could depend on partner language, country or company, this configuration could depend on partner language, country or company,
as discussed at `this OCA issue <https://github.com/OCA/partner-contact/issues/210>`_ as discussed at `this OCA issue <https://github.com/OCA/partner-contact/issues/210>`_
Bug Tracker 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.
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 <https://github.com/OCA/partner-contact/issues/new?body=module:%20partner_firstname%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
Do not contact contributors directly about support or help with technical issues.
Credits Credits
======= =======
Authors
~~~~~~~
* Camptocamp
* Grupo ESOC Ingeniería de Servicios
* Tecnativa
* LasLabs
* ACSONE SA/NV
Contributors Contributors
------------
~~~~~~~~~~~~
* Nicolas Bessi <nicolas.bessi@camptocamp.com> * Nicolas Bessi <nicolas.bessi@camptocamp.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com> * Yannick Vaucher <yannick.vaucher@camptocamp.com>
@ -93,26 +117,21 @@ Contributors
* Sylvain Van Hoof * Sylvain Van Hoof
* Pedro Baeza <pedro.baeza@serviciosbaeza.com> * Pedro Baeza <pedro.baeza@serviciosbaeza.com>
* Dave Lasley <dave@laslabs.com> * Dave Lasley <dave@laslabs.com>
* Graeme Gellatly <graeme@o4sb.com>
Translations
------------
* Danish: Hans Henrik Gabelgaard
* Italian: Leonardo Donelli
* Spanish: Antonio Espinosa
* Antonio Espinosa <antonioea@antiun.com>
Maintainers
~~~~~~~~~~~
Maintainer
----------
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png .. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association :alt: Odoo Community Association
:target: https://odoo-community.org :target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.
This module is part of the `OCA/partner-contact <https://github.com/OCA/partner-contact/tree/12.0/partner_firstname>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

4
partner_firstname/__init__.py

@ -1,6 +1,2 @@
# -*- coding: utf-8 -*-
# © 2013 Nicolas Bessi (Camptocamp SA)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import models from . import models
from .hooks import post_init_hook from .hooks import post_init_hook

9
partner_firstname/__manifest__.py

@ -1,13 +1,12 @@
# -*- coding: utf-8 -*-
# © 2013 Nicolas Bessi (Camptocamp SA)
# © 2014 Agile Business Group (<http://www.agilebg.com>)
# © 2015 Grupo ESOC (<http://www.grupoesoc.es>)
# Copyright 2013 Nicolas Bessi (Camptocamp SA)
# Copyright 2014 Agile Business Group (<http://www.agilebg.com>)
# Copyright 2015 Grupo ESOC (<http://www.grupoesoc.es>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{ {
'name': 'Partner first name and last name', 'name': 'Partner first name and last name',
'summary': "Split first name and last name for non company partners", 'summary': "Split first name and last name for non company partners",
'version': '11.0.1.0.1',
'version': '12.0.1.0.0',
'author': "Camptocamp, " 'author': "Camptocamp, "
"Grupo ESOC Ingeniería de Servicios, " "Grupo ESOC Ingeniería de Servicios, "
"Tecnativa, " "Tecnativa, "

3
partner_firstname/exceptions.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# © 2014-2015 Grupo ESOC (<http://www.grupoesoc.es>)
# Copyright 2014-2015 Grupo ESOC (<http://www.grupoesoc.es>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import _, exceptions from odoo import _, exceptions

1
partner_firstname/hooks.py

@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017 LasLabs Inc. # Copyright 2017 LasLabs Inc.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

14
partner_firstname/migrations/12.0.1.0.0/pre-ir_config_param.py

@ -0,0 +1,14 @@
def store_ir_config_param(cr):
"""Prior to version 12.0 the default order of partner
names was last_first. In order to retain this behaviour we
store the config parameter if it is not present.
"""
cr.execute("SELECT 1 FROM ir_config_parameter "
"WHERE name = 'partner_names_order'")
if not cr.fetchone():
cr.execute("INSERT INTO ir_config_parameter (key, value) VALUES "
"('partner_names_order', 'last_first')")
def migrate(cr, version):
store_ir_config_param(cr)

4
partner_firstname/models/__init__.py

@ -1,7 +1,3 @@
# -*- 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 base_config_settings
from . import res_partner from . import res_partner
from . import res_users from . import res_users

6
partner_firstname/models/base_config_settings.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# Copyright 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging import logging
@ -73,6 +72,9 @@ class ResConfigSettings(models.TransientModel):
@api.multi @api.multi
def action_recalculate_partners_name(self): def action_recalculate_partners_name(self):
self.env['ir.config_parameter'].sudo().set_param(
'partner_names_order', self.partner_names_order
)
partners = self._partners_for_recalculating() partners = self._partners_for_recalculating()
_logger.info("Recalculating names for %d partners.", len(partners)) _logger.info("Recalculating names for %d partners.", len(partners))
partners._compute_name() partners._compute_name()

10
partner_firstname/models/res_partner.py

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# © 2013 Nicolas Bessi (Camptocamp SA)
# © 2014 Agile Business Group (<http://www.agilebg.com>)
# © 2015 Grupo ESOC (<http://www.grupoesoc.es>)
# Copyright 2013 Nicolas Bessi (Camptocamp SA)
# Copyright 2014 Agile Business Group (<http://www.agilebg.com>)
# Copyright 2015 Grupo ESOC (<http://www.grupoesoc.es>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging import logging
from odoo import api, fields, models from odoo import api, fields, models
@ -40,7 +39,6 @@ class ResPartner(models.Model):
self._get_whitespace_cleaned_name(name), self._get_whitespace_cleaned_name(name),
vals.get("is_company", vals.get("is_company",
self.default_get(["is_company"])["is_company"])) self.default_get(["is_company"])["is_company"]))
for key, value in inverted.items(): for key, value in inverted.items():
if not vals.get(key) or context.get("copy"): if not vals.get(key) or context.get("copy"):
vals[key] = value vals[key] = value
@ -80,7 +78,7 @@ class ResPartner(models.Model):
@api.model @api.model
def _names_order_default(self): def _names_order_default(self):
return 'last_first'
return 'first_last'
@api.model @api.model
def _get_names_order(self): def _get_names_order(self):

20
partner_firstname/models/res_users.py

@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
# © 2013 Nicolas Bessi (Camptocamp SA)
# © 2014 Agile Business Group (<http://www.agilebg.com>)
# © 2015 Grupo ESOC (<http://www.grupoesoc.es>)
# Copyright 2013 Nicolas Bessi (Camptocamp SA)
# Copyright 2014 Agile Business Group (<http://www.agilebg.com>)
# Copyright 2015 Grupo ESOC (<http://www.grupoesoc.es>)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, models, _ from odoo import api, models, _
@ -32,14 +31,19 @@ class ResUser(models.Model):
rec.name = rec.partner_id._get_computed_name( rec.name = rec.partner_id._get_computed_name(
rec.lastname, rec.firstname) rec.lastname, rec.firstname)
@api.multi
@api.model
def copy(self, default=None): def copy(self, default=None):
self.ensure_one() self.ensure_one()
default = dict(default or {}) default = dict(default or {})
if ('name' not in default) and ('partner_id' not in default):
if (('name' not in default) and
('partner_id' not in default)):
default['name'] = _("%s (copy)") % self.name default['name'] = _("%s (copy)") % self.name
if 'login' not in default: if 'login' not in default:
default['login'] = _("%s (copy)") % self.login default['login'] = _("%s (copy)") % self.login
if ('firstname' not in default) and ('lastname' not in default) and ('name' in default):
default.update(self.env['res.partner']._get_inverse_name(default['name'], False))
if (('firstname' not in default) and
('lastname' not in default) and
('name' in default)):
default.update(self.env['res.partner']._get_inverse_name(
default['name'], False)
)
return super(ResUser, self).copy(default) return super(ResUser, self).copy(default)

14
partner_firstname/readme/CONFIGURE.rst

@ -0,0 +1,14 @@
You can configure some common name patterns for the inverse function
in Settings > General settings:
* Lastname Firstname: For example 'Anderson Robert'
* Lastname, Firstname: For example 'Anderson, Robert'
* Firstname Lastname: For example 'Robert Anderson'
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 lastname and firstname from a simple string
and also *_get_computed_name* to get a name form the lastname and firstname.
These methods can be overridden to change the format specified above.

18
partner_firstname/readme/CONTRIBUTORS.rst

@ -0,0 +1,18 @@
* Nicolas Bessi <nicolas.bessi@camptocamp.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Vincent Renaville <vincent.renaville@camptocamp.com>
* Guewen Baconnier <guewen.baconnier@camptocamp.com>
* Holger Brunn <hbrunn@terp.nl>
* Jonathan Nemry <jonathan.nemry@acsone.eu>
* Olivier Laurent <olivier.laurent@acsone.eu>
* Sandy Carter <sandy.carter@savoirfairelinux.com>
* Alexis de Lattre <alexis.delattre@akretion.fr>
* Lorenzo Battistini <lorenzo.battistini@agilebg.com>
* Hans Henrik Gabelgaard <hhg@gabelgaard.org>
* Jairo Llopis <j.llopis@grupoesoc.es>
* Adrien Peiffer <adrien.peiffer@acsone.eu>
* Ronald Portier <ronald@therp.nl>
* Sylvain Van Hoof
* Pedro Baeza <pedro.baeza@serviciosbaeza.com>
* Dave Lasley <dave@laslabs.com>
* Graeme Gellatly <graeme@o4sb.com>

2
partner_firstname/readme/DESCRIPTION.rst

@ -0,0 +1,2 @@
This module was written to extend the functionality of contacts to support
having separate last name and first name.

3
partner_firstname/readme/ROADMAP.rst

@ -0,0 +1,3 @@
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>`_

13
partner_firstname/readme/USAGE.rst

@ -0,0 +1,13 @@
The field *name* becomes a stored function field concatenating the *last name*
and the *first name*. This avoids breaking compatibility with other modules.
Users should fulfill manually the separate fields for *last name* and *first
name*, but in case you edit just the *name* field in some unexpected module,
there is an inverse function that tries to split that automatically. It assumes
that you write the *name* in format configured (*"Lastname Firstname"*, by default),
but it could lead to wrong splitting (because it's just blindly trying to
guess what you meant), so you better specify it manually.
For the same reason, after installing, previous names for contacts will stay in
the *name* field, and the first time you edit any of them you will be asked to
supply the *last name* and *first name* (just once per contact).

480
partner_firstname/static/description/index.html

@ -0,0 +1,480 @@
<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" />
<title>Partner first name and last name</title>
<style type="text/css">
/*
:Author: David Goodger (goodger@python.org)
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $
:Copyright: This stylesheet has been placed in the public domain.
Default cascading style sheet for the HTML output of Docutils.
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to
customize this style sheet.
*/
/* used to remove borders from tables and images */
.borderless, table.borderless td, table.borderless th {
border: 0 }
table.borderless td, table.borderless th {
/* Override padding for "table.docutils td" with "! important".
The right padding separates the table cells. */
padding: 0 0.5em 0 0 ! important }
.first {
/* Override more specific margin styles with "! important". */
margin-top: 0 ! important }
.last, .with-subtitle {
margin-bottom: 0 ! important }
.hidden {
display: none }
.subscript {
vertical-align: sub;
font-size: smaller }
.superscript {
vertical-align: super;
font-size: smaller }
a.toc-backref {
text-decoration: none ;
color: black }
blockquote.epigraph {
margin: 2em 5em ; }
dl.docutils dd {
margin-bottom: 0.5em }
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] {
overflow: hidden;
}
/* Uncomment (and remove this text!) to get bold-faced definition list terms
dl.docutils dt {
font-weight: bold }
*/
div.abstract {
margin: 2em 5em }
div.abstract p.topic-title {
font-weight: bold ;
text-align: center }
div.admonition, div.attention, div.caution, div.danger, div.error,
div.hint, div.important, div.note, div.tip, div.warning {
margin: 2em ;
border: medium outset ;
padding: 1em }
div.admonition p.admonition-title, div.hint p.admonition-title,
div.important p.admonition-title, div.note p.admonition-title,
div.tip p.admonition-title {
font-weight: bold ;
font-family: sans-serif }
div.attention p.admonition-title, div.caution p.admonition-title,
div.danger p.admonition-title, div.error p.admonition-title,
div.warning p.admonition-title, .code .error {
color: red ;
font-weight: bold ;
font-family: sans-serif }
/* Uncomment (and remove this text!) to get reduced vertical space in
compound paragraphs.
div.compound .compound-first, div.compound .compound-middle {
margin-bottom: 0.5em }
div.compound .compound-last, div.compound .compound-middle {
margin-top: 0.5em }
*/
div.dedication {
margin: 2em 5em ;
text-align: center ;
font-style: italic }
div.dedication p.topic-title {
font-weight: bold ;
font-style: normal }
div.figure {
margin-left: 2em ;
margin-right: 2em }
div.footer, div.header {
clear: both;
font-size: smaller }
div.line-block {
display: block ;
margin-top: 1em ;
margin-bottom: 1em }
div.line-block div.line-block {
margin-top: 0 ;
margin-bottom: 0 ;
margin-left: 1.5em }
div.sidebar {
margin: 0 0 0.5em 1em ;
border: medium outset ;
padding: 1em ;
background-color: #ffffee ;
width: 40% ;
float: right ;
clear: right }
div.sidebar p.rubric {
font-family: sans-serif ;
font-size: medium }
div.system-messages {
margin: 5em }
div.system-messages h1 {
color: red }
div.system-message {
border: medium outset ;
padding: 1em }
div.system-message p.system-message-title {
color: red ;
font-weight: bold }
div.topic {
margin: 2em }
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle,
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle {
margin-top: 0.4em }
h1.title {
text-align: center }
h2.subtitle {
text-align: center }
hr.docutils {
width: 75% }
img.align-left, .figure.align-left, object.align-left, table.align-left {
clear: left ;
float: left ;
margin-right: 1em }
img.align-right, .figure.align-right, object.align-right, table.align-right {
clear: right ;
float: right ;
margin-left: 1em }
img.align-center, .figure.align-center, object.align-center {
display: block;
margin-left: auto;
margin-right: auto;
}
table.align-center {
margin-left: auto;
margin-right: auto;
}
.align-left {
text-align: left }
.align-center {
clear: both ;
text-align: center }
.align-right {
text-align: right }
/* reset inner alignment in figures */
div.align-right {
text-align: inherit }
/* div.align-center * { */
/* text-align: left } */
.align-top {
vertical-align: top }
.align-middle {
vertical-align: middle }
.align-bottom {
vertical-align: bottom }
ol.simple, ul.simple {
margin-bottom: 1em }
ol.arabic {
list-style: decimal }
ol.loweralpha {
list-style: lower-alpha }
ol.upperalpha {
list-style: upper-alpha }
ol.lowerroman {
list-style: lower-roman }
ol.upperroman {
list-style: upper-roman }
p.attribution {
text-align: right ;
margin-left: 50% }
p.caption {
font-style: italic }
p.credits {
font-style: italic ;
font-size: smaller }
p.label {
white-space: nowrap }
p.rubric {
font-weight: bold ;
font-size: larger ;
color: maroon ;
text-align: center }
p.sidebar-title {
font-family: sans-serif ;
font-weight: bold ;
font-size: larger }
p.sidebar-subtitle {
font-family: sans-serif ;
font-weight: bold }
p.topic-title {
font-weight: bold }
pre.address {
margin-bottom: 0 ;
margin-top: 0 ;
font: inherit }
pre.literal-block, pre.doctest-block, pre.math, pre.code {
margin-left: 2em ;
margin-right: 2em }
pre.code .ln { color: grey; } /* line numbers */
pre.code, code { background-color: #eeeeee }
pre.code .comment, code .comment { color: #5C6576 }
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold }
pre.code .literal.string, code .literal.string { color: #0C5404 }
pre.code .name.builtin, code .name.builtin { color: #352B84 }
pre.code .deleted, code .deleted { background-color: #DEB0A1}
pre.code .inserted, code .inserted { background-color: #A3D289}
span.classifier {
font-family: sans-serif ;
font-style: oblique }
span.classifier-delimiter {
font-family: sans-serif ;
font-weight: bold }
span.interpreted {
font-family: sans-serif }
span.option {
white-space: nowrap }
span.pre {
white-space: pre }
span.problematic {
color: red }
span.section-subtitle {
/* font-size relative to parent (h1..h6 element) */
font-size: 80% }
table.citation {
border-left: solid 1px gray;
margin-left: 1px }
table.docinfo {
margin: 2em 4em }
table.docutils {
margin-top: 0.5em ;
margin-bottom: 0.5em }
table.footnote {
border-left: solid 1px black;
margin-left: 1px }
table.docutils td, table.docutils th,
table.docinfo td, table.docinfo th {
padding-left: 0.5em ;
padding-right: 0.5em ;
vertical-align: top }
table.docutils th.field-name, table.docinfo th.docinfo-name {
font-weight: bold ;
text-align: left ;
white-space: nowrap ;
padding-left: 0 }
/* "booktabs" style (no vertical lines) */
table.docutils.booktabs {
border: 0px;
border-top: 2px solid;
border-bottom: 2px solid;
border-collapse: collapse;
}
table.docutils.booktabs * {
border: 0px;
}
table.docutils.booktabs th {
border-bottom: thin solid;
text-align: left;
}
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils,
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils {
font-size: 100% }
ul.auto-toc {
list-style-type: none }
</style>
</head>
<body>
<div class="document" id="partner-first-name-and-last-name">
<h1 class="title">Partner first name and last name</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/partner-contact/tree/12.0/partner_firstname"><img alt="OCA/partner-contact" src="https://img.shields.io/badge/github-OCA%2Fpartner--contact-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/partner-contact-12-0/partner-contact-12-0-partner_firstname"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/134/12.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p>
<p>This module was written to extend the functionality of contacts to support
having separate last name and first name.</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
<li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li>
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li>
<li><a class="reference internal" href="#known-issues-roadmap" id="id3">Known issues / Roadmap</a></li>
<li><a class="reference internal" href="#bug-tracker" id="id4">Bug Tracker</a></li>
<li><a class="reference internal" href="#credits" id="id5">Credits</a><ul>
<li><a class="reference internal" href="#authors" id="id6">Authors</a></li>
<li><a class="reference internal" href="#contributors" id="id7">Contributors</a></li>
<li><a class="reference internal" href="#maintainers" id="id8">Maintainers</a></li>
</ul>
</li>
</ul>
</div>
<div class="section" id="configuration">
<h1><a class="toc-backref" href="#id1">Configuration</a></h1>
<p>You can configure some common name patterns for the inverse function
in Settings &gt; General settings:</p>
<ul class="simple">
<li>Lastname Firstname: For example ‘Anderson Robert’</li>
<li>Lastname, Firstname: For example ‘Anderson, Robert’</li>
<li>Firstname Lastname: For example ‘Robert Anderson’</li>
</ul>
<p>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.</p>
<p>You can use <em>_get_inverse_name</em> method to get lastname and firstname from a simple string
and also <em>_get_computed_name</em> to get a name form the lastname and firstname.
These methods can be overridden to change the format specified above.</p>
</div>
<div class="section" id="usage">
<h1><a class="toc-backref" href="#id2">Usage</a></h1>
<p>The field <em>name</em> becomes a stored function field concatenating the <em>last name</em>
and the <em>first name</em>. This avoids breaking compatibility with other modules.</p>
<p>Users should fulfill manually the separate fields for <em>last name</em> and <em>first
name</em>, but in case you edit just the <em>name</em> field in some unexpected module,
there is an inverse function that tries to split that automatically. It assumes
that you write the <em>name</em> in format configured (<em>“Lastname Firstname”</em>, by default),
but it could lead to wrong splitting (because it’s just blindly trying to
guess what you meant), so you better specify it manually.</p>
<p>For the same reason, after installing, previous names for contacts will stay in
the <em>name</em> field, and the first time you edit any of them you will be asked to
supply the <em>last name</em> and <em>first name</em> (just once per contact).</p>
</div>
<div class="section" id="known-issues-roadmap">
<h1><a class="toc-backref" href="#id3">Known issues / Roadmap</a></h1>
<p>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 <a class="reference external" href="https://github.com/OCA/partner-contact/issues/210">this OCA issue</a></p>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#id4">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/partner-contact/issues">GitHub Issues</a>.
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
<a class="reference external" href="https://github.com/OCA/partner-contact/issues/new?body=module:%20partner_firstname%0Aversion:%2012.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h1><a class="toc-backref" href="#id5">Credits</a></h1>
<div class="section" id="authors">
<h2><a class="toc-backref" href="#id6">Authors</a></h2>
<ul class="simple">
<li>Camptocamp</li>
<li>Grupo ESOC Ingeniería de Servicios</li>
<li>Tecnativa</li>
<li>LasLabs</li>
<li>ACSONE SA/NV</li>
</ul>
</div>
<div class="section" id="contributors">
<h2><a class="toc-backref" href="#id7">Contributors</a></h2>
<ul class="simple">
<li>Nicolas Bessi &lt;<a class="reference external" href="mailto:nicolas.bessi&#64;camptocamp.com">nicolas.bessi&#64;camptocamp.com</a>&gt;</li>
<li>Yannick Vaucher &lt;<a class="reference external" href="mailto:yannick.vaucher&#64;camptocamp.com">yannick.vaucher&#64;camptocamp.com</a>&gt;</li>
<li>Vincent Renaville &lt;<a class="reference external" href="mailto:vincent.renaville&#64;camptocamp.com">vincent.renaville&#64;camptocamp.com</a>&gt;</li>
<li>Guewen Baconnier &lt;<a class="reference external" href="mailto:guewen.baconnier&#64;camptocamp.com">guewen.baconnier&#64;camptocamp.com</a>&gt;</li>
<li>Holger Brunn &lt;<a class="reference external" href="mailto:hbrunn&#64;terp.nl">hbrunn&#64;terp.nl</a>&gt;</li>
<li>Jonathan Nemry &lt;<a class="reference external" href="mailto:jonathan.nemry&#64;acsone.eu">jonathan.nemry&#64;acsone.eu</a>&gt;</li>
<li>Olivier Laurent &lt;<a class="reference external" href="mailto:olivier.laurent&#64;acsone.eu">olivier.laurent&#64;acsone.eu</a>&gt;</li>
<li>Sandy Carter &lt;<a class="reference external" href="mailto:sandy.carter&#64;savoirfairelinux.com">sandy.carter&#64;savoirfairelinux.com</a>&gt;</li>
<li>Alexis de Lattre &lt;<a class="reference external" href="mailto:alexis.delattre&#64;akretion.fr">alexis.delattre&#64;akretion.fr</a>&gt;</li>
<li>Lorenzo Battistini &lt;<a class="reference external" href="mailto:lorenzo.battistini&#64;agilebg.com">lorenzo.battistini&#64;agilebg.com</a>&gt;</li>
<li>Hans Henrik Gabelgaard &lt;<a class="reference external" href="mailto:hhg&#64;gabelgaard.org">hhg&#64;gabelgaard.org</a>&gt;</li>
<li>Jairo Llopis &lt;<a class="reference external" href="mailto:j.llopis&#64;grupoesoc.es">j.llopis&#64;grupoesoc.es</a>&gt;</li>
<li>Adrien Peiffer &lt;<a class="reference external" href="mailto:adrien.peiffer&#64;acsone.eu">adrien.peiffer&#64;acsone.eu</a>&gt;</li>
<li>Ronald Portier &lt;<a class="reference external" href="mailto:ronald&#64;therp.nl">ronald&#64;therp.nl</a>&gt;</li>
<li>Sylvain Van Hoof</li>
<li>Pedro Baeza &lt;<a class="reference external" href="mailto:pedro.baeza&#64;serviciosbaeza.com">pedro.baeza&#64;serviciosbaeza.com</a>&gt;</li>
<li>Dave Lasley &lt;<a class="reference external" href="mailto:dave&#64;laslabs.com">dave&#64;laslabs.com</a>&gt;</li>
<li>Graeme Gellatly &lt;<a class="reference external" href="mailto:graeme&#64;o4sb.com">graeme&#64;o4sb.com</a>&gt;</li>
</ul>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#id8">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a>
<p>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.</p>
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/partner-contact/tree/12.0/partner_firstname">OCA/partner-contact</a> project on GitHub.</p>
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p>
</div>
</div>
</div>
</body>
</html>

4
partner_firstname/tests/__init__.py

@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
# © 2014 Nemry Jonathan (Acsone SA/NV) (http://www.acsone.eu)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from . import ( from . import (
test_create, test_create,
test_defaults, test_defaults,

12
partner_firstname/tests/base.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# © 2014 Nemry Jonathan (Acsone SA/NV) (http://www.acsone.eu)
# Copyright 2014 Nemry Jonathan (Acsone SA/NV) (http://www.acsone.eu)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
@ -23,14 +23,14 @@ class BaseCase(TransactionCase, MailInstalled):
def create_original(self): def create_original(self):
self.original = self.env["res.partner"].create({ self.original = self.env["res.partner"].create({
"lastname": self.lastname,
"firstname": self.firstname})
"firstname": self.firstname,
"lastname": self.lastname})
def expect(self, lastname, firstname, name=None): def expect(self, lastname, firstname, name=None):
"""Define what is expected in each field when ending.""" """Define what is expected in each field when ending."""
self.lastname = lastname self.lastname = lastname
self.firstname = firstname self.firstname = firstname
self.name = name or "%s %s" % (lastname, firstname)
self.name = name or "%s %s" % (firstname, lastname)
def tearDown(self): def tearDown(self):
if self.check_fields: if self.check_fields:
@ -47,7 +47,7 @@ class BaseCase(TransactionCase, MailInstalled):
def test_copy(self): def test_copy(self):
"""Copy the partner and compare the result.""" """Copy the partner and compare the result."""
self.expect(self.lastname, "%s (copy)" % self.firstname)
self.expect("%s (copy)" % self.lastname, self.firstname)
self.changed = (self.original.with_context(copy=True, lang="en_US") self.changed = (self.original.with_context(copy=True, lang="en_US")
.copy()) .copy())

7
partner_firstname/tests/test_create.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# © 2015 Grupo ESOC Ingeniería de Servicios, S.L. - Jairo Llopis.
# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L. - Jairo Llopis.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
"""Test default values for models.""" """Test default values for models."""
@ -19,8 +18,8 @@ class PersonCase(TransactionCase):
"firstname": "Núñez", "firstname": "Núñez",
"lastname": "Fernán", "lastname": "Fernán",
} }
self.good_values["name"] = "%s %s" % (self.good_values["lastname"],
self.good_values["firstname"])
self.good_values["name"] = "%s %s" % (self.good_values["firstname"],
self.good_values["lastname"])
if "default_is_company" in self.context: if "default_is_company" in self.context:
self.good_values["is_company"] = self.context["default_is_company"] self.good_values["is_company"] = self.context["default_is_company"]
self.values = self.good_values.copy() self.values = self.good_values.copy()

7
partner_firstname/tests/test_defaults.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# © 2015 Grupo ESOC Ingeniería de Servicios, S.L. - Jairo Llopis.
# Copyright 2015 Grupo ESOC Ingeniería de Servicios, S.L. - Jairo Llopis.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
"""Test default values for models.""" """Test default values for models."""
@ -19,8 +18,8 @@ class PersonCase(TransactionCase):
"firstname": "Núñez", "firstname": "Núñez",
"lastname": "Fernán", "lastname": "Fernán",
} }
self.values["name"] = "%s %s" % (self.values["lastname"],
self.values["firstname"])
self.values["name"] = "%s %s" % (self.values["firstname"],
self.values["lastname"])
if "default_is_company" in self.context: if "default_is_company" in self.context:
self.values["is_company"] = self.context["default_is_company"] self.values["is_company"] = self.context["default_is_company"]

3
partner_firstname/tests/test_delete.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# © 2015 Grupo ESOC
# Copyright 2015 Grupo ESOC
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase

5
partner_firstname/tests/test_empty.py

@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
# © 2014-2015 Grupo ESOC <www.grupoesoc.es>
# © 2016 Yannick Vaucher (Camptocamp)
# Copyright 2014-2015 Grupo ESOC <www.grupoesoc.es>
# Copyright 2016 Yannick Vaucher (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
"""Test situations where names are empty. """Test situations where names are empty.

6
partner_firstname/tests/test_name.py

@ -1,5 +1,3 @@
# -*- coding: utf-8 -*-
# Authors: Nemry Jonathan # Authors: Nemry Jonathan
# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) # Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu)
# All Rights Reserved # All Rights Reserved
@ -47,7 +45,7 @@ class PartnerContactCase(BaseCase):
def test_whitespace_cleanup(self): def test_whitespace_cleanup(self):
"""Check that whitespace in name gets cleared.""" """Check that whitespace in name gets cleared."""
self.expect("newlästname", "newfïrstname") self.expect("newlästname", "newfïrstname")
self.original.name = " newlästname newfïrstname "
self.original.name = " newfïrstname newlästname "
# Need this to refresh the ``name`` field # Need this to refresh the ``name`` field
self.original.invalidate_cache() self.original.invalidate_cache()
@ -72,7 +70,7 @@ class PartnerCompanyCase(BaseCase):
class UserCase(PartnerContactCase): class UserCase(PartnerContactCase):
def create_original(self): def create_original(self):
name = "%s %s" % (self.lastname, self.firstname)
name = "%s %s" % (self.firstname, self.lastname)
# Cannot create users if ``mail`` is installed # Cannot create users if ``mail`` is installed
if self.mail_installed(): if self.mail_installed():

5
partner_firstname/tests/test_onchange.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# © 2015 Grupo ESOC <www.grupoesoc.es>
# Copyright 2015 Grupo ESOC <www.grupoesoc.es>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
"""These tests try to mimic the behavior of the UI form. """These tests try to mimic the behavior of the UI form.
@ -102,4 +101,4 @@ class PartnerContactCase(OnChangeCase):
self.assertEqual(partner.lastname, lastname) self.assertEqual(partner.lastname, lastname)
self.assertEqual(partner.firstname, firstname) self.assertEqual(partner.firstname, firstname)
self.assertEqual(partner.name, " ".join((lastname, firstname)))
self.assertEqual(partner.name, " ".join((firstname, lastname)))

3
partner_firstname/tests/test_order.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# Copyright 2015 Antiun Ingenieria S.L. - Antonio Espinosa
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase

5
partner_firstname/tests/test_user_onchange.py

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*-
# © 2016 Yannick Vaucher (Camptocamp SA)
# Copyright 2016 Yannick Vaucher (Camptocamp SA)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo.tests.common import TransactionCase from odoo.tests.common import TransactionCase
@ -46,7 +45,7 @@ class UserOnchangeCase(TransactionCase):
self.assertEqual(self.user.lastname, lastname) self.assertEqual(self.user.lastname, lastname)
self.assertEqual(self.user.firstname, firstname) self.assertEqual(self.user.firstname, firstname)
self.assertEqual(self.user.name, " ".join((lastname, firstname)))
self.assertEqual(self.user.name, " ".join((firstname, lastname)))
def setUp(self): def setUp(self):
super(UserOnchangeCase, self).setUp() super(UserOnchangeCase, self).setUp()

4
partner_firstname/views/base_config_view.xml

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- © 2015 Antiun Ingenieria S.L. - Antonio Espinosa
<!-- Copyright 2015 Antiun Ingenieria S.L. - Antonio Espinosa
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). --> License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
<odoo> <odoo>
@ -10,7 +10,7 @@
ref="base_setup.res_config_settings_view_form"/> ref="base_setup.res_config_settings_view_form"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<xpath expr="//div[@name='multi_company']" position='after'> <xpath expr="//div[@name='multi_company']" position='after'>
<h2>Partner names order</h2>
<h2>Partner Names Order</h2>
<div class="row mt16 o_settings_container" <div class="row mt16 o_settings_container"
name="partner_names_order"> name="partner_names_order">
<div class="col-xs-12 col-md-6 o_setting_box"> <div class="col-xs-12 col-md-6 o_setting_box">

Loading…
Cancel
Save