2
0

Fix flake8 tests for account_move_template

This commit is contained in:
Nicolas Bessi 2014-07-04 18:42:47 +02:00 committed by Abraham Anes
parent fb2db74256
commit 813f393626
6 changed files with 546 additions and 0 deletions

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
import account_document_template
import account_move_template
import wizard

View File

@ -0,0 +1,49 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
{
'name': "Account Move Template",
'version': '0.1',
'category': 'Generic Modules/Accounting',
'summary': "Templates for recurring Journal Entries",
'description': """
Templates for Journal Entries
User can configure journal entries templates, useful for recurring entries.
The amount of each template line can be computed (through python code) or kept as user input.
If user input, when using the template, user has to fill the amount of every input lines.
The journal entry form allows lo load, through a wizard, the template to use and the amounts to fill.
""",
'author': 'Agile Business Group',
'website': 'http://www.agilebg.com',
'license': 'AGPL-3',
'depends': ['account_accountant', 'analytic'],
'data': [
'move_template.xml',
'wizard/select_template.xml',
'security/ir.model.access.csv',
],
'test': [
'test/generate_move.yml',
],
'active': False,
'installable': True,
}

View File

@ -0,0 +1,111 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, orm
from openerp.tools.translate import _
import re
class account_document_template(orm.Model):
_computed_lines = {}
_current_template_id = 0
_cr = None
_uid = None
_name = 'account.document.template'
_columns = {
'name': fields.char('Name', size=64, required=True),
}
def _input_lines(self, cr, uid, template):
count = 0
for line in template.template_line_ids:
if line.type == 'input':
count += 1
return count
def _get_template_line(self, cr, uid, template_id, line_number):
for line in self.browse(cr, uid, template_id).template_line_ids:
if line.sequence == line_number:
return line
return False
def _generate_empty_lines(self, cr, uid, template_id):
lines = {}
for template_line in self.browse(cr, uid, template_id).template_line_ids:
lines[template_line.sequence] = None
return lines
def lines(self, line_number):
if self._computed_lines[line_number] is not None:
return self._computed_lines[line_number]
line = self._get_template_line(self._cr, self._uid, self._current_template_id, line_number)
if re.match('L\( *' + str(line_number) + ' *\)', line.python_code):
raise orm.except_orm(
_('Error'),
_('Line %s can\'t refer to itself') % str(line_number)
)
try:
self._computed_lines[line_number] = eval(line.python_code.replace('L', 'self.lines'))
except KeyError:
raise orm.except_orm(
_('Error'),
_('Code "%s" refers to non existing line') % line.python_code)
return self._computed_lines[line_number]
def compute_lines(self, cr, uid, template_id, input_lines):
# input_lines: dictionary in the form {line_number: line_amount}
# returns all the lines (included input lines) in the form {line_number: line_amount}
template = self.browse(cr, uid, template_id)
if len(input_lines) != self._input_lines(cr, uid, template):
raise orm.except_orm(
_('Error'),
_('Inconsistency between input lines and filled lines for template %s') % template.name
)
self._current_template_id = template.id
self._cr = cr
self._uid = uid
self._computed_lines = self._generate_empty_lines(cr, uid, template_id)
self._computed_lines.update(input_lines)
for line_number in self._computed_lines:
self.lines(line_number)
return self._computed_lines
def check_zero_lines(self, cr, uid, wizard):
if not wizard.line_ids:
return True
for template_line in wizard.line_ids:
if template_line.amount:
return True
return False
class account_document_template_line(orm.Model):
_name = 'account.document.template.line'
_columns = {
'name': fields.char('Name', size=64, required=True),
'sequence': fields.integer('Sequence', required=True),
'type': fields.selection([('computed', 'Computed'), ('input', 'User input')], 'Type', required=True),
'python_code': fields.text('Python Code'),
}

View File

@ -0,0 +1,89 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, orm
class account_move_template(orm.Model):
_inherit = 'account.document.template'
_name = 'account.move.template'
_columns = {
'company_id': fields.many2one('res.company', 'Company', required=True, change_default=True),
'template_line_ids': fields.one2many('account.move.template.line', 'template_id', 'Template Lines'),
'cross_journals': fields.boolean('Cross-Journals'),
'transitory_acc_id': fields.many2one('account.account', 'Transitory account', required=False),
}
_defaults = {
'company_id': lambda self, cr, uid, c: self.pool.get('res.company')._company_default_get(
cr, uid, 'account.move.template', context=c
),
}
def _check_different_journal(self, cr, uid, ids, context=None):
#Check that the journal on these lines are different/same in the case of cross journals/single journal
journal_ids = []
all_journal_ids = []
move_template = self.pool.get('account.move.template').browse(cr, uid, ids)[0]
if not move_template.template_line_ids:
return True
for template_line in move_template.template_line_ids:
all_journal_ids.append(template_line.journal_id.id)
if template_line.journal_id.id not in journal_ids:
journal_ids.append(template_line.journal_id.id)
if move_template.cross_journals:
return len(all_journal_ids) == len(journal_ids)
else:
return len(journal_ids) == 1
_constraints = [
(_check_different_journal,
'If the template is "cross-journals", the Journals must be different,'
'if the template does not "cross-journals" the Journals must be the same!',
['journal_id'])
]
class account_move_template_line(orm.Model):
_name = 'account.move.template.line'
_inherit = 'account.document.template.line'
_columns = {
'journal_id': fields.many2one('account.journal', 'Journal', required=True),
'account_id': fields.many2one('account.account', 'Account',
required=True, ondelete="cascade"),
'move_line_type': fields.selection(
[('cr', 'Credit'),
('dr', 'Debit')],
'Move Line Type',
required=True
),
'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account', ondelete="cascade"),
'template_id': fields.many2one('account.move.template', 'Template'),
'account_tax_id': fields.many2one('account.tax', 'Tax'),
}
_sql_constraints = [
('sequence_template_uniq', 'unique (template_id,sequence)',
'The sequence of the line must be unique per template !')
]

View File

@ -0,0 +1,21 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
import select_template

View File

@ -0,0 +1,253 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (C) 2011 Agile Business Group sagl (<http://www.agilebg.com>)
# Copyright (C) 2011 Domsense srl (<http://www.domsense.com>)
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
from openerp.osv import fields, orm
import time
from openerp.tools.translate import _
class wizard_select_template(orm.TransientModel):
_name = "wizard.select.move.template"
_columns = {
'template_id': fields.many2one(
'account.move.template',
'Move Template',
required=True
),
'partner_id': fields.many2one('res.partner', 'Partner'),
'line_ids': fields.one2many(
'wizard.select.move.template.line',
'template_id',
'Lines'
),
'state': fields.selection(
[
('template_selected', 'Template selected'),
],
'State'
),
}
def on_change_template_id(self, cr, uid, ids, template_id):
res = {}
if template_id:
res['value'] = {'line_ids': []}
template_pool = self.pool.get('account.move.template')
template = template_pool.browse(cr, uid, template_id)
for line in template.template_line_ids:
if line.type == 'input':
res['value']['line_ids'].append({
'sequence': line.sequence,
'name': line.name,
'account_id': line.account_id.id,
'move_line_type': line.move_line_type,
})
return res
def load_lines(self, cr, uid, ids, context=None):
wizard = self.browse(cr, uid, ids, context=context)[0]
template_pool = self.pool.get('account.move.template')
wizard_line_pool = self.pool.get('wizard.select.move.template.line')
model_data_obj = self.pool.get('ir.model.data')
template = template_pool.browse(cr, uid, wizard.template_id.id)
for line in template.template_line_ids:
if line.type == 'input':
wizard_line_pool.create(cr, uid, {
'template_id': wizard.id,
'sequence': line.sequence,
'name': line.name,
'amount': 0.0,
'account_id': line.account_id.id,
'move_line_type': line.move_line_type,
})
if not wizard.line_ids:
return self.load_template(cr, uid, ids)
wizard.write({'state': 'template_selected'})
view_rec = model_data_obj.get_object_reference(cr, uid, 'account_move_template', 'wizard_select_template')
view_id = view_rec and view_rec[1] or False
return {
'view_type': 'form',
'view_id': [view_id],
'view_mode': 'form',
'res_model': 'wizard.select.move.template',
'res_id': wizard.id,
'type': 'ir.actions.act_window',
'target': 'new',
'context': context,
}
def load_template(self, cr, uid, ids, context=None):
template_obj = self.pool.get('account.move.template')
account_period_obj = self.pool.get('account.period')
wizard = self.browse(cr, uid, ids, context=context)[0]
if not template_obj.check_zero_lines(cr, uid, wizard):
raise orm.except_orm(_('Error !'), _('At least one amount has to be non-zero!'))
input_lines = {}
for template_line in wizard.line_ids:
input_lines[template_line.sequence] = template_line.amount
period_id = account_period_obj.find(cr, uid, context=context)
if not period_id:
raise orm.except_orm(_('No period found !'), _('Unable to find a valid period !'))
period_id = period_id[0]
computed_lines = template_obj.compute_lines(cr, uid, wizard.template_id.id, input_lines)
moves = {}
for line in wizard.template_id.template_line_ids:
if line.journal_id.id not in moves:
moves[line.journal_id.id] = self._make_move(
cr, uid,
wizard.template_id.name,
period_id,
line.journal_id.id,
wizard.partner_id.id
)
self._make_move_line(
cr, uid,
line,
computed_lines,
moves[line.journal_id.id],
period_id,
wizard.partner_id.id
)
if wizard.template_id.cross_journals:
trans_account_id = wizard.template_id.transitory_acc_id.id
self._make_transitory_move_line(
cr,
uid,
line,
computed_lines,
moves[line.journal_id.id],
period_id,
trans_account_id,
wizard.partner_id.id
)
return {
'domain': "[('id','in', " + str(moves.values()) + ")]",
'name': 'Entries',
'view_type': 'form',
'view_mode': 'tree,form',
'res_model': 'account.move',
'type': 'ir.actions.act_window',
'target': 'current',
}
def _make_move(self, cr, uid, ref, period_id, journal_id, partner_id):
account_move_obj = self.pool.get('account.move')
move_id = account_move_obj.create(cr, uid, {
'ref': ref,
'period_id': period_id,
'journal_id': journal_id,
'partner_id': partner_id,
})
return move_id
def _make_move_line(self, cr, uid, line, computed_lines, move_id, period_id, partner_id):
account_move_line_obj = self.pool.get('account.move.line')
analytic_account_id = False
if line.analytic_account_id:
if not line.journal_id.analytic_journal_id:
raise orm.except_orm(
_('No Analytic Journal !'),
_("You have to dfine an analytic journal on the '%s' journal!")
% (line.journal_id.name,)
)
analytic_account_id = line.analytic_account_id.id
val = {
'name': line.name,
'move_id': move_id,
'journal_id': line.journal_id.id,
'period_id': period_id,
'analytic_account_id': analytic_account_id,
'account_id': line.account_id.id,
'date': time.strftime('%Y-%m-%d'),
'account_tax_id': line.account_tax_id.id,
'credit': 0.0,
'debit': 0.0,
'partner_id': partner_id,
}
if line.move_line_type == 'cr':
val['credit'] = computed_lines[line.sequence]
if line.move_line_type == 'dr':
val['debit'] = computed_lines[line.sequence]
id_line = account_move_line_obj.create(cr, uid, val)
return id_line
def _make_transitory_move_line(self, cr, uid, line,
computed_lines, move_id, period_id,
trans_account_id, partner_id):
account_move_line_obj = self.pool.get('account.move.line')
analytic_account_id = False
if line.analytic_account_id:
if not line.journal_id.analytic_journal_id:
raise orm.except_orm(
_('No Analytic Journal !'),
_("You have to define an analytic journal on the '%s' journal!")
% (line.template_id.journal_id.name,)
)
analytic_account_id = line.analytic_account_id.id
val = {
'name': 'transitory',
'move_id': move_id,
'journal_id': line.journal_id.id,
'period_id': period_id,
'analytic_account_id': analytic_account_id,
'account_id': trans_account_id,
'date': time.strftime('%Y-%m-%d'),
'partner_id': partner_id,
}
if line.move_line_type != 'cr':
val['credit'] = computed_lines[line.sequence]
if line.move_line_type != 'dr':
val['debit'] = computed_lines[line.sequence]
id_line = account_move_line_obj.create(cr, uid, val)
return id_line
class wizard_select_template_line(orm.TransientModel):
_description = 'Template Lines'
_name = "wizard.select.move.template.line"
_columns = {
'template_id': fields.many2one('wizard.select.move.template', 'Template'),
'sequence': fields.integer('Number', required=True),
'name': fields.char('Name', size=64, required=True, readonly=True),
'account_id': fields.many2one('account.account', 'Account', required=True, readonly=True),
'move_line_type': fields.selection(
[('cr', 'Credit'),
('dr', 'Debit')],
'Move Line Type',
required=True,
readonly=True
),
'amount': fields.float('Amount', required=True),
}