质量模块和库存扫码
This commit is contained in:
4
quality_control/wizard/__init__.py
Normal file
4
quality_control/wizard/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import quality_check_wizard
|
||||
114
quality_control/wizard/quality_check_wizard.py
Normal file
114
quality_control/wizard/quality_check_wizard.py
Normal file
@@ -0,0 +1,114 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
import ast
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class QualityCheckWizard(models.TransientModel):
|
||||
_name = 'quality.check.wizard'
|
||||
_description = "Wizard for Quality Check Pop Up"
|
||||
|
||||
check_ids = fields.Many2many('quality.check', required=True)
|
||||
current_check_id = fields.Many2one('quality.check', required=True)
|
||||
nb_checks = fields.Integer(compute='_compute_nb_checks')
|
||||
position_current_check = fields.Integer(compute='_compute_position')
|
||||
is_last_check = fields.Boolean(compute='_compute_position')
|
||||
|
||||
# fields linked to the current_check_id
|
||||
name = fields.Char(related='current_check_id.name')
|
||||
title = fields.Char(related='current_check_id.title')
|
||||
product_id = fields.Many2one(related='current_check_id.product_id')
|
||||
lot_name = fields.Char(related='current_check_id.lot_name')
|
||||
lot_line_id = fields.Many2one(related='current_check_id.lot_line_id')
|
||||
qty_line = fields.Float(related='current_check_id.qty_line')
|
||||
qty_to_test = fields.Float(related='current_check_id.qty_to_test')
|
||||
qty_tested = fields.Float(related='current_check_id.qty_tested', readonly=False)
|
||||
measure = fields.Float(related='current_check_id.measure', readonly=False)
|
||||
measure_on = fields.Selection(related='current_check_id.measure_on')
|
||||
quality_state = fields.Selection(related='current_check_id.quality_state')
|
||||
test_type = fields.Char(related='current_check_id.test_type')
|
||||
norm_unit = fields.Char(related='current_check_id.norm_unit')
|
||||
picture = fields.Binary(related='current_check_id.picture', readonly=False)
|
||||
note = fields.Html(related='current_check_id.note', readonly=False)
|
||||
additional_note = fields.Text(related='current_check_id.additional_note', readonly=False)
|
||||
is_lot_tested_fractionally = fields.Boolean(related="current_check_id.is_lot_tested_fractionally")
|
||||
testing_percentage_within_lot = fields.Float(related="current_check_id.testing_percentage_within_lot")
|
||||
uom_id = fields.Many2one(related="current_check_id.uom_id")
|
||||
warning_message = fields.Text(related='current_check_id.warning_message')
|
||||
failure_message = fields.Html(related='current_check_id.failure_message')
|
||||
show_lot_text = fields.Boolean(related='current_check_id.show_lot_text')
|
||||
product_tracking = fields.Selection(related='current_check_id.product_tracking')
|
||||
|
||||
@api.depends('current_check_id', 'check_ids')
|
||||
def _compute_nb_checks(self):
|
||||
for wz in self:
|
||||
wz.nb_checks = len(wz.check_ids)
|
||||
|
||||
@api.depends('current_check_id', 'check_ids')
|
||||
def _compute_position(self):
|
||||
for wz in self:
|
||||
wz.position_current_check = wz.check_ids.ids.index(wz.current_check_id.id) + 1
|
||||
wz.is_last_check = False
|
||||
if wz.position_current_check == len(wz.check_ids):
|
||||
wz.is_last_check = True
|
||||
|
||||
def do_measure(self):
|
||||
self.current_check_id.do_measure()
|
||||
if self.quality_state == 'fail' and self.current_check_id._is_pass_fail_applicable() and (self.failure_message or self.warning_message):
|
||||
return self.show_failure_message()
|
||||
return self.action_generate_next_window()
|
||||
|
||||
def do_pass(self):
|
||||
if self.test_type == 'picture' and not self.picture:
|
||||
raise UserError('You must provide a picture before validating')
|
||||
self.current_check_id.do_pass()
|
||||
return self.action_generate_next_window()
|
||||
|
||||
def do_fail(self):
|
||||
self.current_check_id.do_fail()
|
||||
if self.quality_state == 'fail' and self.current_check_id._is_pass_fail_applicable() and (self.failure_message or self.warning_message):
|
||||
return self.show_failure_message()
|
||||
return self.action_generate_next_window()
|
||||
|
||||
def action_generate_next_window(self):
|
||||
if not self.is_last_check:
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("quality_control.action_quality_check_wizard")
|
||||
action['context'] = dict(ast.literal_eval(action['context']))
|
||||
action['context'].update(
|
||||
self.env.context,
|
||||
default_current_check_id=self.check_ids[self.position_current_check].id
|
||||
)
|
||||
return action
|
||||
|
||||
def action_generate_previous_window(self):
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("quality_control.action_quality_check_wizard")
|
||||
action['context'] = dict(ast.literal_eval(action['context']))
|
||||
action['context'].update(
|
||||
self.env.context,
|
||||
default_current_check_id=self.check_ids[self.position_current_check - 2].id
|
||||
)
|
||||
return action
|
||||
|
||||
def show_failure_message(self):
|
||||
return {
|
||||
'name': _('Quality Check Failed'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'quality.check.wizard',
|
||||
'views': [(self.env.ref('quality_control.quality_check_wizard_form_failure').id, 'form')],
|
||||
'target': 'new',
|
||||
'res_id': self.id,
|
||||
'context': self.env.context,
|
||||
}
|
||||
|
||||
def correct_measure(self):
|
||||
self.current_check_id.quality_state = 'none'
|
||||
action = self.env["ir.actions.actions"]._for_xml_id("quality_control.action_quality_check_wizard")
|
||||
action['context'] = dict(ast.literal_eval(action['context']))
|
||||
action['context'].update(
|
||||
self.env.context,
|
||||
default_check_ids=self.check_ids.ids,
|
||||
default_current_check_id=self.current_check_id.id,
|
||||
)
|
||||
return action
|
||||
121
quality_control/wizard/quality_check_wizard_views.xml
Normal file
121
quality_control/wizard/quality_check_wizard_views.xml
Normal file
@@ -0,0 +1,121 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<record id="view_quality_check_wizard" model="ir.ui.view">
|
||||
<field name="name">quality_check_wizard</field>
|
||||
<field name="model">quality.check.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Quality Checks">
|
||||
<field name="current_check_id" invisible="1"/>
|
||||
<field name="measure_on" invisible="1"/>
|
||||
<field name="test_type" invisible="1"/>
|
||||
<field name="quality_state" invisible="1"/>
|
||||
<field name="is_last_check" invisible="1"/>
|
||||
<field name="testing_percentage_within_lot" invisible="1"/>
|
||||
<field name="is_lot_tested_fractionally" invisible="1"/>
|
||||
<field name="show_lot_text" invisible="1"/>
|
||||
<field name="product_tracking" invisible="1"/>
|
||||
|
||||
<h2 class="o_row d-flex justify-content-between">
|
||||
<span>
|
||||
<span attrs="{'invisible': [('product_id', '=', False)]}">
|
||||
<field name="product_id" readonly="1" options="{'no_open': True}"/>
|
||||
:
|
||||
</span>
|
||||
<field name="name" readonly="1"/>
|
||||
<field class="ml8" name="title" readonly="1"/>
|
||||
</span>
|
||||
<span>
|
||||
<field name="position_current_check" readonly="1"/> /
|
||||
<field name="nb_checks" readonly="1"/>
|
||||
</span>
|
||||
</h2>
|
||||
<field name="note" readonly="1"/>
|
||||
<group attrs="{'invisible': [('measure_on', '!=', 'move_line')]}">
|
||||
<group>
|
||||
<field name="lot_name" string="Lot/SN" attrs="{'invisible': ['|', ('show_lot_text', '!=', True), ('product_tracking', '=', 'none')]}"/>
|
||||
<field name="lot_line_id" string="Lot/SN" attrs="{'invisible': ['|', ('show_lot_text', '=', True), ('product_tracking', '=', 'none')]}"/>
|
||||
<label for="qty_line"/>
|
||||
<div class="o_row">
|
||||
<field name="qty_line"/>
|
||||
<field name="uom_id"/>
|
||||
</div>
|
||||
<label for="qty_to_test" attrs="{'invisible': [('is_lot_tested_fractionally', '!=', True)]}"/>
|
||||
<div class="o_row" attrs="{'invisible': [('is_lot_tested_fractionally', '!=', True)]}">
|
||||
<field name="qty_to_test"/>
|
||||
<field name="uom_id"/>
|
||||
</div>
|
||||
<label for="qty_tested" attrs="{'invisible': [('is_lot_tested_fractionally', '!=', True)]}"/>
|
||||
<div class="o_row" attrs="{'invisible': [('is_lot_tested_fractionally', '!=', True)]}">
|
||||
<field name="qty_tested" attrs="{'readonly': [('quality_state', '!=', 'none')]}"/>
|
||||
<field name="uom_id"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<group>
|
||||
<group>
|
||||
<label for="measure" attrs="{'invisible': [('test_type', '!=', 'measure')]}"/>
|
||||
<div attrs="{'invisible': [('test_type', '!=', 'measure')]}" class="o_row">
|
||||
<field name="measure" attrs="{'readonly': [('quality_state', '!=', 'none')]}"/>
|
||||
<field name="norm_unit" string="Unit of Measure"/>
|
||||
</div>
|
||||
</group>
|
||||
</group>
|
||||
<label for="picture" invisible="1"/>
|
||||
<div attrs="{'invisible': [('test_type', '!=', 'picture')]}">
|
||||
<field name="picture" widget="image" attrs="{'readonly': [('quality_state', '!=', 'none')]}"/>
|
||||
</div>
|
||||
<group>
|
||||
<field name="additional_note" attrs="{'readonly': [('quality_state', '!=', 'none')]}"/>
|
||||
</group>
|
||||
<footer>
|
||||
<button name="do_measure" type="object" class="btn-primary" string="Validate"
|
||||
attrs="{'invisible': [ '|', ('quality_state', '!=', 'none'), ('test_type', '!=', 'measure')]}" data-hotkey="q"/>
|
||||
<button name="do_pass" type="object" class="btn-primary" string="Validate"
|
||||
attrs="{'invisible': [ '|', ('quality_state', '!=', 'none'), ('test_type', 'not in', ('picture', 'instructions') )]}" data-hotkey="w"/>
|
||||
<button name="do_pass" type="object" class="btn-primary" string="Pass"
|
||||
attrs="{'invisible': ['|', ('quality_state', '!=', 'none'), ('test_type', '!=', 'passfail')]}" data-hotkey="w"/>
|
||||
<button name="do_fail" type="object" class="btn-primary" string="Fail"
|
||||
attrs="{'invisible': ['|', ('quality_state', '!=', 'none'), ('test_type', '!=', 'passfail')]}" data-hotkey="x"/>
|
||||
<button name="action_generate_previous_window" type="object" class="btn-secondary" string="Previous" attrs="{'invisible': [('position_current_check', '=', 1)]}"/>
|
||||
<button name="action_generate_next_window" type="object" class="btn-secondary" string="Next" attrs="{'invisible': [('is_last_check', '=', True)]}"/>
|
||||
<button string="Cancel" class="btn btn-secondary" special="cancel" data-hotkey="z" />
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="quality_check_wizard_form_failure" model="ir.ui.view">
|
||||
<field name="name">quality.check.wizard.form.failure</field>
|
||||
<field name="priority">1000</field>
|
||||
<field name="model">quality.check.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Quality Check Failed">
|
||||
<field name="test_type" invisible="1"/>
|
||||
<div class="alert alert-warning" role="alert" attrs="{'invisible': [('test_type', '!=', 'measure')]}" >
|
||||
<field name="warning_message"/>
|
||||
</div>
|
||||
<div>
|
||||
<field name="failure_message"/>
|
||||
</div>
|
||||
<footer>
|
||||
<button name="correct_measure" type="object" class="btn-primary" string="Correct Measure"
|
||||
attrs="{'invisible': [('test_type', '!=', 'measure')]}" data-hotkey="q"/>
|
||||
<button name="action_generate_next_window" type="object" string="Confirm Measure"
|
||||
attrs="{'invisible': [('test_type', '!=', 'measure')]}" data-hotkey="w"/>
|
||||
<button name="action_generate_next_window" type="object" class="btn-primary" string="OK"
|
||||
attrs="{'invisible': [('test_type', '!=', 'passfail')]}" data-hotkey="w"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_quality_check_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Quality Check</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">quality.check.wizard</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="context">{}</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user