Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
e74bcdb
[ADD] shopinvader_unit_management
paradoxxxzero Mar 7, 2024
269ac2c
[ADD] shopinvader_api_unit_member
paradoxxxzero Mar 7, 2024
322d38b
[ADD] shopinvader_api_unit_request
paradoxxxzero Mar 7, 2024
0daac7c
[LINT] shopinvader_unit_management, shopinvader_api_unit_member, shop…
paradoxxxzero Mar 7, 2024
bce18f2
[IMP] shopinvader_unit_management: Use fields for members/units
paradoxxxzero Mar 12, 2024
1412dca
[IMP] shopinvader_api_unit_request: Add request_partner_id to request…
paradoxxxzero Mar 12, 2024
acd5294
[IMP] shopinvader_api_unit_request: Create manager cart if none is av…
paradoxxxzero Mar 13, 2024
57b4679
[IMP] shopinvader_api_unit_member: Use sudo to alter res_partner
paradoxxxzero Mar 13, 2024
5919b7b
[IMP] shopinvader_unit_management: Add doc
paradoxxxzero Mar 13, 2024
8d5031b
[IMP] shopinvader_api_unit_member: Add doc
paradoxxxzero Mar 13, 2024
d080057
[IMP] shopinvader_api_unit_request: Add doc
paradoxxxzero Mar 13, 2024
068c7ca
[LINT] shopinvader_unit_management, shopinvader_api_unit_member, shop…
paradoxxxzero Mar 13, 2024
43bed42
[IMP] shopinvader_api_unit_request: Add rrules for sale.order request…
paradoxxxzero Mar 28, 2024
d596eda
[IMP] shopinvader_unit_api_request: Extract notification for request …
paradoxxxzero Oct 15, 2024
6060e99
[IMP] shopinvader_unit_management: Include unit addresses
paradoxxxzero Oct 16, 2024
73c0689
[FIX] shopinvader_api_unit_member: Use framework/pull/464 instead of …
paradoxxxzero Oct 16, 2024
11c8e40
[FIX] shopinvader_api_unit_request: Use framework/pull/464 instead of…
paradoxxxzero Oct 16, 2024
ebccfac
[ADD] shopinvader_fastapi_auth_partner_api_unit_member
paradoxxxzero Oct 18, 2024
946cd06
[IMP] shopinvader_api_unit_request: Add request_order_id and request_…
paradoxxxzero Oct 29, 2024
f55383a
[IMP] request_order_id with index=True
Kev-Roche Feb 25, 2025
b4736ed
shopinvader_api_unit_request: add missing index
sebastienbeau Feb 27, 2025
76aed54
shopinvader_api_unit_request: fix compatibility with sale_exception
sebastienbeau Mar 11, 2025
de5a454
[FIX] shopinvader_api_unit_request: Request sols as root
paradoxxxzero Mar 31, 2025
bbcbb3c
[IMP] shopinvader_api_unit_request: Relax sale RRule a bit to include…
paradoxxxzero Apr 3, 2025
94e0474
[IMP] shopinvader_api_unit_request: Add missing fields on sale line r…
paradoxxxzero Apr 10, 2025
fd7d786
[FIX] shopinvader_api_unit_request: Fix according to upstream changes
paradoxxxzero Jun 2, 2025
0ff576e
[IMP] shopinvader_api_unit_request: Add request partner filter + sort
paradoxxxzero Apr 24, 2026
b18371b
[IMP] shopinvader_api_unit_request: Extend sale order to unit addresses
paradoxxxzero Jul 2, 2026
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
6 changes: 6 additions & 0 deletions setup/shopinvader_api_unit_member/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
6 changes: 6 additions & 0 deletions setup/shopinvader_api_unit_request/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
6 changes: 6 additions & 0 deletions setup/shopinvader_unit_management/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
94 changes: 94 additions & 0 deletions shopinvader_api_unit_member/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
===========================
Shopinvader Api Unit Member
===========================

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

.. |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%2Fodoo--shopinvader-lightgray.png?logo=github
:target: https://github.com/OCA/odoo-shopinvader/tree/16.0/shopinvader_api_unit_member
: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_api_unit_member
: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|

This module adds a service to shopinvader to manage units members: managers and collaborators.

A manager can list, create, update and delete collaborators.

The router defines these routes:

- `GET /unit/members` to list collaborators
- `GET /unit/members/:id` to get a collaborator
- `POST /unit/members` to create a collaborator
- `POST /unit/members/:id` to update a collaborator
- `DELETE /unit/members/:id` to delete a collaborator


**Table of contents**

.. contents::
:local:

Usage
=====

The routes are under the `unit_member_router.py` python file in the routers folder.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/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_api_unit_member%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
~~~~~~~

* Akretion

Contributors
~~~~~~~~~~~~

* `Akretion <https://www.akretion.com>`_:

* Florian Mounier

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_api_unit_member>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions shopinvader_api_unit_member/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import routers
from . import schemas
27 changes: 27 additions & 0 deletions shopinvader_api_unit_member/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Copyright 2024 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

{
"name": "Shopinvader Api Unit Member",
"summary": "This module adds a service to shopinvader to manage units members: "
"managers and collaborators.",
"version": "16.0.1.0.0",
"license": "AGPL-3",
"author": "Akretion",
"website": "https://github.com/shopinvader/odoo-shopinvader",
"depends": [
"extendable",
"extendable_fastapi",
"fastapi",
"shopinvader_unit_management",
],
"data": [
"security/res_groups.xml",
"security/res_partner.xml",
],
"external_dependencies": {
"python": ["fastapi", "extendable_pydantic>=1.0.0", "pydantic>=2.0.0"]
},
"installable": True,
}
3 changes: 3 additions & 0 deletions shopinvader_api_unit_member/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* `Akretion <https://www.akretion.com>`_:

* Florian Mounier
12 changes: 12 additions & 0 deletions shopinvader_api_unit_member/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
This module adds a service to shopinvader to manage units members: managers and collaborators.

A manager can list, create, update and delete collaborators.

The router defines these routes:

- `GET /unit/members` to list collaborators
- `GET /unit/members/:id` to get a collaborator
- `POST /unit/members` to create a collaborator
- `POST /unit/members/:id` to update a collaborator
- `DELETE /unit/members/:id` to delete a collaborator

1 change: 1 addition & 0 deletions shopinvader_api_unit_member/readme/USAGE.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The routes are under the `unit_member_router.py` python file in the routers folder.
1 change: 1 addition & 0 deletions shopinvader_api_unit_member/routers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from .unit_members import unit_member_router
88 changes: 88 additions & 0 deletions shopinvader_api_unit_member/routers/unit_members.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Copyright 2024 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from typing import Annotated, List

from fastapi import APIRouter, Depends

from odoo import _
from odoo.exceptions import AccessError

from odoo.addons.base.models.res_partner import Partner as ResPartner
from odoo.addons.fastapi.dependencies import authenticated_partner

from ..schemas import UnitMember, UnitMemberCreate, UnitMemberUpdate

# create a router
unit_member_router = APIRouter(tags=["unit"])


def authenticated_manager(
partner: Annotated[ResPartner, Depends(authenticated_partner)],
) -> ResPartner:
if partner.unit_profile != "manager":
raise AccessError(_("Only a manager can perform this action."))
return partner


@unit_member_router.get("/unit/members")
async def get_unit_members(
partner: Annotated[ResPartner, Depends(authenticated_manager)],
) -> List[UnitMember]:
"""
Get list of unit members
"""
members = partner._get_shopinvader_unit_members()
return [UnitMember.from_res_partner(rec) for rec in members]


@unit_member_router.get("/unit/members/{member_id}")
async def get_unit_member(
partner: Annotated[ResPartner, Depends(authenticated_manager)],
member_id: int,
) -> UnitMember:
"""
Get a specific unit member
"""
member = partner._get_shopinvader_unit_member(member_id)
return UnitMember.from_res_partner(member)


@unit_member_router.post("/unit/members", status_code=201)
async def create_unit_member(
data: UnitMemberCreate,
partner: Annotated[ResPartner, Depends(authenticated_manager)],
) -> UnitMember:
"""
Create a new unit member (manager or collaborator) as manager
"""
vals = data.to_res_partner_vals()
member = partner._create_shopinvader_unit_member(vals)
return UnitMember.from_res_partner(member)


@unit_member_router.post("/unit/members/{member_id}")
async def update_unit_member(
data: UnitMemberUpdate,
partner: Annotated[ResPartner, Depends(authenticated_manager)],
member_id: int,
) -> UnitMember:
"""
Update a specific unit member (manager or collaborator) as manager
"""
vals = data.to_res_partner_vals()
member = partner._update_shopinvader_unit_member(member_id, vals)
return UnitMember.from_res_partner(member)


@unit_member_router.delete("/unit/members/{member_id}")
async def delete_unit_member(
partner: Annotated[ResPartner, Depends(authenticated_manager)],
member_id: int,
) -> UnitMember:
"""
Delete a specific unit member (manager or collaborator) as manager
"""
member = partner._delete_shopinvader_unit_member(member_id)
return UnitMember.from_res_partner(member)
89 changes: 89 additions & 0 deletions shopinvader_api_unit_member/schemas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# Copyright 2024 Akretion (http://www.akretion.com).
# @author Florian Mounier <florian.mounier@akretion.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from extendable_pydantic import StrictExtendableBaseModel


class UnitMember(StrictExtendableBaseModel):
id: int
name: str | None = None
street: str | None = None
street2: str | None = None
zip: str | None = None
city: str | None = None
phone: str | None = None
email: str | None = None
state_id: int | None = None
country_id: int | None = None

@classmethod
def from_res_partner(cls, odoo_rec):
return cls.model_construct(
id=odoo_rec.id,
name=odoo_rec.name or None,
street=odoo_rec.street or None,
street2=odoo_rec.street2 or None,
zip=odoo_rec.zip or None,
city=odoo_rec.city or None,
phone=odoo_rec.phone or None,
email=odoo_rec.email or None,
state_id=odoo_rec.state_id.id or None,
country_id=odoo_rec.country_id.id or None,
)


class UnitMemberCreate(StrictExtendableBaseModel, extra="ignore"):
type: str | None = "collaborator"
name: str | None = None
street: str | None = None
street2: str | None = None
zip: str | None = None
city: str | None = None
phone: str | None = None
email: str | None = None
state_id: int | None = None
country_id: int | None = None

def to_res_partner_vals(self) -> dict:
vals = {
"unit_profile": self.type,
"name": self.name,
"street": self.street,
"street2": self.street2,
"zip": self.zip,
"city": self.city,
"phone": self.phone,
"email": self.email,
"state_id": self.state_id,
"country_id": self.country_id,
}

return vals


class UnitMemberUpdate(StrictExtendableBaseModel, extra="ignore"):
name: str | None = None
street: str | None = None
street2: str | None = None
zip: str | None = None
city: str | None = None
phone: str | None = None
email: str | None = None
state_id: int | None = None
country_id: int | None = None

def to_res_partner_vals(self) -> dict:
fields = [
"name",
"street",
"street2",
"zip",
"city",
"phone",
"email",
"state_id",
"country_id",
]
values = self.model_dump(exclude_unset=True)
return {f: values[f] for f in fields if f in values}
19 changes: 19 additions & 0 deletions shopinvader_api_unit_member/security/res_groups.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--
Copyright 2024 Akretion (http://www.akretion.com).
@author Florian Mounier <florian.mounier@akretion.com>
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
-->
<odoo>
<record id="shopinvader_unit_management_user_group" model="res.groups">
<field name="name">Shopinvader Unit Management user</field>
<field
name="implied_ids"
eval="[
(4, ref('fastapi.group_fastapi_endpoint_runner')),
]"
/>

</record>

</odoo>
Loading
Loading