Skip to content

Commit 1fa14d4

Browse files
committed
[MIG] sale_order_action_invoice_create_hook: Migration to 11.0
1 parent 417bc35 commit 1fa14d4

File tree

8 files changed

+248
-129
lines changed

8 files changed

+248
-129
lines changed

sale_order_action_invoice_create_hook/README.rst

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
.. image:: https://img.shields.io/badge/licence-LGPL--3-blue.svg
2-
:alt: License LGPL-3
2+
:target: https://www.gnu.org/licenses/lgpl-3.0-standalone.html
3+
:alt: License LGPL-3
34

45
=====================================
56
Sale Order Action Invoice Create Hook
@@ -22,11 +23,11 @@ Usage
2223
various Sales Orders.
2324
#. Change the _get_draft_invoices function in order to take into account
2425
existing draft invoices when creating new ones. This feature is already
25-
implemented in the module 10.0-sale_merge_draft_invoice.
26+
implemented in the module sale_merge_draft_invoice.
2627

2728
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
2829
:alt: Try me on Runbot
29-
:target: https://runbot.odoo-community.org/runbot/167/10.0
30+
:target: https://runbot.odoo-community.org/runbot/167/11.0
3031

3132
Bug Tracker
3233
===========
@@ -39,6 +40,11 @@ help us smashing it by providing a detailed and welcomed feedback.
3940
Credits
4041
=======
4142

43+
Images
44+
------
45+
46+
* Odoo Community Association: `Icon <https://odoo-community.org/logo.png>`_.
47+
4248
Contributors
4349
------------
4450

@@ -59,4 +65,3 @@ mission is to support the collaborative development of Odoo features and
5965
promote its widespread use.
6066

6167
To contribute to this module, please visit https://odoo-community.org.
62-
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
# -*- coding: utf-8 -*-
21
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
3-
# License LGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
43

54
from . import model
5+
from .hooks import post_load_hook
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
# -*- coding: utf-8 -*-
21
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
32
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
43

54
{
65
"name": "Sale Order Action Invoice Create Hook",
76
"author": "Eficent, Odoo Community Association (OCA)",
8-
"version": "10.0.1.0.0",
7+
"version": "11.0.1.0.0",
98
"category": "Sale Workflow",
109
"website": "https://github.com/OCA/sale-workflow",
1110
"depends": [
1211
'sale',
1312
],
1413
"license": 'LGPL-3',
14+
"post_load": "post_load_hook",
1515
"installable": True
1616
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
3+
4+
from odoo import _
5+
from odoo.exceptions import UserError
6+
from odoo.tools import float_is_zero
7+
from odoo.addons.sale.models.sale import SaleOrder
8+
9+
10+
def post_load_hook():
11+
12+
def new_action_invoice_create(self, grouped=False, final=False):
13+
"""
14+
Create the invoice associated to the SO.
15+
:param grouped: if True, invoices are grouped by SO id. If False,
16+
invoices are grouped by (partner_invoice_id, currency)
17+
:param final: if True, refunds will be generated if necessary
18+
:returns: list of created invoices
19+
"""
20+
if not hasattr(self, '_get_invoice_group_key'):
21+
return self.action_invoice_create_original(grouped=grouped,
22+
final=final)
23+
invoices = {}
24+
references = {}
25+
26+
# START HOOK
27+
# Take into account draft invoices when creating new ones
28+
self._get_draft_invoices(invoices, references)
29+
# END HOOK
30+
31+
inv_obj = self.env['account.invoice']
32+
precision = self.env['decimal.precision'].\
33+
precision_get('Product Unit of Measure')
34+
35+
# START HOOK
36+
# As now from the beginning there can be invoices related to that
37+
# order, instead of new invoices, new lines are taking into account in
38+
# order to know whether there are invoice lines or not
39+
new_lines = False
40+
# END HOOK
41+
for order in self:
42+
# START HOOK
43+
# Add more flexibility in grouping key fields
44+
# WAS: group_key = order.id if grouped
45+
# else (order.partner_invoice_id.id, order.currency_id.id)
46+
group_key = order.id if grouped else \
47+
self._get_invoice_group_key(order)
48+
# 'invoice' must be always instantiated respecting the old logic
49+
if group_key in invoices:
50+
invoice = invoices[group_key]
51+
# END HOOK
52+
for line in order.order_line.sorted(
53+
key=lambda l: l.qty_to_invoice < 0):
54+
if float_is_zero(line.qty_to_invoice,
55+
precision_digits=precision):
56+
continue
57+
if group_key not in invoices:
58+
inv_data = order._prepare_invoice()
59+
invoice = inv_obj.create(inv_data)
60+
references[invoice] = order
61+
invoices[group_key] = invoice
62+
elif group_key in invoices:
63+
# START HOOK
64+
# This line below is added in order to cover cases where an
65+
# invoice is not created and instead a draft one is picked
66+
invoice = invoices[group_key]
67+
# END HOOK
68+
vals = {}
69+
if order.name not in invoices[group_key].\
70+
origin.split(', '):
71+
vals['origin'] = invoices[group_key].origin + ', ' + \
72+
order.name
73+
if order.client_order_ref and order.client_order_ref not \
74+
in invoices[group_key].name.split(', ') and \
75+
order.client_order_ref != invoices[group_key].name:
76+
vals['name'] = invoices[group_key].name + ', ' +\
77+
order.client_order_ref
78+
invoices[group_key].write(vals)
79+
if line.qty_to_invoice > 0:
80+
line.invoice_line_create(invoices[group_key].id,
81+
line.qty_to_invoice)
82+
# START HOOK
83+
# Change to true if new lines are added
84+
new_lines = True
85+
# END HOOK
86+
elif line.qty_to_invoice < 0 and final:
87+
line.invoice_line_create(invoices[group_key].id,
88+
line.qty_to_invoice)
89+
# START HOOK
90+
# Change to true if new lines are added
91+
new_lines = True
92+
# END HOOOK
93+
94+
if references.get(invoices.get(group_key)):
95+
if order not in references[invoices[group_key]]:
96+
references[invoice] = references[invoice] | order
97+
98+
# START HOOK
99+
# WAS: if not invoices:
100+
# Check if new lines have been added in order to determine whether
101+
# there are invoice lines or not
102+
if not new_lines:
103+
raise UserError(_('There is no invoicable line.'))
104+
# END HOOK
105+
106+
for invoice in invoices.values():
107+
if not invoice.invoice_line_ids:
108+
raise UserError(_('There is no invoicable line.'))
109+
# If invoice is negative, do a refund invoice instead
110+
if invoice.amount_untaxed < 0:
111+
invoice.type = 'out_refund'
112+
for line in invoice.invoice_line_ids:
113+
line.quantity = -line.quantity
114+
# Use additional field helper function (for account extensions)
115+
for line in invoice.invoice_line_ids:
116+
line._set_additional_fields(invoice)
117+
# Necessary to force computation of taxes. In account_invoice,
118+
# they are triggered by onchanges, which are not triggered when
119+
# doing a create.
120+
invoice.compute_taxes()
121+
invoice.message_post_with_view(
122+
'mail.message_origin_link',
123+
values={'self': invoice, 'origin': references[invoice]},
124+
subtype_id=self.env.ref('mail.mt_note').id)
125+
return [inv.id for inv in invoices.values()]
126+
127+
if not hasattr(SaleOrder, 'action_invoice_create_original'):
128+
SaleOrder.action_invoice_create_original = \
129+
SaleOrder.action_invoice_create
130+
131+
SaleOrder.action_invoice_create = new_action_invoice_create
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
# -*- coding: utf-8 -*-
21
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
3-
# License LGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
43

54
from . import sale_order
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
1-
# -*- coding: utf-8 -*-
21
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
3-
# License LGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
43

5-
from odoo import api, models, _
6-
from odoo.exceptions import UserError
7-
from odoo.tools import float_is_zero
4+
from odoo import api, models
85

96

107
class SaleOrder(models.Model):
@@ -17,117 +14,3 @@ def _get_invoice_group_key(self, order):
1714
@api.model
1815
def _get_draft_invoices(self, invoices, references):
1916
return invoices, references
20-
21-
@api.multi
22-
def action_invoice_create(self, grouped=False, final=False):
23-
"""
24-
Create the invoice associated to the SO.
25-
:param grouped: if True, invoices are grouped by SO id. If False,
26-
invoices are grouped by (partner_invoice_id, currency)
27-
:param final: if True, refunds will be generated if necessary
28-
:returns: list of created invoices
29-
"""
30-
31-
invoices = {}
32-
references = {}
33-
34-
# START HOOK
35-
# Take into account draft invoices when creating new ones
36-
self._get_draft_invoices(invoices, references)
37-
# END HOOK
38-
39-
inv_obj = self.env['account.invoice']
40-
precision = self.env['decimal.precision'].\
41-
precision_get('Product Unit of Measure')
42-
43-
# START HOOK
44-
# As now from the beginning there can be invoices related to that
45-
# order, instead of new invoices, new lines are taking into account in
46-
# order to know whether there are invoice lines or not
47-
new_lines = False
48-
# END HOOK
49-
for order in self:
50-
# START HOOK
51-
# Add more flexibility in grouping key fields
52-
# WAS: group_key = order.id if grouped
53-
# else (order.partner_invoice_id.id, order.currency_id.id)
54-
group_key = order.id if grouped else \
55-
self._get_invoice_group_key(order)
56-
# 'invoice' must be always instantiated respecting the old logic
57-
if group_key in invoices:
58-
invoice = invoices[group_key]
59-
# END HOOK
60-
for line in order.order_line.sorted(
61-
key=lambda l: l.qty_to_invoice < 0):
62-
if float_is_zero(line.qty_to_invoice,
63-
precision_digits=precision):
64-
continue
65-
if group_key not in invoices:
66-
inv_data = order._prepare_invoice()
67-
invoice = inv_obj.create(inv_data)
68-
references[invoice] = order
69-
invoices[group_key] = invoice
70-
elif group_key in invoices:
71-
# START HOOK
72-
# This line below is added in order to cover cases where an
73-
# invoice is not created and instead a draft one is picked
74-
invoice = invoices[group_key]
75-
# END HOOK
76-
vals = {}
77-
if order.name not in invoices[group_key].\
78-
origin.split(', '):
79-
vals['origin'] = invoices[group_key].origin + ', ' + \
80-
order.name
81-
if order.client_order_ref and order.client_order_ref not \
82-
in invoices[group_key].name.split(', ') and \
83-
order.client_order_ref != invoices[group_key].name:
84-
vals['name'] = invoices[group_key].name + ', ' +\
85-
order.client_order_ref
86-
invoices[group_key].write(vals)
87-
if line.qty_to_invoice > 0:
88-
line.invoice_line_create(invoices[group_key].id,
89-
line.qty_to_invoice)
90-
# START HOOK
91-
# Change to true if new lines are added
92-
new_lines = True
93-
# END HOOK
94-
elif line.qty_to_invoice < 0 and final:
95-
line.invoice_line_create(invoices[group_key].id,
96-
line.qty_to_invoice)
97-
# START HOOK
98-
# Change to true if new lines are added
99-
new_lines = True
100-
# END HOOOK
101-
102-
if references.get(invoices.get(group_key)):
103-
if order not in references[invoices[group_key]]:
104-
references[invoice] = references[invoice] | order
105-
106-
# START HOOK
107-
# WAS: if not invoices:
108-
# Check if new lines have been added in order to determine whether
109-
# there are invoice lines or not
110-
if not new_lines:
111-
raise UserError(_('There is no invoicable line.'))
112-
# END HOOK
113-
114-
for invoice in invoices.values():
115-
if not invoice.invoice_line_ids:
116-
raise UserError(_('There is no invoicable line.'))
117-
# If invoice is negative, do a refund invoice instead
118-
if invoice.amount_untaxed < 0:
119-
invoice.type = 'out_refund'
120-
for line in invoice.invoice_line_ids:
121-
line.quantity = -line.quantity
122-
# Use additional field helper function (for account extensions)
123-
for line in invoice.invoice_line_ids:
124-
line._set_additional_fields(invoice)
125-
# Necessary to force computation of taxes. In account_invoice,
126-
# they are triggered by onchanges, which are not triggered when
127-
# doing a create.
128-
invoice.compute_taxes()
129-
invoice.message_post_with_view(
130-
'mail.message_origin_link',
131-
values={'self': invoice, 'origin': references[invoice]},
132-
subtype_id=self.env.ref('mail.mt_note').id)
133-
return [inv.id for inv in invoices.values()]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
2+
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).
3+
4+
from . import test_sale_order_action_create_hook

0 commit comments

Comments
 (0)