质量检查优化

This commit is contained in:
mgw
2025-03-10 17:10:27 +08:00
parent 1541326dfc
commit 2cc7386027
5 changed files with 68 additions and 26 deletions

View File

@@ -34,7 +34,8 @@ class QualityPoint(models.Model):
('day', 'Days'), ('day', 'Days'),
('week', 'Weeks'), ('week', 'Weeks'),
('month', 'Months')], default="day") # TDE RENAME ? ('month', 'Months')], default="day") # TDE RENAME ?
is_lot_tested_fractionally = fields.Boolean(string="Lot Tested Fractionally", help="Determines if only a fraction of the lot should be tested") is_lot_tested_fractionally = fields.Boolean(string="Lot Tested Fractionally",
help="Determines if only a fraction of the lot should be tested")
testing_percentage_within_lot = fields.Float(help="Defines the percentage within a lot that should be tested") testing_percentage_within_lot = fields.Float(help="Defines the percentage within a lot that should be tested")
norm = fields.Float('Norm', digits='Quality Tests') # TDE RENAME ? norm = fields.Float('Norm', digits='Quality Tests') # TDE RENAME ?
tolerance_min = fields.Float('Min Tolerance', digits='Quality Tests') tolerance_min = fields.Float('Min Tolerance', digits='Quality Tests')
@@ -63,7 +64,7 @@ class QualityPoint(models.Model):
if n > 1: if n > 1:
point.average = mean point.average = mean
point.standard_deviation = sqrt( s / ( n - 1)) point.standard_deviation = sqrt(s / (n - 1))
elif n == 1: elif n == 1:
point.average = mean point.average = mean
point.standard_deviation = 0.0 point.standard_deviation = 0.0
@@ -94,7 +95,7 @@ class QualityPoint(models.Model):
checks = self.env['quality.check'].search([ checks = self.env['quality.check'].search([
('point_id', '=', self.id), ('point_id', '=', self.id),
('create_date', '>=', date_previous.strftime(DEFAULT_SERVER_DATETIME_FORMAT))], limit=1) ('create_date', '>=', date_previous.strftime(DEFAULT_SERVER_DATETIME_FORMAT))], limit=1)
return not(bool(checks)) return not (bool(checks))
return super(QualityPoint, self).check_execute_now() return super(QualityPoint, self).check_execute_now()
def _get_type_default_domain(self): def _get_type_default_domain(self):
@@ -123,13 +124,31 @@ class QualityPoint(models.Model):
class QualityCheck(models.Model): class QualityCheck(models.Model):
_inherit = "quality.check" _inherit = "quality.check"
part_name = fields.Char('零件名称', compute='_compute_part_name_number', readonly=True) part_name = fields.Char('零件名称', compute='_compute_part_name_number', readonly=True)
part_number = fields.Char('零件图号', compute='_compute_part_name_number', readonly=True) part_number = fields.Char('零件图号', compute='_compute_part_name_number', readonly=True)
# 材料
material_name = fields.Char('材料名称', compute='_compute_material_name', readonly=True)
# # 总数量值未调拨单_产品明细_数量
# total_qty = fields.Float('总数量', compute='_compute_total_qty', readonly=True)
# # 检验数
# check_qty = fields.Float('检验数', compute='_compute_check_qty', readonly=True)
# # 出厂检验报告编号
# report_number = fields.Char('出厂检验报告编号', compute='_compute_report_number', readonly=True)
@depends('product_id') @depends('product_id')
def _compute_part_name_number(self): def _compute_part_name_number(self):
for record in self: for record in self:
record.part_number = record.product_id.part_number record.part_number = record.product_id.part_number
record.part_name = record.product_id.part_name record.part_name = record.product_id.part_name
@depends('product_id')
def _compute_material_name(self):
for record in self:
materials_id_name = record.product_id.materials_id.name if record.product_id.materials_id else ''
materials_type_name = record.product_id.materials_type_id.name if record.product_id.materials_type_id else ''
record.material_name = materials_id_name + ' ' + materials_type_name
failure_message = fields.Html(related='point_id.failure_message', readonly=True) failure_message = fields.Html(related='point_id.failure_message', readonly=True)
measure = fields.Float('Measure', default=0.0, digits='Quality Tests', tracking=True) measure = fields.Float('Measure', default=0.0, digits='Quality Tests', tracking=True)
measure_success = fields.Selection([ measure_success = fields.Selection([
@@ -141,7 +160,8 @@ class QualityCheck(models.Model):
tolerance_max = fields.Float('Max Tolerance', related='point_id.tolerance_max', readonly=True) tolerance_max = fields.Float('Max Tolerance', related='point_id.tolerance_max', readonly=True)
warning_message = fields.Text(compute='_compute_warning_message') warning_message = fields.Text(compute='_compute_warning_message')
norm_unit = fields.Char(related='point_id.norm_unit', readonly=True) norm_unit = fields.Char(related='point_id.norm_unit', readonly=True)
qty_to_test = fields.Float(compute="_compute_qty_to_test", string="Quantity to Test", help="Quantity of product to test within the lot") qty_to_test = fields.Float(compute="_compute_qty_to_test", string="Quantity to Test",
help="Quantity of product to test within the lot")
qty_tested = fields.Float(string="Quantity Tested", help="Quantity of product tested within the lot") qty_tested = fields.Float(string="Quantity Tested", help="Quantity of product tested within the lot")
measure_on = fields.Selection([ measure_on = fields.Selection([
('operation', 'Operation'), ('operation', 'Operation'),
@@ -150,7 +170,8 @@ class QualityCheck(models.Model):
help="""Operation = One quality check is requested at the operation level. help="""Operation = One quality check is requested at the operation level.
Product = A quality check is requested per product. Product = A quality check is requested per product.
Quantity = A quality check is requested for each new product quantity registered, with partial quantity checks also possible.""") Quantity = A quality check is requested for each new product quantity registered, with partial quantity checks also possible.""")
move_line_id = fields.Many2one('stock.move.line', 'Stock Move Line', check_company=True, help="In case of Quality Check by Quantity, Move Line on which the Quality Check applies") move_line_id = fields.Many2one('stock.move.line', 'Stock Move Line', check_company=True,
help="In case of Quality Check by Quantity, Move Line on which the Quality Check applies")
lot_name = fields.Char('Lot/Serial Number Name') lot_name = fields.Char('Lot/Serial Number Name')
lot_line_id = fields.Many2one('stock.lot', store=True, compute='_compute_lot_line_id') lot_line_id = fields.Many2one('stock.lot', store=True, compute='_compute_lot_line_id')
qty_line = fields.Float(compute='_compute_qty_line', string="Quantity") qty_line = fields.Float(compute='_compute_qty_line', string="Quantity")
@@ -231,7 +252,8 @@ class QualityCheck(models.Model):
def _compute_qty_to_test(self): def _compute_qty_to_test(self):
for qc in self: for qc in self:
if qc.is_lot_tested_fractionally: if qc.is_lot_tested_fractionally:
qc.qty_to_test = float_round(qc.qty_line * qc.testing_percentage_within_lot / 100, precision_rounding=self.product_id.uom_id.rounding, rounding_method="UP") qc.qty_to_test = float_round(qc.qty_line * qc.testing_percentage_within_lot / 100,
precision_rounding=self.product_id.uom_id.rounding, rounding_method="UP")
else: else:
qc.qty_to_test = qc.qty_line qc.qty_to_test = qc.qty_line
@@ -386,7 +408,8 @@ class QualityAlert(models.Model):
class ProductTemplate(models.Model): class ProductTemplate(models.Model):
_inherit = "product.template" _inherit = "product.template"
quality_control_point_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user') quality_control_point_qty = fields.Integer(compute='_compute_quality_check_qty',
groups='quality.group_quality_user')
quality_pass_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user') quality_pass_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user')
quality_fail_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user') quality_fail_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user')
@@ -394,14 +417,16 @@ class ProductTemplate(models.Model):
def _compute_quality_check_qty(self): def _compute_quality_check_qty(self):
for product_tmpl in self: for product_tmpl in self:
product_tmpl.quality_fail_qty, product_tmpl.quality_pass_qty = product_tmpl.product_variant_ids._count_quality_checks() product_tmpl.quality_fail_qty, product_tmpl.quality_pass_qty = product_tmpl.product_variant_ids._count_quality_checks()
product_tmpl.quality_control_point_qty = product_tmpl.with_context(active_test=product_tmpl.active).product_variant_ids._count_quality_points() product_tmpl.quality_control_point_qty = product_tmpl.with_context(
active_test=product_tmpl.active).product_variant_ids._count_quality_points()
def action_see_quality_control_points(self): def action_see_quality_control_points(self):
self.ensure_one() self.ensure_one()
action = self.env["ir.actions.actions"]._for_xml_id("quality_control.quality_point_action") action = self.env["ir.actions.actions"]._for_xml_id("quality_control.quality_point_action")
action['context'] = dict(self.env.context, default_product_ids=self.product_variant_ids.ids) action['context'] = dict(self.env.context, default_product_ids=self.product_variant_ids.ids)
domain_in_products_or_categs = ['|', ('product_ids', 'in', self.product_variant_ids.ids), ('product_category_ids', 'parent_of', self.categ_id.ids)] domain_in_products_or_categs = ['|', ('product_ids', 'in', self.product_variant_ids.ids),
('product_category_ids', 'parent_of', self.categ_id.ids)]
domain_no_products_and_categs = [('product_ids', '=', False), ('product_category_ids', '=', False)] domain_no_products_and_categs = [('product_ids', '=', False), ('product_category_ids', '=', False)]
action['domain'] = OR([domain_in_products_or_categs, domain_no_products_and_categs]) action['domain'] = OR([domain_in_products_or_categs, domain_no_products_and_categs])
return action return action
@@ -412,10 +437,10 @@ class ProductTemplate(models.Model):
action['context'] = dict(self.env.context, default_product_id=self.product_variant_id.id, create=False) action['context'] = dict(self.env.context, default_product_id=self.product_variant_id.id, create=False)
action['domain'] = [ action['domain'] = [
'|', '|',
('product_id', 'in', self.product_variant_ids.ids), ('product_id', 'in', self.product_variant_ids.ids),
'&', '&',
('measure_on', '=', 'operation'), ('measure_on', '=', 'operation'),
('picking_id.move_ids.product_tmpl_id', '=', self.id), ('picking_id.move_ids.product_tmpl_id', '=', self.id),
] ]
return action return action
@@ -423,7 +448,8 @@ class ProductTemplate(models.Model):
class ProductProduct(models.Model): class ProductProduct(models.Model):
_inherit = "product.product" _inherit = "product.product"
quality_control_point_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user') quality_control_point_qty = fields.Integer(compute='_compute_quality_check_qty',
groups='quality.group_quality_user')
quality_pass_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user') quality_pass_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user')
quality_fail_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user') quality_fail_qty = fields.Integer(compute='_compute_quality_check_qty', groups='quality.group_quality_user')
@@ -437,10 +463,10 @@ class ProductProduct(models.Model):
quality_pass_qty = 0 quality_pass_qty = 0
domain = [ domain = [
'|', '|',
('product_id', 'in', self.ids), ('product_id', 'in', self.ids),
'&', '&',
('measure_on', '=', 'operation'), ('measure_on', '=', 'operation'),
('picking_id.move_ids.product_id', 'in', self.ids), ('picking_id.move_ids.product_id', 'in', self.ids),
('company_id', '=', self.env.company.id), ('company_id', '=', self.env.company.id),
('quality_state', '!=', 'none') ('quality_state', '!=', 'none')
] ]
@@ -464,7 +490,8 @@ class ProductProduct(models.Model):
_, where_clause, where_clause_args = query.get_sql() _, where_clause, where_clause_args = query.get_sql()
additional_where_clause = self._additional_quality_point_where_clause() additional_where_clause = self._additional_quality_point_where_clause()
where_clause += additional_where_clause where_clause += additional_where_clause
parent_category_ids = [int(parent_id) for parent_id in self.categ_id.parent_path.split('/')[:-1]] if self.categ_id else [] parent_category_ids = [int(parent_id) for parent_id in
self.categ_id.parent_path.split('/')[:-1]] if self.categ_id else []
self.env.cr.execute(""" self.env.cr.execute("""
SELECT COUNT(*) SELECT COUNT(*)
@@ -485,7 +512,7 @@ class ProductProduct(models.Model):
) )
) )
""" % (where_clause,), where_clause_args + [self.ids, parent_category_ids] """ % (where_clause,), where_clause_args + [self.ids, parent_category_ids]
) )
return self.env.cr.fetchone()[0] return self.env.cr.fetchone()[0]
def action_see_quality_control_points(self): def action_see_quality_control_points(self):
@@ -493,7 +520,8 @@ class ProductProduct(models.Model):
action = self.product_tmpl_id.action_see_quality_control_points() action = self.product_tmpl_id.action_see_quality_control_points()
action['context'].update(default_product_ids=self.ids) action['context'].update(default_product_ids=self.ids)
domain_in_products_or_categs = ['|', ('product_ids', 'in', self.ids), ('product_category_ids', 'parent_of', self.categ_id.ids)] domain_in_products_or_categs = ['|', ('product_ids', 'in', self.ids),
('product_category_ids', 'parent_of', self.categ_id.ids)]
domain_no_products_and_categs = [('product_ids', '=', False), ('product_category_ids', '=', False)] domain_no_products_and_categs = [('product_ids', '=', False), ('product_category_ids', '=', False)]
action['domain'] = OR([domain_in_products_or_categs, domain_no_products_and_categs]) action['domain'] = OR([domain_in_products_or_categs, domain_no_products_and_categs])
return action return action
@@ -504,10 +532,10 @@ class ProductProduct(models.Model):
action['context'] = dict(self.env.context, default_product_id=self.id, create=False) action['context'] = dict(self.env.context, default_product_id=self.id, create=False)
action['domain'] = [ action['domain'] = [
'|', '|',
('product_id', '=', self.id), ('product_id', '=', self.id),
'&', '&',
('measure_on', '=', 'operation'), ('measure_on', '=', 'operation'),
('picking_id.move_ids.product_id', '=', self.id), ('picking_id.move_ids.product_id', '=', self.id),
] ]
return action return action

View File

@@ -268,6 +268,7 @@
<field name="measure_on" attrs="{'readonly': [('point_id', '!=', False)]}"/> <field name="measure_on" attrs="{'readonly': [('point_id', '!=', False)]}"/>
<field name="part_name"/> <field name="part_name"/>
<field name="part_number"/> <field name="part_number"/>
<field name="material_name"/>
<field name="show_lot_text" invisible="1"/> <field name="show_lot_text" invisible="1"/>
<field name="move_line_id" invisible="1"/> <field name="move_line_id" invisible="1"/>
<field name="product_tracking" invisible="1"/> <field name="product_tracking" invisible="1"/>

View File

@@ -16,6 +16,7 @@
'depends': ['quality_control', 'web_widget_model_viewer', 'sf_manufacturing','jikimo_attachment_viewer'], 'depends': ['quality_control', 'web_widget_model_viewer', 'sf_manufacturing','jikimo_attachment_viewer'],
'data': [ 'data': [
'security/ir.model.access.csv', 'security/ir.model.access.csv',
'data/check_standards.xml',
'views/view.xml', 'views/view.xml',
'views/quality_cnc_test_view.xml', 'views/quality_cnc_test_view.xml',
'views/mrp_workorder.xml', 'views/mrp_workorder.xml',

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="quality_point_out_check_report" model="quality.point">
<field name="title">出厂检验报告</field>
<field name="picking_type_ids" eval="[(4, ref('stock.picking_type_out'))]"/> <!-- 作业类型:发料出库 -->
<field name="measure_on">product</field> <!-- 控制方式:产品 -->
<field name="measure_frequency_type">all</field> <!-- 控制频率:全部 -->
</record>
</data>
</odoo>

View File

@@ -4,6 +4,7 @@ from odoo import models, fields
class SfQualityPoint(models.Model): class SfQualityPoint(models.Model):
_inherit = 'quality.point' _inherit = 'quality.point'
_rec_name = 'title'
product_ids = fields.Many2many( product_ids = fields.Many2many(
'product.product', string='适用产品', 'product.product', string='适用产品',