[IMP] purchase_stock, stock_account: handle invoice before receipt
In some buisness case when the invoice is done before the receipt, the `stock.valuation.layer` price unit will be taken on the invoice rather than the `purchase.order.line` Part-of: odoo/odoo#99411
This commit is contained in:
@@ -29,10 +29,33 @@ class StockMove(models.Model):
|
||||
def _get_price_unit(self):
|
||||
""" Returns the unit price for the move"""
|
||||
self.ensure_one()
|
||||
if self.purchase_line_id and self.product_id.id:
|
||||
price_unit_prec = self.env['decimal.precision'].precision_get('Product Price')
|
||||
line = self.purchase_line_id
|
||||
order = line.order_id
|
||||
if not self.purchase_line_id or not self.product_id.id:
|
||||
return super(StockMove, self)._get_price_unit()
|
||||
price_unit_prec = self.env['decimal.precision'].precision_get('Product Price')
|
||||
line = self.purchase_line_id
|
||||
order = line.order_id
|
||||
received_qty = line.qty_received
|
||||
if self.state == 'done':
|
||||
received_qty -= self.product_uom._compute_quantity(self.quantity_done, line.product_uom)
|
||||
if line.qty_invoiced > received_qty:
|
||||
move_layer = line.move_ids.stock_valuation_layer_ids
|
||||
invoiced_layer = line.invoice_lines.stock_valuation_layer_ids
|
||||
receipt_value = sum(move_layer.mapped('value')) + sum(invoiced_layer.mapped('value'))
|
||||
invoiced_value = 0
|
||||
invoiced_qty = 0
|
||||
for invoice_line in line.invoice_lines:
|
||||
if invoice_line.tax_ids:
|
||||
invoiced_value += invoice_line.tax_ids.with_context(round=False).compute_all(
|
||||
invoice_line.price_unit, currency=invoice_line.account_id.currency_id, quantity=invoice_line.quantity)['total_void']
|
||||
else:
|
||||
invoiced_value += invoice_line.price_unit * invoice_line.quantity
|
||||
invoiced_qty += invoice_line.product_uom_id._compute_quantity(invoice_line.quantity, line.product_id.uom_id)
|
||||
# TODO currency check
|
||||
remaining_value = invoiced_value - receipt_value
|
||||
# TODO qty_received in product uom
|
||||
remaining_qty = invoiced_qty - line.product_uom._compute_quantity(received_qty, line.product_id.uom_id)
|
||||
price_unit = float_round(remaining_value / remaining_qty, precision_digits=price_unit_prec)
|
||||
else:
|
||||
price_unit = line.price_unit
|
||||
if line.taxes_id:
|
||||
qty = line.product_qty or 1
|
||||
@@ -40,15 +63,14 @@ class StockMove(models.Model):
|
||||
price_unit = float_round(price_unit / qty, precision_digits=price_unit_prec)
|
||||
if line.product_uom.id != line.product_id.uom_id.id:
|
||||
price_unit *= line.product_uom.factor / line.product_id.uom_id.factor
|
||||
if order.currency_id != order.company_id.currency_id:
|
||||
# The date must be today, and not the date of the move since the move move is still
|
||||
# in assigned state. However, the move date is the scheduled date until move is
|
||||
# done, then date of actual move processing. See:
|
||||
# https://github.com/odoo/odoo/blob/2f789b6863407e63f90b3a2d4cc3be09815f7002/addons/stock/models/stock_move.py#L36
|
||||
price_unit = order.currency_id._convert(
|
||||
price_unit, order.company_id.currency_id, order.company_id, fields.Date.context_today(self), round=False)
|
||||
return price_unit
|
||||
return super(StockMove, self)._get_price_unit()
|
||||
if order.currency_id != order.company_id.currency_id:
|
||||
# The date must be today, and not the date of the move since the move move is still
|
||||
# in assigned state. However, the move date is the scheduled date until move is
|
||||
# done, then date of actual move processing. See:
|
||||
# https://github.com/odoo/odoo/blob/2f789b6863407e63f90b3a2d4cc3be09815f7002/addons/stock/models/stock_move.py#L36
|
||||
price_unit = order.currency_id._convert(
|
||||
price_unit, order.company_id.currency_id, order.company_id, fields.Date.context_today(self), round=False)
|
||||
return price_unit
|
||||
|
||||
def _generate_valuation_lines_data(self, partner_id, qty, debit_value, credit_value, debit_account_id, credit_account_id, svl_id, description):
|
||||
""" Overridden from stock_account to support amount_currency on valuation lines generated from po
|
||||
|
||||
@@ -247,6 +247,8 @@ class AccountMove(models.Model):
|
||||
class AccountMoveLine(models.Model):
|
||||
_inherit = 'account.move.line'
|
||||
|
||||
stock_valuation_layer_ids = fields.One2many('stock.valuation.layer', 'account_move_line_id', string='Stock Valuation Layer')
|
||||
|
||||
def _compute_account_id(self):
|
||||
super()._compute_account_id()
|
||||
input_lines = self.filtered(lambda line: (
|
||||
|
||||
Reference in New Issue
Block a user