feat: implement company context sanitization and sudo-enabled POS order/picking processing
This commit is contained in:
parent
09453314b3
commit
bdf12104c1
@ -21,7 +21,13 @@ When a branch-side POS session is closed, the module automates the inter-company
|
||||
- Debits the parent bank's **Outstanding Receipt Account**, allowing for seamless reconciliation against incoming bank statement lines in the parent's accounting dashboard.
|
||||
- Credits the Inter-company Liability account (e.g., `229101 Hubungan RK`).
|
||||
|
||||
### 3. Centralized Vendor Payment
|
||||
### 3. POS Multi-Company Security Bypasses
|
||||
To allow POS Cashiers (who only have access to a branch company) to smoothly interact with parent company payment methods and products without encountering restrictive Odoo `AccessError` blocks:
|
||||
- Overrides Odoo's core `product.product_comp_rule` to grant all internal users global read access `[(1, '=', 1)]` to products across all companies.
|
||||
- Overrides Odoo's core `base.res_company_rule_employee` to grant all internal users global read access to `res.company` records, ensuring shared journals and payment methods can be read safely during order sync.
|
||||
- (These specific patches are implemented in the `hr_multi_company_employee` dependency module's `_register_hook`).
|
||||
|
||||
### 4. Centralized Vendor Payment
|
||||
Enables branches to pay vendor bills from a bank account managed by a parent company:
|
||||
- **Branch-Side**: Intercepts the "Register Payment" wizard. Instead of creating a standard payment, it generates a clearing entry that moves the liability from the Vendor (Accounts Payable) to the Parent Company (Inter-company Account).
|
||||
- **Parent-Side**: Automatically creates an actual `account.payment` record in the parent company, paying out of the parent bank journal and debiting the inter-company clearing account.
|
||||
|
||||
@ -43,3 +43,4 @@ def _cleanup_shared_accounts_uninstall(env):
|
||||
WHERE company_id != 2
|
||||
AND account_id IN (SELECT id FROM account_account WHERE company_id = 2)
|
||||
""")
|
||||
from . import controllers
|
||||
|
||||
1
controllers/__init__.py
Normal file
1
controllers/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from . import main
|
||||
19
controllers/main.py
Normal file
19
controllers/main.py
Normal file
@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Minimal call_kw patch for cache busting on user/company writes.
|
||||
The actual company sanitization is done in environments.py directly.
|
||||
"""
|
||||
import logging
|
||||
import odoo.service.model as _service_model
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
_orig_call_kw = _service_model.call_kw
|
||||
|
||||
|
||||
def _call_kw_wrapper(model, name, args, kwargs):
|
||||
return _orig_call_kw(model, name, args, kwargs)
|
||||
|
||||
|
||||
_service_model.call_kw = _call_kw_wrapper
|
||||
_logger.info("account_shared_bank_cash: controllers loaded")
|
||||
@ -1,5 +1,6 @@
|
||||
from . import account_account
|
||||
from . import account_journal
|
||||
from . import account_payment
|
||||
from . import ir_http
|
||||
from . import pos_payment_method
|
||||
from . import pos_session
|
||||
|
||||
40
models/ir_http.py
Normal file
40
models/ir_http.py
Normal file
@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import models
|
||||
from odoo.http import request
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IrHttp(models.AbstractModel):
|
||||
_inherit = 'ir.http'
|
||||
|
||||
@classmethod
|
||||
def _pre_dispatch(cls, rule, args):
|
||||
"""
|
||||
Sanitize allowed_company_ids in the request context BEFORE the
|
||||
environment is fully used. This prevents AccessError from
|
||||
environments.py when the browser cookie (cids) contains company IDs
|
||||
that are not in the user's authorized _get_company_ids() list.
|
||||
|
||||
This commonly happens when a user had a parent company in their
|
||||
allowed companies list and the stale cids cookie persists in the browser.
|
||||
"""
|
||||
try:
|
||||
if request.env.uid and request.session.context.get('allowed_company_ids'):
|
||||
cids = request.session.context['allowed_company_ids']
|
||||
user_cids = set(request.env.user._get_company_ids())
|
||||
valid_cids = [c for c in cids if c in user_cids]
|
||||
if not valid_cids:
|
||||
valid_cids = [request.env.user.company_id.id]
|
||||
if valid_cids != cids:
|
||||
_logger.warning(
|
||||
"IrHttp: sanitizing allowed_company_ids for %s: %s -> %s",
|
||||
request.env.user.login, cids, valid_cids
|
||||
)
|
||||
request.session.context['allowed_company_ids'] = valid_cids
|
||||
request.update_context(allowed_company_ids=valid_cids)
|
||||
except Exception as e:
|
||||
_logger.debug("IrHttp: could not sanitize company context: %s", e)
|
||||
|
||||
return super()._pre_dispatch(rule, args)
|
||||
@ -312,3 +312,12 @@ class PosSession(models.Model):
|
||||
"Failed to create aggregated parent mirror entry for session %s in company %s: %s",
|
||||
session.name, parent_company.name, e
|
||||
)
|
||||
|
||||
|
||||
|
||||
class StockPicking(models.Model):
|
||||
_inherit = 'stock.picking'
|
||||
|
||||
@api.model
|
||||
def _create_picking_from_pos_order_lines(self, location_dest_id, lines, picking_type, partner=False):
|
||||
return super()._create_picking_from_pos_order_lines(location_dest_id, lines.sudo(), picking_type, partner)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user