diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 3b04713a1bb..23846183ddf 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,13 +53,14 @@ 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"], + "depends" : ["base_setup", "product", "analytic", "process","board"], 'update_xml': [ 'security/account_security.xml', 'security/ir.model.access.csv', 'account_menuitem.xml', 'report/account_invoice_report_view.xml', 'report/account_entries_report_view.xml', + 'report/account_treasury_report_view.xml', 'report/account_report_view.xml', 'report/account_analytic_entries_report_view.xml', 'wizard/account_move_bank_reconcile_view.xml', @@ -123,10 +125,11 @@ module named account_voucher. "wizard/account_report_balance_sheet_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 75041705547..72208314ed9 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -102,7 +102,7 @@ class account_payment_term_line(osv.osv): ('fixed', 'Fixed Amount')], 'Valuation', required=True, help="""Select here the kind of valuation related to this payment term line. Note that you should have your last line with the type 'Balance' to ensure that the whole amount will be threated."""), - 'value_amount': fields.float('Value Amount', help="For Value percent enter % ratio between 0-1."), + 'value_amount': fields.float('Value Amount', digits_compute=dp.get_precision('Payment Term'), help="For Value percent enter % ratio between 0-1."), 'days': fields.integer('Number of Days', required=True, help="Number of days to add before computation of the day of month." \ "If Date=15/01, Number of Days=22, Day of Month=-1, then the due date is 28/02."), 'days2': fields.integer('Day of the Month', required=True, help="Day of the month, set -1 for the last day of the current month. If it's positive, it gives the day of the next month. Set 0 for net days (otherwise it's based on the beginning of the month)."), @@ -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'), @@ -879,7 +879,7 @@ class account_period(osv.osv): _defaults = { 'state': 'draft', } - _order = "date_start" + _order = "date_start, special desc" def _check_duration(self,cr,uid,ids,context=None): obj_period = self.browse(cr, uid, ids[0], context=context) @@ -921,14 +921,13 @@ 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): mode = 'draft' - for id in ids: - cr.execute('update account_journal_period set state=%s where period_id=%s', (mode, id)) - cr.execute('update account_period set state=%s where id=%s', (mode, id)) + cr.execute('update account_journal_period set state=%s where period_id in %s', (mode, tuple(ids),)) + cr.execute('update account_period set state=%s where id in %s', (mode, tuple(ids),)) return True def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=100): @@ -961,7 +960,10 @@ class account_period(osv.osv): raise osv.except_osv(_('Error'), _('You should have chosen periods that belongs to the same company')) if period_date_start > period_date_stop: raise osv.except_osv(_('Error'), _('Start period should be smaller then End period')) - return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id)]) + #for period from = january, we want to exclude the opening period (but it has same date_from, so we have to check if period_from is special or not to include that clause or not in the search). + if period_from.special: + return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id)]) + return self.search(cr, uid, [('date_start', '>=', period_date_start), ('date_stop', '<=', period_date_stop), ('company_id', '=', company1_id), ('special', '=', False)]) account_period() @@ -983,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.'), @@ -1137,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 = { @@ -1329,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 = {} @@ -1379,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 # @@ -1562,14 +1593,15 @@ class account_tax_code(osv.osv): (parent_ids,) + where_params) res=dict(cr.fetchall()) obj_precision = self.pool.get('decimal.precision') + res2 = {} for record in self.browse(cr, uid, ids, context=context): def _rec_get(record): amount = res.get(record.id, 0.0) for rec in record.child_ids: amount += _rec_get(rec) * rec.sign return amount - res[record.id] = round(_rec_get(record), obj_precision.precision_get(cr, uid, 'Account')) - return res + res2[record.id] = round(_rec_get(record), obj_precision.precision_get(cr, uid, 'Account')) + return res2 def _sum_year(self, cr, uid, ids, name, args, context=None): if context is None: @@ -1614,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'), @@ -2470,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'), @@ -2659,8 +2691,6 @@ class wizard_multi_charts_accounts(osv.osv_memory): def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): res = super(wizard_multi_charts_accounts, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False) - configured_cmp = [] - unconfigured_cmp = [] cmp_select = [] company_ids = self.pool.get('res.company').search(cr, uid, [], context=context) #display in the widget selection of companies, only the companies that haven't been configured yet (but don't care about the demo chart of accounts) @@ -2668,12 +2698,12 @@ class wizard_multi_charts_accounts(osv.osv_memory): configured_cmp = [r[0] for r in cr.fetchall()] unconfigured_cmp = list(set(company_ids)-set(configured_cmp)) for field in res['fields']: - if field == 'company_id': - res['fields'][field]['domain'] = unconfigured_cmp - res['fields'][field]['selection'] = [('', '')] - if unconfigured_cmp: - cmp_select = [(line.id, line.name) for line in self.pool.get('res.company').browse(cr, uid, unconfigured_cmp)] - res['fields'][field]['selection'] = cmp_select + if field == 'company_id': + res['fields'][field]['domain'] = unconfigured_cmp + res['fields'][field]['selection'] = [('', '')] + if unconfigured_cmp: + cmp_select = [(line.id, line.name) for line in self.pool.get('res.company').browse(cr, uid, unconfigured_cmp)] + res['fields'][field]['selection'] = cmp_select return res def execute(self, cr, uid, ids, context=None): @@ -2681,7 +2711,6 @@ class wizard_multi_charts_accounts(osv.osv_memory): obj_acc = self.pool.get('account.account') obj_acc_tax = self.pool.get('account.tax') obj_journal = self.pool.get('account.journal') - obj_sequence = self.pool.get('ir.sequence') obj_acc_template = self.pool.get('account.account.template') obj_fiscal_position_template = self.pool.get('account.fiscal.position.template') obj_fiscal_position = self.pool.get('account.fiscal.position') @@ -2689,9 +2718,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): analytic_journal_obj = self.pool.get('account.analytic.journal') obj_tax_code = self.pool.get('account.tax.code') obj_tax_code_template = self.pool.get('account.tax.code.template') - obj_acc_journal_view = self.pool.get('account.journal.view') - ir_values = self.pool.get('ir.values') - obj_product = self.pool.get('product.product') + ir_values_obj = self.pool.get('ir.values') # Creating Account obj_acc_root = obj_multi.chart_template_id.account_root_id tax_code_root_id = obj_multi.chart_template_id.tax_code_root_id.id @@ -2924,15 +2951,20 @@ class wizard_multi_charts_accounts(osv.osv_memory): ref_acc_bank = obj_multi.chart_template_id.bank_account_view_id current_num = 1 + valid = True for line in obj_multi.bank_accounts_id: #create the account_account for this bank journal tmp = line.acc_name dig = obj_multi.code_digits - if ref_acc_bank.code: - try: - new_code = str(int(ref_acc_bank.code.ljust(dig,'0')) + current_num) - except: - new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)),'0')) + str(current_num) + if not ref_acc_bank.code: + raise osv.except_osv(_('Configuration Error !'), _('The bank account defined on the selected chart of account hasn\'t a code.')) + 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', '=', company_id)]) + if not ids: + break + else: + current_num += 1 vals = { 'name': tmp, 'currency_id': line.currency_id and line.currency_id.id or False, @@ -2946,8 +2978,6 @@ class wizard_multi_charts_accounts(osv.osv_memory): acc_cash_id = obj_acc.create(cr,uid,vals) #create the bank journal - analytical_bank_ids = analytic_journal_obj.search(cr,uid,[('type','=','situation')]) - analytical_journal_bank = analytical_bank_ids and analytical_bank_ids[0] or False vals_journal = { 'name': vals['name'], 'code': _('BNK') + str(current_num), @@ -2965,6 +2995,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): vals_journal['default_debit_account_id'] = acc_cash_id obj_journal.create(cr, uid, vals_journal) current_num += 1 + valid = True #create the properties property_obj = self.pool.get('ir.property') @@ -3029,10 +3060,10 @@ class wizard_multi_charts_accounts(osv.osv_memory): obj_ac_fp.create(cr, uid, vals_acc) if obj_multi.sale_tax: - ir_values.set(cr, uid, key='default', key2=False, name="taxes_id", company=obj_multi.company_id.id, + ir_values_obj.set(cr, uid, key='default', key2=False, name="taxes_id", company=obj_multi.company_id.id, models =[('product.product',False)], value=[tax_template_to_tax[obj_multi.sale_tax.id]]) if obj_multi.purchase_tax: - ir_values.set(cr, uid, key='default', key2=False, name="supplier_taxes_id", company=obj_multi.company_id.id, + ir_values_obj.set(cr, uid, key='default', key2=False, name="supplier_taxes_id", company=obj_multi.company_id.id, models =[('product.product',False)], value=[tax_template_to_tax[obj_multi.purchase_tax.id]]) wizard_multi_charts_accounts() diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 7a885fb2cad..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.'), } @@ -461,7 +461,7 @@ class account_bank_statement_line(osv.osv): select=True, required=True, ondelete='cascade'), 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account'), 'move_ids': fields.many2many('account.move', - 'account_bank_statement_line_move_rel', 'statement_id','move_id', + 'account_bank_statement_line_move_rel', 'statement_line_id','move_id', 'Moves'), 'ref': fields.char('Reference', size=32), 'note': fields.text('Notes'), 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 43f09bebc49..b21d3e9604f 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -53,8 +53,8 @@
- - + + @@ -123,6 +123,7 @@ + @@ -174,7 +175,7 @@ - + @@ -202,7 +203,7 @@ -