Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[17.0][MIG] quality_control_oca: Migration to 17.0 #1271

Merged
merged 97 commits into from
May 27, 2024
Merged
Changes from all commits
Commits
Show all changes
97 commits
Select commit Hold shift + click to select a range
468fa88
Modulos de calidad sin migrar
oihane Aug 22, 2014
c2b7f3f
quality_control * PEP8 * Travis * Size in field (deprecated)
pedrobaeza Sep 28, 2014
3f4c74c
no msg
alfredoavanzosc Oct 9, 2014
6f07483
quality_control: Some improvement
pedrobaeza Oct 14, 2014
2cea433
<quality_control> deleted constraint
oihane Oct 24, 2014
cf4646d
quality_control: Total refactorization with new API, README files, an…
pedrobaeza Dec 10, 2014
60099cf
New module <quality_control_hr> closes #662 * Changes in access rules…
oihane Feb 13, 2015
eb592b4
quality_control * Fix wizard set test
pedrobaeza Mar 16, 2015
5f2116d
changed default references of fields.Datetime.now() to fields.Datetim…
ejans Jul 16, 2015
cc582d3
Slovene translations added
sysadminmatmoz Aug 1, 2015
64aa70d
quality_control: * Changed permissions
oihane Aug 12, 2015
c005120
quality_control_*: Make use of qty field
pedrobaeza Nov 14, 2015
1de6cf6
quality_control: deleting qc.inspection does not delete its lines fixed
oihane Apr 28, 2016
999e065
[IMP] quality_control: decimal precision configurable + approving ins…
Feb 8, 2017
15c0a5f
[9.0][MIG] quality_control
LoisRForgeFlow May 24, 2017
d83847a
[FIX] quality_control: Several things:
Jun 7, 2017
29d129d
[FIX] quality_control: Fix TypeError on new test category (#193)
zamberjo Nov 18, 2017
69cb19a
[9.0][FIX] quality_control: use odoo tag on views
LoisRForgeFlow Nov 21, 2017
6be2e0e
[MIG] quality_control: Migration to 10.0
SimoRubi Nov 21, 2017
2842351
[MIG] quality_control: Migration to 11.0
Aug 23, 2018
97e7baa
[11.0][FIX] quality_control: Fixed dashboard icon. (#304)
SalahAdDin Aug 30, 2018
d16e781
[10.0][FIX] quality_control: move quality control configuration menu …
LoisRForgeFlow Oct 8, 2018
0517d14
[FIX] quality_control: created new notebook page to avoid activate va…
oihane Dec 19, 2018
a6292d6
[IMP] quality_control: App drawer icon
pedrobaeza Feb 16, 2019
77b7c10
[MIG] quality_control: Migration to 12.0
NachoAlesLopez May 10, 2019
605b911
[12.0][FIX] quality_control: add user admin to quality control manage…
LoisRForgeFlow Jul 11, 2019
3a8fe91
[UPD] Update module logo
Aug 8, 2019
3dff45b
Translated using Weblate (Portuguese)
pedrocs-exo Sep 12, 2019
58b336e
[FIX] quality_control
NachoAlesLopez Oct 29, 2019
f38d8e5
Translated using Weblate (Croatian)
badbole Dec 4, 2019
1f9deae
[IMP] quality_control: black, isort
ps-tubtim Mar 16, 2020
697ee30
[MIG] quality_control: Migration to 13.0 + renaming to quality_contro…
ps-tubtim Mar 17, 2020
e006be2
[UPD] Update quality_control_oca.pot
oca-travis Feb 13, 2021
025a000
[UPD] README.rst
OCA-git-bot Feb 13, 2021
b4f9f30
[FIX] quality_control_oca: Missing README piece
pedrobaeza Feb 23, 2021
91d5701
[IMP] quality_control_oca: Added triggers on product.product views
CarlosRoca13 Mar 2, 2021
b67e158
[UPD] Update quality_control_oca.pot
oca-travis Mar 2, 2021
0143d83
quality_control_oca 13.0.1.1.0
OCA-git-bot Mar 2, 2021
b2c9205
Update translation files
oca-transbot Mar 2, 2021
1246def
[14.0][MIG] quality_control_oca
enriquemartin Mar 5, 2021
032e88e
[UPD] Update quality_control_oca.pot
oca-travis Oct 4, 2021
6b93a4b
[UPD] README.rst
OCA-git-bot Oct 4, 2021
0594881
[FIX] quality_control_oca: inherit from mail tracking in qc_trigger_line
AaronHForgeFlow Oct 21, 2021
54edd53
[UPD] Update quality_control_oca.pot
oca-travis Oct 26, 2021
35068eb
quality_control_oca 14.0.1.2.0
OCA-git-bot Oct 26, 2021
25eb185
Update translation files
oca-transbot Oct 26, 2021
779a60d
[IMP] quality_control_oca: add chatter to quality tests
cubells Apr 22, 2022
4f0efb1
[UPD] Update quality_control_oca.pot
oca-travis Apr 22, 2022
4ac7357
[UPD] README.rst
OCA-git-bot Apr 22, 2022
c9bac8b
quality_control_oca 14.0.1.3.0
OCA-git-bot Apr 22, 2022
476d145
Update translation files
oca-transbot Apr 22, 2022
838c0f6
Translated using Weblate (Italian)
francesco-ooops May 18, 2022
14a1fbc
[FIX] quality_control_oca: Protect product category view with group
pedrobaeza Sep 27, 2022
9a2914e
quality_control_oca 14.0.1.4.0
OCA-git-bot Sep 28, 2022
d6354de
[IMP] quality_control_oca: black, isort, prettier
mymage Dec 10, 2022
5a08f56
[MIG] quality_control_oca: Migration to 15.0
mymage Dec 10, 2022
0a2c49f
[UPD] Update quality_control_oca.pot
Dec 16, 2022
6dfac03
[UPD] README.rst
OCA-git-bot Dec 16, 2022
386c673
Translated using Weblate (Italian)
mymage Dec 19, 2022
8426e61
[MIG] quality_control_oca: Migration to 16.0
mymage Dec 26, 2022
4b8a02d
[UPD] Update quality_control_oca.pot
May 21, 2023
599408b
[UPD] README.rst
OCA-git-bot May 21, 2023
9372180
Update translation files
weblate May 21, 2023
af3e290
Update translation files
weblate May 21, 2023
607549f
Translated using Weblate (Italian)
mymage May 22, 2023
01c0414
Translated using Weblate (Italian)
mymage May 31, 2023
67ad8d5
Translated using Weblate (Italian)
mymage Jun 7, 2023
6fc2e33
Translated using Weblate (Italian)
mymage Jun 8, 2023
399e834
Translated using Weblate (Italian)
francesco-ooops Jun 9, 2023
24cd3c0
Translated using Weblate (Italian)
mymage Jun 14, 2023
b45af0d
Translated using Weblate (Italian)
mymage Jun 15, 2023
6beca88
Translated using Weblate (Italian)
mymage Jun 16, 2023
664efea
Translated using Weblate (Italian)
mymage Jun 23, 2023
9c3cec1
Translated using Weblate (Spanish)
Ivorra78 Jul 8, 2023
72359a9
Translated using Weblate (Italian)
mymage Jul 13, 2023
3c8e376
Translated using Weblate (Italian)
mymage Jul 24, 2023
df03d97
[UPD] README.rst
OCA-git-bot Sep 3, 2023
f1111d1
[UPD] Update quality_control_oca.pot
Sep 3, 2023
9078776
Translated using Weblate (Italian)
mymage Aug 22, 2023
72f10c8
Update translation files
weblate Sep 3, 2023
dc9d0d6
Translated using Weblate (Italian)
mymage Sep 4, 2023
466489c
Translated using Weblate (Spanish)
Ivorra78 Sep 5, 2023
896d07e
Translated using Weblate (Italian)
francesco-ooops Sep 8, 2023
974e546
Translated using Weblate (Italian)
mymage Sep 15, 2023
02b4fe1
Translated using Weblate (Italian)
francesco-ooops Oct 13, 2023
9fb84ea
[UPD] Update quality_control_oca.pot
Oct 27, 2023
616e2aa
Update translation files
weblate Oct 28, 2023
e9b5e3b
Translated using Weblate (Italian)
mymage Nov 8, 2023
39161ae
Translated using Weblate (Italian)
mymage Nov 30, 2023
759845a
[FIX] quality_control_oca: XML-ID must be fully qualified
pedrobaeza Dec 20, 2023
4a5ca7b
[BOT] post-merge updates
OCA-git-bot Dec 20, 2023
c0b886c
[MIG] quality_control_stock_oca: Migration to 16.0
angelmoya Jun 7, 2023
4a3cdb8
[MIG] quality_control_stock_oca: Migration to 16.0
victoralmau Feb 28, 2024
7b06265
[FIX] quality_control_oca add colspan attribute to show the inline tr…
uolaizola Apr 9, 2024
a533496
[BOT] post-merge updates
OCA-git-bot Apr 9, 2024
989080c
[IMP] quality_control_oca: pre-commit auto fixes
peluko00 May 14, 2024
11f31e9
[MIG] quality_control_oca: Migration to 17.0
peluko00 May 14, 2024
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
135 changes: 135 additions & 0 deletions quality_control_oca/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
===================
Quality Control OCA
===================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:f681e05b0e199eb1c9dc6fbaaf96e42573ad9f3de8c94fdb10219d577b0dc541
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
.. |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/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
:target: https://github.com/OCA/manufacture/tree/17.0/quality_control_oca
:alt: OCA/manufacture
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/manufacture-17-0/manufacture-17-0-quality_control_oca
:alt: Translate me on Weblate
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
:target: https://runboat.odoo-community.org/builds?repo=OCA/manufacture&target_branch=17.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module provides a generic infrastructure for quality tests. The
idea is that it can be later reused for doing quality inspections on
production lots or any other area of the company.

**Table of contents**

.. contents::
:local:

Configuration
=============

- Question: The thing to be checked. We have two types of questions:
- Qualitative: The result is a description, color, yes, no...
- Quantitative: The result must be within a range.
- Possible values: The values chosen in qualitative questions.
- Test: The set of questions to be used in inspections.
- Once these values are set, we define the inspection.

We have a *generic* test that can be applied to any model: shipments,
invoices or product, or a *test related*, making it specific to a
particular product and that eg apply whenever food is sold or when
creating a batch.

Once these parameters are set, we can just pass the test. We create a
new inspection, selecting a relationship with the model (sale, stock
move...), and pressing "Select test" button to choose the test to pass.
Then, you must fill the lines depending on the chosen test.

The complete inspection workflow is:

Draft -> Confirmed -> Success

-> Failure (Pending approval) -> Approved

Known issues / Roadmap
======================

- Make translatable the trigger name.

Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/manufacture/issues>`_.
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
`feedback <https://github.com/OCA/manufacture/issues/new?body=module:%20quality_control_oca%0Aversion:%2017.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

Do not contact contributors directly about support or help with technical issues.

Credits
=======

Authors
-------

* AvanzOSC
* Tecnativa

Contributors
------------

- Oihane Crucelaegui <[email protected]>
- Ana Juaristi <[email protected]>
- Lois Rilo <[email protected]>
- Simone Rubino <[email protected]>
- Juan Humanes <[email protected]>
- Ignacio José Alés López <[email protected]>
- Pimolnat Suntian <[email protected]>
- `Tecnativa <https://www.tecnativa.com>`__:

- Pedro M. Baeza
- Carlos Roca

- `Trey Kilobytes de Soluciones SL <https://www.trey.es>`__:

- Vicent Cubells

- `APSL-Nagarro <https://www.apsl.tech>`__:

- Antoni Marroig <[email protected]>

Other credits
-------------

- Originally based on the old
`nan_quality_control <https://github.com/NaN-tic/nan_quality_control>`__
modules from NaN·tic.

Maintainers
-----------

This module is maintained by the OCA.

.. image:: https://odoo-community.org/logo.png
:alt: Odoo Community Association
:target: https://odoo-community.org

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.

This module is part of the `OCA/manufacture <https://github.com/OCA/manufacture/tree/17.0/quality_control_oca>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
4 changes: 4 additions & 0 deletions quality_control_oca/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import models
from . import wizard
32 changes: 32 additions & 0 deletions quality_control_oca/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014-2021 Tecnativa Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017-2020 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

{
"name": "Quality Control OCA",
"version": "17.0.1.0.0",
"category": "Quality Control",
"license": "AGPL-3",
"summary": "Generic infrastructure for quality tests.",
"author": "AvanzOSC, Tecnativa, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/manufacture",
"depends": ["product"],
"data": [
"data/quality_control_data.xml",
"security/quality_control_security.xml",
"security/ir.model.access.csv",
"wizard/qc_test_wizard_view.xml",
"views/qc_menus.xml",
"views/qc_inspection_view.xml",
"views/qc_test_category_view.xml",
"views/qc_test_view.xml",
"views/qc_trigger_view.xml",
"views/product_template_view.xml",
"views/product_category_view.xml",
],
"demo": ["demo/quality_control_demo.xml"],
"installable": True,
}
27 changes: 27 additions & 0 deletions quality_control_oca/data/quality_control_data.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
Copyright 2021 Tecnativa - Carlos Roca
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo noupdate="1">
<record id="qc_test_template_category_generic" model="qc.test.category">
<field name="name">Generic</field>
</record>
<record id="qc_test_template_category_referenced" model="qc.test.category">
<field name="name">Referenced</field>
</record>
<record forcecreate="True" id="decimal_quality_control" model="decimal.precision">
<field name="name">Quality Control</field>
<field name="digits">5</field>
</record>
<record id="seq_qc_inspection" model="ir.sequence">
<field name="name">Quality inspection</field>
<field name="code">qc.inspection</field>
<field name="prefix">QC-</field>
<field name="padding">6</field>
<field name="company_id" eval="False" />
</record>
</odoo>
32 changes: 32 additions & 0 deletions quality_control_oca/demo/quality_control_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo noupdate="1">
<record model="qc.test" id="qc_test_1">
<field name="name">Generic Test (demo)</field>
<field name="type">generic</field>
<field name="active" eval="True" />
<field name="category" ref="qc_test_template_category_generic" />
</record>
<record model="qc.test.question" id="qc_test_question_1">
<field name="name">Overall quality</field>
<field name="test" ref="qc_test_1" />
<field name="type">qualitative</field>
</record>
<record model="qc.test.question.value" id="qc_test_question_value_1">
<field name="name">Good</field>
<field name="ok" eval="True" />
<field name="test_line" ref="qc_test_question_1" />
</record>
<record model="qc.test.question.value" id="qc_test_question_value_2">
<field name="name">Bad</field>
<field name="ok" eval="False" />
<field name="test_line" ref="qc_test_question_1" />
</record>
<record model="qc.test.question" id="qc_test_question_2">
<field name="name">Size</field>
<field name="test" ref="qc_test_1" />
<field name="type">quantitative</field>
<field name="min_value" eval="1.0" />
<field name="max_value" eval="10.0" />
<field name="uom_id" ref="uom.product_uom_unit" />
</record>
</odoo>
1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/am.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/ar.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/bg.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/bs.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/ca.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/ca_ES.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/cs.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/da.po

Large diffs are not rendered by default.

1,132 changes: 1,132 additions & 0 deletions quality_control_oca/i18n/de.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/el_GR.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/en_AU.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/en_GB.po

Large diffs are not rendered by default.

1,119 changes: 1,119 additions & 0 deletions quality_control_oca/i18n/es.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_AR.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_CL.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_CO.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_CR.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_DO.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_EC.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_MX.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_PE.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_PY.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/es_VE.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/et.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/eu.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/fa.po

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/fi.po

Large diffs are not rendered by default.

1,097 changes: 1,097 additions & 0 deletions quality_control_oca/i18n/fr.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/fr_CA.po

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/fr_CH.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/fr_FR.po

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/gl.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/gl_ES.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/he.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/hi.po

Large diffs are not rendered by default.

1,129 changes: 1,129 additions & 0 deletions quality_control_oca/i18n/hr.po

Large diffs are not rendered by default.

1,091 changes: 1,091 additions & 0 deletions quality_control_oca/i18n/hr_HR.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/hu.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/id.po

Large diffs are not rendered by default.

1,142 changes: 1,142 additions & 0 deletions quality_control_oca/i18n/it.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/ja.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/ko.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/lo.po

Large diffs are not rendered by default.

1,091 changes: 1,091 additions & 0 deletions quality_control_oca/i18n/lt.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/lt_LT.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/lv.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/mk.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/mn.po

Large diffs are not rendered by default.

1,090 changes: 1,090 additions & 0 deletions quality_control_oca/i18n/nb.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/nb_NO.po

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/nl.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/nl_BE.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/nl_NL.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/pl.po

Large diffs are not rendered by default.

1,140 changes: 1,140 additions & 0 deletions quality_control_oca/i18n/pt.po

Large diffs are not rendered by default.

1,108 changes: 1,108 additions & 0 deletions quality_control_oca/i18n/pt_BR.po

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/pt_PT.po

Large diffs are not rendered by default.

973 changes: 973 additions & 0 deletions quality_control_oca/i18n/quality_control.pot

Large diffs are not rendered by default.

1,083 changes: 1,083 additions & 0 deletions quality_control_oca/i18n/quality_control_oca.pot

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/ro.po

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/ru.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/sk.po

Large diffs are not rendered by default.

1,112 changes: 1,112 additions & 0 deletions quality_control_oca/i18n/sl.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/sr.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/sr@latin.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/sv.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/th.po

Large diffs are not rendered by default.

1,088 changes: 1,088 additions & 0 deletions quality_control_oca/i18n/tr.po

Large diffs are not rendered by default.

1,090 changes: 1,090 additions & 0 deletions quality_control_oca/i18n/tr_TR.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/uk.po

Large diffs are not rendered by default.

1,086 changes: 1,086 additions & 0 deletions quality_control_oca/i18n/vi.po

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/vi_VN.po

Large diffs are not rendered by default.

1,089 changes: 1,089 additions & 0 deletions quality_control_oca/i18n/zh_CN.po

Large diffs are not rendered by default.

1,087 changes: 1,087 additions & 0 deletions quality_control_oca/i18n/zh_TW.po

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions quality_control_oca/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import qc_trigger
from . import qc_trigger_line
from . import qc_test_category
from . import qc_test
from . import qc_inspection
from . import product_product
from . import product_template
from . import product_category
from . import qc_trigger_product_category_line
from . import qc_trigger_product_line
from . import qc_trigger_product_template_line
18 changes: 18 additions & 0 deletions quality_control_oca/models/product_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ProductCategory(models.Model):
_inherit = "product.category"

qc_triggers = fields.One2many(
comodel_name="qc.trigger.product_category_line",
inverse_name="product_category",
string="Quality control triggers",
)
18 changes: 18 additions & 0 deletions quality_control_oca/models/product_product.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class ProductProduct(models.Model):
_inherit = "product.product"

qc_triggers = fields.One2many(
comodel_name="qc.trigger.product_line",
inverse_name="product",
string="Quality control triggers",
)
18 changes: 18 additions & 0 deletions quality_control_oca/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


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

qc_triggers = fields.One2many(
comodel_name="qc.trigger.product_template_line",
inverse_name="product_template",
string="Quality control triggers",
)
334 changes: 334 additions & 0 deletions quality_control_oca/models/qc_inspection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, api, exceptions, fields, models
from odoo.tools import formatLang


class QcInspection(models.Model):
_name = "qc.inspection"
_description = "Quality control inspection"
_inherit = ["mail.thread", "mail.activity.mixin"]

@api.depends("inspection_lines", "inspection_lines.success")
def _compute_success(self):
for i in self:
i.success = all([x.success for x in i.inspection_lines])

def object_selection_values(self):
"""
Overridable method for adding more object models to an inspection.
:return: A list with the selection's possible values.
"""
return [("product.product", "Product")]

@api.depends("object_id")
def _compute_product_id(self):
for i in self:
if i.object_id and i.object_id._name == "product.product":
i.product_id = i.object_id
else:
i.product_id = False

name = fields.Char(
string="Inspection number",
required=True,
default="/",
copy=False,
)
date = fields.Datetime(
required=True,
copy=False,
default=fields.Datetime.now,
)
object_id = fields.Reference(
string="Reference",
selection="object_selection_values",
ondelete="set null",
)
product_id = fields.Many2one(
comodel_name="product.product",
compute="_compute_product_id",
store=True,
help="Product associated with the inspection",
)
qty = fields.Float(string="Quantity", default=1.0)
test = fields.Many2one(comodel_name="qc.test")
inspection_lines = fields.One2many(
comodel_name="qc.inspection.line",
inverse_name="inspection_id",
)
internal_notes = fields.Text(string="Internal notes")
external_notes = fields.Text()
state = fields.Selection(
[
("draft", "Draft"),
("ready", "Ready"),
("waiting", "Waiting supervisor approval"),
("success", "Quality success"),
("failed", "Quality failed"),
("canceled", "Canceled"),
],
default="draft",
tracking=True,
)
success = fields.Boolean(
compute="_compute_success",
help="This field will be marked if all tests have succeeded.",
store=True,
)
auto_generated = fields.Boolean(
string="Auto-generated",
copy=False,
help="If an inspection is auto-generated, it can be canceled but not removed.",
)
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",
default=lambda self: self.env.company,
)
user = fields.Many2one(
comodel_name="res.users",
string="Responsible",
tracking=True,
default=lambda self: self.env.user,
)

@api.model_create_multi
def create(self, val_list):
for vals in val_list:
if vals.get("name", "/") == "/":
vals["name"] = self.env["ir.sequence"].next_by_code("qc.inspection")
return super().create(vals)

def unlink(self):
for inspection in self:
if inspection.auto_generated:
raise exceptions.UserError(
_("You cannot remove an auto-generated inspection.")
)
if inspection.state != "draft":
raise exceptions.UserError(
_("You cannot remove an inspection that is not in draft state.")
)
return super().unlink()

def action_draft(self):
self.write({"state": "draft"})

def action_todo(self):
for inspection in self:
if not inspection.test:
raise exceptions.UserError(_("You must first set the test to perform."))
self.write({"state": "ready"})

def action_confirm(self):
for inspection in self:
for line in inspection.inspection_lines:
if line.question_type == "qualitative" and not line.qualitative_value:
raise exceptions.UserError(
_(
"You should provide an answer for all "
"qualitative questions."
)
)
elif line.question_type != "qualitative" and not line.uom_id:
raise exceptions.UserError(
_(
"You should provide a unit of measure for "
"quantitative questions."
)
)
if inspection.success:
inspection.state = "success"
else:
inspection.state = "waiting"

def action_approve(self):
for inspection in self:
if inspection.success:
inspection.state = "success"
else:
inspection.state = "failed"

def action_cancel(self):
self.write({"state": "canceled"})

def set_test(self, trigger_line, force_fill=False):
for inspection in self:
header = self._prepare_inspection_header(inspection.object_id, trigger_line)
del header["state"] # don't change current status
del header["auto_generated"] # don't change auto_generated flag
del header["user"] # don't change current user
inspection.write(header)
inspection.inspection_lines.unlink()
inspection.inspection_lines = inspection._prepare_inspection_lines(
trigger_line.test, force_fill=force_fill
)

def _make_inspection(self, object_ref, trigger_line):
"""Overridable hook method for creating inspection from test.
:param object_ref: Object instance
:param trigger_line: Trigger line instance
:return: Inspection object
"""
inspection = self.create(
self._prepare_inspection_header(object_ref, trigger_line)
)
inspection.set_test(trigger_line)
return inspection

def _prepare_inspection_header(self, object_ref, trigger_line):
"""Overridable hook method for preparing inspection header.
:param object_ref: Object instance
:param trigger_line: Trigger line instance
:return: List of values for creating the inspection
"""
return {
"object_id": object_ref and f"{object_ref._name},{object_ref.id}" or False,
"state": "ready",
"test": trigger_line.test.id,
"user": trigger_line.user.id,
"auto_generated": True,
}

def _prepare_inspection_lines(self, test, force_fill=False):
new_data = []
for line in test.test_lines:
data = self._prepare_inspection_line(
test, line, fill=test.fill_correct_values or force_fill
)
new_data.append((0, 0, data))
return new_data

def _prepare_inspection_line(self, test, line, fill=None):
data = {
"name": line.name,
"test_line": line.id,
"notes": line.notes,
"min_value": line.min_value,
"max_value": line.max_value,
"test_uom_id": line.uom_id.id,
"uom_id": line.uom_id.id,
"question_type": line.type,
"possible_ql_values": [x.id for x in line.ql_values],
}
if fill:
if line.type == "qualitative":
# Fill with the first correct value found
for value in line.ql_values:
if value.ok:
data["qualitative_value"] = value.id
break
else:
# Fill with a value inside the interval
data["quantitative_value"] = (line.min_value + line.max_value) * 0.5
return data


class QcInspectionLine(models.Model):
_name = "qc.inspection.line"
_description = "Quality control inspection line"

@api.depends(
"question_type",
"uom_id",
"test_uom_id",
"max_value",
"min_value",
"quantitative_value",
"qualitative_value",
"possible_ql_values",
)
def _compute_quality_test_check(self):
for insp_line in self:
if insp_line.question_type == "qualitative":
insp_line.success = insp_line.qualitative_value.ok
else:
if insp_line.uom_id.id == insp_line.test_uom_id.id:
amount = insp_line.quantitative_value
else:
amount = self.env["uom.uom"]._compute_quantity(
insp_line.quantitative_value, insp_line.test_uom_id.id
)
insp_line.success = insp_line.max_value >= amount >= insp_line.min_value

@api.depends(
"possible_ql_values", "min_value", "max_value", "test_uom_id", "question_type"
)
def _compute_valid_values(self):
for insp_line in self:
if insp_line.question_type == "qualitative":
insp_line.valid_values = ", ".join(
[x.name for x in insp_line.possible_ql_values if x.ok]
)
else:
insp_line.valid_values = "{} ~ {}".format(
formatLang(self.env, insp_line.min_value),
formatLang(self.env, insp_line.max_value),
)
if self.env.ref("uom.group_uom") in self.env.user.groups_id:
insp_line.valid_values += " %s" % insp_line.test_uom_id.name

inspection_id = fields.Many2one(
comodel_name="qc.inspection", string="Inspection", ondelete="cascade"
)
name = fields.Char(string="Question")
product_id = fields.Many2one(
comodel_name="product.product",
related="inspection_id.product_id",
store=True,
)
test_line = fields.Many2one(comodel_name="qc.test.question", string="Test question")
possible_ql_values = fields.Many2many(
comodel_name="qc.test.question.value", string="Answers"
)
quantitative_value = fields.Float(
string="Quantitative value",
digits="Quality Control",
help="Value of the result for a quantitative question.",
)
qualitative_value = fields.Many2one(
comodel_name="qc.test.question.value",
string="Qualitative value",
help="Value of the result for a qualitative question.",
domain="[('id', 'in', possible_ql_values)]",
)
notes = fields.Text()
min_value = fields.Float(
string="Min",
digits="Quality Control",
help="Minimum valid value for a quantitative question.",
)
max_value = fields.Float(
string="Max",
digits="Quality Control",
help="Maximum valid value for a quantitative question.",
)
test_uom_id = fields.Many2one(
comodel_name="uom.uom",
string="Test UoM",
help="UoM for minimum and maximum values for a quantitative " "question.",
)
test_uom_category = fields.Many2one(
comodel_name="uom.category", related="test_uom_id.category_id", store=True
)
uom_id = fields.Many2one(
comodel_name="uom.uom",
string="UoM",
domain="[('category_id', '=', test_uom_category)]",
help="UoM of the inspection value for a quantitative question.",
)
question_type = fields.Selection(
[("qualitative", "Qualitative"), ("quantitative", "Quantitative")],
)
valid_values = fields.Char(
string="Valid values", store=True, compute="_compute_valid_values"
)
success = fields.Boolean(
compute="_compute_quality_test_check", string="Success?", store=True
)
116 changes: 116 additions & 0 deletions quality_control_oca/models/qc_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, api, exceptions, fields, models


class QcTest(models.Model):
"""
A test is a group of questions along with the values that make them valid.
"""

_name = "qc.test"
_description = "Quality control test"
_inherit = "mail.thread"

def object_selection_values(self):
return set()

@api.onchange("type")
def onchange_type(self):
if self.type == "generic":
self.object_id = False

active = fields.Boolean(default=True)
name = fields.Char(required=True, translate=True)
test_lines = fields.One2many(
comodel_name="qc.test.question",
inverse_name="test",
string="Questions",
copy=True,
)
object_id = fields.Reference(
string="Reference object",
selection="object_selection_values",
)
fill_correct_values = fields.Boolean(string="Pre-fill with correct values")
type = fields.Selection(
[("generic", "Generic"), ("related", "Related")],
required=True,
default="generic",
)
category = fields.Many2one(comodel_name="qc.test.category")
company_id = fields.Many2one(
comodel_name="res.company",
default=lambda self: self.env.company,
)


class QcTestQuestion(models.Model):
"""Each test line is a question with its valid value(s)."""

_name = "qc.test.question"
_description = "Quality control question"
_order = "sequence, id"

@api.constrains("ql_values")
def _check_valid_answers(self):
for tc in self:
if (
tc.type == "qualitative"
and tc.ql_values
and not tc.ql_values.filtered("ok")
):
raise exceptions.ValidationError(
_(
"Question '%s' is not valid: "
"you have to mark at least one value as OK."
)
% tc.display_name
)

@api.constrains("min_value", "max_value")
def _check_valid_range(self):
for tc in self:
if tc.type == "quantitative" and tc.min_value > tc.max_value:
raise exceptions.ValidationError(
_(
"Question '%s' is not valid: "
"minimum value can't be higher than maximum value."
)
% tc.display_name
)

sequence = fields.Integer(required=True, default="10")
test = fields.Many2one(comodel_name="qc.test")
name = fields.Char(required=True, translate=True)
type = fields.Selection(
[("qualitative", "Qualitative"), ("quantitative", "Quantitative")],
required=True,
)
ql_values = fields.One2many(
comodel_name="qc.test.question.value",
inverse_name="test_line",
string="Qualitative values",
copy=True,
)
notes = fields.Text()
min_value = fields.Float(string="Min", digits="Quality Control")
max_value = fields.Float(string="Max", digits="Quality Control")
uom_id = fields.Many2one(comodel_name="uom.uom", string="Uom")


class QcTestQuestionValue(models.Model):
_name = "qc.test.question.value"
_description = "Possible values for qualitative questions."

test_line = fields.Many2one(comodel_name="qc.test.question", string="Test question")
name = fields.Char(required=True, translate=True)
ok = fields.Boolean(
string="Correct answer?",
help="When this field is marked, the answer is considered correct.",
)
47 changes: 47 additions & 0 deletions quality_control_oca/models/qc_test_category.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import _, api, exceptions, fields, models


class QcTestTemplateCategory(models.Model):
_name = "qc.test.category"
_description = "Test category"

@api.depends("name", "parent_id")
def _compute_get_complete_name(self):
for record in self:
names = [record.name or ""]
parent = record.parent_id
while parent:
names.append(parent.name)
parent = parent.parent_id
record.complete_name = " / ".join(reversed(names))

@api.constrains("parent_id")
def _check_parent_id(self):
if not self._check_recursion():
raise exceptions.UserError(
_("Error! You can not create recursive categories.")
)

name = fields.Char(required=True, translate=True)
parent_id = fields.Many2one(
comodel_name="qc.test.category", string="Parent category"
)
complete_name = fields.Char(
compute="_compute_get_complete_name", string="Full name"
)
child_ids = fields.One2many(
comodel_name="qc.test.category",
inverse_name="parent_id",
string="Child categories",
)
active = fields.Boolean(
default=True,
help="This field allows you to hide the category without removing it.",
)
26 changes: 26 additions & 0 deletions quality_control_oca/models/qc_trigger.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class QcTrigger(models.Model):
_name = "qc.trigger"
_description = "Quality control trigger"

name = fields.Char(required=True, translate=True)
active = fields.Boolean(default=True)
company_id = fields.Many2one(
comodel_name="res.company",
string="Company",
default=lambda self: self.env.company,
)
partner_selectable = fields.Boolean(
string="Selectable by partner",
default=False,
help="This technical field is to allow to filter by partner in triggers",
)
51 changes: 51 additions & 0 deletions quality_control_oca/models/qc_trigger_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


def _filter_trigger_lines(trigger_lines):
filtered_trigger_lines = []
unique_tests = []
for trigger_line in trigger_lines:
if trigger_line.test not in unique_tests:
filtered_trigger_lines.append(trigger_line)
unique_tests.append(trigger_line.test)
return filtered_trigger_lines


class QcTriggerLine(models.AbstractModel):
_name = "qc.trigger.line"
_inherit = "mail.thread"
_description = "Abstract line for defining triggers"

trigger = fields.Many2one(comodel_name="qc.trigger", required=True)
test = fields.Many2one(comodel_name="qc.test", required=True)
user = fields.Many2one(
comodel_name="res.users",
string="Responsible",
tracking=True,
default=lambda self: self.env.user,
)
partners = fields.Many2many(
comodel_name="res.partner",
help="If filled, the test will only be created when the action is done"
" for one of the specified partners. If empty, the test will always be"
" created.",
domain="[('parent_id', '=', False)]",
)

def get_trigger_line_for_product(self, trigger, product, partner=False):
"""Overridable method for getting trigger_line associated to a product.
Each inherited model will complete this module to make the search by
product, template or category.
:param trigger: Trigger instance.
:param product: Product instance.
:return: Set of trigger_lines that matches to the given product and
trigger.
"""
return set()
34 changes: 34 additions & 0 deletions quality_control_oca/models/qc_trigger_product_category_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class QcTriggerProductCategoryLine(models.Model):
_inherit = "qc.trigger.line"
_name = "qc.trigger.product_category_line"
_description = "Quality Control Trigger Product Category Line"

product_category = fields.Many2one(comodel_name="product.category")

def get_trigger_line_for_product(self, trigger, product, partner=False):
trigger_lines = super().get_trigger_line_for_product(
trigger, product, partner=partner
)
category = product.categ_id
while category:
for trigger_line in category.qc_triggers.filtered(
lambda r: r.trigger == trigger
and (
not r.partners
or not partner
or partner.commercial_partner_id in r.partners
)
):
trigger_lines.add(trigger_line)
category = category.parent_id
return trigger_lines
32 changes: 32 additions & 0 deletions quality_control_oca/models/qc_trigger_product_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class QcTriggerProductLine(models.Model):
_inherit = "qc.trigger.line"
_name = "qc.trigger.product_line"
_description = "Quality Control Trigger Product Line"

product = fields.Many2one(comodel_name="product.product")

def get_trigger_line_for_product(self, trigger, product, partner=False):
trigger_lines = super().get_trigger_line_for_product(
trigger, product, partner=partner
)
for trigger_line in product.qc_triggers.filtered(
lambda r: r.trigger == trigger
and (
not r.partners
or not partner
or partner.commercial_partner_id in r.partners
)
and r.test.active
):
trigger_lines.add(trigger_line)
return trigger_lines
32 changes: 32 additions & 0 deletions quality_control_oca/models/qc_trigger_product_template_line.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class QcTriggerProductTemplateLine(models.Model):
_inherit = "qc.trigger.line"
_name = "qc.trigger.product_template_line"
_description = "Quality Control Trigger Product Template Line"

product_template = fields.Many2one(comodel_name="product.template")

def get_trigger_line_for_product(self, trigger, product, partner=False):
trigger_lines = super().get_trigger_line_for_product(
trigger, product, partner=partner
)
for trigger_line in product.product_tmpl_id.qc_triggers.filtered(
lambda r: r.trigger == trigger
and (
not r.partners
or not partner
or partner.commercial_partner_id in r.partners
)
and r.test.active
):
trigger_lines.add(trigger_line)
return trigger_lines
3 changes: 3 additions & 0 deletions quality_control_oca/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
22 changes: 22 additions & 0 deletions quality_control_oca/readme/CONFIGURE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
- Question: The thing to be checked. We have two types of questions:
- Qualitative: The result is a description, color, yes, no...
- Quantitative: The result must be within a range.
- Possible values: The values chosen in qualitative questions.
- Test: The set of questions to be used in inspections.
- Once these values are set, we define the inspection.

We have a *generic* test that can be applied to any model: shipments,
invoices or product, or a *test related*, making it specific to a
particular product and that eg apply whenever food is sold or when
creating a batch.

Once these parameters are set, we can just pass the test. We create a
new inspection, selecting a relationship with the model (sale, stock
move...), and pressing "Select test" button to choose the test to pass.
Then, you must fill the lines depending on the chosen test.

The complete inspection workflow is:

> Draft -\> Confirmed -\> Success
>
> -\> Failure (Pending approval) -\> Approved
14 changes: 14 additions & 0 deletions quality_control_oca/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
- Oihane Crucelaegui \<<oihanecrucelaegi@avanzosc.es>\>
- Ana Juaristi \<<anajuaristi@avanzosc.es>\>
- Lois Rilo \<<lois.rilo@forgeflow.com>\>
- Simone Rubino \<<simone.rubino@agilebg.com>\>
- Juan Humanes \<<juan.humanes@guadaltech.es>\>
- Ignacio José Alés López \<<ignacio.ales@guadaltech.es>\>
- Pimolnat Suntian \<<pimolnats@ecosoft.co.th>\>
- [Tecnativa](https://www.tecnativa.com):
- Pedro M. Baeza
- Carlos Roca
- [Trey Kilobytes de Soluciones SL](https://www.trey.es):
- Vicent Cubells
- [APSL-Nagarro](https://www.apsl.tech):
- Antoni Marroig \<<amarroig@apsl.net>\>
2 changes: 2 additions & 0 deletions quality_control_oca/readme/CREDITS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Originally based on the old [nan_quality_control](https://github.com/NaN-tic/nan_quality_control) modules from
NaN·tic.
3 changes: 3 additions & 0 deletions quality_control_oca/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
This module provides a generic infrastructure for quality tests. The
idea is that it can be later reused for doing quality inspections on
production lots or any other area of the company.
1 change: 1 addition & 0 deletions quality_control_oca/readme/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Make translatable the trigger name.
20 changes: 20 additions & 0 deletions quality_control_oca/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_user_qc_inspection,qc_inspection,model_qc_inspection,group_quality_control_user,1,1,1,1
access_user_qc_inspection_line,qc_inspection_line,model_qc_inspection_line,group_quality_control_user,1,1,1,1
access_user_qc_test,qc_test user,model_qc_test,group_quality_control_user,1,0,0,0
access_manager_qc_test,qc_test manager,model_qc_test,group_quality_control_manager,1,1,1,1
access_user_qc_test_question,qc_test_question user,model_qc_test_question,group_quality_control_user,1,0,0,0
access_manager_qc_test_question,qc_test_question manager,model_qc_test_question,group_quality_control_manager,1,1,1,1
access_user_qc_test_question_value,qc_test_question_value user,model_qc_test_question_value,group_quality_control_user,1,0,0,0
access_manager_qc_test_question_value,qc_test_question_value manager,model_qc_test_question_value,group_quality_control_manager,1,1,1,1
access_user_qc_test_category,qc_test_category user,model_qc_test_category,group_quality_control_user,1,0,0,0
access_manager_qc_test_category,qc_test_category manager,model_qc_test_category,group_quality_control_manager,1,1,1,1
access_user_qc_trigger,qc_trigger user,model_qc_trigger,group_quality_control_user,1,0,0,0
access_manager_qc_trigger,qc_trigger manager,model_qc_trigger,group_quality_control_manager,1,1,1,1
access_user_qc_trigger_product_category_line,qc_trigger_product_category_line user,model_qc_trigger_product_category_line,group_quality_control_user,1,0,0,0
access_manager_qc_trigger_product_category_line,qc_trigger_product_category_line manager,model_qc_trigger_product_category_line,group_quality_control_manager,1,1,1,1
access_user_qc_trigger_product_template_line,qc_trigger_product_template_line user,model_qc_trigger_product_template_line,group_quality_control_user,1,0,0,0
access_manager_qc_trigger_product_template_line,qc_trigger_product_template_line manager,model_qc_trigger_product_template_line,group_quality_control_manager,1,1,1,1
access_user_qc_trigger_product_line,qc_trigger_product_line user,model_qc_trigger_product_line,group_quality_control_user,1,0,0,0
access_manager_qc_trigger_product_line,qc_trigger_product_line manager,model_qc_trigger_product_line,group_quality_control_manager,1,1,1,1
access_user_qc_inspection_set_test,qc_inspection_set_test user,model_qc_inspection_set_test,group_quality_control_user,1,1,1,0
49 changes: 49 additions & 0 deletions quality_control_oca/security/quality_control_security.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.module.category" id="module_category_quality_control">
<field name="name">Quality control</field>
</record>
<record id="group_quality_control_user" model="res.groups">
<field name="name">User</field>
<field name="category_id" ref="module_category_quality_control" />
</record>
<record id="group_quality_control_manager" model="res.groups">
<field name="name">Manager</field>
<field name="category_id" ref="module_category_quality_control" />
<field name="implied_ids" eval="[(4, ref('group_quality_control_user'))]" />
<field
name="users"
eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"
/>
</record>
<record id="qc_test_multi_company_rule" model="ir.rule">
<field name="name">Quality control test multi-company</field>
<field name="model_id" ref="model_qc_test" />
<field name="global" eval="True" />
<field
name="domain_force"
>['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
</record>
<record id="qc_inspection_multi_company_rule" model="ir.rule">
<field name="name">Quality control inspection multi-company</field>
<field name="model_id" ref="model_qc_inspection" />
<field name="global" eval="True" />
<field
name="domain_force"
>['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
</record>
<record id="qc_trigger_multi_company_rule" model="ir.rule">
<field name="name">Quality control trigger multi-company</field>
<field name="model_id" ref="model_qc_trigger" />
<field name="global" eval="True" />
<field
name="domain_force"
>['|', ('company_id', '=', False), ('company_id', 'in', company_ids)]</field>
</record>
</odoo>
Binary file added quality_control_oca/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
204 changes: 204 additions & 0 deletions quality_control_oca/static/description/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
483 changes: 483 additions & 0 deletions quality_control_oca/static/description/index.html

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions quality_control_oca/tests/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import test_quality_control
234 changes: 234 additions & 0 deletions quality_control_oca/tests/test_quality_control.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import exceptions

from odoo.addons.base.tests.common import BaseCommon

from ..models.qc_trigger_line import _filter_trigger_lines


class TestQualityControlOcaBase(BaseCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.inspection_model = cls.env["qc.inspection"]
cls.category_model = cls.env["qc.test.category"]
cls.question_model = cls.env["qc.test.question"]
cls.wizard_model = cls.env["qc.inspection.set.test"]
cls.qc_trigger = cls.env["qc.trigger"].create({"name": "Test Trigger"})
cls.test = cls.env.ref("quality_control_oca.qc_test_1")
cls.val_ok = cls.env.ref("quality_control_oca.qc_test_question_value_1")
cls.val_ko = cls.env.ref("quality_control_oca.qc_test_question_value_2")
cls.qn_question = cls.env.ref("quality_control_oca.qc_test_question_2")
cls.cat_generic = cls.env.ref(
"quality_control_oca.qc_test_template_category_generic"
)
cls.product = cls.env["product.product"].create({"name": "Test product"})
cls.inspection1 = cls.inspection_model.create(
{
"name": "Test Inspection",
"inspection_lines": cls.inspection_model._prepare_inspection_lines(
cls.test
),
}
)


class TestQualityControlOca(TestQualityControlOcaBase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.wizard = cls.wizard_model.with_context(active_id=cls.inspection1.id).create(
{"test": cls.test.id}
)
cls.wizard.action_create_test()
cls.inspection1.action_todo()

def test_inspection_correct(self):
for line in self.inspection1.inspection_lines:
if line.question_type == "qualitative":
line.qualitative_value = self.val_ok
if line.question_type == "quantitative":
line.quantitative_value = 5.0
self.inspection1.action_confirm()
for line in self.inspection1.inspection_lines:
self.assertTrue(
line.success, "Incorrect state in inspection line %s" % line.name
)
self.assertTrue(
self.inspection1.success,
"Incorrect state in inspection %s" % self.inspection1.name,
)
self.assertEqual(self.inspection1.state, "success")
self.inspection1.action_approve()
self.assertEqual(self.inspection1.state, "success")

def test_inspection_incorrect(self):
for line in self.inspection1.inspection_lines:
if line.question_type == "qualitative":
line.qualitative_value = self.val_ko
if line.question_type == "quantitative":
line.quantitative_value = 15.0
self.inspection1.action_confirm()
for line in self.inspection1.inspection_lines:
self.assertFalse(
line.success, "Incorrect state in inspection line %s" % line.name
)
self.assertFalse(
self.inspection1.success,
"Incorrect state in inspection %s" % self.inspection1.name,
)
self.assertEqual(self.inspection1.state, "waiting")
self.inspection1.action_approve()
self.assertEqual(self.inspection1.state, "failed")

def test_actions_errors(self):
inspection2 = self.inspection1.copy()
inspection2.action_draft()
inspection2.write({"test": False})
with self.assertRaises(exceptions.UserError):
inspection2.action_todo()
inspection3 = self.inspection1.copy()
inspection3.write(
{
"inspection_lines": self.inspection_model._prepare_inspection_lines(
inspection3.test
)
}
)
for line in inspection3.inspection_lines:
if line.question_type == "quantitative":
line.quantitative_value = 15.0
with self.assertRaises(exceptions.UserError):
inspection3.action_confirm()
inspection4 = self.inspection1.copy()
inspection4.write(
{
"inspection_lines": self.inspection_model._prepare_inspection_lines(
inspection4.test
)
}
)
for line in inspection4.inspection_lines:
if line.question_type == "quantitative":
line.write({"uom_id": False, "quantitative_value": 15.0})
elif line.question_type == "qualitative":
line.qualitative_value = self.val_ok
with self.assertRaises(exceptions.UserError):
inspection4.action_confirm()

def test_categories(self):
category1 = self.category_model.create({"name": "Category ONE"})
category2 = self.category_model.create(
{"name": "Category TWO", "parent_id": category1.id}
)
self.assertEqual(
category2.complete_name,
f"{category1.name} / {category2.name}",
"Something went wrong when computing complete name",
)
with self.assertRaises(exceptions.UserError):
category1.parent_id = category2.id

def test_get_qc_trigger_product(self):
self.test.write({"fill_correct_values": True})
trigger_lines = set()
self.product.write(
{
"qc_triggers": [
(0, 0, {"trigger": self.qc_trigger.id, "test": self.test.id})
],
}
)
self.product.product_tmpl_id.write(
{
"qc_triggers": [
(0, 0, {"trigger": self.qc_trigger.id, "test": self.test.id})
],
}
)
self.product.categ_id.write(
{
"qc_triggers": [
(0, 0, {"trigger": self.qc_trigger.id, "test": self.test.id})
],
}
)
for model in [
"qc.trigger.product_category_line",
"qc.trigger.product_template_line",
"qc.trigger.product_line",
]:
trigger_lines = trigger_lines.union(
self.env[model].get_trigger_line_for_product(
self.qc_trigger, self.product
)
)
self.assertEqual(len(trigger_lines), 3)
filtered_trigger_lines = _filter_trigger_lines(trigger_lines)
self.assertEqual(len(filtered_trigger_lines), 1)
for trigger_line in filtered_trigger_lines:
inspection = self.inspection_model._make_inspection(
self.product, trigger_line
)
self.assertEqual(inspection.state, "ready")
self.assertTrue(inspection.auto_generated)
self.assertEqual(inspection.test, self.test)
for line in inspection.inspection_lines:
if line.question_type == "qualitative":
self.assertEqual(line.qualitative_value, self.val_ok)
elif line.question_type == "quantitative":
self.assertAlmostEqual(
round(line.quantitative_value, 2),
round(
(self.qn_question.min_value + self.qn_question.max_value)
* 0.5,
2,
),
)

def test_qc_inspection_not_draft_unlink(self):
with self.assertRaises(exceptions.UserError):
self.inspection1.unlink()
inspection2 = self.inspection1.copy()
inspection2.action_cancel()
self.assertEqual(inspection2.state, "canceled")
inspection2.action_draft()
self.assertEqual(inspection2.state, "draft")
inspection2.unlink()

def test_qc_inspection_auto_generate_unlink(self):
inspection2 = self.inspection1.copy()
inspection2.write({"auto_generated": True})
with self.assertRaises(exceptions.UserError):
inspection2.unlink()

def test_qc_inspection_product(self):
self.inspection1.write(
{"object_id": "%s,%d" % (self.product._name, self.product.id)}
)
self.assertEqual(self.inspection1.product_id, self.product)

def test_qc_test_question_constraints(self):
with self.assertRaises(exceptions.ValidationError):
self.question_model.create(
{
"name": "Quantitative Question",
"type": "quantitative",
"min_value": 1.0,
"max_value": 0.0,
}
)
with self.assertRaises(exceptions.ValidationError):
self.question_model.create(
{
"name": "Qualitative Question",
"type": "qualitative",
"ql_values": [(0, 0, {"name": "Qualitative answer", "ok": False})],
}
)
33 changes: 33 additions & 0 deletions quality_control_oca/views/product_category_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="product_category_qc_form_view">
<field name="name">product.category.qc</field>
<field name="model">product.category</field>
<field name="inherit_id" ref="product.product_category_form_view" />
<field name="arch" type="xml">
<group name="first" position="after">
<t groups="quality_control_oca.group_quality_control_user">
<group name="qc" string="Quality control">
<field name="qc_triggers" nolabel="1">
<tree editable="bottom">
<field
name="trigger"
options="{'no_create': True, 'no_edit': True, 'no_open': True}"
/>
<field name="test" />
<field name="user" />
<field name="partners" widget="many2many_tags" />
</tree>
</field>
</group>
</t>
</group>
</field>
</record>
</odoo>
33 changes: 33 additions & 0 deletions quality_control_oca/views/product_template_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="product_template_form_view">
<field name="name">product.template.common.qc</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="arch" type="xml">
<page name="inventory" position="inside">
<t groups="quality_control_oca.group_quality_control_user">
<group name="qc" string="Quality control">
<field name="qc_triggers" nolabel="1" colspan="2">
<tree editable="bottom">
<field
name="trigger"
options="{'no_create': True, 'no_edit': True, 'no_open': True}"
/>
<field name="test" />
<field name="user" />
<field name="partners" widget="many2many_tags" />
</tree>
</field>
</group>
</t>
</page>
</field>
</record>
</odoo>
357 changes: 357 additions & 0 deletions quality_control_oca/views/qc_inspection_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,357 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="qc_inspection_form_view">
<field name="name">qc.inspection.form</field>
<field name="model">qc.inspection</field>
<field name="arch" type="xml">
<form>
<header>
<button
name="action_draft"
type="object"
invisible="state != 'canceled'"
string="Draft"
/>
<button
name="action_todo"
type="object"
class="oe_highlight"
invisible="state != 'draft'"
string="Mark todo"
/>
<button
name="action_confirm"
type="object"
class="oe_highlight"
invisible="state != 'ready'"
string="Confirm"
icon="fa-check"
/>
<button
name="action_approve"
type="object"
invisible="state != 'waiting'"
class="oe_highlight"
groups="quality_control_oca.group_quality_control_manager"
string="Approve"
/>
<button
name="action_cancel"
type="object"
invisible="state not in ['waiting', 'ready', 'failed', 'success']"
string="Cancel"
icon="fa-ban"
/>
<field
name="state"
widget="statusbar"
statusbar_visible="draft,waiting,success"
readonly="1"
/>
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<button
class="oe_stat_button"
type="action"
name="%(action_qc_inspection_set_test)d"
icon="fa-bookmark-o"
invisible="state != 'draft'"
string="Set test"
/>
</div>
<h1>
<label string="Inspection " for="name" />
<field
name="name"
class="oe_inline"
readonly="state != 'draft'"
/>
</h1>
<group>
<group>
<field name="test" readonly="1" />
<field name="user" />
<field name="object_id" readonly="state != 'draft'" />
<field name="qty" />
<field name="product_id" />
</group>
<group>
<field name="date" readonly="state != 'draft'" />
<field name="success" />
<field name="auto_generated" readonly="1" />
</group>
</group>
<notebook>
<page string="Questions">
<field
name="inspection_lines"
nolabel="1"
readonly="state != 'ready'"
>
<tree editable="top" delete="false" create="false">
<field name="name" readonly="1" />
<field name="question_type" readonly="1" />
<field
name="possible_ql_values"
column_invisible="1"
/>
<field
name="qualitative_value"
readonly="question_type == 'quantitative'"
/>
<field
name="quantitative_value"
readonly="question_type == 'qualitative'"
/>
<field
name="uom_id"
groups="uom.group_uom"
readonly="question_type == 'qualitative'"
/>
<field
name="test_uom_category"
column_invisible="1"
/>
<field
name="min_value"
column_invisible="1"
readonly="1"
/>
<field
name="max_value"
column_invisible="1"
readonly="1"
/>
<field name="valid_values" />
<field name="success" />
</tree>
</field>
</page>
<page string="Notes">
<group string="Internal notes">
<field name="internal_notes" nolabel="1" />
</group>
<group string="External notes">
<field
name="external_notes"
nolabel="1"
readonly="state in ['success', 'failed']"
/>
</group>
</page>
</notebook>
</sheet>
<div class="oe_chatter">
<field
name="message_follower_ids"
widget="mail_followers"
groups="base.group_user"
/>
<field name="message_ids" widget="mail_thread" />
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="qc_inspection_tree_view">
<field name="name">qc.inspection.tree</field>
<field name="model">qc.inspection</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="user" />
<field name="test" />
<field name="qty" />
<field name="product_id" />
<field name="success" />
<field name="state" />
</tree>
</field>
</record>
<record model="ir.ui.view" id="qc_inspection_search_view">
<field name="name">qc.inspection.search</field>
<field name="model">qc.inspection</field>
<field name="arch" type="xml">
<search string="Search inspection">
<group>
<field name="name" />
<field name="user" />
<field name="object_id" />
<field name="product_id" />
<field name="test" />
</group>
<newline />
<filter
string="Correct"
name="correct"
domain="[('success', '=', True)]"
/>
<filter
string="Incorrect"
name="incorrect"
domain="[('success', '=', False)]"
/>
<newline />
<group expand="0" string="Group by...">
<filter
string="Reference"
name="group_by_object_id"
domain="[]"
context="{'group_by': 'object_id'}"
/>
<filter
string="Test"
name="group_by_test"
domain="[]"
context="{'group_by': 'test'}"
/>
<filter
string="Responsible"
name="group_by_user"
domain="[]"
context="{'group_by': 'user'}"
/>
<filter
string="Product"
name="group_by_product_id"
domain="[]"
context="{'group_by': 'product_id'}"
/>
<filter
string="State"
name="group_by_state"
domain="[]"
context="{'group_by': 'state'}"
/>
<filter
string="Success"
name="group_by_success"
domain="[]"
context="{'group_by': 'success'}"
/>
<filter
string="Auto-generated"
name="group_by_auto_generated"
domain="[]"
context="{'group_by': 'auto_generated'}"
/>
</group>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_qc_inspection">
<field name="name">Inspections</field>
<field name="res_model">qc.inspection</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem
name="Inspections"
parent="qc_inspection_menu_parent"
id="qc_inspection_menu"
action="action_qc_inspection"
/>
<record model="ir.ui.view" id="qc_inspection_line_tree_view">
<field name="name">qc.inspection.line.tree</field>
<field name="model">qc.inspection.line</field>
<field name="arch" type="xml">
<tree
decoration-danger="success==False"
decoration-info="success==True"
delete="false"
create="false"
>
<field name="inspection_id" />
<field name="product_id" />
<field name="name" />
<field name="question_type" />
<field name="possible_ql_values" column_invisible="1" />
<field
name="qualitative_value"
readonly="question_type == 'quantitative'"
/>
<field
name="quantitative_value"
readonly="question_type == 'qualitative'"
/>
<field
name="uom_id"
groups="uom.group_uom"
readonly="question_type == 'qualitative'"
/>
<field name="test_uom_category" column_invisible="1" />
<field name="valid_values" />
<field name="success" />
</tree>
</field>
</record>
<record model="ir.ui.view" id="qc_inspection_line_search_view">
<field name="name">qc.inspection.line.search</field>
<field name="model">qc.inspection.line</field>
<field name="arch" type="xml">
<search string="Search inspection line">
<group>
<field name="name" />
<field name="inspection_id" />
<field name="product_id" />
<field name="success" />
</group>
<newline />
<filter
string="Correct"
name="correct"
domain="[('success', '=', True)]"
/>
<filter
string="Incorrect"
name="incorrect"
domain="[('success', '=', False)]"
/>
<newline />
<group expand="0" string="Group by...">
<filter
string="Inspection"
name="group_by_inspection_id"
domain="[]"
context="{'group_by': 'inspection_id'}"
/>
<filter
string="Product"
name="group_by_product_id"
domain="[]"
context="{'group_by': 'product_id'}"
/>
<filter
string="Question"
name="group_by_name"
domain="[]"
context="{'group_by': 'name'}"
/>
<filter
string="Success"
name="group_by_success"
domain="[]"
context="{'group_by': 'success'}"
/>
</group>
</search>
</field>
</record>
<record model="ir.actions.act_window" id="action_qc_inspection_line">
<field name="name">Inspection lines</field>
<field name="res_model">qc.inspection.line</field>
<field name="view_mode">tree</field>
<field name="view_id" ref="qc_inspection_line_tree_view" />
</record>
<menuitem
name="Inspection lines"
parent="qc_inspection_menu_parent"
id="qc_inspection_lines_menu"
action="action_qc_inspection_line"
/>
</odoo>
36 changes: 36 additions & 0 deletions quality_control_oca/views/qc_menus.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<menuitem
name="Quality Control"
id="qc_menu"
groups="quality_control_oca.group_quality_control_user"
web_icon="quality_control_oca,static/description/icon.png"
sequence="40"
/>
<menuitem
name="Inspections"
parent="qc_menu"
id="qc_inspection_menu_parent"
sequence="10"
/>
<menuitem
parent="qc_menu"
name="Tests"
id="qc_menu_test_parent"
groups="group_quality_control_manager"
sequence="20"
/>
<menuitem
name="Configuration"
id="menu_qc_config"
groups="base.group_system"
parent="qc_menu"
sequence="100"
/>
</odoo>
34 changes: 34 additions & 0 deletions quality_control_oca/views/qc_test_category_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="qc_test_category_tree_view">
<field name="name">qc.test.category.tree</field>
<field name="model">qc.test.category</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="complete_name" />
<field name="name" />
<field name="parent_id" />
<field name="active" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_qc_test_category">
<field name="name">Test categories</field>
<field name="res_model">qc.test.category</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem
name="Test categories"
parent="qc_menu_test_parent"
id="qc_test_category_menu"
action="action_qc_test_category"
groups="group_quality_control_manager"
sequence="10"
/>
</odoo>
145 changes: 145 additions & 0 deletions quality_control_oca/views/qc_test_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="qc_test_form_view">
<field name="name">qc.test.form</field>
<field name="model">qc.test</field>
<field name="arch" type="xml">
<form string="Test">
<sheet>
<label for="name" class="oe_edit_only" />
<h1>
<field name="name" class="oe_inline" />
</h1>
<group>
<group>
<field name="type" />
<field name="object_id" invisible="type == 'generic'" />
<field name="active" />
</group>
<group>
<field name="category" />
<field name="fill_correct_values" />
<field
name="company_id"
groups="base.group_multi_company"
/>
</group>
</group>
<field name="test_lines" nolabel="1">
<tree>
<field name="sequence" widget="handle" />
<field name="name" />
<field name="type" />
<field name="min_value" />
<field name="max_value" />
<field name="uom_id" />
<field name="ql_values" />
</tree>
</field>
</sheet>
<div class="oe_chatter">
<field name="message_follower_ids" widget="mail_followers" />
<field name="message_ids" widget="mail_thread" />
</div>
</form>
</field>
</record>
<record model="ir.ui.view" id="qc_test_tree_view">
<field name="name">qc.test.tree</field>
<field name="model">qc.test</field>
<field name="arch" type="xml">
<tree>
<field name="name" />
<field name="category" />
<field name="type" />
<field name="object_id" />
<field name="company_id" groups="base.group_multi_company" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_qc_test">
<field name="name">Tests</field>
<field name="res_model">qc.test</field>
<field name="view_mode">tree,form</field>
</record>
<record model="ir.ui.view" id="qc_test_question_form_view">
<field name="name">qc.test.question.form</field>
<field name="model">qc.test.question</field>
<field name="arch" type="xml">
<form string="Test question">
<label for="name" class="oe_edit_only" />
<h1>
<field name="name" class="oe_inline" />
</h1>
<group>
<field name="sequence" />
<field name="type" />
</group>
<group
name="qualitative"
string="Answers"
colspan="4"
invisible="type != 'qualitative'"
>
<field
name="ql_values"
nolabel="1"
colspan="2"
required="type == 'qualitative'"
>
<tree editable="bottom">
<field name="name" />
<field name="ok" />
</tree>
</field>
</group>
<div
name="quantitative"
align="center"
invisible="type != 'quantitative'"
>
<h1 name="quantitative-data">
<span name="quantitative-interval">
<field
name="min_value"
class="oe_inline"
nolabel="1"
required="type == 'quantitative'"
/>
<span> - </span>
<field
name="max_value"
class="oe_inline"
nolabel="1"
required="type == 'quantitative'"
/>
</span>
<span name="quantitative-uom">
<field
name="uom_id"
class="oe_inline"
nolabel="1"
required="type == 'quantitative'"
/>
</span>
</h1>
</div>
<field name="notes" />
</form>
</field>
</record>
<menuitem
name="Tests"
parent="qc_menu_test_parent"
id="qc_test_menu"
action="action_qc_test"
groups="group_quality_control_manager"
sequence="20"
/>
</odoo>
47 changes: 47 additions & 0 deletions quality_control_oca/views/qc_trigger_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record model="ir.ui.view" id="qc_trigger_form_view">
<field name="name">qc.trigger.form</field>
<field name="model">qc.trigger</field>
<field name="arch" type="xml">
<form string="Quality control trigger">
<group>
<field name="name" />
<field name="active" />
<field name="partner_selectable" readonly="1" />
</group>
<group>
<field name="company_id" groups="base.group_multi_company" />
</group>
</form>
</field>
</record>
<record model="ir.ui.view" id="qc_trigger_tree_view">
<field name="name">qc.trigger.tree</field>
<field name="model">qc.trigger</field>
<field name="arch" type="xml">
<tree editable="bottom">
<field name="name" />
<field name="company_id" groups="base.group_multi_company" />
<field name="partner_selectable" />
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_qc_trigger">
<field name="name">Triggers</field>
<field name="res_model">qc.trigger</field>
<field name="view_mode">tree,form</field>
</record>
<menuitem
name="Triggers"
parent="menu_qc_config"
id="qc_trigger_menu"
action="action_qc_trigger"
/>
</odoo>
3 changes: 3 additions & 0 deletions quality_control_oca/wizard/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from . import qc_test_wizard
28 changes: 28 additions & 0 deletions quality_control_oca/wizard/qc_test_wizard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Copyright 2010 NaN Projectes de Programari Lliure, S.L.
# Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
# Copyright 2014 Oihane Crucelaegui - AvanzOSC
# Copyright 2017 ForgeFlow S.L.
# Copyright 2017 Simone Rubino - Agile Business Group
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).

from odoo import fields, models


class QcInspectionSetTest(models.TransientModel):
"""This wizard is used to preset the test for a given
inspection. This will not only fill in the 'test' field, but will
also fill in all lines of the inspection with the corresponding lines of
the template.
"""

_name = "qc.inspection.set.test"
_description = "Set test for inspection"

test = fields.Many2one(comodel_name="qc.test")

def action_create_test(self):
inspection = self.env["qc.inspection"].browse(self.env.context["active_id"])
inspection.test = self.test
inspection.inspection_lines.unlink()
inspection.inspection_lines = inspection._prepare_inspection_lines(self.test)
return True
37 changes: 37 additions & 0 deletions quality_control_oca/wizard/qc_test_wizard_view.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!-- Copyright 2010 NaN Projectes de Programari Lliure, S.L.
Copyright 2014 Serv. Tec. Avanzados - Pedro M. Baeza
Copyright 2014 Oihane Crucelaegui - AvanzOSC
Copyright 2017 ForgeFlow S.L.
Copyright 2017 Simone Rubino - Agile Business Group
License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="view_qc_test_set_test_form" model="ir.ui.view">
<field name="name">qc.inspection.set.test.form</field>
<field name="model">qc.inspection.set.test</field>
<field name="arch" type="xml">
<form string="Select test" version="7.0">
<group>
<field name="test" />
</group>
<footer>
<button
name="action_create_test"
string="Accept"
type="object"
class="oe_highlight"
/>
or
<button special="cancel" class="oe_link" string="Cancel" />
</footer>
</form>
</field>
</record>
<record id="action_qc_inspection_set_test" model="ir.actions.act_window">
<field name="name">Select test</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">qc.inspection.set.test</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</odoo>