Files
tryton/journal.py
T

309 lines
10 KiB
Python
Raw Normal View History

2014-12-02 12:54:29 +01:00
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from sql import Null
2009-02-28 16:57:10 +01:00
from trytond.model import ModelView, ModelSQL, fields
2012-01-02 17:54:33 +01:00
from trytond.wizard import Wizard, StateTransition
2013-09-06 22:33:47 +02:00
from trytond import backend
2011-08-21 11:20:29 +02:00
from trytond.pyson import Eval, Bool
2010-08-19 22:02:00 +02:00
from trytond.transaction import Transaction
2011-07-03 13:18:40 +02:00
from trytond.pool import Pool
2012-09-24 22:17:29 +02:00
__all__ = ['JournalType', 'JournalView', 'JournalViewColumn', 'Journal',
'JournalPeriod', 'CloseJournalPeriod', 'ReOpenJournalPeriod']
2008-03-17 18:32:06 +01:00
STATES = {
2011-08-21 11:20:29 +02:00
'readonly': Eval('state') == 'close',
2008-03-17 18:32:06 +01:00
}
DEPENDS = ['state']
2008-03-17 18:32:06 +01:00
_ICONS = {
2008-06-06 22:13:31 +02:00
'open': 'tryton-open',
'close': 'tryton-readonly',
2008-03-17 18:32:06 +01:00
}
2008-03-13 23:22:59 +01:00
2012-09-24 22:17:29 +02:00
class JournalType(ModelSQL, ModelView):
2008-03-13 23:22:59 +01:00
'Journal Type'
2012-09-24 22:17:29 +02:00
__name__ = 'account.journal.type'
2008-03-13 23:22:59 +01:00
name = fields.Char('Name', size=None, required=True, translate=True)
code = fields.Char('Code', size=None, required=True)
2012-09-24 22:17:29 +02:00
@classmethod
def __setup__(cls):
super(JournalType, cls).__setup__()
cls._sql_constraints += [
('code_uniq', 'UNIQUE(code)', 'The code must be unique.'),
2012-09-24 22:17:29 +02:00
]
cls._order.insert(0, ('code', 'ASC'))
2008-03-13 23:22:59 +01:00
2012-09-24 22:17:29 +02:00
class JournalView(ModelSQL, ModelView):
2008-03-13 23:22:59 +01:00
'Journal View'
2012-09-24 22:17:29 +02:00
__name__ = 'account.journal.view'
2008-03-13 23:22:59 +01:00
name = fields.Char('Name', size=None, required=True)
columns = fields.One2Many('account.journal.view.column', 'view', 'Columns')
2012-09-24 22:17:29 +02:00
@classmethod
def __setup__(cls):
super(JournalView, cls).__setup__()
cls._order.insert(0, ('name', 'ASC'))
2008-03-13 23:22:59 +01:00
2012-09-24 22:17:29 +02:00
class JournalViewColumn(ModelSQL, ModelView):
2008-03-13 23:22:59 +01:00
'Journal View Column'
2012-09-24 22:17:29 +02:00
__name__ = 'account.journal.view.column'
2008-03-13 23:22:59 +01:00
name = fields.Char('Name', size=None, required=True)
field = fields.Many2One('ir.model.field', 'Field', required=True,
2009-06-23 18:52:32 +02:00
domain=[('model.model', '=', 'account.move.line')])
2012-03-05 10:52:56 +01:00
view = fields.Many2One('account.journal.view', 'View', select=True)
2013-09-06 22:33:47 +02:00
sequence = fields.Integer('Sequence', select=True)
2008-03-13 23:22:59 +01:00
required = fields.Boolean('Required')
readonly = fields.Boolean('Readonly')
2012-09-24 22:17:29 +02:00
@classmethod
def __setup__(cls):
super(JournalViewColumn, cls).__setup__()
cls._order.insert(0, ('sequence', 'ASC'))
2008-04-22 17:47:52 +02:00
2012-09-24 22:17:29 +02:00
@classmethod
def __register__(cls, module_name):
2013-09-06 22:33:47 +02:00
TableHandler = backend.get('TableHandler')
2012-05-14 15:36:13 +02:00
cursor = Transaction().cursor
2012-09-24 22:17:29 +02:00
table = TableHandler(cursor, cls, module_name)
2012-05-14 15:36:13 +02:00
2012-09-24 22:17:29 +02:00
super(JournalViewColumn, cls).__register__(module_name)
2012-05-14 15:36:13 +02:00
# Migration from 2.4: drop required on sequence
table.not_null_action('sequence', action='remove')
2013-09-06 22:33:47 +02:00
@staticmethod
def order_sequence(tables):
table, _ = tables[None]
return [table.sequence == Null, table.sequence]
2013-09-06 22:33:47 +02:00
2012-09-24 22:17:29 +02:00
@staticmethod
def default_required():
2008-07-29 21:18:31 +02:00
return False
2012-09-24 22:17:29 +02:00
@staticmethod
def default_readonly():
2008-07-29 21:18:31 +02:00
return False
2008-03-13 23:22:59 +01:00
2009-02-28 16:57:10 +01:00
class Journal(ModelSQL, ModelView):
2008-03-13 23:22:59 +01:00
'Journal'
2012-09-24 22:17:29 +02:00
__name__ = 'account.journal'
2008-03-13 23:22:59 +01:00
name = fields.Char('Name', size=None, required=True, translate=True)
code = fields.Char('Code', size=None)
2012-03-05 10:52:56 +01:00
active = fields.Boolean('Active', select=True)
2008-03-13 23:22:59 +01:00
type = fields.Selection('get_types', 'Type', required=True)
view = fields.Many2One('account.journal.view', 'View')
update_posted = fields.Boolean('Allow cancelling moves')
2010-03-11 16:45:27 +01:00
sequence = fields.Property(fields.Many2One('ir.sequence', 'Sequence',
2011-08-21 11:20:29 +02:00
domain=[('code', '=', 'account.journal')],
context={'code': 'account.journal'},
states={
2013-10-09 18:25:04 +02:00
'required': Bool(Eval('context', {}).get('company', -1)),
2011-08-21 11:20:29 +02:00
}))
2010-03-11 16:45:27 +01:00
credit_account = fields.Property(fields.Many2One('account.account',
2011-08-21 11:20:29 +02:00
'Default Credit Account', domain=[
('kind', '!=', 'view'),
2013-10-09 18:25:04 +02:00
('company', '=', Eval('context', {}).get('company', -1)),
2011-08-21 11:20:29 +02:00
],
states={
2013-12-20 13:59:46 +01:00
'required': ((Eval('type').in_(['cash', 'write-off']))
& (Eval('context', {}).get('company', -1) != -1)),
2013-10-09 18:25:04 +02:00
'invisible': ~Eval('context', {}).get('company', -1),
2013-05-21 19:09:37 +02:00
}, depends=['type']))
2010-03-11 16:45:27 +01:00
debit_account = fields.Property(fields.Many2One('account.account',
2011-08-21 11:20:29 +02:00
'Default Debit Account', domain=[
('kind', '!=', 'view'),
2013-10-09 18:25:04 +02:00
('company', '=', Eval('context', {}).get('company', -1)),
2011-08-21 11:20:29 +02:00
],
states={
2013-12-20 13:59:46 +01:00
'required': ((Eval('type').in_(['cash', 'write-off']))
& (Eval('context', {}).get('company', -1) != -1)),
2013-10-09 18:25:04 +02:00
'invisible': ~Eval('context', {}).get('company', -1),
2013-05-21 19:09:37 +02:00
}, depends=['type']))
2008-03-13 23:22:59 +01:00
2012-09-24 22:17:29 +02:00
@classmethod
def __setup__(cls):
super(Journal, cls).__setup__()
cls._order.insert(0, ('name', 'ASC'))
2008-04-22 17:47:52 +02:00
2012-09-24 22:17:29 +02:00
@classmethod
def __register__(cls, module_name):
2013-09-06 22:33:47 +02:00
TableHandler = backend.get('TableHandler')
2012-09-24 22:17:29 +02:00
super(Journal, cls).__register__(module_name)
2010-08-19 22:02:00 +02:00
cursor = Transaction().cursor
2012-09-24 22:17:29 +02:00
table = TableHandler(cursor, cls, module_name)
2008-11-25 18:32:08 +01:00
# Migration from 1.0 sequence Many2One change into Property
2009-02-04 13:30:24 +01:00
if table.column_exist('sequence'):
2012-09-24 22:17:29 +02:00
Property = Pool().get('ir.property')
sql_table = cls.__table__()
cursor.execute(*sql_table.select(sql_table.id, sql_table.sequence))
2014-09-17 21:44:51 +02:00
for journal_id, sequence_id in cursor.fetchall():
Property.set('sequence', cls._name,
journal_id, (sequence_id and
'ir.sequence,' + str(sequence_id) or False))
2009-02-04 13:30:24 +01:00
table.drop_column('sequence', exception=True)
2012-09-24 22:17:29 +02:00
@staticmethod
def default_active():
2008-03-13 23:22:59 +01:00
return True
2012-09-24 22:17:29 +02:00
@staticmethod
def default_update_posted():
2008-12-02 20:22:29 +01:00
return False
2012-09-24 22:17:29 +02:00
@staticmethod
def default_sequence():
2012-03-27 10:43:03 +02:00
return None
2008-03-13 23:22:59 +01:00
2012-09-24 22:17:29 +02:00
@staticmethod
def get_types():
Type = Pool().get('account.journal.type')
types = Type.search([])
2008-03-13 23:22:59 +01:00
return [(x.code, x.name) for x in types]
2012-09-24 22:17:29 +02:00
@classmethod
def search_rec_name(cls, name, clause):
2014-01-31 14:06:56 +01:00
return ['OR',
('code',) + tuple(clause[1:]),
(cls._rec_name,) + tuple(clause[1:]),
]
2008-03-17 18:32:06 +01:00
2012-09-24 22:17:29 +02:00
class JournalPeriod(ModelSQL, ModelView):
2008-03-17 18:32:06 +01:00
'Journal - Period'
2012-09-24 22:17:29 +02:00
__name__ = 'account.journal.period'
2008-03-17 18:32:06 +01:00
name = fields.Char('Name', size=None, required=True)
journal = fields.Many2One('account.journal', 'Journal', required=True,
ondelete='CASCADE', states=STATES, depends=DEPENDS)
2008-03-17 18:32:06 +01:00
period = fields.Many2One('account.period', 'Period', required=True,
ondelete='CASCADE', states=STATES, depends=DEPENDS)
2010-03-11 16:45:27 +01:00
icon = fields.Function(fields.Char('Icon'), 'get_icon')
2012-03-05 10:52:56 +01:00
active = fields.Boolean('Active', select=True, states=STATES,
depends=DEPENDS)
2008-03-17 18:32:06 +01:00
state = fields.Selection([
('open', 'Open'),
('close', 'Close'),
], 'State', readonly=True, required=True)
2012-09-24 22:17:29 +02:00
@classmethod
def __setup__(cls):
super(JournalPeriod, cls).__setup__()
cls._sql_constraints += [
2008-03-17 18:32:06 +01:00
('journal_period_uniq', 'UNIQUE(journal, period)',
'You can only open one journal per period.'),
2012-09-24 22:17:29 +02:00
]
cls._order.insert(0, ('name', 'ASC'))
cls._error_messages.update({
'modify_del_journal_period': ('You can not modify/delete '
'journal - period "%s" because it has moves.'),
'create_journal_period': ('You can not create a '
'journal - period on closed period "%s".'),
'open_journal_period': ('You can not open '
'journal - period "%(journal_period)s" because period '
'"%(period)s" is closed.'),
})
2008-03-17 18:32:06 +01:00
2012-09-24 22:17:29 +02:00
@staticmethod
def default_active():
2008-03-17 18:32:06 +01:00
return True
2012-09-24 22:17:29 +02:00
@staticmethod
def default_state():
2008-03-17 18:32:06 +01:00
return 'open'
2012-09-24 22:17:29 +02:00
def get_icon(self, name):
return _ICONS.get(self.state, '')
2008-03-17 18:32:06 +01:00
2012-09-24 22:17:29 +02:00
@classmethod
def _check(cls, periods):
Move = Pool().get('account.move')
for period in periods:
moves = Move.search([
('journal', '=', period.journal.id),
('period', '=', period.period.id),
], limit=1)
if moves:
cls.raise_user_error('modify_del_journal_period', (
period.rec_name,))
2008-03-17 18:32:06 +01:00
2012-09-24 22:17:29 +02:00
@classmethod
2013-01-06 22:18:13 +01:00
def create(cls, vlist):
2012-09-24 22:17:29 +02:00
Period = Pool().get('account.period')
2013-01-06 22:18:13 +01:00
for vals in vlist:
if vals.get('period'):
period = Period(vals['period'])
if period.state == 'close':
cls.raise_user_error('create_journal_period', (
period.rec_name,))
2013-01-06 22:18:13 +01:00
return super(JournalPeriod, cls).create(vlist)
2012-09-24 22:17:29 +02:00
@classmethod
2013-12-19 14:44:33 +01:00
def write(cls, *args):
actions = iter(args)
for journal_periods, values in zip(actions, actions):
if (values != {'state': 'close'}
and values != {'state': 'open'}):
cls._check(journal_periods)
if values.get('state') == 'open':
for journal_period in journal_periods:
if journal_period.period.state == 'close':
cls.raise_user_error('open_journal_period', {
'journal_period': journal_period.rec_name,
'period': journal_period.period.rec_name,
})
super(JournalPeriod, cls).write(*args)
2008-03-17 18:32:06 +01:00
2012-09-24 22:17:29 +02:00
@classmethod
def delete(cls, periods):
cls._check(periods)
super(JournalPeriod, cls).delete(periods)
2008-03-17 18:32:06 +01:00
2012-09-24 22:17:29 +02:00
@classmethod
def close(cls, periods):
2008-09-19 15:00:26 +02:00
'''
Close journal - period
'''
2012-09-24 22:17:29 +02:00
cls.write(periods, {
'state': 'close',
})
2008-09-19 15:00:26 +02:00
2012-09-24 22:17:29 +02:00
@classmethod
def open_(cls, periods):
2012-01-02 17:54:33 +01:00
"Open journal - period"
2012-09-24 22:17:29 +02:00
cls.write(periods, {
2012-01-02 17:54:33 +01:00
'state': 'open',
})
2012-09-24 22:17:29 +02:00
class CloseJournalPeriod(Wizard):
'Close Journal - Period'
2012-09-24 22:17:29 +02:00
__name__ = 'account.journal.period.close'
2012-01-02 17:54:33 +01:00
start_state = 'close'
close = StateTransition()
2012-09-24 22:17:29 +02:00
def transition_close(self):
JournalPeriod = Pool().get('account.journal.period')
JournalPeriod.close(
JournalPeriod.browse(Transaction().context['active_ids']))
2012-01-02 17:54:33 +01:00
return 'end'
2012-09-24 22:17:29 +02:00
class ReOpenJournalPeriod(Wizard):
'Re-Open Journal - Period'
2012-09-24 22:17:29 +02:00
__name__ = 'account.journal.period.reopen'
2012-01-02 17:54:33 +01:00
start_state = 'reopen'
reopen = StateTransition()
2012-09-24 22:17:29 +02:00
def transition_reopen(self):
JournalPeriod = Pool().get('account.journal.period')
JournalPeriod.open_(
JournalPeriod.browse(Transaction().context['active_ids']))
2012-01-02 17:54:33 +01:00
return 'end'