From f05e3eabbe1a910b71b6717f2262ed44ab277e86 Mon Sep 17 00:00:00 2001 From: "Tiffany Chang (tic)" Date: Wed, 6 Jul 2022 14:15:02 +0000 Subject: [PATCH] [IMP] stock{_account}: add (product) stock report Adds a new reporting view for [storable] product.product to allow for easier analysis by product (rather than by quant which is location specific). This includes: - adding 3 new fields for products: - avg_cost = total svl value / total qty - total_value = avg_cost / on hand - company_currency_id = self.env.company.currency_id (i.e. the currently selected company) for which currency symbol to display in the view - IMPORTANT NOTE: - these variables (and some of the existing ones) do NOT support multi-company aggregations due these values being used to calcuate future svls which should be company specific. Larger refactoring would be needed to ensure correct calc in both cases. Larger issue occurs in stock.report which uses these variables in combination with variables that do take into account multi-company records. - A customized `SearchPanel` so that a warehouse context can be applied to the view, rather than a filter. (viewable only when more than 1 warehouse) "stock report" part of b2b task: 2882539 Part-of: odoo/odoo#97109 --- addons/stock/__manifest__.py | 35 ++-------- addons/stock/models/product.py | 7 +- addons/stock/models/stock_warehouse.py | 3 + .../src/views/list/stock_report_list_view.js | 15 ++++ .../views/search/stock_report_search_model.js | 48 +++++++++++++ .../views/search/stock_report_search_panel.js | 30 ++++++++ .../search/stock_report_search_panel.xml | 24 +++++++ addons/stock/views/product_views.xml | 70 +++++++++++++++++++ addons/stock/views/stock_orderpoint_views.xml | 2 +- addons/stock_account/__manifest__.py | 2 +- addons/stock_account/models/product.py | 21 ++++-- addons/stock_account/views/product_views.xml | 17 +++++ 12 files changed, 236 insertions(+), 38 deletions(-) create mode 100644 addons/stock/static/src/views/list/stock_report_list_view.js create mode 100644 addons/stock/static/src/views/search/stock_report_search_model.js create mode 100644 addons/stock/static/src/views/search/stock_report_search_panel.js create mode 100644 addons/stock/static/src/views/search/stock_report_search_panel.xml diff --git a/addons/stock/__manifest__.py b/addons/stock/__manifest__.py index 2b09ce31f10..a73a8a57d00 100644 --- a/addons/stock/__manifest__.py +++ b/addons/stock/__manifest__.py @@ -69,15 +69,15 @@ 'views/res_partner_views.xml', 'views/product_strategy_views.xml', - 'views/product_views.xml', 'views/stock_lot_views.xml', 'views/stock_scrap_views.xml', 'views/stock_quant_views.xml', - 'views/stock_location_views.xml', 'views/stock_warehouse_views.xml', 'views/stock_move_line_views.xml', 'views/stock_picking_views.xml', 'views/stock_move_views.xml', + 'views/product_views.xml', + 'views/stock_location_views.xml', 'views/stock_orderpoint_views.xml', 'views/stock_storage_category_views.xml', 'views/res_config_settings_views.xml', @@ -103,24 +103,8 @@ 'stock/static/src/scss/stock_traceability_report.scss', ], 'web.assets_backend': [ - 'stock/static/src/js/inventory_report_list_controller.js', - 'stock/static/src/js/inventory_report_list_view.js', - 'stock/static/src/js/inventory_singleton_list_renderer.js', - 'stock/static/src/js/inventory_singleton_list_controller.js', - 'stock/static/src/js/inventory_singleton_list_view.js', - 'stock/static/src/js/report_stock_forecasted.js', - 'stock/static/src/js/report_stock_reception.js', - 'stock/static/src/js/lazy_column_list.js', - 'stock/static/src/js/stock_orderpoint_list_controller.js', - 'stock/static/src/js/stock_orderpoint_list_model.js', - 'stock/static/src/js/stock_orderpoint_list_view.js', - 'stock/static/src/js/stock_traceability_report_backend.js', - 'stock/static/src/js/stock_traceability_report_widgets.js', - 'stock/static/src/js/popover_widget.js', - 'stock/static/src/js/forecast_widget.js', - 'stock/static/src/js/counted_quantity_widget.js', - 'stock/static/src/js/basic_model.js', - 'stock/static/src/js/stock_rescheduling_popover.js', + 'stock/static/src/**/*.js', + 'stock/static/src/views/**/*.js', 'stock/static/src/scss/forecast_widget.scss', 'stock/static/src/scss/stock_empty_screen.scss', ], @@ -134,15 +118,8 @@ 'stock/static/tests/stock_traceability_report_backend_tests.js', ], 'web.assets_qweb': [ - 'stock/static/src/xml/inventory_report.xml', - 'stock/static/src/xml/inventory_adjustments.xml', - 'stock/static/src/xml/inventory_lines.xml', - 'stock/static/src/xml/popover_widget.xml', - 'stock/static/src/xml/forecast_widget.xml', - 'stock/static/src/xml/report_stock_forecasted.xml', - 'stock/static/src/xml/report_stock_reception.xml', - 'stock/static/src/xml/stock_orderpoint.xml', - 'stock/static/src/xml/stock_traceability_report_backend.xml', + 'stock/static/src/**/*.xml', + 'stock/static/src/views/**/*.xml', ], }, 'license': 'LGPL-3', diff --git a/addons/stock/models/product.py b/addons/stock/models/product.py index 7d5189f5022..4876ba58ade 100644 --- a/addons/stock/models/product.py +++ b/addons/stock/models/product.py @@ -516,7 +516,6 @@ class Product(models.Model): # Be aware that the exact same function exists in product.template def action_open_quants(self): - domain = [('product_id', 'in', self.ids)] hide_location = not self.user_has_groups('stock.group_stock_multi_locations') hide_lot = all(product.tracking == 'none' for product in self) self = self.with_context( @@ -544,8 +543,10 @@ class Product(models.Model): else: self = self.with_context(product_tmpl_ids=self.product_tmpl_id.ids) action = self.env['stock.quant'].action_view_inventory() - action['domain'] = domain - action["name"] = _('Update Quantity') + # note that this action is used by different views w/varying customizations + if not self.env.context.get('is_stock_report'): + action['domain'] = [('product_id', 'in', self.ids)] + action["name"] = _('Update Quantity') return action def action_update_quantity_on_hand(self): diff --git a/addons/stock/models/stock_warehouse.py b/addons/stock/models/stock_warehouse.py index 0a34cbc6674..9a96620d310 100644 --- a/addons/stock/models/stock_warehouse.py +++ b/addons/stock/models/stock_warehouse.py @@ -1074,3 +1074,6 @@ class Warehouse(models.Model): 'limit': 20, 'context': dict(self._context, default_warehouse_selectable=True, default_warehouse_ids=self.ids) } + + def get_current_warehouses(self): + return self.env['stock.warehouse'].search_read(fields=['id', 'name', 'code'], order='name') diff --git a/addons/stock/static/src/views/list/stock_report_list_view.js b/addons/stock/static/src/views/list/stock_report_list_view.js new file mode 100644 index 00000000000..54945043398 --- /dev/null +++ b/addons/stock/static/src/views/list/stock_report_list_view.js @@ -0,0 +1,15 @@ +/** @odoo-module **/ + +import { listView } from '@web/views/list/list_view'; +import { registry } from "@web/core/registry"; +import { StockReportSearchModel } from "../search/stock_report_search_model"; +import { StockReportSearchPanel } from '../search/stock_report_search_panel'; + + +export const StockReportListView = { + ...listView, + SearchModel: StockReportSearchModel, + SearchPanel: StockReportSearchPanel, +}; + +registry.category("views").add("stock_report_list_view", StockReportListView); diff --git a/addons/stock/static/src/views/search/stock_report_search_model.js b/addons/stock/static/src/views/search/stock_report_search_model.js new file mode 100644 index 00000000000..d2d185e7bba --- /dev/null +++ b/addons/stock/static/src/views/search/stock_report_search_model.js @@ -0,0 +1,48 @@ +/** @odoo-module **/ + +import { SearchModel } from "@web/search/search_model"; + +export class StockReportSearchModel extends SearchModel { + + async load() { + await super.load(...arguments); + await this._loadWarehouses(); + } + + + //--------------------------------------------------------------------- + // Actions / Getters + //--------------------------------------------------------------------- + + getWarehouses() { + return this.warehouses; + } + + async _loadWarehouses() { + this.warehouses = await this.orm.call( + 'stock.warehouse', + 'get_current_warehouses', + [[]], + { context: this.context }, + ); + } + + /** + * Clears the context of a warehouse so values calculate based on all possible + * warehouses + */ + clearWarehouseContext() { + delete this.globalContext.warehouse; + this._notify(); + } + + /** + * @param {number} warehouse_id + * Sets the context to the selected warehouse so values that take this into account + * will recalculate based on this without filtering out any records + */ + applyWarehouseContext(warehouse_id) { + this.globalContext['warehouse'] = warehouse_id; + this._notify(); + } +} diff --git a/addons/stock/static/src/views/search/stock_report_search_panel.js b/addons/stock/static/src/views/search/stock_report_search_panel.js new file mode 100644 index 00000000000..5cdcda15694 --- /dev/null +++ b/addons/stock/static/src/views/search/stock_report_search_panel.js @@ -0,0 +1,30 @@ +/** @odoo-module **/ + +import { SearchPanel } from "@web/search/search_panel/search_panel"; + +export class StockReportSearchPanel extends SearchPanel { + setup() { + super.setup(...arguments); + this.selectedWarehouse = false; + } + + //--------------------------------------------------------------------- + // Actions / Getters + //--------------------------------------------------------------------- + + get warehouses() { + return this.env.searchModel.getWarehouses(); + } + + clearWarehouseContext() { + this.env.searchModel.clearWarehouseContext(); + this.selectedWarehouse = null; + } + + applyWarehouseContext(warehouse_id) { + this.env.searchModel.applyWarehouseContext(warehouse_id); + this.selectedWarehouse = warehouse_id; + } +} + +StockReportSearchPanel.template = "stock.StockReportSearchPanel"; diff --git a/addons/stock/static/src/views/search/stock_report_search_panel.xml b/addons/stock/static/src/views/search/stock_report_search_panel.xml new file mode 100644 index 00000000000..0fddad34d1f --- /dev/null +++ b/addons/stock/static/src/views/search/stock_report_search_panel.xml @@ -0,0 +1,24 @@ + + + + + +
+
+ + Warehouses +
+
    +
  • + All Warehouses +
  • +
  • + +
  • +
+
+
+
+
diff --git a/addons/stock/views/product_views.xml b/addons/stock/views/product_views.xml index 087da7de0d3..bbbf54ddbe5 100644 --- a/addons/stock/views/product_views.xml +++ b/addons/stock/views/product_views.xml @@ -450,6 +450,74 @@ + + + product.product.stock.tree + product.product + + + + + + + +