diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 1b378e15e93..d1726d164b6 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -98,6 +98,7 @@ module named account_voucher. 'wizard/account_reconcile_view.xml', 'wizard/account_reconcile_partner_process_view.xml', 'wizard/account_automatic_reconcile_view.xml', + 'wizard/account_financial_report_view.xml', 'project/wizard/project_account_analytic_line_view.xml', 'account_end_fy.xml', 'account_invoice_view.xml', diff --git a/addons/account/account.py b/addons/account/account.py index 39e680fa414..38ed96d4aac 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -139,7 +139,7 @@ class account_account_type(osv.osv): 'Balance' will generally be used for cash accounts. 'Detail' will copy each existing journal item of the previous year, even the reconciled ones. 'Unreconciled' will copy only the journal items that were unreconciled on the first day of the new fiscal year."""), - 'sign': fields.selection([(-1, 'Negative'), (1, 'Positive')], 'Sign on Reports', required=True, help='Allows you to change the sign of the balance amount displayed in the reports, so that you can see positive figures instead of negative ones in expenses accounts.'), + 'sign': fields.selection([(-1, 'Reverse balance sign'), (1, 'Preserve balance sign')], 'Sign on Reports', required=True, help='For accounts that are typically more debited than credited and that you would like to print as negative amounts in your reports, you should reverse the sign of the balance; e.g.: Expense account. The same applies for accounts that are typically more credited than debited and that you would like to print as positive amounts in your reports; e.g.: Income account.'), 'report_type':fields.selection([ ('none','/'), ('income','Profit & Loss (Income Accounts)'), @@ -431,9 +431,16 @@ class account_account(osv.osv): return False return True + def _check_account_type(self, cr, uid, ids, context=None): + for account in self.browse(cr, uid, ids, context=context): + if account.type in ('receivable', 'payable') and account.user_type.close_method != 'unreconciled': + return False + return True + _constraints = [ (_check_recursion, 'Error ! You can not create recursive accounts.', ['parent_id']), - (_check_type, 'Configuration Error! \nYou cannot define children to an account with internal type different of "View"! ', ['type']), + (_check_type, 'Configuration Error! \nYou can not define children to an account with internal type different of "View"! ', ['type']), + (_check_account_type, 'Configuration Error! \nYou can not select an account type with a deferral method different of "Unreconciled" for accounts with internal type "Payable/Receivable"! ', ['user_type','type']), ] _sql_constraints = [ ('code_company_uniq', 'unique (code,company_id)', 'The code of the account must be unique per company !') @@ -509,14 +516,14 @@ class account_account(osv.osv): if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]): if method == 'write': - raise osv.except_osv(_('Error !'), _('You cannot deactivate an account that contains account moves.')) + raise osv.except_osv(_('Error !'), _('You can not desactivate an account that contains some journal items.')) elif method == 'unlink': - raise osv.except_osv(_('Error !'), _('You cannot remove an account which has account entries!. ')) + raise osv.except_osv(_('Error !'), _('You can not remove an account containing journal items!. ')) #Checking whether the account is set as a property to any Partner or not value = 'account.account,' + str(ids[0]) partner_prop_acc = self.pool.get('ir.property').search(cr, uid, [('value_reference','=',value)], context=context) if partner_prop_acc: - raise osv.except_osv(_('Warning !'), _('You cannot remove/deactivate an account which is set as a property to any Partner.')) + raise osv.except_osv(_('Warning !'), _('You can not remove/desactivate an account which is set on a customer or supplier.')) return True def _check_allow_type_change(self, cr, uid, ids, new_type, context=None): @@ -529,15 +536,20 @@ class account_account(osv.osv): if line_obj.search(cr, uid, [('account_id', 'in', account_ids)]): #Check for 'Closed' type if old_type == 'closed' and new_type !='closed': - raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from 'Closed' to any other type which contains account entries!")) + raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from 'Closed' to any other type which contains journal items!")) #Check for change From group1 to group2 and vice versa if (old_type in group1 and new_type in group2) or (old_type in group2 and new_type in group1): - raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from '%s' to '%s' type as it contains account entries!") % (old_type,new_type,)) + raise osv.except_osv(_('Warning !'), _("You cannot change the type of account from '%s' to '%s' type as it contains journal items!") % (old_type,new_type,)) return True def write(self, cr, uid, ids, vals, context=None): + if context is None: context = {} + if not ids: + return True + if isinstance(ids, (int, long)): + ids = [ids] # Dont allow changing the company_id when account_move_line already exist if 'company_id' in vals: @@ -623,7 +635,7 @@ class account_journal(osv.osv): 'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'), 'entry_posted': fields.boolean('Skip \'Draft\' State for Manual Entries', help='Check this box if you don\'t want new journal entries to pass through the \'draft\' state and instead goes directly to the \'posted state\' without any manual validation. \nNote that journal entries that are automatically created by the system are always skipping that state.'), 'company_id': fields.many2one('res.company', 'Company', required=True, select=1, help="Company related to this journal"), - 'allow_date':fields.boolean('Check Date not in the Period', help= 'If set to True then do not accept the entry if the entry date is not into the period dates'), + 'allow_date':fields.boolean('Check Date in Period', help= 'If set to True then do not accept the entry if the entry date is not into the period dates'), } _defaults = { @@ -650,11 +662,13 @@ class account_journal(osv.osv): def write(self, cr, uid, ids, vals, context=None): if context is None: context = {} + if isinstance(ids, (int, long)): + ids = [ids] for journal in self.browse(cr, uid, ids, context=context): if 'company_id' in vals and journal.company_id.id != vals['company_id']: move_lines = self.pool.get('account.move.line').search(cr, uid, [('journal_id', 'in', ids)]) if move_lines: - raise osv.except_osv(_('Warning !'), _('You cannot modify company of this journal as its related record exist in Entry Lines')) + raise osv.except_osv(_('Warning !'), _('You can not modify the company of this journal as its related record exist in journal items')) return super(account_journal, self).write(cr, uid, ids, vals, context=context) def create_sequence(self, cr, uid, vals, context=None): @@ -800,8 +814,8 @@ class account_fiscalyear(osv.osv): return True _constraints = [ - (_check_duration, 'Error! The duration of the Fiscal Year is invalid. ', ['date_stop']), - (_check_fiscal_year, 'Error! You cannot define overlapping fiscal years',['date_start', 'date_stop']) + (_check_duration, 'Error! The start date of the fiscal year must be before his end date.', ['date_start','date_stop']), + (_check_fiscal_year, 'Error! You can not define overlapping fiscal years for the same company.',['date_start', 'date_stop']) ] def create_period3(self, cr, uid, ids, context=None): @@ -879,7 +893,10 @@ class account_period(osv.osv): 'state': 'draft', } _order = "date_start, special desc" - + _sql_constraints = [ + ('name_company_uniq', 'unique(name, company_id)', 'The name of the period must be unique per company!'), + ] + def _check_duration(self,cr,uid,ids,context=None): obj_period = self.browse(cr, uid, ids[0], context=context) if obj_period.date_stop < obj_period.date_start: @@ -952,7 +969,7 @@ class account_period(osv.osv): if 'company_id' in vals: move_lines = self.pool.get('account.move.line').search(cr, uid, [('period_id', 'in', ids)]) if move_lines: - raise osv.except_osv(_('Warning !'), _('You cannot modify company of this period as its related record exist in Entry Lines')) + raise osv.except_osv(_('Warning !'), _('You can not modify company of this period as some journal items exists.')) return super(account_period, self).write(cr, uid, ids, vals, context=context) def build_ctx_periods(self, cr, uid, period_from_id, period_to_id): @@ -1180,10 +1197,10 @@ class account_move(osv.osv): _constraints = [ (_check_centralisation, - 'You cannot create more than one move per period on centralized journal', + 'You can not create more than one move per period on centralized journal', ['journal_id']), (_check_period_journal, - 'You cannot create entries on different periods/journals in the same move', + 'You can not create journal items on different periods/journals in the same journal entry', ['line_id']), ] @@ -1194,7 +1211,7 @@ class account_move(osv.osv): valid_moves = self.validate(cr, uid, ids, context) if not valid_moves: - raise osv.except_osv(_('Integrity Error !'), _('You cannot validate a non-balanced entry !\nMake sure you have configured Payment Term properly !\nIt should contain atleast one Payment Term Line with type "Balance" !')) + raise osv.except_osv(_('Integrity Error !'), _('You can not validate a non-balanced entry !\nMake sure you have configured payment terms properly !\nThe latest payment term line should be of the type "Balance" !')) obj_sequence = self.pool.get('ir.sequence') for move in self.browse(cr, uid, valid_moves, context=context): if move.name =='/': @@ -1230,7 +1247,7 @@ class account_move(osv.osv): if not top: top = account2.id elif top<>account2.id: - raise osv.except_osv(_('Error !'), _('You cannot validate a Journal Entry unless all journal items are in same chart of accounts !')) + raise osv.except_osv(_('Error !'), _('You can not validate a journal entry unless all journal items belongs to the same chart of accounts !')) return self.post(cursor, user, ids, context=context) def button_cancel(self, cr, uid, ids, context=None): @@ -1317,7 +1334,7 @@ class account_move(osv.osv): for move in self.browse(cr, uid, ids, context=context): if move['state'] != 'draft': raise osv.except_osv(_('UserError'), - _('You can not delete posted movement: "%s"!') % \ + _('You can not delete a posted journal entry "%s"!') % \ move['name']) line_ids = map(lambda x: x.id, move.line_id) context['journal_id'] = move.journal_id.id @@ -1337,7 +1354,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') + currency_obj = self.pool.get('res.currency') if context is None: context = {} @@ -1599,7 +1616,7 @@ class account_tax_code(osv.osv): (parent_ids,) + where_params) res=dict(cr.fetchall()) obj_precision = self.pool.get('decimal.precision') - res2 = {} + res2 = {} for record in self.browse(cr, uid, ids, context=context): def _rec_get(record): amount = res.get(record.id, 0.0) @@ -1768,6 +1785,9 @@ class account_tax(osv.osv): 'type_tax_use': fields.selection([('sale','Sale'),('purchase','Purchase'),('all','All')], 'Tax Application', required=True) } + _sql_constraints = [ + ('name_company_uniq', 'unique(name, company_id)', 'Tax Name must be unique per company!'), + ] def name_search(self, cr, user, name, args=None, operator='ilike', context=None, limit=80): """ @@ -2126,7 +2146,11 @@ class account_model(osv.osv): period_id = period_id[0] for model in self.browse(cr, uid, ids, context=context): - entry['name'] = model.name%{'year':time.strftime('%Y'), 'month':time.strftime('%m'), 'date':time.strftime('%Y-%m')} + try: + entry['name'] = model.name%{'year':time.strftime('%Y'), 'month':time.strftime('%m'), 'date':time.strftime('%Y-%m')} + except: + raise osv.except_osv(_('Wrong model !'), _('You have a wrong expression "%(...)s" in your model !')) + move_id = account_move_obj.create(cr, uid, { 'ref': entry['name'], 'period_id': period_id, @@ -2198,8 +2222,8 @@ class account_model_line(osv.osv): } _order = 'sequence' _sql_constraints = [ - ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in model (Credit Or Debit Must Be "0")!'), - ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in model (Credit + Debit Must Be greater "0")!'), + ('credit_debit1', 'CHECK (credit*debit=0)', 'Wrong credit or debit value in model, they must be positive!'), + ('credit_debit2', 'CHECK (credit+debit>=0)', 'Wrong credit or debit value in model, they must be positive!'), ] account_model_line() @@ -2365,7 +2389,7 @@ class account_account_template(osv.osv): _check_recursion = check_cycle _constraints = [ (_check_recursion, 'Error ! You can not create recursive account templates.', ['parent_id']), - (_check_type, 'Configuration Error! \nYou cannot define children to an account with internal type different of "View"! ', ['type']), + (_check_type, 'Configuration Error!\nYou can not define children to an account with internal type different of "View"! ', ['type']), ] @@ -2398,7 +2422,7 @@ class account_add_tmpl_wizard(osv.osv_memory): ptids = tmpl_obj.read(cr, uid, [tids[0]['parent_id'][0]], ['code']) res = None if not ptids or not ptids[0]['code']: - raise osv.except_osv(_('Error !'), _('Cannot locate parent code for template account!')) + raise osv.except_osv(_('Error !'), _('I can not locate a parent code for the template account!')) res = acc_obj.search(cr, uid, [('code','=',ptids[0]['code'])]) return res and res[0] or False @@ -2613,7 +2637,88 @@ class account_fiscal_position_account_template(osv.osv): account_fiscal_position_account_template() - # Multi charts of Accounts wizard +# --------------------------------------------------------- +# Account Financial Report +# --------------------------------------------------------- + +class account_financial_report(osv.osv): + _name = "account.financial.report" + _description = "Account Report" + + def _get_level(self, cr, uid, ids, field_name, arg, context=None): + res = {} + for report in self.browse(cr, uid, ids, context=context): + level = 0 + if report.parent_id: + level = report.parent_id.level + 1 + res[report.id] = level + return res + + def _get_children_by_order(self, cr, uid, ids, context=None): + res = [] + for id in ids: + res.append(id) + ids2 = self.search(cr, uid, [('parent_id', '=', id)], order='sequence ASC', context=context) + res += self._get_children_by_order(cr, uid, ids2, context=context) + return res + + def _get_balance(self, cr, uid, ids, name, args, context=None): + res = {} + res_all = {} + for report in self.browse(cr, uid, ids, context=context): + balance = 0.0 + if report.id in res_all: + balance = res_all[report.id] + elif report.type == 'accounts': + # it's the sum of balance of the linked accounts + for a in report.account_ids: + balance += a.balance + elif report.type == 'account_report' and report.account_report_id: + # it's the amount of the linked report + res2 = self._get_balance(cr, uid, [report.account_report_id.id], 'balance', False, context=context) + res_all.update(res2) + for key, value in res2.items(): + balance += value + elif report.type == 'sum': + # it's the sum of balance of the children of this account.report + #for child in report.children_ids: + res2 = self._get_balance(cr, uid, [rec.id for rec in report.children_ids], 'balance', False, context=context) + res_all.update(res2) + for key, value in res2.items(): + balance += value + res[report.id] = balance + res_all[report.id] = balance + return res + + _columns = { + 'name': fields.char('Report Name', size=128, required=True), + 'parent_id': fields.many2one('account.financial.report', 'Parent'), + 'children_ids': fields.one2many('account.financial.report', 'parent_id', 'Account Report'), + 'sequence': fields.integer('Sequence'), + 'note': fields.text('Notes'), + 'balance': fields.function(_get_balance, 'Balance'), + 'level': fields.function(_get_level, string='Level', store=True, type='integer'), + 'type': fields.selection([ + ('sum','View'), + ('accounts','Accounts'), + ('account_type','Account Type'), + ('account_report','Report Value'), + ],'Type'), + 'account_ids': fields.many2many('account.account', 'account_account_financial_report', 'report_line_id', 'account_id', 'Accounts'), + 'display_detail': fields.boolean('Display details', help='Display every account with its balance instead of the sum.'), + 'account_report_id': fields.many2one('account.financial.report', 'Report Value'), + 'account_type_ids': fields.many2many('account.account.type', 'account_account_financial_report_type', 'report_id', 'account_type_id', 'Account Types'), + } + + _defaults = { + 'type': 'sum', + } + +account_financial_report() + +# --------------------------------------------------------- +# Account generation from template wizards +# --------------------------------------------------------- class wizard_multi_charts_accounts(osv.osv_memory): """ @@ -2706,7 +2811,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): 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]['domain'] = [('id','in',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)] diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 8b0161e7baa..d3386d9ac6d 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -58,13 +58,6 @@ class account_bank_statement(osv.osv): journal_id = ids[0] return journal_id - def _default_balance_start(self, cr, uid, context=None): - cr.execute('select id from account_bank_statement where journal_id=%s order by date desc limit 1', (1,)) - res = cr.fetchone() - if res: - return self.browse(cr, uid, res[0], context=context).balance_end - return 0.0 - 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') @@ -90,7 +83,8 @@ class account_bank_statement(osv.osv): res[statement.id] -= res_currency_obj.compute(cursor, user, company_currency_id, currency_id, line.credit, context=context) - if statement.state == 'draft': + + if statement.state in ('draft', 'open'): for line in statement.line_ids: res[statement.id] += line.amount for r in res: @@ -127,7 +121,7 @@ class account_bank_statement(osv.osv): _name = "account.bank.statement" _description = "Bank Statement" _columns = { - 'name': fields.char('Name', size=64, required=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', states={'confirm': [('readonly', True)]}), + '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'), # readonly for account_cash_statement 'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}), 'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}), @@ -136,19 +130,21 @@ class account_bank_statement(osv.osv): 'balance_start': fields.float('Starting Balance', digits_compute=dp.get_precision('Account'), 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, string='Balance'), + states={'confirm': [('readonly', True)]}), + 'balance_end': fields.function(_end_balance, store=True, # store=True for account_cash_statement + string="Balance", help='Balance as calculated based on Starting Balance and transaction lines'), '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', states={'confirm':[('readonly', True)]}), 'move_line_ids': fields.one2many('account.move.line', 'statement_id', 'Entry lines', states={'confirm':[('readonly',True)]}), - 'state': fields.selection([('draft', 'New'),('confirm', 'Confirmed')], - 'State', required=True, - 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.'), + 'state': fields.selection([('draft', 'New'), + ('open','Open'), # used by cash statements + ('confirm', 'Closed')], + 'State', required=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, 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.'), @@ -158,7 +154,6 @@ class account_bank_statement(osv.osv): 'name': "/", 'date': lambda *a: time.strftime('%Y-%m-%d'), 'state': 'draft', - 'balance_start': _default_balance_start, 'journal_id': _default_journal_id, 'period_id': _get_period, 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'account.bank.statement',context=c), @@ -386,7 +381,7 @@ class account_bank_statement(osv.osv): if t['state'] in ('draft'): unlink_ids.append(t['id']) else: - raise osv.except_osv(_('Invalid action !'), _('Cannot delete bank statement(s) which are already confirmed !')) + raise osv.except_osv(_('Invalid action !'), _('In order to delete a bank statement, you must first cancel it to delete related journal items.')) osv.osv.unlink(self, cr, uid, unlink_ids, context=context) return True diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py index 982383ea2a7..3957e75c860 100644 --- a/addons/account/account_cash_statement.py +++ b/addons/account/account_cash_statement.py @@ -119,39 +119,6 @@ class account_cash_statement(osv.osv): res2[statement.id] = encoding_total return res2 - 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 - def _get_company(self, cr, uid, context=None): user_pool = self.pool.get('res.users') company_pool = self.pool.get('res.company') @@ -218,18 +185,11 @@ class account_cash_statement(osv.osv): return res _columns = { - 'balance_end_real': fields.float('Closing Balance', digits_compute=dp.get_precision('Account'), states={'confirm': [('readonly', True)]}, help="closing balance entered by the cashbox verifier"), - 'state': fields.selection( - [('draft', 'Draft'), - ('confirm', 'Closed'), - ('open','Open')], 'State', required=True, states={'confirm': [('readonly', True)]}, readonly="1"), '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, 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'), 'user_id': fields.many2one('res.users', 'Responsible', required=False), } _defaults = { @@ -247,7 +207,7 @@ class account_cash_statement(osv.osv): ] open_jrnl = self.search(cr, uid, sql) if open_jrnl: - raise osv.except_osv(_('Error'), _('You can not have two open register for the same journal')) + raise osv.except_osv(_('Error'), _('You can not have two open register for the same journal!')) if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash': open_close = self._get_cash_open_close_box_lines(cr, uid, context) diff --git a/addons/account/account_installer.xml b/addons/account/account_installer.xml index 151f7bbc0f0..374304135df 100644 --- a/addons/account/account_installer.xml +++ b/addons/account/account_installer.xml @@ -23,7 +23,7 @@ 23 - + diff --git a/addons/account/account_invoice_view.xml b/addons/account/account_invoice_view.xml index d440f2efc90..09a90b98686 100644 --- a/addons/account/account_invoice_view.xml +++ b/addons/account/account_invoice_view.xml @@ -294,7 +294,7 @@ -