Files
tradon/modules/account_export/account.py
2026-03-14 09:42:12 +00:00

222 lines
6.9 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import trytond.config as config
from trytond.i18n import gettext
from trytond.model import ModelSQL, ModelView, Workflow, fields
from trytond.model.exceptions import AccessError
from trytond.modules.company.model import CompanyValueMixin
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.transaction import Transaction
if config.getboolean('account_export', 'filestore', default=False):
file_id = 'file_id'
store_prefix = config.get('account_export', 'store_prefix', default=None)
else:
file_id = store_prefix = None
class _ExportTypes:
__slots__ = ()
@classmethod
def get_move_export_types(cls):
pool = Pool()
MoveExport = pool.get('account.move.export')
return MoveExport.fields_get(['type'])['type']['selection']
class Configuration(_ExportTypes, metaclass=PoolMeta):
__name__ = 'account.configuration'
move_export_type = fields.MultiValue(fields.Selection(
'get_move_export_types', "Move Export Type"))
@classmethod
def multivalue_model(cls, field):
pool = Pool()
if field == 'move_export_type':
return pool.get('account.configuration.export')
return super().multivalue_model(field)
class ConfigurationExport(_ExportTypes, ModelSQL, CompanyValueMixin):
__name__ = 'account.configuration.export'
move_export_type = fields.Selection(
'get_move_export_types', "Move Export Type")
class Move(metaclass=PoolMeta):
__name__ = 'account.move'
export = fields.Many2One(
'account.move.export', "Export", readonly=True, ondelete='RESTRICT',
domain=[
('company', '=', Eval('company', -1)),
])
@classmethod
def __setup__(cls):
super().__setup__()
cls._check_modify_exclude.add('export')
@classmethod
def copy(cls, moves, default=None):
default = default.copy() if default is not None else {}
default.setdefault('export')
return super().copy(moves, default=default)
class MoveExport(Workflow, ModelSQL, ModelView):
__name__ = 'account.move.export'
company = fields.Many2One('company.company', "Company", required=True)
type = fields.Selection([
(None, ""),
], "Type",
states={
'readonly': Eval('state') != 'draft',
})
moves = fields.One2Many(
'account.move', 'export', "Moves", readonly=True,
domain=[
('company', '=', Eval('company', -1)),
('state', '=', 'posted'),
],
order=[
('id', 'ASC'),
])
file = fields.Binary("File", filename='filename',
file_id=file_id, store_prefix=store_prefix, readonly=True)
file_id = fields.Char("File ID", readonly=True)
filename = fields.Function(fields.Char("Filename"), 'get_filename')
state = fields.Selection([
('draft', "Draft"),
('waiting', "Waiting"),
('done', "Done"),
], "State", readonly=True, sort=False)
@classmethod
def __setup__(cls):
super().__setup__()
cls._transitions |= {
('draft', 'draft'),
('draft', 'waiting'),
('waiting', 'draft'),
('waiting', 'done'),
}
cls._buttons.update({
'draft': {
'invisible': ~(
((Eval('state') == 'draft') & Eval('moves'))
| (Eval('state') == 'waiting')),
'depends': ['state'],
},
'select_moves': {
'invisible': Eval('state') != 'draft',
'depends': ['state'],
},
'wait': {
'invisible': Eval('state') != 'draft',
'readonly': ~Eval('moves'),
'depends': ['state', 'moves'],
},
'do': {
'invisible': Eval('state') != 'waiting',
'depends': ['state'],
},
})
@classmethod
def default_company(cls):
return Transaction().context.get('company')
@fields.depends('company')
def on_change_company(self):
pool = Pool()
Configuration = pool.get('account.configuration')
if self.company:
self.type = Configuration(1).get_multivalue(
'move_export_type', company=self.company.id)
else:
self.type = None
@classmethod
def default_type(cls):
pool = Pool()
Configuration = pool.get('account.configuration')
return Configuration(1).get_multivalue(
'move_export_type', company=cls.default_company())
def get_filename(self, name):
pass
@classmethod
def default_state(cls):
return 'draft'
def get_rec_name(self, name):
return f'{self.company.rec_name} ({self.id})'
@classmethod
@ModelView.button
@Workflow.transition('draft')
def draft(cls, exports):
pool = Pool()
Move = pool.get('account.move')
moves = list(sum((e.moves for e in exports), ()))
Move.write(moves, {'export': None})
cls.write(exports, {'file': None})
@classmethod
@ModelView.button
def select_moves(cls, exports):
pool = Pool()
Move = pool.get('account.move')
exports = [e for e in exports if e.state == 'draft']
moves = list(sum((e.moves for e in exports), ()))
Move.write(moves, {'export': None})
for export in exports:
export.moves = Move.search([
('export', '=', None),
('company', '=', export.company.id),
])
export.file = None
cls.save(exports)
@classmethod
@ModelView.button
@Workflow.transition('waiting')
def wait(cls, exports):
for export in exports:
if export.type:
getattr(export, f'_process_{export.type}')()
cls.save(exports)
@classmethod
@ModelView.button
@Workflow.transition('done')
def do(cls, exports):
pass
@classmethod
def copy(cls, exports, default=None):
default = default.copy() if default is not None else {}
default.setdefault('moves')
return super().copy(exports, default=default)
@classmethod
def check_modification(cls, mode, exports, values=None, external=False):
super().check_modification(
mode, exports, values=values, external=external)
if mode == 'delete':
for export in exports:
if export.state != 'draft':
raise AccessError(gettext(
'account_export.'
'msg_account_move_export_delete_draft',
export=export.rec_name))