Compare commits

...

65 Commits

Author SHA1 Message Date
胡尧
c5dfb50da5 修改模块名字 2024-10-31 14:42:28 +08:00
胡尧
1f938292f5 解决异常报错的问题 2024-10-31 14:34:53 +08:00
胡尧
e73e9d6960 增加日志 2024-10-28 17:42:44 +08:00
胡尧
61339da204 增加销售订单确认日志 2024-10-28 17:26:27 +08:00
胡尧
745fd429c2 增加销售订单确认日志 2024-10-28 17:21:51 +08:00
胡尧
5c59a27a81 增加采购总监消息推送权限 2024-10-28 16:30:46 +08:00
胡尧
1467dbf88c 修改排程逻辑 2024-10-28 09:44:52 +08:00
胡尧
aa1353cf99 修改排程逻辑 2024-10-28 09:38:50 +08:00
胡尧
3f84972bfd 删除多余代码 2024-10-24 13:57:26 +08:00
胡尧
ed15958319 解决报错 2024-10-24 11:29:36 +08:00
胡尧
0b70447333 修改排程逻辑 2024-10-24 09:47:20 +08:00
胡尧
1026c0edd0 修改排程逻辑 2024-10-24 09:18:21 +08:00
胡尧
a28d20b3bf 修改排程逻辑 2024-10-23 15:30:05 +08:00
胡尧
451e70b7c7 Accept Merge Request #1434: (feature/workorder_exceptions -> develop)
Merge Request: 修改无功能刀具原因话术

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1434
2024-10-21 17:03:34 +08:00
胡尧
6c1c2ca0fc 修改无功能刀具原因话术 2024-10-21 17:02:59 +08:00
廖丹龙
e7420365cf Accept Merge Request #1433: (feature/销售和排程添加消息推送 -> develop)
Merge Request: 制造订单添加订单交期字段信息

Created By: @廖丹龙
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @廖丹龙
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1433
2024-10-21 16:09:08 +08:00
liaodanlong
736a18518c 制造订单添加订单交期字段信息 2024-10-21 16:07:43 +08:00
liaodanlong
41b287d559 制造订单添加订单交期字段信息 2024-10-21 16:06:03 +08:00
胡尧
5d8e0bda08 Accept Merge Request #1432: (feature/workorder_exceptions -> develop)
Merge Request: 处理设备故障的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1432?initial=true
2024-10-21 15:41:06 +08:00
胡尧
e9dbbaedf4 处理设备故障的问题 2024-10-21 15:40:38 +08:00
胡尧
92ae6be3bd Accept Merge Request #1431: (feature/workorder_exceptions -> develop)
Merge Request: 修改模板标题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1431
2024-10-21 14:59:57 +08:00
胡尧
b00038aaed 修改YC0004消息推送 2024-10-21 14:59:16 +08:00
胡尧
86c1880cdb 修改模板标题 2024-10-21 14:41:09 +08:00
廖丹龙
cfd2dda4e6 Accept Merge Request #1430: (feature/销售和排程添加消息推送 -> develop)
Merge Request: 制造订单添加订单交期字段信息

Created By: @廖丹龙
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @廖丹龙
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1430
2024-10-21 14:34:07 +08:00
liaodanlong
c01e9a4d39 制造订单添加订单交期字段信息 2024-10-21 14:18:53 +08:00
廖丹龙
88ff4bbaa9 Accept Merge Request #1429: (feature/销售和排程添加消息推送 -> develop)
Merge Request: 制造订单添加订单交期字段信息

Created By: @廖丹龙
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @廖丹龙
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1429?initial=true
2024-10-21 14:01:20 +08:00
liaodanlong
f62c70d354 Merge branch 'refs/heads/develop' into feature/销售和排程添加消息推送 2024-10-21 13:57:24 +08:00
liaodanlong
22c9de86f6 制造订单添加订单交期字段信息 2024-10-21 13:56:34 +08:00
胡尧
b362f74336 Accept Merge Request #1428: (feature/workorder_exceptions -> develop)
Merge Request: 修改接口参数

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1428?initial=true
2024-10-21 13:47:36 +08:00
胡尧
81cfbfb540 修改接口参数 2024-10-21 11:46:14 +08:00
胡尧
668db4475f Accept Merge Request #1427: (feature/workorder_exceptions -> develop)
Merge Request: 修改单元测试

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1427?initial=true
2024-10-21 11:37:48 +08:00
胡尧
2af21bc4ee 修改单元测试 2024-10-21 11:37:01 +08:00
管欢
e6614a624f Accept Merge Request #1426: (feature/auxiliary_files_upload -> develop)
Merge Request: 辅助文件上传

Created By: @管欢
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @管欢
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1426
2024-10-21 10:11:36 +08:00
guanhuan
124bc8478e 辅助文件上传 2024-10-21 10:09:19 +08:00
guanhuan
1a3a178ec6 Revert "辅助文件上传"
This reverts commit cae5149fba.
2024-10-21 10:08:35 +08:00
guanhuan
cae5149fba 辅助文件上传 2024-10-21 10:07:49 +08:00
管欢
5c4c036948 Accept Merge Request #1425: (feature/auxiliary_files_upload -> develop)
Merge Request: 辅助文件上传

Created By: @管欢
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @管欢
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1425
2024-10-21 10:01:22 +08:00
guanhuan
4003d6a652 Merge branch 'refs/heads/develop' into feature/auxiliary_files_upload
# Conflicts:
#	sf_dlm_management/views/product_template_management_view.xml
2024-10-21 09:50:09 +08:00
胡嘉莹
0e8e81e4cb Accept Merge Request #1423: (feature/临时分支 -> develop)
Merge Request: sf销售订单明细新增是否带料及带料尺寸字段

Created By: @胡嘉莹
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @胡嘉莹
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1423
2024-10-18 16:44:46 +08:00
guanhuan
b132771c92 辅助文件上传 2024-10-18 14:32:20 +08:00
马广威
cbaf0d79c1 Accept Merge Request #1422: (feature/制造功能优化 -> develop)
Merge Request: 增加设备oee处获取数据的定时器

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1422?initial=true
2024-10-18 10:18:28 +08:00
mgw
953d675dcf Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-10-18 10:17:38 +08:00
mgw
182eb83090 暂时屏蔽24数据 2024-10-18 10:17:22 +08:00
mgw
67a607b053 增加设备oee处获取数据的定时器 2024-10-18 10:05:55 +08:00
禹翔辉
33d23c28b1 Accept Merge Request #1421: (feature/工单状态优化 -> develop)
Merge Request: 处理制造订单、工单的状态计算方法没有触发的问题

Created By: @禹翔辉
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1421
2024-10-18 09:21:43 +08:00
yuxianghui
571fb29482 Merge branch 'feature/用刀校验优化' into feature/工单状态优化 2024-10-18 09:14:39 +08:00
yuxianghui
1dae20e055 处理制造订单、工单的状态计算方法没有触发的问题 2024-10-18 09:13:34 +08:00
mgw
8a459e7e90 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-10-17 17:54:59 +08:00
mgw
4c486e53aa 设备oee界面数据准备 2024-10-17 17:54:32 +08:00
yuxianghui
19509a3ce2 1 2024-10-17 17:54:08 +08:00
胡嘉莹
4d424e90d3 Accept Merge Request #1420: (feature/临时分支 -> develop)
Merge Request: 修改生成完工入库提醒,订单发货提醒跳转到表单详情

Created By: @胡嘉莹
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @胡嘉莹
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1420?initial=true
2024-10-17 17:49:26 +08:00
禹翔辉
f5ea0ec153 Accept Merge Request #1419: (feature/用刀校验优化 -> develop)
Merge Request: 优化手动返工时,cnc用刀校验逻辑

Created By: @禹翔辉
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1419?initial=true
2024-10-17 17:04:12 +08:00
yuxianghui
ea6c0f7d0b Merge branch 'feature/程序用刀校验优化' into feature/用刀校验优化 2024-10-17 17:02:17 +08:00
yuxianghui
763009a3c0 1、优化手动返工时,cnc用刀校验逻辑 2024-10-17 17:01:20 +08:00
guanhuan
cf34ac5bbc 辅助文件上传 2024-10-17 16:31:13 +08:00
禹翔辉
0faedd35d7 Accept Merge Request #1418: (feature/程序用刀校验优化 -> develop)
Merge Request: 修改调用创建cam程序用刀计划方法的判断条件

Created By: @禹翔辉
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1418
2024-10-17 16:01:42 +08:00
yuxianghui
135b97d4f8 1 2024-10-17 16:00:44 +08:00
yuxianghui
61f3aff768 Merge branch 'feature/制造订单状态优化_3' into feature/程序用刀校验优化 2024-10-17 15:52:06 +08:00
yuxianghui
9e369f0150 修改调用创建cam程序用刀计划方法的判断条件 2024-10-17 15:51:00 +08:00
杨金灵
16d50f5bf2 Accept Merge Request #1417: (feature/工作中心添加质检权限 -> develop)
Merge Request: 工作中心添加质检权限

Created By: @杨金灵
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @杨金灵
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1417?initial=true
2024-10-17 15:40:23 +08:00
jinling.yang
80f0454996 工作中心添加质检权限 2024-10-17 15:37:08 +08:00
jinling.yang
9b9d811594 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-17 15:33:51 +08:00
jinling.yang
008ae20329 Merge branch 'feature/检测结果添加质检权限' into develop 2024-10-17 15:33:29 +08:00
杨金灵
80b3b4b0f7 Accept Merge Request #1416: (feature/检测结果添加质检权限 -> develop)
Merge Request: 检测结果添加质检权限

Created By: @杨金灵
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @杨金灵
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1416
2024-10-17 15:26:29 +08:00
jinling.yang
d64b480496 检测结果添加质检权限 2024-10-17 15:25:13 +08:00
26 changed files with 347 additions and 173 deletions

View File

@@ -21,8 +21,8 @@ class WorkorderExceptionConroller(http.Controller):
try:
res = {'Succeed': True, 'ErrorCode': 0, 'Error': ''}
datas = request.httprequest.data
ret = json.loads(datas)['Datas']
if not ret.get('RfidCode') or not ret.get('ErrorType'):
ret = json.loads(datas)
if not ret.get('RfidCode') or not ret.get('coding'):
res = {'Succeed': False, 'ErrorCode': 400, 'Error': '参数错误'}
return json.JSONEncoder().encode(res)
@@ -38,12 +38,12 @@ class WorkorderExceptionConroller(http.Controller):
# 创建工单异常记录,关联工单
request.env['jikimo.workorder.exception'].sudo().create({
'workorder_id': workorder.id,
'exception_code': ret.get('ErrorType'),
'exception_code': ret.get('coding'),
'exception_content': ret.get('Error', '')
})
except Exception as e:
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
res = {'Succeed': False, 'ErrorCode': 202, 'Error': str(e)}
_logger.info('workder_exception error:%s' % e)
return json.JSONEncoder().encode(res)

View File

@@ -10,7 +10,7 @@
<field name="urgency">urgent</field>
<field name="content">### 生产线无功能刀具提醒
单号:工单[{{workorder_id.production_id.name}}]({{url}})
原因:生产线无加工程序用的{{function_tool_name}}名称功能刀具</field>
原因:生产线无加工程序用的功能刀具</field>
</record>
<record id="template_no_position_data" model="jikimo.message.template">
<field name="name">工单无定位数据提醒</field>
@@ -19,7 +19,7 @@
<field name="bussiness_node_id" ref="bussiness_no_position_data"/>
<field name="msgtype">markdown</field>
<field name="urgency">urgent</field>
<field name="content">### 生产线无功能刀具提醒
<field name="content">### 工单无定位数据提醒
单号:工单[{{workorder_id.production_id.name}}]({{url}})
原因:无装夹定位测量数据</field>
</record>

View File

@@ -34,7 +34,7 @@ class JikimoWorkorderException(models.Model):
rec.add_queue('无定位数据')
elif rec.exception_code == 'YC0004':
# 无FTP文件调用cloud接口
data = {'name': rec.workorder_id.programming_no, 'exception_code': 'YC0004'}
data = {'name': rec.workorder_id.production_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'

View File

@@ -14,12 +14,25 @@ class TestJikimoWorkorderExceptionNotify(TestJikimoWorkorderExceptionNotifyCommo
('model', '=', 'jikimo.workorder.exception')
]))
self.assertTrue(self.env['jikimo.message.template'].search([
('name', '=', '加工失败'),
('name', '=', '工单加工失败提醒'),
('model', '=', 'jikimo.workorder.exception')
]))
def test_create_message_queue_yc0001(self):
exception_record = self.env['jikimo.workorder.exception'].create({
'workorder_id': self.workorder.id,
'exception_code': 'YC0001',
'exception_content': '无CNC程序'
})
def test_create_message_queue(self):
message_record = self.env['jikimo.message.queue'].search([
('res_id', '=', exception_record.id),
('model', '=', 'jikimo.workorder.exception'),
('message_status', '=', 'pending')
])
self.assertFalse(message_record)
def test_create_message_queue_yc0002(self):
exception_record = self.env['jikimo.workorder.exception'].create({
'workorder_id': self.workorder.id,
'exception_code': 'YC0002',
@@ -43,7 +56,45 @@ class TestJikimoWorkorderExceptionNotify(TestJikimoWorkorderExceptionNotifyCommo
('message_template_id', '=', message_template.id)
])
self.assertTrue(message_record)
def test_create_message_queue_yc0003(self):
exception_record = self.env['jikimo.workorder.exception'].create({
'workorder_id': self.workorder.id,
'exception_code': 'YC0003',
'exception_content': '无定位数据'
})
bussiness_node = self.env['jikimo.message.bussiness.node'].search([
('name', '=', '无定位数据'),
('model', '=', 'jikimo.workorder.exception')
])
message_template = self.env['jikimo.message.template'].search([
('bussiness_node_id', '=', bussiness_node.id),
('model', '=', 'jikimo.workorder.exception')
])
message_record = self.env['jikimo.message.queue'].search([
('res_id', '=', exception_record.id),
('model', '=', 'jikimo.workorder.exception'),
('message_status', '=', 'pending'),
('message_template_id', '=', message_template.id)
])
self.assertTrue(message_record)
def test_create_message_queue_yc0004(self):
exception_record = self.env['jikimo.workorder.exception'].create({
'workorder_id': self.workorder.id,
'exception_code': 'YC0004',
'exception_content': '无CNC程序'
})
message_record = self.env['jikimo.message.queue'].search([
('res_id', '=', exception_record.id),
('model', '=', 'jikimo.workorder.exception'),
('message_status', '=', 'pending')
])
self.assertFalse(message_record)
def test_get_message(self):
exception_record = self.env['jikimo.workorder.exception'].create({

View File

@@ -36,6 +36,7 @@ class StatusChange(models.Model):
# 使用super()来调用原始方法(在本例中为'sale.order'模型的'action_confirm'方法)
try:
res = super(StatusChange, self).action_confirm()
logging.info('原生方法返回结果:%s' % res)
# 原有方法执行后进行额外的操作如调用外部API
process_start_time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
config = self.env['res.config.settings'].get_values()
@@ -61,6 +62,7 @@ class StatusChange(models.Model):
traceback_error = traceback.format_exc()
logging.error("工厂加工同步订单状态失败:%s " % traceback_error)
raise UserError(e)
logging.info('最终返回值:%s' % res)
return res
def action_cancel(self):

View File

@@ -16,8 +16,8 @@
<field name='is_bfm' invisible="1"/>
<field name='categ_type' invisible="1"/>
<field name='part_number' attrs="{'invisible': [('categ_type', '!=', '成品')]}"/>
<!-- <field name='machining_drawings' attrs="{'invisible': [('categ_type', '!=', '成品')]}" widget="image"/>-->
<!-- <field name='quality_standard' attrs="{'invisible': [('categ_type', '!=', '成品')]}"/>-->
<field name='machining_drawings' attrs="{'invisible': [('categ_type', '!=', '成品')]}" widget="adaptive_viewer"/>
<field name='quality_standard' attrs="{'invisible': [('categ_type', '!=', '成品')]}" widget="adaptive_viewer"/>
<field name='manual_quotation' attrs="{'invisible':[('upload_model_file', '=', [])]}"/>
<field name="upload_model_file"
widget="many2many_binary"

View File

@@ -1272,6 +1272,7 @@ class Sf_Dashboard_Connect(http.Controller):
time_threshold = datetime.now() - timedelta(days=1)
alarm_last_24_time = 0.0
alarm_all_time = 0.0
def fetch_result_as_dict(cursor):
"""辅助函数:将查询结果转为字典"""
@@ -1332,6 +1333,35 @@ class Sf_Dashboard_Connect(http.Controller):
alarm_last_24_time += float(result[0])
else:
alarm_last_24_time += 0.0
alarm_all_nums = []
with conn.cursor() as cur:
cur.execute("""
SELECT DISTINCT ON (alarm_start_time) alarm_time, alarm_start_time
FROM device_data
WHERE device_name = %s
AND alarm_start_time IS NOT NULL;
""", (item,))
results = cur.fetchall()
for result in results:
alarm_all_nums.append(result[1])
if result[0]:
if float(result[0]) >= 1000:
continue
alarm_all_time += float(result[0])
else:
alarm_all_time += 0.0
# with conn.cursor() as cur:
# cur.execute("""
# SELECT * FROM device_data
# WHERE device_name = %s
# AND total_count IS NOT NULL
# ORDER BY time ASC
# LIMIT 1;
# """, (item, ))
# total_count = fetch_result_as_dict(cur)
# 返回数据
res['data'][item] = {
'wait_time': last_all_time['run_time'] if last_all_time['run_time'] is not None else 0,
@@ -1343,6 +1373,9 @@ class Sf_Dashboard_Connect(http.Controller):
'alarm_last_24_nums': len(list(set(alarm_last_24_nums))),
'idle_count': idle_count,
'first_online_time': first_online_duration,
'alarm_all_time': alarm_all_time,
'alarm_all_nums': len(list(set(alarm_all_nums)))
# 'total_count': total_count['total_count'] if total_count else 0
}
conn.close()

View File

@@ -11,6 +11,7 @@
'security/group_security.xml',
'security/ir.model.access.csv',
'security/ir_rule_data.xml',
'data/scheduled_actions.xml',
'views/maintenance_logs_views.xml',
'views/maintenance_equipment_oee_views.xml',
'views/maintenance_views.xml',

View File

@@ -0,0 +1,14 @@
<odoo>
<data noupdate="1">
<record id="ir_cron_oee_get_running_datas" model="ir.cron">
<field name="name">设备运行数据</field>
<field name="model_id" ref="model_maintenance_equipment_oee"/>
<field name="state">code</field>
<field name="code">model.get_running_datas()</field>
<field name="interval_number">15</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="active" eval="True"/>
</record>
</data>
</odoo>

View File

@@ -88,6 +88,69 @@ class SfMaintenanceEquipmentOEE(models.Model):
begin_time = fields.Date('开始时间')
end_time = fields.Date('结束时间')
def get_running_datas(self):
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
url_time = base_url + '/api/RunningTimeDetail'
cnc_list_obj = self.env['maintenance.equipment'].sudo().search(
[('function_type', '!=', False), ('active', '=', True)])
machine_list = list(map(lambda x: x.code, cnc_list_obj))
# print('machine_list: %s' % machine_list)
data_time = {
"machine_list": str(machine_list)
}
# 发送POST请求
response_time = requests.post(url_time, json={}, data=data_time)
# print(response_time.json())
if response_time.status_code == 200:
result_time = response_time.json()
if result_time['status'] == 1:
real_dict = result_time['data']
for key in real_dict:
# print(key)
equipment_obj = self.env['maintenance.equipment.oee'].sudo().search([('equipment_code', '=', key)])
if real_dict[key]['power_on_time'] == 0:
equipment_obj.online_time = 0
equipment_obj.idle_time = 0
equipment_obj.idle_rate = 0
equipment_obj.work_rate = 0
equipment_obj.fault_time = 0
equipment_obj.fault_rate = 0
equipment_obj.fault_nums = 0
equipment_obj.idle_nums = 0
equipment_obj.work_time = 0
else:
equipment_obj.online_time = round(convert_to_seconds(real_dict[key]['power_on_time']) / 3600, 2)
equipment_obj.work_time = round(convert_to_seconds(real_dict[key]['cut_time']) / 3600, 2)
equipment_obj.fault_nums = real_dict[key]['alarm_all_nums']
equipment_obj.idle_nums = real_dict[key]['idle_count']
equipment_obj.fault_time = round((float(real_dict[key]['alarm_all_time']) if real_dict[key][
'alarm_all_time'] else 0) / 3600, 2)
equipment_obj.idle_time = float(equipment_obj.online_time) - float(
equipment_obj.work_time) if equipment_obj.online_time and equipment_obj.work_time else 0
equipment_obj.idle_rate = round(
float(equipment_obj.idle_time) / (
float(equipment_obj.online_time) if equipment_obj.online_time else 1) * 100, 2)
equipment_obj.work_rate = round(
float(equipment_obj.work_time) / (
float(equipment_obj.online_time) if equipment_obj.online_time else 1) * 100, 2)
equipment_obj.fault_rate = round(
float(equipment_obj.fault_time) / (
float(equipment_obj.online_time) if equipment_obj.online_time else 1) * 100, 2)
# 获取当前时间的时间戳
current_timestamp = datetime.datetime.now().timestamp()
# 机床上线时间段
first_online_duration = current_timestamp - int(equipment_obj.equipment_id.first_online_time.timestamp())
if equipment_obj.online_time:
equipment_obj.offline_time = round((first_online_duration - float(equipment_obj.online_time)) / 3600, 2)
else:
equipment_obj.offline_time = False
# equipment_obj.offline_time = equipment_obj.equipment_id.first_online_time - (
# float(equipment_obj.online_time) if equipment_obj.online_time else 0)
# 获取日志详情
def get_day_logs(self):
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
@@ -150,12 +213,11 @@ class SfMaintenanceEquipmentOEE(models.Model):
self.fault_nums = real_dict['alarm_last_24_nums']
self.idle_nums = real_dict['idle_count']
self.work_time = round(
(convert_to_seconds(real_dict['cut_time']) - convert_to_seconds(real_dict['cut_24_time'])) / 3600,
(convert_to_seconds(real_dict['cut_time']) - convert_to_seconds(
real_dict['cut_24_time'])) / 3600,
2)
self.offline_time = 24 - (float(self.online_time) if self.online_time else 0)
if response.status_code == 200:
result = response.json()
print('============', result)

View File

@@ -79,12 +79,12 @@
</group>
</group>
<notebook>
<page string="24H日志详情">
<group>
<button name="get_day_logs" type="object" string="查看24H日志" t-attf-style="white-space:nowrap;"/>
</group>
<field name="day_logs_detail" readonly="1" widget="html"/>
<!-- <notebook> -->
<!-- <page string="24H日志详情"> -->
<!-- <group> -->
<!-- <button name="get_day_logs" type="object" string="查看24H日志" t-attf-style="white-space:nowrap;"/> -->
<!-- </group> -->
<!-- <field name="day_logs_detail" readonly="1" widget="html"/> -->
<!-- <field name="page_num"/> -->
<!-- <group> -->
<!-- <group> -->
@@ -109,7 +109,7 @@
<!-- </div> -->
<!-- </div> -->
<!-- </group> -->
</page>
<!-- </page> -->
<!-- <page string="历史日志详情"> -->
<!-- <group> -->
<!-- <group> -->
@@ -132,7 +132,7 @@
<!-- </group> -->
<!-- <field name="history_logs_detail"/> -->
<!-- </page> -->
</notebook>
<!-- </notebook> -->
</sheet>
</form>
</field>

View File

@@ -18,7 +18,7 @@ class MrpProduction(models.Model):
_inherit = 'mrp.production'
_description = "制造订单"
_order = 'create_date desc'
deadline_of_delivery = fields.Date('订单交期', tracking=True, compute='_compute_deadline_of_delivery')
# tray_ids = fields.One2many('sf.tray', 'production_id', string="托盘")
maintenance_count = fields.Integer(compute='_compute_maintenance_count', string="Number of maintenance requests")
request_ids = fields.One2many('maintenance.request', 'production_id')
@@ -34,6 +34,16 @@ class MrpProduction(models.Model):
tool_state_remark = fields.Text(string='功能刀具状态备注(缺刀)', compute='_compute_tool_state_remark', store=True)
tool_state_remark2 = fields.Text(string='功能刀具状态备注(无效刀)', readonly=True)
@api.depends('procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id')
def _compute_deadline_of_delivery(self):
for production in self:
sale_order_ids = production.procurement_group_id.mrp_production_ids.move_dest_ids.group_id.sale_id.ids
if not sale_order_ids or len(sale_order_ids) < 1:
continue
sale_id = self.env['sale.order'].sudo().browse(sale_order_ids[0])
if sale_id:
production.deadline_of_delivery = sale_id.deadline_of_delivery
@api.depends('workorder_ids.tool_state_remark')
def _compute_tool_state_remark(self):
for item in self:
@@ -118,10 +128,12 @@ class MrpProduction(models.Model):
], string='工序状态', default='待装夹')
# 零件图号
part_number = fields.Char('零件图号')
part_number = fields.Char('零件图号', readonly=True)
# 上传零件图纸
part_drawing = fields.Binary('零件图纸')
part_drawing = fields.Binary('零件图纸', readonly=True)
quality_standard = fields.Binary('质检标准', readonly=True)
@api.depends('product_id.manual_quotation')
def _compute_manual_quotation(self):
@@ -948,6 +960,8 @@ class MrpProduction(models.Model):
if production.programming_no in program_to_production_names:
productions_not_delivered = self.env['mrp.production'].search(
[('programming_no', '=', production.programming_no), ('programming_state', '=', '已编程未下发')])
productions = self.env['mrp.production'].search(
[('programming_no', '=', production.programming_no), ('state', 'not in', ('cancel', 'done'))])
rework_workorder = production.workorder_ids.filtered(lambda m: m.state == 'rework')
if rework_workorder:
for rework_item in rework_workorder:
@@ -960,12 +974,12 @@ class MrpProduction(models.Model):
productions_not_delivered.write(
{'state': 'progress', 'programming_state': '已编程', 'is_rework': False})
# 对制造订单所以面的cnc工单的程序用刀进行校验
try:
logging.info(f'已更新制造订单:{productions_not_delivered}')
productions_not_delivered.production_cnc_tool_checkout()
except Exception as e:
logging.info(f'对cnc工单的程序用刀进行校验报错{e}')
# 对制造订单所以面的cnc工单的程序用刀进行校验
try:
logging.info(f'已更新制造订单:{productions_not_delivered}')
productions.production_cnc_tool_checkout()
except Exception as e:
logging.info(f'对cnc工单的程序用刀进行校验报错{e}')
# 从cloud获取重新编程过的最新程序
def get_new_program(self, processing_panel):

View File

@@ -225,6 +225,9 @@ class ResMrpWorkOrder(models.Model):
material_height = fields.Float(string='')
# 零件图号
part_number = fields.Char(related='production_id.part_number', string='零件图号')
machining_drawings = fields.Binary('2D加工图纸', related='production_id.part_drawing', readonly=True)
quality_standard = fields.Binary('质检标准', related='production_id.quality_standard', readonly=True)
# 工序状态
process_state = fields.Selection([
('待装夹', '待装夹'),

View File

@@ -774,8 +774,8 @@ class ResProductMo(models.Model):
# bfm下单
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
part_number = fields.Char(string='零件图号', readonly=True)
# machining_drawings = fields.Binary('2D加工图纸', readonly=True)
# quality_standard = fields.Binary('质检标准', readonly=True)
machining_drawings = fields.Binary('2D加工图纸', readonly=True)
quality_standard = fields.Binary('质检标准', readonly=True)
@api.constrains('tool_length')
def _check_tool_length_size(self):
@@ -875,8 +875,8 @@ class ResProductMo(models.Model):
'manual_quotation': item['manual_quotation'] or False,
'part_number': item.get('part_number') or '',
'active': True,
# 'machining_drawings': '' if not item['machining_drawings'] else base64.b64decode(item['machining_drawings']),
# 'quality_standard': '' if not item['quality_standard'] else base64.b64decode(item['quality_standard']),
'machining_drawings': '' if not item['machining_drawings'] else base64.b64decode(item['machining_drawings']),
'quality_standard': '' if not item['quality_standard'] else base64.b64decode(item['quality_standard']),
}
tax_id = self.env['account.tax'].sudo().search(
[('type_tax_use', '=', 'sale'), ('amount', '=', item.get('tax')), ('price_include', '=', 'True')])

View File

@@ -272,6 +272,10 @@ class StockRule(models.Model):
if quick_easy_order:
production.write({'part_number': quick_easy_order.part_drawing_number,
'part_drawing': quick_easy_order.machining_drawings})
else:
production.write({'part_number': production.product_id.part_number,
'part_drawing': production.product_id.machining_drawings,
'quality_standard': production.product_id.quality_standard})
if sale_order:
# sale_order.write({'schedule_status': 'to schedule'})
self.env['sf.production.plan'].sudo().with_company(company_id).create({

View File

@@ -103,7 +103,10 @@ access_mrp_production_split_multi_group_sf_mrp_user,access.mrp.production.split.
access_mrp_production_split_group_sf_mrp_user,access.mrp.production.split,mrp.model_mrp_production_split,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_production_split_line_group_sf_mrp_user,access.mrp.production.split.line,mrp.model_mrp_production_split_line,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_workcenter_capacity_manager_group_sf_mrp_user,mrp.workcenter.capacity.manager,mrp.model_mrp_workcenter_capacity,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_workcenter_group_quality,mrp_workcenter_group_quality,model_mrp_workcenter,sf_base.group_quality,1,0,0,0
access_mrp_workcenter_group_quality_director,mrp_workcenter_group_quality_director,model_mrp_workcenter,sf_base.group_quality_director,1,0,0,0
access_sf_detection_result_group_quality,sf_detection_result_group_quality,model_sf_detection_result,sf_base.group_quality,1,0,1,0
access_sf_detection_result_group_quality_director,sf_detection_result_group_quality_director,model_sf_detection_result,sf_base.group_quality_director,1,0,1,0
access_mrp_workcenter_productivity_loss_group_quality,mrp_workcenter_productivity_loss_group_quality,mrp.model_mrp_workcenter_productivity_loss,sf_base.group_quality,1,0,0,0
access_mrp_workcenter_productivity_loss_group_quality_director,mrp_workcenter_productivity_loss_group_quality_director,mrp.model_mrp_workcenter_productivity_loss,sf_base.group_quality_director,1,0,0,0
access_mrp_workcenter_productivity_group_quality,mrp_workcenter_productivity_group_quality,mrp.model_mrp_workcenter_productivity,sf_base.group_quality,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
103 access_mrp_production_split_line_group_sf_mrp_user access.mrp.production.split.line mrp.model_mrp_production_split_line sf_base.group_sf_mrp_user 1 1 1 0
104 access_mrp_workcenter_capacity_manager_group_sf_mrp_user mrp.workcenter.capacity.manager mrp.model_mrp_workcenter_capacity sf_base.group_sf_mrp_user 1 1 1 0
105 access_mrp_workcenter_productivity_loss_group_quality access_mrp_workcenter_group_quality mrp_workcenter_productivity_loss_group_quality mrp_workcenter_group_quality mrp.model_mrp_workcenter_productivity_loss model_mrp_workcenter sf_base.group_quality 1 0 0 0
106 access_mrp_workcenter_productivity_loss_group_quality_director access_mrp_workcenter_group_quality_director mrp_workcenter_productivity_loss_group_quality_director mrp_workcenter_group_quality_director mrp.model_mrp_workcenter_productivity_loss model_mrp_workcenter sf_base.group_quality_director 1 0 0 0
107 access_sf_detection_result_group_quality sf_detection_result_group_quality model_sf_detection_result sf_base.group_quality 1 0 1 0
108 access_sf_detection_result_group_quality_director sf_detection_result_group_quality_director model_sf_detection_result sf_base.group_quality_director 1 0 1 0
109 access_mrp_workcenter_productivity_loss_group_quality mrp_workcenter_productivity_loss_group_quality mrp.model_mrp_workcenter_productivity_loss sf_base.group_quality 1 0 0 0
110 access_mrp_workcenter_productivity_group_quality access_mrp_workcenter_productivity_loss_group_quality_director mrp_workcenter_productivity_group_quality mrp_workcenter_productivity_loss_group_quality_director mrp.model_mrp_workcenter_productivity mrp.model_mrp_workcenter_productivity_loss sf_base.group_quality sf_base.group_quality_director 1 1 0 1 0 0
111 access_mrp_workcenter_productivity_group_quality_director access_mrp_workcenter_productivity_group_quality mrp_workcenter_productivity_group_quality_director mrp_workcenter_productivity_group_quality mrp.model_mrp_workcenter_productivity sf_base.group_quality_director sf_base.group_quality 1 1 1 0
112 access_mrp_production_group_plan_dispatch access_mrp_workcenter_productivity_group_quality_director mrp_production mrp_workcenter_productivity_group_quality_director model_mrp_production mrp.model_mrp_workcenter_productivity sf_base.group_plan_dispatch sf_base.group_quality_director 1 1 0 1 0

View File

@@ -98,9 +98,11 @@
<field name="production_line_id" readonly="1"/>
<!-- <field name="production_line_state" readonly="1"/>-->
<field name="part_number" string="成品的零件图号"/>
<field name="part_drawing"/>
<field name="part_drawing" widget="adaptive_viewer"/>
<field name="quality_standard" widget="adaptive_viewer"/>
<field name="tool_state"/>
<field name="tool_state_remark" string="备注" attrs="{'invisible': [('tool_state', '!=', '1')]}"/>
<field name="deadline_of_delivery" readonly="1"/>
<field name="tool_state_remark2" invisible="1"/>
</xpath>
<xpath expr="//header//button[@name='action_cancel']" position="replace">

View File

@@ -268,6 +268,8 @@
<field name="material_height" class="o_address_zip"/>
</div>
<field name="part_number" string="成品的零件图号"/>
<field name="machining_drawings" widget="adaptive_viewer" attrs="{'invisible': [('routing_type', '!=', 'CNC加工')]}"/>
<field name="quality_standard" widget="adaptive_viewer" attrs="{'invisible': [('routing_type', '!=', 'CNC加工')]}"/>
</xpath>
<xpath expr="//label[1]" position="attributes">
<attribute name="string">计划加工时间</attribute>

View File

@@ -4,11 +4,11 @@ class SFMessageMaintenanceLogs(models.Model):
_name = 'sf.maintenance.logs'
_inherit = ['sf.maintenance.logs', 'jikimo.message.dispatch']
@api._model_create_multi
@api.model_create_multi
def create(self, vals_list):
res = super(SFMessageMaintenanceLogs, self).create(vals_list)
for rec in res:
rec.add_queue()
rec.add_queue('设备故障')
return res
def _get_message(self, message_queue_ids):

View File

@@ -39,6 +39,7 @@ class SFMessageSale(models.Model):
purchase_order_info.add_queue('坯料采购提醒')
except Exception as e:
logging.info('add_queue error:%s' % e)
logging.info('action_confirm res:%s' % res)
return res
# 继承并重写jikimo.message.dispatch的_get_message()

View File

@@ -12,7 +12,7 @@ class SFMessageWork(models.Model):
_name = 'mrp.workorder'
_inherit = ['mrp.workorder', 'jikimo.message.dispatch']
@api.depends('production_availability', 'blocked_by_workorder_ids.state')
@api.depends('production_availability', 'blocked_by_workorder_ids.state', 'production_id.tool_state')
def _compute_state(self):
super(SFMessageWork, self)._compute_state()
for workorder in self:
@@ -153,6 +153,6 @@ class SFMessageWork(models.Model):
getattr(item, queue_method_name)(*args)
def _recover_time_warning_func(self):
workorder_done = self.env['mrp.workorder'].search([("state", "=", "done")])
workorder_done = self.env['mrp.workorder'].search([("state", "in", ["done", "rework", "cancel"])])
workorder_overdue = workorder_done.filtered(lambda x: x.delivery_warning in ['overdue', 'warning'])
workorder_overdue.write({'delivery_warning': 'normal'})

View File

@@ -5,24 +5,28 @@ access_jikimo_message_template_group_purchase,jikimo_message_template,jikimo_mes
access_jikimo_message_template_group_sf_stock_user,jikimo_message_template,jikimo_message_notify.model_jikimo_message_template,sf_base.group_sf_stock_user,1,1,1,0
access_jikimo_message_template_group_sf_order_user,jikimo_message_template,jikimo_message_notify.model_jikimo_message_template,sf_base.group_sf_order_user,1,1,1,0
access_jikimo_message_template_group_sf_tool_user,jikimo_message_template,jikimo_message_notify.model_jikimo_message_template,sf_base.group_sf_tool_user,1,1,1,0
access_jikimo_message_template_group_purchase_director,jikimo_message_template,jikimo_message_notify.model_jikimo_message_template,sf_base.group_purchase_director,1,1,1,0
access_jikimo_message_bussiness_node_group_sale_salemanager,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_sale_salemanager,1,1,1,0
access_jikimo_message_bussiness_node_group_purchase,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_purchase,1,1,1,0
access_jikimo_message_bussiness_node_group_sf_stock_user,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_sf_stock_user,1,1,1,0
access_jikimo_message_bussiness_node_group_sf_order_user,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_sf_order_user,1,1,1,0
access_jikimo_message_bussiness_node_group_sf_tool_user,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_sf_tool_user,1,1,1,0
access_jikimo_message_bussiness_node_group_purchase_director,jikimo_message_bussiness_node,jikimo_message_notify.model_jikimo_message_bussiness_node,sf_base.group_purchase_director,1,1,1,0
access_jikimo_message_queue_group_sale_salemanager,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_sale_salemanager,1,1,1,0
access_jikimo_message_queue_group_purchase,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_purchase,1,1,1,0
access_jikimo_message_queue_group_sf_stock_user,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_sf_stock_user,1,1,1,0
access_jikimo_message_queue_group_sf_order_user,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_sf_order_user,1,1,1,0
access_jikimo_message_queue_group_sf_tool_user,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_sf_tool_user,1,1,1,0
access_jikimo_message_queue_group_purchase_director,jikimo_message_queue,jikimo_message_notify.model_jikimo_message_queue,sf_base.group_purchase_director,1,1,1,0
access_jikimo_message_reminder_time_group_sale_salemanager,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_sale_salemanager,1,1,1,0
access_jikimo_message_reminder_time_group_purchase,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_purchase,1,1,1,0
access_jikimo_message_reminder_time_group_sf_stock_user,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_sf_stock_user,1,1,1,0
access_jikimo_message_reminder_time_group_sf_order_user,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_sf_order_user,1,1,1,0
access_jikimo_message_reminder_time_group_sf_tool_user,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_sf_tool_user,1,1,1,0
access_jikimo_message_reminder_time_group_purchase_director,jikimo_message_reminder_time,jikimo_message_notify.model_jikimo_message_reminder_time,sf_base.group_purchase_director,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
5 access_jikimo_message_template_group_sf_order_user jikimo_message_template jikimo_message_notify.model_jikimo_message_template sf_base.group_sf_order_user 1 1 1 0
6 access_jikimo_message_template_group_sf_tool_user jikimo_message_template jikimo_message_notify.model_jikimo_message_template sf_base.group_sf_tool_user 1 1 1 0
7 access_jikimo_message_bussiness_node_group_sale_salemanager access_jikimo_message_template_group_purchase_director jikimo_message_bussiness_node jikimo_message_template jikimo_message_notify.model_jikimo_message_bussiness_node jikimo_message_notify.model_jikimo_message_template sf_base.group_sale_salemanager sf_base.group_purchase_director 1 1 1 0
8 access_jikimo_message_bussiness_node_group_sale_salemanager jikimo_message_bussiness_node jikimo_message_notify.model_jikimo_message_bussiness_node sf_base.group_sale_salemanager 1 1 1 0
9 access_jikimo_message_bussiness_node_group_purchase jikimo_message_bussiness_node jikimo_message_notify.model_jikimo_message_bussiness_node sf_base.group_purchase 1 1 1 0
10 access_jikimo_message_bussiness_node_group_sf_stock_user jikimo_message_bussiness_node jikimo_message_notify.model_jikimo_message_bussiness_node sf_base.group_sf_stock_user 1 1 1 0
11 access_jikimo_message_bussiness_node_group_sf_order_user jikimo_message_bussiness_node jikimo_message_notify.model_jikimo_message_bussiness_node sf_base.group_sf_order_user 1 1 1 0
12 access_jikimo_message_bussiness_node_group_sf_tool_user jikimo_message_bussiness_node jikimo_message_notify.model_jikimo_message_bussiness_node sf_base.group_sf_tool_user 1 1 1 0
13 access_jikimo_message_queue_group_sale_salemanager access_jikimo_message_bussiness_node_group_purchase_director jikimo_message_queue jikimo_message_bussiness_node jikimo_message_notify.model_jikimo_message_queue jikimo_message_notify.model_jikimo_message_bussiness_node sf_base.group_sale_salemanager sf_base.group_purchase_director 1 1 1 0
14 access_jikimo_message_queue_group_purchase access_jikimo_message_queue_group_sale_salemanager jikimo_message_queue jikimo_message_notify.model_jikimo_message_queue sf_base.group_purchase sf_base.group_sale_salemanager 1 1 1 0
15 access_jikimo_message_queue_group_purchase jikimo_message_queue jikimo_message_notify.model_jikimo_message_queue sf_base.group_purchase 1 1 1 0
16 access_jikimo_message_queue_group_sf_stock_user jikimo_message_queue jikimo_message_notify.model_jikimo_message_queue sf_base.group_sf_stock_user 1 1 1 0
17 access_jikimo_message_queue_group_sf_order_user jikimo_message_queue jikimo_message_notify.model_jikimo_message_queue sf_base.group_sf_order_user 1 1 1 0
18 access_jikimo_message_queue_group_sf_tool_user jikimo_message_queue jikimo_message_notify.model_jikimo_message_queue sf_base.group_sf_tool_user 1 1 1 0
19 access_jikimo_message_reminder_time_group_sale_salemanager access_jikimo_message_queue_group_purchase_director jikimo_message_reminder_time jikimo_message_queue jikimo_message_notify.model_jikimo_message_reminder_time jikimo_message_notify.model_jikimo_message_queue sf_base.group_sale_salemanager sf_base.group_purchase_director 1 1 1 0
20 access_jikimo_message_reminder_time_group_purchase access_jikimo_message_reminder_time_group_sale_salemanager jikimo_message_reminder_time jikimo_message_notify.model_jikimo_message_reminder_time sf_base.group_purchase sf_base.group_sale_salemanager 1 1 1 0
21 access_jikimo_message_reminder_time_group_sf_stock_user access_jikimo_message_reminder_time_group_purchase jikimo_message_reminder_time jikimo_message_notify.model_jikimo_message_reminder_time sf_base.group_sf_stock_user sf_base.group_purchase 1 1 1 0
22 access_jikimo_message_reminder_time_group_sf_stock_user jikimo_message_reminder_time jikimo_message_notify.model_jikimo_message_reminder_time sf_base.group_sf_stock_user 1 1 1 0
23 access_jikimo_message_reminder_time_group_sf_order_user jikimo_message_reminder_time jikimo_message_notify.model_jikimo_message_reminder_time sf_base.group_sf_order_user 1 1 1 0
24 access_jikimo_message_reminder_time_group_sf_tool_user jikimo_message_reminder_time jikimo_message_notify.model_jikimo_message_reminder_time sf_base.group_sf_tool_user 1 1 1 0
25 access_jikimo_message_reminder_time_group_purchase_director jikimo_message_reminder_time jikimo_message_notify.model_jikimo_message_reminder_time sf_base.group_purchase_director 1 1 1 0
26
27
28
29
30
31
32

View File

@@ -219,7 +219,7 @@ class sf_production_plan(models.Model):
return num
def do_production_schedule(self, count=1):
def do_production_schedule(self):
"""
排程方法
"""
@@ -227,48 +227,46 @@ class sf_production_plan(models.Model):
if not record.production_line_id:
raise ValidationError("未选择生产线")
else:
is_schedule = self.deal_processing_schedule(record.date_planned_start, count)
if not is_schedule:
raise ValidationError("排程失败")
workorder_id_list = record.production_id.workorder_ids.ids
if record.production_id:
if record.production_id.workorder_ids:
for item in record.production_id.workorder_ids:
if item.name == 'CNC加工':
item.date_planned_finished = datetime.now() + timedelta(days=100)
item.date_planned_start = self.date_planned_start if self.date_planned_start else datetime.now()
record.sudo().production_id.plan_start_processing_time = item.date_planned_start
item.date_planned_finished = item.date_planned_start + timedelta(
minutes=record.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', 'CNC加工')]).time_cycle)
item.duration_expected = record.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', 'CNC加工')]).time_cycle
record.calculate_plan_time_before(item, workorder_id_list)
record.calculate_plan_time_after(item, workorder_id_list)
record.date_planned_start, record.date_planned_finished = \
item.date_planned_start, item.date_planned_finished
record.state = 'done'
record.date_planned_finished = record.date_planned_start + timedelta(
minutes=60) if not record.date_planned_finished else record.date_planned_finished
# record.production_id.schedule_state = '已排'
record.sudo().production_id.schedule_state = '已排'
record.sudo().production_id.process_state = '待装夹'
# self.env['sale.order'].browse(record.production_id.origin).schedule_status = 'to process'
# sale_obj = self.env['sale.order'].search([('name', '=', record.origin)])
# if 'S' in sale_obj.name:
# sale_obj.schedule_status = 'to process'
mrp_production_ids = record.production_id._get_children().ids
print('mrp_production_ids', mrp_production_ids)
for i in mrp_production_ids:
record.env['mrp.production'].sudo().browse(i).schedule_state = '已排'
# record.production_id.date_planned_start = record.date_planned_start
# record.production_id.date_planned_finished = record.date_planned_finished
record.sudo().production_id.production_line_id = record.production_line_id.id
if record.production_id.workorder_ids:
record.sudo().production_id.workorder_ids.filtered(
lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write(
{'production_line_id': record.production_line_id.id,
'plan_start_processing_time': record.date_planned_start})
if record.production_id.workorder_ids:
last_cnc_start = record.date_planned_start if record.date_planned_start else datetime.now()
for item in record.production_id.workorder_ids:
if item.name == 'CNC加工':
# 将同一个面的所有工单筛选出来
workorder_list = record.production_id.workorder_ids.filtered(lambda x: x.processing_panel == item.processing_panel)
routing_workcenter = record.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', 'CNC加工')], limit=1)
# 设置一个小的开始时间
item.date_planned_start = datetime.now() - timedelta(days=100)
item.date_planned_finished = last_cnc_start + timedelta(
minutes=routing_workcenter.time_cycle)
item.date_planned_start = last_cnc_start
record.sudo().production_id.plan_start_processing_time = item.date_planned_start
item.duration_expected = routing_workcenter.time_cycle
pre_duration , next_duration = record.calculate_plan_time(item, workorder_list)
record.date_planned_finished = item.date_planned_finished
# 计算下一个cnc工单的开始时间
last_cnc_start = workorder_list[-1].date_planned_finished + timedelta(minutes=pre_duration)
# 没有工单也能排程
record.state = 'done'
# record.production_id.schedule_state = '已排'
record.sudo().production_id.schedule_state = '已排'
record.sudo().production_id.process_state = '待装夹'
# self.env['sale.order'].browse(record.production_id.origin).schedule_status = 'to process'
# sale_obj = self.env['sale.order'].search([('name', '=', record.origin)])
# if 'S' in sale_obj.name:
# sale_obj.schedule_status = 'to process'
mrp_production_ids = record.production_id._get_children().ids
print('mrp_production_ids', mrp_production_ids)
for i in mrp_production_ids:
record.env['mrp.production'].sudo().browse(i).schedule_state = '已排'
# record.production_id.date_planned_start = record.date_planned_start
# record.production_id.date_planned_finished = record.date_planned_finished
record.sudo().production_id.production_line_id = record.production_line_id.id
if record.production_id.workorder_ids:
record.sudo().production_id.workorder_ids.filtered(
lambda b: b.routing_type == "装夹预调").workpiece_delivery_ids.write(
{'production_line_id': record.production_line_id.id,
'plan_start_processing_time': record.date_planned_start})
# record.date_planned_finished = record.date_planned_start + timedelta(days=3)
# record.state = 'done'
@@ -282,54 +280,66 @@ class sf_production_plan(models.Model):
}
# 处理是否可排程
def deal_processing_schedule(self, date_planned_start, count):
for record in self:
workcenter_ids = record.production_line_id.mrp_workcenter_ids
if not workcenter_ids:
raise UserError('生产线没有配置工作中心')
production_lines = workcenter_ids.filtered(lambda b: "自动生产线" in b.name)
if not production_lines: # 判断是否配置了自动生产线
raise UserError('生产线没有配置自动生产线')
if date_planned_start < datetime.now(): # 判断计划开始时间是否小于当前时间
raise UserError('计划开始时间不能小于当前时间')
if all(not production_line.deal_with_workcenter_calendar(date_planned_start) for production_line in
production_lines): # 判断计划开始时间是否在配置的工作中心的工作日历内
raise UserError('当前计划开始时间不能预约排程,请在工作时间内排程')
if not production_lines.deal_available_default_capacity(date_planned_start): # 判断生产线是否可排程
raise UserError('当前计划开始时间不能预约排程,生产线今日没有可排程的资源')
if not production_lines.deal_available_single_machine_capacity(date_planned_start, count): # 判断生产线是否可排程
raise UserError('当前计划开始时间不能预约排程,生产线该时间段没有可排程的资源')
def deal_processing_schedule(self, date_planned_start,):
count = len(self)
workcenter_ids = self.production_line_id.mrp_workcenter_ids
if not workcenter_ids:
raise UserError('生产线没有配置工作中心')
production_lines = workcenter_ids.filtered(lambda b: "自动生产线" in b.name)
if not production_lines: # 判断是否配置了自动生产线
raise UserError('生产线没有配置自动生产线')
if date_planned_start < datetime.now(): # 判断计划开始时间是否小于当前时间
raise UserError('计划开始时间不能小于当前时间')
if all(not production_line.deal_with_workcenter_calendar(date_planned_start) for production_line in
production_lines): # 判断计划开始时间是否在配置的工作中心的工作日历内
raise UserError('当前计划开始时间不能预约排程,请在工作时间内排程')
if not production_lines.deal_available_default_capacity(date_planned_start): # 判断生产线是否可排程
raise UserError('当前计划开始时间不能预约排程,生产线今日没有可排程的资源')
if not production_lines.deal_available_single_machine_capacity(date_planned_start, count): # 判断生产线是否可排程
raise UserError('当前计划开始时间不能预约排程,生产线该时间段没有可排程的资源')
return True
def calculate_plan_time_before(self, item, workorder_id_list):
def calculate_plan_time(self, item, workorder_list):
"""
根据CNC工单的时间去计算之前的其他工单的开始结束时间
"""
sequence = workorder_id_list.index(item.id) - 1
# 计算CNC加工之前工单的开始结束时间
for i in range(1 if sequence == 0 else sequence):
current_workorder_id = (item.id - (i + 1))
current_workorder_obj = self.env['mrp.workorder'].sudo().search(
[('id', '=', current_workorder_id)])
old_workorder_obj = self.env['mrp.workorder'].sudo().search(
[('id', '=', (current_workorder_id + 1))])
work_order = self.env['mrp.workorder'].sudo().search(
[('production_id', '=', self.production_id.id), ('id', '=', current_workorder_id)])
work_order.date_planned_finished = datetime.now() + timedelta(days=100)
work_order.date_planned_start = old_workorder_obj.date_planned_start - timedelta(
minutes=self.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', current_workorder_obj.name)]).time_cycle)
work_order.date_planned_finished = old_workorder_obj.date_planned_start
work_order.duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', current_workorder_obj.name)]).time_cycle
first_workorder = self.env['mrp.workorder'].sudo().search([('id', '=', workorder_id_list[0])])
second_workorder = self.env['mrp.workorder'].sudo().search([('id', '=', workorder_id_list[1])])
if second_workorder.date_planned_start < first_workorder.date_planned_finished:
item.date_planned_start += timedelta(minutes=60)
item.date_planned_finished += timedelta(minutes=60)
item.duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', 'CNC加工')]).time_cycle
self.calculate_plan_time_before(item, workorder_id_list)
item_position = 0
for index, workorder in enumerate(workorder_list):
if workorder.id == item.id:
item_position = index
break
routing_workcenters = self.env['mrp.routing.workcenter'].sudo().search([])
# 记录所有前序工序时长
previous_workorder_duration = 0
for i in range(item_position, -1, -1):
if i < 1:
break
current_workorder = workorder_list[i]
next_workorder = workorder_list[i - 1]
routing_workcenter = routing_workcenters.filtered(lambda x: x.name == next_workorder.name)[0]
# 设置一个小的开始时间
next_workorder.date_planned_start = datetime.now() - timedelta(days=100)
next_workorder.date_planned_finished = current_workorder.date_planned_start
next_workorder.date_planned_start = next_workorder.date_planned_finished - timedelta(
minutes=routing_workcenter.time_cycle)
next_workorder.duration_expected = routing_workcenter.time_cycle
previous_workorder_duration += routing_workcenter.time_cycle
# 记录所有后续工序时长
next_workorder_duration = 0
for i in range(item_position, len(workorder_list) - 1):
if i > len(workorder_list) - 1:
break
current_workorder = workorder_list[i]
next_workorder = workorder_list[i + 1]
routing_workcenter = routing_workcenters.filtered(lambda x: x.name == next_workorder.name)[0]
# 设置一个小的开始时间
next_workorder.date_planned_start = datetime.now() - timedelta(days=100)
next_workorder.date_planned_finished = current_workorder.date_planned_finished + timedelta(
minutes=routing_workcenter.time_cycle)
next_workorder.date_planned_start = current_workorder.date_planned_finished
next_workorder.duration_expected = routing_workcenter.time_cycle
next_workorder_duration += routing_workcenter.time_cycle
return previous_workorder_duration, next_workorder_duration
def calculate_plan_time_after(self, item, workorder_id_list):
"""

View File

@@ -31,46 +31,10 @@ class Action_Plan_All_Wizard(models.TransientModel):
# 确认排程按钮
def action_plan_all(self):
# 使用传递过来的计划ID
temp_plan_ids = self.plan_ids
self.plan_ids.production_line_id = self.production_line_id.id
self.plan_ids.date_planned_start = self.date_planned_start
# 在这里添加您的逻辑来处理这些ID
count = len(temp_plan_ids) + 1
for plan in temp_plan_ids:
count = count - 1
# 处理每个计划
# 比如更新计划状态、分配资源等
# 示例plan.state = 'scheduled'
print('处理计划:', plan.id)
# 拿到计划对象
plan_obj = self.env['sf.production.plan'].browse(plan.id)
plan_obj.production_line_id = self.production_line_id.id
plan.date_planned_start = self.date_planned_start
plan_obj.do_production_schedule(count)
# plan_obj.state = 'done'
print('处理计划:', plan.id, '完成')
# # 获取当前生产线
# production_line_id = self.production_line_id
# # 获取当前生产线的所有生产订单
# production_order_ids = self.env['mrp.production'].search([('production_line_id', '=', production_line_id.id)])
# # 获取当前生产线的所有生产订单的id
# production_order_id_list = []
# for production_order_id in production_order_ids:
# production_order_id_list.append(production_order_id.id)
# # 获取当前生产线的所有生产订单的排程状态
# production_order_plan_state_list = []
# for production_order_id in production_order_ids:
# production_order_plan_state_list.append(production_order_id.plan_state)
# # 如果当前生产线的所有生产订单的排程状态都是已排程,则报错
# if all(production_order_plan_state == '已排程' for production_order_plan_state in production_order_plan_state_list):
# raise UserError('当前生产线的所有生产订单都已排程,请勿重复排程!')
# # 如果当前生产线的所有生产订单的排程状态都是未排程,则报错
# if all(production_order_plan_state == '未排程' for production_order_plan_state in production_order_plan_state_list):
# raise UserError('当前生产线的所有生产订单都未排程,请先排程!')
# # 如果当前生产线的所有生产订单的排程状态都是已完成,则报错
# if all(production_order_plan_state == '已完成' for production_order_plan_state in production_order_plan_state_list):
# raise UserError('当前生产线的所有生产订单都已完成,请勿重复排程!')
# # 如果当前生产线的所有生产订单的排程状态都是已取消,则报错
# if all(production_order_plan_state == '已取消' for production_order_plan_state in production_order_plan_state_list):
# raise UserError('当前生产线的所有生产订单都已取消,请勿重复排程!')
# # 如果当前生产线的所有生产订单的排程状态都是已暂停,则报错
# if all(production_order_plan_state == '已暂停' for production_order_plan_state in production
# 判断能否排成
self.plan_ids.deal_processing_schedule(self.date_planned_start)
self.plan_ids.do_production_schedule()
_logger.info('处理计划: %s 完成', self.plan_ids.ids)

View File

@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
{
'name': "sf_stock",
'name': "机企猫 库存/代发货",
'summary': """
处理仓库 -代发货业务""",

View File

@@ -175,7 +175,9 @@ class MrpProduction(models.Model):
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
[('workorder_id', 'in', workorder_ids.ids), ('cutting_tool_name', 'in', invalid_tool)])
if cnc_ids:
cnc_ids.write({'tool_state': '2'})
for cnc_id in cnc_ids:
cnc_id.tool_state = '2'
# cnc_ids.write({'tool_state': '2'})
# 创建制造订单无效刀检测结果记录
for production_id in self:
for processing_panel in list(set(invalid_tool_processing_panel)):
@@ -204,12 +206,14 @@ class MrpProduction(models.Model):
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
[('workorder_id', 'in', workorder_ids.ids), ('cutting_tool_name', 'in', missing_tool_1)])
if cnc_ids:
cnc_ids.write({'tool_state': '1'})
for cnc_id in cnc_ids:
cnc_id.tool_state = '1'
# cnc_ids.write({'tool_state': '1'})
if missing_tool_2 and invalid_tool == []:
logging.info(f'库存缺刀:{missing_tool_2}')
# 调用CAM工单程序用刀计划创建方法
cnc_ids = self.env['sf.cnc.processing'].sudo().search(
[('workorder_id', 'in', workorder_ids.filtered(lambda a: a.production_id == self[0].id).ids),
[('workorder_id', 'in', workorder_ids.filtered(lambda a: a.production_id == self[0]).ids),
('cutting_tool_name', 'in', missing_tool_2)])
if cnc_ids:
logging.info('调用CAM工单程序用刀计划创建方法')