diff --git a/CHANGELOG b/CHANGELOG index 6c4ac3e633..6e6bdaec03 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Add reconciliation sequence to configuration * Add report for income statement and balance sheet * Allow filtering general ledger by journal * Add journal context to Move.query_get diff --git a/__init__.py b/__init__.py index 3b0a5cf2d9..55c3d751f3 100644 --- a/__init__.py +++ b/__init__.py @@ -44,6 +44,7 @@ def register(): configuration.Configuration, configuration.ConfigurationDefaultAccount, configuration.DefaultTaxRule, + configuration.Sequence, period.Period, journal.Journal, journal.JournalSequence, diff --git a/configuration.py b/configuration.py index 15c5594576..c2e9678b70 100644 --- a/configuration.py +++ b/configuration.py @@ -3,7 +3,7 @@ from trytond.pool import Pool from trytond.model import ModelView, ModelSQL, ModelSingleton, fields from trytond.transaction import Transaction -from trytond.pyson import Eval +from trytond.pyson import Eval, Id from trytond.modules.company.model import ( CompanyMultiValueMixin, CompanyValueMixin) @@ -47,6 +47,15 @@ class Configuration( help="Default supplier tax rule for new parties.")) tax_rounding = fields.MultiValue(fields.Selection( tax_roundings, "Tax Rounding")) + reconciliation_sequence = fields.MultiValue(fields.Many2One( + 'ir.sequence', "Reconciliation Sequence", required=True, + domain=[ + ('company', 'in', + [Eval('context', {}).get('company', -1), None]), + ('sequence_type', '=', + Id('account', + 'sequence_type_account_move_reconciliation')), + ])) @classmethod def multivalue_model(cls, field): @@ -55,12 +64,19 @@ class Configuration( return pool.get('account.configuration.default_account') if field in {'default_customer_tax_rule', 'default_supplier_tax_rule'}: return pool.get('account.configuration.default_tax_rule') + if field == 'reconciliation_sequence': + return pool.get('account.configuration.sequence') return super(Configuration, cls).multivalue_model(field) @classmethod def default_tax_rounding(cls, **pattern): return cls.multivalue_model('tax_rounding').default_tax_rounding() + @classmethod + def default_reconciliation_sequence(cls, **pattern): + return cls.multivalue_model( + 'reconciliation_sequence').default_reconciliation_sequence() + class ConfigurationDefaultAccount(ModelSQL, CompanyValueMixin): "Account Configuration Default Account" @@ -131,3 +147,26 @@ class ConfigurationTaxRounding(ModelSQL, CompanyValueMixin): @classmethod def default_tax_rounding(cls): return 'document' + + +class Sequence(ModelSQL, CompanyValueMixin): + "Account Configuration Sequence" + __name__ = 'account.configuration.sequence' + reconciliation_sequence = fields.Many2One( + 'ir.sequence', "Reconciliation Sequence", required=True, + domain=[ + ('company', 'in', [Eval('company', -1), None]), + ('sequence_type', '=', + Id('account', 'sequence_type_account_move_reconciliation')), + ], + depends=['company']) + + @classmethod + def default_reconciliation_sequence(cls): + pool = Pool() + ModelData = pool.get('ir.model.data') + try: + return ModelData.get_id( + 'account', 'sequence_account_move_reconciliation') + except KeyError: + return None diff --git a/fiscalyear.py b/fiscalyear.py index bd77f74499..6ae9e2011d 100644 --- a/fiscalyear.py +++ b/fiscalyear.py @@ -7,7 +7,7 @@ from trytond.i18n import gettext from trytond.model import ModelView, ModelSQL, Workflow, fields from trytond.model.exceptions import AccessError from trytond.pool import Pool -from trytond.pyson import Eval, If, PYSONEncoder +from trytond.pyson import Eval, If, PYSONEncoder, Id from trytond.rpc import RPC from trytond.transaction import Transaction from trytond.wizard import ( @@ -43,17 +43,14 @@ class FiscalYear(Workflow, ModelSQL, ModelView): ('close', 'Close'), ('locked', 'Locked'), ], 'State', readonly=True, required=True) - post_move_sequence = fields.Many2One('ir.sequence', 'Post Move Sequence', - required=True, domain=[('code', '=', 'account.move'), - ['OR', - ('company', '=', Eval('company')), - ('company', '=', None) - ]], - context={ - 'code': 'account.move', - 'company': Eval('company'), - }, - depends=['company']) + post_move_sequence = fields.Many2One( + 'ir.sequence', "Post Move Sequence", required=True, + domain=[ + ('sequence_type', '=', + Id('account', 'sequence_type_account_move')), + ('company', '=', Eval('company')), + ], + depends=['company']) company = fields.Many2One('company.company', 'Company', required=True, domain=[ ('id', If(Eval('context', {}).contains('company'), '=', '!='), diff --git a/journal.py b/journal.py index 3ba3f79d3f..88198599a9 100644 --- a/journal.py +++ b/journal.py @@ -9,7 +9,7 @@ from trytond.i18n import gettext from trytond.model import ( ModelView, ModelSQL, Workflow, DeactivableMixin, fields, Unique) from trytond.model.exceptions import AccessError -from trytond.pyson import Eval, Bool +from trytond.pyson import Eval, Bool, Id from trytond.transaction import Transaction from trytond.pool import Pool from trytond.tools import reduce_ids, grouped_slice, lstrip_wildcard @@ -40,7 +40,8 @@ class Journal( sequence = fields.MultiValue(fields.Many2One( 'ir.sequence', "Sequence", domain=[ - ('code', '=', 'account.journal'), + ('sequence_type', '=', + Id('account', 'sequence_type_account_journal')), ('company', 'in', [ Eval('context', {}).get('company', -1), None]), ], @@ -162,7 +163,8 @@ class JournalSequence(ModelSQL, CompanyValueMixin): sequence = fields.Many2One( 'ir.sequence', "Sequence", domain=[ - ('code', '=', 'account.journal'), + ('sequence_type', '=', + Id('account', 'sequence_type_account_journal')), ('company', 'in', [Eval('company', -1), None]), ], depends=['company']) diff --git a/journal.xml b/journal.xml index 6748a5e303..42c9f41712 100644 --- a/journal.xml +++ b/journal.xml @@ -87,7 +87,6 @@ this repository contains the full copyright notices and license terms. --> Account Journal - account.journal @@ -102,7 +101,7 @@ this repository contains the full copyright notices and license terms. --> Default Account Journal - account.journal + diff --git a/move.py b/move.py index 7a761c0749..7723e87a52 100644 --- a/move.py +++ b/move.py @@ -273,7 +273,6 @@ class Move(ModelSQL, ModelView): @classmethod def create(cls, vlist): pool = Pool() - Sequence = pool.get('ir.sequence') Journal = pool.get('account.journal') vlist = [x.copy() for x in vlist] @@ -284,7 +283,7 @@ class Move(ModelSQL, ModelView): if journal_id: journal = Journal(journal_id) if journal.sequence: - vals['number'] = Sequence.get_id(journal.sequence.id) + vals['number'] = journal.sequence.get() moves = super(Move, cls).create(vlist) cls.validate_move(moves) @@ -413,7 +412,6 @@ class Move(ModelSQL, ModelView): @ModelView.button def post(cls, moves): pool = Pool() - Sequence = pool.get('ir.sequence') Date = pool.get('ir.date') Line = pool.get('account.move.line') @@ -435,8 +433,7 @@ class Move(ModelSQL, ModelView): move.state = 'posted' if not move.post_number: move.post_date = Date.today() - move.post_number = Sequence.get_id( - move.period.post_move_sequence_used.id) + move.post_number = move.period.post_move_sequence_used.get() def keyfunc(l): return l.party, l.account @@ -490,12 +487,14 @@ class Reconciliation(ModelSQL, ModelView): @classmethod def create(cls, vlist): - Sequence = Pool().get('ir.sequence') + pool = Pool() + Configuration = pool.get('account.configuration') + configuration = Configuration(1) vlist = [x.copy() for x in vlist] for vals in vlist: if 'name' not in vals: - vals['name'] = Sequence.get('account.move.reconciliation') + vals['name'] = configuration.reconciliation_sequence.get() return super(Reconciliation, cls).create(vlist) diff --git a/move.xml b/move.xml index 751c5b92b1..43c1dc58de 100644 --- a/move.xml +++ b/move.xml @@ -69,7 +69,6 @@ this repository contains the full copyright notices and license terms. --> Account Move - account.move @@ -131,7 +130,6 @@ this repository contains the full copyright notices and license terms. --> Account Move Reconciliation - account.move.reconciliation @@ -146,7 +144,7 @@ this repository contains the full copyright notices and license terms. --> Default Account Move Reconciliation - account.move.reconciliation + diff --git a/period.py b/period.py index 3caeafc190..69f41f7dde 100644 --- a/period.py +++ b/period.py @@ -4,7 +4,7 @@ from trytond.i18n import gettext from trytond.model import ModelView, ModelSQL, Workflow, fields from trytond.model.exceptions import AccessError -from trytond.pyson import Eval +from trytond.pyson import Eval, Id from trytond.transaction import Transaction from trytond.pool import Pool from trytond.const import OPERATORS @@ -37,7 +37,8 @@ class Period(Workflow, ModelSQL, ModelView): ], 'State', readonly=True, required=True) post_move_sequence = fields.Many2One('ir.sequence', 'Post Move Sequence', domain=[ - ('code', '=', 'account.move'), + ('sequence_type', '=', + Id('account', 'sequence_type_account_move')), ['OR', ('company', '=', None), ('company', '=', Eval('company', -1)), diff --git a/tests/scenario_account_reconcile.rst b/tests/scenario_account_reconcile.rst index 6dfbb12647..6e0b8dec27 100644 --- a/tests/scenario_account_reconcile.rst +++ b/tests/scenario_account_reconcile.rst @@ -82,7 +82,8 @@ Create Moves to reconcile:: Create a write off method:: >>> Sequence = Model.get('ir.sequence') - >>> sequence_journal, = Sequence.find([('code', '=', 'account.journal')]) + >>> sequence_journal, = Sequence.find( + ... [('sequence_type.name', '=', "Account Journal")], limit=1) >>> journal_writeoff = Journal(name='Write-Off', type='write-off', ... sequence=sequence_journal) >>> journal_writeoff.save() diff --git a/tests/scenario_account_reconciliation.rst b/tests/scenario_account_reconciliation.rst index 2239aee501..32b89e98e5 100644 --- a/tests/scenario_account_reconciliation.rst +++ b/tests/scenario_account_reconciliation.rst @@ -124,11 +124,12 @@ Create Moves for writeoff reconciliation:: >>> move.save() >>> reconcile2, = [l for l in move.lines if l.account == receivable] -Create a writeof payment method:: +Create a write-off payment method:: >>> Sequence = Model.get('ir.sequence') - >>> sequence_journal, = Sequence.find([('code', '=', 'account.journal')]) + >>> sequence_journal, = Sequence.find( + ... [('sequence_type.name', '=', "Account Journal")], limit=1) >>> journal_writeoff = Journal(name='Write-Off', type='write-off', ... sequence=sequence_journal) >>> journal_writeoff.save() @@ -140,7 +141,7 @@ Create a writeof payment method:: >>> writeoff_method.credit_account = expense >>> writeoff_method.save() -Reconcile Lines with writeoff:: +Reconcile Lines with write-off:: >>> reconcile_lines = Wizard('account.move.reconcile_lines', ... [reconcile1, reconcile2]) >>> reconcile_lines.form_state == 'writeoff' diff --git a/tests/test_account.py b/tests/test_account.py index 87d907974c..63954cfef7 100644 --- a/tests/test_account.py +++ b/tests/test_account.py @@ -86,6 +86,7 @@ def create_chart(company, tax=False, chart='account.account_template_root_en'): def get_fiscalyear(company, today=None, start_date=None, end_date=None): pool = Pool() Sequence = pool.get('ir.sequence') + SequenceType = pool.get('ir.sequence.type') FiscalYear = pool.get('account.fiscalyear') if not today: @@ -95,9 +96,12 @@ def get_fiscalyear(company, today=None, start_date=None, end_date=None): if not end_date: end_date = today.replace(month=12, day=31) + sequence_type, = SequenceType.search([ + ('name', '=', "Account Move"), + ], limit=1) sequence, = Sequence.create([{ 'name': '%s' % today.year, - 'code': 'account.move', + 'sequence_type': sequence_type.id, 'company': company.id, }]) fiscalyear = FiscalYear(name='%s' % today.year, company=company) @@ -121,8 +125,8 @@ def close_fiscalyear(fiscalyear): # Balance non-deferral journal_sequence, = Sequence.search([ - ('code', '=', 'account.journal'), - ]) + ('sequence_type.name', '=', "Account Journal"), + ], limit=1) journal_closing, = Journal.create([{ 'name': 'Closing', 'code': 'CLO', diff --git a/tests/tools.py b/tests/tools.py index 6def35007e..0cc5df0918 100644 --- a/tests/tools.py +++ b/tests/tools.py @@ -16,6 +16,7 @@ def create_fiscalyear(company=None, today=None, config=None): "Create a fiscal year for the company on today" FiscalYear = Model.get('account.fiscalyear', config=config) Sequence = Model.get('ir.sequence', config=config) + SequenceType = Model.get('ir.sequence.type', config=config) if not company: company = get_company() @@ -28,7 +29,11 @@ def create_fiscalyear(company=None, today=None, config=None): fiscalyear.end_date = today + relativedelta(month=12, day=31) fiscalyear.company = company - post_move_sequence = Sequence(name=str(today.year), code='account.move', + sequence_type, = SequenceType.find( + [('name', '=', "Account Move")], limit=1) + post_move_sequence = Sequence( + name=str(today.year), + sequence_type=sequence_type, company=company) post_move_sequence.save() fiscalyear.post_move_sequence = post_move_sequence diff --git a/view/configuration_form.xml b/view/configuration_form.xml index 3b81b1295c..65f641f3c9 100644 --- a/view/configuration_form.xml +++ b/view/configuration_form.xml @@ -14,4 +14,7 @@ this repository contains the full copyright notices and license terms. -->