# -*- coding: utf-8 -*- # This file is part of the cashbook-module from m-ds for Tryton. # The COPYRIGHT file at the top level of this repository contains the # full copyright notices and license terms. from trytond.model import ModelView, ModelSQL, fields, Unique, tree, sequence_ordered from trytond.transaction import Transaction from trytond.pool import Pool from trytond.exceptions import UserError from trytond.i18n import gettext sel_categorytype = [ ('in', 'Revenue'), ('out', 'Expense'), ] class Category(tree(separator='/'), sequence_ordered(), ModelSQL, ModelView): 'Category' __name__ = 'cashbook.category' name = fields.Char(string='Name', required=True, translate=True) description = fields.Char(string='Description', translate=True) cattype = fields.Selection(string='Type', required=True, help='Type of Category', selection=sel_categorytype) account = fields.Many2One(string='Account', select=True, model_name='account.account', ondelete='RESTRICT') account_code = fields.Function(fields.Char(string='Account', readonly=True), 'on_change_with_account_code', searcher='search_account_code') company = fields.Many2One(string='Company', model_name='company.company', required=True, ondelete="RESTRICT") sequence = fields.Integer(string='Sequence', select=True) parent = fields.Many2One(string="Parent", model_name='cashbook.category', ondelete='RESTRICT', left='left', right='right') childs = fields.One2Many(string='Children', field='parent', model_name='cashbook.category') left = fields.Integer(string='Left', required=True, select=True) right = fields.Integer(string='Right', required=True, select=True) @classmethod def __setup__(cls): super(Category, cls).__setup__() cls._order.insert(0, ('name', 'ASC')) t = cls.__table__() cls._sql_constraints.extend([ ('name_uniq', Unique(t, t.name, t.company, t.parent), 'cashbook.msg_category_name_unique'), ('account_uniq', Unique(t, t.account, t.company), 'cashbook.msg_category_account_unique'), ]) @classmethod def default_cattype(cls): return 'out' @staticmethod def default_company(): return Transaction().context.get('company') or None @staticmethod def default_left(): return 0 @staticmethod def default_right(): return 0 def get_long_recname(self, recname): """ build rec_name with account-no """ Configuration = Pool().get('cashbook.configuration') l1 = [recname] if self.account: if self.account.code: cfg1 = Configuration.get_singleton() if getattr(cfg1, 'cataccno', True) == True: l1.append('[%s]' % self.account.code) return ' '.join(l1) def get_rec_name(self, name): """ short + name """ return self.get_long_recname( super(Category, self).get_rec_name(name) ) @classmethod def search_rec_name(cls, name, clause): """ search in account + name """ return ['OR', super(Category, cls).search_rec_name(name, clause), ('account.rec_name',) + tuple(clause[1:]), ('account.code',) + tuple(clause[1:]), ] @fields.depends('account') def on_change_with_account_code(self, name=None): """ get code of account """ if self.account: return self.account.code @classmethod def search_account_code(cls, names, clause): """ search in code """ return [('account.code',) + tuple(clause[1:])] @classmethod def write(cls, *args): """ parent.cattape == cattype, update sub-categories """ to_write = [] actions = iter(args) for categories, values in zip(actions, actions): if 'cattype' in values.keys(): for category in categories: if category.parent: if category.parent.cattype != values['cattype']: raise UserError(gettext( 'cashbook.msg_category_type_not_like_parent', parentname = category.parent.rec_name, catname = category.rec_name, )) cats = Category.search([('parent', 'child_of', [x.id for x in categories])]) if len(cats) > 0: to_write.extend([ cats, { 'cattype': values['cattype'], }]) super(Category, cls).write(*args) if len(to_write) > 0: print('\n## to_write:',to_write) Category.write(*to_write) # end Category