Skip to content

Commit

Permalink
[IMP] shopinvader_unit_management: Include unit addresses
Browse files Browse the repository at this point in the history
  • Loading branch information
paradoxxxzero committed Oct 15, 2024
1 parent aa0a369 commit b9ac35d
Show file tree
Hide file tree
Showing 9 changed files with 230 additions and 71 deletions.
12 changes: 9 additions & 3 deletions shopinvader_api_unit_member/security/res_partner.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,15 @@
name="groups"
eval="[(4, ref('shopinvader_api_unit_member.shopinvader_unit_management_user_group'))]"
/>
<field
name="domain_force"
>['|', ('unit_id.manager_ids','=',authenticated_partner_id), ('manager_ids','=',authenticated_partner_id)]</field>
<field name="domain_force">[
'|',
('manager_ids','=',authenticated_partner_id),
'|',
('unit_id.manager_ids','=',authenticated_partner_id),
'|',
('parent_id.manager_ids','=',authenticated_partner_id),
('parent_id.unit_id.manager_ids','=',authenticated_partner_id)
]</field>

</record>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

import json
from contextlib import contextmanager
from unittest import mock

from fastapi import status
from requests import Response

from odoo.tests.common import tagged
from odoo.tools import mute_logger

from odoo.addons.extendable_fastapi.tests.common import FastAPITransactionCase
from odoo.addons.shopinvader_unit_management.tests.common import (
Expand Down Expand Up @@ -51,12 +51,10 @@ def setUpClass(cls) -> None:
)._get_app()

@contextmanager
def _rollback_called_test_client(self):
with self._create_test_client() as test_client, mock.patch.object(
self.env.cr.__class__, "rollback"
) as mock_rollback:
def _create_test_client(self, **kwargs):
kwargs.setdefault("raise_server_exceptions", False)
with mute_logger("httpx"), super()._create_test_client(**kwargs) as test_client:
yield test_client
mock_rollback.assert_called_once()

def test_get_manager_unit_members(self):
"""
Expand Down Expand Up @@ -94,7 +92,7 @@ def test_collaborator_unit_members(self):
"""
self.default_fastapi_authenticated_partner = self.collaborator_1_1

with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.get("/unit/members")
self.assertEqual(
response.status_code,
Expand All @@ -107,7 +105,7 @@ def test_unit_unit_members(self):
"""
self.default_fastapi_authenticated_partner = self.unit_1

with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.get("/unit/members")
self.assertEqual(
response.status_code,
Expand Down Expand Up @@ -149,7 +147,7 @@ def test_get_manager_unit_members_wrong_unit(self):
"""
Test that a manager can't access members of another unit
"""
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.get(
f"/unit/members/{self.collaborator_2_2.id}"
)
Expand All @@ -162,13 +160,13 @@ def test_get_manager_unit_members_wrong_type(self):
"""
Test that a manager can't access a unit
"""
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.get(f"/unit/members/{self.unit_1.id}")
self.assertEqual(
response.status_code,
status.HTTP_404_NOT_FOUND,
)
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.get(f"/unit/members/{self.unit_2.id}")
self.assertEqual(
response.status_code,
Expand Down Expand Up @@ -257,7 +255,7 @@ def test_create_unit_manager(self):
)

def test_create_unit_wrong_type(self):
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.post(
"/unit/members",
data=json.dumps({"name": "New Unit", "type": "unit"}),
Expand All @@ -267,7 +265,7 @@ def test_create_unit_wrong_type(self):
status.HTTP_403_FORBIDDEN,
)

with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.post(
"/unit/members",
data=json.dumps({"name": "New Unit", "type": "unknown"}),
Expand All @@ -279,7 +277,7 @@ def test_create_unit_wrong_type(self):

def test_create_unit_wrong_partner(self):
self.default_fastapi_authenticated_partner = self.collaborator_1_1
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.post(
"/unit/members",
data=json.dumps({"name": "New Unit", "type": "collaborator"}),
Expand Down Expand Up @@ -387,7 +385,7 @@ def test_update_unit_manager(self):

def test_update_unit_wrong_partner(self):
self.default_fastapi_authenticated_partner = self.collaborator_1_1
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.post(
f"/unit/members/{self.collaborator_1_1.id}",
data=json.dumps({"name": "New Unit Name"}),
Expand Down Expand Up @@ -474,7 +472,7 @@ def test_delete_unit_manager(self):

def test_delete_unit_wrong_partner(self):
self.default_fastapi_authenticated_partner = self.collaborator_1_1
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.delete(
f"/unit/members/{self.collaborator_1_1.id}",
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@

import json
from contextlib import contextmanager
from unittest import mock

from fastapi import status
from requests import Response

from odoo.tests.common import tagged
from odoo.tools import mute_logger

from odoo.addons.shopinvader_api_cart.tests.common import CommonSaleCart
from odoo.addons.shopinvader_api_sale.routers import sale_line_router
Expand Down Expand Up @@ -112,12 +112,10 @@ def _slice_sol(self, data, *fields):
return {tuple(item[field] for field in fields) for item in data["items"]}

@contextmanager
def _rollback_called_test_client(self, **kwargs):
with self._create_test_client(**kwargs) as test_client, mock.patch.object(
self.env.cr.__class__, "rollback"
) as mock_rollback:
def _create_test_client(self, **kwargs):
kwargs.setdefault("raise_server_exceptions", False)
with mute_logger("httpx"), super()._create_test_client(**kwargs) as test_client:
yield test_client
mock_rollback.assert_called_once()

def test_cart_request_as_collaborator(self):
"""
Expand Down Expand Up @@ -178,7 +176,7 @@ def test_cart_request_as_manager(self):
self.env["sale.order"]._create_empty_cart(
self.default_fastapi_authenticated_partner.id
)
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.post("/request")
self.assertEqual(
response.status_code,
Expand All @@ -196,7 +194,7 @@ def test_cart_request_as_unit(self):
self.env["sale.order"]._create_empty_cart(
self.default_fastapi_authenticated_partner.id
)
with self._rollback_called_test_client() as test_client:
with self._create_test_client() as test_client:
response: Response = test_client.post("/request")
self.assertEqual(
response.status_code,
Expand Down Expand Up @@ -305,7 +303,7 @@ def test_sale_line_requested_flow(self):
self.assertEqual(response.json()["count"], 1)

def test_sale_line_requested_as_collaborator(self):
with self._rollback_called_test_client(
with self._create_test_client(
app=self.sale_line_app, router=unit_request_line_router
) as test_client:
response: Response = test_client.get("/unit/request_lines")
Expand Down
36 changes: 10 additions & 26 deletions shopinvader_unit_management/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Shopinvader Unit Management
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:8b84b0911ab2e1dd5bca6a65f2d6a814183bb0ff565d3772f39aa28e24c4223d
!! source digest: sha256:c85b9aaf1e5ec9ff4516960b20e84bae393a2240bd14e62e11d410ca7d6d6028
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
Expand All @@ -16,17 +16,11 @@ Shopinvader Unit Management
.. |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%2Fodoo--shopinvader-lightgray.png?logo=github
:target: https://github.com/OCA/odoo-shopinvader/tree/16.0/shopinvader_unit_management
:alt: OCA/odoo-shopinvader
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/odoo-shopinvader-16-0/odoo-shopinvader-16-0-shopinvader_unit_management
: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/odoo-shopinvader&target_branch=16.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|
.. |badge3| image:: https://img.shields.io/badge/github-shopinvader%2Fodoo--shopinvader-lightgray.png?logo=github
:target: https://github.com/shopinvader/odoo-shopinvader/tree/16.0/shopinvader_unit_management
:alt: shopinvader/odoo-shopinvader

|badge1| |badge2| |badge3|

This module introduces the concept of unit management.
The unit is a group of partners with managers and collaborators.
Expand All @@ -42,10 +36,10 @@ To cater to your needs, you can inherit the res.partner model and make the unit_
Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/odoo-shopinvader/issues>`_.
Bugs are tracked on `GitHub Issues <https://github.com/shopinvader/odoo-shopinvader/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/odoo-shopinvader/issues/new?body=module:%20shopinvader_unit_management%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
`feedback <https://github.com/shopinvader/odoo-shopinvader/issues/new?body=module:%20shopinvader_unit_management%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.

Expand All @@ -67,16 +61,6 @@ Contributors
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/odoo-shopinvader <https://github.com/OCA/odoo-shopinvader/tree/16.0/shopinvader_unit_management>`_ project on GitHub.
This module is part of the `shopinvader/odoo-shopinvader <https://github.com/shopinvader/odoo-shopinvader/tree/16.0/shopinvader_unit_management>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
You are welcome to contribute.
2 changes: 1 addition & 1 deletion shopinvader_unit_management/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"license": "AGPL-3",
"author": "Akretion",
"website": "https://github.com/shopinvader/odoo-shopinvader",
"depends": [],
"depends": ["shopinvader_address"],
"demo": [
"demo/res_partner_demo.xml",
],
Expand Down
27 changes: 27 additions & 0 deletions shopinvader_unit_management/models/res_partner.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,30 @@ def _delete_shopinvader_unit_member(self, member_id):
raise AccessError(_("Cannot perform this action on this member"))
member.sudo().active = False
return member

# Address overrides
def _get_shopinvader_invoicing_addresses(self) -> "ResPartner":
# A unit member can invoice on unit
addresses = super()._get_shopinvader_invoicing_addresses()
if self.unit_id:
addresses |= self.unit_id._get_shopinvader_invoicing_addresses()
return addresses

def _get_shopinvader_delivery_addresses(self) -> "ResPartner":
# A unit member can deliver at unit
addresses = super()._get_shopinvader_delivery_addresses()
if self.unit_id:
addresses |= self.unit_id._get_shopinvader_delivery_addresses()
return addresses

def _get_shopinvader_invoicing_address(self, address_id: int) -> "ResPartner":
address = super()._get_shopinvader_invoicing_address(address_id)
if address in self.unit_id._get_shopinvader_invoicing_addresses():
raise AccessError(_("Cannot perform this action on this address"))
return address

def _get_shopinvader_delivery_address(self, address_id: int) -> "ResPartner":
address = super()._get_shopinvader_delivery_address(address_id)
if address in self.unit_id._get_shopinvader_delivery_addresses():
raise AccessError(_("Cannot perform this action on this address"))
return address
24 changes: 10 additions & 14 deletions shopinvader_unit_management/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@

/*
:Author: David Goodger ([email protected])
:Id: $Id: html4css1.css 8954 2022-01-20 10:10:25Z milde $
:Id: $Id: html4css1.css 9511 2024-01-13 09:50:07Z milde $
:Copyright: This stylesheet has been placed in the public domain.

Default cascading style sheet for the HTML output of Docutils.
Despite the name, some widely supported CSS2 features are used.

See https://docutils.sourceforge.io/docs/howto/html-stylesheets.html for how to
customize this style sheet.
Expand Down Expand Up @@ -275,7 +276,7 @@
margin-left: 2em ;
margin-right: 2em }

pre.code .ln { color: grey; } /* line numbers */
pre.code .ln { color: gray; } /* 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 }
Expand All @@ -301,7 +302,7 @@
span.pre {
white-space: pre }

span.problematic {
span.problematic, pre.problematic {
color: red }

span.section-subtitle {
Expand Down Expand Up @@ -367,9 +368,9 @@ <h1 class="title">Shopinvader Unit Management</h1>
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:8b84b0911ab2e1dd5bca6a65f2d6a814183bb0ff565d3772f39aa28e24c4223d
!! source digest: sha256:c85b9aaf1e5ec9ff4516960b20e84bae393a2240bd14e62e11d410ca7d6d6028
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" 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 image-reference" 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 image-reference" href="https://github.com/OCA/odoo-shopinvader/tree/16.0/shopinvader_unit_management"><img alt="OCA/odoo-shopinvader" src="https://img.shields.io/badge/github-OCA%2Fodoo--shopinvader-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/odoo-shopinvader-16-0/odoo-shopinvader-16-0-shopinvader_unit_management"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/odoo-shopinvader&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external image-reference" 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 image-reference" 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 image-reference" href="https://github.com/shopinvader/odoo-shopinvader/tree/16.0/shopinvader_unit_management"><img alt="shopinvader/odoo-shopinvader" src="https://img.shields.io/badge/github-shopinvader%2Fodoo--shopinvader-lightgray.png?logo=github" /></a></p>
<p>This module introduces the concept of unit management.
The unit is a group of partners with managers and collaborators.
This module provides a simple implementation of the unit management concept.</p>
Expand All @@ -388,10 +389,10 @@ <h1 class="title">Shopinvader Unit Management</h1>
</div>
<div class="section" id="bug-tracker">
<h1><a class="toc-backref" href="#toc-entry-1">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/odoo-shopinvader/issues">GitHub Issues</a>.
<p>Bugs are tracked on <a class="reference external" href="https://github.com/shopinvader/odoo-shopinvader/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 to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/odoo-shopinvader/issues/new?body=module:%20shopinvader_unit_management%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<a class="reference external" href="https://github.com/shopinvader/odoo-shopinvader/issues/new?body=module:%20shopinvader_unit_management%0Aversion:%2016.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">
Expand All @@ -413,13 +414,8 @@ <h2><a class="toc-backref" href="#toc-entry-4">Contributors</a></h2>
</div>
<div class="section" id="maintainers">
<h2><a class="toc-backref" href="#toc-entry-5">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/odoo-shopinvader/tree/16.0/shopinvader_unit_management">OCA/odoo-shopinvader</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>
<p>This module is part of the <a class="reference external" href="https://github.com/shopinvader/odoo-shopinvader/tree/16.0/shopinvader_unit_management">shopinvader/odoo-shopinvader</a> project on GitHub.</p>
<p>You are welcome to contribute.</p>
</div>
</div>
</div>
Expand Down
4 changes: 2 additions & 2 deletions shopinvader_unit_management/tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
# @author Florian Mounier <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo.tests.common import SavepointCase
from odoo.tests.common import TransactionCase


class TestUnitManagementCommon(SavepointCase):
class TestUnitManagementCommon(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
Expand Down
Loading

0 comments on commit b9ac35d

Please sign in to comment.