[MERGE] sale: invoice generation refactoring, courtesy of Alexis de Lattre
bzr revid: odo@openerp.com-20120215173252-0gjpehkjtmw5s1uk
This commit is contained in:
commit
11292d811c
|
@ -393,26 +393,61 @@ class sale_order(osv.osv):
|
|||
def button_dummy(self, cr, uid, ids, context=None):
|
||||
return True
|
||||
|
||||
#FIXME: the method should return the list of invoices created (invoice_ids)
|
||||
# and not the id of the last invoice created (res). The problem is that we
|
||||
# cannot change it directly since the method is called by the sales order
|
||||
# workflow and I suppose it expects a single id...
|
||||
# FIXME: deprecated method, overriders should be using _prepare_invoice() instead.
|
||||
# can be removed after 6.1.
|
||||
def _inv_get(self, cr, uid, order, context=None):
|
||||
return {}
|
||||
|
||||
def _prepare_invoice(self, cr, uid, order, lines, context=None):
|
||||
"""Prepare the dict of values to create the new invoice for a
|
||||
sale order. This method may be overridden to implement custom
|
||||
invoice generation (making sure to call super() to establish
|
||||
a clean extension chain).
|
||||
|
||||
:param browse_record order: sale.order record to invoice
|
||||
:param list(int) line: list of invoice line IDs that must be
|
||||
attached to the invoice
|
||||
:return: dict of value to create() the invoice
|
||||
"""
|
||||
if context is None:
|
||||
context = {}
|
||||
journal_ids = self.pool.get('account.journal').search(cr, uid,
|
||||
[('type', '=', 'sale'), ('company_id', '=', order.company_id.id)],
|
||||
limit=1)
|
||||
if not journal_ids:
|
||||
raise osv.except_osv(_('Error !'),
|
||||
_('There is no sales journal defined for this company: "%s" (id:%d)') % (order.company_id.name, order.company_id.id))
|
||||
|
||||
invoice_vals = {
|
||||
'name': order.client_order_ref or '',
|
||||
'origin': order.name,
|
||||
'type': 'out_invoice',
|
||||
'reference': order.client_order_ref or order.name,
|
||||
'account_id': order.partner_id.property_account_receivable.id,
|
||||
'partner_id': order.partner_id.id,
|
||||
'journal_id': journal_ids[0],
|
||||
'address_invoice_id': order.partner_invoice_id.id,
|
||||
'address_contact_id': order.partner_order_id.id,
|
||||
'invoice_line': [(6, 0, lines)],
|
||||
'currency_id': order.pricelist_id.currency_id.id,
|
||||
'comment': order.note,
|
||||
'payment_term': order.payment_term and order.payment_term.id or False,
|
||||
'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
|
||||
'date_invoice': context.get('date_invoice', False),
|
||||
'company_id': order.company_id.id,
|
||||
'user_id': order.user_id and order.user_id.id or False
|
||||
}
|
||||
|
||||
# Care for deprecated _inv_get() hook - FIXME: to be removed after 6.1
|
||||
invoice_vals.update(self._inv_get(cr, uid, order, context=context))
|
||||
|
||||
return invoice_vals
|
||||
|
||||
def _make_invoice(self, cr, uid, order, lines, context=None):
|
||||
journal_obj = self.pool.get('account.journal')
|
||||
inv_obj = self.pool.get('account.invoice')
|
||||
obj_invoice_line = self.pool.get('account.invoice.line')
|
||||
if context is None:
|
||||
context = {}
|
||||
|
||||
journal_ids = journal_obj.search(cr, uid, [('type', '=', 'sale'), ('company_id', '=', order.company_id.id)], limit=1)
|
||||
if not journal_ids:
|
||||
raise osv.except_osv(_('Error !'),
|
||||
_('There is no sales journal defined for this company: "%s" (id:%d)') % (order.company_id.name, order.company_id.id))
|
||||
a = order.partner_id.property_account_receivable.id
|
||||
pay_term = order.payment_term and order.payment_term.id or False
|
||||
invoiced_sale_line_ids = self.pool.get('sale.order.line').search(cr, uid, [('order_id', '=', order.id), ('invoiced', '=', True)], context=context)
|
||||
from_line_invoice_ids = []
|
||||
for invoiced_sale_line_id in self.pool.get('sale.order.line').browse(cr, uid, invoiced_sale_line_ids, context=context):
|
||||
|
@ -424,28 +459,9 @@ class sale_order(osv.osv):
|
|||
for preline in preinv.invoice_line:
|
||||
inv_line_id = obj_invoice_line.copy(cr, uid, preline.id, {'invoice_id': False, 'price_unit': -preline.price_unit})
|
||||
lines.append(inv_line_id)
|
||||
inv = {
|
||||
'name': order.client_order_ref or '',
|
||||
'origin': order.name,
|
||||
'type': 'out_invoice',
|
||||
'reference': order.client_order_ref or order.name,
|
||||
'account_id': a,
|
||||
'partner_id': order.partner_id.id,
|
||||
'journal_id': journal_ids[0],
|
||||
'address_invoice_id': order.partner_invoice_id.id,
|
||||
'address_contact_id': order.partner_order_id.id,
|
||||
'invoice_line': [(6, 0, lines)],
|
||||
'currency_id': order.pricelist_id.currency_id.id,
|
||||
'comment': order.note,
|
||||
'payment_term': pay_term,
|
||||
'fiscal_position': order.fiscal_position.id or order.partner_id.property_account_position.id,
|
||||
'date_invoice': context.get('date_invoice',False),
|
||||
'company_id': order.company_id.id,
|
||||
'user_id': order.user_id and order.user_id.id or False
|
||||
}
|
||||
inv.update(self._inv_get(cr, uid, order))
|
||||
inv = self._prepare_invoice(cr, uid, order, lines, context=context)
|
||||
inv_id = inv_obj.create(cr, uid, inv, context=context)
|
||||
data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], pay_term, time.strftime(DEFAULT_SERVER_DATE_FORMAT))
|
||||
data = inv_obj.onchange_payment_term_date_invoice(cr, uid, [inv_id], inv['payment_term'], time.strftime(DEFAULT_SERVER_DATE_FORMAT))
|
||||
if data.get('value', False):
|
||||
inv_obj.write(cr, uid, [inv_id], data['value'], context=context)
|
||||
inv_obj.button_compute(cr, uid, [inv_id])
|
||||
|
@ -981,11 +997,16 @@ class sale_order_line(osv.osv):
|
|||
'price_unit': 0.0,
|
||||
}
|
||||
|
||||
def _prepare_order_line_invoice_line(self, cr, uid, ids, line, account_id=False, context=None):
|
||||
""" Builds the invoice line dict from a sale order line
|
||||
@param line: sale order line object
|
||||
@param account_id: the id of the account to force eventually (the method is used for picking return including service)
|
||||
@return: dict that will be used to create the invoice line
|
||||
def _prepare_order_line_invoice_line(self, cr, uid, line, account_id=False, context=None):
|
||||
"""Prepare the dict of values to create the new invoice line for a
|
||||
sale order line. This method may be overridden to implement custom
|
||||
invoice generation (making sure to call super() to establish
|
||||
a clean extension chain).
|
||||
|
||||
:param browse_record line: sale.order.line record to invoice
|
||||
:param int account_id: optional ID of a G/L account to force
|
||||
(this is used for returning products including service)
|
||||
:return: dict of values to create() the invoice line
|
||||
"""
|
||||
|
||||
def _get_line_qty(line):
|
||||
|
@ -1055,7 +1076,7 @@ class sale_order_line(osv.osv):
|
|||
create_ids = []
|
||||
sales = set()
|
||||
for line in self.browse(cr, uid, ids, context=context):
|
||||
vals = self._prepare_order_line_invoice_line(cr, uid, ids, line, False, context)
|
||||
vals = self._prepare_order_line_invoice_line(cr, uid, line, False, context)
|
||||
if vals:
|
||||
inv_id = self.pool.get('account.invoice.line').create(cr, uid, vals, context=context)
|
||||
cr.execute('insert into sale_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
|
||||
|
|
|
@ -176,7 +176,7 @@ class stock_picking(osv.osv):
|
|||
account_id = sale_line.product_id.categ_id.\
|
||||
property_account_expense_categ.id
|
||||
|
||||
vals = order_line_obj._prepare_order_line_invoice_line(cursor, user, ids, sale_line, account_id, context)
|
||||
vals = order_line_obj._prepare_order_line_invoice_line(cursor, user, sale_line, account_id, context)
|
||||
if vals: #note: in some cases we may not want to include all service lines as invoice lines
|
||||
vals['name'] = name
|
||||
vals['account_analytic_id'] = self._get_account_analytic_invoice(cursor, user, picking, sale_line)
|
||||
|
|
Loading…
Reference in New Issue