Add cancel to Account Move
issue3875 review10261002
This commit is contained in:
1 parent
6a2149e5bc
commit
0ef36b0ec8
6 files changed
+250
-2
No files matched your search
@@ -1,3 +1,5 @@
|
||||
* Add cancel to Account Move
|
||||
|
||||
Version 3.2.0 - 2014-04-21
|
||||
* Bug fixes (see mercurial logs for details)
|
||||
* Add start/end date to tax
|
||||
|
||||
@@ -89,6 +89,7 @@ def register():
|
||||
ReconcileLines,
|
||||
UnreconcileLines,
|
||||
OpenReconcileLines,
|
||||
CancelMoves,
|
||||
PrintGeneralJournal,
|
||||
OpenChartTaxCode,
|
||||
OpenTaxCode,
|
||||
|
||||
@@ -4,6 +4,8 @@ from decimal import Decimal
|
||||
import datetime
|
||||
from itertools import groupby
|
||||
from operator import itemgetter
|
||||
from collections import defaultdict
|
||||
|
||||
from sql.aggregate import Sum
|
||||
from sql.conditionals import Coalesce
|
||||
|
||||
@@ -21,7 +23,8 @@ from trytond.tools import reduce_ids
|
||||
__all__ = ['Move', 'Reconciliation', 'Line', 'OpenJournalAsk',
|
||||
'OpenJournal', 'OpenAccount', 'ReconcileLinesWriteOff', 'ReconcileLines',
|
||||
'UnreconcileLines', 'OpenReconcileLinesStart',
|
||||
'OpenReconcileLines', 'FiscalYearLine', 'FiscalYear2',
|
||||
'OpenReconcileLines', 'CancelMoves',
|
||||
'FiscalYearLine', 'FiscalYear2',
|
||||
'PrintGeneralJournalStart', 'PrintGeneralJournal', 'GeneralJournal']
|
||||
__metaclass__ = PoolMeta
|
||||
|
||||
@@ -86,6 +89,9 @@ class Move(ModelSQL, ModelView):
|
||||
'because it\'s date is outside its period.'),
|
||||
'draft_closed_period': ('You can not set to draft move '
|
||||
'"%(move)s" because period "%(period)s" is closed.'),
|
||||
'period_cancel': (
|
||||
'The period of move "%s" is closed.\n'
|
||||
'Use the current period?'),
|
||||
})
|
||||
cls._buttons.update({
|
||||
'post': {
|
||||
@@ -156,7 +162,7 @@ class Move(ModelSQL, ModelView):
|
||||
@classmethod
|
||||
def _get_origin(cls):
|
||||
'Return list of Model names for origin Reference'
|
||||
return ['account.fiscalyear']
|
||||
return ['account.fiscalyear', 'account.move']
|
||||
|
||||
@classmethod
|
||||
def get_origin(cls):
|
||||
@@ -334,6 +340,50 @@ class Move(ModelSQL, ModelView):
|
||||
values=[state],
|
||||
where=red_sql))
|
||||
|
||||
def _cancel_default(self):
|
||||
'Return default dictionary to cancel move'
|
||||
pool = Pool()
|
||||
Date = pool.get('ir.date')
|
||||
Period = pool.get('account.period')
|
||||
|
||||
default = {
|
||||
'origin': str(self),
|
||||
}
|
||||
if self.period.state == 'close':
|
||||
self.raise_user_warning('%s.cancel' % self,
|
||||
'period_cancel', self.rec_name)
|
||||
date = Date.today()
|
||||
period_id = Period.find(self.company.id, date=date)
|
||||
default.update({
|
||||
'date': date,
|
||||
'period': period_id,
|
||||
})
|
||||
return default
|
||||
|
||||
def cancel(self):
|
||||
'Return a cancel move'
|
||||
pool = Pool()
|
||||
Line = pool.get('account.move.line')
|
||||
TaxLine = pool.get('account.tax.line')
|
||||
default = self._cancel_default()
|
||||
cancel_move, = Move.copy([self], default=default)
|
||||
lines = []
|
||||
tax_lines = []
|
||||
for line in cancel_move.lines:
|
||||
line.debit *= -1
|
||||
line.credit *= -1
|
||||
lines.extend(([line], line._save_values))
|
||||
line._values = None
|
||||
for tax_line in line.tax_lines:
|
||||
tax_line.amount *= -1
|
||||
tax_lines.extend(([tax_line], tax_line._save_values))
|
||||
tax_line._values = None
|
||||
if lines:
|
||||
Line.write(*lines)
|
||||
if tax_lines:
|
||||
TaxLine.write(*tax_lines)
|
||||
return cancel_move
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def post(cls, moves):
|
||||
@@ -1670,6 +1720,29 @@ class OpenReconcileLines(Wizard):
|
||||
return action, {}
|
||||
|
||||
|
||||
class CancelMoves(Wizard):
|
||||
'Cancel Moves'
|
||||
__name__ = 'account.move.cancel'
|
||||
start_state = 'cancel'
|
||||
cancel = StateTransition()
|
||||
|
||||
def transition_cancel(self):
|
||||
pool = Pool()
|
||||
Move = pool.get('account.move')
|
||||
Line = pool.get('account.move.line')
|
||||
|
||||
moves = Move.browse(Transaction().context['active_ids'])
|
||||
for move in moves:
|
||||
cancel_move = move.cancel()
|
||||
to_reconcile = defaultdict(list)
|
||||
for line in move.lines + cancel_move.lines:
|
||||
if line.account.reconcile:
|
||||
to_reconcile[line.account].append(line)
|
||||
for lines in to_reconcile.itervalues():
|
||||
Line.reconcile(lines)
|
||||
return 'end'
|
||||
|
||||
|
||||
class FiscalYearLine(ModelSQL):
|
||||
'Fiscal Year - Move Line'
|
||||
__name__ = 'account.fiscalyear-account.move.line'
|
||||
|
||||
@@ -294,6 +294,16 @@ this repository contains the full copyright notices and license terms. -->
|
||||
action="act_open_reconcile_lines"
|
||||
id="menu_open_reconcile_lines"/>
|
||||
|
||||
<record model="ir.action.wizard" id="act_cancel_moves">
|
||||
<field name="name">Cancel Moves</field>
|
||||
<field name="wiz_name">account.move.cancel</field>
|
||||
</record>
|
||||
<record model="ir.action.keyword" id="act_cancel_moves_keyword1">
|
||||
<field name="keyword">form_action</field>
|
||||
<field name="model">account.move,-1</field>
|
||||
<field name="action" ref="act_cancel_moves"/>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="print_general_journal_start_view_form">
|
||||
<field name="model">account.move.print_general_journal.start</field>
|
||||
<field name="type">form</field>
|
||||
|
||||
@@ -0,0 +1,158 @@
|
||||
====================
|
||||
Move Cancel Scenario
|
||||
====================
|
||||
|
||||
=============
|
||||
General Setup
|
||||
=============
|
||||
|
||||
Imports::
|
||||
|
||||
>>> import datetime
|
||||
>>> from dateutil.relativedelta import relativedelta
|
||||
>>> from decimal import Decimal
|
||||
>>> from proteus import config, Model, Wizard
|
||||
>>> today = datetime.date.today()
|
||||
|
||||
Create database::
|
||||
|
||||
>>> config = config.set_trytond()
|
||||
>>> config.pool.test = True
|
||||
|
||||
Install account::
|
||||
|
||||
>>> Module = Model.get('ir.module.module')
|
||||
>>> modules = Module.find([
|
||||
... ('name', '=', 'account'),
|
||||
... ])
|
||||
>>> Module.install([x.id for x in modules], config.context)
|
||||
>>> Wizard('ir.module.module.install_upgrade').execute('upgrade')
|
||||
|
||||
Create company::
|
||||
|
||||
>>> Currency = Model.get('currency.currency')
|
||||
>>> CurrencyRate = Model.get('currency.currency.rate')
|
||||
>>> Company = Model.get('company.company')
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> company_config = Wizard('company.company.config')
|
||||
>>> company_config.execute('company')
|
||||
>>> company = company_config.form
|
||||
>>> party = Party(name='Dunder Mifflin')
|
||||
>>> party.save()
|
||||
>>> company.party = party
|
||||
>>> currencies = Currency.find([('code', '=', 'USD')])
|
||||
>>> if not currencies:
|
||||
... currency = Currency(name='U.S. Dollar', symbol='$', code='USD',
|
||||
... rounding=Decimal('0.01'), mon_grouping='[3, 3, 0]',
|
||||
... mon_decimal_point='.', mon_thousands_sep=',')
|
||||
... currency.save()
|
||||
... CurrencyRate(date=today + relativedelta(month=1, day=1),
|
||||
... rate=Decimal('1.0'), currency=currency).save()
|
||||
... else:
|
||||
... currency, = currencies
|
||||
>>> company.currency = currency
|
||||
>>> company_config.execute('add')
|
||||
>>> company, = Company.find()
|
||||
|
||||
Reload the context::
|
||||
|
||||
>>> User = Model.get('res.user')
|
||||
>>> config._context = User.get_preferences(True, config.context)
|
||||
|
||||
Create fiscal year::
|
||||
|
||||
>>> FiscalYear = Model.get('account.fiscalyear')
|
||||
>>> Sequence = Model.get('ir.sequence')
|
||||
>>> SequenceStrict = Model.get('ir.sequence.strict')
|
||||
>>> fiscalyear = FiscalYear(name='%s' % today.year)
|
||||
>>> fiscalyear.start_date = today + relativedelta(month=1, day=1)
|
||||
>>> fiscalyear.end_date = today + relativedelta(month=12, day=31)
|
||||
>>> fiscalyear.company = company
|
||||
>>> post_move_sequence = Sequence(name='%s' % today.year,
|
||||
... code='account.move', company=company)
|
||||
>>> post_move_sequence.save()
|
||||
>>> fiscalyear.post_move_sequence = post_move_sequence
|
||||
>>> fiscalyear.save()
|
||||
>>> FiscalYear.create_period([fiscalyear.id], config.context)
|
||||
>>> period = fiscalyear.periods[0]
|
||||
|
||||
Create chart of accounts::
|
||||
|
||||
>>> AccountTemplate = Model.get('account.account.template')
|
||||
>>> Account = Model.get('account.account')
|
||||
>>> account_template, = AccountTemplate.find([('parent', '=', None)])
|
||||
>>> create_chart = Wizard('account.create_chart')
|
||||
>>> create_chart.execute('account')
|
||||
>>> create_chart.form.account_template = account_template
|
||||
>>> create_chart.form.company = company
|
||||
>>> create_chart.execute('create_account')
|
||||
>>> receivable, = Account.find([
|
||||
... ('kind', '=', 'receivable'),
|
||||
... ('company', '=', company.id),
|
||||
... ])
|
||||
>>> payable, = Account.find([
|
||||
... ('kind', '=', 'payable'),
|
||||
... ('company', '=', company.id),
|
||||
... ])
|
||||
>>> revenue, = Account.find([
|
||||
... ('kind', '=', 'revenue'),
|
||||
... ('company', '=', company.id),
|
||||
... ])
|
||||
>>> create_chart.form.account_receivable = receivable
|
||||
>>> create_chart.form.account_payable = payable
|
||||
>>> create_chart.execute('create_properties')
|
||||
|
||||
Create parties::
|
||||
|
||||
>>> Party = Model.get('party.party')
|
||||
>>> customer = Party(name='Customer')
|
||||
>>> customer.save()
|
||||
|
||||
Create Move to cancel::
|
||||
|
||||
>>> Journal = Model.get('account.journal')
|
||||
>>> Move = Model.get('account.move')
|
||||
>>> journal_revenue, = Journal.find([
|
||||
... ('code', '=', 'REV'),
|
||||
... ])
|
||||
>>> journal_cash, = Journal.find([
|
||||
... ('code', '=', 'CASH'),
|
||||
... ])
|
||||
>>> move = Move()
|
||||
>>> move.period = period
|
||||
>>> move.journal = journal_revenue
|
||||
>>> move.date = period.start_date
|
||||
>>> line = move.lines.new()
|
||||
>>> line.account = revenue
|
||||
>>> line.credit = Decimal(42)
|
||||
>>> line = move.lines.new()
|
||||
>>> line.account = receivable
|
||||
>>> line.debit = Decimal(42)
|
||||
>>> line.party = customer
|
||||
>>> move.save()
|
||||
>>> revenue.reload()
|
||||
>>> revenue.credit
|
||||
Decimal('42.00')
|
||||
>>> receivable.reload()
|
||||
>>> receivable.debit
|
||||
Decimal('42.00')
|
||||
|
||||
Cancel Move::
|
||||
|
||||
>>> cancel_move = Wizard('account.move.cancel', [move])
|
||||
>>> cancel_move.state
|
||||
'end'
|
||||
>>> move.reload()
|
||||
>>> line, = [l for l in move.lines if l.account == receivable]
|
||||
>>> bool(line.reconciliation)
|
||||
True
|
||||
>>> cancel_move, = [l.move for l in line.reconciliation.lines
|
||||
... if l.move != move]
|
||||
>>> cancel_move.origin == move
|
||||
True
|
||||
>>> revenue.reload()
|
||||
>>> revenue.credit
|
||||
Decimal('0.00')
|
||||
>>> receivable.reload()
|
||||
>>> receivable.debit
|
||||
Decimal('0.00')
|
||||
@@ -436,4 +436,8 @@ def suite():
|
||||
'scenario_account_reconciliation.rst',
|
||||
setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8',
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||
suite.addTests(doctest.DocFileSuite(
|
||||
'scenario_move_cancel.rst',
|
||||
setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8',
|
||||
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
|
||||
return suite
|
||||
Reference in new issue
Block a user