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.
|
2017-12-27 13:39:32 +01:00
|
|
|
from sql import Column, Null
|
2014-04-10 17:39:35 +02:00
|
|
|
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
|
2018-03-21 18:01:12 +01:00
|
|
|
from trytond.pyson import Eval, Or, PYSONEncoder, PYSONDecoder
|
2014-04-10 17:39:35 +02:00
|
|
|
from trytond.transaction import Transaction
|
|
|
|
from trytond.wizard import Wizard
|
2019-04-04 09:54:40 +02:00
|
|
|
from trytond.i18n import gettext
|
|
|
|
from trytond.exceptions import UserError
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
__all__ = ['AnalyticAccount', 'AnalyticAccountAccountRequired',
|
|
|
|
'AnalyticAccountAccountForbidden', 'AnalyticAccountAccountOptional',
|
|
|
|
'AnalyticLine', 'OpenChartAccountStart', 'OpenChartAccount']
|
|
|
|
|
|
|
|
|
2018-08-24 12:18:13 +02:00
|
|
|
class AnalyticAccount(metaclass=PoolMeta):
|
2014-04-10 17:39:35 +02:00
|
|
|
__name__ = 'analytic_account.account'
|
|
|
|
|
|
|
|
analytic_required = fields.Many2Many(
|
|
|
|
'analytic_account.account-required-account.account',
|
|
|
|
'analytic_account', 'account', 'Analytic Required', domain=[
|
2019-04-04 12:23:27 +02:00
|
|
|
('type', '!=', None),
|
2016-07-27 15:07:08 +02:00
|
|
|
('company', '=', Eval('company')),
|
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',
|
2016-07-27 15:07:08 +02:00
|
|
|
},
|
|
|
|
depends=['company', 'analytic_forbidden', 'analytic_optional', 'type'])
|
2014-04-10 17:39:35 +02:00
|
|
|
analytic_forbidden = fields.Many2Many(
|
|
|
|
'analytic_account.account-forbidden-account.account',
|
|
|
|
'analytic_account', 'account', 'Analytic Forbidden', domain=[
|
2019-04-04 12:23:27 +02:00
|
|
|
('type', '!=', None),
|
2016-07-27 15:07:08 +02:00
|
|
|
('company', '=', Eval('company')),
|
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',
|
2016-07-27 15:07:08 +02:00
|
|
|
},
|
|
|
|
depends=['company', 'analytic_required', 'analytic_optional', 'type'])
|
2014-04-10 17:39:35 +02:00
|
|
|
analytic_optional = fields.Many2Many(
|
|
|
|
'analytic_account.account-optional-account.account',
|
|
|
|
'analytic_account', 'account', 'Analytic Optional', domain=[
|
2019-04-04 12:23:27 +02:00
|
|
|
('type', '!=', None),
|
2016-07-27 15:07:08 +02:00
|
|
|
('company', '=', Eval('company')),
|
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',
|
2016-07-27 15:07:08 +02:00
|
|
|
},
|
|
|
|
depends=['company', 'analytic_required', 'analytic_forbidden', 'type'])
|
2014-04-10 17:39:35 +02:00
|
|
|
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')
|
|
|
|
|
2014-06-04 16:36:13 +02:00
|
|
|
@fields.depends('analytic_required', 'analytic_forbidden',
|
2017-12-27 13:39:32 +01:00
|
|
|
'analytic_optional', 'company')
|
2014-04-10 17:39:35 +02:00
|
|
|
def on_change_with_analytic_pending_accounts(self, name=None):
|
|
|
|
Account = Pool().get('account.account')
|
|
|
|
|
2018-08-24 12:18:13 +02:00
|
|
|
current_accounts = [x.id for x in self.analytic_required]
|
|
|
|
current_accounts += [x.id for x in self.analytic_forbidden]
|
|
|
|
current_accounts += [x.id for x in self.analytic_optional]
|
2014-04-10 17:39:35 +02:00
|
|
|
pending_accounts = Account.search([
|
2019-04-04 12:23:27 +02:00
|
|
|
('type', '!=', None),
|
2016-07-27 15:07:08 +02:00
|
|
|
('company', '=', self.company),
|
2014-04-10 17:39:35 +02:00
|
|
|
('id', 'not in', current_accounts),
|
|
|
|
])
|
2018-08-24 12:18:13 +02:00
|
|
|
return [x.id for x in pending_accounts]
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
@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:
|
2019-04-04 09:54:40 +02:00
|
|
|
raise UserError(gettext(
|
|
|
|
'analytic_line_state.analytic_account_required_forbidden',
|
|
|
|
root=self.rec_name,
|
|
|
|
accounts=', '.join([a.rec_name
|
2014-04-10 17:39:35 +02:00
|
|
|
for a in (required & forbidden)])
|
2019-04-04 09:54:40 +02:00
|
|
|
))
|
2014-04-10 17:39:35 +02:00
|
|
|
if required & optional:
|
2019-04-04 09:54:40 +02:00
|
|
|
raise UserError(gettext(
|
|
|
|
'analytic_line_state.analytic_account_required_optional',
|
|
|
|
root=self.rec_name,
|
|
|
|
accounts=', '.join([a.rec_name
|
2014-04-10 17:39:35 +02:00
|
|
|
for a in (required & optional)])
|
2019-04-04 09:54:40 +02:00
|
|
|
))
|
2014-04-10 17:39:35 +02:00
|
|
|
if forbidden & optional:
|
2019-04-04 09:54:40 +02:00
|
|
|
raise UserError(gettext(
|
|
|
|
'analytic_line_state.analytic_account_forbidden_optional',
|
|
|
|
root=self.rec_name,
|
|
|
|
accounts=', '.join([a.rec_name
|
2014-04-10 17:39:35 +02:00
|
|
|
for a in (forbidden & optional)])
|
2019-04-04 09:54:40 +02:00
|
|
|
))
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
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']
|
|
|
|
|
|
|
|
|
2018-08-24 12:18:13 +02:00
|
|
|
class AnalyticLine(metaclass=PoolMeta):
|
2014-04-10 17:39:35 +02:00
|
|
|
__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']
|
2017-12-27 13:39:32 +01:00
|
|
|
for fname in ['debit', 'credit', 'account', 'date']:
|
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
|
|
|
|
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',
|
|
|
|
}
|
2015-04-13 10:31:42 +02:00
|
|
|
cls.move_line.depends += ['internal_company', 'state']
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
|
|
|
|
@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
|
|
|
|
2017-12-27 13:39:32 +01:00
|
|
|
is_sqlite = backend.name() == 'sqlite'
|
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'],
|
2017-12-27 13:39:32 +01:00
|
|
|
where=((sql_table.state == Null) &
|
|
|
|
(sql_table.move_line == Null))))
|
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_digits(self, name=None):
|
2017-12-27 13:39:32 +01:00
|
|
|
digits = super(AnalyticLine, self).on_change_with_currency_digits(
|
|
|
|
name=name)
|
2015-04-13 10:31:42 +02:00
|
|
|
if self.internal_company:
|
2017-12-27 13:39:32 +01:00
|
|
|
digits = self.internal_company.currency.digits
|
|
|
|
return digits
|
2015-01-20 18:45:04 +01:00
|
|
|
|
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
|
|
|
|
|
2016-07-27 15:07:08 +02:00
|
|
|
@classmethod
|
|
|
|
def search_company(cls, name, clause):
|
|
|
|
return [('internal_company',) + tuple(clause[1:])]
|
|
|
|
|
2014-04-10 17:39:35 +02:00
|
|
|
@staticmethod
|
|
|
|
def default_state():
|
|
|
|
return 'draft'
|
|
|
|
|
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'):
|
2019-04-04 09:54:40 +02:00
|
|
|
raise UserError(gettext(
|
|
|
|
'analytic_line_state.move_line_account_analytic_forbidden',
|
|
|
|
line=self.rec_name,
|
|
|
|
account=self.move_line.account.rec_name,
|
|
|
|
))
|
2014-04-10 17:39:35 +02:00
|
|
|
|
|
|
|
@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
|
2016-02-18 11:31:50 +01:00
|
|
|
def write(cls, *args):
|
2014-04-10 17:39:35 +02:00
|
|
|
MoveLine = Pool().get('account.move.line')
|
|
|
|
|
2016-02-18 11:31:50 +01:00
|
|
|
actions = iter(args)
|
|
|
|
lines_to_check, all_lines = [], []
|
|
|
|
for lines, vals in zip(actions, actions):
|
|
|
|
if any(k not in cls._check_modify_exclude for k in vals):
|
|
|
|
lines_to_check.extend(lines)
|
|
|
|
all_lines.extend(lines)
|
|
|
|
cls.check_modify(lines_to_check)
|
|
|
|
|
|
|
|
move_lines = set([l.move_line for l in all_lines if l.move_line])
|
|
|
|
super(AnalyticLine, cls).write(*args)
|
|
|
|
move_lines |= set([l.move_line for l in all_lines if l.move_line])
|
|
|
|
|
|
|
|
lines_to_check = []
|
|
|
|
for lines, vals in zip(actions, actions):
|
|
|
|
if any(k not in cls._check_modify_exclude for k in vals):
|
|
|
|
lines_to_check.extend(lines)
|
|
|
|
cls.check_modify(lines_to_check)
|
|
|
|
MoveLine.validate_analytic_lines(list(move_lines))
|
|
|
|
todraft_lines = [l for l in all_lines
|
|
|
|
if (not l.move_line and l.state != 'draft')]
|
|
|
|
# Call super to avoid_recursion error:
|
|
|
|
if todraft_lines:
|
|
|
|
super(AnalyticLine, cls).write(todraft_lines, {
|
2014-04-10 17:39:35 +02:00
|
|
|
'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)
|
2018-03-21 18:01:12 +01:00
|
|
|
pyson_context = PYSONDecoder().decode(action['pyson_context'])
|
|
|
|
pyson_context.update({
|
2014-04-10 17:39:35 +02:00
|
|
|
'posted': self.start.posted,
|
2018-03-21 18:01:12 +01:00
|
|
|
'date': self.start.end_date,
|
2014-04-10 17:39:35 +02:00
|
|
|
})
|
2018-03-21 18:01:12 +01:00
|
|
|
action['pyson_context'] = PYSONEncoder().encode(pyson_context)
|
2014-04-10 17:39:35 +02:00
|
|
|
return action, context
|
|
|
|
|
|
|
|
# vim:ft=python.tryton:
|