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

[16.0] [ADD] shopinvader_api_cart_options #1576

Open
wants to merge 2 commits into
base: 16.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
6 changes: 6 additions & 0 deletions setup/shopinvader_api_cart_options/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,
)
139 changes: 139 additions & 0 deletions shopinvader_api_cart_options/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
============================
Shopinvader API Cart Options
============================

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

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

|badge1| |badge2| |badge3|

This module allows to add options to the cart lines, grouping cart
transaction on the combination of the product and the options.

It also handles the cart transfer merge by using the options to merge
the cart lines.

**Table of contents**

.. contents::
:local:

Usage
=====

This module is designed to be extended, so you can add your own options
to the cart lines.

In order to do so, you need to extend the ``SaleLineOptions`` schema and
add your own options:

.. code:: python

class SaleLineOptions(BaseSaleLineOptions, extends=True):
engraving: str | None = None
special: bool = False

@classmethod
def from_sale_order_line(cls, odoo_rec):
rv = super().from_sale_order_line(odoo_rec)
rv.engraving = odoo_rec.carving or None
rv.special = odoo_rec.special
return rv

Then you will need to extend the ``SaleOrderLine`` model to add support
for you options in the cart line matching and in the cart line transfer:

.. code:: python

class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
carving = fields.Char()
special = fields.Boolean()

def _match_cart_line(
self,
product_id,
carving=None,
special=None,
**kwargs,
):
rv = super()._match_cart_line(
product_id,
carving=carving,
special=special,
**kwargs,
)
return rv and self.carving == carving and self.special == special

def _prepare_cart_line_transfer_values(self):
vals = super()._prepare_cart_line_transfer_values()
vals["carving"] = self.carving
vals["special"] = self.special
return vals

And finally, you will need to extend the
``ShopinvaderApiCartRouterHelper`` to add support for your options in
the cart line creation from the transaction API:

.. code:: python

class ShopinvaderApiCartRouterHelper(
models.AbstractModel
): # pylint: disable=consider-merging-classes-inherited
_inherit = "shopinvader_api_cart.cart_router.helper"

@api.model
def _apply_transactions_creating_new_cart_line_prepare_vals(
self, cart: SaleOrder, transactions: list[CartTransaction], values: dict
):
options = transactions[0].options
if options:
values["carving"] = options.engraving
values["special"] = options.special

return values

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

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/shopinvader/odoo-shopinvader/issues/new?body=module:%20shopinvader_api_cart_options%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
------------

- Florian Mounier florian.mounier@akretion.com

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

This module is part of the `shopinvader/odoo-shopinvader <https://github.com/shopinvader/odoo-shopinvader/tree/16.0/shopinvader_api_cart_options>`_ project on GitHub.

You are welcome to contribute.
2 changes: 2 additions & 0 deletions shopinvader_api_cart_options/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import helper
from . import schemas
16 changes: 16 additions & 0 deletions shopinvader_api_cart_options/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# 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 Cart Options",
"version": "16.0.1.0.0",
"author": "Akretion, Odoo Community Association (OCA)",
"summary": "Add product options to the cart API",
"depends": ["shopinvader_api_cart"],
"website": "https://github.com/shopinvader/odoo-shopinvader",
"data": [],
"demo": [],
"installable": True,
"license": "AGPL-3",
}
28 changes: 28 additions & 0 deletions shopinvader_api_cart_options/helper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# 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 collections import namedtuple

from odoo import models

from odoo.addons.shopinvader_api_cart.schemas import CartTransaction

from .schemas import SaleLineOptions


class ShopinvaderApiCartRouterHelper(models.AbstractModel):
_inherit = "shopinvader_api_cart.cart_router.helper"

def _get_transaction_key(self, transaction: CartTransaction):
"""
Override the method to add the options defined in the SaleLineOptions
"""
key = super()._get_transaction_key(transaction)
options = tuple(SaleLineOptions._get_assembled_cls().model_fields.keys())
return namedtuple(key.__class__.__name__, key._fields + options)(
*key,
*tuple(
getattr(transaction.options, key) if transaction.options else None
for key in options
),
)
1 change: 1 addition & 0 deletions shopinvader_api_cart_options/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Florian Mounier <florian.mounier@akretion.com>
4 changes: 4 additions & 0 deletions shopinvader_api_cart_options/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
This module allows to add options to the cart lines, grouping cart transaction on the
combination of the product and the options.

It also handles the cart transfer merge by using the options to merge the cart lines.
70 changes: 70 additions & 0 deletions shopinvader_api_cart_options/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
This module is designed to be extended, so you can add your own options to the cart
lines.

In order to do so, you need to extend the `SaleLineOptions` schema and add your own
options:

```python
class SaleLineOptions(BaseSaleLineOptions, extends=True):
engraving: str | None = None
special: bool = False

@classmethod
def from_sale_order_line(cls, odoo_rec):
rv = super().from_sale_order_line(odoo_rec)
rv.engraving = odoo_rec.carving or None
rv.special = odoo_rec.special
return rv
```

Then you will need to extend the `SaleOrderLine` model to add support for you options in
the cart line matching and in the cart line transfer:

```python
class SaleOrderLine(models.Model):
_inherit = "sale.order.line"
carving = fields.Char()
special = fields.Boolean()

def _match_cart_line(
self,
product_id,
carving=None,
special=None,
**kwargs,
):
rv = super()._match_cart_line(
product_id,
carving=carving,
special=special,
**kwargs,
)
return rv and self.carving == carving and self.special == special

def _prepare_cart_line_transfer_values(self):
vals = super()._prepare_cart_line_transfer_values()
vals["carving"] = self.carving
vals["special"] = self.special
return vals
```

And finally, you will need to extend the `ShopinvaderApiCartRouterHelper` to add support
for your options in the cart line creation from the transaction API:

```python
class ShopinvaderApiCartRouterHelper(
models.AbstractModel
): # pylint: disable=consider-merging-classes-inherited
_inherit = "shopinvader_api_cart.cart_router.helper"

@api.model
def _apply_transactions_creating_new_cart_line_prepare_vals(
self, cart: SaleOrder, transactions: list[CartTransaction], values: dict
):
options = transactions[0].options
if options:
values["carving"] = options.engraving
values["special"] = options.special

return values
```
27 changes: 27 additions & 0 deletions shopinvader_api_cart_options/schemas.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).

from odoo.addons.extendable_fastapi import StrictExtendableBaseModel
from odoo.addons.shopinvader_api_cart.schemas import cart
from odoo.addons.shopinvader_schema_sale.schemas import sale_line


class SaleLineOptions(StrictExtendableBaseModel):
@classmethod
def from_sale_order_line(cls, odoo_rec):
return cls.model_construct()


class SaleLine(sale_line.SaleLine, extends=True):
options: SaleLineOptions

@classmethod
def from_sale_order_line(cls, odoo_rec):
res = super().from_sale_order_line(odoo_rec)
res.options = SaleLineOptions.from_sale_order_line(odoo_rec)
return res


class CartTransaction(cart.CartTransaction, extends=True):
options: SaleLineOptions | None = None
Loading
Loading