summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGoffin Simon <sig@odoo.com>2016-09-05 14:55:01 +0200
committerqdp-odoo <qdp@odoo.com>2016-09-05 14:56:53 +0200
commite424a9a938749d26adfa4eb4fca830a7c7f8944e (patch)
treed45980a54a116a1fa74392877af8c8df2f3cb81b
parentea8d52a4600b74cb97c6dc3da340af5843291653 (diff)
[FIX] account_tax_cash_basis: backport 39d68ac. opw:683625
-rw-r--r--addons/account_tax_exigible/__init__.py46
-rw-r--r--addons/account_tax_exigible/__openerp__.py17
-rw-r--r--addons/account_tax_exigible/models/__init__.py1
-rw-r--r--addons/account_tax_exigible/models/account_move.py103
4 files changed, 167 insertions, 0 deletions
diff --git a/addons/account_tax_exigible/__init__.py b/addons/account_tax_exigible/__init__.py
new file mode 100644
index 00000000000..18647072982
--- /dev/null
+++ b/addons/account_tax_exigible/__init__.py
@@ -0,0 +1,46 @@
+import models
+
+from openerp import SUPERUSER_ID
+
+def _migration_script(cr, registry):
+ #1. set the tax_exigible at True on all account.move lines not related to a tax in cash basis
+ cr.execute('''UPDATE account_move_line SET tax_exigible='t' ''')
+
+ cr.execute('''SELECT id FROM account_tax WHERE use_cash_basis = 't' ''')
+ tax_ids = tuple([x[0] for x in cr.fetchall()])
+ if tax_ids:
+ cr.execute('''UPDATE account_move_line SET tax_exigible='f' WHERE id IN (SELECT id FROM account_move_line WHERE tax_line_id IN %s OR id IN (SELECT account_move_line_id FROM account_move_line_account_tax_rel WHERE account_tax_id IN %s))''', (tax_ids, tax_ids))
+
+ #2. Fix the moves already created by the tax case based feature
+ # create account.move.lines for tax_line_id and tax_ids that weren't correctly set/created at the time of reconciliation
+ existing_move = registry['account.move'].search(cr, SUPERUSER_ID, [('tax_cash_basis_rec_id', '!=', False)])
+ for m in registry['account.move'].browse(cr, SUPERUSER_ID, existing_move):
+ partial_rec = m.tax_cash_basis_rec_id
+ for move in (partial_rec.debit_move_id.move_id, partial_rec.credit_move_id.move_id):
+ matched_percentage = partial_rec.amount and (partial_rec.amount / move.amount) or 0.0
+ for l in move.line_ids:
+ if l.tax_exigible:
+ continue
+
+ move_to_fix = registry['account.move'].search(cr, SUPERUSER_ID, [('tax_cash_basis_rec_id', '=', partial_rec.id)])[0]
+ amount = (l.debit - l.credit) * matched_percentage
+
+ registry['account.move.line'].create(cr, SUPERUSER_ID, {
+ 'name': '/',
+ 'debit': amount > 0 and amount or 0.0,
+ 'credit': amount < 0 and -amount or 0.0,
+ 'account_id': l.account_id.id,
+ 'tax_line_id': l.tax_line_id and l.tax_line_id.id or False,
+ 'tax_ids': l.tax_ids and [(6, 0, l.tax_ids.ids)] or [],
+ 'tax_exigible': True,
+ 'move_id': move_to_fix,
+ }, apply_taxes=False, context={'check_move_validity': False})
+ registry['account.move.line'].create(cr, SUPERUSER_ID, {
+ 'name': '/',
+ 'debit': -amount > 0 and -amount or 0.0,
+ 'credit': -amount < 0 and amount or 0.0,
+ 'account_id': l.account_id.id,
+ 'move_id': move_to_fix,
+ 'tax_exigible': True,
+ }, context={'check_move_validity': False})
+ return
diff --git a/addons/account_tax_exigible/__openerp__.py b/addons/account_tax_exigible/__openerp__.py
new file mode 100644
index 00000000000..11244bd9aa7
--- /dev/null
+++ b/addons/account_tax_exigible/__openerp__.py
@@ -0,0 +1,17 @@
+# -*- encoding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+{
+ 'name': 'Tax exigible',
+ 'version': '1.0',
+ 'category': 'Accounting',
+ 'description': """
+ This is a bugfix-module backporting 39d68ac and adding the concept of tax exigibility on journal items.
+ """,
+ 'depends': ['account_tax_cash_basis'],
+ 'data': [],
+ 'test': [],
+ 'demo': [],
+ 'auto_install': True,
+ 'installable': True,
+ 'post_init_hook': '_migration_script',
+}
diff --git a/addons/account_tax_exigible/models/__init__.py b/addons/account_tax_exigible/models/__init__.py
new file mode 100644
index 00000000000..00c67c4c228
--- /dev/null
+++ b/addons/account_tax_exigible/models/__init__.py
@@ -0,0 +1 @@
+import account_move \ No newline at end of file
diff --git a/addons/account_tax_exigible/models/account_move.py b/addons/account_tax_exigible/models/account_move.py
new file mode 100644
index 00000000000..d0954d38ff1
--- /dev/null
+++ b/addons/account_tax_exigible/models/account_move.py
@@ -0,0 +1,103 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from openerp import fields, models, api, _
+from openerp.exceptions import UserError
+
+
+class AccountMoveLine(models.Model):
+ _inherit = "account.move.line"
+ tax_exigible = fields.Boolean(string='Appears in VAT report', default=True,
+ help="Technical field used to mark a tax line as exigible in the vat report or not (only exigible journal items are displayed). By default all new journal items are directly exigible, but with the module account_tax_cash_basis, some will become exigible only when the payment is recorded.")
+
+ @api.model
+ def create(self, vals, apply_taxes=True):
+ taxes = False
+ if vals.get('tax_line_id'):
+ taxes = [{'use_cash_basis': self.env['account.tax'].browse(vals['tax_line_id']).use_cash_basis}]
+ if vals.get('tax_ids'):
+ taxes = self.env['account.move.line'].resolve_2many_commands('tax_ids', vals['tax_ids'])
+ if taxes and any([tax['use_cash_basis'] for tax in taxes]) and not vals.get('tax_exigible'):
+ vals['tax_exigible'] = False
+ return super(AccountMoveLine, self).create(vals, apply_taxes=apply_taxes)
+
+class AccountPartialReconcileCashBasis(models.Model):
+ _inherit = 'account.partial.reconcile'
+
+ def create_tax_cash_basis_entry(self, value_before_reconciliation):
+ # Search in account_move if we have any taxes account move lines
+ tax_group = {}
+ total_by_cash_basis_account = {}
+ line_to_create = []
+ for move in (self.debit_move_id.move_id, self.credit_move_id.move_id):
+ for line in move.line_ids:
+ #TOCHECK: normal and cash basis taxes shoudn't be mixed together (on the same invoice line for example) as it will
+ #create reporting issues. Not sure of the behavior to implement in that case, though.
+ if not line.tax_exigible:
+ # amount to write is the current cash_basis amount minus the one before the reconciliation
+ matched_percentage = value_before_reconciliation[move.id]
+ amount = (line.credit_cash_basis - line.debit_cash_basis) - (line.credit - line.debit) * matched_percentage
+ if line.tax_line_id and line.tax_line_id.use_cash_basis:
+ # group by line account
+ acc = line.account_id.id
+ if tax_group.get(acc, False):
+ tax_group[acc] += amount
+ else:
+ tax_group[acc] = amount
+ # Group by cash basis account and tax
+ acc = line.tax_line_id.cash_basis_account.id
+ key = (acc, line.tax_line_id.id)
+ if key in total_by_cash_basis_account:
+ total_by_cash_basis_account[key] += amount
+ else:
+ total_by_cash_basis_account[key] = amount
+ for tax in line.tax_ids:
+ if tax.use_cash_basis:
+ line_to_create.append((0, 0, {
+ 'name': '/',
+ 'debit': line.debit_cash_basis - line.debit * matched_percentage,
+ 'credit': line.credit_cash_basis - line.credit * matched_percentage,
+ 'account_id': line.account_id.id,
+ 'tax_ids': [(6, 0, [tax.id])],
+ 'tax_exigible': True,
+ }))
+ line_to_create.append((0, 0, {
+ 'name': '/',
+ 'credit': line.debit_cash_basis - line.debit * matched_percentage,
+ 'debit': line.credit_cash_basis - line.credit * matched_percentage,
+ 'account_id': line.account_id.id,
+ }))
+
+ for k, v in tax_group.items():
+ line_to_create.append((0, 0, {
+ 'name': '/',
+ 'debit': v if v > 0 else 0.0,
+ 'credit': abs(v) if v < 0 else 0.0,
+ 'account_id': k,
+ }))
+
+ # Create counterpart vals
+ for key, v in total_by_cash_basis_account.items():
+ k, tax_id = key
+ line_to_create.append((0, 0, {
+ 'name': '/',
+ 'debit': abs(v) if v < 0 else 0.0,
+ 'credit': v if v > 0 else 0.0,
+ 'account_id': k,
+ 'tax_line_id': tax_id,
+ 'tax_exigible': True,
+ }))
+
+ # Create move
+ if len(line_to_create) > 0:
+ # Check if company_journal for cash basis is set if not, raise exception
+ if not self.company_id.tax_cash_basis_journal_id:
+ raise UserError(_('There is no tax cash basis journal defined ' \
+ 'for this company: "%s" \nConfigure it in Accounting/Configuration/Settings') % \
+ (self.company_id.name))
+ move = self.env['account.move'].with_context(dont_create_taxes=True).create({
+ 'journal_id': self.company_id.tax_cash_basis_journal_id.id,
+ 'line_ids': line_to_create,
+ 'tax_cash_basis_rec_id': self.id})
+ # post move
+ move.post()