Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[18.0][ADD] partner_type_base extracted from partner_firstname #1905

Open
wants to merge 2 commits into
base: 18.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions partner_firstname/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
{
"name": "Partner first name and last name",
"summary": "Split first name and last name for non company partners",
"version": "18.0.1.1.0",
"version": "18.0.1.2.0",
"author": "Camptocamp, "
"Grupo ESOC Ingeniería de Servicios, "
"Tecnativa, "
Expand All @@ -15,10 +15,9 @@
"DynApps NV, "
"Odoo Community Association (OCA)",
"license": "AGPL-3",
"maintainer": "Camptocamp, Acsone",
"category": "Extra Tools",
"website": "https://github.com/OCA/partner-contact",
"depends": ["base_setup"],
"depends": ["partner_type_base"],
"post_init_hook": "post_init_hook",
"data": [
"views/base_config_view.xml",
Expand Down
10 changes: 10 additions & 0 deletions partner_firstname/migrations/18.0.1.2.0/pre-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import logging

from odoo.upgrade import util

_logger = logging.getLogger(__name__)


def migrate(cr, version):
_logger.info("Installing dependent module 'partner_type_base' by migration script.")
util.force_install_module(cr, "partner_type_base")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you need this? Odoo's ORM is in charge of that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought that too, but @houssine78 informed me that there is a bug and from my testing I can confirm that the added dependency is not installed automatically. odoo/odoo#72703

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hasn't odoo/odoo#72661 fixed that ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not totally as sbidoul wrote at the end of the ticket I've linked:

Half fixed to be precise.

52 changes: 12 additions & 40 deletions partner_firstname/views/res_partner.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,12 @@
<field name="inherit_id" ref="base.view_partner_simple_form" />
<field name="arch" type="xml">
<xpath expr="//field[@id='individual']" position="attributes">
<attribute name="invisible">is_company</attribute>
<attribute name="readonly">not is_company</attribute>
<attribute name="required">type == 'contact' and is_company</attribute>
</xpath>
<xpath expr="//field[@id='company']" position="attributes">
<attribute name="invisible">is_company == False</attribute>
<attribute name="readonly">not is_company</attribute>
<attribute name="required">type == 'contact' and is_company</attribute>
<attribute name="readonly">is_individual</attribute>
</xpath>
<xpath expr="//h1//field[@id='company']/.." position="before">
<group invisible="is_company">
<field
name="lastname"
required="not firstname and not is_company and type == 'contact'"
/>
<field
name="firstname"
required="not lastname and not is_company and type == 'contact'"
/>
<group invisible="not is_individual">
<field name="lastname" required="not firstname and is_individual" />
<field name="firstname" required="not lastname and is_individual" />
</group>
</xpath>
</field>
Expand All @@ -32,54 +19,39 @@
<field name="inherit_id" ref="base.view_partner_form" />
<field name="arch" type="xml">
<xpath expr="//field[@id='individual']" position="attributes">
<attribute name="invisible">is_company</attribute>
<attribute name="readonly">not is_company</attribute>
<attribute name="required">type == 'contact' and is_company</attribute>
</xpath>
<xpath expr="//field[@id='company']" position="attributes">
<attribute name="invisible">not is_company</attribute>
<attribute name="readonly">not is_company</attribute>
<attribute name="required">type == 'contact' and is_company</attribute>
<attribute name="readonly">is_individual</attribute>
</xpath>
<xpath
expr="//div[hasclass('oe_title')]//field[@id='company']/.."
position="after"
>
<div class="oe_edit_only">
<group invisible="is_company">
<group invisible="not is_individual">
<field
name="lastname"
required="not firstname and not is_company and type == 'contact'"
required="not firstname and is_individual"
/>
<field
name="firstname"
required="not lastname and not is_company and type == 'contact'"
required="not lastname and is_individual"
/>
</group>
</div>
</xpath>
<!-- Modify inner contact form of child_ids -->
<xpath
expr="//field[@name='child_ids']/form//field[@name='name']"
position="attributes"
>
<attribute name="readonly">not is_company</attribute>
<attribute name="required">is_company</attribute>
</xpath>

<xpath
expr="//field[@name='child_ids']/form//field[@name='name']"
position="after"
>
<div class="oe_edit_only" colspan="2">
<field name="is_company" invisible="True" />
<group invisible="is_company">
<group invisible="not is_individual">
<field
name="lastname"
required="not firstname and not is_company and type == 'contact'"
required="not firstname and is_individual"
/>
<field
name="firstname"
required="not lastname and not is_company and type == 'contact'"
required="not lastname and is_individual"
/>
</group>
</div>
Expand Down
77 changes: 77 additions & 0 deletions partner_type_base/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
=====================
Partner Address Types
=====================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:43d730c51ef59b1c6de4109020507234da1ada647d1a04e2b0bc1dc74dad4451
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |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/18.0/partner_type_base
: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-18-0/partner-contact-18-0-partner_type_base
: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=18.0
:alt: Try me on Runboat

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

This module was written to extend the functionality of contact types for
a flexible extension.

**Table of contents**

.. contents::
:local:

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_type_base%0Aversion:%2018.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
-------

* glueckkanja AG

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

- Christopher Rogos

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

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/18.0/partner_type_base>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
1 change: 1 addition & 0 deletions partner_type_base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
20 changes: 20 additions & 0 deletions partner_type_base/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# 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).

{
"name": "Partner Address Types",
"summary": "Base implementation to improve the address type customization.",
"version": "18.0.1.0.0",
"author": "glueckkanja AG, Odoo Community Association (OCA)",
"license": "AGPL-3",
"category": "Extra Tools",
"website": "https://github.com/OCA/partner-contact",
"depends": ["base_setup"],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not base ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good question... I've copied it from "partner_firstname" module.

There is a module in odoo/addons/base_setup which depends on "base" and "web". It also has some minor changes on the patner kanban view. So maybe a view order issue?

A general question:
If partner_firstname has a dependency to partner_type_base and partner_type_base depends on base, but partner_firstname also references base in a view. Shall partner_firstname reference base explicit in the manifest or should it not add the base to the depends?

partner_firstname.depends = ["partner_type_base"] or ["base", "partner_type_base"] ???
when
partner_type_base.depends = ["base"]

"data": [
"views/res_partner.xml",
],
"auto_install": False,
"installable": True,
}
1 change: 1 addition & 0 deletions partner_type_base/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import res_partner
46 changes: 46 additions & 0 deletions partner_type_base/models/res_partner.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2024 Christopher Rogos (<https://www.glueckkanja.com>)

from odoo import api, fields, models


class ResPartner(models.Model):
"""Adds last name and first name; name becomes a stored function field."""

_inherit = "res.partner"

is_address_readonly = fields.Boolean(
compute="_compute_contact_type",
help="If true, the address fields are readonly.",
)
is_individual = fields.Boolean(
compute="_compute_contact_type", help="If true, the partner name is splitted."
)
can_be_parent = fields.Boolean(
compute="_compute_contact_type",
search="_search_can_be_parent",
help="If true, the partner is available as parent.",
)
can_be_child = fields.Boolean(
compute="_compute_contact_type",
help="If true, the partner_id field is available.",
)

@api.depends("is_company", "type", "parent_id")
def _compute_contact_type(self):
for partner in self:
partner.is_address_readonly = not (
partner.is_company
or not partner.parent_id
or partner.type not in ["contact"]
)
partner.is_individual = not partner.is_company and partner.type in [
"contact",
"other",
]

partner.can_be_parent = partner.is_company
partner.can_be_child = not partner.is_company

@api.model
def _search_can_be_parent(self, operator, value):
return [("is_company", operator, value)]

Check warning on line 46 in partner_type_base/models/res_partner.py

View check run for this annotation

Codecov / codecov/patch

partner_type_base/models/res_partner.py#L46

Added line #L46 was not covered by tests
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it real ? An individual can have a child partner as delivery address for instance.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is totally inconsistent in Odoo.

When you go to a contact, you can add a subcontact/address:
image

When you open this other address, the contact is set as parent:
image

But when you search for the contact to select it in this view, this is not possible:
image

In my Opinion a big weakness of Odoo, because it is very unclear to the user how to use it.
After setting a parent, you can also switch the contact to "company" and the parent_id is kept.
Basically this could be good feature to address hierarchies, but I am not sure if all Odoo modules can work with this.

What we are doing is, that we use a 3 level hirache Company -> "Other Address" -> Contact to bundle all people of a certain Office address. Because commerical_partner_id looks upwards until the first company, this should work. But I am not sure if it is a Odoo recommended structure.
To have it more consistent, I added the can_be_parent attribute to make it more flexible and we overload the computation and add "Other Address" to the types which can_be_parent = True in another module.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had also opened an Odoo ticket on this topic 9 Months ago, and this was the answer:

Thank you for your patience. I have been trying to find information on whether this behavior is supported or not, and in fact a lot of feedback has been created in the past suggesting we need this feature (three-level hierarchy with contacts). The reply the development team has given us in all of these cases is the behavior is indeed possible, but not entirely supported. Odoo does not support this behavior because it is a very problematic data structure, with a lot of hidden complexities, especially on the accounting aspect. This reply has been the same for feedbacks created 3 to 1 year ago, and the team does admit that if demand for this becomes very high it will be reconsidered.

Therefore, I have created a feedback ticket to shed light on the fact that you, like other customers, do need this hierarchy for your daily business flows. Depending on whether you just need to display that a contact belongs to another, the workaround proposed is to create a Studio field for it. If however this information will be used in other business flows such as accounting flows, custom code will be necessary to satisfy the need.

3 changes: 3 additions & 0 deletions partner_type_base/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
1 change: 1 addition & 0 deletions partner_type_base/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Christopher Rogos
2 changes: 2 additions & 0 deletions partner_type_base/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
This module was written to extend the functionality of contact types
for a flexible extension.
Binary file added partner_type_base/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading