[11.0][MIG] stock_cycle_count

This commit is contained in:
Lois Rilo
2018-09-19 18:02:32 +02:00
committed by Mateu Griful
parent 28f15f610d
commit e748a95c78
26 changed files with 177 additions and 114 deletions

View File

@@ -1,11 +1,27 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
=================
Stock Cycle Count
=================
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |badge1| image:: https://img.shields.io/badge/maturity-Mature-brightgreen.png
:target: https://odoo-community.org/page/development-status
:alt: Mature
.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fstock--logistics--warehouse-lightgray.png?logo=github
:target: https://github.com/OCA/stock-logistics-warehouse/tree/11.0/stock_cycle_count
:alt: OCA/stock-logistics-warehouse
.. |badge4| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png
:target: https://runbot.odoo-community.org/runbot/153/11.0
:alt: Try me on Runbot
|badge1| |badge2| |badge3| |badge4|
This module provides the capability to execute a cycle count strategy in a
warehouse through different rules defined by the user. Cycle count is an
alternative to full wall-to-wall physical inventories in which little
@@ -24,6 +40,11 @@ With this strategy it is possible to:
* Measure the accuracy of the inventory records and improve it.
* Correct inventory errors earlier and prevent them to become bigger.
**Table of contents**
.. contents::
:local:
Installation
============
@@ -33,7 +54,7 @@ To install this module, you need to:
* Install the module in your database.
Recommendations
---------------
~~~~~~~~~~~~~~~
It is highly recommended to use this module in conjunction with:
@@ -59,21 +80,17 @@ Usage
Once you have some rules configured for your warehouses, you can proceed as
is described below.
#. Go to "Inventory > Configuration > Warehouse Management > Warehouses".
#. Go to *Inventory > Configuration > Warehouse Management > Warehouses*.
#. Select all the warehouses you want to compute the rules in.
#. Click on "Action" and then in "Compute Cycle Count Rules". (**note**: A
cron job will do this for every warehouse daily.)
#. Go to "Inventory Control > Cycle Counts".
#. Go to *Operations > Cycle Counts*.
#. Select a planned Cycle Count and confirm it, this will create a draft
Inventory Adjustment.
#. In the right top corner of the form view you can access to the generated
Inventory Adjustment.
#. Proceed with the Inventory Adjustment as usual.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/153/10.0
Known issues / Roadmap
======================
@@ -81,37 +98,58 @@ Known issues / Roadmap
converting some of the searches to actual fields. E.g.
`inventory_history_ids` for all the inventories done in a location.
Changelog
=========
11.0.1.0.0 (2018-09-19)
~~~~~~~~~~~~~~~~~~~~~~~
* [MIG] Migrated to v11. Start of history.
Bug Tracker
===========
Bugs are tracked on `GitHub Issues
<https://github.com/OCA/stock-logistics-warehouse/issues>`_. In case of
trouble, please check there if your issue has already been reported. If you
spotted it first, help us smash it by providing detailed and welcomed feedback.
Bugs are tracked on `GitHub Issues <https://github.com/OCA/stock-logistics-warehouse/issues>`_.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback.
Do not contact contributors directly about support or help with technical issues.
Images
------
Credits
=======
* Odoo Community Association: `Icon <https://github.com/OCA/maintainer-tools/blob/master/template/module/static/description/icon.svg>`_.
Authors
~~~~~~~
* Eficent
Contributors
------------
~~~~~~~~~~~~
* Lois Rilo <lois.rilo@eficent.com>
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
Maintainer
----------
Maintainers
~~~~~~~~~~~
This module is maintained by the OCA.
.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org
This module is maintained by the OCA.
OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and
promote its widespread use.
To contribute to this module, please visit https://odoo-community.org.
.. |maintainer-lreficent| image:: https://github.com/lreficent.png?size=40px
:target: https://github.com/lreficent
:alt: lreficent
Current `maintainer <https://odoo-community.org/page/maintainer-role>`_:
|maintainer-lreficent|
This module is part of the `OCA/stock-logistics-warehouse <https://github.com/OCA/stock-logistics-warehouse/tree/11.0/stock_cycle_count>`_ project on GitHub.
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

View File

@@ -1,5 +1,2 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import models
from . import reports

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017-18 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).
@@ -6,20 +5,18 @@
"name": "Stock Cycle Count",
"summary": "Adds the capability to schedule cycle counts in a "
"warehouse through different rules defined by the user.",
"version": "10.0.1.0.0",
"version": "11.0.1.0.0",
"development_status": "Mature",
"maintainers": ["lreficent"],
"author": "Eficent, "
"Odoo Community Association (OCA)",
"website": "https://github.com/OCA/stock-logistics-warehouse",
"category": "Warehouse Management",
"depends": [
"stock",
"mail",
"stock_account",
"stock_inventory_discrepancy",
"stock_inventory_exclude_sublocation",
],
"external_dependencies": {
"python": ["numpy"],
},
"data": [
"views/stock_cycle_count_view.xml",
"views/stock_cycle_count_rule_view.xml",

View File

@@ -7,14 +7,14 @@
<record forcecreate="True"
id="ir_cron_compute_cycle_count_action" model="ir.cron">
<field name="name">Cycle Count Planner Computation</field>
<field name="state">code</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="model" eval="'stock.warehouse'"/>
<field name="function" eval="'cron_cycle_count'"/>
<field name="args" eval="'()'" />
<field name="model_id" ref="stock.model_stock_warehouse"/>
<field name="code">model.cron_cycle_count()</field>
</record>
</odoo>

View File

@@ -4,12 +4,12 @@
<odoo noupdate="1">
<record id="seq_cycle_count" model="ir.sequence">
<field name="name">Cycle Count</field>
<field name="code">stock.cycle.count</field>
<field name="prefix">CC/%(range_year)s/</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
<record id="seq_cycle_count" model="ir.sequence">
<field name="name">Cycle Count</field>
<field name="code">stock.cycle.count</field>
<field name="prefix">CC/%(range_year)s/</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
</odoo>

View File

@@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import stock_cycle_count
from . import stock_cycle_count_rule
from . import stock_location

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017-18 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).
@@ -11,6 +10,7 @@ class StockCycleCount(models.Model):
_name = 'stock.cycle.count'
_description = "Stock Cycle Counts"
_inherit = 'mail.thread'
_order = "id desc"
@api.model
def _default_company(self):

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017-18 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).
@@ -170,7 +169,7 @@ class StockCycleCountRule(models.Model):
except Exception as e:
raise UserError(
_('Error found determining the frequency of periodic '
'cycle count rule. %s') % e.message)
'cycle count rule. %s') % str(e))
else:
next_date = datetime.today()
cycle_count = self._propose_cycle_count(next_date, loc)
@@ -188,7 +187,7 @@ class StockCycleCountRule(models.Model):
@api.model
def _compute_turnover(self, move):
price = move.get_price_unit()
price = move._get_price_unit()
turnover = move.product_uom_qty * price
return turnover
@@ -217,7 +216,7 @@ class StockCycleCountRule(models.Model):
except Exception as e:
raise UserError(_(
'Error found when comparing turnover with the '
'rule threshold. %s') % e.message)
'rule threshold. %s') % str(e))
else:
next_date = datetime.today()
cycle_count = self._propose_cycle_count(next_date, loc)

View File

@@ -1,4 +1,3 @@
# -*- 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).

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017-18 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).
@@ -11,8 +10,8 @@ from datetime import datetime
_logger = logging.getLogger(__name__)
try:
from numpy import mean
NUMPY_PATH = tools.find_in_path('numpy')
from statistics import mean
STATS_PATH = tools.find_in_path('statistics')
except (ImportError, IOError) as err:
_logger.debug(err)

View File

@@ -1,4 +1,3 @@
# -*- 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).
@@ -10,7 +9,7 @@ class StockMove(models.Model):
_inherit = 'stock.move'
@api.multi
def action_done(self):
super(StockMove, self).action_done()
def _action_done(self):
super()._action_done()
self.mapped("location_id").check_zero_confirmation()
return True

View File

@@ -1,4 +1,3 @@
# -*- coding: utf-8 -*-
# Copyright 2017-18 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).
@@ -92,12 +91,12 @@ class StockWarehouse(models.Model):
locations = list(set([d['location'] for d in
proposed_cycle_counts]))
for loc in locations:
proposed_for_loc = filter(lambda x: x['location'] == loc,
proposed_cycle_counts)
proposed_for_loc = list(filter(
lambda x: x['location'] == loc, proposed_cycle_counts))
earliest_date = min([d['date'] for d in proposed_for_loc])
cycle_count_proposed = filter(lambda x: x['date'] ==
earliest_date,
proposed_for_loc)[0]
cycle_count_proposed = list(filter(
lambda x: x['date'] == earliest_date,
proposed_for_loc))[0]
domain = [('location_id', '=', loc.id),
('state', 'in', ['draft'])]
existing_cycle_counts = self.env[
@@ -130,9 +129,9 @@ class StockWarehouse(models.Model):
try:
whs = self.search([])
whs.action_compute_cycle_count_rules()
except:
except Exception as e:
_logger.info(
"An error raised while running stock_cycle_count cron job.")
"Error while running stock_cycle_count cron job: %s", str(e))
raise
_logger.info("stock_cycle_count cron job ended.")
return True

View File

@@ -0,0 +1,8 @@
You can configure the rules to compute the cycle count, acting as follow:
#. Go to *Inventory > Configuration > Cycle Count Rules*.
#. Create as much cycle count rules as you want.
#. Assign the rules to the Warehouse or zones where you want to apply the rules
in.
#. Go to *Inventory > Configuration > Warehouse Management > Warehouses* and
set a *Cycle Count Planning Horizon* for each warehouse.

View File

@@ -0,0 +1,2 @@
* Lois Rilo <lois.rilo@eficent.com>
* Jordi Ballester Alomar <jordi.ballester@eficent.com>

View File

@@ -0,0 +1,17 @@
This module provides the capability to execute a cycle count strategy in a
warehouse through different rules defined by the user. Cycle count is an
alternative to full wall-to-wall physical inventories in which little
portions (stock locations) of the stock are selected to count on a regular
basis.
The system propose locations in which to perform a inventory adjustment every
day based on a set of rules defined for the warehouse. In addition the system
can propose Zero-Confirmations which are simple and opportunistic counts to
check whether a locations has actually became empty or not.
With this strategy it is possible to:
* Remove the need to perform full physical inventories and to stop the
production in the warehouse.
* Measure the accuracy of the inventory records and improve it.
* Correct inventory errors earlier and prevent them to become bigger.

View File

@@ -0,0 +1,4 @@
11.0.1.0.0 (2018-09-19)
~~~~~~~~~~~~~~~~~~~~~~~
* [MIG] Migrated to v11. Start of history.

View File

@@ -0,0 +1,13 @@
To install this module, you need to:
* Download this module to your addons path.
* Install the module in your database.
Recommendations
~~~~~~~~~~~~~~~
It is highly recommended to use this module in conjunction with:
* ``stock_inventory_verification_request``: Adds the capability to request Slot
Verifications.
* ``stock_inventory_lockdown``: Lock down locations during inventories.

View File

@@ -0,0 +1,3 @@
* Assess the possibility to refactor `action_compute_cycle_count_rules` method
converting some of the searches to actual fields. E.g.
`inventory_history_ids` for all the inventories done in a location.

View File

@@ -0,0 +1,13 @@
Once you have some rules configured for your warehouses, you can proceed as
is described below.
#. Go to *Inventory > Configuration > Warehouse Management > Warehouses*.
#. Select all the warehouses you want to compute the rules in.
#. Click on "Action" and then in "Compute Cycle Count Rules". (**note**: A
cron job will do this for every warehouse daily.)
#. Go to *Operations > Cycle Counts*.
#. Select a planned Cycle Count and confirm it, this will create a draft
Inventory Adjustment.
#. In the right top corner of the form view you can access to the generated
Inventory Adjustment.
#. Proceed with the Inventory Adjustment as usual.

View File

@@ -1,4 +1 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import report_stock_location_accuracy

View File

@@ -1,4 +1,3 @@
# -*- 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).

View File

@@ -1,4 +1 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from . import test_stock_cycle_count

View File

@@ -1,4 +1,3 @@
# -*- 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).
@@ -166,7 +165,7 @@ class TestStockCycleCount(common.TransactionCase):
self.quant_model.create({
'product_id': self.product1.id,
'location_id': self.count_loc.id,
'qty': 1.0,
'quantity': 1.0,
'cost': 15.0
})
move1 = self.stock_move_model.create({
@@ -177,7 +176,10 @@ class TestStockCycleCount(common.TransactionCase):
'location_id': self.count_loc.id,
'location_dest_id': loc.id
})
move1.action_done()
move1._action_confirm()
move1._action_assign()
move1.move_line_ids[0].qty_done = 1.0
move1._action_done()
wh.cron_cycle_count()
self.assertNotEqual(pre_existing_count.date_deadline,
date_pre_existing_cc,
@@ -200,7 +202,10 @@ class TestStockCycleCount(common.TransactionCase):
'location_id': loc.id,
'location_dest_id': self.count_loc.id
})
move2.action_done()
move2._action_confirm()
move2._action_assign()
move2.move_line_ids[0].qty_done = 1.0
move2._action_done()
count = self.cycle_count_model.search([
('location_id', '=', loc.id),
('cycle_count_rule_id', '=', self.zero_rule.id)])
@@ -213,7 +218,7 @@ class TestStockCycleCount(common.TransactionCase):
inventory = self.inventory_model.search([
('cycle_count_id', '=', self.cycle_count_1.id)])
self.assertTrue(inventory, 'Inventory not created.')
inventory.prepare_inventory()
inventory.action_start()
inventory.action_done()
self.assertEqual(self.cycle_count_1.state, 'done',
'Cycle count not set as done.')

View File

@@ -55,12 +55,15 @@
<p colspan="4">In either case you can exclude specific locations
going to the locations form and checking the box
"Exclude from Cycle Count".</p>
<field name="apply_in"/>
<field name="warehouse_ids" widget="many2many_tags"/>
<label for="location_ids"
attrs="{'invisible': [('apply_in', '!=', 'location')]}"/>
<field name="location_ids" colspan="3" nolabel="1"
attrs="{'invisible': [('apply_in', '!=', 'location')]}"/>
<group colspan="2">
<field name="apply_in"/>
</group>
<group colspan="2">
<field name="warehouse_ids" widget="many2many_tags"
attrs="{'readonly': [('apply_in', '!=', 'warehouse')]}"/>
<field name="location_ids" widget="many2many_tags"
attrs="{'invisible': [('apply_in', '!=', 'location')]}"/>
</group>
</group>
</sheet>

View File

@@ -124,29 +124,19 @@
view_mode="tree,form"
context="{'search_default_planned':1,'search_default_execution':1}"/>
<menuitem id="menu_stock_cycle_count"
name="Cycle Counts" parent="stock.menu_stock_inventory_control"
action="action_stock_cycle_count" />
name="Cycle Counts"
parent="stock.menu_stock_warehouse_mgmt"
sequence="28"
action="action_stock_cycle_count"/>
<!-- Action to confirm several Stock Cycle Counts -->
<record id="action_server_cycle_count_confirm"
model="ir.actions.server">
<field name="name">Confirm Cycle Counts</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_stock_cycle_count" />
<field name="binding_model_id" ref="model_stock_cycle_count"/>
<field name="state">code</field>
<field name="code">records.action_create_inventory_adjustment()</field>
</record>
<record model="ir.values" id="action_cycle_count_confirm">
<field name="name">confirm several cycle counts</field>
<field name="action_id"
ref="action_server_cycle_count_confirm" />
<field name="value" eval="'ir.actions.server,' + str(ref('action_server_cycle_count_confirm'))" />
<field name="key">action</field>
<field name="model_id" ref="model_stock_cycle_count" />
<field name="model">stock.cycle.count</field>
<field name="key2">client_action_multi</field>
</record>
</odoo>

View File

@@ -26,22 +26,10 @@
<record id="action_server_warehouse_execute_cycle_count"
model="ir.actions.server">
<field name="name">Compute Cycle Count Rules</field>
<field name="condition">True</field>
<field name="type">ir.actions.server</field>
<field name="model_id" ref="model_stock_warehouse" />
<field name="model_id" ref="stock.model_stock_warehouse"/>
<field name="binding_model_id" ref="stock.model_stock_warehouse"/>
<field name="state">code</field>
<field name="code">records.action_compute_cycle_count_rules()</field>
</record>
<record model="ir.values" id="action_warehouse_execute_cycle_count">
<field name="name">action_warehouse_execute_cycle_count</field>
<field name="action_id"
ref="action_server_warehouse_execute_cycle_count" />
<field name="value" eval="'ir.actions.server,' + str(ref('action_server_warehouse_execute_cycle_count'))" />
<field name="key">action</field>
<field name="model_id" ref="model_stock_warehouse" />
<field name="model">stock.warehouse</field>
<field name="key2">client_action_multi</field>
</record>
</odoo>