From 2f7aed274456c0b1c2224d4eb296c7f18ffef640 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Mon, 11 Mar 2019 23:28:44 +0100 Subject: [PATCH] [REF] - add method to get quantity to invoice the contract line quantity can be in some use cases variable, to simplify the way it is changed we add a new method _get_quantity_to_invoice. --- contract/models/abstract_contract.py | 3 +- contract/models/abstract_contract_line.py | 30 +++++-- contract/models/contract.py | 40 +++++---- contract/models/contract_line.py | 29 +++---- contract/tests/test_contract.py | 99 ++++++++++++++++++----- 5 files changed, 138 insertions(+), 63 deletions(-) diff --git a/contract/models/abstract_contract.py b/contract/models/abstract_contract.py index 1c6292f9..93d7098e 100644 --- a/contract/models/abstract_contract.py +++ b/contract/models/abstract_contract.py @@ -19,8 +19,7 @@ class AbstractAccountAnalyticContract(models.AbstractModel): name = fields.Char(required=True) # Needed for avoiding errors on several inherited behaviors partner_id = fields.Many2one( - comodel_name="res.partner", string="Partner (always False)", - index=True, + comodel_name="res.partner", string="Partner (always False)", index=True ) pricelist_id = fields.Many2one( comodel_name='product.pricelist', string='Pricelist' diff --git a/contract/models/abstract_contract_line.py b/contract/models/abstract_contract_line.py index 9d171ca6..ca82a2d1 100644 --- a/contract/models/abstract_contract_line.py +++ b/contract/models/abstract_contract_line.py @@ -81,7 +81,7 @@ class AccountAbstractAnalyticContractLine(models.AbstractModel): ) date_start = fields.Date(string='Date Start') recurring_next_date = fields.Date(string='Date of Next Invoice') - + last_date_invoiced = fields.Date(string='Last Date Invoiced') is_canceled = fields.Boolean(string="Canceled", default=False) is_auto_renew = fields.Boolean(string="Auto Renew", default=False) auto_renew_interval = fields.Integer( @@ -116,6 +116,17 @@ class AccountAbstractAnalyticContractLine(models.AbstractModel): oldname='analytic_account_id', ) + @api.multi + def _get_invoiced_period(self, last_date_invoiced, recurring_next_date): + return self.date_start, last_date_invoiced, recurring_next_date + + @api.multi + def _get_quantity_to_invoice( + self, period_first_date, period_last_date, invoice_date + ): + self.ensure_one() + return self.quantity + @api.depends( 'automatic_price', 'specific_price', @@ -130,9 +141,13 @@ class AccountAbstractAnalyticContractLine(models.AbstractModel): """ for line in self: if line.automatic_price: + dates = line._get_invoiced_period( + line.last_date_invoiced, line.recurring_next_date + ) product = line.product_id.with_context( quantity=line.env.context.get( - 'contract_line_qty', line.quantity + 'contract_line_qty', + line._get_quantity_to_invoice(*dates), ), pricelist=line.contract_id.pricelist_id.id, partner=line.contract_id.partner_id.id, @@ -155,7 +170,10 @@ class AccountAbstractAnalyticContractLine(models.AbstractModel): @api.depends('quantity', 'price_unit', 'discount') def _compute_price_subtotal(self): for line in self: - subtotal = line.quantity * line.price_unit + dates = line._get_invoiced_period( + line.last_date_invoiced, line.recurring_next_date + ) + subtotal = line._get_quantity_to_invoice(*dates) * line.price_unit discount = line.discount / 100 subtotal *= 1 - discount if line.contract_id.pricelist_id: @@ -192,11 +210,13 @@ class AccountAbstractAnalyticContractLine(models.AbstractModel): date = self.recurring_next_date or fields.Date.context_today(self) partner = self.contract_id.partner_id or self.env.user.partner_id - + dates = self._get_invoiced_period( + self.last_date_invoiced, self.recurring_next_date + ) product = self.product_id.with_context( lang=partner.lang, partner=partner.id, - quantity=self.quantity, + quantity=self._get_quantity_to_invoice(*dates), date=date, pricelist=self.contract_id.pricelist_id.id, uom=self.uom_id.id, diff --git a/contract/models/contract.py b/contract/models/contract.py index 1212a459..3d3a02f6 100644 --- a/contract/models/contract.py +++ b/contract/models/contract.py @@ -48,8 +48,7 @@ class AccountAnalyticAccount(models.Model): compute='_compute_date_end', string='Date End', store=True ) payment_term_id = fields.Many2one( - comodel_name='account.payment.term', string='Payment Terms', - index=True, + comodel_name='account.payment.term', string='Payment Terms', index=True ) invoice_count = fields.Integer(compute="_compute_invoice_count") fiscal_position_id = fields.Many2one( @@ -63,8 +62,7 @@ class AccountAnalyticAccount(models.Model): ondelete='restrict', ) partner_id = fields.Many2one( - comodel_name='res.partner', - inverse='_inverse_partner_id', + comodel_name='res.partner', inverse='_inverse_partner_id' ) @api.multi @@ -72,7 +70,8 @@ class AccountAnalyticAccount(models.Model): for rec in self: if not rec.invoice_partner_id: rec.invoice_partner_id = rec.partner_id.address_get( - ['invoice'])['invoice'] + ['invoice'] + )['invoice'] @api.multi def _get_related_invoices(self): @@ -104,11 +103,16 @@ class AccountAnalyticAccount(models.Model): @api.multi def action_show_invoices(self): self.ensure_one() - tree_view_ref = 'account.invoice_supplier_tree' \ - if self.contract_type == 'purchase' \ + tree_view_ref = ( + 'account.invoice_supplier_tree' + if self.contract_type == 'purchase' else 'account.invoice_tree_with_onboarding' - form_view_ref = 'account.invoice_supplier_form' \ - if self.contract_type == 'purchase' else 'account.invoice_form' + ) + form_view_ref = ( + 'account.invoice_supplier_form' + if self.contract_type == 'purchase' + else 'account.invoice_form' + ) tree_view = self.env.ref(tree_view_ref, raise_if_not_found=False) form_view = self.env.ref(form_view_ref, raise_if_not_found=False) action = { @@ -184,12 +188,18 @@ class AccountAnalyticAccount(models.Model): def _onchange_partner_id(self): self.pricelist_id = self.partner_id.property_product_pricelist.id self.fiscal_position_id = self.partner_id.property_account_position_id - self.invoice_partner_id = self.partner_id.address_get( - ['invoice'])['invoice'] - return {'domain': {'invoice_partner_id': [ - '|', - ('id', 'parent_of', self.partner_id.id), - ('id', 'child_of', self.partner_id.id)]}} + self.invoice_partner_id = self.partner_id.address_get(['invoice'])[ + 'invoice' + ] + return { + 'domain': { + 'invoice_partner_id': [ + '|', + ('id', 'parent_of', self.partner_id.id), + ('id', 'child_of', self.partner_id.id), + ] + } + } @api.constrains('partner_id', 'recurring_invoices') def _check_partner_id_recurring_invoices(self): diff --git a/contract/models/contract_line.py b/contract/models/contract_line.py index 998ea8db..2d512788 100644 --- a/contract/models/contract_line.py +++ b/contract/models/contract_line.py @@ -486,9 +486,12 @@ class AccountAnalyticInvoiceLine(models.Model): @api.multi def _prepare_invoice_line(self, invoice_id=False): self.ensure_one() + dates = self._get_invoiced_period( + self.last_date_invoiced, self.recurring_next_date + ) invoice_line_vals = { 'product_id': self.product_id.id, - 'quantity': self.quantity, + 'quantity': self._get_quantity_to_invoice(*dates), 'uom_id': self.uom_id.id, 'discount': self.discount, 'contract_line_id': self.id, @@ -501,8 +504,7 @@ class AccountAnalyticInvoiceLine(models.Model): invoice_line_vals = invoice_line._convert_to_write(invoice_line._cache) # Insert markers contract = self.contract_id - first_date_invoiced, last_date_invoiced = self._get_invoiced_period() - name = self._insert_markers(first_date_invoiced, last_date_invoiced) + name = self._insert_markers(dates[0], dates[1]) invoice_line_vals.update( { 'name': name, @@ -513,10 +515,11 @@ class AccountAnalyticInvoiceLine(models.Model): return invoice_line_vals @api.multi - def _get_next_invoiced_period( - self, last_date_invoiced, recurring_next_date - ): + def _get_invoiced_period(self, last_date_invoiced, recurring_next_date): self.ensure_one() + first_date_invoiced = False + if not recurring_next_date: + return first_date_invoiced, last_date_invoiced, recurring_next_date first_date_invoiced = ( last_date_invoiced + relativedelta(days=1) if last_date_invoiced @@ -537,21 +540,9 @@ class AccountAnalyticInvoiceLine(models.Model): last_date_invoiced = recurring_next_date - relativedelta( days=1 ) - recurring_next_date = recurring_next_date + self.get_relative_delta( - self.recurring_rule_type, self.recurring_interval - ) - return first_date_invoiced, last_date_invoiced, recurring_next_date - - @api.multi - def _get_invoiced_period(self): - self.ensure_one() - dates = self._get_next_invoiced_period( - self.last_date_invoiced, self.recurring_next_date - ) - first_date_invoiced, last_date_invoiced, recurring_next_date = dates if self.date_end and self.date_end < last_date_invoiced: last_date_invoiced = self.date_end - return first_date_invoiced, last_date_invoiced + return first_date_invoiced, last_date_invoiced, recurring_next_date @api.multi def _insert_markers(self, first_date_invoiced, last_date_invoiced): diff --git a/contract/tests/test_contract.py b/contract/tests/test_contract.py index 54e71c2e..cf2bc803 100644 --- a/contract/tests/test_contract.py +++ b/contract/tests/test_contract.py @@ -153,9 +153,7 @@ class TestContract(TestContractBase): self.inv_line = self.invoice_monthly.invoice_line_ids[0] self.assertTrue(self.inv_line.invoice_line_tax_ids) self.assertAlmostEqual(self.inv_line.price_subtotal, 50.0) - self.assertEqual( - self.contract.user_id, self.invoice_monthly.user_id - ) + self.assertEqual(self.contract.user_id, self.invoice_monthly.user_id) def test_contract_recurring_next_date(self): recurring_next_date = to_date('2018-01-15') @@ -1332,15 +1330,24 @@ class TestContract(TestContractBase): self.acct_line.recurring_rule_type = 'monthlylastday' self.acct_line.date_end = '2018-03-15' self.acct_line._onchange_date_start() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-01-05')) self.assertEqual(last, to_date('2018-01-31')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-02-01')) self.assertEqual(last, to_date('2018-02-28')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-03-01')) self.assertEqual(last, to_date('2018-03-15')) self.acct_line.manual_renew_needed = True @@ -1352,11 +1359,17 @@ class TestContract(TestContractBase): self.acct_line.date_end = '2018-08-15' self.acct_line._onchange_date_start() self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-02-05')) self.assertEqual(last, to_date('2018-03-04')) self.acct_line.recurring_next_date = '2018-06-05' - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-02-05')) self.assertEqual(last, to_date('2018-07-04')) @@ -1367,11 +1380,17 @@ class TestContract(TestContractBase): self.acct_line.date_end = '2018-08-15' self.acct_line._onchange_date_start() self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-02-05')) self.assertEqual(last, to_date('2018-03-04')) self.acct_line.recurring_next_date = '2018-06-05' - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-02-05')) self.assertEqual(last, to_date('2018-06-04')) @@ -1381,15 +1400,24 @@ class TestContract(TestContractBase): self.acct_line.recurring_rule_type = 'monthly' self.acct_line.date_end = '2018-03-15' self.acct_line._onchange_date_start() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-01-05')) self.assertEqual(last, to_date('2018-02-04')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-02-05')) self.assertEqual(last, to_date('2018-03-04')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-03-05')) self.assertEqual(last, to_date('2018-03-15')) @@ -1399,15 +1427,24 @@ class TestContract(TestContractBase): self.acct_line.recurring_rule_type = 'monthly' self.acct_line.date_end = '2018-03-15' self.acct_line._onchange_date_start() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-01-05')) self.assertEqual(last, to_date('2018-02-04')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-02-05')) self.assertEqual(last, to_date('2018-03-04')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-03-05')) self.assertEqual(last, to_date('2018-03-15')) @@ -1417,15 +1454,24 @@ class TestContract(TestContractBase): self.acct_line.recurring_rule_type = 'yearly' self.acct_line.date_end = '2020-03-15' self.acct_line._onchange_date_start() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-01-05')) self.assertEqual(last, to_date('2019-01-04')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2019-01-05')) self.assertEqual(last, to_date('2020-01-04')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2020-01-05')) self.assertEqual(last, to_date('2020-03-15')) @@ -1435,15 +1481,24 @@ class TestContract(TestContractBase): self.acct_line.recurring_rule_type = 'yearly' self.acct_line.date_end = '2020-03-15' self.acct_line._onchange_date_start() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2018-01-05')) self.assertEqual(last, to_date('2019-01-04')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2019-01-05')) self.assertEqual(last, to_date('2020-01-04')) self.contract.recurring_create_invoice() - first, last = self.acct_line._get_invoiced_period() + first, last, recurring_next_date = self.acct_line._get_invoiced_period( + self.acct_line.last_date_invoiced, + self.acct_line.recurring_next_date, + ) self.assertEqual(first, to_date('2020-01-05')) self.assertEqual(last, to_date('2020-03-15'))