质量模块和库存扫码

This commit is contained in:
qihao.gong@jikimo.com
2023-07-24 11:42:15 +08:00
parent 8d024ad625
commit 3c89404543
228 changed files with 142596 additions and 0 deletions

View 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

View 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

View 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>