diff --git a/shopinvader_api_cart/routers/cart.py b/shopinvader_api_cart/routers/cart.py index 2fbe80a777..ddd091e1a6 100644 --- a/shopinvader_api_cart/routers/cart.py +++ b/shopinvader_api_cart/routers/cart.py @@ -46,7 +46,7 @@ def sync( uuid: str | None = None, ) -> Sale | None: cart = env["sale.order"]._find_open_cart(partner.id, uuid) - cart = env["shopinvader_api_cart.service.helper"]._sync_cart( + cart = env["shopinvader_api_cart.cart_router.helper"]._sync_cart( partner, cart, uuid, data.transactions ) return Sale.from_sale_order(cart) if cart else None @@ -60,14 +60,14 @@ def update( partner: Annotated["ResPartner", Depends(authenticated_partner)], uuid: str | None = None, ) -> Sale: - cart = env["shopinvader_api_cart.service.helper"]._update(partner, data, uuid) + cart = env["shopinvader_api_cart.cart_router.helper"]._update(partner, data, uuid) return Sale.from_sale_order(cart) -class ShopinvaderApiCartServiceHelper(models.AbstractModel): - _name = "shopinvader_api_cart.service.helper" - _description = "ShopInvader API Cart Service Helper" +class ShopinvaderApiCartRouterHelper(models.AbstractModel): + _name = "shopinvader_api_cart.cart_router.helper" + _description = "ShopInvader API Cart Router Helper" @api.model def _check_transactions(self, transactions: list[CartTransaction]): @@ -225,37 +225,9 @@ def _sync_cart( self._apply_transactions(cart, transactions) return cart - def _convert_delivery_values(self, values): - if values and values.get("address_id"): - return {"partner_shipping_id": values["address_id"]} - else: - return {} - - def _convert_invoicing_values(self, values): - if values and values.get("address_id"): - return {"partner_invoice_id": values["address_id"]} - else: - return {} - - def _prepare_cart_vals(self, values): - for key, func in self._get_update_mapping().items(): - if key in values: - values.update(getattr(self, func)(values.pop(key))) - return values - - def _get_update_mapping(self): - """Mapping are needed only if you want to alter the input data. - if a mapping is define, the key is pop and the result will update the value - if their is not mapping for a key the key/value will be kept as it is""" - return { - "delivery": "_convert_delivery_values", - "invoicing": "_convert_invoicing_values", - } - def _update(self, partner, data, uuid): cart = self.env["sale.order"]._find_open_cart(partner.id, uuid) if not cart: cart = self.env["sale.order"]._create_empty_cart() - values = data.model_dump(exclude_unset=True) - cart.write(self._prepare_cart_vals(values)) + cart.write(data.convert_to_sale_write()) return cart diff --git a/shopinvader_api_cart/schemas/cart.py b/shopinvader_api_cart/schemas/cart.py index ae9d42dd0f..dea67500c2 100644 --- a/shopinvader_api_cart/schemas/cart.py +++ b/shopinvader_api_cart/schemas/cart.py @@ -29,3 +29,16 @@ class CartUpdateInput(StrictExtendableBaseModel): delivery: ShippingUpdateInfo | None = None invoicing: InvoicingUpdateInfo | None = None note: str | None = None + + def convert_to_sale_write(self): + vals = {} + data = self.model_dump(exclude_unset=True) + if "client_order_ref" in data: + vals["client_order_ref"] = data["client_order_ref"] + if "note" in data: + vals["note"] = data["note"] + if (data.get("delivery") or {}).get("address_id"): + vals["partner_shipping_id"] = data["delivery"]["address_id"] + if (data.get("invoicing") or {}).get("address_id"): + vals["partner_invoicing_id"] = data["invoicing"]["address_id"] + return vals diff --git a/shopinvader_api_cart/tests/test_shopinvader_api_cart.py b/shopinvader_api_cart/tests/test_shopinvader_api_cart.py index bdd9e2aeb6..36c86b43f5 100644 --- a/shopinvader_api_cart/tests/test_shopinvader_api_cart.py +++ b/shopinvader_api_cart/tests/test_shopinvader_api_cart.py @@ -433,8 +433,7 @@ def test_update(self) -> None: so = self.env["sale.order"]._create_empty_cart( self.default_fastapi_authenticated_partner.id ) - # TODO FIXME how to not pass the key invoicing ? - data = {"delivery": {"address_id": address.id}, "invoicing": None} + data = {"delivery": {"address_id": address.id}} with self._create_test_client(router=cart_router) as test_client: response: Response = test_client.post( f"/update/{so.uuid}", content=json.dumps(data) diff --git a/shopinvader_api_sale/routers/sales.py b/shopinvader_api_sale/routers/sales.py index a08ac5f687..b7f6e651fe 100644 --- a/shopinvader_api_sale/routers/sales.py +++ b/shopinvader_api_sale/routers/sales.py @@ -17,6 +17,7 @@ paging, ) from odoo.addons.fastapi.schemas import Paging +from odoo.addons.fastapi.utils import FilteredDomainAdapter from odoo.addons.shopinvader_schema_sale.schemas import Sale from ..schemas import SaleSearch @@ -32,7 +33,9 @@ def search( partner: Annotated["ResPartner", Depends(authenticated_partner)], ) -> PagedCollection[Sale]: """Get the list of sale orders.""" - count, orders = env["shopinvader_api_sale.service.sales"]._search(paging, params) + count, orders = env["shopinvader_api_sale.sales_router.helper"]._search( + paging, params + ) return PagedCollection[Sale]( count=count, items=[Sale.from_sale_order(order) for order in orders], @@ -49,21 +52,27 @@ def get( Get sale order of authenticated user with specific sale_id sale corresponds to authenticated partner """ - return Sale.from_sale_order(env["shopinvader_api_sale.service.sales"]._get(sale_id)) + return Sale.from_sale_order( + env["shopinvader_api_sale.sales_router.helper"]._get(sale_id) + ) -class ShopinvaderApiServiceSales(models.AbstractModel): - _inherit = "fastapi.service.base" - _name = "shopinvader_api_sale.service.sales" +class ShopinvaderApiSaleSalesRouterHelper(models.AbstractModel): + _name = "shopinvader_api_sale.sales_router.helper" _description = "Shopinvader Api Sale Service Helper" - _odoo_model = "sale.order" @property - def _odoo_model_domain_restrict(self): - return [("typology", "=", "sale")] - - def _convert_search_params_to_domain(self, params): - if params.name: - return [("name", "ilike", self.name)] - else: - return [] + def adapter(self): + return FilteredDomainAdapter( + self.env["sale.order"], [("typology", "=", "sale")] + ) + + def _get(self, record_id): + return self.adapter.get(record_id) + + def _search(self, paging, params): + return self.adapter.search_with_count( + params.to_odoo_domain(), + limit=paging.limit, + offset=paging.offset, + ) diff --git a/shopinvader_api_sale/schemas.py b/shopinvader_api_sale/schemas.py index 13917e24bb..ad0ed878f8 100644 --- a/shopinvader_api_sale/schemas.py +++ b/shopinvader_api_sale/schemas.py @@ -8,3 +8,9 @@ class SaleSearch(StrictExtendableBaseModel): name: str | None = None + + def to_odoo_domain(self): + if self.name: + return [("name", "ilike", self.name)] + else: + return []