summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLucas Perais (lpe) <lpe@odoo.com>2019-01-18 16:31:38 +0000
committerLucas Perais (lpe) <lpe@odoo.com>2019-01-28 08:58:13 +0000
commite5cc3d5ab98182a930fe232b995030cd2cf28247 (patch)
treea922e89c918635867b0f5224313f0fd53c3be3ac
parent03a88196525abe0cc3c2a47cc46bcdf802416ef7 (diff)
[FIX] account: journal dashboard amounts
Have a journal with 1 unpaid invoice and 1 refund to be paid too Before this commit, the data on the journal's dashboard for unpaid invoice was the sum of the refund and the invoice After this commit, the amount of the refunds are substracted while the amount of invoices are added Also, the behavior is harmonized across other amounts that display on the dashboard and tested OPW 1924388 closes odoo/odoo#30395
-rw-r--r--addons/account/models/account_journal_dashboard.py24
-rw-r--r--addons/account/tests/test_account_customer_invoice.py118
2 files changed, 135 insertions, 7 deletions
diff --git a/addons/account/models/account_journal_dashboard.py b/addons/account/models/account_journal_dashboard.py
index 106eebb37fa..c24b1be061d 100644
--- a/addons/account/models/account_journal_dashboard.py
+++ b/addons/account/models/account_journal_dashboard.py
@@ -185,8 +185,8 @@ class account_journal(models.Model):
self.env.cr.execute(query, query_args)
query_results_drafts = self.env.cr.dictfetchall()
- today = datetime.today()
- query = """SELECT amount_total, currency_id AS currency, type, date_invoice, company_id FROM account_invoice WHERE journal_id = %s AND date <= %s AND state = 'open';"""
+ today = fields.Date.today()
+ query = """SELECT residual_signed as amount_total, currency_id AS currency, type, date_invoice, company_id FROM account_invoice WHERE journal_id = %s AND date <= %s AND state = 'open';"""
self.env.cr.execute(query, (self.id, today))
late_query_results = self.env.cr.dictfetchall()
(number_waiting, sum_waiting) = self._count_results_and_sum_amounts(query_results_to_pay, currency)
@@ -226,13 +226,23 @@ class account_journal(models.Model):
gather the bills in draft state data, and the arguments
dictionary to use to run it as its second.
"""
- return ("""SELECT state, amount_total, currency_id AS currency, type, date_invoice, company_id
- FROM account_invoice
+ # there is no account_move_lines for draft invoices, so no relevant residual_signed value
+ return ("""SELECT state,
+ (CASE WHEN inv.type in ('out_invoice', 'in_invoice')
+ THEN inv.amount_total
+ ELSE (-1 * inv.amount_total)
+ END) AS amount_total,
+ inv.currency_id AS currency,
+ inv.type,
+ inv.date_invoice,
+ inv.company_id
+ FROM account_invoice inv
WHERE journal_id = %(journal_id)s AND state = 'draft';""", {'journal_id':self.id})
def _count_results_and_sum_amounts(self, results_dict, target_currency):
""" Loops on a query result to count the total number of invoices and sum
their amount_total field (expressed in the given target currency).
+ amount_total must be signed !
"""
rslt_count = 0
rslt_sum = 0.0
@@ -240,9 +250,9 @@ class account_journal(models.Model):
cur = self.env['res.currency'].browse(result.get('currency'))
company = self.env['res.company'].browse(result.get('company_id')) or self.env.user.company_id
rslt_count += 1
- type_factor = result.get('type') in ('in_refund', 'out_refund') and -1 or 1
- rslt_sum += type_factor * cur._convert(
- result.get('amount_total'), target_currency, company, result.get('date_invoice') or fields.Date.today())
+ amount = result.get('amount_total', 0)
+ rslt_sum += cur._convert(
+ amount, target_currency, company, result.get('date_invoice') or fields.Date.today())
return (rslt_count, rslt_sum)
@api.multi
diff --git a/addons/account/tests/test_account_customer_invoice.py b/addons/account/tests/test_account_customer_invoice.py
index 0906eae595b..8e2e825ae2b 100644
--- a/addons/account/tests/test_account_customer_invoice.py
+++ b/addons/account/tests/test_account_customer_invoice.py
@@ -1,3 +1,5 @@
+from unittest.mock import patch
+
from odoo.addons.account.tests.account_test_users import AccountTestUsers
import datetime
from odoo.tests import tagged
@@ -165,3 +167,119 @@ class TestAccountCustomerInvoice(AccountTestUsers):
))
self.assertEquals(invoice.amount_untaxed, sum([x.base for x in invoice.tax_line_ids]))
+
+ def test_customer_invoice_dashboard(self):
+ def patched_today(*args, **kwargs):
+ return '2019-01-22'
+
+ date_invoice = '2019-01-21'
+ partner3 = self.env.ref('base.res_partner_3')
+ account_id = self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id)], limit=1).id
+
+ journal = self.env['account.journal'].create({
+ 'name': 'sale_0',
+ 'code': 'SALE0',
+ 'type': 'sale',
+ })
+
+ invoice_line_data = [
+ (0, 0,
+ {
+ 'product_id': self.env.ref('product.product_product_1').id,
+ 'quantity': 40.0,
+ 'account_id': account_id,
+ 'name': 'product test 1',
+ 'discount': 10.00,
+ 'price_unit': 2.27,
+ }
+ )
+ ]
+
+ invoice = self.env['account.invoice'].create(dict(
+ name="Test Customer Invoice",
+ journal_id=journal.id,
+ partner_id=partner3.id,
+ invoice_line_ids=invoice_line_data,
+ date_invoice=date_invoice,
+ ))
+
+ refund_line_data = [
+ (0, 0,
+ {
+ 'product_id': self.env.ref('product.product_product_1').id,
+ 'quantity': 1.0,
+ 'account_id': account_id,
+ 'name': 'product test 1',
+ 'price_unit': 13.3,
+ }
+ )]
+
+ refund = self.env['account.invoice'].create(dict(
+ name="Test Customer Refund",
+ type='out_refund',
+ journal_id=journal.id,
+ partner_id=partner3.id,
+ invoice_line_ids=refund_line_data,
+ date_invoice=date_invoice,
+ ))
+
+ # Check Draft
+ dashboard_data = journal.get_journal_dashboard_datas()
+
+ self.assertEquals(dashboard_data['number_draft'], 2)
+ self.assertEquals(dashboard_data['sum_draft'], '$ 68.42')
+
+ self.assertEquals(dashboard_data['number_waiting'], 0)
+ self.assertEquals(dashboard_data['sum_waiting'], '$ 0.00')
+
+ # Check Both
+ invoice.action_invoice_open()
+
+ dashboard_data = journal.get_journal_dashboard_datas()
+ self.assertEquals(dashboard_data['number_draft'], 1)
+ self.assertEquals(dashboard_data['sum_draft'], '$ -13.30')
+
+ self.assertEquals(dashboard_data['number_waiting'], 1)
+ self.assertEquals(dashboard_data['sum_waiting'], '$ 81.72')
+
+ # Check waiting payment
+ refund.action_invoice_open()
+
+ dashboard_data = journal.get_journal_dashboard_datas()
+ self.assertEquals(dashboard_data['number_draft'], 0)
+ self.assertEquals(dashboard_data['sum_draft'], '$ 0.00')
+
+ self.assertEquals(dashboard_data['number_waiting'], 2)
+ self.assertEquals(dashboard_data['sum_waiting'], '$ 68.42')
+
+ # Check partial
+ receivable_account = refund.move_id.line_ids.mapped('account_id').filtered(lambda a: a.internal_type == 'receivable')
+ payment_move = self.env['account.move'].create({
+ 'journal_id': journal.id,
+ })
+ payment_move_line = self.env['account.move.line'].with_context(check_move_validity=False).create({
+ 'move_id': payment_move.id,
+ 'account_id': receivable_account.id,
+ 'debit': 10.00,
+ })
+ self.env['account.move.line'].with_context(check_move_validity=False).create({
+ 'move_id': payment_move.id,
+ 'account_id': self.env['account.account'].search([('user_type_id', '=', self.env.ref('account.data_account_type_liquidity').id)], limit=1).id,
+ 'credit': 10.00,
+ })
+
+ payment_move.post()
+
+ refund.register_payment(payment_move_line)
+
+ dashboard_data = journal.get_journal_dashboard_datas()
+ self.assertEquals(dashboard_data['number_draft'], 0)
+ self.assertEquals(dashboard_data['sum_draft'], '$ 0.00')
+
+ self.assertEquals(dashboard_data['number_waiting'], 2)
+ self.assertEquals(dashboard_data['sum_waiting'], '$ 78.42')
+
+ with patch('odoo.fields.Date.today', patched_today):
+ dashboard_data = journal.get_journal_dashboard_datas()
+ self.assertEquals(dashboard_data['number_late'], 2)
+ self.assertEquals(dashboard_data['sum_late'], '$ 78.42')