Add company on statement for issue1904

This commit is contained in:
Cédric Krier committed 2011-04-10 20:59:25 +02:00
1 parent f906f2f2bb
commit a3855e6666
5 files changed
+379 -39

No files matched your search

+2
View File
@@ -1,3 +1,5 @@
* Add company on statement
Version 1.8.0 - 2010-11-01
* Bug fixes (see mercurial logs for details)
+76 -37
View File
@@ -2,8 +2,9 @@
#this repository contains the full copyright notices and license terms.
from decimal import Decimal
from trytond.model import ModelWorkflow, ModelView, ModelSQL, fields
from trytond.pyson import Not, Equal, Eval, Or, Bool, Get, If
from trytond.pyson import Not, Equal, Eval, Or, Bool, Get, If, In
from trytond.transaction import Transaction
from trytond.backend import TableHandler
_STATES = {'readonly': Not(Equal(Eval('state'), 'draft'))}
@@ -13,13 +14,21 @@ class Statement(ModelWorkflow, ModelSQL, ModelView):
_name = 'account.statement'
_description = __doc__
company = fields.Many2One('company.company', 'Company', required=True,
select=1, states=_STATES, domain=[
('id', If(In('company', Eval('context', {})), '=', '!='),
Get(Eval('context', {}), 'company', 0)),
])
journal = fields.Many2One('account.statement.journal', 'Journal', required=True,
states={
'readonly': Or(Not(Equal(Eval('state'), 'draft')),
Bool(Eval('lines'))),
}, on_change=['journal'], select=1)
domain=[
('company', '=', Eval('company')),
],
states={
'readonly': Or(Not(Equal(Eval('state'), 'draft')),
Bool(Eval('lines'))),
}, on_change=['journal'], select=1)
currency_digits = fields.Function(fields.Integer('Currency Digits',
on_change_with=['journal']), 'get_currency_digits')
on_change_with=['company']), 'get_currency_digits')
date = fields.Date('Date', required=True, states=_STATES, select=1)
start_balance = fields.Numeric('Start Balance',
digits=(16, Eval('currency_digits', 2)),
@@ -30,8 +39,8 @@ class Statement(ModelWorkflow, ModelSQL, ModelView):
lines = fields.One2Many('account.statement.line', 'statement',
'Transactions', states={
'readonly': Or(Not(Equal(Eval('state'), 'draft')),
Not(Bool(Eval('journal')))),
}, on_change=['lines', 'journal'])
Not(Bool(Eval('company')))),
}, on_change=['lines', 'company'])
state = fields.Selection([
('draft', 'Draft'),
('validated', 'Validated'),
@@ -51,6 +60,33 @@ class Statement(ModelWorkflow, ModelSQL, ModelView):
'wrong_end_balance': 'End Balance must be %s!',
})
def init(self, module_name):
cursor = Transaction().cursor
# Migration from 1.8: new field company
table = TableHandler(cursor, self, module_name)
company_exist = table.column_exist('company')
super(Statement, self).init(module_name)
# Migration from 1.8: fill new field company
if not company_exist:
offset = 0
limit = cursor.IN_MAX
statement_ids = True
while statement_ids:
statement_ids = self.search([], offset=offset, limit=limit)
offset += limit
for statement in self.browse(statement_ids):
self.write(statement.id, {
'company': statement.journal.company.id,
})
table = TableHandler(cursor, self, module_name)
table.not_null_action('company', action='add')
def default_company(self):
return Transaction().context.get('company') or False
def default_state(self):
return 'draft'
@@ -83,16 +119,16 @@ class Statement(ModelWorkflow, ModelSQL, ModelView):
return res
def on_change_with_currency_digits(self, vals):
journal_obj = self.pool.get('account.statement.journal')
if vals.get('journal'):
journal = journal_obj.browse(vals['journal'])
return journal.currency.digits
company_obj = self.pool.get('company.company')
if vals.get('company'):
company = company_obj.browse(vals['company'])
return company.currency.digits
return 2
def get_currency_digits(self, ids, name):
res = {}
for statement in self.browse(ids):
res[statement.id] = statement.journal.currency.digits
res[statement.id] = statement.company.currency.digits
return res
def get_rec_name(self, ids, name):
@@ -113,10 +149,10 @@ class Statement(ModelWorkflow, ModelSQL, ModelView):
for statement in self.browse(ids):
res[statement.id] = statement.journal.name + ' ' + \
lang.currency(lang, statement.start_balance,
statement.journal.currency, symbol=False,
statement.company.currency, symbol=False,
grouping=True) + \
lang.currency(lang, statement.end_balance,
statement.journal.currency, symbol=False,
statement.company.currency, symbol=False,
grouping=True)
return res
@@ -154,13 +190,13 @@ class Statement(ModelWorkflow, ModelSQL, ModelView):
def on_change_lines(self, values):
invoice_obj = self.pool.get('account.invoice')
journal_obj = self.pool.get('account.statement.journal')
company_obj = self.pool.get('company.company')
currency_obj = self.pool.get('currency.currency')
res = {
'lines': {},
}
if values.get('journal') and values.get('lines'):
journal = journal_obj.browse(values['journal'])
if values.get('company') and values.get('lines'):
company = company_obj.browse(values['company'])
invoice_ids = set()
for line in values['lines']:
if line['invoice']:
@@ -169,14 +205,14 @@ class Statement(ModelWorkflow, ModelSQL, ModelView):
for invoice in invoice_obj.browse(invoice_ids):
invoice_id2amount_to_pay[invoice.id] = currency_obj.compute(
invoice.currency, invoice.amount_to_pay,
journal.currency)
company.currency)
for line in values['lines']:
if line['invoice'] and line['id']:
amount_to_pay = invoice_id2amount_to_pay[line['invoice']]
if abs(line['amount']) > amount_to_pay:
res['lines'].setdefault('update', [])
if currency_obj.is_zero(journal.currency,
if currency_obj.is_zero(company.currency,
amount_to_pay):
res['lines']['update'].append({
'id': line['id'],
@@ -218,7 +254,7 @@ class Statement(ModelWorkflow, ModelSQL, ModelView):
lang = lang_obj.browse(lang_ids[0])
amount = lang_obj.format(lang,
'%.' + str(statement.journal.currency.digits) + 'f',
'%.' + str(statement.company.currency.digits) + 'f',
computed_end_balance, True)
self.raise_user_error('wrong_end_balance', error_args=(amount,))
for line in statement.lines:
@@ -267,11 +303,14 @@ class Line(ModelSQL, ModelView):
digits=(16, Get(Eval('_parent_statement', {}),
'currency_digits', 2)),
on_change=['amount', 'party', 'account', 'invoice',
'_parent_statement.journal'])
'_parent_statement.company'])
party = fields.Many2One('party.party', 'Party',
on_change=['amount', 'party', 'invoice'])
account = fields.Many2One('account.account', 'Account', required=True,
on_change=['account', 'invoice'], domain=[('kind', '!=', 'view')])
on_change=['account', 'invoice'], domain=[
('kind', '!=', 'view'),
('company', '=', Get(Eval('_parent_statement', {}), 'company')),
])
description = fields.Char('Description')
move = fields.Many2One('account.move', 'Account Move', readonly=True)
invoice = fields.Many2One('account.invoice', 'Invoice',
@@ -323,7 +362,7 @@ class Line(ModelSQL, ModelView):
def on_change_amount(self, value):
party_obj = self.pool.get('party.party')
invoice_obj = self.pool.get('account.invoice')
journal_obj = self.pool.get('account.statement.journal')
company_obj = self.pool.get('company.company')
currency_obj = self.pool.get('currency.currency')
res = {}
@@ -341,11 +380,11 @@ class Line(ModelSQL, ModelView):
res['account'] = account.id
res['account.rec_name'] = account.rec_name
if value.get('invoice'):
if value.get('amount') and value.get('_parent_statement.journal'):
if value.get('amount') and value.get('_parent_statement.company'):
invoice = invoice_obj.browse(value['invoice'])
journal = journal_obj.browse(value['_parent_statement.journal'])
company = company_obj.browse(value['_parent_statement.company'])
amount_to_pay = currency_obj.compute(invoice.currency,
invoice.amount_to_pay, journal.currency)
invoice.amount_to_pay, company.currency)
if abs(value['amount']) > amount_to_pay:
res['invoice'] = False
else:
@@ -379,7 +418,7 @@ class Line(ModelSQL, ModelView):
move_line_obj = self.pool.get('account.move.line')
lang_obj = self.pool.get('ir.lang')
period_id = period_obj.find(line.statement.journal.company.id,
period_id = period_obj.find(line.statement.company.id,
date=line.date)
move_lines = self._get_move_lines(line)
@@ -398,7 +437,7 @@ class Line(ModelSQL, ModelView):
if line.invoice:
amount_to_pay = currency_obj.compute(line.invoice.currency,
line.invoice.amount_to_pay, line.statement.journal.currency)
line.invoice.amount_to_pay, line.statement.company.currency)
if amount_to_pay < abs(line.amount):
for code in [Transaction().language, 'en_US']:
lang_ids = lang_obj.search([
@@ -409,13 +448,13 @@ class Line(ModelSQL, ModelView):
lang = lang_obj.browse(lang_ids[0])
amount = lang_obj.format(lang,
'%.' + str(line.statement.journal.currency.digits) + 'f',
'%.' + str(line.statement.company.currency.digits) + 'f',
line.amount, True)
self.raise_user_error('amount_greater_invoice_amount_to_pay',
error_args=(amount,))
amount = currency_obj.compute(line.statement.journal.currency,
line.amount, line.statement.journal.company.currency)
amount = currency_obj.compute(line.statement.company.currency,
line.amount, line.statement.company.currency)
reconcile_lines = invoice_obj.get_reconcile_lines_for_amount(
line.invoice, abs(amount))
@@ -452,11 +491,11 @@ class Line(ModelSQL, ModelView):
currency_obj = self.pool.get('currency.currency')
zero = Decimal("0.0")
amount = currency_obj.compute(
statement_line.statement.journal.currency, statement_line.amount,
statement_line.statement.journal.company.currency)
if statement_line.statement.journal.currency.id != \
statement_line.statement.journal.company.currency.id:
second_currency = statement_line.statement.journal.currency.id
statement_line.statement.company.currency, statement_line.amount,
statement_line.statement.company.currency)
if statement_line.statement.company.currency.id != \
statement_line.statement.company.currency.id:
second_currency = statement_line.statement.company.currency.id
amount_second_currency = abs(statement_line.amount)
else:
amount_second_currency = False
+15 -2
View File
@@ -50,8 +50,10 @@ this repository contains the full copyright notices and license terms. -->
states="{'invisible': Not(Equal(Eval('state'), 'cancel'))}"/>
</group>
</page>
<page string="Move Lines" col="1" id="move_lines">
<field name="move_lines"/>
<page string="Other Info" id="info">
<label name="company"/>
<field name="company"/>
<field name="move_lines" colspan="4"/>
</page>
</notebook>
<field name="currency_digits" colspan="4" invisible="1"/>
@@ -163,6 +165,17 @@ this repository contains the full copyright notices and license terms. -->
<menuitem parent="menu_statements" sequence="5"
action="act_statement_form" id="menu_statement_form"/>
<record model="ir.rule.group" id="rule_group_statement">
<field name="model" search="[('model', '=', 'account.statement')]"/>
<field name="global_p" eval="True"/>
</record>
<record model="ir.rule" id="rule_statement1">
<field name="field" search="[('name', '=', 'company'), ('model.model', '=', 'account.statement')]"/>
<field name="operator">=</field>
<field name="operand">User/Current Company</field>
<field name="rule_group" ref="rule_group_statement"/>
</record>
<record model="ir.ui.view" id="statement_line_view_form">
<field name="model">account.statement.line</field>
<field name="type">form</field>
+271
View File
@@ -0,0 +1,271 @@
==========================
Account Statement 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()
Install account_statement and account_invoice::
>>> Module = Model.get('ir.module.module')
>>> modules = Module.find([
... ('name', 'in', ('account_statement', 'account_invoice')),
... ])
>>> Module.button_install([x.id for x in modules], config.context)
>>> Wizard('ir.module.module.install_upgrade').execute('start')
Create company::
>>> Currency = Model.get('currency.currency')
>>> CurrencyRate = Model.get('currency.currency.rate')
>>> Company = Model.get('company.company')
>>> company_config = Wizard('company.company.config')
>>> company_config.execute('company')
>>> company = company_config.form
>>> company.name = 'B2CK'
>>> currencies = Currency.find([('code', '=', 'EUR')])
>>> if not currencies:
... currency = Currency(name='Euro', symbol=u'€', code='EUR',
... rounding=Decimal('0.01'), mon_grouping='[3, 3, 0]',
... mon_decimal_point=',')
... 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
>>> invoice_sequence = SequenceStrict(name='%s' % today.year,
... code='account.invoice',
... company=company)
>>> invoice_sequence.save()
>>> fiscalyear.out_invoice_sequence = invoice_sequence
>>> fiscalyear.in_invoice_sequence = invoice_sequence
>>> fiscalyear.out_credit_note_sequence = invoice_sequence
>>> fiscalyear.in_credit_note_sequence = invoice_sequence
>>> fiscalyear.save()
>>> FiscalYear.create_period([fiscalyear.id], config.context)
True
Create chart of accounts::
>>> AccountTemplate = Model.get('account.account.template')
>>> Account = Model.get('account.account')
>>> AccountJournal = Model.get('account.journal')
>>> account_template, = AccountTemplate.find([('parent', '=', False)])
>>> create_chart_account = Wizard('account.account.create_chart_account')
>>> create_chart_account.execute('account')
>>> create_chart_account.form.account_template = account_template
>>> create_chart_account.form.company = company
>>> create_chart_account.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),
... ])
>>> expense, = Account.find([
... ('kind', '=', 'expense'),
... ('company', '=', company.id),
... ])
>>> cash, = Account.find([
... ('name', '=', 'Main Cash'),
... ('company', '=', company.id),
... ])
>>> create_chart_account.form.account_receivable = receivable
>>> create_chart_account.form.account_payable = payable
>>> create_chart_account.execute('create_properties')
Create parties::
>>> Party = Model.get('party.party')
>>> supplier = Party(name='Supplier')
>>> supplier.save()
>>> customer = Party(name='Customer')
>>> customer.save()
Create payment term::
>>> PaymentTerm = Model.get('account.invoice.payment_term')
>>> PaymentTermLine = Model.get('account.invoice.payment_term.line')
>>> payment_term = PaymentTerm(name='Direct')
>>> payment_term_line = PaymentTermLine(type='remainder')
>>> payment_term.lines.append(payment_term_line)
>>> payment_term.save()
Create 2 customer invoices::
>>> Invoice = Model.get('account.invoice')
>>> InvoiceLine = Model.get('account.invoice.line')
>>> customer_invoice1 = Invoice(type='out_invoice')
>>> customer_invoice1.party = customer
>>> customer_invoice1.payment_term = payment_term
>>> invoice_line = InvoiceLine()
>>> customer_invoice1.lines.append(invoice_line)
>>> invoice_line.quantity = 1
>>> invoice_line.unit_price = Decimal('100')
>>> invoice_line.account = revenue
>>> invoice_line.description = 'Test'
>>> customer_invoice1.save()
>>> Invoice.workflow_trigger_validate(customer_invoice1.id, 'open',
... config.context)
>>> customer_invoice1.state
u'open'
>>> customer_invoice2 = Invoice(type='out_invoice')
>>> customer_invoice2.party = customer
>>> customer_invoice2.payment_term = payment_term
>>> invoice_line = InvoiceLine()
>>> customer_invoice2.lines.append(invoice_line)
>>> invoice_line.quantity = 1
>>> invoice_line.unit_price = Decimal('150')
>>> invoice_line.account = revenue
>>> invoice_line.description = 'Test'
>>> customer_invoice2.save()
>>> Invoice.workflow_trigger_validate(customer_invoice2.id, 'open',
... config.context)
>>> customer_invoice2.state
u'open'
Create 1 supplier invoices::
>>> supplier_invoice = Invoice(type='in_invoice')
>>> supplier_invoice.party = supplier
>>> supplier_invoice.payment_term = payment_term
>>> invoice_line = InvoiceLine()
>>> supplier_invoice.lines.append(invoice_line)
>>> invoice_line.quantity = 1
>>> invoice_line.unit_price = Decimal('50')
>>> invoice_line.account = expense
>>> invoice_line.description = 'Test'
>>> supplier_invoice.save()
>>> Invoice.workflow_trigger_validate(supplier_invoice.id, 'open',
... config.context)
>>> supplier_invoice.state
u'open'
Create statement::
>>> StatementJournal = Model.get('account.statement.journal')
>>> Statement = Model.get('account.statement')
>>> StatementLine = Model.get('account.statement.line')
>>> sequence = Sequence(name='Satement',
... code='account.journal',
... company=company,
... )
>>> sequence.save()
>>> account_journal = AccountJournal(name='Statement',
... type='statement',
... credit_account=cash,
... debit_account=cash,
... sequence=sequence,
... )
>>> account_journal.save()
>>> statement_journal = StatementJournal(name='Test',
... journal=account_journal,
... )
>>> statement_journal.save()
>>> statement = Statement(journal=statement_journal,
... start_balance=Decimal('0'),
... end_balance=Decimal('130'),
... )
Received 180 from customer::
>>> statement_line = StatementLine()
>>> statement.lines.append(statement_line)
>>> statement_line.date = today
>>> statement_line.amount = Decimal('180')
>>> statement_line.party = customer
>>> statement_line.account == receivable
True
>>> statement_line.invoice = customer_invoice1
>>> statement_line.amount == Decimal('100')
True
>>> statement_line = statement.lines[-1]
>>> statement_line.amount == Decimal('80')
True
>>> statement_line.party == customer
True
>>> statement_line.account == receivable
True
>>> statement_line.invoice = customer_invoice2
>>> statement_line.amount == Decimal('80')
True
Paid 50 to supplier::
>>> statement_line = StatementLine()
>>> statement.lines.append(statement_line)
>>> statement_line.date = today
>>> statement_line.amount = Decimal('-50')
>>> statement_line.party = supplier
>>> statement_line.account == payable
True
>>> statement_line.invoice = supplier_invoice
>>> statement.save()
Validate statement::
>>> Statement.workflow_trigger_validate(statement.id, 'validated',
... config.context)
>>> statement.state
u'validated'
Test invoice state::
>>> customer_invoice1.reload()
>>> customer_invoice1.state
u'paid'
>>> customer_invoice2.reload()
>>> customer_invoice2.state
u'open'
>>> customer_invoice2.amount_to_pay == Decimal('70')
True
>>> supplier_invoice.reload()
>>> supplier_invoice.state
u'paid'
+15
View File
@@ -9,6 +9,7 @@ if os.path.isdir(DIR):
sys.path.insert(0, os.path.dirname(DIR))
import unittest
import doctest
import trytond.tests.test_tryton
from trytond.tests.test_tryton import test_view
@@ -27,10 +28,24 @@ class AccountStatementTestCase(unittest.TestCase):
'''
test_view('account_statement')
def doctest_dropdb(test):
'''
Remove sqlite memory database
'''
database = SQLiteDatabase().connect()
cursor = database.cursor(autocommit=True)
try:
database.drop(cursor, ':memory:')
cursor.commit()
finally:
cursor.close()
def suite():
suite = trytond.tests.test_tryton.suite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(
AccountStatementTestCase))
suite.addTests(doctest.DocFileSuite('scenario_account_statement.rst',
setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8'))
return suite
if __name__ == '__main__':