X-Git-Url: http://git.inspyration.org/?a=blobdiff_plain;f=addons%2Faccount%2Faccount_invoice.py;h=f324a07d684b27d83331b62e45cf0d6e9513f627;hb=96bcaadd46e7685de3f5267506f051f47e601624;hp=2a7a0fb3b88b3362812427eef0dfa8e08a33400e;hpb=40c193d193bc94c79fc853f98829366bd6c2bfa0;p=odoo%2Fodoo.git diff --git a/addons/account/account_invoice.py b/addons/account/account_invoice.py index 2a7a0fb..f324a07 100644 --- a/addons/account/account_invoice.py +++ b/addons/account/account_invoice.py @@ -24,9 +24,10 @@ from lxml import etree import openerp.addons.decimal_precision as dp import openerp.exceptions -from openerp import netsvc +from openerp import netsvc, SUPERUSER_ID from openerp import pooler from openerp.osv import fields, osv, orm +from openerp.tools import float_compare from openerp.tools.translate import _ class account_invoice(osv.osv): @@ -53,9 +54,12 @@ class account_invoice(osv.osv): company_id = context.get('company_id', user.company_id.id) type2journal = {'out_invoice': 'sale', 'in_invoice': 'purchase', 'out_refund': 'sale_refund', 'in_refund': 'purchase_refund'} journal_obj = self.pool.get('account.journal') - res = journal_obj.search(cr, uid, [('type', '=', type2journal.get(type_inv, 'sale')), - ('company_id', '=', company_id)], - limit=1) + domain = [('company_id', '=', company_id)] + if isinstance(type_inv, list): + domain.append(('type', 'in', [type2journal.get(type) for type in type_inv if type2journal.get(type)])) + else: + domain.append(('type', '=', type2journal.get(type_inv, 'sale'))) + res = journal_obj.search(cr, uid, domain, limit=1) return res and res[0] or False def _get_currency(self, cr, uid, context=None): @@ -71,7 +75,7 @@ class account_invoice(osv.osv): tt = type2journal.get(type_inv, 'sale') result = self.pool.get('account.analytic.journal').search(cr, uid, [('type','=',tt)], context=context) if not result: - raise osv.except_osv(_('No Analytic Journal !'),_("You must define an analytic journal of type '%s'!") % (tt,)) + raise osv.except_osv(_('No Analytic Journal!'),_("You must define an analytic journal of type '%s'!") % (tt,)) return result[0] def _get_type(self, cr, uid, context=None): @@ -98,7 +102,7 @@ class account_invoice(osv.osv): ctx = context.copy() result = {} currency_obj = self.pool.get('res.currency') - for invoice in self.browse(cr, uid, ids, context=context): + for invoice in self.browse(cr, SUPERUSER_ID, ids, context=context): nb_inv_in_partial_rec = max_invoice_id = 0 result[invoice.id] = 0.0 if invoice.move_id: @@ -114,7 +118,7 @@ class account_invoice(osv.osv): #we check if the invoice is partially reconciled and if there are other invoices #involved in this partial reconciliation (and we sum these invoices) for line in aml.reconcile_partial_id.line_partial_ids: - if line.invoice: + if line.invoice and invoice.type == line.invoice.type: nb_inv_in_partial_rec += 1 #store the max invoice id as for this invoice we will make a balance instead of a simple division max_invoice_id = max(max_invoice_id, line.invoice.id) @@ -174,6 +178,8 @@ class account_invoice(osv.osv): lines = [] if invoice.move_id: for m in invoice.move_id.line_id: + if m.account_id != invoice.account_id: + continue temp_lines = [] if m.reconcile_id: temp_lines = map(lambda x: x.id, m.reconcile_id.line_id) @@ -295,7 +301,8 @@ class account_invoice(osv.osv): }, multi='all'), 'currency_id': fields.many2one('res.currency', 'Currency', required=True, readonly=True, states={'draft':[('readonly',False)]}, track_visibility='always'), - 'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}), + 'journal_id': fields.many2one('account.journal', 'Journal', required=True, readonly=True, states={'draft':[('readonly',False)]}, + domain="[('type', 'in', {'out_invoice': ['sale'], 'out_refund': ['sale_refund'], 'in_refund': ['purchase_refund'], 'in_invoice': ['purchase']}.get(type, [])), ('company_id', '=', company_id)]"), 'company_id': fields.many2one('res.company', 'Company', required=True, change_default=True, readonly=True, states={'draft':[('readonly',False)]}), 'check_total': fields.float('Verification Total', digits_compute=dp.get_precision('Account'), readonly=True, states={'draft':[('readonly',False)]}), 'reconciled': fields.function(_reconciled, string='Paid/Reconciled', type='boolean', @@ -316,7 +323,7 @@ class account_invoice(osv.osv): 'account.move.reconcile': (_get_invoice_from_reconcile, None, 50), }, help="Remaining amount due."), - 'payment_ids': fields.function(_compute_lines, relation='account.move.line', type="many2many", string='Payments'), + 'payment_ids': fields.function(_compute_lines, relation='account.move.line', type="many2many", string='Payments', groups='base.group_user'), 'move_name': fields.char('Journal Entry', size=64, readonly=True, states={'draft':[('readonly',False)]}), 'user_id': fields.many2one('res.users', 'Salesperson', readonly=True, track_visibility='onchange', states={'draft':[('readonly',False)]}), 'fiscal_position': fields.many2one('account.fiscal.position', 'Fiscal Position', readonly=True, states={'draft':[('readonly',False)]}) @@ -348,13 +355,22 @@ class account_invoice(osv.osv): if context.get('active_model', '') in ['res.partner'] and context.get('active_ids', False) and context['active_ids']: partner = self.pool.get(context['active_model']).read(cr, uid, context['active_ids'], ['supplier','customer'])[0] if not view_type: - view_id = self.pool.get('ir.ui.view').search(cr, uid, [('name', '=', 'account.invoice.tree')]) + try: + view_id = self.pool['ir.model.data'].get_object_reference(cr, uid, 'account', 'invoice_tree')[1] + except ValueError: + view_id = self.pool.get('ir.ui.view').search(cr, uid, [('name', '=', 'account.invoice.tree')], limit=1) view_type = 'tree' if view_type == 'form': if partner['supplier'] and not partner['customer']: - view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name', '=', 'account.invoice.supplier.form')]) + try: + view_id = self.pool['ir.model.data'].get_object_reference(cr, uid, 'account', 'invoice_supplier_form')[1] + except ValueError: + view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name', '=', 'account.invoice.supplier.form')], limit=1) elif partner['customer'] and not partner['supplier']: - view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name', '=', 'account.invoice.form')]) + try: + view_id = self.pool['ir.model.data'].get_object_reference(cr, uid, 'account', 'invoice_form')[1] + except ValueError: + view_id = self.pool.get('ir.ui.view').search(cr,uid,[('name', '=', 'account.invoice.form')], limit=1) if view_id and isinstance(view_id, (list, tuple)): view_id = view_id[0] res = super(account_invoice,self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar, submenu=submenu) @@ -557,10 +573,14 @@ class account_invoice(osv.osv): def onchange_payment_term_date_invoice(self, cr, uid, ids, payment_term_id, date_invoice): res = {} + if isinstance(ids, (int, long)): + ids = [ids] if not date_invoice: - date_invoice = time.strftime('%Y-%m-%d') + date_invoice = fields.date.context_today(self, cr, uid) if not payment_term_id: - return {'value':{'date_due': date_invoice}} #To make sure the invoice has a due date when no payment term + inv = self.browse(cr, uid, ids[0]) + #To make sure the invoice due date should contain due date which is entered by user when there is no payment term defined + return {'value':{'date_due': inv.date_due and inv.date_due or date_invoice}} pterm_list = self.pool.get('account.payment.term').compute(cr, uid, payment_term_id, value=1, date_ref=date_invoice) if pterm_list: pterm_list = [line[0] for line in pterm_list] @@ -627,7 +647,7 @@ class account_invoice(osv.osv): obj_l = account_obj.browse(cr, uid, inv_line[2]['account_id']) if obj_l.company_id.id != company_id: raise osv.except_osv(_('Configuration Error!'), - _('Invoice line account\'s company and invoice\'s compnay does not match.')) + _('Invoice line account\'s company and invoice\'s company does not match.')) else: continue if company_id and type: @@ -769,7 +789,7 @@ class account_invoice(osv.osv): else: ref = self._convert_ref(cr, uid, inv.number) if not inv.journal_id.analytic_journal_id: - raise osv.except_osv(_('No Analytic Journal !'),_("You have to define an analytic journal on the '%s' journal!") % (inv.journal_id.name,)) + raise osv.except_osv(_('No Analytic Journal!'),_("You have to define an analytic journal on the '%s' journal!") % (inv.journal_id.name,)) il['analytic_lines'] = [(0,0, { 'name': il['name'], 'date': inv['date_invoice'], @@ -816,7 +836,8 @@ class account_invoice(osv.osv): if not key in compute_taxes: raise osv.except_osv(_('Warning!'), _('Global taxes defined, but they are not in invoice lines !')) base = compute_taxes[key]['base'] - if abs(base - tax.base) > company_currency.rounding: + precision = self.pool.get('decimal.precision').precision_get(cr, uid, 'Account') + if float_compare(abs(base - tax.base), company_currency.rounding, precision_digits=precision) == 1: raise osv.except_osv(_('Warning!'), _('Tax base different!\nClick on compute to update the tax base.')) for key in compute_taxes: if not key in tax_key: @@ -830,7 +851,7 @@ class account_invoice(osv.osv): cur_obj = self.pool.get('res.currency') for i in invoice_move_lines: if inv.currency_id.id != company_currency: - context.update({'date': inv.date_invoice or time.strftime('%Y-%m-%d')}) + context.update({'date': inv.date_invoice or fields.date.context_today(self, cr, uid, context=context)}) i['currency_id'] = inv.currency_id.id i['amount_currency'] = i['price'] i['price'] = cur_obj.compute(cr, uid, inv.currency_id.id, @@ -895,14 +916,15 @@ class account_invoice(osv.osv): if not inv.journal_id.sequence_id: raise osv.except_osv(_('Error!'), _('Please define sequence on the journal related to this invoice.')) if not inv.invoice_line: - raise osv.except_osv(_('No Invoice Lines !'), _('Please create some invoice lines.')) + raise osv.except_osv(_('No Invoice Lines!'), _('Please create some invoice lines.')) if inv.move_id: continue ctx = context.copy() ctx.update({'lang': inv.partner_id.lang}) if not inv.date_invoice: - self.write(cr, uid, [inv.id], {'date_invoice': fields.date.context_today(self,cr,uid,context=context)}, context=ctx) + self.write(cr, uid, [inv.id], {'date_invoice': fields.date.context_today(self, cr, uid, context=context)}, context=ctx) + inv.refresh() company_currency = self.pool['res.company'].browse(cr, uid, inv.company_id.id).currency_id.id # create the analytical lines # one move line per invoice line @@ -912,11 +934,9 @@ class account_invoice(osv.osv): self.check_tax_lines(cr, uid, inv, compute_taxes, ait_obj) # I disabled the check_total feature - group_check_total_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'group_supplier_inv_check_total')[1] - group_check_total = self.pool.get('res.groups').browse(cr, uid, group_check_total_id, context=context) - if group_check_total and uid in [x.id for x in group_check_total.users]: + if self.pool['res.users'].has_group(cr, uid, 'account.group_supplier_inv_check_total'): if (inv.type in ('in_invoice', 'in_refund') and abs(inv.check_total - inv.amount_total) >= (inv.currency_id.rounding/2.0)): - raise osv.except_osv(_('Bad total !'), _('Please verify the price of the invoice !\nThe encoded total does not match the computed total.')) + raise osv.except_osv(_('Bad Total!'), _('Please verify the price of the invoice!\nThe encoded total does not match the computed total.')) if inv.payment_term: total_fixed = total_percent = 0 @@ -951,7 +971,7 @@ class account_invoice(osv.osv): total, total_currency, iml = self.compute_invoice_totals(cr, uid, inv, company_currency, ref, iml, context=ctx) acc_id = inv.account_id.id - name = inv['name'] or '/' + name = inv['name'] or inv['supplier_invoice_number'] or '/' totlines = False if inv.payment_term: totlines = payment_term_obj.compute(cr, @@ -998,11 +1018,9 @@ class account_invoice(osv.osv): 'ref': ref }) - date = inv.date_invoice or time.strftime('%Y-%m-%d') - part = self.pool.get("res.partner")._find_accounting_partner(inv.partner_id) - line = map(lambda x:(0,0,self.line_get_convert(cr, uid, x, part.id, date, context=ctx)),iml) + line = map(lambda x:(0,0,self.line_get_convert(cr, uid, x, part.id, inv.date_invoice, context=ctx)),iml) line = self.group_lines(cr, uid, iml, line, inv) @@ -1018,7 +1036,7 @@ class account_invoice(osv.osv): 'ref': inv.reference and inv.reference or inv.name, 'line_id': line, 'journal_id': journal_id, - 'date': date, + 'date': inv.date_invoice, 'narration': inv.comment, 'company_id': inv.company_id.id, } @@ -1234,7 +1252,7 @@ class account_invoice(osv.osv): refund_journal_ids = obj_journal.search(cr, uid, [('type','=','sale_refund')], context=context) if not date: - date = time.strftime('%Y-%m-%d') + date = fields.date.context_today(self, cr, uid, context=context) invoice_data.update({ 'type': type_dict[invoice['type']], 'date_invoice': date, @@ -1400,6 +1418,7 @@ class account_invoice_line(osv.osv): _name = "account.invoice.line" _description = "Invoice Line" + _order = "invoice_id,sequence,id" _columns = { 'name': fields.text('Description', required=True), 'origin': fields.char('Source Document', size=256, help="Reference of the document that produced this invoice."), @@ -1436,6 +1455,7 @@ class account_invoice_line(osv.osv): 'discount': 0.0, 'price_unit': _price_unit_default, 'account_id': _default_account_id, + 'sequence': 10, } def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): @@ -1459,7 +1479,7 @@ class account_invoice_line(osv.osv): context = dict(context) context.update({'company_id': company_id, 'force_company': company_id}) if not partner_id: - raise osv.except_osv(_('No Partner Defined !'),_("You must first select a partner !") ) + raise osv.except_osv(_('No Partner Defined!'),_("You must first select a partner!") ) if not product: if type in ('in_invoice', 'in_refund'): return {'value': {}, 'domain':{'product_uom':[]}} @@ -1556,8 +1576,7 @@ class account_invoice_line(osv.osv): company_currency = self.pool['res.company'].browse(cr, uid, inv.company_id.id).currency_id.id for line in inv.invoice_line: mres = self.move_line_get_item(cr, uid, line, context) - if not mres: - continue + mres['invl_id'] = line.id res.append(mres) tax_code_found= False for tax in tax_obj.compute_all(cr, uid, line.invoice_line_tax_id, @@ -1670,7 +1689,7 @@ class account_invoice_tax(osv.osv): if company_id: company_currency = company_obj.read(cr, uid, [company_id], ['currency_id'])[0]['currency_id'][0] if currency_id and company_currency: - base = cur_obj.compute(cr, uid, currency_id, company_currency, base*factor, context={'date': date_invoice or time.strftime('%Y-%m-%d')}, round=False) + base = cur_obj.compute(cr, uid, currency_id, company_currency, base*factor, context={'date': date_invoice or fields.date.context_today(self, cr, uid)}, round=False) return {'value': {'base_amount':base}} def amount_change(self, cr, uid, ids, amount, currency_id=False, company_id=False, date_invoice=False): @@ -1683,7 +1702,7 @@ class account_invoice_tax(osv.osv): if company_id: company_currency = company_obj.read(cr, uid, [company_id], ['currency_id'])[0]['currency_id'][0] if currency_id and company_currency: - amount = cur_obj.compute(cr, uid, currency_id, company_currency, amount*factor, context={'date': date_invoice or time.strftime('%Y-%m-%d')}, round=False) + amount = cur_obj.compute(cr, uid, currency_id, company_currency, amount*factor, context={'date': date_invoice or fields.date.context_today(self, cr, uid)}, round=False) return {'value': {'tax_amount': amount}} _order = 'sequence' @@ -1712,15 +1731,15 @@ class account_invoice_tax(osv.osv): if inv.type in ('out_invoice','in_invoice'): val['base_code_id'] = tax['base_code_id'] val['tax_code_id'] = tax['tax_code_id'] - val['base_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['base'] * tax['base_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False) - val['tax_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['amount'] * tax['tax_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False) + val['base_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['base'] * tax['base_sign'], context={'date': inv.date_invoice or fields.date.context_today(self, cr, uid, context=context)}, round=False) + val['tax_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['amount'] * tax['tax_sign'], context={'date': inv.date_invoice or fields.date.context_today(self, cr, uid, context=context)}, round=False) val['account_id'] = tax['account_collected_id'] or line.account_id.id val['account_analytic_id'] = tax['account_analytic_collected_id'] else: val['base_code_id'] = tax['ref_base_code_id'] val['tax_code_id'] = tax['ref_tax_code_id'] - val['base_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['base'] * tax['ref_base_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False) - val['tax_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['amount'] * tax['ref_tax_sign'], context={'date': inv.date_invoice or time.strftime('%Y-%m-%d')}, round=False) + val['base_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['base'] * tax['ref_base_sign'], context={'date': inv.date_invoice or fields.date.context_today(self, cr, uid, context=context)}, round=False) + val['tax_amount'] = cur_obj.compute(cr, uid, inv.currency_id.id, company_currency, val['amount'] * tax['ref_tax_sign'], context={'date': inv.date_invoice or fields.date.context_today(self, cr, uid, context=context)}, round=False) val['account_id'] = tax['account_paid_id'] or line.account_id.id val['account_analytic_id'] = tax['account_analytic_paid_id']