diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py index 96412077840..da1f95de301 100644 --- a/addons/account/__openerp__.py +++ b/addons/account/__openerp__.py @@ -53,13 +53,14 @@ module named account_voucher. 'wizard/account_move_bank_reconcile_view.xml', 'wizard/account_use_model_view.xml', 'account_installer.xml', + 'wizard/account_period_close_view.xml', 'account_view.xml', 'account_report.xml', 'wizard/account_report_common_view.xml', 'wizard/account_invoice_refund_view.xml', - 'wizard/account_period_close_view.xml', 'wizard/account_fiscalyear_close_state.xml', 'wizard/account_chart_view.xml', + 'wizard/account_tax_chart_view.xml', 'wizard/account_move_journal_view.xml', 'wizard/account_move_line_reconcile_select_view.xml', 'wizard/account_open_closed_fiscalyear_view.xml', @@ -74,7 +75,6 @@ module named account_voucher. 'wizard/account_journal_select_view.xml', 'wizard/account_change_currency_view.xml', 'wizard/account_validate_move_view.xml', - 'wizard/account_pay_invoice_view.xml', 'wizard/account_unreconcile_view.xml', 'wizard/account_report_general_ledger_view.xml', 'wizard/account_invoice_state_view.xml', diff --git a/addons/account/account.py b/addons/account/account.py index 2a07154461c..08725e0cc5e 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -18,6 +18,7 @@ # along with this program. If not, see . # ############################################################################## + import time from datetime import datetime, timedelta from dateutil.relativedelta import relativedelta @@ -60,7 +61,7 @@ class account_payment_term(osv.osv): 'line_ids': fields.one2many('account.payment.term.line', 'payment_id', 'Terms'), } _defaults = { - 'active': lambda *a: 1, + 'active': 1, } _order = "name" @@ -120,9 +121,9 @@ class account_payment_term_line(osv.osv): 'payment_id': fields.many2one('account.payment.term', 'Payment Term', required=True, select=True), } _defaults = { - 'value': lambda *a: 'balance', - 'sequence': lambda *a: 5, - 'days2': lambda *a: 0, + 'value': 'balance', + 'sequence': 5, + 'days2': 0, } _order = "sequence" @@ -401,18 +402,14 @@ 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), - 'check_history': fields.boolean('Display History', - help="Check this box if you want to print all entries when printing the General Ledger, "\ - "otherwise it will only print its balance."), 'level': fields.function(_get_level, string='Level', method=True, store=True, type='integer'), } _defaults = { - 'type': lambda *a : 'view', - 'reconcile': lambda *a: False, - 'active': lambda *a: True, - 'check_history': lambda *a: True, - 'currency_mode': lambda *a: 'current', + 'type': 'view', + 'reconcile': False, + 'active': True, + 'currency_mode': 'current', 'company_id': lambda s,cr,uid,c: s.pool.get('res.company')._company_default_get(cr, uid, 'account.account', context=c), } @@ -506,7 +503,7 @@ class account_account(osv.osv): default['child_parent_ids'] = False return super(account_account, self).copy(cr, uid, id, default, context=context) - def _check_moves(self, cr, uid, ids, method, context): + def _check_moves(self, cr, uid, ids, method, context=None): line_obj = self.pool.get('account.move.line') account_ids = self.search(cr, uid, [('id', 'child_of', ids)]) @@ -522,7 +519,7 @@ class account_account(osv.osv): raise osv.except_osv(_('Warning !'), _('You cannot remove/deactivate an account which is set as a property to any Partner.')) return True - def _check_allow_type_change(self, cr, uid, ids, new_type, context): + def _check_allow_type_change(self, cr, uid, ids, new_type, context=None): group1 = ['payable', 'receivable', 'other'] group2 = ['consolidation','view'] line_obj = self.pool.get('account.move.line') @@ -552,9 +549,9 @@ class account_account(osv.osv): self._check_allow_type_change(cr, uid, ids, vals['type'], context=context) return super(account_account, self).write(cr, uid, ids, vals, context=context) - def unlink(self, cr, uid, ids, context={}): - self._check_moves(cr, uid, ids, "unlink", context) - return super(account_account, self).unlink(cr, uid, ids, context) + def unlink(self, cr, uid, ids, context=None): + self._check_moves(cr, uid, ids, "unlink", context=context) + return super(account_account, self).unlink(cr, uid, ids, context=context) account_account() @@ -566,6 +563,7 @@ class account_journal_view(osv.osv): 'columns_id': fields.one2many('account.journal.column', 'view_id', 'Columns') } _order = "name" + account_journal_view() @@ -591,6 +589,7 @@ class account_journal_column(osv.osv): 'readonly': fields.boolean('Readonly'), } _order = "sequence" + account_journal_column() class account_journal(osv.osv): @@ -599,7 +598,7 @@ class account_journal(osv.osv): _columns = { 'name': fields.char('Journal Name', size=64, required=True, translate=True,help="Name of the journal"), 'code': fields.char('Code', size=16,required=True,help="Code of the journal"), - 'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'),('expense', 'Expense'), ('cash', 'Cash'), ('bank', 'Bank'), ('general', 'General'), ('situation', 'Situation')], 'Type', size=32, required=True, + 'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'),('expense', 'Expense'), ('cash', 'Cash'), ('bank', 'Bank and Cheques'), ('general', 'General'), ('situation', '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."\ " Select 'Cash' to be used at the time of making payment."\ @@ -618,7 +617,7 @@ class account_journal(osv.osv): 'user_id': fields.many2one('res.users', 'User', help="The user responsible for this journal"), 'groups_id': fields.many2many('res.groups', 'account_journal_group_rel', 'journal_id', 'group_id', 'Groups'), 'currency': fields.many2one('res.currency', 'Currency', help='The currency used to enter statement'), - 'entry_posted': fields.boolean('Skip \'Draft\' State for Created Entries', help='Check this box if you don\'t want new account moves to pass through the \'draft\' state and instead goes directly to the \'posted state\' without any manual validation.'), + '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"), # 'invoice_sequence_id': fields.many2one('ir.sequence', 'Invoice Sequence', \ # help="The sequence used for invoice numbers in this journal."), @@ -839,7 +838,7 @@ class account_period(osv.osv): 'company_id': fields.related('fiscalyear_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True) } _defaults = { - 'state': lambda *a: 'draft', + 'state': 'draft', } _order = "date_start" @@ -887,13 +886,10 @@ class account_period(osv.osv): return ids def action_draft(self, cr, uid, ids, *args): - users_roles = self.pool.get('res.users').browse(cr, uid, uid).roles_id - for role in users_roles: - if role.name=='Period': - 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)) + 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)) return True def name_search(self, cr, user, name, args=None, operator='ilike', context={}, limit=80): @@ -1004,13 +1000,13 @@ class account_move(osv.osv): @param context: context arguments, like lang, time zone @param limit: Returns first 'n' ids of complete result, default is 80. - @return: Returns a list of tupples containing id and name + @return: Returns a list of tuples containing id and name """ if not args: - args=[] + args = [] if not context: - context={} + context = {} ids = [] if name: ids += self.search(cr, user, [('name','ilike',name)]+args, limit=limit, context=context) @@ -1026,7 +1022,7 @@ class account_move(osv.osv): def name_get(self, cursor, user, ids, context=None): if not len(ids): return [] - res=[] + res = [] data_move = self.pool.get('account.move').browse(cursor,user,ids) for move in data_move: if move.state=='draft': @@ -1040,8 +1036,7 @@ class account_move(osv.osv): periods = self.pool.get('account.period').find(cr, uid) if periods: return periods[0] - else: - return False + return False def _amount_compute(self, cr, uid, ids, name, args, context, where =''): if not ids: return {} @@ -1055,21 +1050,25 @@ class account_move(osv.osv): return result def _search_amount(self, cr, uid, obj, name, args, context): - ids = [] - cr.execute('select move_id,sum(debit) from account_move_line group by move_id') - result = dict(cr.fetchall()) - - for item in args: - if item[1] == '>=': - res = [('id', 'in', [k for k,v in result.iteritems() if v >= item[2]])] + ids = set() + for cond in args: + amount = cond[2] + if isinstance(cond[2],(list,tuple)): + if cond[1] in ['in','not in']: + amount = tuple(cond[2]) + else: + continue else: - res = [('id', 'in', [k for k,v in result.iteritems() if v <= item[2]])] - ids += res + if cond[1] in ['=like', 'like', 'not like', 'ilike', 'not ilike', 'in', 'not in', 'child_of']: + continue - if not ids: - return [('id', '>', '0')] - - return ids + cr.execute("select move_id from account_move_line group by move_id having sum(debit) %s %%s" % (cond[1]) ,(amount,)) + res_ids = set(id[0] for id in cr.fetchall()) + ids = ids and (ids & res_ids) or res_ids + if ids: + return [('id','in',tuple(ids))] + else: + return [('id', '=', '0')] _columns = { 'name': fields.char('Number', size=64, required=True), @@ -1079,11 +1078,11 @@ class account_move(osv.osv): 'state': fields.selection([('draft','Draft'), ('posted','Posted')], 'State', required=True, readonly=True, help='When new account move is created the state will be \'Draft\'. When all the payments are done it will be in \'Posted\' state.'), 'line_id': fields.one2many('account.move.line', 'move_id', 'Entries', states={'posted':[('readonly',True)]}), - 'to_check': fields.boolean('To Be Verified'), + '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"), 'amount': fields.function(_amount_compute, method=True, string='Amount', digits_compute=dp.get_precision('Account'), type='float', fnct_search=_search_amount), 'date': fields.date('Date', required=True, states={'posted':[('readonly',True)]}), - 'narration':fields.text('Narration', select=True), + 'narration':fields.text('Narration'), 'company_id': fields.related('journal_id','company_id',type='many2one',relation='res.company',string='Company',store=True), } _defaults = { @@ -1152,6 +1151,17 @@ class account_move(osv.osv): return True def button_validate(self, cursor, user, ids, context=None): + for move in self.browse(cursor, user, ids): + top = None + for line in move.line_id: + account = line.account_id + while account: + account2 = account + account = account.parent_id + 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 !')) return self.post(cursor, user, ids, context=context) def button_cancel(self, cr, uid, ids, context={}): @@ -1457,7 +1467,7 @@ class account_tax_code(osv.osv): This code is used for some tax declarations. """ - def _sum(self, cr, uid, ids, name, args, context,where ='', where_params=()): + def _sum(self, cr, uid, ids, name, args, context, where ='', where_params=()): parent_ids = tuple(self.search(cr, uid, [('parent_id', 'child_of', ids)])) if context.get('based_on', 'invoices') == 'payments': cr.execute('SELECT line.tax_code_id, sum(line.tax_amount) \ @@ -1470,13 +1480,15 @@ class account_tax_code(osv.osv): AND ((invoice.state = \'paid\') \ OR (invoice.id IS NULL)) \ GROUP BY line.tax_code_id', - (parent_ids,)+where_params) + (parent_ids,) + where_params) else: cr.execute('SELECT line.tax_code_id, sum(line.tax_amount) \ - FROM account_move_line AS line \ + FROM account_move_line AS line, \ + account_move AS move \ WHERE line.tax_code_id IN %s '+where+' \ + AND move.id = line.move_id \ GROUP BY line.tax_code_id', - (parent_ids,)+where_params) + (parent_ids,) + where_params) res=dict(cr.fetchall()) for record in self.browse(cr, uid, ids, context): def _rec_get(record): @@ -1487,7 +1499,12 @@ class account_tax_code(osv.osv): res[record.id] = round(_rec_get(record), self.pool.get('decimal.precision').precision_get(cr, uid, 'Account')) return res - def _sum_year(self, cr, uid, ids, name, args, context): + def _sum_year(self, cr, uid, ids, name, args, context=None): + if context is None: + context = {} + move_state = ('posted', ) + if 'state' in context and context['state'] == 'all': + move_state = ('draft', 'posted', ) if 'fiscalyear_id' in context and context['fiscalyear_id']: fiscalyear_id = context['fiscalyear_id'] else: @@ -1497,12 +1514,17 @@ class account_tax_code(osv.osv): if fiscalyear_id: pids = map(lambda x: str(x.id), self.pool.get('account.fiscalyear').browse(cr, uid, fiscalyear_id).period_ids) if pids: - where = ' and period_id IN %s' - where_params = (tuple(pids),) + where = ' AND line.period_id IN %s AND move.state IN %s ' + where_params = (tuple(pids), move_state) return self._sum(cr, uid, ids, name, args, context, where=where, where_params=where_params) def _sum_period(self, cr, uid, ids, name, args, context): + if context is None: + context = {} + move_state = ('posted', ) + if 'state' in context and context['state'] == 'all': + move_state = ('draft', 'posted', ) if 'period_id' in context and context['period_id']: period_id = context['period_id'] else: @@ -1511,7 +1533,7 @@ class account_tax_code(osv.osv): return dict.fromkeys(ids, 0.0) period_id = period_id[0] return self._sum(cr, uid, ids, name, args, context, - where=' and line.period_id=%s', where_params=(period_id,)) + where=' AND line.period_id=%s AND move.state IN %s', where_params=(period_id, move_state)) _name = 'account.tax.code' _description = 'Tax Code' @@ -1646,9 +1668,9 @@ class account_tax(osv.osv): @return: Returns a list of tupples containing id and name """ if not args: - args=[] + args = [] if not context: - context={} + context = {} ids = [] ids = self.search(cr, user, args, limit=limit, context=context) return self.name_get(cr, user, ids, context=context) @@ -1669,37 +1691,37 @@ class account_tax(osv.osv): return super(account_tax, self).search(cr, uid, args, offset, limit, order, context, count) - def name_get(self, cr, uid, ids, context={}): + def name_get(self, cr, uid, ids, context=None): if not len(ids): return [] res = [] - for record in self.read(cr, uid, ids, ['description','name'], context): + for record in self.read(cr, uid, ids, ['description','name'], context=context): name = record['description'] and record['description'] or record['name'] res.append((record['id'],name )) return res - def _default_company(self, cr, uid, context={}): + def _default_company(self, cr, uid, context=None): user = self.pool.get('res.users').browse(cr, uid, uid, context=context) if user.company_id: return user.company_id.id return self.pool.get('res.company').search(cr, uid, [('parent_id', '=', False)])[0] _defaults = { - 'python_compute': lambda *a: '''# price_unit\n# address : res.partner.address object or False\n# product : product.product object or None\n# partner : res.partner object or None\n\nresult = price_unit * 0.10''', - 'python_compute_inv': lambda *a: '''# price_unit\n# address : res.partner.address object or False\n# product : product.product object or False\n\nresult = price_unit * 0.10''', - 'applicable_type': lambda *a: 'true', - 'type': lambda *a: 'percent', - 'amount': lambda *a: 0, - 'price_include': lambda *a: 0, - 'active': lambda *a: 1, - 'type_tax_use': lambda *a: 'all', - 'sequence': lambda *a: 1, - 'tax_group': lambda *a: 'vat', - 'ref_tax_sign': lambda *a: 1, - 'ref_base_sign': lambda *a: 1, - 'tax_sign': lambda *a: 1, - 'base_sign': lambda *a: 1, - 'include_base_amount': lambda *a: False, + 'python_compute': '''# price_unit\n# address : res.partner.address object or False\n# product : product.product object or None\n# partner : res.partner object or None\n\nresult = price_unit * 0.10''', + 'python_compute_inv': '''# price_unit\n# address : res.partner.address object or False\n# product : product.product object or False\n\nresult = price_unit * 0.10''', + 'applicable_type': 'true', + 'type': 'percent', + 'amount': 0, + 'price_include': 0, + 'active': 1, + 'type_tax_use': 'all', + 'sequence': 1, + 'tax_group': 'vat', + 'ref_tax_sign': 1, + 'ref_base_sign': 1, + 'tax_sign': 1, + 'base_sign': 1, + 'include_base_amount': False, 'company_id': _default_company, } _order = 'sequence' @@ -1803,7 +1825,7 @@ class account_tax(osv.osv): tin = self.compute_inv(cr, uid, tin, price_unit, quantity, address_id=address_id, product=product, partner=partner) for r in tin: totalex -= r['amount'] - totlex_qty=0.0 + totlex_qty = 0.0 try: totlex_qty=totalex/quantity except: @@ -2017,7 +2039,7 @@ class account_model_line(osv.osv): 'currency_id': fields.many2one('res.currency', 'Currency'), 'partner_id': fields.many2one('res.partner', 'Partner'), - 'date_maturity': fields.selection([('today','Date of the day'), ('partner','Partner Payment Term')], 'Maturity date', help="The maturity date of the generated entries for this model. You can choose between the creation date or the creation date of the entries plus the partner payment terms."), + 'date_maturity': fields.selection([('today','Date of the day'), ('partner','Partner Payment Term')], 'Due date', help="The due date of the generated entries for this model. You can choose between the creation date or the creation date of the entries plus the partner payment terms."), 'date': fields.selection([('today','Date of the day'), ('partner','Partner Payment Term')], 'Current Date', required=True, help="The date of the generated entries"), } _defaults = { @@ -2224,12 +2246,12 @@ class account_add_tmpl_wizard(osv.osv_memory): } def action_create(self,cr,uid,ids,context=None): - acc_obj=self.pool.get('account.account') - tmpl_obj=self.pool.get('account.account.template') - data= self.read(cr, uid, ids) + acc_obj = self.pool.get('account.account') + tmpl_obj = self.pool.get('account.account.template') + data = self.read(cr, uid, ids) company_id = acc_obj.read(cr, uid, [data[0]['cparent_id']], ['company_id'])[0]['company_id'][0] account_template = tmpl_obj.browse(cr, uid, context['tmpl_ids']) - vals={ + vals = { 'name': account_template.name, 'currency_id': account_template.currency_id and account_template.currency_id.id or False, 'code': account_template.code, @@ -2628,13 +2650,13 @@ class wizard_multi_charts_accounts(osv.osv_memory): data_id = data_pool.search(cr, uid, [('model','=','account.journal.view'), ('name','=','account_journal_bank_view_multi')]) data = data_pool.browse(cr, uid, data_id[0]) - ref_acc_bank = data.res_id + view_id_cur = data.res_id ref_acc_bank = obj_multi.chart_template_id.bank_account_view_id current_num = 1 for line in obj_multi.bank_accounts_id: #create the account_account for this bank journal - tmp = self.pool.get('res.partner.bank').name_get(cr, uid, [line.acc_no.id])[0][1] + tmp = line.acc_name dig = obj_multi.code_digits if ref_acc_bank.code: try: @@ -2642,7 +2664,7 @@ class wizard_multi_charts_accounts(osv.osv_memory): except Exception,e: new_code = str(ref_acc_bank.code.ljust(dig-len(str(current_num)),'0')) + str(current_num) vals = { - 'name': line.acc_no.bank and line.acc_no.bank.name+' '+tmp or tmp, + 'name': tmp, 'currency_id': line.currency_id and line.currency_id.id or False, 'code': new_code, 'type': 'other', diff --git a/addons/account/account_assert_test.xml b/addons/account/account_assert_test.xml index ba5f9840ccc..88025514763 100644 --- a/addons/account/account_assert_test.xml +++ b/addons/account/account_assert_test.xml @@ -1,7 +1,7 @@ - + diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 8ae6b24f7d0..f7c943f71d3 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -104,8 +104,7 @@ class account_bank_statement(osv.osv): periods = self.pool.get('account.period').find(cr, uid) if periods: return periods[0] - else: - return False + return False def _currency(self, cursor, user, ids, name, args, context=None): res = {} @@ -201,6 +200,7 @@ class account_bank_statement(osv.osv): 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_analytic_line_obj = self.pool.get('account.analytic.line') account_bank_statement_line_obj = self.pool.get('account.bank.statement.line') obj_seq = self.pool.get('ir.sequence') @@ -222,6 +222,11 @@ class account_bank_statement(osv.osv): raise osv.except_osv(_('Configuration Error !'), _('Please verify that an account is defined in the journal.')) + if not st.name == '/': + next_number = st.name + else: + next_number = obj_seq.get(cr, uid, 'account.bank.statement') + for line in st.move_line_ids: if line.state <> 'valid': raise osv.except_osv(_('Error !'), @@ -230,14 +235,18 @@ class account_bank_statement(osv.osv): # 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}) + if move.analytic_account_id: + if not st.journal_id.analytic_journal_id: + raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (st.journal_id.name,)) + + 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)] + 'move_ids': [(4, move_id, False)] }) if not move.amount: continue @@ -268,6 +277,7 @@ class account_bank_statement(osv.osv): 'journal_id': st.journal_id.id, 'period_id': st.period_id.id, 'currency_id': st.currency.id, + 'analytic_account_id': move.analytic_account_id and move.analytic_account_id.id or False } amount = res_currency_obj.compute(cr, uid, st.currency.id, @@ -289,7 +299,28 @@ class account_bank_statement(osv.osv): account=acc_cur) val['amount_currency'] = amount_cur - torec.append(account_move_line_obj.create(cr, uid, val , context=context)) + move_line_id = account_move_line_obj.create(cr, uid, val , context=context) + torec.append(move_line_id) + + if move.analytic_account_id: + anal_val = {} + amt = (val['credit'] or 0.0) - (val['debit'] or 0.0) + anal_val = { + 'name': val['name'], + 'ref': val['ref'], + 'date': val['date'], + 'amount': amt, + 'account_id': val['analytic_account_id'], + 'currency_id': val['currency_id'], + 'general_account_id': val['account_id'], + 'journal_id': st.journal_id.analytic_journal_id.id, + 'period_id': val['period_id'], + 'user_id': uid, + 'move_id': move_line_id + } + if val.get('amount_currency', False): + anal_val['amount_currency'] = val['amount_currency'] + account_analytic_line_obj.create(cr, uid, anal_val, context=context) if move.reconcile_id and move.reconcile_id.line_new_ids: for newline in move.reconcile_id.line_new_ids: @@ -338,7 +369,7 @@ class account_bank_statement(osv.osv): context=context): if line.state <> 'valid': raise osv.except_osv(_('Error !'), - _('Ledger Posting line "%s" is not valid') % line.name) + _('Journal Item "%s" is not valid') % line.name) if move.reconcile_id and move.reconcile_id.line_ids: ## Search if move has already a partial reconciliation @@ -367,17 +398,11 @@ class account_bank_statement(osv.osv): 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) - - if st.journal_id.entry_posted: - account_move_obj.write(cr, uid, [move_id], {'state': 'posted'}) + move_name = next_number + ' - ' + str(move.sequence) + account_move_obj.write(cr, uid, [move_id], {'name': move_name, 'state': 'posted'}) # Bank statements will not consider boolean on journal entry_posted self.log(cr, uid, st.id, 'Statement %s is confirmed and entries are created.' % st.name) done.append(st.id) - - next_number = obj_seq.get(cr, uid, 'account.bank.statement') - if not st.name == '/': - next_number = st.name + '/' + next_number[-1:] - account_move_obj.write(cr, uid, [move_id], {'state': 'posted', 'name': next_number}) self.write(cr, uid, [st.id], {'name': next_number}, context=context) self.write(cr, uid, done, {'state':'confirm'}, context=context) @@ -397,28 +422,15 @@ class account_bank_statement(osv.osv): return True def onchange_journal_id(self, cursor, user, statement_id, journal_id, context=None): - if not journal_id: - return {'value': {'currency': False}} - account_journal_obj = self.pool.get('account.journal') res_users_obj = self.pool.get('res.users') - res_currency_obj = self.pool.get('res.currency') - cursor.execute('SELECT balance_end_real \ FROM account_bank_statement \ - WHERE journal_id = %s \ - ORDER BY date DESC,id DESC LIMIT 1', (journal_id,)) + WHERE journal_id = %s AND NOT state = %s \ + ORDER BY date DESC,id DESC LIMIT 1', (journal_id, 'draft')) res = cursor.fetchone() balance_start = res and res[0] or 0.0 - - currency_id = account_journal_obj.browse(cursor, user, journal_id, - context=context).currency.id - if not currency_id: - currency_id = res_users_obj.browse(cursor, user, user, - context=context).company_id.currency_id.id - currency = res_currency_obj.name_get(cursor, user, [currency_id], - context=context)[0] - return {'value': {'balance_start': balance_start, 'currency': currency}} + return {'value': {'balance_start': balance_start}} def unlink(self, cr, uid, ids, context=None): stat = self.read(cr, uid, ids, ['state']) @@ -629,6 +641,26 @@ class account_bank_statement_line(osv.osv): else: account_id = part.property_account_receivable.id res['value']['account_id'] = account_id + + if not line or (line and not line[0].amount): + res_users_obj = self.pool.get('res.users') + res_currency_obj = self.pool.get('res.currency') + company_currency_id = res_users_obj.browse(cursor, user, user, + context=context).company_id.currency_id.id + if not currency_id: + currency_id = company_currency_id + + cursor.execute('SELECT sum(debit-credit) \ + FROM account_move_line \ + WHERE (reconcile_id is null) \ + AND partner_id = %s \ + AND account_id=%s', (partner_id, account_id)) + pgres = cursor.fetchone() + balance = pgres and pgres[0] or 0.0 + + balance = res_currency_obj.compute(cursor, user, company_currency_id, + currency_id, balance, context=context) + res['value']['amount'] = balance return res def _reconcile_amount(self, cursor, user, ids, name, args, context=None): @@ -669,6 +701,7 @@ class account_bank_statement_line(osv.osv): select=True, required=True, ondelete='cascade'), 'reconcile_id': fields.many2one('account.bank.statement.reconcile', 'Reconcile'), + 'analytic_account_id': fields.many2one('account.analytic.account', 'Analytic Account'), 'move_ids': fields.many2many('account.move', 'account_bank_statement_line_move_rel', 'move_id','statement_id', 'Moves'), diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py index 8bf75a8dd03..5ed057536a8 100644 --- a/addons/account/account_cash_statement.py +++ b/addons/account/account_cash_statement.py @@ -77,7 +77,7 @@ class account_cash_statement(osv.osv): """ res ={} for statement in self.browse(cr, uid, ids): - amount_total=0.0 + amount_total = 0.0 if statement.journal_id.type not in('cash'): continue @@ -232,7 +232,7 @@ class account_cash_statement(osv.osv): 'starting_details_ids':False }) res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context) - self.write(cr, uid, [res_id], {}) + #self.write(cr, uid, [res_id], {}) return res_id def write(self, cr, uid, ids, vals, context=None): @@ -273,8 +273,6 @@ class account_cash_statement(osv.osv): 'balance_start': balance_start }) return res - - res = super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context) return res @@ -304,7 +302,7 @@ class account_cash_statement(osv.osv): if statement.name and statement.name == '/': number = self.pool.get('ir.sequence').get(cr, uid, 'account.cash.statement') vals.update({ - 'name':number + 'name': number }) 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')) @@ -346,6 +344,7 @@ class account_cash_statement(osv.osv): 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_analytic_line_obj = self.pool.get('account.analytic.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 @@ -374,6 +373,10 @@ class account_cash_statement(osv.osv): # 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: + if move.analytic_account_id: + if not st.journal_id.analytic_journal_id: + raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (st.journal_id.name,)) + context.update({'date':move.date}) move_id = account_move_obj.create(cr, uid, { 'journal_id': st.journal_id.id, @@ -412,6 +415,7 @@ class account_cash_statement(osv.osv): 'journal_id': st.journal_id.id, 'period_id': st.period_id.id, 'currency_id': st.currency.id, + 'analytic_account_id': move.analytic_account_id and move.analytic_account_id.id or False } amount = res_currency_obj.compute(cr, uid, st.currency.id, @@ -432,8 +436,28 @@ class account_cash_statement(osv.osv): move.account_id.currency_id.id, amount, context=context, account=acc_cur) val['amount_currency'] = amount_cur + move_line_id = account_move_line_obj.create(cr, uid, val , context=context) + torec.append(move_line_id) - torec.append(account_move_line_obj.create(cr, uid, val , context=context)) + if move.analytic_account_id: + anal_val = {} + amt = (val['credit'] or 0.0) - (val['debit'] or 0.0) + anal_val = { + 'name': val['name'], + 'ref': val['ref'], + 'date': val['date'], + 'amount': amt, + 'account_id': val['analytic_account_id'], + 'currency_id': val['currency_id'], + 'general_account_id': val['account_id'], + 'journal_id': st.journal_id.analytic_journal_id.id, + 'period_id': val['period_id'], + 'user_id': uid, + 'move_id': move_line_id + } + if val.get('amount_currency', False): + anal_val['amount_currency'] = val['amount_currency'] + account_analytic_line_obj.create(cr, uid, anal_val, context=context) if move.reconcile_id and move.reconcile_id.line_new_ids: for newline in move.reconcile_id.line_new_ids: @@ -482,7 +506,7 @@ class account_cash_statement(osv.osv): context=context): if line.state <> 'valid': raise osv.except_osv(_('Error !'), - _('Ledger Posting line "%s" is not valid') % line.name) + _('Journal Item "%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) @@ -498,9 +522,8 @@ class account_cash_statement(osv.osv): 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) - - if st.journal_id.entry_posted: - account_move_obj.write(cr, uid, [move_id], {'state':'posted'}) + move_name = st.name + ' - ' + str(move.sequence) + account_move_obj.write(cr, uid, [move_id], {'state':'posted', 'name': move_name}) done.append(st.id) vals = { diff --git a/addons/account/account_installer.xml b/addons/account/account_installer.xml index b0a0e8e059e..a262dc5eb7f 100644 --- a/addons/account/account_installer.xml +++ b/addons/account/account_installer.xml @@ -8,13 +8,13 @@
- Accounting System Configuration + Accounting Modules Configuration
Configure Your Accounting System - 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 your accounting system. By default, Chart of Account is matching to your country. If there are not chart of account certified for your county, you can install the generic chart of account. Configure @@ -66,28 +66,24 @@
- Extra Accounting Modules Installation + Accounting Modules Configuration
- Install Extra Accounting Modules In Your Accounting System + Extra Accounting Modules From this screen, you can install extra accounting modules in your accounting system. Select the modules to directly install them. If you do not think you need any of these right now, you can easily install them later. - 23 - - - - - - - - - + + + + + +
@@ -123,18 +119,8 @@ 5 always + - - ir.actions.todo - account_installer_action_replace - tree - - - -