Skip to content

Commit d91139e

Browse files
committed
[MIG] sale_invoice_plan: Migration to 18.0
1 parent e8b605d commit d91139e

File tree

9 files changed

+89
-112
lines changed

9 files changed

+89
-112
lines changed

sale_invoice_plan/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
{
55
"name": "Sales Invoice Plan",
66
"summary": "Add to sales order, ability to manage future invoice plan",
7-
"version": "16.0.1.0.0",
7+
"version": "18.0.1.0.0",
88
"author": "Ecosoft,Odoo Community Association (OCA)",
99
"license": "AGPL-3",
1010
"website": "https://github.com/OCA/sale-workflow",

sale_invoice_plan/models/sale.py

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html)
33
from dateutil.relativedelta import relativedelta
44

5-
from odoo import _, api, fields, models
5+
from odoo import api, fields, models
66
from odoo.exceptions import UserError, ValidationError
77
from odoo.tools.float_utils import float_round
88

@@ -13,7 +13,7 @@ class SaleOrder(models.Model):
1313
invoice_plan_ids = fields.One2many(
1414
comodel_name="sale.invoice.plan",
1515
inverse_name="sale_id",
16-
string="Inovice Plan",
16+
string="Invoice Plan",
1717
copy=False,
1818
)
1919
use_invoice_plan = fields.Boolean(
@@ -31,7 +31,7 @@ class SaleOrder(models.Model):
3131
)
3232
invoice_plan_total_amount = fields.Monetary(
3333
compute="_compute_invoice_plan_total",
34-
string="Total Amount",
34+
string="Total Plan Amount",
3535
)
3636

3737
@api.depends("invoice_plan_ids")
@@ -44,7 +44,7 @@ def _compute_invoice_plan_total(self):
4444
def _compute_invoice_plan_process(self):
4545
for rec in self:
4646
has_invoice_plan = rec.use_invoice_plan and rec.invoice_plan_ids
47-
to_invoice = rec.invoice_plan_ids.filtered(lambda l: not l.invoiced)
47+
to_invoice = rec.invoice_plan_ids.filtered(lambda plan: not plan.invoiced)
4848
inv_or_adv = rec.invoice_status == "to invoice" or (
4949
rec.invoice_status == "no"
5050
and "advance" in to_invoice.mapped("invoice_type")
@@ -59,20 +59,24 @@ def _check_invoice_plan_total_percent(self):
5959
installments = rec.invoice_plan_ids.filtered("installment")
6060
invoice_plan_total_percent = sum(installments.mapped("percent"))
6161
if float_round(invoice_plan_total_percent, 0) > 100:
62-
raise UserError(_("Invoice plan total percentage must not exceed 100%"))
62+
raise UserError(
63+
self.env._("Invoice plan total percentage must not exceed 100%")
64+
)
6365

6466
@api.constrains("state")
6567
def _check_invoice_plan(self):
6668
for rec in self:
6769
if rec.state != "draft":
68-
if rec.invoice_plan_ids.filtered(lambda l: not l.percent):
70+
if rec.invoice_plan_ids.filtered(lambda plan: not plan.percent):
6971
raise ValidationError(
70-
_("Please fill percentage for all invoice plan lines")
72+
self.env._("Please fill percentage for all invoice plan lines")
7173
)
7274

7375
def action_confirm(self):
7476
if self.filtered(lambda r: r.use_invoice_plan and not r.invoice_plan_ids):
75-
raise UserError(_("Use Invoice Plan selected, but no plan created"))
77+
raise UserError(
78+
self.env._("Use Invoice Plan selected, but no plan created")
79+
)
7680
return super().action_confirm()
7781

7882
def create_invoice_plan(

sale_invoice_plan/models/sale_invoice_plan.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from odoo import _, api, fields, models
1+
from odoo import api, fields, models
22
from odoo.exceptions import UserError, ValidationError
33
from odoo.tools.float_utils import float_compare, float_round
44

@@ -15,7 +15,9 @@ class SaleInvoicePlan(models.Model):
1515
readonly=True,
1616
ondelete="cascade",
1717
)
18-
analytic_account_id = fields.Many2one(related="sale_id.analytic_account_id")
18+
analytic_account_id = fields.Many2many(
19+
related="sale_id.order_line.distribution_analytic_account_ids"
20+
)
1921
partner_id = fields.Many2one(
2022
comodel_name="res.partner",
2123
string="Customer",
@@ -104,7 +106,7 @@ def _compute_amount(self):
104106
# For last line, amount is the left over
105107
if rec.last:
106108
installments = rec.sale_id.invoice_plan_ids.filtered(
107-
lambda l: l.invoice_type == "installment"
109+
lambda plan: plan.invoice_type == "installment"
108110
)
109111
prev_amount = sum((installments - rec).mapped("amount"))
110112
rec.amount = amount_untaxed - prev_amount
@@ -117,7 +119,7 @@ def _inverse_amount(self):
117119
if rec.sale_id.amount_untaxed != 0:
118120
if rec.last:
119121
installments = rec.sale_id.invoice_plan_ids.filtered(
120-
lambda l: l.invoice_type == "installment"
122+
lambda invoice_plan: invoice_plan.invoice_type == "installment"
121123
)
122124
prev_percent = sum((installments - rec).mapped("percent"))
123125
rec.percent = 100 - prev_percent
@@ -142,23 +144,17 @@ def _compute_to_invoice(self):
142144
def _get_amount_invoice(self, invoices):
143145
"""Hook function"""
144146
amount_invoiced = sum(invoices.mapped("amount_untaxed"))
145-
deposit_product_id = (
146-
self.env["ir.config_parameter"]
147-
.sudo()
148-
.get_param("sale.default_deposit_product_id")
147+
lines = invoices.mapped("invoice_line_ids").filtered(
148+
lambda invoice_line: invoice_line.product_id.id
149149
)
150-
if deposit_product_id:
151-
lines = invoices.mapped("invoice_line_ids").filtered(
152-
lambda l: l.product_id.id != int(deposit_product_id)
153-
)
154-
amount_invoiced = sum(lines.mapped("price_subtotal"))
150+
amount_invoiced = sum(lines.mapped("price_subtotal"))
155151
return amount_invoiced
156152

157153
@api.depends("invoice_move_ids.state")
158154
def _compute_invoiced(self):
159155
for rec in self:
160156
invoiced = rec.invoice_move_ids.filtered(
161-
lambda l: l.state in ("draft", "posted")
157+
lambda move_line: move_line.state in ("draft", "posted")
162158
)
163159
rec.invoiced = True if invoiced else False
164160
rec.amount_invoiced = (
@@ -178,7 +174,9 @@ def _compute_new_invoice_quantity(self, invoice_move):
178174
return
179175
percent = self.percent
180176
move = invoice_move.with_context(check_move_validity=False)
181-
for line in move.invoice_line_ids:
177+
for line in move.invoice_line_ids.filtered(
178+
lambda line: line.display_type not in ("line_section", "line_note")
179+
):
182180
self._update_new_quantity(line, percent)
183181
move.line_ids.filtered(
184182
lambda x: x.display_type
@@ -188,7 +186,7 @@ def _compute_new_invoice_quantity(self, invoice_move):
188186
def _update_new_quantity(self, line, percent):
189187
"""Hook function"""
190188
if not len(line.sale_line_ids) >= 0:
191-
raise UserError(_("No matched order line for invoice line"))
189+
raise UserError(self.env._("No matched order line for invoice line"))
192190
order_line = fields.first(line.sale_line_ids)
193191
if order_line.is_downpayment: # based on 1 unit
194192
line.write({"quantity": -percent / 100})
@@ -197,9 +195,14 @@ def _update_new_quantity(self, line, percent):
197195
prec = order_line.product_uom.rounding
198196
if plan_qty:
199197
plan_qty = float_round(plan_qty, precision_rounding=prec)
200-
if float_compare(abs(plan_qty), abs(line.quantity), prec) == 1:
198+
if (
199+
float_compare(
200+
abs(plan_qty), abs(line.quantity), precision_rounding=prec
201+
)
202+
== 1
203+
):
201204
raise ValidationError(
202-
_(
205+
self.env._(
203206
"Plan quantity: %(plan_qty)s, exceed invoiceable quantity: "
204207
"%(invoiceable_qty)s"
205208
"\nProduct should be delivered before invoice"
@@ -218,7 +221,7 @@ def unlink(self):
218221
if lines:
219222
installments = [str(x) for x in lines.mapped("installment")]
220223
raise UserError(
221-
_(
224+
self.env._(
222225
"Installment %s: already used and not allowed to delete.\n"
223226
"Please discard changes."
224227
)
Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2-
access_sale_invoice_plan,access_sale_invoice_plan,model_sale_invoice_plan,,1,1,1,1
3-
access_sale_create_invoice_plan,access_sale_create_invoice_plan,model_sale_create_invoice_plan,,1,1,1,1
4-
access_sale_make_planned_invoice,access_sale_make_planned_invoice,model_sale_make_planned_invoice,,1,1,1,1
2+
access_sale_invoice_plan,access_sale_invoice_plan,model_sale_invoice_plan,sales_team.group_sale_salesman,1,1,1,1
3+
access_sale_create_invoice_plan,access_sale_create_invoice_plan,model_sale_create_invoice_plan,sales_team.group_sale_salesman,1,1,1,1
4+
access_sale_make_planned_invoice,access_sale_make_planned_invoice,model_sale_make_planned_invoice,sales_team.group_sale_salesman,1,1,1,1

sale_invoice_plan/tests/test_sale_invoice_plan.py

Lines changed: 13 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)
33
import logging
44

5-
from odoo import _, fields
5+
from odoo import fields
66
from odoo.exceptions import UserError, ValidationError
77
from odoo.tests import Form, tagged
88

@@ -85,7 +85,9 @@ def setUpClass(cls):
8585
},
8686
)
8787
],
88-
"pricelist_id": cls.env.ref("product.list0").id,
88+
"pricelist_id": cls.env["product.pricelist"]
89+
.browse(cls.env.context.get("pricelist"))
90+
.id,
8991
}
9092
)
9193

@@ -124,22 +126,6 @@ def setUpClassicProducts(cls):
124126
"categ_id": cls.product_category.id,
125127
}
126128
)
127-
# Advance Product
128-
deposit_account = cls.env["account.account"].search(
129-
[("internal_group", "=", "income"), ("deprecated", "=", False)], limit=1
130-
)
131-
cls.product_advance = cls.env["product.product"].create(
132-
{
133-
"name": _("Down payment"),
134-
"type": "service",
135-
"invoice_policy": "order",
136-
"property_account_income_id": deposit_account.id,
137-
"taxes_id": False,
138-
}
139-
)
140-
cls.env["ir.config_parameter"].sudo().set_param(
141-
"sale.default_deposit_product_id", cls.product_advance.id
142-
)
143129

144130
def test_00_invoice_plan(self):
145131
# To create next invoice from SO
@@ -152,7 +138,9 @@ def test_00_invoice_plan(self):
152138
try: # UserError if no installment
153139
plan = f.save()
154140
except ValidationError as e:
155-
_logger.info(_("No installment raises following error : %s"), e.args[0])
141+
_logger.info(
142+
self.env._("No installment raises following error : %s"), e.args[0]
143+
)
156144
# Create Invoice Plan 3 installment
157145
num_installment = 5
158146
f.num_installment = num_installment
@@ -241,7 +229,7 @@ def test_02_invoice_plan_with_advance(self):
241229
with self.assertRaises(ValidationError):
242230
self.so_service.action_confirm()
243231
advance_line = self.so_service.invoice_plan_ids.filtered(
244-
lambda l: l.invoice_type == "advance"
232+
lambda invoice_plan: invoice_plan.invoice_type == "advance"
245233
)
246234
self.assertEqual(len(advance_line), 1, "No one advance line")
247235
# Add 10% to advance
@@ -259,7 +247,9 @@ def test_02_invoice_plan_with_advance(self):
259247
# Valid total quantity of invoices (exclude Advance line)
260248
quantity = sum(
261249
invoices.mapped("invoice_line_ids")
262-
.filtered(lambda l: l.product_id == self.product_order)
250+
.filtered(
251+
lambda invoice_line: invoice_line.product_id == self.product_order
252+
)
263253
.mapped("quantity")
264254
)
265255
self.assertEqual(quantity, 1, "Wrong number of total invoice quantity")
@@ -323,7 +313,8 @@ def test_invoice_plan_so_edit(self):
323313
],
324314
}
325315
)
326-
# Overall amount changed to 3080, install amount not changed, only percent changed.
316+
# Overall amount changed to 3080, install amount not changed,
317+
# only percent changed.
327318
self.assertEqual(self.so_service.amount_total, 3080.0)
328319
self.so_service.invoice_plan_ids._compute_amount()
329320
self.assertEqual(first_install.amount, 280.0)

0 commit comments

Comments
 (0)