Skip to content

Commit

Permalink
[FIX] stock_account, sale_stock, purchase: anglo saxon accounting fix…
Browse files Browse the repository at this point in the history
…ed. It now correctly created the cost of good sold lines when selling a stockable product in perpetual valuation. Was broken since the sale-pocalypse merge, I suppose. Was PR odoo#8717
  • Loading branch information
jco-odoo authored and qdp-odoo committed Sep 30, 2015
1 parent d212f90 commit fabf900
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 52 deletions.
27 changes: 14 additions & 13 deletions addons/purchase/invoice.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,19 +61,13 @@ def purchase_order_change(self):
self.invoice_line_ids = result
return {}


class AccountInvoiceLine(models.Model):
""" Override AccountInvoice_line to add the link to the purchase order line it is related to"""
_inherit = 'account.invoice.line'
purchase_line_id = fields.Many2one('purchase.order.line', 'Purchase Order Line', ondelete='set null', select=True, readonly=True)

@api.model
def move_line_get(self, invoice_id):
res = super(AccountInvoiceLine, self).move_line_get(invoice_id)
invoice = self.browse(invoice_id)
def invoice_line_move_line_get(self):
res = super(AccountInvoice, self).invoice_line_move_line_get()

if self.env.user.company_id.anglo_saxon_accounting:
if invoice.type in ['in_invoice', 'in_refund']:
for i_line in invoice.invoice_line_ids:
if self.type in ['in_invoice', 'in_refund']:
for i_line in self.invoice_line_ids:
res.extend(self._anglo_saxon_purchase_move_lines(i_line, res))
return res

Expand All @@ -87,7 +81,7 @@ def _anglo_saxon_purchase_move_lines(self, i_line, res):
inv = i_line.invoice_id
company_currency = inv.company_id.currency_id
if i_line.product_id and i_line.product_id.valuation == 'real_time':
if i_line.product_id.type != 'service':
if i_line.product_id.type in ('product', 'consu'):
# get the price difference account at the product
acc = i_line.product_id.property_account_creditor_price_difference and i_line.product_id.property_account_creditor_price_difference.id
if not acc:
Expand All @@ -102,7 +96,7 @@ def _anglo_saxon_purchase_move_lines(self, i_line, res):
oa = i_line.product_id.categ_id.property_stock_account_input_categ_id and i_line.product_id.categ_id.property_stock_account_input_categ_id.id
if oa:
# get the fiscal position
fpos = i_line.invoice_id.fiscal_position_id or False
fpos = i_line.invoice_id.fiscal_position_id
a = fpos.map_account(oa)
diff_res = []
account_prec = inv.company_id.currency_id.decimal_places
Expand Down Expand Up @@ -140,3 +134,10 @@ def _anglo_saxon_purchase_move_lines(self, i_line, res):
})
return diff_res
return []


class AccountInvoiceLine(models.Model):
""" Override AccountInvoice_line to add the link to the purchase order line it is related to"""
_inherit = 'account.invoice.line'
purchase_line_id = fields.Many2one('purchase.order.line', 'Purchase Order Line', ondelete='set null', select=True, readonly=True)

43 changes: 43 additions & 0 deletions addons/sale_stock/sale_stock.py
Original file line number Diff line number Diff line change
Expand Up @@ -253,3 +253,46 @@ def _compute_sale_id(self):
self.sale_id = sale_order.id if sale_order else False

sale_id = fields.Many2one(comodel_name='sale.order', string="Sale Order", compute='_compute_sale_id')


class AccountInvoiceLine(models.Model):
_inherit = "account.invoice.line"

def _get_price_unit(self):
price_unit = super(AccountInvoiceLine,self)._get_price_unit()
# in case of anglo saxon with a product configured as invoiced based on delivery, with perpetual
# valuation and real price costing method, we must find the real price for the cost of good sold
uom_obj = self.env['product.uom']
if self.product_id.invoice_policy == "delivery":
for s_line in self.sale_line_ids:
# qtys already invoiced
qty_done = sum([uom_obj._compute_qty_obj(x.uom_id, x.quantity, x.product_id.uom_id) for x in s_line.invoice_lines if x.invoice_id.state in ('open', 'paid')])
quantity = uom_obj._compute_qty_obj(self.uom_id, self.quantity, self.product_id.uom_id)
# Put moves in fixed order by date executed
moves = self.env['stock.move']
for procurement in s_line.procurement_ids:
moves |= procurement.move_ids
moves.sorted(lambda x: x.date)
# Go through all the moves and do nothing until you get to qty_done
# Beyond qty_done we need to calculate the average of the price_unit
# on the moves we encounter.
average_price_unit = 0
qty_delivered = 0
invoiced_qty = 0
for move in moves:
if move.state != 'done':
continue
invoiced_qty += move.product_qty
if invoiced_qty <= qty_done:
continue
qty_to_consider = move.product_qty
if invoiced_qty - move.product_qty < qty_done:
qty_to_consider = invoiced_qty - qty_done
qty_to_consider = min(qty_to_consider, quantity - qty_delivered)
qty_delivered += qty_to_consider
average_price_unit = (average_price_unit * (qty_delivered - qty_to_consider) + move.price_unit * qty_to_consider) / qty_delivered
if qty_delivered == quantity:
break
price_unit = average_price_unit or price_unit
price_unit = uom_obj._compute_qty_obj(self.uom_id, price_unit, self.product_id.uom_id)
return price_unit
68 changes: 29 additions & 39 deletions addons/stock_account/stock_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,18 +27,9 @@ def post_inventory(self, cr, uid, inv, context=None):
class account_invoice_line(osv.osv):
_inherit = "account.invoice.line"

_columns = {
'move_id': fields.many2one('stock.move', string="Move line", help="If the invoice was generated from a stock transfer, specify the reference to the related stock move."),
}

def move_line_get(self, cr, uid, invoice_id, context=None):
res = super(account_invoice_line,self).move_line_get(cr, uid, invoice_id, context=context)
if self.company_id.anglo_saxon_accounting:
inv = self.pool.get('account.invoice').browse(cr, uid, invoice_id, context=context)
if inv.type in ('out_invoice','out_refund'):
for i_line in inv.invoice_line_ids:
res.extend(self._anglo_saxon_sale_move_lines(cr, uid, i_line, res, context=context))
return res
def _get_price_unit(self):
self.ensure_one()
return self.product_id.standard_price

def _get_price(self, cr, uid, inv, company_currency, i_line, price_unit):
cur_obj = self.pool.get('res.currency')
Expand All @@ -57,7 +48,20 @@ def get_invoice_line_account(self, type, product, fpos, company):
return accounts['stock_ouput']
return super(account_invoice_line, self).get_invoice_line_account(type, product, fpos, company)

def _anglo_saxon_sale_move_lines(self, cr, uid, i_line, res, context=None):
class account_invoice(osv.osv):
_inherit = "account.invoice"

@api.model
def invoice_line_move_line_get(self):
res = super(account_invoice,self).invoice_line_move_line_get()
if self.company_id.anglo_saxon_accounting:
if self.type in ('out_invoice','out_refund'):
for i_line in self.invoice_line_ids:
res.extend(self._anglo_saxon_sale_move_lines(i_line))
return res

@api.model
def _anglo_saxon_sale_move_lines(self, i_line):
"""Return the additional move lines for sales invoices and refunds.
i_line: An account.invoice.line object.
Expand All @@ -66,32 +70,21 @@ def _anglo_saxon_sale_move_lines(self, cr, uid, i_line, res, context=None):
inv = i_line.invoice_id
company_currency = inv.company_id.currency_id.id

if i_line.product_id.type == 'product' and i_line.product_id.valuation == 'real_time':
if i_line.product_id.type in ('product', 'consu') and i_line.product_id.valuation == 'real_time':
accounts = i_line.product_id.product_tmpl_id.get_product_accounts()
# debit account dacc will be the output account
# first check the product, if empty check the category
dacc = i_line.product_id.property_stock_account_output and i_line.product_id.property_stock_account_output.id
if not dacc:
dacc = i_line.product_id.categ_id.property_stock_account_output_categ_id and i_line.product_id.categ_id.property_stock_account_output_categ_id.id
# in both cases the credit account cacc will be the expense account
# first check the product, if empty check the category
cacc = i_line.product_id.property_account_expense_id and i_line.product_id.property_account_expense_id.id
if not cacc:
cacc = i_line.product_id.categ_id.property_account_expense_categ_id and i_line.product_id.categ_id.property_account_expense_categ_id.id
dacc = accounts['stock_output'].id
# credit account cacc will be the expense account
cacc = accounts['expense'].id
if dacc and cacc:
if i_line.move_id:
price = i_line.move_id.product_id.standard_price
from_unit = i_line.move_id.product_tmpl_id.uom_id.id
to_unit = i_line.move_id.product_uom.id
price_unit = self.pool['product.uom']._compute_price(cr, uid, from_unit, price, to_uom_id=to_unit)
else:
price_unit = i_line.product_id.standard_price
price_unit = i_line._get_price_unit()
return [
{
'type':'src',
'name': i_line.name[:64],
'price_unit':price_unit,
'quantity':i_line.quantity,
'price':self._get_price(cr, uid, inv, company_currency, i_line, price_unit),
'price_unit': price_unit,
'quantity': i_line.quantity,
'price': self.env['account.invoice.line']._get_price(inv, company_currency, i_line, price_unit),
'account_id':dacc,
'product_id':i_line.product_id.id,
'uom_id':i_line.uom_id.id,
Expand All @@ -102,9 +95,9 @@ def _anglo_saxon_sale_move_lines(self, cr, uid, i_line, res, context=None):
{
'type':'src',
'name': i_line.name[:64],
'price_unit':price_unit,
'quantity':i_line.quantity,
'price': -1 * self._get_price(cr, uid, inv, company_currency, i_line, price_unit),
'price_unit': price_unit,
'quantity': i_line.quantity,
'price': -1 * self.env['account.invoice.line']._get_price(inv, company_currency, i_line, price_unit),
'account_id':cacc,
'product_id':i_line.product_id.id,
'uom_id':i_line.uom_id.id,
Expand All @@ -114,9 +107,6 @@ def _anglo_saxon_sale_move_lines(self, cr, uid, i_line, res, context=None):
]
return []

class account_invoice(osv.osv):
_inherit = "account.invoice"

def _prepare_refund(self, cr, uid, invoice, date_invoice=None, date=None, description=None, journal_id=None, context=None):
invoice_data = super(account_invoice, self)._prepare_refund(cr, uid, invoice, date, date,
description, journal_id, context=context)
Expand Down

0 comments on commit fabf900

Please sign in to comment.