[FIX] account, sale: Fix account.move (invoices) access rights

Without any access rights on the 'account' module, a salesperson should be able to
create a new invoice from a sale order.

Since the merge of account.invoice with account.move, we need to manage carefully the
access rights when dealing with invoices. A salesperson must not be able to manage the
journal entries except the one being an invoice created for a sale order.

To make such restriction on the journal entry's type, we need additional record rules
- in sale: to restrict the access to invoices.
- in account: to exit such restrictions when having billing access rights.

closes odoo/odoo#44023

Signed-off-by: Laurent Smet <smetl@users.noreply.github.com>
This commit is contained in:
Laurent Smet
2020-01-28 08:18:10 +00:00
parent efa60a1538
commit 62ae169dfb
4 changed files with 31 additions and 10 deletions
@@ -203,6 +203,22 @@
<field name="domain_force">['|',('company_id','=',False),('company_id', 'in', company_ids)]</field>
</record>
<!-- Billing record rules for account.move -->
<record id="account_move_see_all" model="ir.rule">
<field name="name">All Journal Entries</field>
<field ref="model_account_move" name="model_id"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('account.group_account_invoice'))]"/>
</record>
<record id="account_move_line_see_all" model="ir.rule">
<field name="name">All Journal Items</field>
<field ref="model_account_move_line" name="model_id"/>
<field name="domain_force">[(1, '=', 1)]</field>
<field name="groups" eval="[(4, ref('account.group_account_invoice'))]"/>
</record>
<!-- Portal for invoice move and invoice move lines -->
<record id="account_invoice_rule_portal" model="ir.rule">
<field name="name">Portal Personal Account Invoices</field>
+7 -2
View File
@@ -579,6 +579,9 @@ class SaleOrder(models.Model):
:param final: if True, refunds will be generated if necessary
:returns: list of created invoices
"""
if not self.env.user.has_group('sales_team.group_sale_salesman'):
return []
precision = self.env['decimal.precision'].precision_get('Product Unit of Measure')
# 1) Create invoices.
@@ -636,12 +639,14 @@ class SaleOrder(models.Model):
invoice_vals_list = new_invoice_vals_list
# 3) Create invoices.
moves = self.env['account.move'].with_context(default_type='out_invoice').create(invoice_vals_list)
# Manage the creation of invoices in sudo because a salesperson must be able to generate an invoice from a
# sale order without "billing" access rights. However, he should not be able to create an invoice from scratch.
moves = self.env['account.move'].sudo().with_context(default_type='out_invoice').create(invoice_vals_list)
# 4) Some moves might actually be refunds: convert them if the total amount is negative
# We do this after the moves have been created since we need taxes, etc. to know if the total
# is actually negative or not
if final:
moves.filtered(lambda m: m.amount_total < 0).action_switch_invoice_into_refund_credit_note()
moves.sudo().filtered(lambda m: m.amount_total < 0).action_switch_invoice_into_refund_credit_note()
for move in moves:
move.message_post_with_view('mail.message_origin_link',
values={'self': move, 'origin': move.line_ids.mapped('sale_line_ids.order_id')},
+4 -4
View File
@@ -5,10 +5,10 @@ access_sale_order_line_readonly,sale.order.line accountant,model_sale_order_line
access_sale_order_line_accountant,sale.order.line accountant,model_sale_order_line,account.group_account_user,1,1,0,0
access_sale_order_portal,sale.order.portal,sale.model_sale_order,base.group_portal,1,0,0,0
access_sale_order_line_portal,sale.order.line.portal,sale.model_sale_order_line,base.group_portal,1,0,0,0
access_account_move_salesman,account_move salesman,account.model_account_move,sales_team.group_sale_salesman,1,1,1,0
access_account_move_manager,account_move manager,account.model_account_move,sales_team.group_sale_manager,1,1,1,1
access_account_move_line_salesman,account_move_line salesman,account.model_account_move_line,sales_team.group_sale_salesman,1,1,1,0
access_account_move__linemanager,account_move_line manager,account.model_account_move_line,sales_team.group_sale_manager,1,1,1,1
access_account_move_manager,account_move manager,account.model_account_move,sales_team.group_sale_manager,1,0,0,0
access_account_move_salesman,account_move salesman,account.model_account_move,sales_team.group_sale_salesman,1,0,0,0
access_account_move_line_salesman,account_move_line salesman,account.model_account_move_line,sales_team.group_sale_salesman,1,0,0,0
access_account_partial_reconcile_salesman,account_partial_reconcile salesman,account.model_account_partial_reconcile,sales_team.group_sale_salesman,1,0,0,0
access_account_payment_term_salesman,account_payment_term salesman,account.model_account_payment_term,sales_team.group_sale_salesman,1,0,0,0
access_account_account_tag_sale_salesman,account.account.tag.sale.salesman,account.model_account_account_tag,sales_team.group_sale_salesman,1,0,0,0
access_account_account_type_sale_salesman,account.account.type.sale.salesman,account.model_account_account_type,sales_team.group_sale_salesman,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
5 access_sale_order_line_accountant sale.order.line accountant model_sale_order_line account.group_account_user 1 1 0 0
6 access_sale_order_portal sale.order.portal sale.model_sale_order base.group_portal 1 0 0 0
7 access_sale_order_line_portal sale.order.line.portal sale.model_sale_order_line base.group_portal 1 0 0 0
8 access_account_move_salesman access_account_move_manager account_move salesman account_move manager account.model_account_move sales_team.group_sale_salesman sales_team.group_sale_manager 1 1 0 1 0 0
9 access_account_move_manager access_account_move_salesman account_move manager account_move salesman account.model_account_move sales_team.group_sale_manager sales_team.group_sale_salesman 1 1 0 1 0 1 0
10 access_account_move_line_salesman account_move_line salesman account.model_account_move_line sales_team.group_sale_salesman 1 1 0 1 0 0
11 access_account_move__linemanager access_account_partial_reconcile_salesman account_move_line manager account_partial_reconcile salesman account.model_account_move_line account.model_account_partial_reconcile sales_team.group_sale_manager sales_team.group_sale_salesman 1 1 0 1 0 1 0
12 access_account_payment_term_salesman account_payment_term salesman account.model_account_payment_term sales_team.group_sale_salesman 1 0 0 0
13 access_account_account_tag_sale_salesman account.account.tag.sale.salesman account.model_account_account_tag sales_team.group_sale_salesman 1 0 0 0
14 access_account_account_type_sale_salesman account.account.type.sale.salesman account.model_account_account_type sales_team.group_sale_salesman 1 0 0 0
+4 -4
View File
@@ -163,28 +163,28 @@
<record id="account_invoice_rule_see_personal" model="ir.rule">
<field name="name">Personal Invoices</field>
<field name="model_id" ref="model_account_move"/>
<field name="domain_force">[('invoice_user_id', '=', user.id), ('type', '!=', 'entry')]</field>
<field name="domain_force">[('type', 'in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund')), '|', ('invoice_user_id', '=', user.id), ('invoice_user_id', '=', False)]</field>
<field name="groups" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
</record>
<record id="account_invoice_rule_see_all" model="ir.rule">
<field name="name">All Invoices</field>
<field name="model_id" ref="model_account_move"/>
<field name="domain_force">[('type', '!=', 'entry')]</field>
<field name="domain_force">[('type', 'in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund'))]</field>
<field name="groups" eval="[(4, ref('sales_team.group_sale_salesman_all_leads'))]"/>
</record>
<record id="account_invoice_line_rule_see_personal" model="ir.rule">
<field name="name">Personal Invoice Lines</field>
<field name="model_id" ref="model_account_move_line"/>
<field name="domain_force">[('invoice_user_id', '=', user.id), ('type', '!=', 'entry')]</field>
<field name="domain_force">[('move_id.type', 'in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund')), '|', ('move_id.invoice_user_id', '=', user.id), ('move_id.invoice_user_id', '=', False)]</field>
<field name="groups" eval="[(4, ref('sales_team.group_sale_salesman'))]"/>
</record>
<record id="account_invoice_line_rule_see_all" model="ir.rule">
<field name="name">All Invoice Lines</field>
<field name="model_id" ref="model_account_move_line"/>
<field name="domain_force">[('type', '!=', 'entry')]</field>
<field name="domain_force">[('move_id.type', 'in', ('out_invoice', 'out_refund', 'in_invoice', 'in_refund'))]</field>
<field name="groups" eval="[(4, ref('sales_team.group_sale_salesman_all_leads'))]"/>
</record>
</data>