Skip to content

Commit

Permalink
[IMP] Some changes
Browse files Browse the repository at this point in the history
  • Loading branch information
maq-adhoc committed Nov 26, 2024
1 parent 67a37d8 commit ae33f69
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 45 deletions.
1 change: 1 addition & 0 deletions stock_currency_valuation/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
],
'depends': [
'stock_account',
'stock_landed_costs',
'product_replenishment_cost',
],
'data': [
Expand Down
1 change: 1 addition & 0 deletions stock_currency_valuation/models/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
from . import product_product
from . import product_template
from . import stock_move
from . import stock_landed_cost
50 changes: 21 additions & 29 deletions stock_currency_valuation/models/product_template.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,38 @@ class productTemplate(models.Model):
ondelete={'average_in_currency': 'set default'}
)

@api.depends()
@api.depends('standard_price_in_currency')
def _compute_replenishment_cost(self):
use_average_in_currency = self.filtered(lambda x: x.replenishment_cost_type == "average_in_currency")
super(productTemplate, self - use_average_in_currency)._compute_replenishment_cost()
if use_average_in_currency:
company_id = self.env.company
# domain = [
# ('product_tmpl_id', 'in', use_average_in_currency.ids),
# ('company_id', '=', company_id.id),
# ]
# groups = self.env['stock.valuation.layer']._read_group(domain, ['value_in_currency:sum', 'quantity:sum'],
# ['product_tmpl_id'])
# products_avg_cost = {group['product_tmpl_id'][0]: group['value_in_currency'] / group['quantity']
# if group['quantity'] else 0 for group in groups}
for rec in use_average_in_currency:
product_currency = rec.currency_id
#product_cost = products_avg_cost.get(rec.id) or 0
price_unit = rec.valuation_currency_id._convert(
from_amount=rec.standard_price_in_currency,
to_currency=product_currency,
company=company_id,
date=fields.date.today(),
)
rec.update({
'replenishment_base_cost_currency_id': rec.valuation_currency_id.id,
'replenishment_base_cost_on_currency': price_unit,
'replenishment_cost': price_unit,
'replenishment_base_cost': rec.standard_price_in_currency,
})
company_id = self.env.company
for rec in use_average_in_currency:
product_currency = rec.currency_id
replenishment_cost_rule = rec.replenishment_cost_rule_id
replenishment_cost = rec.standard_price_in_currency
if replenishment_cost_rule:
replenishment_cost = replenishment_cost_rule.compute_rule(replenishment_cost, rec)
replenishment_base_cost_on_currency = rec.valuation_currency_id._convert(
from_amount=replenishment_cost,
to_currency=product_currency,
company=company_id,
date=fields.date.today(),
)
rec.update({
'replenishment_base_cost_on_currency': replenishment_base_cost_on_currency,
'replenishment_cost': replenishment_cost,
})

@api.depends_context('company')
@api.depends('product_variant_ids', 'product_variant_ids.standard_price')
def _compute_standard_price_in_currency(self):
# Depends on force_company context because standard_price_in_currency is company_dependent
# on the product_product
# Por ahora hacemos esto porque replishment cost no es compatible al 100% con variantes
# obtenemos el precio del primer producto
unique_variants = self.filtered(lambda template: len(template.product_variant_ids) == 1)
for template in unique_variants:
template.standard_price_in_currency = template.product_variant_ids.standard_price_in_currency
for template in (self - unique_variants):
template.standard_price_in_currency = 0.0
template.standard_price_in_currency = template.product_variant_ids[:1].standard_price_in_currency

def _set_standard_price_in_currency(self):
for template in self:
Expand Down
37 changes: 37 additions & 0 deletions stock_currency_valuation/models/stock_landed_cost.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from odoo import models, api, _
from odoo.tools.safe_eval import safe_eval
from odoo.exceptions import ValidationError
from odoo.tools import float_compare


class StockLandedCost(models.Model):

_inherit = 'stock.landed.cost'

def button_validate(self):
super().button_validate()

return True
class AdjustmentLines(models.Model):

_inherit = 'stock.valuation.adjustment.lines'

def _create_accounting_entries(self, move, qty_out):
AccountMoveLine = super()._create_accounting_entries(move, qty_out)
if self.product_id.categ_id.valuation_currency_id:
amount = AccountMoveLine[0][2]['debit'] or AccountMoveLine[0][2]['credit'] * -1
value_in_currency = self.cost_id.currency_id._convert(
from_amount=amount,
to_currency=self.product_id.categ_id.valuation_currency_id,
company=self.cost_id.company_id,
date=self.create_date,
)
AccountMoveLine[0][2].update(({
'currency_id': self.product_id.categ_id.valuation_currency_id.id,
'amount_currency': value_in_currency
}))
AccountMoveLine[1][2].update(({
'currency_id': self.product_id.categ_id.valuation_currency_id.id,
'amount_currency': value_in_currency * -1
}))
return AccountMoveLine
17 changes: 15 additions & 2 deletions stock_currency_valuation/models/stock_valuation_layer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from odoo.tools.safe_eval import safe_eval
from odoo.exceptions import ValidationError
from odoo.tools import float_compare
from odoo.tools.float_utils import float_is_zero


class StockValuationLayer(models.Model):
Expand All @@ -17,8 +18,7 @@ class StockValuationLayer(models.Model):
@api.depends('categ_id', 'value', 'bypass_currency_valuation', 'stock_valuation_layer_id')
def _compute_other_currency_values(self):
for rec in self:
##rec.stock_valuation_layer_id

# rec.stock_valuation_layer_id
if not rec.bypass_currency_valuation and rec.valuation_currency_id:
rec.value_in_currency = rec.currency_id._convert(
from_amount=rec.value,
Expand All @@ -33,3 +33,16 @@ def _compute_other_currency_values(self):
else:
rec.value_in_currency = False
rec.unit_cost_in_currency = False

@api.model_create_multi
def create(self, vals_list):
res = super().create(vals_list)
res._update_currency_standard_price()
return res

def _update_currency_standard_price(self):
for layer_id in self.filtered(lambda x: x.stock_landed_cost_id and x.product_id.cost_method == 'average' and x.value_in_currency):
# batch standard price computation avoid recompute quantity_svl at each iteration
product = layer_id.product_id.with_company(layer_id.company_id)
if not float_is_zero(product.quantity_svl, precision_rounding=product.uom_id.rounding):
product.sudo().with_context(disable_auto_svl=True).standard_price_in_currency += layer_id.value_in_currency / product.quantity_svl
File renamed without changes.
163 changes: 149 additions & 14 deletions stock_currency_valuation/wizard/stock_valuation_layer_revaluation.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,157 @@
from odoo import models
from odoo import models, fields, _
from odoo.exceptions import UserError
from odoo.tools import float_compare, float_is_zero


class StockValuationLayerRevaluation(models.TransientModel):
_inherit = 'stock.valuation.layer.revaluation'

# def action_validate_revaluation(self):
# res = super().action_validate_revaluation()
# # Update the stardard price in currency in case of AVCO
# product_id = self.product_id.with_company(self.company_id)
# if product_id.categ_id.property_cost_method in ('average', 'fifo') and product_id.categ_id.valuation_currency_id:
# # Para actualizar el costo en currency vuelvo a calcular el valor en moneda
# # Si bien hago dos veces el calculo (en el layer y aqui) esto es mas
# # sencillo que obtener el ultimo layer y agregar el valor.
# value_in_currency = self.currency_id._convert(
# from_amount=self.added_value,
# to_currency=product_id.categ_id.valuation_currency_id,
# company=self.company_id,
# date=self.create_date,
# )

# product_id.with_context(disable_auto_svl=True).standard_price_in_currency += value_in_currency / self.current_quantity_svl
# return res


def action_validate_revaluation(self):
res = super().action_validate_revaluation()
# Update the stardard price in currency in case of AVCO
""" Revaluate the stock for `self.product_id` in `self.company_id`.
- Change the stardard price with the new valuation by product unit.
- Create a manual stock valuation layer with the `added_value` of `self`.
- Distribute the `added_value` on the remaining_value of layers still in stock (with a remaining quantity)
- If the Inventory Valuation of the product category is automated, create
related account move.
"""
self.ensure_one()
if self.currency_id.is_zero(self.added_value):
raise UserError(_("The added value doesn't have any impact on the stock valuation"))

product_id = self.product_id.with_company(self.company_id)
if product_id.categ_id.property_cost_method in ('average', 'fifo') and product_id.categ_id.valuation_currency_id:
# Para actualizar el costo en currency vuelvo a calcular el valor en moneda
# Si bien hago dos veces el calculo (en el layer y aqui) esto es mas
# sencillo que obtener el ultimo layer y agregar el valor.
value_in_currency = self.currency_id._convert(
from_amount=self.added_value,
to_currency=product_id.categ_id.valuation_currency_id,
company=self.company_id,
date=self.create_date,

remaining_svls = self.env['stock.valuation.layer'].search([
('product_id', '=', product_id.id),
('remaining_qty', '>', 0),
('company_id', '=', self.company_id.id),
])

# Create a manual stock valuation layer
if self.reason:
description = _("Manual Stock Valuation: %s.", self.reason)
else:
description = _("Manual Stock Valuation: No Reason Given.")
if product_id.categ_id.property_cost_method == 'average':
description += _(
" Product cost updated from %(previous)s to %(new_cost)s.",
previous=product_id.standard_price,
new_cost=product_id.standard_price + self.added_value / self.current_quantity_svl
)
product_id.with_context(disable_auto_svl=True).standard_price_in_currency += value_in_currency / self.current_quantity_svl
return res
revaluation_svl_vals = {
'company_id': self.company_id.id,
'product_id': product_id.id,
'description': description,
'value': self.added_value,
'quantity': 0,
}

remaining_qty = sum(remaining_svls.mapped('remaining_qty'))
remaining_value = self.added_value
remaining_value_unit_cost = self.currency_id.round(remaining_value / remaining_qty)
for svl in remaining_svls:
if float_is_zero(svl.remaining_qty - remaining_qty, precision_rounding=self.product_id.uom_id.rounding):
taken_remaining_value = remaining_value
else:
taken_remaining_value = remaining_value_unit_cost * svl.remaining_qty
if float_compare(svl.remaining_value + taken_remaining_value, 0, precision_rounding=self.product_id.uom_id.rounding) < 0:
raise UserError(_('The value of a stock valuation layer cannot be negative. Landed cost could be use to correct a specific transfer.'))

svl.remaining_value += taken_remaining_value
remaining_value -= taken_remaining_value
remaining_qty -= svl.remaining_qty

previous_value_svl = self.current_value_svl
revaluation_svl = self.env['stock.valuation.layer'].create(revaluation_svl_vals)

# Update the stardard price in case of AVCO
if product_id.categ_id.property_cost_method in ('average', 'fifo'):
product_id.with_context(disable_auto_svl=True).standard_price += self.added_value / self.current_quantity_svl
if product_id.categ_id.valuation_currency_id:
# Para actualizar el costo en currency vuelvo a calcular el valor en moneda
# Si bien hago dos veces el calculo (en el layer y aqui) esto es mas
# sencillo que obtener el ultimo layer y agregar el valor.
value_in_currency = self.currency_id._convert(
from_amount=self.added_value,
to_currency=product_id.categ_id.valuation_currency_id,
company=self.company_id,
date=self.create_date,
)
product_id.with_context(disable_auto_svl=True).standard_price_in_currency += value_in_currency / self.current_quantity_svl

# If the Inventory Valuation of the product category is automated, create related account move.
if self.property_valuation != 'real_time':
return True

accounts = product_id.product_tmpl_id.get_product_accounts()

if self.added_value < 0:
debit_account_id = self.account_id.id
credit_account_id = accounts.get('stock_valuation') and accounts['stock_valuation'].id
else:
debit_account_id = accounts.get('stock_valuation') and accounts['stock_valuation'].id
credit_account_id = self.account_id.id

move_vals = {
'journal_id': self.account_journal_id.id or accounts['stock_journal'].id,
'company_id': self.company_id.id,
'ref': _("Revaluation of %s", product_id.display_name),
'stock_valuation_layer_ids': [(6, None, [revaluation_svl.id])],
'date': self.date or fields.Date.today(),
'move_type': 'entry',
'line_ids': [(0, 0, {
'name': _('%(user)s changed stock valuation from %(previous)s to %(new_value)s - %(product)s',
user=self.env.user.name,
previous=previous_value_svl,
new_value=previous_value_svl + self.added_value,
product=product_id.display_name,
),
'account_id': debit_account_id,
'debit': abs(self.added_value),
'credit': 0,
'product_id': product_id.id,
}), (0, 0, {
'name': _('%(user)s changed stock valuation from %(previous)s to %(new_value)s - %(product)s',
user=self.env.user.name,
previous=previous_value_svl,
new_value=previous_value_svl + self.added_value,
product=product_id.display_name,
),
'account_id': credit_account_id,
'debit': 0,
'credit': abs(self.added_value),
'product_id': product_id.id,
})],
}
if product_id.categ_id.valuation_currency_id:
move_vals['line_ids'][0][2].update(({
'currency_id': product_id.categ_id.valuation_currency_id.id,
'amount_currency': abs(value_in_currency)
}))
move_vals['line_ids'][1][2].update(({
'currency_id': product_id.categ_id.valuation_currency_id.id,
'amount_currency': abs(value_in_currency) * -1
}))
account_move = self.env['account.move'].create(move_vals)
account_move._post()

return True

0 comments on commit ae33f69

Please sign in to comment.