diff --git a/addons/account/__init__.py b/addons/account/__init__.py index da397978bd2..0608bb83c88 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_cash_statement import account_move_line import account_analytic_line import wizard @@ -33,4 +34,4 @@ import product import sequence import company -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 39e40555f39..04f55566d40 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -18,8 +18,6 @@ # along with this program. If not, see . # ############################################################################## - - { "name" : "Accounting and Financial Management", "version" : "1.1", @@ -119,6 +117,8 @@ module named account_vouchers 'report/account_account_report_view.xml', 'report/account_analytic_entries_report_view.xml', 'board_account_view.xml', + "wizard/account_pl_report_view.xml", + "wizard/account_bs_report_view.xml" ], 'demo_xml': [ #'demo/price_accuracy00.yml', @@ -145,4 +145,4 @@ module named account_vouchers 'active': False, 'certificate': '0080331923549', } -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/account/account.py b/addons/account/account.py index 06060f59e28..0abdd2af7e0 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -584,6 +584,9 @@ class account_journal_column(osv.osv): result = [] cols = self.pool.get('account.move.line')._columns for col in cols: + if col in ('period_id', 'journal_id'): + continue + result.append( (col, cols[col].string) ) result.sort() return result @@ -657,11 +660,9 @@ class account_journal(osv.osv): # }) return journal_id - def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100): + def name_search(self, cr, user, name, args=None, operator='ilike', context={}, limit=100): if not args: args = [] - if context is None: - context = {} ids = [] if name: ids = self.search(cr, user, [('code','ilike',name)]+ args, limit=limit, context=context) @@ -832,7 +833,7 @@ class account_period(osv.osv): cr.execute('update account_period set state=%s where id=%s', (mode, id)) return True - def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80): + def name_search(self, cr, user, name, args=None, operator='ilike', context={}, limit=80): if args is None: args = [] if context is None: @@ -844,7 +845,7 @@ class account_period(osv.osv): ids = self.search(cr, user, [('name',operator,name)]+ args, limit=limit) return self.name_get(cr, user, ids, context=context) - def write(self, cr, uid, ids, vals, context=None): + def write(self, cr, uid, ids, vals, context={}): obj=[] if 'company_id' in vals: move_lines = self.pool.get('account.move.line').search(cr, uid, [('period_id', 'in', ids)]) @@ -1143,6 +1144,7 @@ class account_move(osv.osv): return amount def _centralise(self, cr, uid, move, mode, context=None): + assert(mode in ('debit', 'credit'), 'Invalid Mode') #to prevent sql injection if context is None: context = {} @@ -1190,10 +1192,7 @@ class account_move(osv.osv): else: line_id2 = 0 - cr.execute('SELECT SUM(%s) '\ - 'FROM account_move_line '\ - 'WHERE move_id=%s AND id<>%s', - (mode, move.id, line_id2)) + 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)) return True diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 6de3dabaa28..572cb9d04fd 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -45,7 +45,7 @@ class account_bank_statement(osv.osv): 'type': 'ir.actions.act_window', 'target': 'new', 'nodestroy': True - } + } def _default_journal_id(self, cr, uid, context={}): if context.get('journal_id', False): @@ -303,6 +303,13 @@ class account_bank_statement(osv.osv): _('Ledger Posting line "%s" is not valid') % line.name) if move.reconcile_id and move.reconcile_id.line_ids: + ## Search if move has already a partial reconciliation + previous_partial = False + for line_reconcile_move in move.reconcile_id.line_ids: + if line_reconcile_move.reconcile_partial_id: + previous_partial = True + break + ## torec += map(lambda x: x.id, move.reconcile_id.line_ids) #try: if abs(move.reconcile_amount-move.amount)<0.0001: @@ -312,8 +319,14 @@ class account_bank_statement(osv.osv): for entry in move.reconcile_id.line_new_ids: writeoff_acc_id = entry.account_id.id break - - account_move_line_obj.reconcile(cr, uid, torec, 'statement', writeoff_acc_id=writeoff_acc_id, writeoff_period_id=st.period_id.id, writeoff_journal_id=st.journal_id.id, context=context) + ## If we have already a partial reconciliation + ## We need to make a partial reconciliation + ## To add this amount to previous paid amount + if previous_partial: + account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context) + ## If it's the first reconciliation, we do a full reconciliation as regular + else: + account_move_line_obj.reconcile(cr, uid, torec, 'statement', writeoff_acc_id=writeoff_acc_id, writeoff_period_id=st.period_id.id, writeoff_journal_id=st.journal_id.id, context=context) else: account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context) #except: @@ -556,9 +569,9 @@ account_bank_statement_reconcile_line() class account_bank_statement_line(osv.osv): - def onchange_partner_id(self, cursor, user, line_id, partner_id, type, currency_id, - context={}): + def onchange_partner_id(self, cursor, user, line_id, partner_id, type, currency_id, context={}): res = {'value': {}} + if not partner_id: return res line = self.browse(cursor, user, line_id) @@ -591,6 +604,10 @@ class account_bank_statement_line(osv.osv): balance = res_currency_obj.compute(cursor, user, company_currency_id, currency_id, balance, context=context) res['value']['amount'] = balance + + if context.get('amount', 0) > 0: + res['value']['amount'] = context.get('amount') + return res def _reconcile_amount(self, cursor, user, ids, name, args, context=None): diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py new file mode 100644 index 00000000000..eea57359099 --- /dev/null +++ b/addons/account/account_cash_statement.py @@ -0,0 +1,448 @@ +# encoding: utf-8 +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2008 PC Solutions (). All Rights Reserved +# $Id$ +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +############################################################################## + +from osv import osv, fields +import time +from mx import DateTime +from decimal import Decimal +from tools.translate import _ + +class singer_statement(osv.osv): + + """ Singer Statements """ + + _name = 'singer.statement' + _description = 'Statement' + + def _sub_total(self, cr, uid, ids, name, arg, context=None): + + """ Calculates Sub total" + @param name: Names of fields. + @param arg: User defined arguments + @return: Dictionary of values. + """ + res = {} + for obj in self.browse(cr, uid, ids): + res[obj.id] = obj.pieces * obj.number + return res + + def on_change_sub(self, cr, uid, ids, pieces, number,*a): + + """ Calculates Sub total on change of number + @param pieces: Names of fields. + @param number: + """ + sub=pieces*number + return {'value':{'subtotal': sub or 0.0}} + + _columns = { + 'pieces': fields.float('Values', digits=(16,2)), + 'number': fields.integer('Number'), + 'subtotal': fields.function(_sub_total, method=True, string='Sub Total', type='float',digits=(16,2)), + 'starting_id': fields.many2one('account.bank.statement',ondelete='cascade'), + 'ending_id': fields.many2one('account.bank.statement',ondelete='cascade'), + } +singer_statement() + +class account_cash_statement(osv.osv): + + _inherit = 'account.bank.statement' + + def _get_starting_balance(self, cr, uid, ids, name, arg, context=None): + + """ Find starting balance " + @param name: Names of fields. + @param arg: User defined arguments + @return: Dictionary of values. + """ + res ={} + for statement in self.browse(cr, uid, ids): + amount_total=0.0 + for line in statement.starting_details_ids: + amount_total+= line.pieces * line.number + res[statement.id]=amount_total + return res + + def _balance_end_cash(self, cr, uid, ids, name, arg, context=None): + """ Find ending balance " + @param name: Names of fields. + @param arg: User defined arguments + @return: Dictionary of values. + """ + res ={} + for statement in self.browse(cr, uid, ids): + amount_total=0.0 + for line in statement.ending_details_ids: + amount_total+= line.pieces * line.number + res[statement.id]=amount_total + return res + + def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None): + + """ Find encoding total of statements " + @param name: Names of fields. + @param arg: User defined arguments + @return: Dictionary of values. + """ + res2={} + for statement in self.browse(cr, uid, ids): + encoding_total=0.0 + for line in statement.line_ids: + encoding_total+= line.amount + res2[statement.id]=encoding_total + return res2 + + def _default_journal_id(self, cr, uid, context={}): + + """ To get default journal for the object" + @param name: Names of fields. + @return: journal + """ + company_id = self.pool.get('res.users').browse(cr, uid, uid).company_id.id + journal = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash'), ('company_id', '=', company_id)]) + if journal: + return journal[0] + else: + return False + + def _end_balance(self, cursor, user, ids, name, attr, context=None): + res_currency_obj = self.pool.get('res.currency') + res_users_obj = self.pool.get('res.users') + + res = {} + + company_currency_id = res_users_obj.browse(cursor, user, user, + context=context).company_id.currency_id.id + + statements = self.browse(cursor, user, ids, context=context) + for statement in statements: + res[statement.id] = statement.balance_start + currency_id = statement.currency.id + for line in statement.move_line_ids: + if line.debit > 0: + if line.account_id.id == \ + statement.journal_id.default_debit_account_id.id: + res[statement.id] += res_currency_obj.compute(cursor, + user, company_currency_id, currency_id, + line.debit, context=context) + else: + if line.account_id.id == \ + statement.journal_id.default_credit_account_id.id: + res[statement.id] -= res_currency_obj.compute(cursor, + user, company_currency_id, currency_id, + line.credit, context=context) + if statement.state in ('draft', 'open'): + for line in statement.line_ids: + res[statement.id] += line.amount + for r in res: + res[r] = round(res[r], 2) + return res + + _columns = { + 'company_id':fields.many2one('res.company', 'Company', required=False), + 'journal_id': fields.many2one('account.journal', 'Journal', required=True), + 'balance_start': fields.function(_get_starting_balance, method=True, string='Opening Balance', type='float',digits=(16,2), help="Opening balance based on cashBox"), + 'balance_end_real': fields.float('Closing Balance', digits=(16,2), states={'confirm':[('readonly', True)]}, help="closing balance entered by the cashbox verifier"), + 'state': fields.selection( + [('draft', 'Draft'), + ('confirm', 'Confirm'), + ('open','Open')], 'State', required=True, states={'confirm': [('readonly', True)]}, readonly="1"), + 'total_entry_encoding':fields.function(_get_sum_entry_encoding, method=True, string="Cash Transaction", help="Total cash transactions"), + 'date':fields.datetime("Open On"), + 'closing_date':fields.datetime("Closed On"), + 'balance_end': fields.function(_end_balance, method=True, string='Balance', help="Closing balance based on transactions"), + 'balance_end_cash': fields.function(_balance_end_cash, method=True, string='Balance', help="Closing balance based on cashBox"), + 'starting_details_ids': fields.one2many('singer.statement', 'starting_id', string='Opening Cashbox'), + 'ending_details_ids': fields.one2many('singer.statement', 'ending_id', string='Closing Cashbox'), + 'name': fields.char('Name', size=64, required=True, readonly=True), + 'user_id':fields.many2one('res.users', 'Responsible', required=False), + } + _defaults = { + 'state': lambda *a: 'draft', + 'name': lambda *a: '/', + 'date': lambda *a:time.strftime("%Y-%m-%d %H:%M:%S"), + 'journal_id': _default_journal_id, + 'user_id': lambda self, cr, uid, context=None: uid + } + + def create(self, cr, uid, vals, context=None): + company_id = vals and vals.get('company_id',False) + if company_id: + open_jrnl = self.search(cr, uid, [('company_id', '=', vals['company_id']), ('journal_id', '=', vals['journal_id']), ('state', '=', 'open')]) + if open_jrnl: + raise osv.except_osv('Error', u'Une caisse de type espèce est déjà ouverte') + if 'starting_details_ids' in vals: + vals['starting_details_ids'] = starting_details_ids = map(list, vals['starting_details_ids']) + for i in starting_details_ids: + if i and i[0] and i[1]: + i[0], i[1] = 0, 0 + res = super(account_cash_statement, self).create(cr, uid, vals, context=context) + return res + + def onchange_journal_id(self, cr, uid, statement_id, journal_id, context={}): + """ Changes balance start and starting details if journal_id changes" + @param statement_id: Changed statement_id + @param journal_id: Changed journal_id + @return: Dictionary of changed values + """ + + cash_pool = self.pool.get('singer.statement') + statement_pool = self.pool.get('account.bank.statement') + + res = {} + balance_start = 0.0 + + if not journal_id: + res.update({ + 'balance_start': balance_start + }) + return res + + + res = super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context) + return res + + def button_open(self, cr, uid, ids, context=None): + + """ Changes statement state to Running. + @return: True + """ + cash_pool = self.pool.get('singer.statement') + statement_pool = self.pool.get('account.bank.statement') + + statement = statement_pool.browse(cr, uid, ids[0]) + number = self.pool.get('ir.sequence').get(cr, uid, 'account.bank.statement') + + if len(statement.starting_details_ids) > 0: + sid = [] + for line in statement.starting_details_ids: + sid.append(line.id) + + cash_pool.unlink(cr, uid, sid) + + cr.execute("select id from account_bank_statement where journal_id=%s and user_id=%s and state=%s order by id desc limit 1", (statement.journal_id.id, uid, 'confirm')) + rs = cr.fetchone() + rs = rs and rs[0] or None + if rs: + statement = statement_pool.browse(cr, uid, rs) + balance_start = statement.balance_end_real or 0.0 + open_ids = cash_pool.search(cr, uid, [('ending_id','=',statement.id)]) + for sid in open_ids: + default = { + 'ending_id': False, + 'starting_id':ids[0] + } + cash_pool.copy(cr, uid, sid, default) + + vals = { + 'date':time.strftime("%Y-%m-%d %H:%M:%S"), + 'state':'open', + 'name':number + } + + self.write(cr, uid, ids, vals) + return True + + def button_confirm(self, cr, uid, ids, context={}): + + """ Check the starting and ending detail of statement + @return: True + """ + done = [] + res_currency_obj = self.pool.get('res.currency') + res_users_obj = self.pool.get('res.users') + account_move_obj = self.pool.get('account.move') + account_move_line_obj = self.pool.get('account.move.line') + account_bank_statement_line_obj = self.pool.get('account.bank.statement.line') + + company_currency_id = res_users_obj.browse(cr, uid, uid, context=context).company_id.currency_id.id + + for st in self.browse(cr, uid, ids, context): + if not st.state == 'open': + continue + + if st.balance_end != st.balance_end_cash: + raise osv.except_osv(_('Error !'), _('Cash balance is not matching with closing balance !')) + + if not (abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001): + raise osv.except_osv(_('Error !'), + _('The statement balance is incorrect !\n') + + _('The expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end)) + if (not st.journal_id.default_credit_account_id) \ + or (not st.journal_id.default_debit_account_id): + raise osv.except_osv(_('Configuration Error !'), + _('Please verify that an account is defined in the journal.')) + + for line in st.move_line_ids: + if line.state <> 'valid': + raise osv.except_osv(_('Error !'), + _('The account entries lines are not in valid state.')) + # for bank.statement.lines + # In line we get reconcile_id on bank.ste.rec. + # in bank stat.rec we get line_new_ids on bank.stat.rec.line + for move in st.line_ids: + context.update({'date':move.date}) + move_id = account_move_obj.create(cr, uid, { + 'journal_id': st.journal_id.id, + 'period_id': st.period_id.id, + 'date': move.date, + }, context=context) + account_bank_statement_line_obj.write(cr, uid, [move.id], { + 'move_ids': [(4,move_id, False)] + }) + if not move.amount: + continue + + torec = [] + if move.amount >= 0: + account_id = st.journal_id.default_credit_account_id.id + else: + account_id = st.journal_id.default_debit_account_id.id + acc_cur = ((move.amount<=0) and st.journal_id.default_debit_account_id) or move.account_id + amount = res_currency_obj.compute(cr, uid, st.currency.id, + company_currency_id, move.amount, context=context, + account=acc_cur) + if move.reconcile_id and move.reconcile_id.line_new_ids: + for newline in move.reconcile_id.line_new_ids: + amount += newline.amount + + val = { + 'name': move.name, + 'date': move.date, + 'ref': move.ref, + 'move_id': move_id, + 'partner_id': ((move.partner_id) and move.partner_id.id) or False, + 'account_id': (move.account_id) and move.account_id.id, + 'credit': ((amount>0) and amount) or 0.0, + 'debit': ((amount<0) and -amount) or 0.0, + 'statement_id': st.id, + 'journal_id': st.journal_id.id, + 'period_id': st.period_id.id, + 'currency_id': st.currency.id, + } + + amount = res_currency_obj.compute(cr, uid, st.currency.id, + company_currency_id, move.amount, context=context, + account=acc_cur) + if st.currency.id <> company_currency_id: + amount_cur = res_currency_obj.compute(cr, uid, company_currency_id, + st.currency.id, amount, context=context, + account=acc_cur) + val['amount_currency'] = -amount_cur + + if move.account_id and move.account_id.currency_id and move.account_id.currency_id.id <> company_currency_id: + val['currency_id'] = move.account_id.currency_id.id + if company_currency_id==move.account_id.currency_id.id: + amount_cur = move.amount + else: + amount_cur = res_currency_obj.compute(cr, uid, company_currency_id, + move.account_id.currency_id.id, amount, context=context, + account=acc_cur) + val['amount_currency'] = amount_cur + + torec.append(account_move_line_obj.create(cr, uid, val , context=context)) + + if move.reconcile_id and move.reconcile_id.line_new_ids: + for newline in move.reconcile_id.line_new_ids: + account_move_line_obj.create(cr, uid, { + 'name': newline.name or move.name, + 'date': move.date, + 'ref': move.ref, + 'move_id': move_id, + 'partner_id': ((move.partner_id) and move.partner_id.id) or False, + 'account_id': (newline.account_id) and newline.account_id.id, + 'debit': newline.amount>0 and newline.amount or 0.0, + 'credit': newline.amount<0 and -newline.amount or 0.0, + 'statement_id': st.id, + 'journal_id': st.journal_id.id, + 'period_id': st.period_id.id, + 'analytic_account_id':newline.analytic_id and newline.analytic_id.id or False, + + }, context=context) + + # Fill the secondary amount/currency + # if currency is not the same than the company + amount_currency = False + currency_id = False + if st.currency.id <> company_currency_id: + amount_currency = move.amount + currency_id = st.currency.id + account_move_line_obj.create(cr, uid, { + 'name': move.name, + 'date': move.date, + 'ref': move.ref, + 'move_id': move_id, + 'partner_id': ((move.partner_id) and move.partner_id.id) or False, + 'account_id': account_id, + 'credit': ((amount < 0) and -amount) or 0.0, + 'debit': ((amount > 0) and amount) or 0.0, + 'statement_id': st.id, + 'journal_id': st.journal_id.id, + 'period_id': st.period_id.id, + 'amount_currency': amount_currency, + 'currency_id': currency_id, + }, context=context) + + for line in account_move_line_obj.browse(cr, uid, [x.id for x in + account_move_obj.browse(cr, uid, move_id, + context=context).line_id], + context=context): + if line.state <> 'valid': + raise osv.except_osv(_('Error !'), + _('Ledger Posting line "%s" is not valid') % line.name) + + if move.reconcile_id and move.reconcile_id.line_ids: + torec += map(lambda x: x.id, move.reconcile_id.line_ids) + #try: + if abs(move.reconcile_amount-move.amount)<0.0001: + + writeoff_acc_id = False + #There should only be one write-off account! + for entry in move.reconcile_id.line_new_ids: + writeoff_acc_id = entry.account_id.id + break + + account_move_line_obj.reconcile(cr, uid, torec, 'statement', writeoff_acc_id=writeoff_acc_id, writeoff_period_id=st.period_id.id, writeoff_journal_id=st.journal_id.id, context=context) + else: + account_move_line_obj.reconcile_partial(cr, uid, torec, 'statement', context) + #except: + # raise osv.except_osv(_('Error !'), _('Unable to reconcile entry "%s": %.2f') % (move.name, move.amount)) + + if st.journal_id.entry_posted: + account_move_obj.write(cr, uid, [move_id], {'state':'posted'}) + done.append(st.id) + self.write(cr, uid, done, {'state':'confirm'}, context=context) + return True + + def button_cancel(self, cr, uid, ids, context={}): + done = [] + for st in self.browse(cr, uid, ids, context): + ids = [] + for line in st.line_ids: + ids += [x.id for x in line.move_ids] + self.pool.get('account.move').unlink(cr, uid, ids, context) + done.append(st.id) + self.write(cr, uid, done, {'state':'draft'}, context=context) + return True + +account_cash_statement() + diff --git a/addons/account/account_installer.xml b/addons/account/account_installer.xml index 50e431935bc..0bce735f1b3 100644 --- a/addons/account/account_installer.xml +++ b/addons/account/account_installer.xml @@ -17,7 +17,7 @@ - You can enhance OpenERP's basic accounting support with a few additional OpenERP applications. + From this screen, you can configure your accounting system. Choose a Chart of Account matched to your accounting system or the Generic Chart of Account which allows you to configure which suit your needs. Configure diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index bceb1b3c857..fc10c58cc8f 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -349,11 +349,15 @@ + + - + + + @@ -363,7 +367,7 @@ - + diff --git a/addons/account/account_menuitem.xml b/addons/account/account_menuitem.xml index 7394b15f0be..56d83debe4c 100644 --- a/addons/account/account_menuitem.xml +++ b/addons/account/account_menuitem.xml @@ -2,31 +2,30 @@ - - - - + + + + - - - - - - + + + + + + - - - - + + + + - - - - - - - + + + + + + @@ -37,9 +36,9 @@ - - + diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index b8719f26242..0bc9e476601 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -788,57 +788,89 @@ class account_move_line(osv.osv): def fields_view_get(self, cr, uid, view_id=None, view_type='form', context={}, toolbar=False, submenu=False): result = super(osv.osv, self).fields_view_get(cr, uid, view_id,view_type,context,toolbar=toolbar, submenu=submenu) - if view_type=='tree' and 'journal_id' in context: - title = self.view_header_get(cr, uid, view_id, view_type, context) - journal = self.pool.get('account.journal').browse(cr, uid, context['journal_id']) + if view_type != 'tree': + return result - # if the journal view has a state field, color lines depending on - # its value - state = '' + fld = [] + fields = {} + flds = [] + title = self.view_header_get(cr, uid, view_id, view_type, context) + xml = '''\n\n\t''' % (title) + journal_pool = self.pool.get('account.journal') + + ids = journal_pool.search(cr, uid, []) + journals = journal_pool.browse(cr, uid, ids) + all_journal = [None] + common_fields = {} + total = len(journals) + for journal in journals: + all_journal.append(journal.id) for field in journal.view_id.columns_id: - if field.field=='state': - state = ' colors="red:state==\'draft\'"' - - #xml = '''\n\n\t''' % (title, state) - xml = '''\n\n\t''' % (title, state) - fields = [] - - widths = { - 'ref': 50, - 'statement_id': 50, - 'state': 60, - 'tax_code_id': 50, - 'move_id': 40, - } - for field in journal.view_id.columns_id: - fields.append(field.field) - attrs = [] - if field.field=='debit': - attrs.append('sum="Total debit"') - elif field.field=='credit': - attrs.append('sum="Total credit"') - elif field.field=='account_tax_id': - attrs.append('domain="[(\'parent_id\',\'=\',False)]"') - elif field.field=='account_id' and journal.id: - attrs.append('domain="[(\'journal_id\', \'=\', '+str(journal.id)+'),(\'type\',\'<>\',\'view\'), (\'type\',\'<>\',\'closed\')]" on_change="onchange_account_id(account_id, partner_id)"') - elif field.field == 'partner_id': - attrs.append('on_change="onchange_partner_id(move_id,partner_id,account_id,debit,credit,date,((\'journal_id\' in context) and context[\'journal_id\']) or {})"') - if field.readonly: - attrs.append('readonly="1"') - if field.required: - attrs.append('required="1"') + if not field.field in fields: + fields[field.field] = [journal.id] + fld.append((field.field, field.sequence)) + flds.append(field.field) + common_fields[field.field] = 1 else: - attrs.append('required="0"') - if field.field in ('amount_currency','currency_id'): - attrs.append('on_change="onchange_currency(account_id,amount_currency,currency_id,date,((\'journal_id\' in context) and context[\'journal_id\']) or {})"') + fields.get(field.field).append(journal.id) + common_fields[field.field] = common_fields[field.field] + 1 + + fld.append(('period_id', 3)) + fld.append(('journal_id', 10)) + flds.append('period_id') + flds.append('journal_id') + fields['period_id'] = all_journal + fields['journal_id'] = all_journal + + from operator import itemgetter + fld = sorted(fld, key=itemgetter(1)) - if field.field in widths: - attrs.append('width="'+str(widths[field.field])+'"') - xml += '''\n''' % (field.field,' '.join(attrs)) + widths = { + 'ref': 50, + 'statement_id': 50, + 'state': 60, + 'tax_code_id': 50, + 'move_id': 40, + } - xml += '''''' - result['arch'] = xml - result['fields'] = self.fields_get(cr, uid, fields, context) + for field_it in fld: + field = field_it[0] + + if common_fields.get(field) == total: + fields.get(field).append(None) + + if field=='state': + state = 'colors="red:state==\'draft\'"' + + attrs = [] + if field == 'debit': + attrs.append('sum="Total debit"') + elif field == 'credit': + attrs.append('sum="Total credit"') + elif field == 'account_tax_id': + attrs.append('domain="[(\'parent_id\',\'=\',False)]"') + elif field == 'account_id' and journal.id: + attrs.append('domain="[(\'journal_id\', \'=\', '+str(journal.id)+'),(\'type\',\'<>\',\'view\'), (\'type\',\'<>\',\'closed\')]" on_change="onchange_account_id(account_id, partner_id)"') + elif field == 'partner_id': + attrs.append('on_change="onchange_partner_id(move_id, partner_id, account_id, debit, credit, date, journal_id)"') +# if field.readonly: +# attrs.append('readonly="1"') +# if field.required: +# attrs.append('required="1"') +# else: +# attrs.append('required="0"') + if field in ('amount_currency','currency_id'): + attrs.append('on_change="onchange_currency(account_id, amount_currency,currency_id, date, journal_id)"') + + if field in widths: + attrs.append('width="'+str(widths[field])+'"') + + attrs.append("invisible=\"context.get('visible_id') not in %s\"" % (fields.get(field))) + xml += '''\n''' % (field,' '.join(attrs)) + + xml += '''''' + result['arch'] = xml + result['fields'] = self.fields_get(cr, uid, flds, context) return result def _check_moves(self, cr, uid, context): diff --git a/addons/account/account_report.xml b/addons/account/account_report.xml index 6480178d1ae..8b4aa147a95 100644 --- a/addons/account/account_report.xml +++ b/addons/account/account_report.xml @@ -34,7 +34,7 @@ string="Taxes Report"/> --> - - - Chart of Taxes - account.tax.code - [('parent_id','=',False)] - tree - - - - - - + @@ -44,14 +44,14 @@ open - - - - - - - - + + + + + + + + diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index a93179e3f98..4067423cc3f 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -270,12 +270,12 @@
- + - + @@ -292,28 +292,31 @@ - - - - + + + + + - + + + + + + - - - - - - - - - + + + + + + @@ -333,7 +336,25 @@ tree,form - + + + account.bank.statement.select + account.bank.statement + search + + + + + + + + + + + + + + account.bank.statement.tree account.bank.statement @@ -357,22 +378,23 @@ account.bank.statement form - - - - - - - - - -