Skip to content

Commit

Permalink
Merge PR #1784 into 17.0
Browse files Browse the repository at this point in the history
Signed-off-by moylop260
  • Loading branch information
OCA-git-bot committed Jun 18, 2024
2 parents 677e517 + 388e9b6 commit 420747f
Show file tree
Hide file tree
Showing 10 changed files with 291 additions and 88 deletions.
122 changes: 60 additions & 62 deletions partner_firstname/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Partner first name and last name
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:547c95a6de4508c96e86e379cfb2d96346381f4b965614d586b2cd48a0eed9b9
!! source digest: sha256:3488c0565691627a30d74647ddd160cead71719973fc68d77008bbb91af2445f
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand All @@ -17,19 +17,19 @@ Partner first name and last name
: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/17.0/partner_firstname
:target: https://github.com/OCA/partner-contact/tree/16.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-17-0/partner-contact-17-0-partner_firstname
:target: https://translation.odoo-community.org/projects/partner-contact-16-0/partner-contact-16-0-partner_firstname
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/partner-contact&target_branch=17.0
:target: https://runboat.odoo-community.org/builds?repo=OCA/partner-contact&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module was written to extend the functionality of contacts to
support having separate last name and first name.
This module was written to extend the functionality of contacts to support
having separate last name and first name.

**Table of contents**

Expand All @@ -39,65 +39,60 @@ support having separate last name and first name.
Configuration
=============

You can configure some common name patterns for the inverse function in
Settings > General settings:
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'
* 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.
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.
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.

Usage
=====

The field *name* becomes a stored function field concatenating the *last
name* and the *first name*. This avoids breaking compatibility with
other modules.
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.
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).
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).

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>`__
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 to smash it by providing a detailed and welcomed
`feedback <https://github.com/OCA/partner-contact/issues/new?body=module:%20partner_firstname%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/OCA/partner-contact/issues/new?body=module:%20partner_firstname%0Aversion:%2016.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
=======

Authors
-------
~~~~~~~

* Camptocamp
* Grupo ESOC Ingeniería de Servicios
Expand All @@ -107,31 +102,34 @@ Authors
* DynApps NV

Contributors
------------

- 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>
- Laurent Mignon <laurent.mignon@acsone.eu>
- Bjorn Billen <bjorn.billen@dynapps.be>
~~~~~~~~~~~~

* 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>
* Laurent Mignon <laurent.mignon@acsone.eu>
* Bjorn Billen <bjorn.billen@dynapps.be>
* `Aion Tech <https://aiontech.company/>`_:

* Simone Rubino <simone.rubino@aion-tech.it>

Maintainers
-----------
~~~~~~~~~~~

This module is maintained by the OCA.

Expand All @@ -143,6 +141,6 @@ 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.

This module is part of the `OCA/partner-contact <https://github.com/OCA/partner-contact/tree/17.0/partner_firstname>`_ project on GitHub.
This module is part of the `OCA/partner-contact <https://github.com/OCA/partner-contact/tree/16.0/partner_firstname>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
5 changes: 4 additions & 1 deletion partner_firstname/models/base_config_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,10 @@ def action_recalculate_partners_name(self):
)
partners = self._partners_for_recalculating()
_logger.info("Recalculating names for %d partners.", len(partners))
partners._compute_name()
# Use add_to_compute instead of _compute_name to avoid triggering
# _inverse_name_after_cleaning_whitespace, which can
# modify a partner's firstname, lastname and lastname2
self.env.add_to_compute(self.env["res.partner"]._fields["name"], partners)
self.partner_names_order_changed = False
self.execute()
_logger.info("%d partners updated.", len(partners))
Expand Down
93 changes: 69 additions & 24 deletions partner_firstname/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# Copyright 2013 Nicolas Bessi (Camptocamp SA)
# Copyright 2014 Agile Business Group (<http://www.agilebg.com>)
# Copyright 2015 Grupo ESOC (<http://www.grupoesoc.es>)
# Copyright 2024 Simone Rubino - Aion Tech
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging

from odoo import api, fields, models
from odoo import _, api, fields, models

from .. import exceptions

Expand All @@ -26,32 +27,71 @@ class ResPartner(models.Model):
readonly=False,
)

@api.model
def name_fields_in_vals(self, vals):
"""Method to check if any name fields are in `vals`."""
return vals.get("firstname") or vals.get("lastname")

@api.model_create_multi
def create(self, vals_list):
"""Add inverted names at creation if unavailable."""
context = dict(self.env.context)
"""Add inverted names at creation if unavailable. Also, remove the full name
from `vals` and context if the partner is an individual and is being created
with any name fields, as the name must be computed from the provided name parts;
otherwise, the name fields will be computed from the `name` again, when calling
its inverse method.
Note that, to avoid deleting the 'default_name' context for all partners when
it's not appropriate, we must call `create` for each partner individually with
the correct context.
"""
created_partners = self.browse()
for vals in vals_list:
name = vals.get("name", context.get("default_name"))

if name is not None:
# Calculate the splitted fields
inverted = self._get_inverse_name(
self._get_whitespace_cleaned_name(name),
vals.get(
"is_company", self.default_get(["is_company"])["is_company"]
),
)
for key, value in inverted.items():
if not vals.get(key) or context.get("copy"):
vals[key] = value

# Remove the combined fields
if "name" in vals:
del vals["name"]
if "default_name" in context:
del context["default_name"]
# pylint: disable=W8121
return super(ResPartner, self.with_context(context)).create(vals_list)
partner_context = dict(self.env.context)
if (
not vals.get("is_company")
and self.name_fields_in_vals(vals)
and "name" in vals
):
del vals["name"]
partner_context.pop("default_name", None)
else:
name = vals.get("name", partner_context.get("default_name"))
if name is not None:
# Calculate the split fields
inverted = self._get_inverse_name(
self._get_whitespace_cleaned_name(name),
vals.get(
"is_company", self.default_get(["is_company"])["is_company"]
),
)
for key, value in inverted.items():
if not vals.get(key) or partner_context.get("copy"):
vals[key] = value

# Remove the combined fields
vals.pop("name", None)
partner_context.pop("default_name", None)
# pylint: disable=W8121
created_partners |= super(
ResPartner, self.with_context(partner_context)
).create([vals])
return created_partners

def get_extra_default_copy_values(self, order):
"""Method to add '(copy)' suffix to lastname or firstname, depending on name
order configuration.
"""
if order == "first_last":
return {
"lastname": _("%s (copy)", self.lastname)
if self.lastname
else _("(copy)")
}
return {
"firstname": _("%s (copy)", self.firstname)
if self.firstname
else _("(copy)")
}

def copy(self, default=None):
"""Ensure partners are copied right.
Expand All @@ -60,6 +100,11 @@ def copy(self, default=None):
ignored in :meth:`~.create` because it also copies explicitly firstname
and lastname fields.
"""
default = default or {}
if not self.is_company:
order = self._get_names_order()
extra_default_values = self.get_extra_default_copy_values(order)
default.update(extra_default_values)
return super(ResPartner, self.with_context(copy=True)).copy(default)

@api.model
Expand Down
23 changes: 23 additions & 0 deletions partner_firstname/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
* 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>
* Laurent Mignon <laurent.mignon@acsone.eu>
* Bjorn Billen <bjorn.billen@dynapps.be>
* `Aion Tech <https://aiontech.company/>`_:

* Simone Rubino <simone.rubino@aion-tech.it>
5 changes: 5 additions & 0 deletions partner_firstname/static/description/index.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?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>
Expand Down Expand Up @@ -471,6 +472,10 @@ <h2><a class="toc-backref" href="#toc-entry-7">Contributors</a></h2>
<li>Graeme Gellatly &lt;<a class="reference external" href="mailto:graeme&#64;o4sb.com">graeme&#64;o4sb.com</a>&gt;</li>
<li>Laurent Mignon &lt;<a class="reference external" href="mailto:laurent.mignon&#64;acsone.eu">laurent.mignon&#64;acsone.eu</a>&gt;</li>
<li>Bjorn Billen &lt;<a class="reference external" href="mailto:bjorn.billen&#64;dynapps.be">bjorn.billen&#64;dynapps.be</a>&gt;</li>
<li><a class="reference external" href="https://aiontech.company/">Aion Tech</a>:<ul>
<li>Simone Rubino &lt;<a class="reference external" href="mailto:simone.rubino&#64;aion-tech.it">simone.rubino&#64;aion-tech.it</a>&gt;</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
Expand Down
Loading

0 comments on commit 420747f

Please sign in to comment.