[REF] stock, stock_account: inventory and valuation report
Kind of switches the behavior for inventory and valuation report, meaning allows the user to see the quantity at date and disallow him to see the valuation at date.
This commit is contained in:
@@ -43,6 +43,7 @@
|
||||
'wizard/stock_immediate_transfer_views.xml',
|
||||
'wizard/stock_backorder_confirmation_views.xml',
|
||||
'wizard/stock_overprocessed_transfer_views.xml',
|
||||
'wizard/stock_quantity_history.xml',
|
||||
|
||||
'views/res_partner_views.xml',
|
||||
'views/product_strategy_views.xml',
|
||||
|
||||
@@ -139,18 +139,6 @@
|
||||
<field name="res_model">stock.quant</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.actions.server" id="quant_merge_action"> <!-- Menu + python -->
|
||||
<field name="name">Merge duplicate quants</field>
|
||||
<field name="model_id" ref="stock.model_stock_quant"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">
|
||||
env['stock.quant']._merge_quants()
|
||||
action = env.ref('stock.quantsact').read()[0]
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem id="menu_quants" name="Inventory" parent="stock.menu_warehouse_report" sequence="100" action="stock.quant_merge_action"/>
|
||||
|
||||
<record id="quant_package_search_view" model="ir.ui.view">
|
||||
<field name="name">stock.quant.package.search</field>
|
||||
<field name="model">stock.quant.package</field>
|
||||
|
||||
@@ -7,3 +7,4 @@ from . import stock_scheduler_compute
|
||||
from . import stock_immediate_transfer
|
||||
from . import stock_backorder_confirmation
|
||||
from . import stock_overprocessed_transfer
|
||||
from . import stock_quantity_history
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class StockQuantityHistory(models.TransientModel):
|
||||
_name = 'stock.quantity.history'
|
||||
_description = 'Stock Quantity History'
|
||||
|
||||
compute_at_date = fields.Selection([
|
||||
(0, 'Current Inventory'),
|
||||
(1, 'At a Specific Date')
|
||||
], string="Compute", help="Choose to analyze the current inventory or from a specific date in the past.")
|
||||
date = fields.Datetime('Inventory at Date', help="Choose a date to get the inventory at that date", default=fields.Datetime.now())
|
||||
|
||||
def open_table(self):
|
||||
self.ensure_one()
|
||||
|
||||
if self.compute_at_date:
|
||||
tree_view_id = self.env.ref('stock.view_stock_product_tree').id
|
||||
form_view_id = self.env.ref('stock.product_form_view_procurement_button').id
|
||||
# We pass `to_date` in the context so that `qty_available` will be computed across
|
||||
# moves until date.
|
||||
action = {
|
||||
'type': 'ir.actions.act_window',
|
||||
'views': [(tree_view_id, 'tree'), (form_view_id, 'form')],
|
||||
'view_mode': 'tree,form',
|
||||
'name': _('Products'),
|
||||
'res_model': 'product.product',
|
||||
'context': dict(self.env.context, to_date=self.date),
|
||||
}
|
||||
return action
|
||||
else:
|
||||
self.env['stock.quant']._merge_quants()
|
||||
return self.env.ref('stock.quantsact').read()[0]
|
||||
+10
-9
@@ -1,8 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="view_wizard_valuation_history" model="ir.ui.view">
|
||||
<field name="name">Inventory Valuation Report</field>
|
||||
<field name="model">wizard.valuation.history</field>
|
||||
<record id="view_stock_quantity_history" model="ir.ui.view">
|
||||
<field name="name">Inventory Report</field>
|
||||
<field name="model">stock.quantity.history</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Choose your date">
|
||||
<group>
|
||||
@@ -12,20 +12,21 @@
|
||||
</group>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="open_table" string="Retrieve the Inventory Value" type="object" class="btn-primary"/>
|
||||
<button name="open_table" string="Retrieve the Inventory Quantities" type="object" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-default" special="cancel" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record id="action_wizard_stock_valuation_history" model="ir.actions.act_window">
|
||||
<field name="name">Inventory Valuation Report</field>
|
||||
<field name="res_model">wizard.valuation.history</field>
|
||||
<record id="action_stock_quantity_history" model="ir.actions.act_window">
|
||||
<field name="name">Inventory Report</field>
|
||||
<field name="res_model">stock.quantity.history</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="view_id" ref="view_wizard_valuation_history"/>
|
||||
<field name="view_id" ref="view_stock_quantity_history"/>
|
||||
<field name="target">new</field>
|
||||
<field name="context">{'default_compute_at_date': 0}</field>
|
||||
</record>
|
||||
<menuitem id="menu_valuation" name="Inventory Valuation" parent="stock.menu_warehouse_report" sequence="110" action="action_wizard_stock_valuation_history"/>
|
||||
<menuitem id="menu_valuation" name="Inventory" parent="stock.menu_warehouse_report" sequence="100" action="action_stock_quantity_history"/>
|
||||
</odoo>
|
||||
|
||||
@@ -30,12 +30,11 @@ Dashboard / Reports for Warehouse Management includes:
|
||||
'security/stock_account_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/stock_change_standard_price_views.xml',
|
||||
'wizard/wizard_valuation_history_views.xml',
|
||||
'views/product_views.xml',
|
||||
'data/stock_account_data.xml',
|
||||
'views/stock_account_views.xml',
|
||||
'views/res_config_settings_views.xml',
|
||||
'data/product_data.xml',
|
||||
'data/stock_account_data.xml',
|
||||
'views/product_views.xml',
|
||||
'data/stock_account_data_post_install.yml',
|
||||
],
|
||||
'test': [
|
||||
|
||||
@@ -26,5 +26,26 @@
|
||||
<field name="value">manual_periodic</field>
|
||||
<field name="type">selection</field>
|
||||
</record>
|
||||
<record id="action_stock_account_valuation_report" model="ir.actions.server">
|
||||
<field name="name">Stock Valuation Report</field>
|
||||
<field name="type">ir.actions.server</field>
|
||||
<field name="state">code</field>
|
||||
<field name="model_id" ref="product.model_product_product"></field>
|
||||
<field name="binding_model_id" ref="product.model_product_product"></field>
|
||||
<field name="code">
|
||||
# Call `_fifo_vacuum` on concerned moves
|
||||
fifo_valued_products = env['product.product']
|
||||
fifo_valued_products |= env['product.template'].search([('property_cost_method', '=', 'fifo')]).mapped('product_variant_ids')
|
||||
fifo_valued_categories = env['product.category'].search([('property_cost_method', '=', 'fifo')])
|
||||
fifo_valued_products |= env['product.product'].search([('categ_id', 'child_of', fifo_valued_categories.ids)])
|
||||
moves_to_vacuum = env['stock.move']
|
||||
Move = env['stock.move']
|
||||
for product in fifo_valued_products:
|
||||
moves_to_vacuum |= Move.search([('product_id', '=', product.id), ('remaining_qty', '<', 0)] + Move._get_all_base_domain())
|
||||
moves_to_vacuum._fifo_vacuum()
|
||||
action = env.ref('stock_account.product_valuation_action').read()[0]
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
</odoo>
|
||||
|
||||
|
||||
@@ -77,8 +77,8 @@ class ProductTemplate(models.Model):
|
||||
@api.multi
|
||||
def action_open_product_moves(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref('stock_account.stock_move_valuation_action').read()[0]
|
||||
action['domain'] = [('product_id.product_tmpl_id', '=', self.id)]
|
||||
action = self.env.ref('stock_account.product_valuation_action').read()[0]
|
||||
action['domain'] = [('product_tmpl_id', '=', self.id)]
|
||||
action['context'] = {
|
||||
'search_default_outgoing': True,
|
||||
'search_default_incoming': True,
|
||||
@@ -172,8 +172,8 @@ class ProductProduct(models.Model):
|
||||
@api.multi
|
||||
def action_open_product_moves(self):
|
||||
self.ensure_one()
|
||||
action = self.env.ref('stock_account.stock_move_valuation_action').read()[0]
|
||||
action['domain'] = [('product_id', '=', self.id)]
|
||||
action = self.env.ref('stock_account.product_valuation_action').read()[0]
|
||||
action['domain'] = [('id', '=', self.id)]
|
||||
action['context'] = {
|
||||
'search_default_outgoing': True,
|
||||
'search_default_incoming': True,
|
||||
|
||||
@@ -107,7 +107,7 @@
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="product_valuation_tree"/>
|
||||
<field name="domain">[('type', '=', 'product')]</field>
|
||||
<field name="domain">[('type', '=', 'product'), ('qty_available', '!=', 0)]</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
|
||||
@@ -49,44 +49,6 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_move_tree_valuation" model="ir.ui.view">
|
||||
<field name="name">stock.move.tree.valuation</field>
|
||||
<field name="model">stock.move</field>
|
||||
<field eval="8" name="priority"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree decoration-muted="state == 'cancel'" decoration-danger="(state not in ('cancel','done')) and date > current_date" string="Moves" create="0">
|
||||
<field name="name"/>
|
||||
<field name="picking_id" string="Reference"/>
|
||||
<field name="origin"/>
|
||||
<field name="picking_type_id" invisible="1"/>
|
||||
<field name="create_date" invisible="1" groups="base.group_no_one"/>
|
||||
<field name="product_id"/>
|
||||
<field name="location_id" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="location_dest_id" groups="stock.group_stock_multi_locations"/>
|
||||
<field name="date" groups="base.group_no_one"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="product_uom_qty" string="Qty"/>
|
||||
<field name="product_uom" options="{'no_open': True, 'no_create': True}" string="Unit of Measure" groups="product.group_uom"/>
|
||||
<field name="price_unit"/>
|
||||
<field name="value" sum="Stock Valuation"/>
|
||||
<field name="remaining_qty" invisible="context.get('is_avg')"/>
|
||||
<field name="remaining_value" sum="Stock Valuation" invisible="context.get('is_avg')"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="stock_move_valuation_action" model="ir.actions.act_window">
|
||||
<field name="name">Stock Moves</field>
|
||||
<field name="res_model">stock.move</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_id" ref="view_move_tree_valuation"/>
|
||||
<field name="search_view_id" ref="stock.view_move_search"/>
|
||||
<field name="context">{'search_default_outgoing': 1, 'search_default_incoming': 1, 'search_default_done': 1, 'search_default_group_by_product': 1}</field>
|
||||
<field name="help" type="html">
|
||||
<p class="oe_view_nocontent_create">
|
||||
Click to create a stock movement.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
<menuitem id="menu_valuation" name="Inventory Valuation" parent="stock.menu_warehouse_report" sequence="110" action="stock_account.action_stock_account_valuation_report"/>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import stock_change_standard_price
|
||||
from . import wizard_valuation_history
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models, fields, _
|
||||
|
||||
|
||||
class WizardValuationHistory(models.TransientModel):
|
||||
_name = 'wizard.valuation.history'
|
||||
_description = 'Wizard that opens the stock valuation history table'
|
||||
|
||||
compute_at_date = fields.Selection([
|
||||
(0, 'Current Inventory'),
|
||||
(1, 'At a Specific Date')
|
||||
], string="Compute", help="Choose to analyze the current inventory or from a specific date in the past.")
|
||||
date = fields.Datetime('Inventory at Date', help="Choose a date to get the inventory at that date", default=fields.Datetime.now())
|
||||
|
||||
@api.multi
|
||||
def open_table(self):
|
||||
self.ensure_one()
|
||||
|
||||
# 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']
|
||||
Move = self.env['stock.move']
|
||||
for product in fifo_valued_products:
|
||||
moves_to_vacuum |= Move.search([('product_id', '=', product.id), ('remaining_qty', '<', 0)] + Move._get_all_base_domain())
|
||||
moves_to_vacuum._fifo_vacuum()
|
||||
|
||||
if self.compute_at_date and self.date:
|
||||
action = self.env['ir.model.data'].xmlid_to_object('stock_account.stock_move_valuation_action')
|
||||
if not action:
|
||||
action = {
|
||||
'view_type': 'form',
|
||||
'view_mode': 'tree',
|
||||
'res_model': 'stock.move',
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
else:
|
||||
action = action[0].read()[0]
|
||||
|
||||
action['domain'] = "[('date', '<=', '" + self.date + "')]"
|
||||
action['name'] = _('Stock Value At Date')
|
||||
else:
|
||||
action = self.env.ref('stock_account.product_valuation_action').read()[0]
|
||||
return action
|
||||
Reference in New Issue
Block a user