Skip to content

Commit

Permalink
[FIXUP] Add tests and simplify object methods
Browse files Browse the repository at this point in the history
  • Loading branch information
p-tombez committed Jan 31, 2018
1 parent e129503 commit bcde952
Show file tree
Hide file tree
Showing 7 changed files with 215 additions and 50 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ Available addons
----------------
addon | version | summary
--- | --- | ---
[account_analytic_default_account](account_analytic_default_account/) | 10.0.1.0.0 | Add default analytic account for accounts
[account_analytic_distribution](account_analytic_distribution/) | 10.0.1.0.0 | Distribute incoming/outcoming account moves to several analytic accounts
[account_analytic_distribution_required](account_analytic_distribution_required/) | 10.0.1.0.0 | Account Analytic Distribution Required
[account_analytic_no_lines](account_analytic_no_lines/) | 10.0.1.0.0 | Hide analytics lines and disable their generation from a move line.
Expand Down
3 changes: 1 addition & 2 deletions account_analytic_default_account/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ accounts.
Configuration
=============

For example, if you want to have an analytic account whenever you use
a given account, then go to *Accounting -> Configuration -> Analytic Defaults*
Go to *Accounting -> Configuration -> Analytic Defaults*
and set the corresponding settings.

Usage
Expand Down
10 changes: 8 additions & 2 deletions account_analytic_default_account/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,13 @@
'license': 'AGPL-3',
'author': "Odoo Community Association (OCA)",
'website': 'https://github.com/OCA/account-analytic',
'depends': ['account_analytic_default'],
'data': ['views/account_analytic_default_account_view.xml'],
'depends': [
'account',
'analytic',
'account_analytic_default'
],
'data': [
'views/account_analytic_default_account_view.xml'
],
'installable': True,
}
3 changes: 3 additions & 0 deletions account_analytic_default_account/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import account_analytic_default_account
Original file line number Diff line number Diff line change
Expand Up @@ -11,78 +11,93 @@ class AccountAnalyticDefaultAccount(models.Model):
account_id = fields.Many2one(
'account.account', string='Account',
ondelete='cascade',
help="Select an account which will use analytic account specified in "
"analytic default (e.g. create new customer invoice or "
"Sales order if we select this product, "
"it will automatically take this as an analytic account)"
help="Select the account corresponding to an analytic account "
"which will be used on the lines of invoices or account moves"
)

@api.model
def account_get(self, product_id=None, partner_id=None, user_id=None,
date=None, company_id=None, account_id=None):
def _account_get_domain_keys(self):
"""Returns a set of original account_get arg names - self + new ones"""
func = super(AccountAnalyticDefaultAccount, self).account_get
return (
list(func.func_code.co_varnames[1:func.func_code.co_argcount]) +
['account_id']
)

def _account_get_domain(self, **kw):
"""Build account.analytic.default domain.
:param kw: filter keys.
Available filter keys are defined into `account_get_domain_keys`.
:return: a search domain with all required keys' leaves.
Each key will be searched for both False and specified value.
For instance: [
('product_id'), '=', False), '|', [('product_id'), '=', 100)
]
"""
domain = []
if product_id:
domain += ['|', ('product_id', '=', product_id)]
domain += [('product_id', '=', False)]
if partner_id:
domain += ['|', ('partner_id', '=', partner_id)]
domain += [('partner_id', '=', False)]
if company_id:
domain += ['|', ('company_id', '=', company_id)]
domain += [('company_id', '=', False)]
if user_id:
domain += ['|', ('user_id', '=', user_id)]
domain += [('user_id', '=', False)]
if account_id:
domain += ['|', ('account_id', '=', account_id)]
domain += [('account_id', '=', False)]
if date:
domain += ['|', ('date_start', '<=', date),
account_get_domain_keys = self._account_get_domain_keys()[:]
# date will be handled differently
account_get_domain_keys.remove('date')

for key in account_get_domain_keys:
if kw.get(key):
domain += ['|', (key, '=', kw.get(key))]
domain += [(key, '=', False)]

date_val = kw.get('date')
if date_val:
domain += ['|', ('date_start', '<=', date_val),
('date_start', '=', False)]
domain += ['|', ('date_stop', '>=', date),
domain += ['|', ('date_stop', '>=', date_val),
('date_stop', '=', False)]
return domain

def _account_get(self, **kw):
domain = self._account_get_domain(**kw)
keys = kw.keys()
if 'date' in keys:
keys.remove('date')
keys += ['date_start', 'date_stop']
best_index = -1
res = self.env['account.analytic.default']
for rec in self.search(domain):
index = 0
if rec.product_id:
index += 1
if rec.partner_id:
index += 1
if rec.company_id:
index += 1
if rec.user_id:
index += 1
if rec.account_id:
index += 1
if rec.date_start:
index += 1
if rec.date_stop:
index += 1
for k in keys:
if rec[k]:
index += 1
if index > best_index:
res = rec
best_index = index
return res

@api.model
def account_get(self, *args, **kwargs):
"""Wrapper method to convert *args to **kwargs"""
kwargs.update(zip(self._account_get_domain_keys(), args))
return self._account_get(**kwargs)


class AccountInvoiceLine(models.Model):
_inherit = "account.invoice.line"

@api.onchange('product_id')
@api.onchange('product_id', 'account_id')
def _onchange_product_id(self):
res = super(AccountInvoiceLine, self)._onchange_product_id()
rec = self.env['account.analytic.default'].account_get(
self.product_id.id, self.invoice_id.partner_id.id, self.env.uid,
fields.Date.today(), company_id=self.company_id.id,
account_id=self.account_id.id)
product_id=self.product_id.id,
partner_id=self.invoice_id.partner_id.id,
user_id=self.env.uid, date=fields.Date.today(),
company_id=self.company_id.id, account_id=self.account_id.id
)
self.account_analytic_id = rec.analytic_id.id
return res

def _set_additional_fields(self, invoice):
if not self.account_analytic_id:
rec = self.env['account.analytic.default'].account_get(
self.product_id.id, self.invoice_id.partner_id.id,
self.env.uid, fields.Date.today(),
product_id=self.product_id.id,
partner_id=self.invoice_id.partner_id.id,
user_id=self.env.uid, date=fields.Date.today(),
company_id=self.company_id.id, account_id=self.account_id.id
)
if rec:
Expand Down
4 changes: 4 additions & 0 deletions account_analytic_default_account/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from . import test_analytic_default_account
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl)

from odoo.tests import common
from odoo import exceptions
import time


class TestAnalyticDefaultAccount(common.SavepointCase):

@classmethod
def setUpClass(cls):
super(TestAnalyticDefaultAccount, cls).setUpClass()

cls.account_analytic_default_model = cls.env['account.analytic.default']
cls.analytic_account_model = cls.env['account.analytic.account']
cls.invoice_model = cls.env['account.invoice']
cls.invoice_line_model = cls.env['account.invoice.line']
cls.move_obj = cls.env['account.move']
cls.move_line_obj = cls.env['account.move.line']

cls.partner_agrolait = cls.env.ref("base.res_partner_2")
cls.product = cls.env.ref("product.product_product_4")
cls.account_receivable = cls.env['account.account'].search(
[('user_type_id', '=',
cls.env.ref('account.data_account_type_receivable').id)],
limit=1
)
cls.account_sales = cls.env['account.account'].create({
'code': "X1020",
'name': "Product Sales - (test)",
'user_type_id': cls.env.ref('account.data_account_type_revenue').id
})

cls.sales_journal = cls.env['account.journal'].create({
'name': "Sales Journal - (test)",
'code': "TSAJ",
'type': "sale",
'refund_sequence': True,
'default_debit_account_id': cls.account_sales.id,
'default_credit_account_id': cls.account_sales.id,
})

cls.analytic_account_1 = cls.analytic_account_model.create(
{'name': 'test 1'})
cls.analytic_account_2 = cls.analytic_account_model.create(
{'name': 'test 2'})
cls.analytic_account_3 = cls.analytic_account_model.create(
{'name': 'test 3'})
cls.analytic_account_4 = cls.analytic_account_model.create(
{'name': 'test 4'})

cls.account_analytic_default_model.create({
'product_id': cls.product.id,
'analytic_id': cls.analytic_account_1.id
})
cls.account_analytic_default_model.create({
'partner_id': cls.partner_agrolait.id,
'analytic_id': cls.analytic_account_2.id
})
cls.account_analytic_default_model.create({
'product_id': cls.product.id,
'account_id': cls.account_sales.id,
'analytic_id': cls.analytic_account_3.id
})
cls.account_analytic_default_model.create({
'account_id': cls.account_sales.id,
'analytic_id': cls.analytic_account_4.id
})

def create_invoice(self, amount=100, type='out_invoice'):
""" Returns an open invoice """
invoice = self.invoice_model.create({
'partner_id': self.partner_agrolait.id,
'reference_type': 'none',
'name': (type == 'out_invoice' and 'invoice to client' or
'invoice to supplier'),
'account_id': self.account_receivable.id,
'type': type,
'date_invoice': time.strftime('%Y') + '-06-26',
})
self.invoice_line_model.create({
'product_id': self.product.id,
'quantity': 1,
'price_unit': amount,
'invoice_id': invoice.id,
'name': 'something',
'account_id': self.account_sales.id
})
invoice.action_invoice_open()
return invoice

def create_move(self, amount=100):
ml_obj = self.move_line_obj.with_context(check_move_validity=False)
move_vals = {
'name': '/',
'journal_id': self.sales_journal.id,
'date': time.strftime('%Y') + '-07-25',
}
move = self.move_obj.create(move_vals)
move_line_1 = ml_obj.create(
{'move_id': move.id,
'name': '/',
'debit': 0,
'credit': amount,
'account_id': self.account_sales.id})
move_line_2 = ml_obj.create(
{'move_id': move.id,
'name': '/',
'debit': amount,
'credit': 0,
'account_id': self.account_receivable.id,
})
return move, move_line_1, move_line_2

def test_account_analytic_default_get_account(self):
rec = self.account_analytic_default_model.account_get(
account_id=self.account_sales.id
)
self.assertEqual(self.analytic_account_4.id, rec.analytic_id.id)

rec = self.account_analytic_default_model.account_get(
account_id=self.account_receivable.id
)
self.assertFalse(rec.id)

def test_account_analytic_default_invoice(self):
invoice = self.create_invoice()
self.assertFalse(invoice.invoice_line_ids[0].account_analytic_id.id)
invoice.invoice_line_ids[0]._set_additional_fields(invoice)
self.assertEqual(invoice.invoice_line_ids[0].account_analytic_id,
self.analytic_account_3)

def test_account_analytic_default_account_move(self):
move, move_line_1, move_line_2 = self.create_move()
self.assertEqual(move_line_1.analytic_account_id,
self.analytic_account_4)
self.assertFalse(move_line_2.analytic_account_id.id)

0 comments on commit bcde952

Please sign in to comment.