#This file is part of Tryton. The COPYRIGHT file at the top level of #this repository contains the full copyright notices and license terms. "Journal" from trytond.osv import fields, OSV from trytond.wizard import Wizard, WizardOSV from trytond.sql_db import table_handler STATES = { 'readonly': "state == 'close'", } _ICONS = { 'open': 'tryton-open', 'close': 'tryton-readonly', } class Type(OSV): 'Journal Type' _name = 'account.journal.type' _description = __doc__ name = fields.Char('Name', size=None, required=True, translate=True) code = fields.Char('Code', size=None, required=True) def __init__(self): super(Type, self).__init__() self._sql_constraints += [ ('code_uniq', 'UNIQUE(code)', 'Code must be unique!'), ] self._order.insert(0, ('code', 'ASC')) Type() class View(OSV): 'Journal View' _name = 'account.journal.view' _description = __doc__ name = fields.Char('Name', size=None, required=True) columns = fields.One2Many('account.journal.view.column', 'view', 'Columns') def __init__(self): super(View, self).__init__() self._order.insert(0, ('name', 'ASC')) View() class Column(OSV): 'Journal View Column' _name = 'account.journal.view.column' _description = __doc__ name = fields.Char('Name', size=None, required=True) field = fields.Many2One('ir.model.field', 'Field', required=True, domain="[('model.model', '=', 'account.move.line')]") view = fields.Many2One('account.journal.view', 'View', select=1) sequence = fields.Integer('Sequence', select=2) required = fields.Boolean('Required') readonly = fields.Boolean('Readonly') def __init__(self): super(Column, self).__init__() self._order.insert(0, ('sequence', 'ASC')) def default_required(self, cursor, user, context=None): return False def default_readonly(self, cursor, user, context=None): return False Column() class Journal(OSV): 'Journal' _name = 'account.journal' _description = __doc__ name = fields.Char('Name', size=None, required=True, translate=True) code = fields.Char('Code', size=None) active = fields.Boolean('Active', select=2) type = fields.Selection('get_types', 'Type', required=True) view = fields.Many2One('account.journal.view', 'View') centralised = fields.Boolean('Centralised counterpart') update_posted = fields.Boolean('Allow cancelling moves') sequence = fields.Property(type='many2one', relation='ir.sequence', string='Sequence', required=True, domain="[('code', '=', 'account.journal')]", context={'code': 'account.journal'}) credit_account = fields.Property(type='many2one', relation='account.account', string='Default Credit Account', domain="[('kind', '!=', 'view'), ('company', '=', company)]", states={ 'required': "centralised or " \ "(type == 'cash' and context.get('company'))", 'invisible': "not context.get('company')", }) debit_account = fields.Property(type='many2one', relation='account.account', string='Default Debit Account', domain="[('kind', '!=', 'view'), ('company', '=', company)]", states={ 'required': "centralised or " \ "(type == 'cash' and context.get('company'))", 'invisible': "not context.get('company')", }) def __init__(self): super(Journal, self).__init__() self._order.insert(0, ('name', 'ASC')) def _auto_init(self, cursor, module_name): super(Journal, self)._auto_init(cursor, module_name) table = table_handler(cursor, self._table, self._name, module_name) # Migration from 1.0 sequence Many2One change into Property if 'sequence' in table.table: property_obj = self.pool.get('ir.property') cursor.execute('SELECT id, sequence FROM "' + self._table +'"') for journal_id, sequence_id in cursor.fetchall(): property_obj.set(cursor, 0, 'sequence', self._name, journal_id, (sequence_id and \ 'ir.sequence,' + str(sequence_id) or False)) cursor.execute('ALTER TABLE "' + self._table +'" ' \ 'DROP COLUMN sequence') def default_active(self, cursor, user, context=None): return True def default_centralised(self, cursor, user, context=None): return False def default_update_posted(self, cursor, user, context=None): return False def get_types(self, cursor, user, context=None): type_obj = self.pool.get('account.journal.type') type_ids = type_obj.search(cursor, user, [], context=context) types = type_obj.browse(cursor, user, type_ids, context=context) return [(x.code, x.name) for x in types] def name_search(self, cursor, user, name='', args=None, operator='ilike', context=None, limit=None): if name: ids = self.search(cursor, user, [('code', 'like', name + '%')] + args, limit=limit, context=context) if not ids: ids = self.search(cursor, user, [(self._rec_name, operator, name)] + args, limit=limit, context=context) else: ids = self.search(cursor, user, args, limit=limit, context=context) res = self.name_get(cursor, user, ids, context=context) return res Journal() class Period(OSV): 'Journal - Period' _name = 'account.journal.period' _description = __doc__ name = fields.Char('Name', size=None, required=True) journal = fields.Many2One('account.journal', 'Journal', required=True, ondelete='CASCADE', states=STATES) period = fields.Many2One('account.period', 'Period', required=True, ondelete='CASCADE', states=STATES) icon = fields.Function('get_icon', string='Icon', type='char') active = fields.Boolean('Active', select=2, states=STATES) state = fields.Selection([ ('open', 'Open'), ('close', 'Close'), ], 'State', readonly=True, required=True) def __init__(self): super(Period, self).__init__() self._sql_constraints += [ ('journal_period_uniq', 'UNIQUE(journal, period)', 'You can only open one journal per period!'), ] self._order.insert(0, ('name', 'ASC')) self._error_messages.update({ 'modify_del_journal_period': 'You can not modify/delete ' \ 'a journal - period with moves!', 'create_journal_period': 'You can not create ' \ 'a journal - period on a closed period!', 'open_journal_period': 'You can not open ' \ 'a journal - period from a closed period!', }) def default_active(self, cursor, user, context=None): return True def default_state(self, cursor, user, context=None): return 'open' def get_icon(self, cursor, user, ids, name, arg, context=None): res = {} for period in self.browse(cursor, user, ids, context=context): res[period.id] = _ICONS.get(period.state, '') return res def _check(self, cursor, user, ids, context=None): move_obj = self.pool.get('account.move') for period in self.browse(cursor, user, ids, context=context): move_ids = move_obj.search(cursor, user, [ ('journal', '=', period.journal.id), ('period', '=', period.period.id), ], limit=1, context=context) if move_ids: self.raise_user_error(cursor, 'modify_del_journal_period', context=context) return def create(self, cursor, user, vals, context=None): period_obj = self.pool.get('account.period') if vals.get('period'): period = period_obj.browse(cursor, user, vals['period'], context=context) if period.state == 'close': self.raise_user_error(cursor, 'create_journal_period', context=context) return super(Period, self).create(cursor, user, vals, context=context) def write(self, cursor, user, ids, vals, context=None): if vals != {'state': 'close'} \ and vals != {'state': 'open'}: self._check(cursor, user, ids, context=context) if vals.get('state') == 'open': for journal_period in self.browse(cursor, user, ids, context=context): if journal_period.period.state == 'close': self.raise_user_error(cursor, 'open_journal_period', context=context) return super(Period, self).write(cursor, user, ids, vals, context=context) def delete(self, cursor, user, ids, context=None): self._check(cursor, user, ids, context=context) return super(Period, self).delete(cursor, user, ids, vals, context=context) def close(self, cursor, user, ids, context=None): ''' Close journal - period :param cursor: the database cursor :param user: the user id :param ids: the journal - period ids :param context: the context ''' self.write(cursor, user, ids, { 'state': 'close', }, context=context) Period() class ClosePeriod(Wizard): 'Close Journal - Period' _name = 'account.journal.close_period' states = { 'init': { 'actions': ['_close'], 'result': { 'type': 'state', 'state': 'end', }, }, } def _close(self, cursor, user, data, context=None): journal_period_obj = self.pool.get('account.journal.period') journal_period_obj.close(cursor, user, data['ids'], context=context) return {} ClosePeriod() class ReOpenPeriod(Wizard): 'Re-Open Journal - Period' _name = 'account.journal.reopen_period' states = { 'init': { 'actions': ['_reopen'], 'result': { 'type': 'state', 'state': 'end', }, }, } def _reopen(self, cursor, user, data, context=None): journal_period_obj = self.pool.get('account.journal.period') journal_period_obj.write(cursor, user, data['ids'], { 'state': 'open', }, context=context) return {} ReOpenPeriod()