From 3ef47ce756d12fc03abf1e59ae1c4fda2f7e67d7 Mon Sep 17 00:00:00 2001 From: lreficent Date: Mon, 9 Oct 2017 15:44:36 +0200 Subject: [PATCH 1/4] [9.0][IMP] stock_cycle_count: fix accuracy computation and store it --- stock_cycle_count/__openerp__.py | 2 +- stock_cycle_count/models/stock_inventory.py | 28 +++++++++++-------- .../views/stock_location_view.xml | 3 +- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/stock_cycle_count/__openerp__.py b/stock_cycle_count/__openerp__.py index c3704e08a..89bd88823 100644 --- a/stock_cycle_count/__openerp__.py +++ b/stock_cycle_count/__openerp__.py @@ -6,7 +6,7 @@ "name": "Stock Cycle Count", "summary": "Adds the capability to schedule cycle counts in a " "warehouse through different rules defined by the user", - "version": "9.0.1.1.0", + "version": "9.0.1.2.0", "author": "Eficent, " "Odoo Community Association (OCA)", "website": "https://github.com/OCA/stock-logistics-warehouse", diff --git a/stock_cycle_count/models/stock_inventory.py b/stock_cycle_count/models/stock_inventory.py index ba548c3d0..c4d755518 100644 --- a/stock_cycle_count/models/stock_inventory.py +++ b/stock_cycle_count/models/stock_inventory.py @@ -12,23 +12,27 @@ PERCENT = 100.0 class StockInventory(models.Model): _inherit = 'stock.inventory' - @api.one + @api.multi + @api.depends("state", "line_ids") def _compute_inventory_accuracy(self): - total_qty = sum(self.line_ids.mapped('theoretical_qty')) - abs_discrepancy = sum(self.line_ids.mapped( - lambda x: abs(x.discrepancy_qty))) - if total_qty: - self.inventory_accuracy = PERCENT * ( - total_qty - abs_discrepancy) / total_qty - if not self.line_ids and self.state == 'done': - self.inventory_accuracy = 100.0 + for inv in self: + theoretical = sum(inv.line_ids.mapped( + lambda x: abs(x.theoretical_qty))) + abs_discrepancy = sum(inv.line_ids.mapped( + lambda x: abs(x.discrepancy_qty))) + if theoretical: + inv.inventory_accuracy = max( + PERCENT * (theoretical - abs_discrepancy) / theoretical, + 0.0) + if not inv.line_ids and inv.state == 'done': + inv.inventory_accuracy = PERCENT cycle_count_id = fields.Many2one( comodel_name='stock.cycle.count', string='Stock Cycle Count', ondelete='cascade', readonly=True) - inventory_accuracy = fields.Float(string='Accuracy', - compute=_compute_inventory_accuracy, - digits=(3, 2)) + inventory_accuracy = fields.Float( + string='Accuracy', compute=_compute_inventory_accuracy, + digits=(3, 2), store=True) @api.multi def action_done(self): diff --git a/stock_cycle_count/views/stock_location_view.xml b/stock_cycle_count/views/stock_location_view.xml index 180adff21..eef47bbfd 100644 --- a/stock_cycle_count/views/stock_location_view.xml +++ b/stock_cycle_count/views/stock_location_view.xml @@ -6,11 +6,12 @@ [('location_id', '=', active_ids), + ('exclude_sublocation', '=', True), ('state', '=', 'done')] Accuracy Stats stock.inventory form - tree,form + tree,form,pivot From 2f3eb2ff3ba3b5ee40cf4843c6baf4402fdeeb01 Mon Sep 17 00:00:00 2001 From: lreficent Date: Tue, 10 Oct 2017 11:52:25 +0200 Subject: [PATCH 2/4] [9.0][IMP] stock_cycle_count: basic_accuracy report --- stock_cycle_count/__init__.py | 1 + stock_cycle_count/__openerp__.py | 4 +- stock_cycle_count/reports/__init__.py | 4 + .../reports/report_stock_location_accuracy.py | 38 ++++++++++ .../stock_location_accuracy_report.xml | 73 +++++++++++++++++++ 5 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 stock_cycle_count/reports/__init__.py create mode 100644 stock_cycle_count/reports/report_stock_location_accuracy.py create mode 100644 stock_cycle_count/reports/stock_location_accuracy_report.xml diff --git a/stock_cycle_count/__init__.py b/stock_cycle_count/__init__.py index 08f93b3a4..f1ca255e7 100644 --- a/stock_cycle_count/__init__.py +++ b/stock_cycle_count/__init__.py @@ -4,3 +4,4 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). from . import models +from . import reports diff --git a/stock_cycle_count/__openerp__.py b/stock_cycle_count/__openerp__.py index 89bd88823..9108ded83 100644 --- a/stock_cycle_count/__openerp__.py +++ b/stock_cycle_count/__openerp__.py @@ -26,7 +26,9 @@ 'views/stock_location_view.xml', 'data/cycle_count_sequence.xml', 'data/cycle_count_ir_cron.xml', - 'security/ir.model.access.csv'], + 'reports/stock_location_accuracy_report.xml', + 'security/ir.model.access.csv', + ], "license": "AGPL-3", 'installable': True, 'application': False, diff --git a/stock_cycle_count/reports/__init__.py b/stock_cycle_count/reports/__init__.py new file mode 100644 index 000000000..97c997be9 --- /dev/null +++ b/stock_cycle_count/reports/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from . import report_stock_location_accuracy diff --git a/stock_cycle_count/reports/report_stock_location_accuracy.py b/stock_cycle_count/reports/report_stock_location_accuracy.py new file mode 100644 index 000000000..f2807da1b --- /dev/null +++ b/stock_cycle_count/reports/report_stock_location_accuracy.py @@ -0,0 +1,38 @@ +# -*- coding: utf-8 -*- +# Copyright 2017 Eficent Business and IT Consulting Services S.L. +# (http://www.eficent.com) +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). + +from openerp import api, fields, models + + +class LocationAccuracyReport(models.AbstractModel): + _name = "report.stock_location_accuracy" + + @api.model + def _get_inventory_domain(self, loc_id): + return [('location_id', '=', loc_id), + ('exclude_sublocation', '=', True), + ('state', '=', 'done')] + + @api.model + def _get_location_data(self, locations): + data = dict() + inventory_obj = self.env["stock.inventory"] + for loc in locations: + counts = inventory_obj.search(self._get_inventory_domain(loc.id)) + data[loc] = counts + return data + + @api.multi + def render_html(self, data=None): + report_obj = self.env["report"] + locs = self.env["stock.location"].browse(self._ids) + data = self._get_location_data(locs) + docargs = { + "doc_ids": locs._ids, + "docs": locs, + "data": data, + } + return report_obj.render( + "stock_cycle_count.stock_location_accuracy", docargs) diff --git a/stock_cycle_count/reports/stock_location_accuracy_report.xml b/stock_cycle_count/reports/stock_location_accuracy_report.xml new file mode 100644 index 000000000..2db18f471 --- /dev/null +++ b/stock_cycle_count/reports/stock_location_accuracy_report.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + + From 9504b8364909e12baed80d22d04bb432bd4ad994 Mon Sep 17 00:00:00 2001 From: lreficent Date: Tue, 10 Oct 2017 11:56:46 +0200 Subject: [PATCH 3/4] [9.0][IMP] stock_cycle_count: enhance views --- stock_cycle_count/models/stock_inventory.py | 2 +- stock_cycle_count/models/stock_location.py | 11 +++++ .../reports/report_stock_location_accuracy.py | 6 +-- .../views/stock_inventory_view.xml | 49 +++++++++++++++++++ .../views/stock_location_view.xml | 15 ++---- 5 files changed, 67 insertions(+), 16 deletions(-) diff --git a/stock_cycle_count/models/stock_inventory.py b/stock_cycle_count/models/stock_inventory.py index c4d755518..f4aad364a 100644 --- a/stock_cycle_count/models/stock_inventory.py +++ b/stock_cycle_count/models/stock_inventory.py @@ -32,7 +32,7 @@ class StockInventory(models.Model): ondelete='cascade', readonly=True) inventory_accuracy = fields.Float( string='Accuracy', compute=_compute_inventory_accuracy, - digits=(3, 2), store=True) + digits=(3, 2), store=True, group_operator="avg") @api.multi def action_done(self): diff --git a/stock_cycle_count/models/stock_location.py b/stock_cycle_count/models/stock_location.py index a9b5730c0..bf040984a 100644 --- a/stock_cycle_count/models/stock_location.py +++ b/stock_cycle_count/models/stock_location.py @@ -91,3 +91,14 @@ class StockLocation(models.Model): 'state': 'draft' }) return True + + @api.multi + def action_accuracy_stats(self): + self.ensure_one() + action = self.env.ref('stock_cycle_count.act_accuracy_stats') + result = action.read()[0] + result['context'] = {"search_default_location_id": self.id} + new_domain = result['domain'][:-1] + \ + ", ('location_id', 'child_of', active_ids)]" + result['domain'] = new_domain + return result diff --git a/stock_cycle_count/reports/report_stock_location_accuracy.py b/stock_cycle_count/reports/report_stock_location_accuracy.py index f2807da1b..6b14a2a2a 100644 --- a/stock_cycle_count/reports/report_stock_location_accuracy.py +++ b/stock_cycle_count/reports/report_stock_location_accuracy.py @@ -3,16 +3,16 @@ # (http://www.eficent.com) # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html). -from openerp import api, fields, models +from openerp import api, models class LocationAccuracyReport(models.AbstractModel): _name = "report.stock_location_accuracy" @api.model - def _get_inventory_domain(self, loc_id): + def _get_inventory_domain(self, loc_id, exclude_sublocation=True): return [('location_id', '=', loc_id), - ('exclude_sublocation', '=', True), + ('exclude_sublocation', '=', exclude_sublocation), ('state', '=', 'done')] @api.model diff --git a/stock_cycle_count/views/stock_inventory_view.xml b/stock_cycle_count/views/stock_inventory_view.xml index 6bdf9c266..dbc84f4c6 100644 --- a/stock_cycle_count/views/stock_inventory_view.xml +++ b/stock_cycle_count/views/stock_inventory_view.xml @@ -10,6 +10,7 @@ + @@ -31,4 +32,52 @@ + + stock.inventory.filter - stock_cycle_count + stock.inventory + + + + + + + + + + stock.inventory.graph + stock.inventory + + + + + + + + + + stock.inventory.pivot + stock.inventory + + + + + + + + + + + [('exclude_sublocation', '=', True), + ('state', '=', 'done')] + Accuracy Stats + stock.inventory + form + pivot,tree,form,graph + + + + diff --git a/stock_cycle_count/views/stock_location_view.xml b/stock_cycle_count/views/stock_location_view.xml index eef47bbfd..71ef6cced 100644 --- a/stock_cycle_count/views/stock_location_view.xml +++ b/stock_cycle_count/views/stock_location_view.xml @@ -4,16 +4,6 @@ - - [('location_id', '=', active_ids), - ('exclude_sublocation', '=', True), - ('state', '=', 'done')] - Accuracy Stats - stock.inventory - form - tree,form,pivot - - Location form - cycle count extension stock.location @@ -21,8 +11,9 @@