工单异常处理
This commit is contained in:
@@ -9,7 +9,6 @@
|
|||||||
'website': 'https://www.sf.jikimo.com',
|
'website': 'https://www.sf.jikimo.com',
|
||||||
'depends': ['sf_manufacturing', 'sf_mrs_connect'],
|
'depends': ['sf_manufacturing', 'sf_mrs_connect'],
|
||||||
'data': [
|
'data': [
|
||||||
# 'views/jikimo_workorder_exception_views.xml',
|
|
||||||
'views/mrp_workorder_views.xml',
|
'views/mrp_workorder_views.xml',
|
||||||
'security/ir.model.access.csv',
|
'security/ir.model.access.csv',
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -63,15 +63,8 @@ class SfMrsConnectController(Sf_Mrs_Connect):
|
|||||||
if res.get('production_ids'):
|
if res.get('production_ids'):
|
||||||
try:
|
try:
|
||||||
productions = request.env['mrp.production'].sudo().search([('id', 'in', res.get('production_ids'))])
|
productions = request.env['mrp.production'].sudo().search([('id', 'in', res.get('production_ids'))])
|
||||||
if productions.workorder_ids.exception_ids:
|
if productions.workorder_ids:
|
||||||
pending_exception = productions.workorder_ids.exception_ids.filtered(
|
productions.workorder_ids.handle_exception(['YC0001', 'YC0004'])
|
||||||
lambda exc: exc.state == 'pending' and exc.exception_code in ['YC0001', 'YC0004']
|
|
||||||
)
|
|
||||||
if pending_exception:
|
|
||||||
pending_exception.write({
|
|
||||||
'completion_time': fields.Datetime.now(),
|
|
||||||
'state': 'done'
|
|
||||||
})
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.info('更新工单异常记录失败:%s' % e)
|
_logger.info('更新工单异常记录失败:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
@@ -90,17 +83,7 @@ class ManufactruingController(Manufacturing_Connect):
|
|||||||
if res.get('workorder_id'):
|
if res.get('workorder_id'):
|
||||||
try:
|
try:
|
||||||
workorder = request.env['mrp.workorder'].sudo().browse(int(res.get('workorder_id')))
|
workorder = request.env['mrp.workorder'].sudo().browse(int(res.get('workorder_id')))
|
||||||
if workorder.exception_ids:
|
workorder.handle_exception(['YC0002', 'YC0003'])
|
||||||
_logger.info('workorder.exception_ids:%s' % workorder.exception_ids)
|
|
||||||
pending_exception = workorder.exception_ids.filtered(
|
|
||||||
lambda exc: exc.state == 'pending' and exc.exception_code in ['YC0002', 'YC0003']
|
|
||||||
)
|
|
||||||
_logger.info('pending_exception:%s' % pending_exception)
|
|
||||||
if pending_exception:
|
|
||||||
pending_exception.write({
|
|
||||||
'completion_time': fields.Datetime.now(),
|
|
||||||
'state': 'done'
|
|
||||||
})
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
_logger.info('更新工单异常记录失败:%s' % e)
|
_logger.info('更新工单异常记录失败:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
@@ -1,4 +1,7 @@
|
|||||||
from odoo import models, fields
|
from odoo import models, fields
|
||||||
|
import logging
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class MrpWorkorder(models.Model):
|
class MrpWorkorder(models.Model):
|
||||||
_inherit = 'mrp.workorder'
|
_inherit = 'mrp.workorder'
|
||||||
@@ -16,3 +19,22 @@ class MrpWorkorder(models.Model):
|
|||||||
'state': 'done'
|
'state': 'done'
|
||||||
})
|
})
|
||||||
return super(MrpWorkorder, self).write(values)
|
return super(MrpWorkorder, self).write(values)
|
||||||
|
|
||||||
|
def handle_exception(self, exception_codes):
|
||||||
|
"""
|
||||||
|
处理异常
|
||||||
|
:param exception_codes: 需要处理的异常编码列表
|
||||||
|
"""
|
||||||
|
if not isinstance(exception_codes, list):
|
||||||
|
exception_codes = [exception_codes]
|
||||||
|
if self.exception_ids:
|
||||||
|
_logger.info('workorder.exception_ids:%s' % self.exception_ids)
|
||||||
|
pending_exception = self.exception_ids.filtered(
|
||||||
|
lambda exc: exc.state == 'pending' and exc.exception_code in exception_codes
|
||||||
|
)
|
||||||
|
_logger.info('pending_exception:%s' % pending_exception)
|
||||||
|
if pending_exception:
|
||||||
|
pending_exception.write({
|
||||||
|
'completion_time': fields.Datetime.now(),
|
||||||
|
'state': 'done'
|
||||||
|
})
|
||||||
|
|||||||
2
jikimo_workorder_exception/tests/__init__.py
Normal file
2
jikimo_workorder_exception/tests/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from . import common
|
||||||
|
from . import test_jikimo_workorder_exception
|
||||||
48
jikimo_workorder_exception/tests/common.py
Normal file
48
jikimo_workorder_exception/tests/common.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
from odoo import fields, Command
|
||||||
|
from odoo.tests.common import TransactionCase, HttpCase, tagged, Form
|
||||||
|
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import base64
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
@tagged('post_install', '-at_install')
|
||||||
|
class TestJikimoWorkorderExceptionCommon(TransactionCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestJikimoWorkorderExceptionCommon, self).setUp()
|
||||||
|
# 获取名字为“1#自动生产线”的制造中心
|
||||||
|
workcenter = self.env['mrp.workcenter'].search([('name', '=', '1#自动生产线')], limit=1)
|
||||||
|
# 创建一个产品
|
||||||
|
product_product = self.env['product.product'].create({
|
||||||
|
'name': '测试产品',
|
||||||
|
'type': 'product',
|
||||||
|
})
|
||||||
|
uom_unit = self.env.ref('uom.product_uom_unit')
|
||||||
|
# 创建一个bom
|
||||||
|
self.bom = self.env['mrp.bom'].create({
|
||||||
|
'product_id': product_product.id,
|
||||||
|
'product_tmpl_id': product_product.product_tmpl_id.id,
|
||||||
|
'product_uom_id': uom_unit.id,
|
||||||
|
'product_qty': 1.0,
|
||||||
|
'type': 'normal',
|
||||||
|
})
|
||||||
|
# 创建一个制造订单
|
||||||
|
self.production = self.env['mrp.production'].create({
|
||||||
|
'name': 'Test Production',
|
||||||
|
'product_id': product_product.id,
|
||||||
|
'bom_id': self.bom.id,
|
||||||
|
'company_id': self.env.ref('base.main_company').id,
|
||||||
|
})
|
||||||
|
# 创建一个测试工单
|
||||||
|
self.workorder = self.env['mrp.workorder'].create({
|
||||||
|
'name': 'Test order',
|
||||||
|
'workcenter_id': workcenter.id,
|
||||||
|
'product_uom_id': self.bom.product_uom_id.id,
|
||||||
|
'production_id': self.production.id,
|
||||||
|
'duration_expected': 1.0,
|
||||||
|
'rfid_code': 'test-123456',
|
||||||
|
'routing_type': 'CNC加工'
|
||||||
|
})
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from odoo.addons.jikimo_workorder_exception.tests.common import TestJikimoWorkorderExceptionCommon
|
||||||
|
|
||||||
|
class TestJikimoWorkorderException(TestJikimoWorkorderExceptionCommon):
|
||||||
|
|
||||||
|
def test_create_exception_record(self):
|
||||||
|
exception_record = self.env['jikimo.workorder.exception'].create({
|
||||||
|
'workorder_id': self.workorder.id,
|
||||||
|
'exception_code': 'YC0001',
|
||||||
|
'exception_content': '无CNC编程'
|
||||||
|
})
|
||||||
|
|
||||||
|
self.assertTrue(exception_record)
|
||||||
|
self.assertEqual(exception_record.exception_content, '无CNC编程')
|
||||||
|
self.assertEqual(exception_record.workorder_id.id, self.workorder.id)
|
||||||
|
self.assertEqual(exception_record.exception_code, 'YC0001')
|
||||||
|
|
||||||
|
def test_handle_exception(self):
|
||||||
|
exception_record = self.env['jikimo.workorder.exception'].create({
|
||||||
|
'workorder_id': self.workorder.id,
|
||||||
|
'exception_code': 'YC0001',
|
||||||
|
'exception_content': '无CNC编程'
|
||||||
|
})
|
||||||
|
self.workorder.handle_exception('YC0001')
|
||||||
|
self.assertEqual(exception_record.state, 'done')
|
||||||
|
# 判断完成时间是否为当前分钟
|
||||||
|
self.assertEqual(exception_record.completion_time.minute, datetime.now().minute)
|
||||||
|
|
||||||
|
def test_handle_exception_with_invalid_code(self):
|
||||||
|
exception_record = self.env['jikimo.workorder.exception'].create({
|
||||||
|
'workorder_id': self.workorder.id,
|
||||||
|
'exception_code': 'YC0001',
|
||||||
|
'exception_content': '无CNC编程'
|
||||||
|
})
|
||||||
|
self.workorder.handle_exception(['YC0002', 'YC0004'])
|
||||||
|
self.assertEqual(exception_record.state, 'pending')
|
||||||
|
self.assertEqual(exception_record.completion_time, False)
|
||||||
|
|
||||||
|
|
||||||
|
def test_handle_exception_with_test_results(self):
|
||||||
|
exception_record = self.env['jikimo.workorder.exception'].create({
|
||||||
|
'workorder_id': self.workorder.id,
|
||||||
|
'exception_code': 'YC0005',
|
||||||
|
'exception_content': '工单加工失败'
|
||||||
|
})
|
||||||
|
self.workorder.write({
|
||||||
|
'test_results': '返工',
|
||||||
|
'reason': 'cutter',
|
||||||
|
'detailed_reason': '刀坏了',
|
||||||
|
})
|
||||||
|
self.assertEqual(exception_record.state, 'done')
|
||||||
|
self.assertEqual(exception_record.completion_time.minute, datetime.now().minute)
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8" ?>
|
|
||||||
<odoo>
|
|
||||||
<data>
|
|
||||||
<record id="jikimo_workorder_exception_list_view" model="ir.ui.view">
|
|
||||||
<field name="name">jikimo.workorder.exception.tree</field>
|
|
||||||
<field name="model">jikimo.workorder.exception</field>
|
|
||||||
<field name="arch" type="xml">
|
|
||||||
|
|
||||||
</field>
|
|
||||||
</record>
|
|
||||||
</data>
|
|
||||||
</odoo>
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
<field name="inherit_id" ref="mrp.mrp_production_workorder_form_view_inherit"/>
|
<field name="inherit_id" ref="mrp.mrp_production_workorder_form_view_inherit"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<xpath expr="//notebook/page[last()]" position="after">
|
<xpath expr="//notebook/page[last()]" position="after">
|
||||||
<page string="异常记录" name="workorder_exception">
|
<page string="异常记录" name="workorder_exception" attrs="{'invisible': [('routing_type', '!=', 'CNC加工')]}">
|
||||||
<field name="exception_ids" nolabel="1" readonly="1">
|
<field name="exception_ids" nolabel="1" readonly="1">
|
||||||
<tree create="false" delete="false" edit="false">
|
<tree create="false" delete="false" edit="false">
|
||||||
<field name="exception_content" string="反馈的异常/问题信息"/>
|
<field name="exception_content" string="反馈的异常/问题信息"/>
|
||||||
|
|||||||
4
jikimo_workorder_exception_notify/__init__.py
Normal file
4
jikimo_workorder_exception_notify/__init__.py
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from . import models
|
||||||
|
|
||||||
22
jikimo_workorder_exception_notify/__manifest__.py
Normal file
22
jikimo_workorder_exception_notify/__manifest__.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
{
|
||||||
|
'name': '机企猫 工单异常消息通知',
|
||||||
|
'version': '1.0',
|
||||||
|
'summary': '当产生工单异常时,发送消息通知',
|
||||||
|
'sequence': 1,
|
||||||
|
'category': 'sf',
|
||||||
|
'website': 'https://www.sf.jikimo.com',
|
||||||
|
'depends': ['jikimo_workorder_exception', 'jikimo_message_notify'],
|
||||||
|
'data': [
|
||||||
|
'data/bussiness_node.xml',
|
||||||
|
'data/template_data.xml',
|
||||||
|
# 'security/ir.model.access.csv',
|
||||||
|
],
|
||||||
|
'demo': [
|
||||||
|
],
|
||||||
|
'license': 'LGPL-3',
|
||||||
|
'installable': True,
|
||||||
|
'application': False,
|
||||||
|
'auto_install': False,
|
||||||
|
}
|
||||||
17
jikimo_workorder_exception_notify/data/bussiness_node.xml
Normal file
17
jikimo_workorder_exception_notify/data/bussiness_node.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="bussiness_no_functional_tool" model="jikimo.message.bussiness.node">
|
||||||
|
<field name="name">无功能刀具</field>
|
||||||
|
<field name="model">jikimo.workorder.exception</field>
|
||||||
|
</record>
|
||||||
|
<record id="bussiness_no_position_data" model="jikimo.message.bussiness.node">
|
||||||
|
<field name="name">无定位数据</field>
|
||||||
|
<field name="model">jikimo.workorder.exception</field>
|
||||||
|
</record>
|
||||||
|
<record id="bussiness_processing_failure" model="jikimo.message.bussiness.node">
|
||||||
|
<field name="name">加工失败</field>
|
||||||
|
<field name="model">jikimo.workorder.exception</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
38
jikimo_workorder_exception_notify/data/template_data.xml
Normal file
38
jikimo_workorder_exception_notify/data/template_data.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" ?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<record id="template_no_function_tool" model="jikimo.message.template">
|
||||||
|
<field name="name">生产线无功能刀具提醒</field>
|
||||||
|
<field name="model_id" ref="jikimo_workorder_exception_notify.model_jikimo_workorder_exception"/>
|
||||||
|
<field name="model">jikimo.workorder.exception</field>
|
||||||
|
<field name="bussiness_node_id" ref="bussiness_no_functional_tool"/>
|
||||||
|
<field name="msgtype">markdown</field>
|
||||||
|
<field name="urgency">urgent</field>
|
||||||
|
<field name="content">### 生产线无功能刀具提醒
|
||||||
|
单号:工单[{{workorder_id.production_id.name}}]({{url}})
|
||||||
|
原因:生产线无加工程序用的{{function_tool_name}}名称功能刀具</field>
|
||||||
|
</record>
|
||||||
|
<record id="template_no_position_data" model="jikimo.message.template">
|
||||||
|
<field name="name">工单无定位数据提醒</field>
|
||||||
|
<field name="model_id" ref="jikimo_workorder_exception_notify.model_jikimo_workorder_exception"/>
|
||||||
|
<field name="model">jikimo.workorder.exception</field>
|
||||||
|
<field name="bussiness_node_id" ref="bussiness_no_position_data"/>
|
||||||
|
<field name="msgtype">markdown</field>
|
||||||
|
<field name="urgency">urgent</field>
|
||||||
|
<field name="content">### 生产线无功能刀具提醒
|
||||||
|
单号:工单[{{workorder_id.production_id.name}}]({{url}})
|
||||||
|
原因:无装夹定位测量数据</field>
|
||||||
|
</record>
|
||||||
|
<record id="template_processing_failure" model="jikimo.message.template">
|
||||||
|
<field name="name">工单加工失败提醒</field>
|
||||||
|
<field name="model_id" ref="jikimo_workorder_exception_notify.model_jikimo_workorder_exception"/>
|
||||||
|
<field name="model">jikimo.workorder.exception</field>
|
||||||
|
<field name="bussiness_node_id" ref="bussiness_processing_failure"/>
|
||||||
|
<field name="msgtype">markdown</field>
|
||||||
|
<field name="urgency">urgent</field>
|
||||||
|
<field name="content">### 工单加工失败提醒
|
||||||
|
单号:工单[{{workorder_id.production_id.name}}]({{url}})
|
||||||
|
原因:加工失败,工件下产线处理</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
3
jikimo_workorder_exception_notify/models/__init__.py
Normal file
3
jikimo_workorder_exception_notify/models/__init__.py
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from . import jikimo_message_template
|
||||||
|
from . import jikimo_workorder_exception
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
from odoo import models
|
||||||
|
|
||||||
|
|
||||||
|
class JikimoMessageTemplate(models.Model):
|
||||||
|
_inherit = "jikimo.message.template"
|
||||||
|
|
||||||
|
def _get_message_model(self):
|
||||||
|
res = super(JikimoMessageTemplate, self)._get_message_model()
|
||||||
|
res.append('jikimo.workorder.exception')
|
||||||
|
return res
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
from odoo import models, api
|
||||||
|
from odoo.addons.sf_base.commons.common import Common
|
||||||
|
import requests, logging
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class JikimoWorkorderException(models.Model):
|
||||||
|
_name = 'jikimo.workorder.exception'
|
||||||
|
_inherit = ['jikimo.workorder.exception', 'jikimo.message.dispatch']
|
||||||
|
|
||||||
|
@api.model_create_multi
|
||||||
|
def create(self, vals_list):
|
||||||
|
res = super(JikimoWorkorderException, self).create(vals_list)
|
||||||
|
# 根据异常编码发送消息提醒
|
||||||
|
try:
|
||||||
|
for rec in res:
|
||||||
|
if rec.exception_code == 'YC0001':
|
||||||
|
# 无CNC程序,调用cloud接口
|
||||||
|
data = {'name': rec.workorder_id.production_id.programming_no, 'exception_code': 'YC0001'}
|
||||||
|
configsettings = self.env['res.config.settings'].sudo().get_values()
|
||||||
|
config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
||||||
|
url = '/api/message/workorder_exception'
|
||||||
|
config_url = configsettings['sf_url'] + url
|
||||||
|
data['token'] = configsettings['token']
|
||||||
|
ret = requests.post(config_url, json=data, headers=config_header)
|
||||||
|
ret = ret.json()
|
||||||
|
_logger.info('无CNC程序异常消息推送接口:%s' % ret)
|
||||||
|
elif rec.exception_code == 'YC0002':
|
||||||
|
# 无功能刀具
|
||||||
|
rec.add_queue('无功能刀具')
|
||||||
|
elif rec.exception_code == 'YC0003':
|
||||||
|
# 无定位数据
|
||||||
|
rec.add_queue('无定位数据')
|
||||||
|
elif rec.exception_code == 'YC0004':
|
||||||
|
# 无FTP文件,调用cloud接口
|
||||||
|
data = {'name': rec.workorder_id.programming_no, 'exception_code': 'YC0004'}
|
||||||
|
configsettings = self.env['res.config.settings'].sudo().get_values()
|
||||||
|
config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
||||||
|
url = '/api/message/workorder_exception'
|
||||||
|
config_url = configsettings['sf_url'] + url
|
||||||
|
data['token'] = configsettings['token']
|
||||||
|
ret = requests.post(config_url, json=data, headers=config_header)
|
||||||
|
ret = ret.json()
|
||||||
|
_logger.info('无FTP文件异常消息推送接口:%s' % ret)
|
||||||
|
elif rec.exception_code == 'YC0005':
|
||||||
|
# 加工失败
|
||||||
|
rec.add_queue('加工失败')
|
||||||
|
except Exception as e:
|
||||||
|
_logger.error('异常编码发送消息提醒失败:%s' % e)
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _get_message(self, message_queue_ids):
|
||||||
|
contents = super(JikimoWorkorderException, self)._get_message(message_queue_ids)
|
||||||
|
url = self.env['ir.config_parameter'].get_param('web.base.url')
|
||||||
|
action_id = self.env.ref('mrp.mrp_production_action').id
|
||||||
|
for index, content in enumerate(contents):
|
||||||
|
exception_id = self.env['jikimo.workorder.exception'].browse(message_queue_ids[index].res_id)
|
||||||
|
url = url + '/web#id=%s&view_type=form&action=%s' % (exception_id.workorder_id.production_id.id, action_id)
|
||||||
|
contents[index] = content.replace('{{url}}', url)
|
||||||
|
return contents
|
||||||
2
jikimo_workorder_exception_notify/tests/__init__.py
Normal file
2
jikimo_workorder_exception_notify/tests/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
from . import common
|
||||||
|
from . import test_jikimo_workorder_exception
|
||||||
18
jikimo_workorder_exception_notify/tests/common.py
Normal file
18
jikimo_workorder_exception_notify/tests/common.py
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
from odoo import fields, Command
|
||||||
|
from odoo.tests.common import TransactionCase, HttpCase, tagged, Form
|
||||||
|
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import base64
|
||||||
|
from lxml import etree
|
||||||
|
|
||||||
|
@tagged('post_install', '-at_install')
|
||||||
|
class TestJikimoWorkorderExceptionNotifyCommon(TransactionCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
super(TestJikimoWorkorderExceptionNotifyCommon, self).setUp()
|
||||||
|
# 获取最后一个工单
|
||||||
|
self.workorder = self.env['mrp.workorder'].search([], order='id desc', limit=1)
|
||||||
|
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
from odoo.addons.jikimo_workorder_exception_notify.tests.common import TestJikimoWorkorderExceptionNotifyCommon
|
||||||
|
|
||||||
|
class TestJikimoWorkorderException(TestJikimoWorkorderExceptionNotifyCommon):
|
||||||
|
|
||||||
|
def test_create_exception_record(self):
|
||||||
|
exception_record = self.env['jikimo.workorder.exception'].create({
|
||||||
|
'workorder_id': self.workorder.id,
|
||||||
|
'exception_code': 'YC0001',
|
||||||
|
'exception_content': '无CNC编程'
|
||||||
|
})
|
||||||
|
|
||||||
|
self.assertTrue(exception_record)
|
||||||
|
self.assertEqual(exception_record.exception_content, '无CNC编程')
|
||||||
|
self.assertEqual(exception_record.workorder_id.id, self.workorder.id)
|
||||||
|
self.assertEqual(exception_record.exception_code, 'YC0001')
|
||||||
|
|
||||||
|
def test_handle_exception(self):
|
||||||
|
exception_record = self.env['jikimo.workorder.exception'].create({
|
||||||
|
'workorder_id': self.workorder.id,
|
||||||
|
'exception_code': 'YC0001',
|
||||||
|
'exception_content': '无CNC编程'
|
||||||
|
})
|
||||||
|
self.workorder.handle_exception(['YC0001'])
|
||||||
|
self.assertEqual(exception_record.state, 'done')
|
||||||
|
# 判断完成时间是否为当前分钟
|
||||||
|
self.assertEqual(exception_record.completion_time.minute, datetime.now().minute)
|
||||||
|
|
||||||
|
def test_handle_exception_with_invalid_code(self):
|
||||||
|
exception_record = self.env['jikimo.workorder.exception'].create({
|
||||||
|
'workorder_id': self.workorder.id,
|
||||||
|
'exception_code': 'YC0001',
|
||||||
|
'exception_content': '无CNC编程'
|
||||||
|
})
|
||||||
|
self.workorder.handle_exception(['YC0002', 'YC0004'])
|
||||||
|
self.assertEqual(exception_record.state, 'pending')
|
||||||
|
self.assertEqual(exception_record.completion_time, False)
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ class MessageSfMrsConnect(Sf_Mrs_Connect):
|
|||||||
_logger.info('已编程的制造订单:%s' % res.get('production_ids'))
|
_logger.info('已编程的制造订单:%s' % res.get('production_ids'))
|
||||||
productions = request.env['mrp.production'].sudo().search([('id', 'in', res.get('production_ids'))])
|
productions = request.env['mrp.production'].sudo().search([('id', 'in', res.get('production_ids'))])
|
||||||
# 过滤programming_state为已编程,tool_state为2的制造订单
|
# 过滤programming_state为已编程,tool_state为2的制造订单
|
||||||
tool_state_valid_productions = productions.filtered(lambda x: x.programming_state == '已编程' and x.tool_state == '2')
|
tool_state_valid_productions = productions.filtered(lambda x: x.tool_state == '2')
|
||||||
if tool_state_valid_productions:
|
if tool_state_valid_productions:
|
||||||
data = {
|
data = {
|
||||||
'name': tool_state_valid_productions[0].programming_no
|
'name': tool_state_valid_productions[0].programming_no
|
||||||
@@ -39,3 +39,22 @@ class MessageSfMrsConnect(Sf_Mrs_Connect):
|
|||||||
_logger.info('无效用刀异常消息推送接口:%s' % e)
|
_logger.info('无效用刀异常消息推送接口:%s' % e)
|
||||||
return json.JSONEncoder().encode(res)
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
|
@http.route('/api/maintenance_logs/notify', type='json', auth='public', methods=['GET', 'POST'], csrf=False, cors="*")
|
||||||
|
def maintenance_logs_notify(self, **kw):
|
||||||
|
res = {'code': 200, 'message': '设备故障日志信息推送成功'}
|
||||||
|
datas = request.httprequest.data
|
||||||
|
ret = json.loads(datas)
|
||||||
|
log_id = ret.get('log_id')
|
||||||
|
if not log_id:
|
||||||
|
res = {'code': 400, 'message': '设备故障日志id不能为空'}
|
||||||
|
return json.JSONEncoder().encode(res)
|
||||||
|
try:
|
||||||
|
if not isinstance(log_id, list):
|
||||||
|
log_id = [log_id]
|
||||||
|
maintenance_logs = request.env['sf.maintenance.logs'].sudo().search([('id', 'in', [int(id) for id in log_id])])
|
||||||
|
if maintenance_logs:
|
||||||
|
maintenance_logs.add_queue('设备故障')
|
||||||
|
except Exception as e:
|
||||||
|
res = {'code': 400, 'message': '设备故障信息推送失败', 'error': str(e)}
|
||||||
|
return json.JSONEncoder().encode(res)
|
||||||
|
|
||||||
|
|||||||
@@ -94,5 +94,9 @@
|
|||||||
<!-- <field name="name">表面工艺工单已逾期</field>-->
|
<!-- <field name="name">表面工艺工单已逾期</field>-->
|
||||||
<!-- <field name="model">mrp.workorder</field>-->
|
<!-- <field name="model">mrp.workorder</field>-->
|
||||||
<!-- </record>-->
|
<!-- </record>-->
|
||||||
|
<record id="bussiness_maintenance_logs" model="jikimo.message.bussiness.node">
|
||||||
|
<field name="name">设备故障</field>
|
||||||
|
<field name="model">sf.maintenance.logs</field>
|
||||||
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
@@ -132,5 +132,16 @@
|
|||||||
单号:发料出库单[{{name}}]({{request_url}})
|
单号:发料出库单[{{name}}]({{request_url}})
|
||||||
事项:销售订单{{sale_order_name}}已全部产出并入库,请及时发货</field>
|
事项:销售订单{{sale_order_name}}已全部产出并入库,请及时发货</field>
|
||||||
</record>
|
</record>
|
||||||
|
<record id="template_maintenance_logs" model="jikimo.message.template">
|
||||||
|
<field name="name">设备故障</field>
|
||||||
|
<field name="model_id" ref="sf_maintenance.model_sf_maintenance_logs"/>
|
||||||
|
<field name="model">sf.maintenance.logs</field>
|
||||||
|
<field name="bussiness_node_id" ref="bussiness_maintenance_logs"/>
|
||||||
|
<field name="msgtype">markdown</field>
|
||||||
|
<field name="urgency">urgent</field>
|
||||||
|
<field name="content">### 设备故障及异常提醒:
|
||||||
|
机台号:[{{maintenance_equipment_id.name}}]({{url}})
|
||||||
|
事项:{{create_date}}故障报警</field>
|
||||||
|
</record>
|
||||||
</data>
|
</data>
|
||||||
</odoo>
|
</odoo>
|
||||||
@@ -8,3 +8,4 @@ from . import sf_message_purchase
|
|||||||
from . import sf_message_workorder
|
from . import sf_message_workorder
|
||||||
from . import sf_message_functional_tool_dismantle
|
from . import sf_message_functional_tool_dismantle
|
||||||
from . import sf_message_mrp_production
|
from . import sf_message_mrp_production
|
||||||
|
from . import sf_message_maintenance_logs
|
||||||
|
|||||||
22
sf_message/models/sf_message_maintenance_logs.py
Normal file
22
sf_message/models/sf_message_maintenance_logs.py
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
from odoo import models, fields, api
|
||||||
|
|
||||||
|
class SFMessageMaintenanceLogs(models.Model):
|
||||||
|
_name = 'sf.maintenance.logs'
|
||||||
|
_inherit = ['sf.maintenance.logs', 'jikimo.message.dispatch']
|
||||||
|
|
||||||
|
@api._model_create_multi
|
||||||
|
def create(self, vals_list):
|
||||||
|
res = super(SFMessageMaintenanceLogs, self).create(vals_list)
|
||||||
|
for rec in res:
|
||||||
|
rec.add_queue()
|
||||||
|
return res
|
||||||
|
|
||||||
|
def _get_message(self, message_queue_ids):
|
||||||
|
contents = super(SFMessageMaintenanceLogs, self)._get_message(message_queue_ids)
|
||||||
|
url = self.env['ir.config_parameter'].get_param('web.base.url')
|
||||||
|
action_id = self.env.ref('sf_maintenance.action_maintenance_logs').id
|
||||||
|
for index, content in enumerate(contents):
|
||||||
|
maintenance_logs_id = self.env['sf.maintenance.logs'].browse(message_queue_ids[index].res_id)
|
||||||
|
url = url + '/web#id=%s&view_type=form&action=%s' % (maintenance_logs_id.id, action_id)
|
||||||
|
contents[index] = content.replace('{{url}}', url)
|
||||||
|
return contents
|
||||||
@@ -14,4 +14,5 @@ class SfMessageTemplate(models.Model):
|
|||||||
res.append('sf.functional.tool.dismantle')
|
res.append('sf.functional.tool.dismantle')
|
||||||
res.append('purchase.order')
|
res.append('purchase.order')
|
||||||
res.append('mrp.workorder')
|
res.append('mrp.workorder')
|
||||||
|
res.append('sf.maintenance.logs')
|
||||||
return res
|
return res
|
||||||
|
|||||||
Reference in New Issue
Block a user