From a29e291b69335260b26840c195599ed5bf845e16 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Fri, 12 Jun 2015 12:33:48 +0200 Subject: [PATCH] [FIX] point_of_sale: ACLs & security rules POS users/managers should not have any access to the account.move/account.move.line, since they are not accountants. Regarding the bank statements, they should only have access to the ones coming from the POS specifically. opw-628000 --- addons/point_of_sale/point_of_sale.py | 71 ++++++++++--------- addons/point_of_sale/report/pos_invoice.py | 3 +- .../security/ir.model.access.csv | 23 +----- .../security/point_of_sale_security.xml | 36 ++++++++++ 4 files changed, 77 insertions(+), 56 deletions(-) diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index aa97a711293..1751a41611b 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -9,7 +9,7 @@ import sets from functools import partial -from openerp import tools, models +from openerp import tools, models, SUPERUSER_ID from openerp.osv import fields, osv from openerp.tools import float_is_zero from openerp.tools.translate import _ @@ -204,7 +204,7 @@ class pos_config(osv.osv): def create(self, cr, uid, values, context=None): ir_sequence = self.pool.get('ir.sequence') # force sequence_id field to new pos.order sequence - values['sequence_id'] = ir_sequence.create(cr, uid, { + values['sequence_id'] = ir_sequence.create(cr, SUPERUSER_ID, { 'name': 'POS Order %s' % values['name'], 'padding': 4, 'prefix': "%s/" % values['name'], @@ -214,7 +214,7 @@ class pos_config(osv.osv): # TODO master: add field sequence_line_id on model # this make sure we always have one available per company - ir_sequence.create(cr, uid, { + ir_sequence.create(cr, SUPERUSER_ID, { 'name': 'POS order line %s' % values['name'], 'padding': 4, 'prefix': "%s/" % values['name'], @@ -394,7 +394,7 @@ class pos_session(osv.osv): if not pos_config.journal_id: jid = jobj.default_get(cr, uid, ['journal_id'], context=context)['journal_id'] if jid: - jobj.write(cr, openerp.SUPERUSER_ID, [pos_config.id], {'journal_id': jid}, context=context) + jobj.write(cr, SUPERUSER_ID, [pos_config.id], {'journal_id': jid}, context=context) else: raise UserError(_("Unable to open the session. You have to assign a sale journal to your point of sale.")) @@ -407,24 +407,21 @@ class pos_session(osv.osv): if not cashids: cashids = journal_proxy.search(cr, uid, [('journal_user','=',True)], context=context) - journal_proxy.write(cr, openerp.SUPERUSER_ID, cashids, {'journal_user': True}) - jobj.write(cr, openerp.SUPERUSER_ID, [pos_config.id], {'journal_ids': [(6,0, cashids)]}) + journal_proxy.write(cr, SUPERUSER_ID, cashids, {'journal_user': True}) + jobj.write(cr, SUPERUSER_ID, [pos_config.id], {'journal_ids': [(6,0, cashids)]}) pos_config = jobj.browse(cr, uid, config_id, context=context) - bank_statement_ids = [] - for journal in pos_config.journal_ids: - bank_values = { - 'journal_id' : journal.id, - 'user_id' : uid, - 'company_id' : pos_config.company_id.id - } - statement_id = self.pool.get('account.bank.statement').create(cr, uid, bank_values, context=context) - bank_statement_ids.append(statement_id) + + statements = [(0, 0, { + 'journal_id': journal.id, + 'user_id': uid, + 'company_id': pos_config.company_id.id + }) for journal in pos_config.journal_ids] values.update({ 'name': self.pool['ir.sequence'].next_by_code(cr, uid, 'pos.session'), - 'statement_ids' : [(6, 0, bank_statement_ids)], + 'statement_ids': statements, 'config_id': config_id }) @@ -488,7 +485,10 @@ class pos_session(osv.osv): def wkf_action_close(self, cr, uid, ids, context=None): # Close CashBox + local_context = dict(context) for record in self.browse(cr, uid, ids, context=context): + company_id = record.config_id.company_id.id + local_context.update({'force_company': company_id, 'company_id': company_id}) for st in record.statement_ids: if abs(st.difference) > st.journal_id.amount_authorized_diff: # The pos manager can close statements with maximums. @@ -496,9 +496,9 @@ class pos_session(osv.osv): raise UserError(_("Your ending balance is too different from the theoretical cash closing (%.2f), the maximum allowed is: %.2f. You can contact your manager to force it.") % (st.difference, st.journal_id.amount_authorized_diff)) if (st.journal_id.type not in ['bank', 'cash']): raise UserError(_("The type of the journal for your payment method should be bank or cash ")) - st.button_confirm_bank() - self._confirm_orders(cr, uid, ids, context=context) - self.write(cr, uid, ids, {'state' : 'closed'}, context=context) + self.pool['account.bank.statement'].button_confirm_bank(cr, SUPERUSER_ID, [st.id], context=local_context) + self._confirm_orders(cr, uid, ids, context=local_context) + self.write(cr, uid, ids, {'state' : 'closed'}, context=local_context) obj = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'point_of_sale', 'menu_point_root')[1] return { @@ -640,7 +640,7 @@ class pos_order(osv.osv): if to_invoice: self.action_invoice(cr, uid, [order_id], context) order_obj = self.browse(cr, uid, order_id, context) - self.pool['account.invoice'].signal_workflow(cr, uid, [order_obj.invoice_id.id], 'invoice_open') + self.pool['account.invoice'].signal_workflow(cr, SUPERUSER_ID, [order_obj.invoice_id.id], 'invoice_open') return order_ids @@ -962,6 +962,9 @@ class pos_order(osv.osv): inv_ids = [] for order in self.pool.get('pos.order').browse(cr, uid, ids, context=context): + # Force company for all SUPERUSER_ID action + company_id = order.company_id.id + local_context = dict(context or {}, force_company=company_id, company_id=company_id) if order.invoice_id: inv_ids.append(order.invoice_id.id) continue @@ -980,6 +983,7 @@ class pos_order(osv.osv): 'partner_id': order.partner_id.id, 'comment': order.note or '', 'currency_id': order.pricelist_id.currency_id.id, # considering partner's sale pricelist's currency + 'company_id': company_id, } invoice = inv_ref.new(cr, uid, inv) invoice._onchange_partner_id() @@ -987,30 +991,30 @@ class pos_order(osv.osv): inv = invoice._convert_to_write(invoice._cache) if not inv.get('account_id', None): inv['account_id'] = acc - inv_id = inv_ref.create(cr, uid, inv, context=context) + inv_id = inv_ref.create(cr, SUPERUSER_ID, inv, context=local_context) - self.write(cr, uid, [order.id], {'invoice_id': inv_id, 'state': 'invoiced'}, context=context) + self.write(cr, uid, [order.id], {'invoice_id': inv_id, 'state': 'invoiced'}, context=local_context) inv_ids.append(inv_id) for line in order.lines: - inv_name = product_obj.name_get(cr, uid, [line.product_id.id], context=context)[0][1] + inv_name = product_obj.name_get(cr, uid, [line.product_id.id], context=local_context)[0][1] inv_line = { 'invoice_id': inv_id, 'product_id': line.product_id.id, 'quantity': line.qty, - 'account_analytic_id': self._prepare_analytic_account(cr, uid, line, context=context), + 'account_analytic_id': self._prepare_analytic_account(cr, uid, line, context=local_context), 'name': inv_name, } #Oldlin trick - - invoice_line = inv_line_ref.new(cr, uid, inv_line, context=context) + invoice_line = inv_line_ref.new(cr, SUPERUSER_ID, inv_line, context=local_context) invoice_line._onchange_product_id() + invoice_line.invoice_line_tax_ids = [tax.id for tax in invoice_line.invoice_line_tax_ids if tax.company_id.id == company_id] # We convert a new id object back to a dictionary to write to bridge between old and new api inv_line = invoice_line._convert_to_write(invoice_line._cache) - inv_line_ref.create(cr, uid, inv_line, context=context) - inv_ref.compute_taxes(cr, uid, [inv_id], context=context) + inv_line_ref.create(cr, SUPERUSER_ID, inv_line, context=local_context) + inv_ref.compute_taxes(cr, SUPERUSER_ID, [inv_id], context=local_context) self.signal_workflow(cr, uid, [order.id], 'invoice') - inv_ref.signal_workflow(cr, uid, [inv_id], 'validate') + inv_ref.signal_workflow(cr, SUPERUSER_ID, [inv_id], 'validate') if not inv_ids: return {} @@ -1037,11 +1041,10 @@ class pos_order(osv.osv): return False def _create_account_move(self, cr, uid, dt, ref, journal_id, company_id, context=None): - local_context = dict(context or {}, company_id=company_id) start_at_datetime = datetime.strptime(dt, tools.DEFAULT_SERVER_DATETIME_FORMAT) date_tz_user = fields.datetime.context_timestamp(cr, uid, start_at_datetime, context=context) date_tz_user = date_tz_user.strftime(tools.DEFAULT_SERVER_DATE_FORMAT) - return self.pool['account.move'].create(cr, uid, {'ref': ref, 'journal_id': journal_id, 'date': date_tz_user}, context=context) + return self.pool['account.move'].create(cr, SUPERUSER_ID, {'ref': ref, 'journal_id': journal_id, 'date': date_tz_user}, context=context) def _create_account_move_line(self, cr, uid, ids, session=None, move_id=None, context=None): # Tricky, via the workflow, we only have one id in the ids variable @@ -1079,7 +1082,7 @@ class pos_order(osv.osv): # Create an entry for the sale move_id = self._create_account_move(cr, uid, order.session_id.start_at, order.name, order.sale_journal.id, order.company_id.id, context=context) - move = account_move_obj.browse(cr, uid, move_id, context=context) + move = account_move_obj.browse(cr, SUPERUSER_ID, move_id, context=context) def insert_data(data_type, values): # if have_to_group_by: @@ -1202,8 +1205,8 @@ class pos_order(osv.osv): for value in group_data: all_lines.append((0, 0, value),) if move_id: #In case no order was changed - self.pool.get("account.move").write(cr, uid, [move_id], {'line_ids':all_lines}, context=context) - self.pool.get("account.move").post(cr, uid, [move_id], context=context) + self.pool.get("account.move").write(cr, SUPERUSER_ID, [move_id], {'line_ids':all_lines}, context=context) + self.pool.get("account.move").post(cr, SUPERUSER_ID, [move_id], context=context) return True diff --git a/addons/point_of_sale/report/pos_invoice.py b/addons/point_of_sale/report/pos_invoice.py index 6506d701494..d3f7dee0b68 100644 --- a/addons/point_of_sale/report/pos_invoice.py +++ b/addons/point_of_sale/report/pos_invoice.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. +from openerp import SUPERUSER_ID from openerp.osv import osv from openerp.tools.translate import _ from openerp.exceptions import UserError @@ -33,4 +34,4 @@ class PosInvoiceReport(osv.AbstractModel): 'doc_model': report.model, 'docs': selected_orders, } - return report_obj.render(cr, uid, ids, 'account.report_invoice', docargs, context=context) + return report_obj.render(cr, SUPERUSER_ID, ids, 'account.report_invoice', docargs, context=context) diff --git a/addons/point_of_sale/security/ir.model.access.csv b/addons/point_of_sale/security/ir.model.access.csv index 7b6cc139d04..8023c5dc076 100644 --- a/addons/point_of_sale/security/ir.model.access.csv +++ b/addons/point_of_sale/security/ir.model.access.csv @@ -1,12 +1,7 @@ id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink access_pos_order,pos.order,model_pos_order,group_pos_user,1,1,1,1 access_pos_order_line,pos.order.line,model_pos_order_line,group_pos_user,1,1,1,1 -access_pos_order_manager,pos.order manager,model_pos_order,group_pos_manager,1,0,0,0 -access_pos_order_line_manager,pos.order.line manager,model_pos_order_line,group_pos_manager,1,0,0,0 access_report_transaction_pos,report.transaction.pos,model_report_transaction_pos,group_pos_manager,1,1,1,1 -access_account_journal_pos_user,account.journal pos_user,account.model_account_journal,group_pos_user,1,0,0,0 -access_account_move_pos_user,account.move pos_user,account.model_account_move,group_pos_user,1,1,1,0 -access_account_account_pos_user,account.account pos_user,account.model_account_account,group_pos_user,1,0,0,0 access_stock_picking_pos_user,stock.picking pos_user,stock.model_stock_picking,group_pos_user,1,1,1,1 access_stock_warehouse_pos_user,stock.warehouse pos_user,stock.model_stock_warehouse,group_pos_user,1,0,0,0 access_pos_order_stock_worker,pos.order stock_worker,model_pos_order,stock.group_stock_user,1,0,0,0 @@ -14,40 +9,26 @@ access_stock_move_pos_user,stock.move pos_user,stock.model_stock_move,group_pos_ access_report_sales_by_user_pos,report.sales.by.user.pos,model_report_sales_by_user_pos,group_pos_user,1,0,0,0 access_report_sales_by_user_pos_month,report.sales.by.user.pos.month,model_report_sales_by_user_pos_month,group_pos_user,1,0,0,0 access_report_pos_order,report.pos.order,model_report_pos_order,group_pos_user,1,1,1,1 +access_account_journal_pos_user,account.journal pos_user,account.model_account_journal,group_pos_user,1,0,0,0 +access_account_payment_method_pos_user,account.payment.method pos_user,account.model_account_payment_method,group_pos_manager,1,0,0,0 access_account_bank_statement,account.bank.statement,account.model_account_bank_statement,group_pos_user,1,1,1,0 access_account_bank_statement_manager,account.bank.statement manager,account.model_account_bank_statement,group_pos_manager,1,1,1,1 access_account_bank_statement_line,account.bank.statement.line,account.model_account_bank_statement_line,group_pos_user,1,1,1,0 -access_account_invoice_pos,account.invoice pos user,account.model_account_invoice,group_pos_user,1,1,1,0 -access_account_invoice_pos_manager,account.invoice pos manager,account.model_account_invoice,group_pos_manager,1,0,0,0 -access_account_invoice_line_pos,account.invoice.line pos user,account.model_account_invoice_line,group_pos_user,1,1,1,0 -access_account_invoice_line_pos_manager,account.invoice.line pos manager,account.model_account_invoice_line,group_pos_manager,1,0,0,0 -access_account_invoice_tax_pos,account.invoice.tax pos user,account.model_account_invoice_tax,group_pos_user,1,1,1,0 -access_account_invoice_tax_pos_manager,account.invoice.tax pos manager,account.model_account_invoice_tax,group_pos_manager,1,0,0,0 access_product_product,product.product,product.model_product_product,group_pos_user,1,0,0,0 access_product_template_pos_user,product.template pos user,product.model_product_template,group_pos_user,1,0,0,0 access_product_product_pos_manager,product.product.pos manager,product.model_product_product,group_pos_manager,1,1,1,1 access_product_template_pos_manager,product.template pos manager,product.model_product_template,group_pos_manager,1,1,1,1 -access_account_move_line,account.move.line,account.model_account_move_line,group_pos_user,1,1,1,0 -access_account_move_line_manager,account.move.line manager,account.model_account_move_line,group_pos_manager,1,1,1,1 -access_account_move,account.move,account.model_account_move,group_pos_manager,1,0,0,0 -access_account_journal,account.journal,account.model_account_journal,group_pos_manager,1,1,1,0 -access_account_analytic_line,account.analytic.line,analytic.model_account_analytic_line,group_pos_user,1,1,1,0 -access_account_analytic_account,account.analytic.account,analytic.model_account_analytic_account,group_pos_user,1,1,1,0 -access_ir_property_pos_manager,ir.property manager,base.model_ir_property,group_pos_manager,1,1,1,1 access_account_bank_statement_line_manager,account.bank.statement.line manager,account.model_account_bank_statement_line,group_pos_manager,1,1,1,1 -access_account_invoice_manager,account.invoice manager,account.model_account_invoice,group_pos_manager,1,1,1,1 access_product_product_supplierinfo_user,product.supplierinfo user,product.model_product_supplierinfo,group_pos_user,1,0,0,0 access_product_product_packaging_user,product.packaging user,product.model_product_packaging,group_pos_user,1,0,0,0 access_stock_warehouse_manager,stock.warehouse manager,stock.model_stock_warehouse,group_pos_manager,1,0,0,0 access_stock_location_manager,stock.location manager,stock.model_stock_location,group_pos_manager,1,0,0,0 access_product_uom_manager,product.uom manager,product.model_product_uom,group_pos_manager,1,1,1,1 -access_res_partner_manager,res.partner manager,base.model_res_partner,group_pos_manager,1,0,0,0 access_product_category_manager,product.category manager,product.model_product_category,group_pos_manager,1,1,1,1 access_product_pricelist_manager,product.pricelist manager,product.model_product_pricelist,group_pos_manager,1,0,0,0 access_pos_session_user,pos.session user,model_pos_session,group_pos_user,1,1,1,0 access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,0,0,0 access_pos_config_manager,pos.config user,model_pos_config,group_pos_manager,1,1,1,0 -access_ir_sequence_manager,ir.sequence manager,base.model_ir_sequence,group_pos_manager,1,1,1,1 access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,1 access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,0 access_barcode_nomenclature_pos_user,barcode.nomenclature.pos.user,barcodes.model_barcode_nomenclature,group_pos_user,1,0,0,0 diff --git a/addons/point_of_sale/security/point_of_sale_security.xml b/addons/point_of_sale/security/point_of_sale_security.xml index 1a472061220..1d3e6123eef 100644 --- a/addons/point_of_sale/security/point_of_sale_security.xml +++ b/addons/point_of_sale/security/point_of_sale_security.xml @@ -13,6 +13,42 @@ + + Point Of Sale Bank Statement POS User + + + [('pos_session_id', '!=', False)] + + + Point Of Sale Bank Statement Accountant + + + [(1, '=', 1)] + + + Point Of Sale Bank Statement Line POS User + + + [('statement_id.pos_session_id', '!=', False)] + + + Point Of Sale Bank Statement Line Accountant + + + [(1, '=', 1)] + + + Point Of Sale Cashbox Line POS User + + + [('bank_statement_id.pos_session_id', '!=', False)] + + + Point Of Sale Cashbox Line Accountant + + + [(1, '=', 1)] + Point Of Sale Order