Skip to content

Commit

Permalink
Merge commit 'refs/pull/110/head' of github.com:camptocamp/wms into m…
Browse files Browse the repository at this point in the history
…erge-branch-2879-BSGZT-491-92a1a86c
  • Loading branch information
JuMiSanAr committed Dec 16, 2022
2 parents fd86ad3 + f1ff6fb commit bb0bd72
Show file tree
Hide file tree
Showing 25 changed files with 398 additions and 2 deletions.
6 changes: 6 additions & 0 deletions setup/shopfloor_shopinvader_base/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/shopfloor_shopinvader_mobile_base/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,
)
9 changes: 7 additions & 2 deletions shopfloor_mobile_base/static/wms/src/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,15 @@ const router = new VueRouter({
});
router.beforeEach(async (to, from, next) => {
await Vue.nextTick();
// FIXME: for shopinvader to work we need a user.
// To have a user we must log in or have an api key.
// Hence, either we turn on login for demo mode
// or we find another solution.
// &&
// !router.app.demo_mode
if (
!router.app.is_authenticated() &&
to.meta.requiresAuth &&
!router.app.demo_mode
to.meta.requiresAuth
) {
next("login");
} else {
Expand Down
1 change: 1 addition & 0 deletions shopfloor_shopinvader_base/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wait for the bot ;)
4 changes: 4 additions & 0 deletions shopfloor_shopinvader_base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
from . import components
from . import controllers
from . import models
from . import services
22 changes: 22 additions & 0 deletions shopfloor_shopinvader_base/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2021 Camptocamp SA (http://www.camptocamp.com)
# @author Simone Orsi <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

{
"name": "Shopfloor / Shopinvader integration",
"summary": "Provides base integration for Shopinvader into Shopfloor mobile app",
"version": "14.0.1.0.0",
"development_status": "Alpha",
"category": "E-commerce",
"website": "https://github.com/OCA/wms",
"author": "Camptocamp, Odoo Community Association (OCA)",
"maintainer": ["simahawk"],
"license": "AGPL-3",
"depends": ["shopfloor_base", "shopinvader", "sales_team"],
"data": ["views/shopfloor_app.xml"],
"demo": [
"demo/tech_user_demo.xml",
"demo/res_users_demo.xml",
"demo/shopfloor_app_demo.xml",
],
}
1 change: 1 addition & 0 deletions shopfloor_shopinvader_base/components/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import service_context_provider
61 changes: 61 additions & 0 deletions shopfloor_shopinvader_base/components/service_context_provider.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
# Copyright 2021 ACSONE SA/NV
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).


import logging

from odoo import _
from odoo.exceptions import MissingError

from odoo.addons.component.core import Component
from odoo.addons.shopinvader.utils import get_partner_work_context

_logger = logging.getLogger(__name__)


class ShopfloorInvaderServiceContextProvider(Component):
_name = "shopfloor.invader.service.context.provider"
_inherit = "base.rest.service.context.provider"
# No need to inherit from default ctx provider as it's all custom here
# _inherit = "shopinvader.service.context.provider"
_collection = "shopinvader.backend"
_usage = "shopfloor_invader_component_context_provider"

def _get_component_context(self):
assert self.collection._name == self._collection
res = super()._get_component_context()
res.update(
{
"shopinvader_backend": self.collection,
"shopinvader_session": self._get_shopinvader_session(),
}
)
res.update(get_partner_work_context(self._get_shopinvader_partner()))
return res

def _get_shopinvader_partner(self):
# As we use authenticated users the partner must come from current user.
# NOTE: this piece could probably go into a new shopinvader module
# but we want take full control on this ctx provider now.
partner_model = self.env["shopinvader.partner"]
# TODO: this could depend on having real users or not.
# For now, we rely on having a real user in Odoo.
# Note that this user != self.collection.env.user (tech user)
partner = self.request.env.user.partner_id
s_partner = partner._get_invader_partner(self.collection)
if s_partner:
return s_partner
else:
_logger.warning("Cannot determine shopinvader.partner")
raise MissingError(_("The given shopinvader user is not found!"))
return partner_model.browse()

def _get_shopinvader_session(self):
# HTTP_SESS are data that are store in the shopinvader session
# and forwarded to odoo at each request
# it allow to access to some specific field of the user session
# By security always force typing
# Note: rails cookies store session are serveless ;)
return {
"cart_id": int(self.request.httprequest.environ.get("HTTP_SESS_CART_ID", 0))
}
1 change: 1 addition & 0 deletions shopfloor_shopinvader_base/controllers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import main
59 changes: 59 additions & 0 deletions shopfloor_shopinvader_base/controllers/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright 2021 Camptocamp SA (http://www.camptocamp.com)
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).

import logging

from odoo.http import request

from odoo.addons.base_rest.controllers import main

_logger = logging.getLogger(__name__)


class ShopfloorInvaderController(main.RestController):

# TODO: this should be controlled from shopfloor.app ?
# We should probably generate other app-specific URLs via app._generate_endpoints
_component_context_provider = "shopfloor_invader_component_context_provider"

def _process_shopinvader_endpoint(
self,
app_id,
service_name,
service_method_name,
*args,
collection=None,
**kwargs
):
"""Wrapper for `_process_method` call.
Behavior is the same for the methods automatically
generated by `rest.service.registration`.
"""
collection = collection or request.env["shopfloor.app"].browse(app_id)
# get shopinvader backend from current app
backend = collection.shopinvader_backend_id.with_context(
shopfloor_app=collection.tech_name
)
if collection.shopinvader_tech_user_id:
# Use a technical user to bypass issues like
#
# odoo.exceptions.AccessError:
# You are not allowed to access 'Sales Team' (crm.team) records.
# This operation is allowed for the following groups:
# - Sales/Administrator
# - Sales/User: Own Documents Only
# - User types/Internal User
#
# If you want to support real users updates you must give them proper rights.
backend = backend.with_user(collection.shopinvader_tech_user_id)
if not backend:
# A not found will be raised later, just leave a trace for the poor devs :)
_logger.error(
"No shopinvader backend found for collection: %s", str(collection)
)
# TODO: in base_rest `*args` is passed based on the type of route
# (eg: /<int:id>/update)
return self._process_method(
service_name, service_method_name, *args, collection=backend, params=kwargs
)
24 changes: 24 additions & 0 deletions shopfloor_shopinvader_base/demo/res_users_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<odoo>
<record id="partner_1" model="res.partner">
<field name="name">Johnny</field>
<field name="email">[email protected]</field>
<field name="street">Somewhere</field>
<field name="city">Nowhere</field>
<field name="zip">1110</field>
<field name="country_id" ref="base.fr" />
<field name="property_product_pricelist" ref="product.list0" />
</record>

<record id="shopinvader_partner_1" model="shopinvader.partner">
<field name="backend_id" ref="shopinvader.backend_1" />
<field name="external_id">AaAaA</field>
<field name="record_id" ref="partner_1" />
</record>

<record id="user_demo" model="res.users">
<field name="groups_id" eval="[(4, ref('base.group_portal'))]" />
<field name="partner_id" ref="partner_1" />
<field name="login">shopfloor.invader.demo</field>
<field name="password">12345</field>
</record>
</odoo>
10 changes: 10 additions & 0 deletions shopfloor_shopinvader_base/demo/shopfloor_app_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<odoo>
<record id="app_demo" model="shopfloor.app">
<field name="name">shopinvader demo</field>
<field name="short_name">Shop</field>
<field name="tech_name">shop_demo</field>
<field name="category">shop</field>
<field name="shopinvader_tech_user_id" ref="invader_tech_user_demo" />
<field name="shopinvader_backend_id" ref="shopinvader.backend_1" />
</record>
</odoo>
16 changes: 16 additions & 0 deletions shopfloor_shopinvader_base/demo/tech_user_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<odoo>
<record id="invader_tech_user_demo" model="res.users">
<field
name="groups_id"
eval="[(6,0,[
ref('base.group_user'),
ref('base.group_system'),
ref('shopinvader.group_shopinvader_manager'),
ref('sales_team.group_sale_manager'),
])]"
/>
<field name="name">shopfloor shopinvader technical user</field>
<field name="email">[email protected]</field>
<field name="login">shopfloor.invader.tech.demo</field>
</record>
</odoo>
1 change: 1 addition & 0 deletions shopfloor_shopinvader_base/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import shopfloor_app
65 changes: 65 additions & 0 deletions shopfloor_shopinvader_base/models/shopfloor_app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Copyright 2021 Camptocamp SA (http://www.camptocamp.com)
# @author Simone Orsi <[email protected]>
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).
from odoo import api, fields, models

from odoo.addons.component.core import _component_databases

from ..controllers.main import ShopfloorInvaderController


class ShopfloorApp(models.Model):
_inherit = "shopfloor.app"

category = fields.Selection(selection_add=[("shop", "Shop")])
shopinvader_backend_id = fields.Many2one(
comodel_name="shopinvader.backend",
string="Shopinvader Backend",
)
shopinvader_tech_user_id = fields.Many2one(
comodel_name="res.users",
string="Shopinvader Tech User",
help="""
If this user is not set,
you'll have to ensure that every app user calling shop services
is allowed to handle sale records (eg: sale.order write).
""",
)

shop_api_route = fields.Char(compute="_compute_shop_api_route")

def _register_endpoints(self):
super()._register_endpoints()
self._register_shop_endpoints()

def _register_shop_endpoints(self):
services = self._get_shop_services()
for service in services:
self._prepare_non_decorated_endpoints(service)
self._generate_shop_endpoints(service)
self.env["rest.service.registration"]._register_rest_route(self.shop_api_route)

def _is_component_registry_ready(self):
# TODO: this can be moved to shopfloor_base
comp_registry = _component_databases.get(self.env.cr.dbname)
return comp_registry and comp_registry.ready

def _get_shop_services(self):
if not self._is_component_registry_ready():
return []
return self.env["rest.service.registration"]._get_services(
"shopinvader.backend"
)

@api.depends("api_route")
def _compute_shop_api_route(self):
for rec in self:
rec.shop_api_route = rec.api_route.rstrip("/") + "/invader/"

def _generate_shop_endpoints(self, service):
values = self._generate_endpoints_values(service, self.shop_api_route)
for vals in values:
rest_endpoint_handler = (
ShopfloorInvaderController()._process_shopinvader_endpoint
)
self._generate_endpoints_routes(service, rest_endpoint_handler, vals)
1 change: 1 addition & 0 deletions shopfloor_shopinvader_base/services/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import product
54 changes: 54 additions & 0 deletions shopfloor_shopinvader_base/services/product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2019 Camptocamp SA (http://www.camptocamp.com)
# @author: [email protected]
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html).

from odoo.addons.component.core import Component

# TODO: this is something I mande in 2019 in the ctx of a PoC for COS
# here https://github.com/camptocamp/odoo-shopinvader/
# tree/add-shopinvader_rest_product/shopinvader_rest_product
# should be moved to its own module in odoo-shopinvader if we keep it.


class ProductService(Component):
_inherit = "base.shopinvader.service"
_name = "shopinvader.product.service"
_usage = "products"
_expose_model = "shopinvader.variant"

@property
def _exposed_model(self):
# TODO: do we care at all about permissions here?
# I think not. This is correct till we access product info properly.
# It would be better probably to have a specific RR?
return super()._exposed_model.sudo()

# The following method are 'public' and can be called from the controller.
def get(self, _id):
return self._to_json(self._get(_id))[0]

def search(self, **params):
return self._paginate_search(**params)

def _get_base_search_domain(self):
return [("backend_id", "=", self.shopinvader_backend.id)]

# The following method are 'private' and should be never never NEVER call
# from the controller.
# All params are trusted as they have been checked before

def _get(self, _id):
return self.env[self._expose_model].browse(_id)

def _to_json(self, records):
# TODO: not super-efficient w/ many records
# only if used w/ `shopinvader_data_stored`
return [rec.get_shop_data() for rec in records]

# Validator
def _validator_get(self):
return {}

def _validator_search(self):
validator = self._default_validator_search()
return validator
18 changes: 18 additions & 0 deletions shopfloor_shopinvader_base/views/shopfloor_app.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="shopfloor_app_form_view" model="ir.ui.view">
<field name="name">shopfloor app form</field>
<field name="model">shopfloor.app</field>
<field name="inherit_id" ref="shopfloor_base.shopfloor_app_form_view" />
<field name="arch" type="xml">
<page name="main" position="after">
<page name="shopinvader" string="Shopinvader">
<group name="shop_main">
<field name="shopinvader_backend_id" />
<field name="shopinvader_tech_user_id" />
</group>
</page>
</page>
</field>
</record>
</odoo>
1 change: 1 addition & 0 deletions shopfloor_shopinvader_mobile_base/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
wait for the bot ;)
1 change: 1 addition & 0 deletions shopfloor_shopinvader_mobile_base/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import controllers
Loading

0 comments on commit bb0bd72

Please sign in to comment.