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.
|
- 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`).
|
- 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:
|
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).
|
- **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.
|
- **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
|
WHERE company_id != 2
|
||||||
AND account_id IN (SELECT id FROM account_account 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_account
|
||||||
from . import account_journal
|
from . import account_journal
|
||||||
from . import account_payment
|
from . import account_payment
|
||||||
|
from . import ir_http
|
||||||
from . import pos_payment_method
|
from . import pos_payment_method
|
||||||
from . import pos_session
|
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",
|
"Failed to create aggregated parent mirror entry for session %s in company %s: %s",
|
||||||
session.name, parent_company.name, e
|
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