[MERGE] sale, purchase, stock: refactoring of invoice creation (Alexis de Lattre, Raphael Valyi)
bzr revid: rco@openerp.com-20120131105322-80x7fp2u1z5fyo6o
This commit is contained in:
commit
eea68d6981
|
@ -58,18 +58,24 @@ class stock_picking(osv.osv):
|
||||||
'purchase_id': False,
|
'purchase_id': False,
|
||||||
}
|
}
|
||||||
|
|
||||||
def _get_address_invoice(self, cr, uid, picking):
|
def _get_partner_to_invoice(self, cr, uid, picking, context=None):
|
||||||
""" Gets invoice address of a partner
|
""" Inherit the original function of the 'stock' module
|
||||||
@return {'contact': address, 'invoice': address} for invoice
|
We select the partner of the sale order as the partner of the customer invoice
|
||||||
"""
|
"""
|
||||||
res = super(stock_picking, self)._get_address_invoice(cr, uid, picking)
|
|
||||||
if picking.purchase_id:
|
if picking.purchase_id:
|
||||||
partner_obj = self.pool.get('res.partner')
|
return picking.purchase_id.partner_id
|
||||||
partner = picking.purchase_id.partner_id or picking.address_id.partner_id
|
return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context)
|
||||||
data = partner_obj.address_get(cr, uid, [partner.id],
|
|
||||||
['contact', 'invoice'])
|
def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
|
||||||
res.update(data)
|
""" Inherit the original function of the 'stock' module in order to override some
|
||||||
return res
|
values if the picking has been generated by a purchase order
|
||||||
|
"""
|
||||||
|
invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context)
|
||||||
|
if picking.purchase_id:
|
||||||
|
invoice_vals['address_contact_id'], invoice_vals['address_invoice_id'] = \
|
||||||
|
self.pool.get('res.partner').address_get(cr, uid, [partner.id], ['contact', 'invoice']).values()
|
||||||
|
invoice_vals['fiscal_position'] = picking.purchase_id.fiscal_position.id
|
||||||
|
return invoice_vals
|
||||||
|
|
||||||
def get_currency_id(self, cursor, user, picking):
|
def get_currency_id(self, cursor, user, picking):
|
||||||
if picking.purchase_id:
|
if picking.purchase_id:
|
||||||
|
@ -111,6 +117,11 @@ class stock_picking(osv.osv):
|
||||||
def _invoice_line_hook(self, cursor, user, move_line, invoice_line_id):
|
def _invoice_line_hook(self, cursor, user, move_line, invoice_line_id):
|
||||||
if move_line.purchase_line_id:
|
if move_line.purchase_line_id:
|
||||||
invoice_line_obj = self.pool.get('account.invoice.line')
|
invoice_line_obj = self.pool.get('account.invoice.line')
|
||||||
|
purchase_line_obj = self.pool.get('purchase.order.line')
|
||||||
|
purchase_line_obj.write(cursor, user, [move_line.purchase_line_id.id], {
|
||||||
|
'invoiced': True,
|
||||||
|
'invoice_lines': [(4, invoice_line_id)],
|
||||||
|
})
|
||||||
invoice_line_obj.write(cursor, user, [invoice_line_id], {'note': move_line.purchase_line_id.notes,})
|
invoice_line_obj.write(cursor, user, [invoice_line_id], {'note': move_line.purchase_line_id.notes,})
|
||||||
return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id)
|
return super(stock_picking, self)._invoice_line_hook(cursor, user, move_line, invoice_line_id)
|
||||||
|
|
||||||
|
|
|
@ -981,9 +981,12 @@ class sale_order_line(osv.osv):
|
||||||
'price_unit': 0.0,
|
'price_unit': 0.0,
|
||||||
}
|
}
|
||||||
|
|
||||||
def invoice_line_create(self, cr, uid, ids, context=None):
|
def _prepare_order_line_invoice_line(self, cr, uid, ids, line, account_id=False, context=None):
|
||||||
if context is None:
|
""" Builds the invoice line dict from a sale order line
|
||||||
context = {}
|
@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 _get_line_qty(line):
|
def _get_line_qty(line):
|
||||||
if (line.order_id.invoice_quantity=='order') or not line.procurement_id:
|
if (line.order_id.invoice_quantity=='order') or not line.procurement_id:
|
||||||
|
@ -1003,24 +1006,21 @@ class sale_order_line(osv.osv):
|
||||||
return self.pool.get('procurement.order').uom_get(cr, uid,
|
return self.pool.get('procurement.order').uom_get(cr, uid,
|
||||||
line.procurement_id.id, context=context)
|
line.procurement_id.id, context=context)
|
||||||
|
|
||||||
create_ids = []
|
|
||||||
sales = {}
|
|
||||||
for line in self.browse(cr, uid, ids, context=context):
|
|
||||||
if not line.invoiced:
|
if not line.invoiced:
|
||||||
|
if not account_id:
|
||||||
if line.product_id:
|
if line.product_id:
|
||||||
a = line.product_id.product_tmpl_id.property_account_income.id
|
account_id = line.product_id.product_tmpl_id.property_account_income.id
|
||||||
if not a:
|
if not account_id:
|
||||||
a = line.product_id.categ_id.property_account_income_categ.id
|
account_id = line.product_id.categ_id.property_account_income_categ.id
|
||||||
if not a:
|
if not account_id:
|
||||||
raise osv.except_osv(_('Error !'),
|
raise osv.except_osv(_('Error !'),
|
||||||
_('There is no income account defined ' \
|
_('There is no income account defined for this product: "%s" (id:%d)') % \
|
||||||
'for this product: "%s" (id:%d)') % \
|
|
||||||
(line.product_id.name, line.product_id.id,))
|
(line.product_id.name, line.product_id.id,))
|
||||||
else:
|
else:
|
||||||
prop = self.pool.get('ir.property').get(cr, uid,
|
prop = self.pool.get('ir.property').get(cr, uid,
|
||||||
'property_account_income_categ', 'product.category',
|
'property_account_income_categ', 'product.category',
|
||||||
context=context)
|
context=context)
|
||||||
a = prop and prop.id or False
|
account_id = prop and prop.id or False
|
||||||
uosqty = _get_line_qty(line)
|
uosqty = _get_line_qty(line)
|
||||||
uos_id = _get_line_uom(line)
|
uos_id = _get_line_uom(line)
|
||||||
pu = 0.0
|
pu = 0.0
|
||||||
|
@ -1028,14 +1028,14 @@ class sale_order_line(osv.osv):
|
||||||
pu = round(line.price_unit * line.product_uom_qty / uosqty,
|
pu = round(line.price_unit * line.product_uom_qty / uosqty,
|
||||||
self.pool.get('decimal.precision').precision_get(cr, uid, 'Sale Price'))
|
self.pool.get('decimal.precision').precision_get(cr, uid, 'Sale Price'))
|
||||||
fpos = line.order_id.fiscal_position or False
|
fpos = line.order_id.fiscal_position or False
|
||||||
a = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, a)
|
account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, fpos, account_id)
|
||||||
if not a:
|
if not account_id:
|
||||||
raise osv.except_osv(_('Error !'),
|
raise osv.except_osv(_('Error !'),
|
||||||
_('There is no income category account defined in default Properties for Product Category or Fiscal Position is not defined !'))
|
_('There is no income category account defined in default Properties for Product Category or Fiscal Position is not defined !'))
|
||||||
inv_id = self.pool.get('account.invoice.line').create(cr, uid, {
|
return {
|
||||||
'name': line.name,
|
'name': line.name,
|
||||||
'origin': line.order_id.name,
|
'origin': line.order_id.name,
|
||||||
'account_id': a,
|
'account_id': account_id,
|
||||||
'price_unit': pu,
|
'price_unit': pu,
|
||||||
'quantity': uosqty,
|
'quantity': uosqty,
|
||||||
'discount': line.discount,
|
'discount': line.discount,
|
||||||
|
@ -1044,15 +1044,28 @@ class sale_order_line(osv.osv):
|
||||||
'invoice_line_tax_id': [(6, 0, [x.id for x in line.tax_id])],
|
'invoice_line_tax_id': [(6, 0, [x.id for x in line.tax_id])],
|
||||||
'note': line.notes,
|
'note': line.notes,
|
||||||
'account_analytic_id': line.order_id.project_id and line.order_id.project_id.id or False,
|
'account_analytic_id': line.order_id.project_id and line.order_id.project_id.id or False,
|
||||||
})
|
}
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def invoice_line_create(self, cr, uid, ids, context=None):
|
||||||
|
if context is None:
|
||||||
|
context = {}
|
||||||
|
|
||||||
|
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)
|
||||||
|
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))
|
cr.execute('insert into sale_order_line_invoice_rel (order_line_id,invoice_id) values (%s,%s)', (line.id, inv_id))
|
||||||
self.write(cr, uid, [line.id], {'invoiced': True})
|
self.write(cr, uid, [line.id], {'invoiced': True})
|
||||||
sales[line.order_id.id] = True
|
sales.add(line.order_id.id)
|
||||||
create_ids.append(inv_id)
|
create_ids.append(inv_id)
|
||||||
# Trigger workflow events
|
# Trigger workflow events
|
||||||
wf_service = netsvc.LocalService("workflow")
|
wf_service = netsvc.LocalService("workflow")
|
||||||
for sid in sales.keys():
|
for sale_id in sales:
|
||||||
wf_service.trg_write(uid, 'sale.order', sid, cr)
|
wf_service.trg_write(uid, 'sale.order', sale_id, cr)
|
||||||
return create_ids
|
return create_ids
|
||||||
|
|
||||||
def button_cancel(self, cr, uid, ids, context=None):
|
def button_cancel(self, cr, uid, ids, context=None):
|
||||||
|
|
|
@ -48,24 +48,32 @@ class stock_picking(osv.osv):
|
||||||
else:
|
else:
|
||||||
return super(stock_picking, self).get_currency_id(cursor, user, picking)
|
return super(stock_picking, self).get_currency_id(cursor, user, picking)
|
||||||
|
|
||||||
def _get_payment_term(self, cursor, user, picking):
|
def _get_partner_to_invoice(self, cr, uid, picking, context=None):
|
||||||
if picking.sale_id and picking.sale_id.payment_term:
|
""" Inherit the original function of the 'stock' module
|
||||||
return picking.sale_id.payment_term.id
|
We select the partner of the sale order as the partner of the customer invoice
|
||||||
return super(stock_picking, self)._get_payment_term(cursor, user, picking)
|
"""
|
||||||
|
|
||||||
def _get_address_invoice(self, cursor, user, picking):
|
|
||||||
res = {}
|
|
||||||
if picking.sale_id:
|
if picking.sale_id:
|
||||||
res['contact'] = picking.sale_id.partner_order_id.id
|
return picking.sale_id.partner_id
|
||||||
res['invoice'] = picking.sale_id.partner_invoice_id.id
|
return super(stock_picking, self)._get_partner_to_invoice(cr, uid, picking, context=context)
|
||||||
return res
|
|
||||||
return super(stock_picking, self)._get_address_invoice(cursor, user, picking)
|
|
||||||
|
|
||||||
def _get_comment_invoice(self, cursor, user, picking):
|
def _get_comment_invoice(self, cursor, user, picking):
|
||||||
if picking.note or (picking.sale_id and picking.sale_id.note):
|
if picking.note or (picking.sale_id and picking.sale_id.note):
|
||||||
return picking.note or picking.sale_id.note
|
return picking.note or picking.sale_id.note
|
||||||
return super(stock_picking, self)._get_comment_invoice(cursor, user, picking)
|
return super(stock_picking, self)._get_comment_invoice(cursor, user, picking)
|
||||||
|
|
||||||
|
def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
|
||||||
|
""" Inherit the original function of the 'stock' module in order to override some
|
||||||
|
values if the picking has been generated by a sale order
|
||||||
|
"""
|
||||||
|
invoice_vals = super(stock_picking, self)._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context)
|
||||||
|
if picking.sale_id:
|
||||||
|
invoice_vals['address_contact_id'] = picking.sale_id.partner_order_id.id
|
||||||
|
invoice_vals['address_invoice_id'] = picking.sale_id.partner_invoice_id.id
|
||||||
|
invoice_vals['fiscal_position'] = picking.sale_id.fiscal_position.id
|
||||||
|
invoice_vals['payment_term'] = picking.sale_id.payment_term.id
|
||||||
|
invoice_vals['user_id'] = picking.sale_id.user_id.id
|
||||||
|
return invoice_vals
|
||||||
|
|
||||||
def _get_price_unit_invoice(self, cursor, user, move_line, type):
|
def _get_price_unit_invoice(self, cursor, user, move_line, type):
|
||||||
if move_line.sale_line_id and move_line.sale_line_id.product_id.id == move_line.product_id.id:
|
if move_line.sale_line_id and move_line.sale_line_id.product_id.id == move_line.product_id.id:
|
||||||
uom_id = move_line.product_id.uom_id.id
|
uom_id = move_line.product_id.uom_id.id
|
||||||
|
@ -167,30 +175,15 @@ class stock_picking(osv.osv):
|
||||||
if not account_id:
|
if not account_id:
|
||||||
account_id = sale_line.product_id.categ_id.\
|
account_id = sale_line.product_id.categ_id.\
|
||||||
property_account_expense_categ.id
|
property_account_expense_categ.id
|
||||||
price_unit = sale_line.price_unit
|
|
||||||
discount = sale_line.discount
|
|
||||||
tax_ids = sale_line.tax_id
|
|
||||||
tax_ids = map(lambda x: x.id, tax_ids)
|
|
||||||
|
|
||||||
account_analytic_id = self._get_account_analytic_invoice(cursor,
|
vals = order_line_obj._prepare_order_line_invoice_line(cursor, user, ids, sale_line, account_id, context)
|
||||||
user, picking, sale_line)
|
if vals: #note: in some cases we may not want to include all service lines as invoice lines
|
||||||
|
vals['name'] = name
|
||||||
account_id = fiscal_position_obj.map_account(cursor, user, picking.sale_id.partner_id.property_account_position, account_id)
|
vals['account_analytic_id'] = self._get_account_analytic_invoice(cursor, user, picking, sale_line)
|
||||||
invoice = invoices[result[picking.id]]
|
vals['invoice_id'] = invoices[result[picking.id]].id
|
||||||
invoice_line_id = invoice_line_obj.create(cursor, user, {
|
invoice_line_id = invoice_line_obj.create(cursor, user, vals, context=context)
|
||||||
'name': name,
|
order_line_obj.write(cursor, user, [sale_line.id], {
|
||||||
'invoice_id': invoice.id,
|
'invoiced': True,
|
||||||
'uos_id': sale_line.product_uos.id or sale_line.product_uom.id,
|
|
||||||
'product_id': sale_line.product_id.id,
|
|
||||||
'account_id': account_id,
|
|
||||||
'price_unit': price_unit,
|
|
||||||
'discount': discount,
|
|
||||||
'quantity': sale_line.product_uos_qty,
|
|
||||||
'invoice_line_tax_id': [(6, 0, tax_ids)],
|
|
||||||
'account_analytic_id': account_analytic_id,
|
|
||||||
'notes':sale_line.notes
|
|
||||||
}, context=context)
|
|
||||||
order_line_obj.write(cursor, user, [sale_line.id], {'invoiced': True,
|
|
||||||
'invoice_lines': [(6, 0, [invoice_line_id])],
|
'invoice_lines': [(6, 0, [invoice_line_id])],
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
##############################################################################
|
||||||
#
|
#
|
||||||
# OpenERP, Open Source Management Solution
|
# OpenERP, Open Source Management Solution
|
||||||
|
@ -864,21 +865,13 @@ class stock_picking(osv.osv):
|
||||||
def get_currency_id(self, cr, uid, picking):
|
def get_currency_id(self, cr, uid, picking):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _get_payment_term(self, cr, uid, picking):
|
def _get_partner_to_invoice(self, cr, uid, picking, context=None):
|
||||||
""" Gets payment term from partner.
|
""" Gets the partner that will be invoiced
|
||||||
@return: Payment term
|
Note that this function is inherited in the sale module
|
||||||
|
@param picking: object of the picking for which we are selecting the partner to invoice
|
||||||
|
@return: object of the partner to invoice
|
||||||
"""
|
"""
|
||||||
partner = picking.address_id.partner_id
|
return picking.address_id and picking.address_id.partner_id
|
||||||
return partner.property_payment_term and partner.property_payment_term.id or False
|
|
||||||
|
|
||||||
def _get_address_invoice(self, cr, uid, picking):
|
|
||||||
""" Gets invoice address of a partner
|
|
||||||
@return {'contact': address, 'invoice': address} for invoice
|
|
||||||
"""
|
|
||||||
partner_obj = self.pool.get('res.partner')
|
|
||||||
partner = picking.address_id.partner_id
|
|
||||||
return partner_obj.address_get(cr, uid, [partner.id],
|
|
||||||
['contact', 'invoice'])
|
|
||||||
|
|
||||||
def _get_comment_invoice(self, cr, uid, picking):
|
def _get_comment_invoice(self, cr, uid, picking):
|
||||||
"""
|
"""
|
||||||
|
@ -958,6 +951,113 @@ class stock_picking(osv.osv):
|
||||||
inv_type = 'out_invoice'
|
inv_type = 'out_invoice'
|
||||||
return inv_type
|
return inv_type
|
||||||
|
|
||||||
|
def _prepare_invoice_group(self, cr, uid, picking, partner, invoice, context=None):
|
||||||
|
""" Builds the dict for grouped invoices
|
||||||
|
@param picking: picking object
|
||||||
|
@param partner: object of the partner to invoice (not used here, but may be usefull if this function is inherited)
|
||||||
|
@param invoice: object of the invoice that we are updating
|
||||||
|
@return: dict that will be used to update the invoice
|
||||||
|
"""
|
||||||
|
comment = self._get_comment_invoice(cr, uid, picking)
|
||||||
|
return {
|
||||||
|
'name': (invoice.name or '') + ', ' + (picking.name or ''),
|
||||||
|
'origin': (invoice.origin or '') + ', ' + (picking.name or '') + (picking.origin and (':' + picking.origin) or ''),
|
||||||
|
'comment': (comment and (invoice.comment and invoice.comment + "\n" + comment or comment)) or (invoice.comment and invoice.comment or ''),
|
||||||
|
'date_invoice': context.get('date_inv', False),
|
||||||
|
'user_id': uid,
|
||||||
|
}
|
||||||
|
|
||||||
|
def _prepare_invoice(self, cr, uid, picking, partner, inv_type, journal_id, context=None):
|
||||||
|
""" Builds the dict containing the values for the invoice
|
||||||
|
@param picking: picking object
|
||||||
|
@param partner: object of the partner to invoice
|
||||||
|
@param inv_type: type of the invoice ('out_invoice', 'in_invoice', ...)
|
||||||
|
@param journal_id: ID of the accounting journal
|
||||||
|
@return: dict that will be used to create the invoice object
|
||||||
|
"""
|
||||||
|
if inv_type in ('out_invoice', 'out_refund'):
|
||||||
|
account_id = partner.property_account_receivable.id
|
||||||
|
else:
|
||||||
|
account_id = partner.property_account_payable.id
|
||||||
|
address_contact_id, address_invoice_id = \
|
||||||
|
self.pool.get('res.partner').address_get(cr, uid, [partner.id],
|
||||||
|
['contact', 'invoice']).values()
|
||||||
|
comment = self._get_comment_invoice(cr, uid, picking)
|
||||||
|
invoice_vals = {
|
||||||
|
'name': picking.name,
|
||||||
|
'origin': (picking.name or '') + (picking.origin and (':' + picking.origin) or ''),
|
||||||
|
'type': inv_type,
|
||||||
|
'account_id': account_id,
|
||||||
|
'partner_id': partner.id,
|
||||||
|
'address_invoice_id': address_invoice_id,
|
||||||
|
'address_contact_id': address_contact_id,
|
||||||
|
'comment': comment,
|
||||||
|
'payment_term': partner.property_payment_term and partner.property_payment_term.id or False,
|
||||||
|
'fiscal_position': partner.property_account_position.id,
|
||||||
|
'date_invoice': context.get('date_inv', False),
|
||||||
|
'company_id': picking.company_id.id,
|
||||||
|
'user_id': uid,
|
||||||
|
}
|
||||||
|
cur_id = self.get_currency_id(cr, uid, picking)
|
||||||
|
if cur_id:
|
||||||
|
invoice_vals['currency_id'] = cur_id
|
||||||
|
if journal_id:
|
||||||
|
invoice_vals['journal_id'] = journal_id
|
||||||
|
return invoice_vals
|
||||||
|
|
||||||
|
def _prepare_invoice_line(self, cr, uid, group, picking, move_line, invoice_id,
|
||||||
|
invoice_vals, context=None):
|
||||||
|
""" Builds the dict containing the values for the invoice line
|
||||||
|
@param group: True or False
|
||||||
|
@param picking: picking object
|
||||||
|
@param: move_line: move_line object
|
||||||
|
@param: invoice_id: ID of the related invoice
|
||||||
|
@param: invoice_vals: dict used to created the invoice
|
||||||
|
@return: dict that will be used to create the invoice line
|
||||||
|
"""
|
||||||
|
if group:
|
||||||
|
name = (picking.name or '') + '-' + move_line.name
|
||||||
|
else:
|
||||||
|
name = move_line.name
|
||||||
|
origin = move_line.picking_id.name or ''
|
||||||
|
if move_line.picking_id.origin:
|
||||||
|
origin += ':' + move_line.picking_id.origin
|
||||||
|
|
||||||
|
if invoice_vals['type'] in ('out_invoice', 'out_refund'):
|
||||||
|
account_id = move_line.product_id.product_tmpl_id.\
|
||||||
|
property_account_income.id
|
||||||
|
if not account_id:
|
||||||
|
account_id = move_line.product_id.categ_id.\
|
||||||
|
property_account_income_categ.id
|
||||||
|
else:
|
||||||
|
account_id = move_line.product_id.product_tmpl_id.\
|
||||||
|
property_account_expense.id
|
||||||
|
if not account_id:
|
||||||
|
account_id = move_line.product_id.categ_id.\
|
||||||
|
property_account_expense_categ.id
|
||||||
|
if invoice_vals['fiscal_position']:
|
||||||
|
fp_obj = self.pool.get('account.fiscal.position')
|
||||||
|
fiscal_position = fp_obj.browse(cr, uid, invoice_vals['fiscal_position'], context=context)
|
||||||
|
account_id = fp_obj.map_account(cr, uid, fiscal_position, account_id)
|
||||||
|
# set UoS if it's a sale and the picking doesn't have one
|
||||||
|
uos_id = move_line.product_uos and move_line.product_uos.id or False
|
||||||
|
if not uos_id and invoice_vals['type'] in ('out_invoice', 'out_refund'):
|
||||||
|
uos_id = move_line.product_uom.id
|
||||||
|
|
||||||
|
return {
|
||||||
|
'name': name,
|
||||||
|
'origin': origin,
|
||||||
|
'invoice_id': invoice_id,
|
||||||
|
'uos_id': uos_id,
|
||||||
|
'product_id': move_line.product_id.id,
|
||||||
|
'account_id': account_id,
|
||||||
|
'price_unit': self._get_price_unit_invoice(cr, uid, move_line, invoice_vals['type']),
|
||||||
|
'discount': self._get_discount_invoice(cr, uid, move_line),
|
||||||
|
'quantity': move_line.product_uos_qty or move_line.product_qty,
|
||||||
|
'invoice_line_tax_id': [(6, 0, self._get_taxes_invoice(cr, uid, move_line, invoice_vals['type']))],
|
||||||
|
'account_analytic_id': self._get_account_analytic_invoice(cr, uid, picking, move_line),
|
||||||
|
}
|
||||||
|
|
||||||
def action_invoice_create(self, cr, uid, ids, journal_id=False,
|
def action_invoice_create(self, cr, uid, ids, journal_id=False,
|
||||||
group=False, type='out_invoice', context=None):
|
group=False, type='out_invoice', context=None):
|
||||||
""" Creates invoice based on the invoice state selected for picking.
|
""" Creates invoice based on the invoice state selected for picking.
|
||||||
|
@ -971,14 +1071,13 @@ class stock_picking(osv.osv):
|
||||||
|
|
||||||
invoice_obj = self.pool.get('account.invoice')
|
invoice_obj = self.pool.get('account.invoice')
|
||||||
invoice_line_obj = self.pool.get('account.invoice.line')
|
invoice_line_obj = self.pool.get('account.invoice.line')
|
||||||
address_obj = self.pool.get('res.partner.address')
|
|
||||||
invoices_group = {}
|
invoices_group = {}
|
||||||
res = {}
|
res = {}
|
||||||
inv_type = type
|
inv_type = type
|
||||||
for picking in self.browse(cr, uid, ids, context=context):
|
for picking in self.browse(cr, uid, ids, context=context):
|
||||||
if picking.invoice_state != '2binvoiced':
|
if picking.invoice_state != '2binvoiced':
|
||||||
continue
|
continue
|
||||||
partner = picking.address_id and picking.address_id.partner_id
|
partner = self._get_partner_to_invoice(cr, uid, picking, context=context)
|
||||||
if not partner:
|
if not partner:
|
||||||
raise osv.except_osv(_('Error, no partner !'),
|
raise osv.except_osv(_('Error, no partner !'),
|
||||||
_('Please put a partner on the picking list if you want to generate invoice.'))
|
_('Please put a partner on the picking list if you want to generate invoice.'))
|
||||||
|
@ -986,100 +1085,23 @@ class stock_picking(osv.osv):
|
||||||
if not inv_type:
|
if not inv_type:
|
||||||
inv_type = self._get_invoice_type(picking)
|
inv_type = self._get_invoice_type(picking)
|
||||||
|
|
||||||
if inv_type in ('out_invoice', 'out_refund'):
|
|
||||||
account_id = partner.property_account_receivable.id
|
|
||||||
else:
|
|
||||||
account_id = partner.property_account_payable.id
|
|
||||||
address_contact_id, address_invoice_id = \
|
|
||||||
self._get_address_invoice(cr, uid, picking).values()
|
|
||||||
address = address_obj.browse(cr, uid, address_contact_id, context=context)
|
|
||||||
|
|
||||||
comment = self._get_comment_invoice(cr, uid, picking)
|
|
||||||
if group and partner.id in invoices_group:
|
if group and partner.id in invoices_group:
|
||||||
invoice_id = invoices_group[partner.id]
|
invoice_id = invoices_group[partner.id]
|
||||||
invoice = invoice_obj.browse(cr, uid, invoice_id)
|
invoice = invoice_obj.browse(cr, uid, invoice_id)
|
||||||
invoice_vals = {
|
invoice_vals_group = self._prepare_invoice_group(cr, uid, picking, partner, invoice, context=context)
|
||||||
'name': (invoice.name or '') + ', ' + (picking.name or ''),
|
invoice_obj.write(cr, uid, [invoice_id], invoice_vals_group, context=context)
|
||||||
'origin': (invoice.origin or '') + ', ' + (picking.name or '') + (picking.origin and (':' + picking.origin) or ''),
|
|
||||||
'comment': (comment and (invoice.comment and invoice.comment+"\n"+comment or comment)) or (invoice.comment and invoice.comment or ''),
|
|
||||||
'date_invoice':context.get('date_inv',False),
|
|
||||||
'user_id':uid
|
|
||||||
}
|
|
||||||
invoice_obj.write(cr, uid, [invoice_id], invoice_vals, context=context)
|
|
||||||
else:
|
else:
|
||||||
invoice_vals = {
|
invoice_vals = self._prepare_invoice(cr, uid, picking, partner, inv_type, journal_id, context=context)
|
||||||
'name': picking.name,
|
invoice_id = invoice_obj.create(cr, uid, invoice_vals, context=context)
|
||||||
'origin': (picking.name or '') + (picking.origin and (':' + picking.origin) or ''),
|
|
||||||
'type': inv_type,
|
|
||||||
'account_id': account_id,
|
|
||||||
'partner_id': address.partner_id.id,
|
|
||||||
'address_invoice_id': address_invoice_id,
|
|
||||||
'address_contact_id': address_contact_id,
|
|
||||||
'comment': comment,
|
|
||||||
'payment_term': self._get_payment_term(cr, uid, picking),
|
|
||||||
'fiscal_position': partner.property_account_position.id,
|
|
||||||
'date_invoice': context.get('date_inv',False),
|
|
||||||
'company_id': picking.company_id.id,
|
|
||||||
'user_id':uid
|
|
||||||
}
|
|
||||||
cur_id = self.get_currency_id(cr, uid, picking)
|
|
||||||
if cur_id:
|
|
||||||
invoice_vals['currency_id'] = cur_id
|
|
||||||
if journal_id:
|
|
||||||
invoice_vals['journal_id'] = journal_id
|
|
||||||
invoice_id = invoice_obj.create(cr, uid, invoice_vals,
|
|
||||||
context=context)
|
|
||||||
invoices_group[partner.id] = invoice_id
|
invoices_group[partner.id] = invoice_id
|
||||||
res[picking.id] = invoice_id
|
res[picking.id] = invoice_id
|
||||||
for move_line in picking.move_lines:
|
for move_line in picking.move_lines:
|
||||||
if move_line.state == 'cancel':
|
if move_line.state == 'cancel':
|
||||||
continue
|
continue
|
||||||
origin = move_line.picking_id.name or ''
|
vals = self._prepare_invoice_line(cr, uid, group, picking, move_line,
|
||||||
if move_line.picking_id.origin:
|
invoice_id, invoice_vals, context=context)
|
||||||
origin += ':' + move_line.picking_id.origin
|
if vals:
|
||||||
if group:
|
invoice_line_id = invoice_line_obj.create(cr, uid, vals, context=context)
|
||||||
name = (picking.name or '') + '-' + move_line.name
|
|
||||||
else:
|
|
||||||
name = move_line.name
|
|
||||||
|
|
||||||
if inv_type in ('out_invoice', 'out_refund'):
|
|
||||||
account_id = move_line.product_id.product_tmpl_id.\
|
|
||||||
property_account_income.id
|
|
||||||
if not account_id:
|
|
||||||
account_id = move_line.product_id.categ_id.\
|
|
||||||
property_account_income_categ.id
|
|
||||||
else:
|
|
||||||
account_id = move_line.product_id.product_tmpl_id.\
|
|
||||||
property_account_expense.id
|
|
||||||
if not account_id:
|
|
||||||
account_id = move_line.product_id.categ_id.\
|
|
||||||
property_account_expense_categ.id
|
|
||||||
|
|
||||||
price_unit = self._get_price_unit_invoice(cr, uid,
|
|
||||||
move_line, inv_type)
|
|
||||||
discount = self._get_discount_invoice(cr, uid, move_line)
|
|
||||||
tax_ids = self._get_taxes_invoice(cr, uid, move_line, inv_type)
|
|
||||||
account_analytic_id = self._get_account_analytic_invoice(cr, uid, picking, move_line)
|
|
||||||
|
|
||||||
#set UoS if it's a sale and the picking doesn't have one
|
|
||||||
uos_id = move_line.product_uos and move_line.product_uos.id or False
|
|
||||||
if not uos_id and inv_type in ('out_invoice', 'out_refund'):
|
|
||||||
uos_id = move_line.product_uom.id
|
|
||||||
|
|
||||||
account_id = self.pool.get('account.fiscal.position').map_account(cr, uid, partner.property_account_position, account_id)
|
|
||||||
invoice_line_id = invoice_line_obj.create(cr, uid, {
|
|
||||||
'name': name,
|
|
||||||
'origin': origin,
|
|
||||||
'invoice_id': invoice_id,
|
|
||||||
'uos_id': uos_id,
|
|
||||||
'product_id': move_line.product_id.id,
|
|
||||||
'account_id': account_id,
|
|
||||||
'price_unit': price_unit,
|
|
||||||
'discount': discount,
|
|
||||||
'quantity': move_line.product_uos_qty or move_line.product_qty,
|
|
||||||
'invoice_line_tax_id': [(6, 0, tax_ids)],
|
|
||||||
'account_analytic_id': account_analytic_id,
|
|
||||||
}, context=context)
|
|
||||||
self._invoice_line_hook(cr, uid, move_line, invoice_line_id)
|
self._invoice_line_hook(cr, uid, move_line, invoice_line_id)
|
||||||
|
|
||||||
invoice_obj.button_compute(cr, uid, [invoice_id], context=context,
|
invoice_obj.button_compute(cr, uid, [invoice_id], context=context,
|
||||||
|
|
Loading…
Reference in New Issue