2014-04-10 17:39:35 +02:00
|
|
|
# The COPYRIGHT file at the top level of this repository contains the full
|
|
|
|
# copyright notices and license terms.
|
|
|
|
from sql import Column
|
|
|
|
from sql.aggregate import Sum
|
|
|
|
from sql.conditionals import Coalesce
|
|
|
|
|
|
|
|
from trytond import backend
|
2015-04-13 10:31:42 +02:00
|
|
|
from trytond.model import ModelSQL, ModelView, fields
|
2014-04-10 17:39:35 +02:00
|
|
|
from trytond.pool import Pool, PoolMeta
|
2015-04-13 10:31:42 +02:00
|
|
|
from trytond.pyson import Eval, Or, PYSONEncoder
|
2014-04-10 17:39:35 +02:00
|
|
|
from trytond.transaction import Transaction
|
|
|
|
from trytond.wizard import Wizard
|
|
|
|
|
|
|
|
__all__ = ['AnalyticAccount', 'AnalyticAccountAccountRequired',
|
|
|
|
'AnalyticAccountAccountForbidden', 'AnalyticAccountAccountOptional',
|
|
|
|
'AnalyticLine', 'OpenChartAccountStart', 'OpenChartAccount']
|
|
|
|
__metaclass__ = PoolMeta
|
|
|
|
|
|
|
|
|
|
|
|
class AnalyticAccount:
|
|
|
|
__name__ = 'analytic_account.account'
|
|
|
|
|
|
|
|
analytic_required = fields.Many2Many(
|
|
|
|
'analytic_account.account-required-account.account',
|
|
|
|
'analytic_account', 'account', 'Analytic Required', domain=[
|
2014-05-08 14:21:32 +02:00
|
|
|
('kind', '!=', 'view'),
|
2014-04-10 17:39:35 +02:00
|
|
|
('id', 'not in', Eval('analytic_forbidden')),
|
|
|
|
('id', 'not in', Eval('analytic_optional')),
|
|
|
|
], states={
|
|
|
|
'invisible': Eval('type') != 'root',
|
|
|
|
}, depends=['analytic_forbidden', 'analytic_optional', 'type'])
|
|
|
|
analytic_forbidden = fields.Many2Many(
|
|
|
|
'analytic_account.account-forbidden-account.account',
|
|
|
|
'analytic_account', 'account', 'Analytic Forbidden', domain=[
|
2014-05-08 14:21:32 +02:00
|
|
|
('kind', '!=', 'view'),
|
2014-04-10 17:39:35 +02:00
|
|
|
('id', 'not in', Eval('analytic_required')),
|
|
|
|
('id', 'not in', Eval('analytic_optional')),
|
|
|
|
], states={
|
|
|
|
'invisible': Eval('type') != 'root',
|
|
|
|
}, depends=['analytic_required', 'analytic_optional', 'type'])
|
|
|
|
analytic_optional = fields.Many2Many(
|
|
|
|
'analytic_account.account-optional-account.account',
|
|
|
|
'analytic_account', 'account', 'Analytic Optional', domain=[
|
2014-05-08 14:21:32 +02:00
|
|
|
('kind', '!=', 'view'),
|
2014-04-10 17:39:35 +02:00
|
|
|
('id', 'not in', Eval('analytic_required')),
|
|
|
|
('id', 'not in', Eval('analytic_forbidden')),
|
|
|
|
], states={
|
|
|
|
'invisible': Eval('type') != 'root',
|
|
|
|
}, depends=['analytic_required', 'analytic_forbidden', 'type'])
|
|
|
|
analytic_pending_accounts = fields.Function(fields.Many2Many(
|
|
|
|
'account.account', None, None, 'Pending Accounts', states={
|
|
|
|
'invisible': Eval('type') != 'root',
|
|
|
|
},
|
2014-06-04 16:36:13 +02:00
|
|
|
depends=['type']),
|
2014-04-10 17:39:35 +02:00
|
|
|
'on_change_with_analytic_pending_accounts')
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __setup__(cls):
|
|
|
|
super(AnalyticAccount, cls).__setup__()
|
|
|
|
cls._error_messages.update({
|
|
|
|
'analytic_account_required_forbidden': (
|
|
|
|
'The next accounts are configured as Required and '
|
|
|
|
'Forbidden for the Analytic Root "%(root)s": '
|
|
|
|
'%(accounts)s.'),
|
|
|
|
'analytic_account_required_optional': (
|
|
|
|
'The next accounts are configured as Required and '
|
|
|
|
'Optional for the Analytic Root "%(root)s": '
|
|
|
|
'%(accounts)s.'),
|
|
|
|
'analytic_account_forbidden_optional': (
|
|
|
|
'The next accounts are configured as Forbidden and '
|
|
|
|
'Optional for the Analytic Root "%(root)s": '
|
|
|
|
'%(accounts)s.'),
|
|
|
|
})
|
|
|
|
|
2014-06-04 16:36:13 +02:00
|
|
|
@fields.depends('analytic_required', 'analytic_forbidden',
|
|
|
|
'analytic_optional')
|
2014-04-10 17:39:35 +02:00
|
|
|
def on_change_with_analytic_pending_accounts(self, name=None):
|
|
|
|
Account = Pool().get('account.account')
|
|
|
|
|
|
|
|
current_accounts = map(int, self.analytic_required)
|
|
|
|
current_accounts += map(int, self.analytic_forbidden)
|
|
|
|
current_accounts += map(int, self.analytic_optional)
|
|
|
|
pending_accounts = Account.search([
|
2014-05-08 14:21:32 +02:00
|
|
|
('kind', '!=', 'view'),
|
2014-04-10 17:39:35 +02:00
|
|
|
('id', 'not in', current_accounts),
|
|
|
|
])
|
|
|
|
return map(int, pending_accounts)
|
|
|
|
|
|
|
|
@classmethod
|
2015-02-10 10:54:29 +01:00
|
|
|
def query_get(cls, ids, names):
|
2014-04-10 17:39:35 +02:00
|
|
|
pool = Pool()
|
|
|
|
Line = pool.get('analytic_account.line')
|
2015-04-13 10:31:42 +02:00
|
|
|
Company = pool.get('company.company')
|
2014-04-10 17:39:35 +02:00
|
|
|
table = cls.__table__()
|
|
|
|
line = Line.__table__()
|
2015-04-13 10:31:42 +02:00
|
|
|
company = Company.__table__()
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
line_query = Line.query_get(line)
|
2015-02-10 10:54:29 +01:00
|
|
|
|
2015-04-13 10:31:42 +02:00
|
|
|
columns = [table.id, company.currency]
|
2015-02-10 10:54:29 +01:00
|
|
|
for name in names:
|
|
|
|
if name == 'balance':
|
|
|
|
columns.append(
|
|
|
|
Sum(Coalesce(line.debit, 0) - Coalesce(line.credit, 0)))
|
|
|
|
else:
|
|
|
|
columns.append(Sum(Coalesce(Column(line, name), 0)))
|
|
|
|
query = table.join(line, 'LEFT',
|
|
|
|
condition=table.id == line.account
|
2015-04-13 10:31:42 +02:00
|
|
|
).join(company, 'LEFT',
|
|
|
|
condition=company.id == line.internal_company
|
2015-02-10 10:54:29 +01:00
|
|
|
).select(*columns,
|
|
|
|
where=(table.type != 'view')
|
|
|
|
& table.id.in_(ids)
|
|
|
|
& table.active & line_query,
|
2015-04-13 10:31:42 +02:00
|
|
|
group_by=(table.id, company.currency))
|
2015-02-10 10:54:29 +01:00
|
|
|
return query
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def validate(cls, accounts):
|
|
|
|
super(AnalyticAccount, cls).validate(accounts)
|
|
|
|
for account in accounts:
|
|
|
|
account.check_analytic_accounts()
|
|
|
|
|
|
|
|
def check_analytic_accounts(self):
|
|
|
|
required = set(self.analytic_required)
|
|
|
|
forbidden = set(self.analytic_forbidden)
|
|
|
|
optional = set(self.analytic_optional)
|
|
|
|
if required & forbidden:
|
|
|
|
self.raise_user_error('analytic_account_required_forbidden', {
|
|
|
|
'root': self.rec_name,
|
|
|
|
'accounts': ', '.join([a.rec_name
|
|
|
|
for a in (required & forbidden)])
|
|
|
|
})
|
|
|
|
if required & optional:
|
|
|
|
self.raise_user_error('analytic_account_required_optional', {
|
|
|
|
'root': self.rec_name,
|
|
|
|
'accounts': ', '.join([a.rec_name
|
|
|
|
for a in (required & optional)])
|
|
|
|
})
|
|
|
|
if forbidden & optional:
|
|
|
|
self.raise_user_error('analytic_account_forbidden_optional', {
|
|
|
|
'root': self.rec_name,
|
|
|
|
'accounts': ', '.join([a.rec_name
|
|
|
|
for a in (forbidden & optional)])
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
|
class AnalyticAccountAccountRequired(ModelSQL):
|
|
|
|
'Analytic Account - Account - Required'
|
|
|
|
__name__ = 'analytic_account.account-required-account.account'
|
2016-07-05 15:25:59 +02:00
|
|
|
_table = 'analytic_acc_acc_required_acc_acc'
|
2014-04-10 17:39:35 +02:00
|
|
|
analytic_account = fields.Many2One('analytic_account.account',
|
|
|
|
'Analytic Account', ondelete='CASCADE', required=True, select=True,
|
|
|
|
domain=[('type', '=', 'root')])
|
|
|
|
account = fields.Many2One('account.account', 'Account',
|
|
|
|
ondelete='CASCADE', required=True, select=True)
|
|
|
|
|
2016-07-05 15:25:59 +02:00
|
|
|
@classmethod
|
|
|
|
def __register__(cls, module_name):
|
|
|
|
TableHandler = backend.get('TableHandler')
|
|
|
|
# Migration from 3.4: rename table
|
|
|
|
old_table = 'analytic_account_account-required-account_account'
|
|
|
|
new_table = 'analytic_acc_acc_required_acc_acc'
|
|
|
|
if TableHandler.table_exist(old_table):
|
|
|
|
TableHandler.table_rename(old_table, new_table)
|
2016-07-05 15:28:28 +02:00
|
|
|
super(AnalyticAccountAccountRequired, cls).__register__(
|
2016-07-05 15:25:59 +02:00
|
|
|
module_name)
|
|
|
|
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
class AnalyticAccountAccountForbidden(ModelSQL):
|
|
|
|
'Analytic Account - Account - Forbidden'
|
|
|
|
__name__ = 'analytic_account.account-forbidden-account.account'
|
2016-07-05 15:25:59 +02:00
|
|
|
_table = 'analytic_acc_acc_forbidden_acc_acc'
|
2014-04-10 17:39:35 +02:00
|
|
|
analytic_account = fields.Many2One('analytic_account.account',
|
|
|
|
'Analytic Account', ondelete='CASCADE', required=True, select=True,
|
|
|
|
domain=[('type', '=', 'root')])
|
|
|
|
account = fields.Many2One('account.account', 'Account',
|
|
|
|
ondelete='CASCADE', required=True, select=True)
|
|
|
|
|
2016-07-05 15:25:59 +02:00
|
|
|
@classmethod
|
|
|
|
def __register__(cls, module_name):
|
|
|
|
TableHandler = backend.get('TableHandler')
|
|
|
|
# Migration from 3.4: rename table
|
|
|
|
old_table = 'analytic_account_account-forbidden-account_account'
|
|
|
|
new_table = 'analytic_acc_acc_forbidden_acc_acc'
|
|
|
|
if TableHandler.table_exist(old_table):
|
|
|
|
TableHandler.table_rename(old_table, new_table)
|
2016-07-05 15:28:28 +02:00
|
|
|
super(AnalyticAccountAccountForbidden, cls).__register__(
|
2016-07-05 15:25:59 +02:00
|
|
|
module_name)
|
|
|
|
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
class AnalyticAccountAccountOptional(ModelSQL):
|
|
|
|
'Analytic Account - Account - Optional'
|
|
|
|
__name__ = 'analytic_account.account-optional-account.account'
|
2016-07-05 15:25:59 +02:00
|
|
|
_table = 'analytic_acc_acc_optional_acc_acc'
|
2014-04-10 17:39:35 +02:00
|
|
|
analytic_account = fields.Many2One('analytic_account.account',
|
|
|
|
'Analytic Account', ondelete='CASCADE', required=True, select=True,
|
|
|
|
domain=[('type', '=', 'root')])
|
|
|
|
account = fields.Many2One('account.account', 'Account',
|
|
|
|
ondelete='CASCADE', required=True, select=True)
|
|
|
|
|
2016-07-05 15:25:59 +02:00
|
|
|
@classmethod
|
|
|
|
def __register__(cls, module_name):
|
|
|
|
TableHandler = backend.get('TableHandler')
|
|
|
|
# Migration from 3.4: rename table
|
|
|
|
old_table = 'analytic_account_account-optional-account_account'
|
|
|
|
new_table = 'analytic_acc_acc_optional_acc_acc'
|
|
|
|
if TableHandler.table_exist(old_table):
|
|
|
|
TableHandler.table_rename(old_table, new_table)
|
2016-07-05 15:28:28 +02:00
|
|
|
super(AnalyticAccountAccountOptional, cls).__register__(
|
2016-07-05 15:25:59 +02:00
|
|
|
module_name)
|
|
|
|
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
_STATES = {
|
|
|
|
'readonly': Eval('state') != 'draft',
|
|
|
|
}
|
|
|
|
_DEPENDS = ['state']
|
|
|
|
|
|
|
|
|
|
|
|
class AnalyticLine:
|
|
|
|
__name__ = 'analytic_account.line'
|
|
|
|
|
2015-04-13 10:31:42 +02:00
|
|
|
internal_company = fields.Many2One('company.company', 'Company',
|
|
|
|
required=True, states=_STATES, depends=_DEPENDS)
|
2014-04-10 17:39:35 +02:00
|
|
|
state = fields.Selection([
|
|
|
|
('draft', 'Draft'),
|
|
|
|
('valid', 'Valid'),
|
|
|
|
], 'State', required=True, readonly=True, select=True)
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __setup__(cls):
|
|
|
|
super(AnalyticLine, cls).__setup__()
|
|
|
|
cls._check_modify_exclude = ['state']
|
|
|
|
for fname in ('name', 'debit', 'credit', 'account', 'journal', 'date',
|
2015-04-13 10:31:42 +02:00
|
|
|
'reference', 'party', 'active'):
|
2014-04-10 17:39:35 +02:00
|
|
|
field = getattr(cls, fname)
|
|
|
|
if field.states.get('readonly'):
|
|
|
|
field.states['readonly'] = Or(field.states['readonly'],
|
|
|
|
_STATES['readonly'])
|
|
|
|
else:
|
|
|
|
field.states['readonly'] = _STATES['readonly']
|
2015-01-20 18:45:04 +01:00
|
|
|
if 'state' not in field.depends:
|
|
|
|
field.depends.append('state')
|
2015-04-13 10:31:42 +02:00
|
|
|
|
|
|
|
company_domain = ('account.company', '=', Eval('internal_company'))
|
|
|
|
if not cls.move_line.domain:
|
|
|
|
cls.move_line.domain = [company_domain]
|
|
|
|
elif company_domain not in cls.move_line.domain:
|
|
|
|
cls.move_line.domain.append(company_domain)
|
2015-01-20 18:45:04 +01:00
|
|
|
|
2015-03-31 16:31:21 +02:00
|
|
|
cls.journal.required = False
|
|
|
|
cls.journal.states = {
|
|
|
|
'required': Eval('state') != 'draft',
|
|
|
|
'readonly': Eval('state') != 'draft',
|
|
|
|
}
|
2015-04-13 10:31:42 +02:00
|
|
|
|
2014-04-10 17:39:35 +02:00
|
|
|
cls.move_line.required = False
|
|
|
|
cls.move_line.states = {
|
|
|
|
'required': Eval('state') != 'draft',
|
|
|
|
'readonly': Eval('state') != 'draft',
|
|
|
|
}
|
2014-06-10 19:44:48 +02:00
|
|
|
if not cls.move_line.on_change:
|
|
|
|
cls.move_line.on_change = []
|
|
|
|
for name in ['move_line', 'journal', 'name', 'party', 'debit',
|
|
|
|
'credit']:
|
2015-04-13 10:31:42 +02:00
|
|
|
if name not in cls.move_line.on_change:
|
2014-06-10 19:44:48 +02:00
|
|
|
cls.move_line.on_change.append(name)
|
2015-04-13 10:31:42 +02:00
|
|
|
cls.move_line.depends += ['internal_company', 'state']
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
cls._error_messages.update({
|
|
|
|
'move_line_account_analytic_forbidden': (
|
|
|
|
'The Analytic Line "%(line)s" is related to an Account '
|
|
|
|
'Move Line of Account "%(account)s" which has the '
|
|
|
|
'analytics forbidden for the Line\'s Analytic hierarchy.'),
|
|
|
|
})
|
|
|
|
cls._buttons.update({
|
|
|
|
'post': {
|
|
|
|
'invisible': Eval('state') == 'posted',
|
|
|
|
},
|
|
|
|
'draft': {
|
|
|
|
'invisible': Eval('state') == 'draft',
|
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def __register__(cls, module_name):
|
|
|
|
pool = Pool()
|
|
|
|
TableHandler = backend.get('TableHandler')
|
2016-07-05 11:57:37 +02:00
|
|
|
cursor = Transaction().connection.cursor()
|
2014-04-10 17:39:35 +02:00
|
|
|
sql_table = cls.__table__()
|
|
|
|
account_sql_table = pool.get('account.account').__table__()
|
|
|
|
move_line_sql_table = pool.get('account.move.line').__table__()
|
|
|
|
|
2015-04-13 10:31:42 +02:00
|
|
|
copy_company = False
|
2016-07-05 11:57:37 +02:00
|
|
|
if TableHandler.table_exist(cls._table):
|
2015-01-20 18:45:04 +01:00
|
|
|
# if table doesn't exists => new db
|
2016-07-05 11:57:37 +02:00
|
|
|
table = TableHandler(cls, module_name)
|
2015-04-13 10:31:42 +02:00
|
|
|
copy_company = not table.column_exist('internal_company')
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
super(AnalyticLine, cls).__register__(module_name)
|
|
|
|
|
2016-07-05 11:57:37 +02:00
|
|
|
table = TableHandler(cls, module_name)
|
2014-04-10 17:39:35 +02:00
|
|
|
|
2014-05-14 16:11:22 +02:00
|
|
|
is_sqlite = 'backend.sqlite.table.TableHandler' in str(TableHandler)
|
2014-04-10 17:39:35 +02:00
|
|
|
# Migration from DB without this module
|
2015-04-13 10:31:42 +02:00
|
|
|
# table.not_null_action('move_line', action='remove') don't execute the
|
2014-04-10 17:39:35 +02:00
|
|
|
# action if the field is not defined in this module
|
|
|
|
if not is_sqlite:
|
|
|
|
cursor.execute('ALTER TABLE %s ALTER COLUMN "move_line" '
|
|
|
|
'DROP NOT NULL' % (sql_table,))
|
|
|
|
table._update_definitions()
|
|
|
|
|
|
|
|
cursor.execute(*sql_table.update(columns=[sql_table.state],
|
|
|
|
values=['posted'],
|
|
|
|
where=((sql_table.state == None) &
|
|
|
|
(sql_table.move_line == None))))
|
2015-04-13 10:31:42 +02:00
|
|
|
if copy_company and not is_sqlite:
|
2014-04-10 17:39:35 +02:00
|
|
|
join = move_line_sql_table.join(account_sql_table)
|
|
|
|
join.condition = move_line_sql_table.account == join.right.id
|
2015-04-13 10:31:42 +02:00
|
|
|
query = sql_table.update(columns=[sql_table.internal_company],
|
|
|
|
values=[join.right.company], from_=[join],
|
2014-04-10 17:39:35 +02:00
|
|
|
where=sql_table.move_line == join.left.id)
|
|
|
|
cursor.execute(*query)
|
|
|
|
|
|
|
|
@staticmethod
|
2015-04-13 10:31:42 +02:00
|
|
|
def default_internal_company():
|
|
|
|
return Transaction().context.get('company')
|
2014-04-10 17:39:35 +02:00
|
|
|
|
2015-04-13 10:31:42 +02:00
|
|
|
@fields.depends('internal_company')
|
2015-01-20 18:45:04 +01:00
|
|
|
def on_change_with_currency(self, name=None):
|
2015-04-13 10:31:42 +02:00
|
|
|
if self.internal_company:
|
|
|
|
return self.internal_company.currency.id
|
2015-01-20 18:45:04 +01:00
|
|
|
|
2015-04-13 10:31:42 +02:00
|
|
|
@fields.depends('internal_company')
|
2015-01-20 18:45:04 +01:00
|
|
|
def on_change_with_currency_digits(self, name=None):
|
2015-04-13 10:31:42 +02:00
|
|
|
if self.internal_company:
|
|
|
|
return self.internal_company.currency.digits
|
2015-01-20 18:45:04 +01:00
|
|
|
return 2
|
|
|
|
|
2015-04-13 10:31:42 +02:00
|
|
|
@fields.depends('internal_company')
|
|
|
|
def on_change_with_company(self, name=None):
|
|
|
|
if self.internal_company:
|
|
|
|
return self.internal_company.id
|
|
|
|
|
2014-04-10 17:39:35 +02:00
|
|
|
@staticmethod
|
|
|
|
def default_state():
|
|
|
|
return 'draft'
|
|
|
|
|
2014-06-10 19:44:48 +02:00
|
|
|
def default_move_line_field(field_name):
|
|
|
|
@staticmethod
|
|
|
|
def default_value():
|
|
|
|
return Transaction().context.get(field_name)
|
|
|
|
return default_value
|
|
|
|
|
|
|
|
default_debit = default_move_line_field('debit')
|
|
|
|
default_credit = default_move_line_field('credit')
|
|
|
|
default_journal = default_move_line_field('journal')
|
|
|
|
default_party = default_move_line_field('party')
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def default_date():
|
|
|
|
context = Transaction().context
|
|
|
|
value = context.get('date')
|
|
|
|
if value:
|
|
|
|
return value
|
|
|
|
if 'move' in context:
|
|
|
|
move = Pool().get('account.move')(context.get('move'))
|
|
|
|
return move.date
|
|
|
|
|
|
|
|
@staticmethod
|
|
|
|
def default_name():
|
|
|
|
context = Transaction().context
|
|
|
|
for name in ('description', 'move_description'):
|
2015-04-13 10:31:42 +02:00
|
|
|
value = context.get(name)
|
2014-06-10 19:44:48 +02:00
|
|
|
if value:
|
|
|
|
return value
|
|
|
|
if 'move' in context:
|
|
|
|
move = Pool().get('account.move')(context.get('move'))
|
|
|
|
return move.description
|
|
|
|
|
|
|
|
def on_change_move_line(self):
|
2016-07-05 13:24:19 +02:00
|
|
|
self.journal = None,
|
|
|
|
self.name = None,
|
|
|
|
self.party = None,
|
|
|
|
if self.move_line:
|
|
|
|
self.date = self.move_line.move.date
|
|
|
|
if not self.debit:
|
|
|
|
self.debit = self.move_line.debit
|
|
|
|
if not self.credit:
|
|
|
|
self.credit = self.move_line.credit
|
|
|
|
if not self.journal:
|
|
|
|
self.journal = self.move_line.move.journal.id
|
|
|
|
if not self.party and self.move_line.party:
|
|
|
|
self.party = self.move_line.party.id
|
|
|
|
if not self.name:
|
|
|
|
self.name = self.move_line.description
|
2014-06-10 19:44:48 +02:00
|
|
|
|
2014-04-15 11:09:05 +02:00
|
|
|
@classmethod
|
|
|
|
def query_get(cls, table):
|
|
|
|
'''
|
|
|
|
Return SQL clause for analytic line depending of the context.
|
|
|
|
table is the SQL instance of the analytic_account_line table.
|
|
|
|
'''
|
|
|
|
clause = super(AnalyticLine, cls).query_get(table)
|
|
|
|
if Transaction().context.get('posted'):
|
|
|
|
clause &= table.state == 'posted'
|
|
|
|
return clause
|
|
|
|
|
2014-04-10 17:39:35 +02:00
|
|
|
@classmethod
|
|
|
|
def validate(cls, lines):
|
|
|
|
super(AnalyticLine, cls).validate(lines)
|
|
|
|
for line in lines:
|
|
|
|
line.check_account_forbidden_analytic()
|
|
|
|
|
|
|
|
def check_account_forbidden_analytic(self):
|
|
|
|
if (self.move_line and
|
|
|
|
self.move_line.account.analytic_constraint(self.account)
|
|
|
|
== 'forbidden'):
|
|
|
|
self.raise_user_error('move_line_account_analytic_forbidden', {
|
|
|
|
'line': self.rec_name,
|
|
|
|
'account': self.move_line.account.rec_name,
|
|
|
|
})
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def check_modify(cls, lines):
|
|
|
|
'''
|
|
|
|
Check if the lines can be modified
|
|
|
|
'''
|
|
|
|
MoveLine = Pool().get('account.move.line')
|
|
|
|
move_lines = [l.move_line for l in lines if l.move_line]
|
|
|
|
MoveLine.check_modify(list(set(move_lines)))
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def create(cls, vlist):
|
|
|
|
MoveLine = Pool().get('account.move.line')
|
|
|
|
|
|
|
|
lines = super(AnalyticLine, cls).create(vlist)
|
|
|
|
cls.check_modify(lines)
|
|
|
|
|
|
|
|
move_lines = list(set(l.move_line for l in lines if l.move_line))
|
|
|
|
MoveLine.validate_analytic_lines(move_lines)
|
|
|
|
return lines
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def write(cls, lines, vals):
|
|
|
|
MoveLine = Pool().get('account.move.line')
|
|
|
|
|
|
|
|
if any(k not in cls._check_modify_exclude for k in vals):
|
|
|
|
cls.check_modify(lines)
|
|
|
|
|
|
|
|
move_lines = [l.move_line for l in lines if l.move_line]
|
|
|
|
super(AnalyticLine, cls).write(lines, vals)
|
|
|
|
move_lines += [l.move_line for l in lines if l.move_line]
|
|
|
|
|
|
|
|
if any(k not in cls._check_modify_exclude for k in vals):
|
|
|
|
cls.check_modify(lines)
|
|
|
|
|
|
|
|
MoveLine.validate_analytic_lines(list(set(move_lines)))
|
|
|
|
todraft_lines = [l for l in lines
|
|
|
|
if (not l.move_line and l.state != 'draft')]
|
|
|
|
cls.write(todraft_lines, {
|
|
|
|
'state': 'draft',
|
|
|
|
})
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
def delete(cls, lines):
|
|
|
|
MoveLine = Pool().get('account.move.line')
|
|
|
|
|
|
|
|
cls.check_modify(lines)
|
|
|
|
|
2015-01-20 18:45:04 +01:00
|
|
|
move_lines = list(set([l.move_line for l in lines if l.move_line]))
|
2014-04-10 17:39:35 +02:00
|
|
|
super(AnalyticLine, cls).delete(lines)
|
|
|
|
MoveLine.validate_analytic_lines(move_lines)
|
|
|
|
|
|
|
|
|
|
|
|
class OpenChartAccountStart(ModelView):
|
|
|
|
__name__ = 'analytic_account.open_chart.start'
|
|
|
|
posted = fields.Boolean('Posted Moves',
|
|
|
|
help='Show posted moves only')
|
|
|
|
|
|
|
|
|
|
|
|
class OpenChartAccount(Wizard):
|
|
|
|
__name__ = 'analytic_account.open_chart'
|
|
|
|
|
|
|
|
def do_open_(self, action):
|
|
|
|
action, context = super(OpenChartAccount, self).do_open_(action)
|
|
|
|
action['pyson_context'] = PYSONEncoder().encode({
|
|
|
|
'start_date': self.start.start_date,
|
|
|
|
'end_date': self.start.end_date,
|
|
|
|
'posted': self.start.posted,
|
|
|
|
})
|
|
|
|
return action, context
|
|
|
|
|
|
|
|
# vim:ft=python.tryton:
|