Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions quality_control_stock_oca/README.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
.. image:: https://odoo-community.org/readme-banner-image
:target: https://odoo-community.org/get-involved?utm_source=readme
:alt: Odoo Community Association

=============================
Quality control - Stock (OCA)
=============================
Expand All @@ -17,7 +13,7 @@ Quality control - Stock (OCA)
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
:target: https://odoo-community.org/page/development-status
:alt: Beta
.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png
.. |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%2Fmanufacture-lightgray.png?logo=github
Expand All @@ -35,6 +31,10 @@ Quality control - Stock (OCA)
This module defines triggers that creates inspections when stock moves are done.

It also adds some shortcuts on picking and lots to these inspections.
Activating the "Remind Quality Control" flag on products, if inspections are not done (successfully or unsuccessfully), on picking confirmation a reminder popup appears.
Activating "Scrap Automatically" flag on products, if inspections fail, picking:
- Will be automatic validated if every product in picking has the flag checked;
- On validation, will generate scraps automatically for every product with the flag checked and whose inspection has failed;

**Table of contents**

Expand Down Expand Up @@ -99,6 +99,10 @@ Contributors
* Aung Ko Ko Lin
* Yoshi Tashiro

* `PyTech <https://www.pytech.it>`_:

* Quirino Leone <[email protected]>

Maintainers
~~~~~~~~~~~

Expand Down
1 change: 1 addition & 0 deletions quality_control_stock_oca/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import models
from . import wizard
from odoo import api, SUPERUSER_ID


Expand Down
3 changes: 3 additions & 0 deletions quality_control_stock_oca/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@
"website": "https://github.com/OCA/manufacture",
"depends": ["quality_control_oca", "stock"],
"data": [
"security/ir.model.access.csv",
"views/product_template_view.xml",
"views/qc_inspection_view.xml",
"views/stock_picking_view.xml",
"views/stock_production_lot_view.xml",
"views/qc_trigger_view.xml",
"wizard/qc_check_wizard.xml",
],
"post_init_hook": "post_init_hook",
"installable": True,
Expand Down
1 change: 1 addition & 0 deletions quality_control_stock_oca/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import product_template
from . import qc_trigger
from . import qc_inspection
from . import stock_move
Expand Down
17 changes: 17 additions & 0 deletions quality_control_stock_oca/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ProductTemplate(models.Model):
_inherit = "product.template"

remind_qc = fields.Boolean(
string="Remind Quality Control",
help="If selected, notify to perform Quality Control on this product when scheduled",
)

auto_scrap = fields.Boolean(
string="Scrap Automatically",
help="If selected, automatically scraps this product when inspections fail",
)
11 changes: 11 additions & 0 deletions quality_control_stock_oca/models/qc_inspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,17 @@ def _prepare_inspection_header(self, object_ref, trigger_line):
res["qty"] = object_ref.quantity_done
return res

def action_approve(self):
res = super().action_approve()
if (
self.picking_id.created_inspections == self.picking_id.done_inspections
and all(m.product_id.auto_scrap for m in self.picking_id.move_ids)
):

self.picking_id.button_validate()

return res


class QcInspectionLine(models.Model):
_inherit = "qc.inspection.line"
Expand Down
50 changes: 50 additions & 0 deletions quality_control_stock_oca/models/stock_picking.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,53 @@ def _create_backorder(self):
# To re-allocate backorder moves to the new backorder picking
self.sudo().qc_inspections_ids._compute_picking()
return res

def button_validate(self):
if self._needs_inspections_wizard():
return self._show_inspections_wizard()

res = super().button_validate()

self.create_scraps()

return res

def _needs_inspections_wizard(self):
if (
not self.env.context.get("skip_inspections", False)
and any(m.product_id.remind_qc for m in self.move_line_ids)
and self.created_inspections != self.done_inspections
):
return True

return False

def _show_inspections_wizard(self):
ctx = self.env.context.copy()
ctx.update({"default_stock_picking_ids": self.ids})
action = self.env["ir.actions.actions"]._for_xml_id(
"quality_control_stock_oca.action_qc_check"
)
action["context"] = ctx
return action

def create_scraps(self):
for inspection in self.qc_inspections_ids.filtered(
lambda x: x.state == "failed" and x.product_id.auto_scrap
):
vals = {
"picking_id": self.id,
"product_id": inspection.product_id.id,
"product_uom_id": inspection.product_id.uom_id.id,
"location_id": self.location_dest_id.id,
"scrap_qty": inspection.qty,
"lot_id": inspection.lot_id.id,
}

if inspection.object_id._name == "stock.move":
vals.update(
{
"move_id": inspection.object_id.id,
}
)
self.env["stock.scrap"].create(vals).action_validate()
1 change: 1 addition & 0 deletions quality_control_stock_oca/oca_dependencies.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
manufacture https://github.com/OCA/manufacture refs/pull/1584/head bdd2b3719bb2c71e064ae646745c74e7f9c86e95
4 changes: 4 additions & 0 deletions quality_control_stock_oca/readme/CONTRIBUTORS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@

* Aung Ko Ko Lin
* Yoshi Tashiro

* `PyTech <https://www.pytech.it>`_:

* Quirino Leone <[email protected]>
4 changes: 4 additions & 0 deletions quality_control_stock_oca/readme/DESCRIPTION.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
This module defines triggers that creates inspections when stock moves are done.

It also adds some shortcuts on picking and lots to these inspections.
Activating the "Remind Quality Control" flag on products, if inspections are not done (successfully or unsuccessfully), on picking confirmation a reminder popup appears.
Activating "Scrap Automatically" flag on products, if inspections fail, picking:
- Will be automatic validated if every product in picking has the flag checked;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: I see in description it says: "Moves should be done once set inspection as "failed" (so the "validation" should be automatic).", So I think whenever inspections are done and failed, Validation has to be completed (i.e. Pickings are in Done state) and also create scrap if any one of the products has 'scrap automatically' as True in a receipt- Is my understanding right?

If so, here mentioning validation is automatic only if every product has checked with scrap automatically is valid?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, is valid. This is a way to keep the default behavior, but also a chance to have a different behavior (checking flag auto_scrap) to speed up picking validation.

Copy link

@anusriNPS anusriNPS Oct 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for clarification. Implementation works intact for success scenarios but with respect to failed inspections after latest fix observed some improper behaviour as commented below. Could not figure out yet what makes this trigger of inspection when auto_scrap is checked and inspection is failed.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please see comment below

- On validation, will generate scraps automatically for every product with the flag checked and whose inspection has failed;
2 changes: 2 additions & 0 deletions quality_control_stock_oca/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_qc_check_wizard,access_qc_check_wizard,model_qc_check_wizard,stock.group_stock_user,1,1,1,1
38 changes: 20 additions & 18 deletions quality_control_stock_oca/static/description/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="generator" content="Docutils: https://docutils.sourceforge.io/" />
<title>README.rst</title>
<title>Quality control - Stock (OCA)</title>
<style type="text/css">

/*
Expand Down Expand Up @@ -360,23 +360,22 @@
</style>
</head>
<body>
<div class="document">
<div class="document" id="quality-control-stock-oca">
<h1 class="title">Quality control - Stock (OCA)</h1>


<a class="reference external image-reference" href="https://odoo-community.org/get-involved?utm_source=readme">
<img alt="Odoo Community Association" src="https://odoo-community.org/readme-banner-image" />
</a>
<div class="section" id="quality-control-stock-oca">
<h1>Quality control - Stock (OCA)</h1>
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:58a2217284a73e2729663dbf1d82de966ff4912c16afd7cbb99176ddc246caec
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/license-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/manufacture/tree/16.0/quality_control_stock_oca"><img alt="OCA/manufacture" src="https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/manufacture-16-0/manufacture-16-0-quality_control_stock_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/manufacture&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p><a class="reference external image-reference" href="https://odoo-community.org/page/development-status"><img alt="Beta" src="https://img.shields.io/badge/maturity-Beta-yellow.png" /></a> <a class="reference external image-reference" href="http://www.gnu.org/licenses/agpl-3.0-standalone.html"><img alt="License: AGPL-3" src="https://img.shields.io/badge/licence-AGPL--3-blue.png" /></a> <a class="reference external image-reference" href="https://github.com/OCA/manufacture/tree/16.0/quality_control_stock_oca"><img alt="OCA/manufacture" src="https://img.shields.io/badge/github-OCA%2Fmanufacture-lightgray.png?logo=github" /></a> <a class="reference external image-reference" href="https://translation.odoo-community.org/projects/manufacture-16-0/manufacture-16-0-quality_control_stock_oca"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external image-reference" href="https://runboat.odoo-community.org/builds?repo=OCA/manufacture&amp;target_branch=16.0"><img alt="Try me on Runboat" src="https://img.shields.io/badge/runboat-Try%20me-875A7B.png" /></a></p>
<p>This module defines triggers that creates inspections when stock moves are done.</p>
<p>It also adds some shortcuts on picking and lots to these inspections.</p>
<p>It also adds some shortcuts on picking and lots to these inspections.
Activating the “Remind Quality Control” flag on products, if inspections are not done (successfully or unsuccessfully), on picking confirmation a reminder popup appears.
Activating “Scrap Automatically” flag on products, if inspections fail, picking:
- Will be automatic validated if every product in picking has the flag checked;
- On validation, will generate scraps automatically for every product with the flag checked and whose inspection has failed;</p>
<p><strong>Table of contents</strong></p>
<div class="contents local topic" id="contents">
<ul class="simple">
Expand All @@ -392,7 +391,7 @@ <h1>Quality control - Stock (OCA)</h1>
</ul>
</div>
<div class="section" id="configuration">
<h2><a class="toc-backref" href="#toc-entry-1">Configuration</a></h2>
<h1><a class="toc-backref" href="#toc-entry-1">Configuration</a></h1>
<p>Configure a QC trigger in the product, product template, or product category to define the conditions for creating inspections:</p>
<ul class="simple">
<li>Trigger: Choose the trigger to activate the inspection process.</li>
Expand All @@ -412,23 +411,23 @@ <h2><a class="toc-backref" href="#toc-entry-1">Configuration</a></h2>
</ul>
</div>
<div class="section" id="known-issues-roadmap">
<h2><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h2>
<h1><a class="toc-backref" href="#toc-entry-2">Known issues / Roadmap</a></h1>
<ul class="simple">
<li>Put trigger in all languages.</li>
</ul>
</div>
<div class="section" id="bug-tracker">
<h2><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h2>
<h1><a class="toc-backref" href="#toc-entry-3">Bug Tracker</a></h1>
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/manufacture/issues">GitHub Issues</a>.
In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us to smash it by providing a detailed and welcomed
<a class="reference external" href="https://github.com/OCA/manufacture/issues/new?body=module:%20quality_control_stock_oca%0Aversion:%2016.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p>
<p>Do not contact contributors directly about support or help with technical issues.</p>
</div>
<div class="section" id="credits">
<h2><a class="toc-backref" href="#toc-entry-4">Credits</a></h2>
<h1><a class="toc-backref" href="#toc-entry-4">Credits</a></h1>
<div class="section" id="authors">
<h3><a class="toc-backref" href="#toc-entry-5">Authors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-5">Authors</a></h2>
<ul class="simple">
<li>OdooMRP team</li>
<li>AvanzOSC</li>
Expand All @@ -437,7 +436,7 @@ <h3><a class="toc-backref" href="#toc-entry-5">Authors</a></h3>
</ul>
</div>
<div class="section" id="contributors">
<h3><a class="toc-backref" href="#toc-entry-6">Contributors</a></h3>
<h2><a class="toc-backref" href="#toc-entry-6">Contributors</a></h2>
<ul class="simple">
<li>Oihane Crucelaegui &lt;<a class="reference external" href="mailto:oihanecrucelaegi&#64;avanzosc.es">oihanecrucelaegi&#64;avanzosc.es</a>&gt;</li>
<li>Simone Rubino &lt;<a class="reference external" href="mailto:simone.rubino&#64;agilebg.com">simone.rubino&#64;agilebg.com</a>&gt;</li>
Expand All @@ -454,10 +453,14 @@ <h3><a class="toc-backref" href="#toc-entry-6">Contributors</a></h3>
<li>Yoshi Tashiro</li>
</ul>
</li>
<li><a class="reference external" href="https://www.pytech.it">PyTech</a>:<ul>
<li>Quirino Leone &lt;<a class="reference external" href="mailto:quirino.leone&#64;pytech.it">quirino.leone&#64;pytech.it</a>&gt;</li>
</ul>
</li>
</ul>
</div>
<div class="section" id="maintainers">
<h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
<h2><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h2>
<p>This module is maintained by the OCA.</p>
<a class="reference external image-reference" href="https://odoo-community.org">
<img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" />
Expand All @@ -470,6 +473,5 @@ <h3><a class="toc-backref" href="#toc-entry-7">Maintainers</a></h3>
</div>
</div>
</div>
</div>
</body>
</html>
2 changes: 1 addition & 1 deletion quality_control_stock_oca/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import test_quality_control_stock
from . import test_quality_control_stock, test_qc_check_wizard
55 changes: 55 additions & 0 deletions quality_control_stock_oca/tests/test_qc_check_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
from odoo.tests.common import TransactionCase


class TestQCCheckWizard(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.wiz_model = cls.env["qc.check.wizard"]

cls.test_location = cls.env.ref("stock.stock_location_stock")
cls.product = cls.env["product.product"].create(
{"name": "Test Product", "type": "product"}
)
cls.picking_type = cls.env["stock.picking.type"].create(
{
"name": "Test Operation Type",
"sequence_code": "1",
"code": "incoming",
}
)

cls.stock_picking1 = cls.env["stock.picking"].create(
{
"location_id": cls.test_location.id,
"location_dest_id": cls.test_location.id,
"picking_type_id": cls.picking_type.id,
"move_ids": [
(
0,
0,
{
"product_id": 1,
"product_uom_qty": 1,
"product_uom": 1,
"name": "Test Product",
"location_id": cls.test_location.id,
"location_dest_id": cls.test_location.id,
},
)
],
}
)

def test_qc_check_wizard(self):
wizard = self.wiz_model.create({"stock_picking_ids": self.stock_picking1.ids})
self.assertTrue(wizard.stock_picking_ids)

move1 = self.stock_picking1.move_ids[0]
move1.quantity_done = 1

wizard.action_complete_inspections()
self.assertNotEqual(self.stock_picking1.state, "done")

wizard.action_skip_inspections()
self.assertEqual(self.stock_picking1.state, "done")
Loading