diff --git a/account_partner_aged_statement_webkit/report/partner_aged_statement_report.py b/account_partner_aged_statement_webkit/report/partner_aged_statement_report.py
index 3d6eb68f..44058bc3 100644
--- a/account_partner_aged_statement_webkit/report/partner_aged_statement_report.py
+++ b/account_partner_aged_statement_webkit/report/partner_aged_statement_report.py
@@ -49,7 +49,7 @@ class PartnerAgedTrialReport(aged_trial_report):
'message': self._message,
'getLines30': self._lines_get_30,
'getLines3060': self._lines_get_30_60,
- 'getLines60': self._lines_get60,
+ 'getLines60': self._lines_get_60,
'show_message': True,
'get_current_invoice_lines': self._get_current_invoice_lines,
'get_balance': self._get_balance,
@@ -129,136 +129,48 @@ class PartnerAgedTrialReport(aged_trial_report):
:return: a list of dict containing invoice data
{
'date_due': the date of maturity
+ 'date_original': the date of the invoice
+ 'ref': the partner reference on the invoice
'amount_original': the original date
'amount_unreconciled': the amount left to pay
- 'currency_id': the currency of the move line
+ 'currency_id': the currency of the invoice
'currency_name': the name of the currency
- 'name': the name of the move line
+ 'name': the number of the invoice
}
"""
# Only compute this method one time per partner
if partner.id in self.partner_invoices_dict:
return self.partner_invoices_dict[partner.id]
- voucher_obj = pooler.get_pool(self.cr.dbname)['account.voucher']
- journal_obj = pooler.get_pool(self.cr.dbname)['account.journal']
- move_line_obj = pooler.get_pool(self.cr.dbname)['account.move.line']
- currency_obj = pooler.get_pool(self.cr.dbname)['res.currency']
-
- currency = company.currency_id
-
- # Get the journal with the correct currency
- journal_ids = journal_obj.search(
- self.cr, self.uid, [
- ('type', 'in', ['bank', 'cash']),
- ('currency', '=', currency.id),
- ], context=self.localcontext)
-
- if not journal_ids:
- journal_ids = journal_obj.search(
- self.cr, self.uid, [('type', 'in', ['bank', 'cash'])],
- context=self.localcontext)
-
- journal_id = journal_ids[0]
-
- # Retreive every invoice in a first time
- voucher_lines = voucher_obj.recompute_voucher_lines(
- self.cr, self.uid, ids=False, partner_id=partner.id,
- journal_id=journal_id, price=0, currency_id=currency.id,
- ttype=self.ttype, date=date, context=self.localcontext)['value']
-
- # Map the result by move line
- line_dict = {
- line['move_line_id']: line for line in
- voucher_lines['line_cr_ids'] + voucher_lines['line_dr_ids']
- }
-
- # If some of the invoices have different currency than the currency
- # of the company, need to get the lines in these currencies
- other_currencies = {}
- for move_line in move_line_obj.browse(
- self.cr, self.uid, line_dict.keys(), context=self.localcontext
- ):
- invoice = move_line.invoice
- if invoice and invoice.currency_id.id != currency.id:
- if invoice.currency_id.id in other_currencies:
- other_currencies[invoice.currency_id.id]['move_line_ids'].\
- append(move_line.id)
- else:
- # Get the journal with the correct currency
- journal_ids = journal_obj.search(
- self.cr, self.uid, [
- ('type', 'in', ['bank', 'cash']),
- ('currency', '=', invoice.currency_id.id),
- ], context=self.localcontext)
-
- if not journal_ids:
- journal_ids = journal_obj.search(
- self.cr, self.uid,
- [('type', 'in', ['bank', 'cash'])],
- context=self.localcontext)
-
- journal_id = journal_ids[0]
-
- lines_in_currency = voucher_obj.recompute_voucher_lines(
- self.cr, self.uid, ids=False, partner_id=partner.id,
- journal_id=journal_id, price=0,
- currency_id=invoice.currency_id.id,
- ttype=self.ttype, date=date,
- context=self.localcontext)['value']
-
- other_currencies[invoice.currency_id.id] = {
- 'lines_in_currency': {
- line['move_line_id']: line for line in
- lines_in_currency['line_cr_ids']
- + lines_in_currency['line_dr_ids']
- },
- 'move_line_ids': [move_line.id],
- }
-
- for currency_id in other_currencies:
- for move_line_id in other_currencies[currency_id]['move_line_ids']:
- line_dict[move_line_id] = other_currencies[currency_id][
- 'lines_in_currency'][move_line_id]
-
- for line in line_dict:
- move_line = move_line_obj.browse(
- self.cr, self.uid, line_dict[line]['move_line_id'],
- context=self.localcontext)
- line_dict[line]['ref'] = move_line.ref
-
- currency = currency_obj.browse(
- self.cr, self.uid, line_dict[line]['currency_id'],
- context=self.localcontext)
- line_dict[line]['currency_name'] = currency.name
-
- # Adjust the amount signs depending on the report type
- if self.ttype == 'receipt':
- for line in line_dict:
- if line_dict[line]['type'] == 'dr':
- line_dict[line]['amount_original'] *= -1
- line_dict[line]['amount_unreconciled'] *= -1
-
- elif self.ttype == 'payment':
- for line in line_dict:
- if line_dict[line]['type'] == 'cr':
- line_dict[line]['amount_original'] *= -1
- line_dict[line]['amount_unreconciled'] *= -1
-
- # Order the invoices by date and check for lines with no amount
- invoice_list = [
- inv for inv in
- sorted(line_dict.values(), key=lambda x: x['date_original'])
- if inv['amount_original'] or inv['amount_unreconciled']
+ pool = pooler.get_pool(self.cr.dbname)
+ cr, uid, context = self.cr, self.uid, self.localcontext
+
+ inv_obj = pool['account.invoice']
+
+ invoice_ids = inv_obj.search(cr, uid, [
+ ('state', '=', 'open'),
+ ('company_id', '=', company.id),
+ ('partner_id', '=', partner.id),
+ ('type', '=', 'out_invoice'
+ if self.ttype == 'receipt' else 'in_invoice'),
+ ], context=context)
+
+ invoices = inv_obj.browse(cr, uid, invoice_ids, context=context)
+
+ return [
+ {
+ 'date_due': inv.date_due or '',
+ 'date_original': inv.date_invoice or '',
+ 'amount_original': inv.amount_total,
+ 'amount_unreconciled': inv.residual,
+ 'currency_id': inv.currency_id.id,
+ 'currency_name': inv.currency_id.name,
+ 'name': inv.number,
+ 'ref': inv.reference or '',
+ 'id': inv.id,
+ } for inv in invoices
]
- # Order from the most recent to the older invoice.
- invoice_list.reverse()
-
- self.partner_invoices_dict[partner.id] = invoice_list
-
- return self.partner_invoices_dict[partner.id]
-
def _lines_get_30(self, partner, company):
today = self.today
stop = today - relativedelta(days=30)
@@ -289,7 +201,7 @@ class PartnerAgedTrialReport(aged_trial_report):
]
return movelines
- def _lines_get60(self, partner, company):
+ def _lines_get_60(self, partner, company):
today = self.today
start = today - relativedelta(days=60)
diff --git a/account_partner_aged_statement_webkit/tests/__init__.py b/account_partner_aged_statement_webkit/tests/__init__.py
new file mode 100644
index 00000000..4e709b0a
--- /dev/null
+++ b/account_partner_aged_statement_webkit/tests/__init__.py
@@ -0,0 +1,28 @@
+# -*- coding:utf-8 -*-
+##############################################################################
+#
+# Copyright (C) 2015 Savoir-faire Linux. All Rights Reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from . import (
+ test_aged_statement,
+)
+
+checks = [
+ test_aged_statement,
+]
diff --git a/account_partner_aged_statement_webkit/tests/test_aged_statement.py b/account_partner_aged_statement_webkit/tests/test_aged_statement.py
new file mode 100644
index 00000000..b9bd4cf6
--- /dev/null
+++ b/account_partner_aged_statement_webkit/tests/test_aged_statement.py
@@ -0,0 +1,200 @@
+# -*- coding:utf-8 -*-
+##############################################################################
+#
+# Copyright (C) 2015 Savoir-faire Linux. All Rights Reserved.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published
+# by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+
+from openerp import netsvc
+from datetime import datetime
+from openerp.tests import common
+from ..report.partner_aged_statement_report import PartnerAgedTrialReport
+from openerp.tools import DEFAULT_SERVER_DATE_FORMAT
+
+from dateutil.relativedelta import relativedelta
+
+
+class test_aged_statement(common.TransactionCase):
+
+ def create_fiscal_year(self, year):
+ cr, uid, context = self.cr, self.uid, self.context
+
+ fy_id = self.fiscal_year_model.create(cr, uid, {
+ 'name': 'Test %s' % year,
+ 'code': 'FY%s' % year,
+ 'company_id': self.company_id,
+ 'date_start': datetime(year, 1, 1),
+ 'date_stop': datetime(year, 12, 31),
+ }, context=context)
+
+ fy = self.fiscal_year_model.browse(cr, uid, fy_id, context=context)
+ fy.create_period()
+
+ def setUp(self):
+ super(test_aged_statement, self).setUp()
+ self.user_model = self.registry("res.users")
+ self.partner_model = self.registry("res.partner")
+ self.invoice_model = self.registry("account.invoice")
+ self.account_model = self.registry("account.account")
+ self.journal_model = self.registry("account.journal")
+ self.company_model = self.registry("res.company")
+ self.fiscal_year_model = self.registry("account.fiscalyear")
+
+ self.context = self.user_model.context_get(self.cr, self.uid)
+
+ cr, uid, context = self.cr, self.uid, self.context
+
+ self.company_id = self.user_model.browse(
+ cr, uid, uid, context=context).company_id.id
+
+ self.partner_id = self.partner_model.create(
+ cr, uid, {'name': 'Test', 'customer': True}, context=context)
+
+ self.account_id = self.account_model.search(
+ cr, uid, [
+ ('type', '=', 'receivable'),
+ ('currency_id', '=', False),
+ ], context=context)[0]
+
+ self.account_2_id = self.account_model.search(
+ cr, uid, [
+ ('type', '=', 'other'),
+ ('currency_id', '=', False),
+ ], context=context)[0]
+
+ self.journal_id = self.journal_model.search(
+ cr, uid, [('type', '=', 'sale')], context=context)[0]
+
+ self.today = datetime.now()
+
+ self.create_fiscal_year(self.today.year - 1)
+
+ self.date1 = self.today - relativedelta(weeks=2)
+ self.date2 = self.today - relativedelta(months=1, weeks=1)
+ self.date3 = self.today - relativedelta(months=2, weeks=1)
+ self.date4 = self.today - relativedelta(months=3, weeks=1)
+ self.date5 = self.today - relativedelta(months=4, weeks=1)
+
+ self.invoice_ids = [
+ self.invoice_model.create(
+ cr, uid, {
+ 'journal_id': self.journal_id,
+ 'account_id': self.account_id,
+ 'partner_id': self.partner_id,
+ 'date_invoice': invoice[0],
+ 'invoice_line': [(0, 0, {
+ 'name': 'Test',
+ 'account_id': self.account_2_id,
+ 'price_unit': invoice[1],
+ 'quantity': 1,
+ })],
+ }, context=context)
+ for invoice in [
+ (self.today, 300),
+ (self.date1, 100),
+ (self.date2, 150),
+ (self.date3, 200),
+ (self.date4, 250),
+ (self.date5, 500),
+ ]
+ ]
+
+ wf_service = netsvc.LocalService("workflow")
+ for inv_id in self.invoice_ids:
+ wf_service.trg_validate(
+ uid, 'account.invoice', inv_id, 'invoice_open', cr)
+
+ self.report = PartnerAgedTrialReport(
+ cr, uid, 'webkit.partner_aged_statement_report',
+ context=context)
+
+ self.partner = self.partner_model.browse(
+ cr, uid, self.partner_id, context=context)
+
+ self.company = self.company_model.browse(
+ cr, uid, self.company_id, context=context)
+
+ def test_get_balance(self):
+ balance = self.report._get_balance(self.partner, self.company)
+
+ self.assertEqual(len(balance), 1)
+ self.assertEqual(balance[0]['30'], 400)
+ self.assertEqual(balance[0]['3060'], 150)
+ self.assertEqual(balance[0]['6090'], 200)
+ self.assertEqual(balance[0]['90120'], 250)
+ self.assertEqual(balance[0]['120'], 500)
+ self.assertEqual(balance[0]['total'], 400 + 150 + 200 + 250 + 500)
+
+ def compare_vals(self, line, vals):
+ self.assertEqual(
+ line['date_original'], vals['date_original'].strftime(
+ DEFAULT_SERVER_DATE_FORMAT))
+ self.assertEqual(line['amount_original'], vals['amount_original'])
+ self.assertEqual(
+ line['amount_unreconciled'], vals['amount_unreconciled'])
+
+ def test_line_get_30(self):
+ lines = sorted(
+ self.report._lines_get_30(self.partner, self.company),
+ key=lambda l: l['date_original'])
+
+ self.compare_vals(lines[0], {
+ 'date_original': self.date1,
+ 'amount_original': 100,
+ 'amount_unreconciled': 100,
+ })
+
+ self.compare_vals(lines[1], {
+ 'date_original': self.today,
+ 'amount_original': 300,
+ 'amount_unreconciled': 300,
+ })
+
+ def test_line_get_30_60(self):
+ lines = sorted(
+ self.report._lines_get_30_60(self.partner, self.company),
+ key=lambda l: l['date_original'])
+
+ self.compare_vals(lines[0], {
+ 'date_original': self.date2,
+ 'amount_original': 150,
+ 'amount_unreconciled': 150,
+ })
+
+ def test_line_get_60(self):
+ lines = sorted(
+ self.report._lines_get_60(self.partner, self.company),
+ key=lambda l: l['date_original'])
+
+ self.compare_vals(lines[0], {
+ 'date_original': self.date5,
+ 'amount_original': 500,
+ 'amount_unreconciled': 500,
+ })
+
+ self.compare_vals(lines[1], {
+ 'date_original': self.date4,
+ 'amount_original': 250,
+ 'amount_unreconciled': 250,
+ })
+
+ self.compare_vals(lines[2], {
+ 'date_original': self.date3,
+ 'amount_original': 200,
+ 'amount_unreconciled': 200,
+ })