[IMP] quality_control_issue: add scrap feature.

This commit is contained in:
lreficent
2017-07-28 12:08:40 +02:00
committed by Jordi Ballester Alomar
parent e16506f189
commit 4075ce1ffe
10 changed files with 195 additions and 20 deletions

View File

@@ -2,3 +2,4 @@
# Add a repository url and branch if you need a forked version
product-attribute
stock-logistics-warehouse
stock-logistics-workflow

View File

@@ -6,17 +6,59 @@
Quality Control Issue
=====================
WIP
This module extends the functionality of quality Control to allow you to
report and manage quality control issues.
Configuration
=============
To configure this module in order to take advantage of the kanban views you
need to create the stages for *issues* and *problems*. To **create** stages in
any kanban view click on *Add New Column*. Then you can **reorder** the stages
just dragging them.
In created stages you can **configure** them clicking on the gear button that
appears at the right of the stage name and clicking on *Edit*. Note the
following behaviors:
* You can set a *Quality Control Team*.
- Stages with no team set will be shared by all teams.
- Stages with a team associated will be only available for that specific
team.
* In Issue Stages you can also relate a *QC State* to the stage.
- When you move to a different stage an issue with *QC state* defined the
state of the issue will also change according to it.
- The other way around, if you change the state, the system will look for
an appropriate stage and if existing the issue will be move to that stage.
- If you change the *QC team* of an issue, the system will get the default
stage for that team and apply it to the issue.
Usage
=====
To use this module, you need to:
To use Quality Control Issues, you need to:
#. Go to *Quality Control > Issues > QC Issues*.
#. Go to *Quality Control > Issues > QC Issues* or to *Quality Control >
Dashboard* and click on *Issues* in any of your teams.
#. Click on create to report an issue.
#. Select the product and quantity for the issue. Optionally you can specify
a location and relate the issue to some *Problem*.
To manage your Quality Control Problems, you have to:
#. Go to *Quality Control > Problem Tracking > Problems* or to *Quality
Control > Dashboard* and click on *Problems* in any of your teams.
Issue Dispositions:
-------------------
You can perform the following actions in quality control issues 'in progress':
* Scrap: Click on *Scrap Products* button.
* Create RMA: Install `rma_quality_control_issue` and see instructions there.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
@@ -28,9 +70,7 @@ Known issues / Roadmap
Todo:
-----
* Add Dispositions: RMA, scrap, rework...
* reference to PO, MO, QC...
* Link to Problem tracking...
* Add more dispositions: repair, refurbish...
Bug Tracker
===========
@@ -52,6 +92,7 @@ Contributors
------------
* Lois Rilo <lois.rilo@eficent.com>
* Jordi Ballester Alomar <jordi.ballester@eficent.com>
Maintainer
----------

View File

@@ -11,7 +11,12 @@
"license": "AGPL-3",
"application": False,
"installable": True,
"depends": ["quality_control", "quality_control_team", "stock"],
"depends": [
"quality_control",
"quality_control_team",
"stock",
"stock_scrap",
],
"data": [
"security/ir.model.access.csv",
"security/quality_control_issue_security.xml",
@@ -21,5 +26,6 @@
"views/qc_problem_view.xml",
"views/qc_problem_group_view.xml",
"views/qc_team_dashboard_view.xml",
"views/stock_scrap_view.xml",
],
}

View File

@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import stock_scrap
from . import qc_stage
from . import qc_problem
from . import qc_problem_group

View File

@@ -2,7 +2,8 @@
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import api, fields, models
from openerp import api, fields, models, _
from openerp.exceptions import UserError
import openerp.addons.decimal_precision as dp
@@ -11,6 +12,12 @@ class QualityControlIssue(models.Model):
_description = "Quality Control Issue"
_inherit = "mail.thread"
@api.multi
def _compute_stock_scrap_qty(self):
for rec in self:
rec.stock_scrap_qty = sum(
self.stock_scrap_ids.mapped('scrap_qty'))
@api.model
def create(self, vals):
vals['name'] = self.env['ir.sequence'].next_by_code(
@@ -61,7 +68,7 @@ class QualityControlIssue(models.Model):
("progress", "In Progress"),
("done", "Done"),
("cancel", "Cancel")], default="new",
track_visibility='onchange')
track_visibility='onchange', readonly=True)
product_id = fields.Many2one(
comodel_name="product.product", string="Product",
readonly=True, states={"new": [("readonly", False)]}, required=True)
@@ -111,6 +118,10 @@ class QualityControlIssue(models.Model):
company_id = fields.Many2one(
comodel_name='res.company', string='Company', required=True,
default=lambda self: self.env.user.company_id)
stock_scrap_ids = fields.One2many(
comodel_name='stock.scrap', string='Scraps',
inverse_name='qc_issue_id')
stock_scrap_qty = fields.Integer(compute=_compute_stock_scrap_qty)
_group_by_full = {
'stage_id': _read_group_stage_ids
@@ -131,18 +142,47 @@ class QualityControlIssue(models.Model):
team_ids.add(issue.team_id.id)
search_domain = []
if team_ids:
search_domain += [('|')] * (len(team_ids) - 1)
search_domain += [('|')] * (len(team_ids))
search_domain.append(('qc_team_id', '=', False))
for team_id in team_ids:
search_domain.append(('qc_team_id', '=', team_id))
else:
search_domain.append(('qc_team_id', '=', False))
search_domain += list(domain)
# perform search, return the first found
stage = self.env['qc.issue.stage'].search(
search_domain, order=order, limit=1)
return stage
@api.multi
def write(self, vals):
stage_obj = self.env['qc.issue.stage']
state = vals.get('state')
if state:
if len(self.mapped('qc_team_id')) > 1:
raise UserError(_(
"Every issue must have the same QC team to perform this "
"action."))
team = self[0].qc_team_id
stage = self.issue_stage_find([], team, [('state', '=', state)])
if stage:
vals.update({'stage_id': stage.id})
return super(QualityControlIssue, self).write(vals)
team_id = vals.get('qc_team_id')
if team_id is not None:
team = self.env['qc.team'].browse(team_id)
stage = self.issue_stage_find([], team, [('fold', '=', False)])
if stage:
vals.update({'stage_id': stage.id})
stage_id = vals.get('stage_id')
if stage_id:
state = stage_obj.browse(stage_id).state
if state:
vals.update({'state': state})
return super(QualityControlIssue, self).write(vals)
@api.multi
def action_confirm(self):
self._check_required_fields()
self.write({'state': 'progress'})
@api.multi
@@ -170,7 +210,38 @@ class QualityControlIssue(models.Model):
self.product_id = product
self.product_uom = product.product_tmpl_id.uom_id
@api.onchange("stage_id")
def _onchange_stage_id(self):
if self.stage_id.state:
self.state = self.stage_id.state
@api.multi
def scrap_products(self):
self.ensure_one()
return {
'name': _('Scrap'),
'view_type': 'form',
'view_mode': 'form',
'res_model': 'stock.scrap',
'view_id': self.env.ref('stock_scrap.stock_scrap_form_view2').id,
'type': 'ir.actions.act_window',
'context': {
'default_qc_issue_id': self.id,
'default_location_id': self.location_id.id,
'default_product_id': self.product_id.id,
'default_scrap_qty': self.product_qty,
'default_product_uom_id': self.product_uom.id,
'default_lot_id': self.lot_id.id,
},
'target': 'new',
}
@api.multi
def action_view_stock_scrap(self):
action = self.env.ref('stock_scrap.action_stock_scrap')
result = action.read()[0]
lines = self.stock_scrap_ids
# choose the view_mode accordingly
if len(lines) != 1:
result['domain'] = "[('id', 'in', " + \
str(lines.ids) + ")]"
elif len(lines) == 1:
res = self.env.ref('stock_scrap.stock_scrap_form_view', False)
result['views'] = [(res and res.id or False, 'form')]
result['res_id'] = lines.id
return result

View File

@@ -40,5 +40,5 @@ class QualityControlIssueStage(models.Model):
help='This stage is folded in the kanban view when there are no '
'records in that stage to display.')
state = fields.Selection(
string="QC Status",
string="QC State",
selection=lambda self: self.env['qc.issue']._fields['state'].selection)

View File

@@ -101,9 +101,12 @@ class QcProblem(models.Model):
team_ids.add(problem.team_id.id)
search_domain = []
if team_ids:
search_domain += [('|')] * (len(team_ids) - 1)
search_domain += [('|')] * (len(team_ids))
search_domain.append(('qc_team_id', '=', False))
for team_id in team_ids:
search_domain.append(('qc_team_id', '=', team_id))
else:
search_domain.append(('qc_team_id', '=', False))
search_domain += list(domain)
# perform search, return the first found
stage = self.env['qc.stage'].search(

View File

@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# Copyright 2017 Eficent Business and IT Consulting Services S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import fields, models
class QualityControlIssueStage(models.Model):
_inherit = "stock.scrap"
qc_issue_id = fields.Many2one(
comodel_name="qc.issue", string="Quality Control Issue")

View File

@@ -29,7 +29,10 @@
string="Confirm" class="oe_highlight" />
<button name="action_done"
type="object" states="progress"
string="Set to Done" class="oe_highlight" />
string="Set to Done" class="oe_highlight"/>
<button name="scrap_products"
string="Scrap Products" type="object"
states="progress"/>
<button name="action_cancel"
type="object" states="new,progress"
string="Cancel"/>
@@ -39,7 +42,14 @@
</header>
<sheet>
<div class="oe_button_box" name="button_box">
<!--To be inhereted by other modules.-->
<button type="object" name="action_view_stock_scrap"
class="oe_stat_button"
icon="fa-recycle"
context="{'default_qc_issue_id': active_id}">
<field name="stock_scrap_qty"
widget="statinfo"
string="Scrapped products"/>
</button>
</div>
<div class="oe_title">
<label string="Quality Control Issue"/>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2017 Eficent Business and IT Consulting Services S.L.
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="stock_scrap_form_view" model="ir.ui.view">
<field name="name">stock.scrap.form - quality_control_issue</field>
<field name="model">stock.scrap</field>
<field name="inherit_id" ref="stock_scrap.stock_scrap_form_view"/>
<field name="arch" type="xml">
<field name="owner_id" position="after">
<field name="qc_issue_id" attrs="{'invisible': [('qc_issue_id', '=', False)]}"/>
</field>
</field>
</record>
<record id="stock_scrap_form_view2" model="ir.ui.view">
<field name="name">stock.scrap.form2 - quality_control_issue</field>
<field name="model">stock.scrap</field>
<field name="inherit_id" ref="stock_scrap.stock_scrap_form_view2"/>
<field name="arch" type="xml">
<field name="owner_id" position="after">
<field name="qc_issue_id" attrs="{'invisible': [('qc_issue_id', '=', False)]}"/>
</field>
</field>
</record>
</odoo>