Skip to content
Snippets Groups Projects
Commit 493502bc authored by Pratima Gupta's avatar Pratima Gupta
Browse files

[IMP]stock_account: property_cost_method is removed from

product.product and product.template.

And use property_cost_method of product.category everywhare.

In This -
Used property_cost_method of product.category instead of cost_method or property_cost_method of product.template.

This commit is related to task#1866333.
parent ba9b5ce1
Branches
Tags
No related merge requests found
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record forcecreate="True" id="property_stock_account_output_prd" model="ir.property">
<field name="name">property_stock_account_output</field>
<field name="fields_id" search="[('model','=','product.template'),('name','=','property_stock_account_output')]"/>
<field eval="False" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record forcecreate="True" id="property_stock_account_input_prd" model="ir.property">
<field name="name">property_stock_account_input</field>
<field name="fields_id" search="[('model','=','product.template'),('name','=','property_stock_account_input')]"/>
<field eval="False" name="value"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record forcecreate="True" id="property_stock_account_output_categ_id" model="ir.property">
<field name="name">property_stock_account_output_categ_id</field>
<field name="fields_id" search="[('model','=','product.category'),('name','=','property_stock_account_output_categ_id')]"/>
......
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record forcecreate="True" id="default_cost_method" model="ir.property">
<field name="name">Cost Method Property</field>
<field name="fields_id" ref="field_product_template__property_cost_method"/>
<field name="value" eval="False" />
<field name="type">selection</field>
</record>
<record forcecreate="True" id="default_valuation" model="ir.property">
<field name="name">Valuation Property</field>
<field name="fields_id" ref="field_product_template__property_valuation"/>
<field name="value" eval="False" />
<field name="type">selection</field>
</record>
<record forcecreate="True" id="default_category_cost_method" model="ir.property">
<field name="name">Cost Method Property</field>
......
......@@ -12,62 +12,11 @@ class ProductTemplate(models.Model):
_name = 'product.template'
_inherit = 'product.template'
property_valuation = fields.Selection([
('manual_periodic', 'Periodic (manual)'),
('real_time', 'Perpetual (automated)')], string='Inventory Valuation',
company_dependent=True, copy=True, default='manual_periodic',
help="""Manual: The accounting entries to value the inventory are not posted automatically.
Automated: An accounting entry is automatically created to value the inventory when a product enters or leaves the company.""")
valuation = fields.Char(compute='_compute_valuation_type', inverse='_set_valuation_type')
property_cost_method = fields.Selection([
('standard', 'Standard Price'),
('fifo', 'First In First Out (FIFO)'),
('average', 'Average Cost (AVCO)')], string='Costing Method',
company_dependent=True, copy=True,
help="""Standard Price: The products are valued at their standard cost defined on the product.
Average Cost (AVCO): The products are valued at weighted average cost.
First In First Out (FIFO): The products are valued supposing those that enter the company first will also leave it first.""")
cost_method = fields.Char(compute='_compute_cost_method', inverse='_set_cost_method')
property_stock_account_input = fields.Many2one(
'account.account', 'Stock Input Account',
company_dependent=True, domain=[('deprecated', '=', False)],
help="When doing real-time inventory valuation, counterpart journal items for all incoming stock moves will be posted in this account, unless "
"there is a specific valuation account set on the source location. When not set on the product, the one from the product category is used.")
property_stock_account_output = fields.Many2one(
'account.account', 'Stock Output Account',
company_dependent=True, domain=[('deprecated', '=', False)],
help="When doing real-time inventory valuation, counterpart journal items for all outgoing stock moves will be posted in this account, unless "
"there is a specific valuation account set on the destination location. When not set on the product, the one from the product category is used.")
@api.one
@api.depends('property_valuation', 'categ_id.property_valuation')
def _compute_valuation_type(self):
self.valuation = self.property_valuation or self.categ_id.property_valuation
@api.one
def _set_valuation_type(self):
return self.write({'property_valuation': self.valuation})
@api.one
@api.depends('property_cost_method', 'categ_id.property_cost_method')
def _compute_cost_method(self):
self.cost_method = self.property_cost_method or self.categ_id.property_cost_method
cost_method = fields.Selection(related="categ_id.property_cost_method", readonly=True)
valuation = fields.Selection(related="categ_id.property_valuation", readonly=True)
def _is_cost_method_standard(self):
return self.property_cost_method == 'standard'
@api.one
def _set_cost_method(self):
# When going from FIFO to AVCO or to standard, we update the standard price with the
# average value in stock.
if self.property_cost_method == 'fifo' and self.cost_method in ['average', 'standard']:
# Cannot use the `stock_value` computed field as it's already invalidated when
# entering this method.
valuation = sum([variant._sum_remaining_values()[0] for variant in self.product_variant_ids])
qty_available = self.with_context(company_owned=True).qty_available
if qty_available:
self.standard_price = valuation / qty_available
return self.write({'property_cost_method': self.cost_method})
return self.categ_id.property_cost_method == 'standard'
@api.multi
def _get_product_accounts(self):
......@@ -77,8 +26,8 @@ class ProductTemplate(models.Model):
accounts = super(ProductTemplate, self)._get_product_accounts()
res = self._get_asset_accounts()
accounts.update({
'stock_input': res['stock_input'] or self.property_stock_account_input or self.categ_id.property_stock_account_input_categ_id,
'stock_output': res['stock_output'] or self.property_stock_account_output or self.categ_id.property_stock_account_output_categ_id,
'stock_input': res['stock_input'] or self.categ_id.property_stock_account_input_categ_id,
'stock_output': res['stock_output'] or self.categ_id.property_stock_account_output_categ_id,
'stock_valuation': self.categ_id.property_stock_valuation_account_id or False,
})
return accounts
......@@ -177,7 +126,7 @@ class ProductProduct(models.Model):
return sum(moves.mapped('remaining_value')), moves
@api.multi
@api.depends('stock_move_ids.product_qty', 'stock_move_ids.state', 'stock_move_ids.remaining_value', 'product_tmpl_id.cost_method', 'product_tmpl_id.standard_price', 'product_tmpl_id.property_valuation', 'product_tmpl_id.categ_id.property_valuation')
@api.depends('stock_move_ids.product_qty', 'stock_move_ids.state', 'stock_move_ids.remaining_value', 'product_tmpl_id.cost_method', 'product_tmpl_id.standard_price', 'product_tmpl_id.categ_id.property_valuation')
def _compute_stock_value(self):
StockMove = self.env['stock.move']
to_date = self.env.context.get('to_date')
......@@ -402,6 +351,14 @@ class ProductCategory(models.Model):
input_and_output_accounts = category.property_stock_account_input_categ_id | category.property_stock_account_output_categ_id
if valuation_account and valuation_account in input_and_output_accounts:
raise ValidationError(_('The Stock Input and/or Output accounts cannot be the same than the Stock Valuation account.'))
@api.multi
def write(self, vals):
# When going from FIFO to AVCO or to standard, we update the standard price with the
# average value in stock.
cost_method = vals.get('property_cost_method')
if cost_method and cost_method in ['average', 'standard']:
self._update_standard_price()
return super(ProductCategory, self).write(vals)
@api.onchange('property_cost_method')
def onchange_property_valuation(self):
......@@ -414,3 +371,12 @@ class ProductCategory(models.Model):
'message': _("Changing your cost method is an important change that will impact your inventory valuation. Are you sure you want to make that change?"),
}
}
def _update_standard_price(self):
updated_categories = self.filtered(lambda x: x.property_cost_method == 'fifo')
templates = self.env['product.template'].search([('categ_id', 'in', updated_categories.ids)])
for t in templates:
valuation = sum([variant._sum_remaining_values()[0] for variant in t.product_variant_ids])
qty_available = t.with_context(company_owned=True).qty_available
if qty_available:
t.standard_price = valuation / qty_available
......@@ -476,8 +476,6 @@ class StockMove(models.Model):
def _run_fifo_vacuum(self):
# Call `_fifo_vacuum` on concerned moves
fifo_valued_products = self.env['product.product']
fifo_valued_products |= self.env['product.template'].search([('property_cost_method', '=', 'fifo')]).mapped(
'product_variant_ids')
fifo_valued_categories = self.env['product.category'].search([('property_cost_method', '=', 'fifo')])
fifo_valued_products |= self.env['product.product'].search([('categ_id', 'child_of', fifo_valued_categories.ids)])
moves_to_vacuum = self.env['stock.move']
......
......@@ -35,7 +35,6 @@
<field name="list_price" position="after">
<field name="valuation" invisible="1" readonly="1"/>
<field name="cost_method" invisible="1" readonly="1"/>
<field name="property_cost_method" invisible="1"/>
</field>
<field name="standard_price" position="replace">
<field name="standard_price"
......@@ -49,15 +48,6 @@
class="oe_link oe_read_only"/>
</div>
</field>
<group name="accounting" position="inside">
<group name="property_inventory_valuation" string="Stock Valuation" attrs="{'invisible': ['|', ('type','=','service'), ('valuation', '!=', 'real_time')]}" groups="account.group_account_user">
<field name="property_valuation" invisible="1"/>
<field name="property_stock_account_input"
domain="[('deprecated', '=', False)]"/>
<field name="property_stock_account_output"
domain="[('deprecated', '=', False)]"/>
</group>
</group>
</data>
</field>
</record>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment