优化质量:添加加工质检

This commit is contained in:
jinling.yang
2024-10-11 17:52:33 +08:00
parent 351815ad91
commit d8bade64e1
12 changed files with 287 additions and 86 deletions

View File

@@ -595,14 +595,6 @@ class Manufacturing_Connect(http.Controller):
if panel_workorder:
panel_workorder.write({'production_line_state': '已下产线'})
workorder.write({'state': 'to be detected'})
# workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(
# [
# ('rfid_code', '=', rfid_code), ('type', '=', '下产线'),
# ('production_id', '=', order.production_id.id),
# ('workorder_id', '=', order.id),
# ('workorder_state', '=', 'done')])
# if workpiece_delivery:
# delivery_Arr.append(workpiece_delivery.id)
else:
res = {'Succeed': False, 'ErrorCode': 204,
'Error': 'DeviceId为%s没有对应的已配送工件数据' % ret['DeviceId']}
@@ -623,13 +615,14 @@ class Manufacturing_Connect(http.Controller):
if ret['IsComplete'] is True:
# 向AGV任务调度下发下产线任务
workorders = request.env['mrp.workorder'].browse(workorder_ids)
res['workorder_ids'] = workorder_ids
request.env['sf.agv.scheduling'].add_scheduling(ret['DeviceId'], '下产线', workorders)
else:
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '未传IsComplete字段'}
except RepeatTaskException as e:
logging.info('AGVToProduct error:%s' % e)
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': str(e)}
res = {'Succeed': False, 'ErrorCode': 202, 'Error': str(e), 'workorder_ids': workorder_ids}
logging.info('AGVDownProduct error:%s' % e)
return json.JSONEncoder().encode(res)
@@ -695,4 +688,4 @@ class Manufacturing_Connect(http.Controller):
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': str(e)}
logging.info('AGVDownProduct error:%s' % e)
return json.JSONEncoder().encode(res)
return json.JSONEncoder().encode(res)

View File

@@ -229,7 +229,7 @@
decoration-danger="tag_type == '重新加工'"/>
<field name="rfid_code" force_save="1" readonly="1" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
<field name="rfid_code_old" readonly="0" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
</xpath>
<xpath expr="//label[1]" position="attributes">
@@ -265,7 +265,7 @@
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割","装夹预调"))]}'/>
<field name="production_line_id"
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割"))]}'/>
<field name="production_line_state" readonly="1"
<field name="production_line_state" readonly="0"
attrs='{"invisible": [("routing_type","in",("获取CNC加工程序","切割","装夹预调"))]}'/>
<!-- <field name="functional_fixture_id" -->
<!-- attrs='{"invisible": [("routing_type","!=","装夹预调")]}'/> -->

View File

@@ -113,7 +113,7 @@
</record>
<record id="template_mrp_workorder_cnc_overdue_warning" model="jikimo.message.template">
<field name="name">CNC工单逾期预警</field>
<field name="name">CNC加工工单逾期预警</field>
<field name="model_id" ref="mrp_workorder.model_mrp_workorder"/>
<field name="model">mrp.workorder</field>
<field name="bussiness_node_id" ref="bussiness_mrp_workorder_cnc_overdue_warning"/>
@@ -125,7 +125,7 @@
</record>
<record id="template_mrp_workorder_cnc_overdue" model="jikimo.message.template">
<field name="name">CNC工单已逾期</field>
<field name="name">CNC加工工单已逾期</field>
<field name="model_id" ref="mrp_workorder.model_mrp_workorder"/>
<field name="model">mrp.workorder</field>
<field name="bussiness_node_id" ref="bussiness_mrp_workorder_cnc_overdue"/>
@@ -186,46 +186,46 @@
<record id="template_transfer_inventory_remind" model="jikimo.message.template">
<field name="menu_id" ref="stock.menu_stock_root"/>
<field name="action_id" ref="stock.action_picking_tree_ready"/>
<field name="name">调拨入库</field>
<field name="model_id" ref="stock.model_stock_picking"/>
<field name="model">stock.picking</field>
<field name="bussiness_node_id" ref="transfer_inventory"/>
<field name="msgtype">markdown</field>
<field name="urgency">normal</field>
<field name="content">### 调拨入库通知:
单号:调拨入库单[{{name}}]({{request_url}})
事项:完成刀具物料上架入库</field>
</record>
<!-- <record id="template_transfer_inventory_remind" model="jikimo.message.template">-->
<!-- <field name="menu_id" ref="stock.menu_stock_root"/>-->
<!-- <field name="action_id" ref="stock.action_picking_tree_ready"/>-->
<!-- <field name="name">调拨入库</field>-->
<!-- <field name="model_id" ref="stock.model_stock_picking"/>-->
<!-- <field name="model">stock.picking</field>-->
<!-- <field name="bussiness_node_id" ref="transfer_inventory"/>-->
<!-- <field name="msgtype">markdown</field>-->
<!-- <field name="urgency">normal</field>-->
<!-- <field name="content">### 调拨入库通知:-->
<!--单号:调拨入库单[{{name}}]({{request_url}})-->
<!--事项:完成刀具物料上架入库</field>-->
<!-- </record>-->
<record id="template_tool_expired_remind" model="jikimo.message.template">
<field name="menu_id" ref="mrp.menu_mrp_root"/>
<field name="action_id" ref="sf_tool_management.sf_functional_tool_dismantle_view_act"/>
<field name="name">功能刀具寿命到期</field>
<field name="model_id" ref="sf_tool_management.model_sf_functional_tool_dismantle"/>
<field name="model">sf.functional.tool.dismantle</field>
<field name="bussiness_node_id" ref="tool_dismantle"/>
<field name="msgtype">markdown</field>
<field name="urgency">normal</field>
<field name="content">### 功能刀具寿命到期提醒:
单号:拆解单[{{code}}]({{request_url}})
事项:{{functional_tool_id.tool_name_id.name}}寿命已到期,需拆解</field>
</record>
<!-- <record id="template_tool_expired_remind" model="jikimo.message.template">-->
<!-- <field name="menu_id" ref="mrp.menu_mrp_root"/>-->
<!-- <field name="action_id" ref="sf_tool_management.sf_functional_tool_dismantle_view_act"/>-->
<!-- <field name="name">功能刀具寿命到期</field>-->
<!-- <field name="model_id" ref="sf_tool_management.model_sf_functional_tool_dismantle"/>-->
<!-- <field name="model">sf.functional.tool.dismantle</field>-->
<!-- <field name="bussiness_node_id" ref="tool_dismantle"/>-->
<!-- <field name="msgtype">markdown</field>-->
<!-- <field name="urgency">normal</field>-->
<!-- <field name="content">### 功能刀具寿命到期提醒:-->
<!--单号:拆解单[{{code}}]({{request_url}})-->
<!--事项:{{functional_tool_id.tool_name_id.name}}寿命已到期,需拆解</field>-->
<!-- </record>-->
<record id="template_tool_assembly_remind" model="jikimo.message.template">
<field name="menu_id" ref="mrp.menu_mrp_root"/>
<field name="action_id" ref="sf_tool_management.sf_functional_tool_assembly_view_act"/>
<field name="name">功能刀具组装</field>
<field name="model_id" ref="sf_tool_management.model_sf_functional_tool_assembly"/>
<field name="model">sf.functional.tool.assembly</field>
<field name="bussiness_node_id" ref="tool_assembly"/>
<field name="msgtype">markdown</field>
<field name="urgency">normal</field>
<field name="content">### 功能刀具组装通知:
单号:组装任务单[{{name}}]({{request_url}})
事项:{{use_tool_time}}前完成组装</field>
</record>
<!-- <record id="template_tool_assembly_remind" model="jikimo.message.template">-->
<!-- <field name="menu_id" ref="mrp.menu_mrp_root"/>-->
<!-- <field name="action_id" ref="sf_tool_management.sf_functional_tool_assembly_view_act"/>-->
<!-- <field name="name">功能刀具组装</field>-->
<!-- <field name="model_id" ref="sf_tool_management.model_sf_functional_tool_assembly"/>-->
<!-- <field name="model">sf.functional.tool.assembly</field>-->
<!-- <field name="bussiness_node_id" ref="tool_assembly"/>-->
<!-- <field name="msgtype">markdown</field>-->
<!-- <field name="urgency">normal</field>-->
<!-- <field name="content">### 功能刀具组装通知:-->
<!--单号:组装任务单[{{name}}]({{request_url}})-->
<!--事项:{{use_tool_time}}前完成组装</field>-->
<!-- </record>-->
</data>
</odoo>

View File

@@ -2,3 +2,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
from . import controller

View File

@@ -13,10 +13,11 @@
'author': 'jikimo',
'website': 'https://sf.cs.jikimo.com',
# 此处依赖sf_manufacturing是因为我要重写其中的一个字段operation_id的string故需要sf_manufacturing先安装
'depends': ['quality_control'],
'depends': ['quality_control', 'web_widget_model_viewer', 'sf_manufacturing'],
'data': [
'security/ir.model.access.csv',
'views/view.xml'
'views/view.xml',
'views/quality_cnc_test_view.xml'
],
'assets': {

View File

@@ -0,0 +1 @@
from . import workorder

View File

@@ -0,0 +1,28 @@
# -*- coding: utf-8 -*-
import json
import requests
import logging
from odoo import http
from odoo.http import request
from odoo.addons.sf_manufacturing.controllers.controllers import Manufacturing_Connect
from odoo.addons.sf_base.commons.common import Common
_logger = logging.getLogger(__name__)
class SfQualityConnect(Manufacturing_Connect):
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
cors="*")
def AGVDownProduct(self, **kw):
res = super(SfQualityConnect, self).AGVDownProduct(**kw)
res = json.loads(res)
if res.get('workorder_ids'):
try:
_logger.info('已下产线的工单:%s' % res.get('workorder_ids'))
for order_id in res['workorder_ids']:
request.env['quality.cnc.test'].sudo().create(
{'workorder_id': order_id, 'write_uid': False, 'write_date': False})
except Exception as e:
_logger.info('AGV运送下产线接口:%s' % e)
return json.JSONEncoder().encode(res)

View File

@@ -3,3 +3,4 @@
from . import custom_quality
from . import quality
from . import quality_cnc_test

View File

@@ -0,0 +1,47 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api, _
from odoo.exceptions import UserError
class SfQualityCncTest(models.Model):
_name = 'quality.cnc.test'
_description = 'CNC加工质检'
name = fields.Char('单号', default=lambda self: self.env['ir.sequence'].next_by_code('quality.cnc.test'))
workorder_id = fields.Many2one('mrp.workorder')
production_id = fields.Many2one(related='workorder_id.production_id', string='制造订单')
product_id = fields.Many2one(related='workorder_id.product_id', string='产品')
model_file = fields.Binary(related='workorder_id.glb_file', string='加工模型')
processing_panel = fields.Char(related='workorder_id.processing_panel', string='加工面')
equipment_id = fields.Many2one(related='workorder_id.equipment_id', string='加工设备')
production_line_id = fields.Many2one(related='workorder_id.production_line_id',
string='生产线')
part_number = fields.Char(related='workorder_id.part_number', string='成品零件图号')
detection_report = fields.Binary(related='workorder_id.detection_report', readonly=True, string='检测报告')
state = fields.Selection([
('waiting', '待判定'),
('done', '已完成')], string='状态', default='waiting')
result = fields.Selection([
('pass', '合格'),
('fail', '不合格')], string='判定结果')
number = fields.Integer('数量', default=1)
test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格',
string="检测结果")
reason = fields.Selection(
[("programming", "编程"), ("cutter", "刀具"), ("clamping", "装夹"), ("operate computer", "操机"),
("technology", "工艺"), ("customer redrawing", "客户改图")], string="原因")
detailed_reason = fields.Text('详细原因')
def submit_pass(self):
self.write({'result': 'pass', 'test_results': '合格', 'state': 'done'})
self.workorder_id.write({'test_results': self.test_results})
self.workorder_id.button_finish()
def submit_fail(self):
if not self.reason and not self.detailed_reason:
raise UserError(_('请填写【检测情况】里的信息'))
else:
self.write({'result': 'fail', 'test_results': '合格', 'state': 'done'})
self.workorder_id.write(
{'test_results': self.test_results, 'reason': self.reason, 'detailed_reason': self.detailed_reason})
self.workorder_id.button_finish()

View File

@@ -67,5 +67,8 @@ access_quality_alert_stage,quality.alert.stage,quality.model_quality_alert_stage
access_stock_move_group_quality,stock_move_group_quality,stock.model_stock_move,sf_base.group_quality,1,1,0,0
access_stock_move_group_quality_director,stock_move_group_quality_director,stock.model_stock_move,sf_base.group_quality_director,1,1,0,0
access_quality_cnc_test_group_quality,quality_cnc_test_group_quality,model_quality_cnc_test,sf_base.group_quality,1,1,0,0
access_quality_cnc_test_group_quality_director,quality_cnc_test_group_quality_director,model_quality_cnc_test,sf_base.group_quality_director,1,1,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
67
68
69
70
71
72
73
74

View File

@@ -0,0 +1,126 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="sequence_quality_cnc_test" model="ir.sequence">
<field name="name">加工质检单编码规则</field>
<field name="code">quality.cnc.test</field>
<field name="prefix">QCT</field>
<field name="padding">4</field>
<field name="company_id" eval="False"/>
</record>
<record id="quality_cnc_test_view_tree" model="ir.ui.view">
<field name="name">quality.cnc.test.view.tree</field>
<field name="model">quality.cnc.test</field>
<field name="arch" type="xml">
<tree sample="1">
<field name="name"/>
<field name="production_id"/>
<field name="processing_panel"/>
<field name="product_id"/>
<field name="part_number"/>
<field name="number"/>
<field name="state"/>
<field name="result"/>
<field name="write_uid" widget='many2one_avatar_user' string="判定人"/>
<field name="write_date" string="判定时间"/>
</tree>
</field>
</record>
<record model="ir.ui.view" id="quality_cnc_test_search">
<field name="name">search.quality.cnc.test</field>
<field name="model">quality.cnc.test</field>
<field name="arch" type="xml">
<search string="加工质检">
<filter name="filter_waiting" string="待判定" domain="[('state', '=', 'waiting')]"/>
<separator/>
<field name="production_id" string="制造订单"
filter_domain="[('production_id', 'ilike', self)]"/>
<field name="product_id" string="产品"
filter_domain="[('product_id', 'ilike', self)]"/>
<searchpanel class="account_root">
<field name="state" icon="fa-filter" enable_counters="1"/>
<field name="result" icon="fa-filter" enable_counters="1"/>
</searchpanel>
</search>
</field>
</record>
<record id="action_quality_cnc_test" model="ir.actions.act_window">
<field name="name">加工质检</field>
<field name="res_model">quality.cnc.test</field>
<field name="view_mode">tree,form</field>
<field name="context">{ 'search_default_filter_waiting':1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
请先创建一个加工质检单
</p>
</field>
</record>
<record model="ir.ui.view" id="quality_cnc_test_view_form">
<field name="name">quality.cnc.test.form.</field>
<field name="model">quality.cnc.test</field>
<field name="arch" type="xml">
<form>
<header>
<button string="合格" type="object" name="submit_pass"
class="oe_highlight" confirm="是否确认提交?"
attrs="{'invisible': [('result','!=', False)]}"/>
<button string="不合格" type="object" name="submit_fail"
class="oe_highlight" confirm="是否确认提交?"
attrs="{'invisible': [('result','!=', False)]}"/>
<field name="state" widget="statusbar"/>
<field name="result" invisible="1"/>
</header>
<sheet>
<h2>
<field name="name" readonly="1"/>
</h2>
<group>
<group>
<field name="production_id"/>
<field name="product_id"/>
<field name="production_line_id"/>
<field name="equipment_id"/>
<field name="model_file" widget="Viewer3D"/>
</group>
<group>
<field name="part_number"/>
<field name="processing_panel"/>
<field name="detection_report"/>
</group>
</group>
<notebook>
<page string="检测报告">
<field name="detection_report" string="" widget="pdf_viewer"/>
</page>
<page string="检测情况">
<group>
<field name="test_results"/>
<field name="reason"/>
<field name="detailed_reason"/>
</group>
</page>
<page string="其他">
<group>
<field name="write_uid" widget='many2one_avatar_user' string="判定人" readonly="1"/>
<field name="write_date" string="判定时间" readonly="1"/>
</group>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<menuitem
id="menu_quality_cnc_test"
name="加工质检"
action="action_quality_cnc_test"
sequence="21"
parent="quality_control.menu_quality_control"
/>
</odoo>

View File

@@ -34,36 +34,36 @@
</field>
</record>
<record model="ir.ui.view" id="quality_point_view_form_inherit_sf">
<field name="name">quality.point.form.inherit.sf</field>
<field name="model">quality.point</field>
<field name="inherit_id" ref="quality.quality_point_view_form"/>
<field name="arch" type="xml">
<!-- <xpath expr="//sheet//group//group//field[@name='title']" position="replace"> -->
<!-- <field name="title" class="custom_required" required="1"/> -->
<!-- </xpath> -->
<xpath expr="//sheet//group//group//field[@name='title']" position="attributes">
<attribute name="class">custom_required</attribute>
<attribute name="required">1</attribute>
</xpath>
<xpath expr="//sheet//group//group//field[@name='picking_type_ids']" position="attributes">
<attribute name="class">custom_required</attribute>
<attribute name="required">1</attribute>
</xpath>
</field>
</record>
<!-- <record model="ir.ui.view" id="quality_point_view_form_inherit_sf">-->
<!-- <field name="name">quality.point.form.inherit.sf</field>-->
<!-- <field name="model">quality.point</field>-->
<!-- <field name="inherit_id" ref="quality.quality_point_view_form"/>-->
<!-- <field name="arch" type="xml">-->
<!--&lt;!&ndash; <xpath expr="//sheet//group//group//field[@name='title']" position="replace"> &ndash;&gt;-->
<!--&lt;!&ndash; <field name="title" class="custom_required" required="1"/> &ndash;&gt;-->
<!--&lt;!&ndash; </xpath> &ndash;&gt;-->
<!-- <xpath expr="//sheet//group//group//field[@name='title']" position="attributes">-->
<!-- <attribute name="class">custom_required</attribute>-->
<!-- <attribute name="required">1</attribute>-->
<!-- </xpath>-->
<!-- <xpath expr="//sheet//group//group//field[@name='picking_type_ids']" position="attributes">-->
<!-- <attribute name="class">custom_required</attribute>-->
<!-- <attribute name="required">1</attribute>-->
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<record model="ir.ui.view" id="sf_quality_point_view_form_inherit_quality_control">
<field name="name">sf.quality.point.form.inherit.sf</field>
<field name="model">quality.point</field>
<field name="inherit_id" ref="quality_control.quality_point_view_form_inherit_quality_control"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='measure_on']" position="attributes">
<attribute name="class">custom_required</attribute>
</xpath>
<xpath expr="//field[@name='measure_frequency_type']" position="attributes">
<attribute name="class">custom_required</attribute>
</xpath>
</field>
</record>
<!-- <record model="ir.ui.view" id="sf_quality_point_view_form_inherit_quality_control">-->
<!-- <field name="name">sf.quality.point.form.inherit.sf</field>-->
<!-- <field name="model">quality.point</field>-->
<!-- <field name="inherit_id" ref="quality_control.quality_point_view_form_inherit_quality_control"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//field[@name='measure_on']" position="attributes">-->
<!-- <attribute name="class">custom_required</attribute>-->
<!-- </xpath>-->
<!-- <xpath expr="//field[@name='measure_frequency_type']" position="attributes">-->
<!-- <attribute name="class">custom_required</attribute>-->
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
</odoo>