diff --git a/addons/account/__init__.py b/addons/account/__init__.py index 799f6fe08a5..7ce59d3830d 100644 --- a/addons/account/__init__.py +++ b/addons/account/__init__.py @@ -25,6 +25,7 @@ import project import partner import invoice import account_bank_statement +import account_bank import account_cash_statement import account_move_line import account_analytic_line diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 6e6d1b79f99..67bdee9341e 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -23,6 +23,7 @@ "version" : "1.1", "author" : "OpenERP SA", "category": 'Finance', + 'complexity': "normal", "description": """ Accounting and Financial Management. ==================================== @@ -52,7 +53,7 @@ module named account_voucher. 'website': 'http://www.openerp.com', 'images' : ['images/accounts.jpeg','images/bank_statement.jpeg','images/cash_register.jpeg','images/chart_of_accounts.jpeg','images/customer_invoice.jpeg','images/journal_entries.jpeg'], 'init_xml': [], - "depends" : ["product", "analytic", "process","board", "email_template"], + "depends" : ["base_setup", "product", "analytic", "process","board", "email_template"], 'update_xml': [ 'security/account_security.xml', 'security/ir.model.access.csv', @@ -123,12 +124,14 @@ module named account_voucher. "wizard/account_report_profit_loss_view.xml", "wizard/account_report_balance_sheet_view.xml", "edi_invoice_action_data.xml", - ], + "account_bank_view.xml", + ], 'demo_xml': [ - 'account_demo.xml', + 'demo/account_demo.xml', 'project/project_demo.xml', 'project/analytic_account_demo.xml', 'demo/account_minimal.xml', + 'demo/account_invoice_demo.xml', # 'account_unit_test.xml', ], 'test': [ diff --git a/addons/account/account.py b/addons/account/account.py index f6dd36c01fc..0cee9291e97 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -368,16 +368,16 @@ class account_account(osv.osv): 'parent_id': fields.many2one('account.account', 'Parent', ondelete='cascade', domain=[('type','=','view')]), 'child_parent_ids': fields.one2many('account.account','parent_id','Children'), 'child_consol_ids': fields.many2many('account.account', 'account_account_consol_rel', 'child_id', 'parent_id', 'Consolidated Children'), - 'child_id': fields.function(_get_child_ids, method=True, type='many2many', relation="account.account", string="Child Accounts"), - 'balance': fields.function(__compute, digits_compute=dp.get_precision('Account'), method=True, string='Balance', multi='balance'), - 'credit': fields.function(__compute, digits_compute=dp.get_precision('Account'), method=True, string='Credit', multi='balance'), - 'debit': fields.function(__compute, digits_compute=dp.get_precision('Account'), method=True, string='Debit', multi='balance'), + 'child_id': fields.function(_get_child_ids, type='many2many', relation="account.account", string="Child Accounts"), + 'balance': fields.function(__compute, digits_compute=dp.get_precision('Account'), string='Balance', multi='balance'), + 'credit': fields.function(__compute, digits_compute=dp.get_precision('Account'), string='Credit', multi='balance'), + 'debit': fields.function(__compute, digits_compute=dp.get_precision('Account'), string='Debit', multi='balance'), 'reconcile': fields.boolean('Reconcile', help="Check this if the user is allowed to reconcile entries in this account."), 'shortcut': fields.char('Shortcut', size=12), 'tax_ids': fields.many2many('account.tax', 'account_account_tax_default_rel', 'account_id', 'tax_id', 'Default Taxes'), 'note': fields.text('Note'), - 'company_currency_id': fields.function(_get_company_currency, method=True, type='many2one', relation='res.currency', string='Company Currency'), + 'company_currency_id': fields.function(_get_company_currency, type='many2one', relation='res.currency', string='Company Currency'), 'company_id': fields.many2one('res.company', 'Company', required=True), 'active': fields.boolean('Active', select=2, help="If the active field is set to False, it will allow you to hide the account without removing it."), @@ -390,7 +390,7 @@ class account_account(osv.osv): 'manage this. So if you import from another software system you may have to use the rate at date. ' \ 'Incoming transactions always use the rate at date.', \ required=True), - 'level': fields.function(_get_level, string='Level', method=True, store=True, type='integer'), + 'level': fields.function(_get_level, string='Level', store=True, type='integer'), } _defaults = { @@ -587,7 +587,7 @@ class account_journal_column(osv.osv): _description = "Journal Column" _columns = { 'name': fields.char('Column Name', size=64, required=True), - 'field': fields.selection(_col_get, 'Field Name', method=True, required=True, size=32), + 'field': fields.selection(_col_get, 'Field Name', required=True, size=32), 'view_id': fields.many2one('account.journal.view', 'Journal View', select=True), 'sequence': fields.integer('Sequence', help="Gives the sequence order to journal column.", readonly=True), 'required': fields.boolean('Required'), @@ -602,7 +602,7 @@ class account_journal(osv.osv): _description = "Journal" _columns = { 'name': fields.char('Journal Name', size=64, required=True), - 'code': fields.char('Code', size=5, required=True, help="The code will be used to generate the numbers of the journal entries of this journal."), + 'code': fields.char('Code', size=5, required=True, help="The code will be displayed on reports."), 'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'), ('cash', 'Cash'), ('bank', 'Bank and Cheques'), ('general', 'General'), ('situation', 'Opening/Closing Situation')], 'Type', size=32, required=True, help="Select 'Sale' for Sale journal to be used at the time of making invoice."\ " Select 'Purchase' for Purchase Journal to be used at the time of approving purchase order."\ @@ -921,7 +921,7 @@ class account_period(osv.osv): #CHECKME: shouldn't we check the state of the period? ids = self.search(cr, uid, [('date_start','<=',dt),('date_stop','>=',dt)]) if not ids: - raise osv.except_osv(_('Error !'), _('No period defined for this date: %s !\nPlease create a fiscal year.')%dt) + raise osv.except_osv(_('Error !'), _('No period defined for this date: %s !\nPlease create one.')%dt) return ids def action_draft(self, cr, uid, ids, *args): @@ -985,7 +985,7 @@ class account_journal_period(osv.osv): 'name': fields.char('Journal-Period Name', size=64, required=True), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, ondelete="cascade"), 'period_id': fields.many2one('account.period', 'Period', required=True, ondelete="cascade"), - 'icon': fields.function(_icon_get, method=True, string='Icon', type='char', size=32), + 'icon': fields.function(_icon_get, string='Icon', type='char', size=32), 'active': fields.boolean('Active', required=True, help="If the active field is set to False, it will allow you to hide the journal period without removing it."), 'state': fields.selection([('draft','Draft'), ('printed','Printed'), ('done','Done')], 'State', required=True, readonly=True, help='When journal period is created. The state is \'Draft\'. If a report is printed it comes to \'Printed\' state. When all transactions are done, it comes in \'Done\' state.'), @@ -1139,9 +1139,9 @@ class account_move(osv.osv): 'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}), 'to_check': fields.boolean('To Review', help='Check this box if you are unsure of that journal entry and if you want to note it as \'to be reviewed\' by an accounting expert.'), 'partner_id': fields.related('line_id', 'partner_id', type="many2one", relation="res.partner", string="Partner", store=True), - 'amount': fields.function(_amount_compute, method=True, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount), + 'amount': fields.function(_amount_compute, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount), 'date': fields.date('Date', required=True, states={'posted':[('readonly',True)]}, select=True), - 'narration':fields.text('Narration'), + 'narration':fields.text('Internal Note'), 'company_id': fields.related('journal_id','company_id',type='many2one',relation='res.company',string='Company', store=True, readonly=True), } _defaults = { @@ -1331,6 +1331,7 @@ class account_move(osv.osv): def _centralise(self, cr, uid, move, mode, context=None): assert mode in ('debit', 'credit'), 'Invalid Mode' #to prevent sql injection + currency_obj = self.pool.get('res.currency') if context is None: context = {} @@ -1381,6 +1382,34 @@ class account_move(osv.osv): cr.execute('SELECT SUM(%s) FROM account_move_line WHERE move_id=%%s AND id!=%%s' % (mode,), (move.id, line_id2)) result = cr.fetchone()[0] or 0.0 cr.execute('update account_move_line set '+mode2+'=%s where id=%s', (result, line_id)) + + #adjust also the amount in currency if needed + cr.execute("select currency_id, sum(amount_currency) as amount_currency from account_move_line where move_id = %s and currency_id is not null group by currency_id", (move.id,)) + for row in cr.dictfetchall(): + currency_id = currency_obj.browse(cr, uid, row['currency_id'], context=context) + if not currency_obj.is_zero(cr, uid, currency_id, row['amount_currency']): + amount_currency = row['amount_currency'] * -1 + account_id = amount_currency > 0 and move.journal_id.default_debit_account_id.id or move.journal_id.default_credit_account_id.id + cr.execute('select id from account_move_line where move_id=%s and centralisation=\'currency\' and currency_id = %slimit 1', (move.id, row['currency_id'])) + res = cr.fetchone() + if res: + cr.execute('update account_move_line set amount_currency=%s , account_id=%s where id=%s', (amount_currency, account_id, res[0])) + else: + context.update({'journal_id': move.journal_id.id, 'period_id': move.period_id.id}) + line_id = self.pool.get('account.move.line').create(cr, uid, { + 'name': _('Currency Adjustment'), + 'centralisation': 'currency', + 'account_id': account_id, + 'move_id': move.id, + 'journal_id': move.journal_id.id, + 'period_id': move.period_id.id, + 'date': move.period_id.date_stop, + 'debit': 0.0, + 'credit': 0.0, + 'currency_id': row['currency_id'], + 'amount_currency': amount_currency, + }, context) + return True # @@ -1617,8 +1646,8 @@ class account_tax_code(osv.osv): 'name': fields.char('Tax Case Name', size=64, required=True, translate=True), 'code': fields.char('Case Code', size=64), 'info': fields.text('Description'), - 'sum': fields.function(_sum_year, method=True, string="Year Sum"), - 'sum_period': fields.function(_sum_period, method=True, string="Period Sum"), + 'sum': fields.function(_sum_year, string="Year Sum"), + 'sum_period': fields.function(_sum_period, string="Period Sum"), 'parent_id': fields.many2one('account.tax.code', 'Parent Code', select=True), 'child_ids': fields.one2many('account.tax.code', 'parent_id', 'Child Codes'), 'line_ids': fields.one2many('account.move.line', 'tax_code_id', 'Lines'), @@ -2473,7 +2502,7 @@ class account_tax_template(osv.osv): 'name': fields.char('Tax Name', size=64, required=True), 'sequence': fields.integer('Sequence', required=True, help="The sequence field is used to order the taxes lines from lower sequences to higher ones. The order is important if you have a tax that has several tax children. In this case, the evaluation order is important."), 'amount': fields.float('Amount', required=True, digits=(14,4), help="For Tax Type percent enter % ratio between 0-1."), - 'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code')], 'Tax Type', required=True), + 'type': fields.selection( [('percent','Percent'), ('fixed','Fixed'), ('none','None'), ('code','Python Code'), ('balance','Balance')], 'Tax Type', required=True), 'applicable_type': fields.selection( [('true','True'), ('code','Python Code')], 'Applicable Type', required=True, help="If not applicable (computed through a Python code), the tax won't appear on the invoice."), 'domain':fields.char('Domain', size=32, help="This field is only used if you develop your own module allowing developers to create specific taxes in a custom domain."), 'account_collected_id':fields.many2one('account.account.template', 'Invoice Tax Account'), @@ -2646,9 +2675,10 @@ class wizard_multi_charts_accounts(osv.osv_memory): return False def _get_default_accounts(self, cr, uid, context=None): - return [{'acc_name': _('Current'),'account_type':'bank'}, - {'acc_name': _('Deposit'),'account_type':'bank'}, - {'acc_name': _('Cash'),'account_type':'cash'}] + return [ + {'acc_name': _('Bank Account'),'account_type':'bank'}, + {'acc_name': _('Cash'),'account_type':'cash'} + ] _defaults = { 'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, [uid], c)[0].company_id.id, diff --git a/addons/account/account_bank.py b/addons/account/account_bank.py new file mode 100644 index 00000000000..a3d66ccdf7c --- /dev/null +++ b/addons/account/account_bank.py @@ -0,0 +1,103 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2010 Tiny SPRL (). +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from tools.translate import _ +from osv import fields, osv + +class bank(osv.osv): + _inherit = "res.partner.bank" + _columns = { + 'journal_id': fields.many2one('account.journal', 'Account Journal', help="This journal will be created automatically for this bank account when you save the record"), + } + def create(self, cr, uid, data, context={}): + result = super(bank, self).create(cr, uid, data, context=context) + self.post_write(cr, uid, [result], context=context) + return result + + def write(self, cr, uid, ids, data, context={}): + result = super(bank, self).write(cr, uid, ids, data, context=context) + self.post_write(cr, uid, ids, context=context) + return result + + def post_write(self, cr, uid, ids, context={}): + obj_acc = self.pool.get('account.account') + obj_data = self.pool.get('ir.model.data') + for bank in self.browse(cr, uid, ids, context): + if bank.company_id and not bank.journal_id: + # Find the code and parent of the bank account to create + dig = 6 + current_num = 1 + ids = obj_acc.search(cr, uid, [('type','=','liquidity')], context=context) + # No liquidity account exists, no template available + if not ids: continue + + ref_acc_bank_temp = obj_acc.browse(cr, uid, ids[0], context=context) + ref_acc_bank = ref_acc_bank_temp.parent_id + while True: + new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)), '0')) + str(current_num) + ids = obj_acc.search(cr, uid, [('code', '=', new_code), ('company_id', '=', bank.company_id.id)]) + if not ids: + break + current_num += 1 + + acc = { + 'name': (bank.bank_name or '')+' '+bank.acc_number, + 'currency_id': bank.company_id.currency_id.id, + 'code': new_code, + 'type': 'liquidity', + 'user_type': ref_acc_bank_temp.user_type.id, + 'reconcile': False, + 'parent_id': ref_acc_bank.id, + 'company_id': bank.company_id.id, + } + acc_bank_id = obj_acc.create(cr,uid,acc,context=context) + + # Get the journal view id + data_id = obj_data.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view')]) + data = obj_data.browse(cr, uid, data_id[0], context=context) + view_id_cash = data.res_id + + jour_obj = self.pool.get('account.journal') + new_code = 1 + while True: + code = _('BNK')+str(new_code) + ids = jour_obj.search(cr, uid, [('code','=',code)], context=context) + if not ids: + break + new_code += 1 + + #create the bank journal + vals_journal = { + 'name': (bank.bank_name or '')+' '+bank.acc_number, + 'code': code, + 'type': 'bank', + 'company_id': bank.company_id.id, + 'analytic_journal_id': False, + 'currency_id': False, + 'default_credit_account_id': acc_bank_id, + 'default_debit_account_id': acc_bank_id, + 'view_id': view_id_cash + } + journal_id = jour_obj.create(cr, uid, vals_journal, context=context) + + self.write(cr, uid, [bank.id], {'journal_id': journal_id}, context=context) + return True + diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 54776e5c7e6..f712cc9ab0c 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -137,7 +137,7 @@ class account_bank_statement(osv.osv): states={'confirm':[('readonly',True)]}), 'balance_end_real': fields.float('Ending Balance', digits_compute=dp.get_precision('Account'), states={'confirm':[('readonly', True)]}), - 'balance_end': fields.function(_end_balance, method=True, string='Balance'), + 'balance_end': fields.function(_end_balance, string='Balance'), 'company_id': fields.related('journal_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True), 'line_ids': fields.one2many('account.bank.statement.line', 'statement_id', 'Statement lines', @@ -149,7 +149,7 @@ class account_bank_statement(osv.osv): states={'confirm': [('readonly', True)]}, readonly="1", help='When new statement is created the state will be \'Draft\'. \ \n* And after getting confirmation from the bank it will be in \'Confirmed\' state.'), - 'currency': fields.function(_currency, method=True, string='Currency', + 'currency': fields.function(_currency, string='Currency', type='many2one', relation='res.currency'), 'account_id': fields.related('journal_id', 'default_debit_account_id', type='many2one', relation='account.account', string='Account used in this journal', readonly=True, help='used in statement reconciliation domain, but shouldn\'t be used elswhere.'), } diff --git a/addons/account/account_bank_view.xml b/addons/account/account_bank_view.xml new file mode 100644 index 00000000000..d91739817ac --- /dev/null +++ b/addons/account/account_bank_view.xml @@ -0,0 +1,48 @@ + + + + + + + + Partner Bank Accounts - Journal + res.partner.bank + form + + + + + + + + + + + + + + Bank Accounts + res.partner.bank + form + tree,form + + Configure your company's bank account and select those that must appear on the report footer. You can drag & drop bank in the list view to reorder bank accounts. If you use the accounting application of OpenERP, journals and accounts will be created automatically based on these data. + + + + + + + + 4 + + + + + diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py index 04e780ade30..982383ea2a7 100644 --- a/addons/account/account_cash_statement.py +++ b/addons/account/account_cash_statement.py @@ -58,7 +58,7 @@ class account_cashbox_line(osv.osv): _columns = { 'pieces': fields.float('Values', digits_compute=dp.get_precision('Account')), 'number': fields.integer('Number'), - 'subtotal': fields.function(_sub_total, method=True, string='Sub Total', type='float', digits_compute=dp.get_precision('Account')), + 'subtotal': fields.function(_sub_total, string='Sub Total', type='float', digits_compute=dp.get_precision('Account')), 'starting_id': fields.many2one('account.bank.statement', ondelete='cascade'), 'ending_id': fields.many2one('account.bank.statement', ondelete='cascade'), } @@ -223,10 +223,10 @@ class account_cash_statement(osv.osv): [('draft', 'Draft'), ('confirm', 'Closed'), ('open','Open')], 'State', required=True, states={'confirm': [('readonly', True)]}, readonly="1"), - 'total_entry_encoding': fields.function(_get_sum_entry_encoding, method=True, store=True, string="Cash Transaction", help="Total cash transactions"), + 'total_entry_encoding': fields.function(_get_sum_entry_encoding, store=True, string="Cash Transaction", help="Total cash transactions"), 'closing_date': fields.datetime("Closed On"), - 'balance_end': fields.function(_end_balance, method=True, store=True, string='Balance', help="Closing balance based on Starting Balance and Cash Transactions"), - 'balance_end_cash': fields.function(_balance_end_cash, method=True, store=True, string='Balance', help="Closing balance based on cashBox"), + 'balance_end': fields.function(_end_balance, store=True, string='Balance', help="Closing balance based on Starting Balance and Cash Transactions"), + 'balance_end_cash': fields.function(_balance_end_cash, store=True, string='Balance', help="Closing balance based on cashBox"), 'starting_details_ids': fields.one2many('account.cashbox.line', 'starting_id', string='Opening Cashbox'), 'ending_details_ids': fields.one2many('account.cashbox.line', 'ending_id', string='Closing Cashbox'), 'name': fields.char('Name', size=64, required=True, states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), diff --git a/addons/account/account_installer.xml b/addons/account/account_installer.xml index 609dd8a6c5e..151f7bbc0f0 100644 --- a/addons/account/account_installer.xml +++ b/addons/account/account_installer.xml @@ -19,9 +19,9 @@ Configure - - 23 - + + 23 + @@ -45,35 +45,20 @@ account.installer.modules.form - account.installer.modules + base.setup.installer form - + -
- Accounting Application Configuration -
- - Configure Your Accounting Application - - - - Add extra Accounting functionalities to the ones already installed. + + + + + + + + - - Configure - - - - - - - - - - - -
@@ -88,27 +73,16 @@ new - - Accounting Application Configuration - ir.actions.act_window - account.installer.modules - - form - form - new - + + Accounting + 5 + + 3 - onskip - - - - - 5 - always - + automatic diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index ed45c705674..b21d3e9604f 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -53,8 +53,8 @@
- - + + @@ -175,7 +175,7 @@ - + @@ -203,7 +203,7 @@ -