Compare commits

..

51 Commits

Author SHA1 Message Date
胡尧
b6b92ab1da ftp文件下载适配开发环境 2024-10-10 10:47:46 +08:00
胡尧
94f57629e5 增加空料架配送菜单权限 2024-10-09 17:23:03 +08:00
胡尧
e4c845a9f6 解决空料架配送不能正常下发AGV任务的问题 2024-10-09 14:08:38 +08:00
胡尧
d239509299 解决空料架配送不能正常下发AGV任务的问题 2024-10-09 13:53:49 +08:00
胡尧
457f0aa2ac 修复login页logo不显示的问题 2024-10-08 09:19:06 +08:00
胡嘉莹
84266364e3 Accept Merge Request #1381: (develop -> release/release_2.4)
Merge Request: 修改计划排程

Created By: @胡嘉莹
Accepted By: @胡嘉莹
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1381?initial=true
2024-09-29 17:25:11 +08:00
管欢
ea88d8284a Accept Merge Request #1380: (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/1380
2024-09-29 17:09:47 +08:00
guanhuan
d2ec420f57 域名获取修改 2024-09-29 17:05:42 +08:00
guanhuan
97d33adabd 域名获取修改 2024-09-29 17:03:49 +08:00
胡尧
c11f3cc66c Merge branch 'develop' into release/release_2.4 2024-09-29 16:51:41 +08:00
廖丹龙
6b4a7e35a9 Accept Merge Request #1375: (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/1375
2024-09-29 16:48:53 +08:00
guanhuan
11100c9260 域名获取修改 2024-09-29 16:47:35 +08:00
胡嘉莹
941c3ca43a Accept Merge Request #1379: (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/1379?initial=true
2024-09-29 16:47:10 +08:00
hujiaying
05f9528ca9 修改计划排程代码 2024-09-29 16:44:48 +08:00
杨金灵
b205945f65 Accept Merge Request #1378: (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/1378?initial=true
2024-09-29 16:43:54 +08:00
jinling.yang
c1dc28488a 修复待接单路径 2024-09-29 16:42:32 +08:00
jinling.yang
547d6608e6 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-09-29 15:40:50 +08:00
jinling.yang
dacb3cc076 Merge branch 'feature/消息模版初始化添加相关模版' into develop 2024-09-29 15:33:51 +08:00
胡尧
282657fbca Merge branch 'release/release_2.4' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into release/release_2.4 2024-09-29 15:32:37 +08:00
杨金灵
7e516c6f0b Accept Merge Request #1377: (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/1377
2024-09-29 15:31:28 +08:00
jinling.yang
34e2a49bef 注释部分不上的代码 2024-09-29 15:30:18 +08:00
jinling.yang
ff4bdd2f2d 还原代码 2024-09-29 15:27:27 +08:00
jinling.yang
b239fdf847 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-09-29 15:24:39 +08:00
jinling.yang
47feb4cf3c 消息模版初始化添加相关模版 2024-09-29 15:24:28 +08:00
胡嘉莹
63b732ff42 Accept Merge Request #1376: (develop -> release/release_2.4)
Merge Request: 排程计划bug合并

Created By: @胡嘉莹
Accepted By: @胡嘉莹
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1376?initial=true
2024-09-29 11:42:53 +08:00
胡嘉莹
50d63c28d6 Accept Merge Request #1374: (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/1374?initial=true
2024-09-29 10:36:32 +08:00
hujiaying
73b7ff7d1b 修改计划排程选择日期有生成量,不能排程问题 2024-09-29 10:33:19 +08:00
jinling.yang
ccdcd01372 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop
# Conflicts:
#	sf_message/__manifest__.py
2024-09-29 09:18:07 +08:00
liaodanlong
198296f0f8 价格计算 2024-09-27 18:04:39 +08:00
廖丹龙
f122343e31 Accept Merge Request #1373: (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/1373?initial=true
2024-09-27 18:02:25 +08:00
liaodanlong
82fa39f1a3 价格计算 2024-09-27 18:00:34 +08:00
廖丹龙
841e1b4ce2 Accept Merge Request #1372: (feature/销售和排程添加消息推送 -> develop)
Merge Request: d刀具标准库数据同步

Created By: @廖丹龙
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @廖丹龙
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1372?initial=true
2024-09-27 17:46:09 +08:00
liaodanlong
1ab62d7724 d刀具标准库数据同步 2024-09-27 17:43:47 +08:00
胡尧
28a46d395b Accept Merge Request #1371: (feature/程序用刀异常提醒 -> develop)
Merge Request: 增加日志

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1371
2024-09-27 15:19:21 +08:00
马广威
f8d957486b Accept Merge Request #1370: (feature/制造功能优化 -> develop)
Merge Request: 优化调整相关数据返回结构等

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1370
2024-09-27 14:47:16 +08:00
mgw
1866607967 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-09-27 14:41:41 +08:00
mgw
40efdf6f3b 隐藏status字段 2024-09-27 14:41:23 +08:00
胡尧
f910df3ce5 Accept Merge Request #1369: (feature/程序用刀异常提醒 -> develop)
Merge Request: 去掉多余的无效刀异常推送

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1369?initial=true
2024-09-27 14:39:55 +08:00
胡尧
95cc557577 Accept Merge Request #1368: (feature/程序用刀异常提醒 -> develop)
Merge Request: 程序用刀异常提醒

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1368?initial=true
2024-09-27 14:38:10 +08:00
mgw
fa78389f47 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-09-27 14:31:39 +08:00
mgw
f7381c43aa 调整url的获取方式;暂时屏蔽历史日志部分 2024-09-27 14:31:22 +08:00
mgw
76c5db61da 增加24h的oee参数 2024-09-27 14:13:57 +08:00
mgw
48ab891991 调整设备oee结构,去掉设备运行日志 2024-09-27 10:07:02 +08:00
mgw
c96ff3f5b4 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-09-27 09:20:36 +08:00
mgw
d84758232e 优化值为空时的逻辑 2024-09-27 09:20:19 +08:00
jinling.yang
27881589d4 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop
# Conflicts:
#	sf_message/__manifest__.py
#	sf_message/models/sf_message_workorder.py
2024-09-27 09:10:19 +08:00
mgw
0340563749 筛选加工时间不为空的24h数据 2024-09-26 14:04:35 +08:00
mgw
1d4188df7e 增加24h的故障时间返回 2024-09-26 11:11:46 +08:00
mgw
bd2748659a 去掉关机率 2024-09-25 17:57:24 +08:00
jinling.yang
3ee233c0bc Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-09-25 17:45:34 +08:00
jinling.yang
d63081dffa 优化销售订单+工单逾期 2024-09-25 17:45:15 +08:00
25 changed files with 541 additions and 388 deletions

View File

@@ -16,7 +16,7 @@
<!-- hide 登录页面 powerd by odoo 及管理数据库 -->
<template id="login_page_layout" inherit_id="web.login_layout" name="Login Page Layout">
<xpath expr="//div[@class='card-body']/div[last()]" position="replace"></xpath>
<!-- <xpath expr="//div[@class='card-body']/div[last()]" position="replace"></xpath> -->
</template>
<!-- 隐藏odoo版本信息 -->

View File

@@ -30,7 +30,6 @@
'views/machine_info_present.xml',
'views/delivery_record.xml',
'views/res_config_settings_views.xml',
'views/maintenance_views.xml',
],
'assets': {

View File

@@ -162,7 +162,7 @@ class Sf_Dashboard_Connect(http.Controller):
# 关机时长:初次上线时间 - 通电时间
'power_off_time': power_off_time,
# 关机率:关机时长/初次上线时间
'power_off_rate': power_off_rate,
# 'power_off_rate': power_off_rate,
'first_online_duration': first_online_duration,
# 停机时间:关机时间 - 运行时间
# 停机时长:关机时间 - 初次上线时间
@@ -187,11 +187,11 @@ class Sf_Dashboard_Connect(http.Controller):
"""
res = {'status': 1, 'message': '成功', 'data': {}}
logging.info('前端请求日志数据的参数为:%s' % kw)
# 连接数据库
conn = psycopg2.connect(**db_config)
cur = conn.cursor()
try:
# 连接数据库
conn = psycopg2.connect(**db_config)
cur = conn.cursor()
machine_list = ast.literal_eval(kw['machine_list'])
begin_time_str = kw['begin_time'].strip('"')
end_time_str = kw['end_time'].strip('"')
@@ -231,6 +231,12 @@ class Sf_Dashboard_Connect(http.Controller):
res['message'] = '前端请求日志数据失败,原因:%s' % e
return json.dumps(res)
finally:
if cur:
cur.close()
if conn:
conn.close()
@http.route('/api/logs/page_data', type='http', auth='public', methods=['GET', 'POST'],
csrf=False, cors="*")
def logs_page_data(self, **kw):
@@ -242,11 +248,10 @@ class Sf_Dashboard_Connect(http.Controller):
res = {'status': 1, 'message': '成功', 'data': {}}
logging.info('前端请求日志数据的参数为:%s' % kw)
# 连接数据库
conn = psycopg2.connect(**db_config)
cur = conn.cursor()
try:
# 连接数据库
conn = psycopg2.connect(**db_config)
cur = conn.cursor()
# 获取并解析传递的参数
machine_list = ast.literal_eval(kw.get('machine_list', '[]'))
begin_time_str = kw.get('begin_time', '').strip('"')
@@ -848,10 +853,10 @@ class Sf_Dashboard_Connect(http.Controller):
'''
sql2 = '''
SELECT DISTINCT ON (alarm_time) alarm_time, alarm_repair_time
SELECT DISTINCT ON (alarm_start_time) alarm_time, alarm_start_time
FROM device_data
WHERE device_name = %s AND alarm_time IS NOT NULL
ORDER BY alarm_time, time;
WHERE device_name = %s AND alarm_start_time IS NOT NULL
ORDER BY alarm_start_time, time;
'''
# 执行SQL命令
@@ -867,8 +872,11 @@ class Sf_Dashboard_Connect(http.Controller):
res['data'][item] = {'idle_count': row[0]}
alarm_count = []
for row in result2:
alarm_count.append(row[0])
total_alarm_time += abs(float(row[0]))
alarm_count.append(row[1])
if row[0]:
total_alarm_time += abs(float(row[0]))
else:
total_alarm_time += 0.0
if len(list(set(alarm_count))) == 1:
if list(set(alarm_count))[0] is None:
alarm_count_num = 0
@@ -1233,17 +1241,24 @@ class Sf_Dashboard_Connect(http.Controller):
machine_list = ast.literal_eval(kw['machine_list'])
time_threshold = datetime.now() - timedelta(days=1)
alarm_last_24_time = 0.0
def fetch_result_as_dict(cursor):
"""辅助函数:将查询结果转为字典"""
columns = [desc[0] for desc in cursor.description]
return dict(zip(columns, cursor.fetchone())) if cursor.rowcount != 0 else None
# 获取当前时间的时间戳
current_timestamp = datetime.now().timestamp()
for item in machine_list:
euipment_obj = request.env['maintenance.equipment'].sudo().search([('code', '=', item)])
# 机床上线时间段
first_online_duration = current_timestamp - euipment_obj.first_online_time.timestamp()
with conn.cursor() as cur:
cur.execute("""
SELECT * FROM device_data
WHERE device_name = %s
AND device_state != '离线'
AND device_state != '离线' AND process_time IS NOT NULL
ORDER BY time DESC
LIMIT 1;
""", (item,))
@@ -1252,18 +1267,52 @@ class Sf_Dashboard_Connect(http.Controller):
cur.execute("""
SELECT * FROM device_data
WHERE device_name = %s
AND device_state != '离线' AND time >= %s
AND device_state != '离线' AND time >= %s AND process_time IS NOT NULL
ORDER BY time ASC
LIMIT 1;
""", (item, time_threshold))
last_24_time = fetch_result_as_dict(cur)
with conn.cursor() as cur:
cur.execute("""
SELECT COUNT(*)
FROM (
SELECT DISTINCT ON (idle_start_time) idle_start_time
FROM device_data
WHERE device_name = %s AND idle_start_time IS NOT NULL AND time >= %s
ORDER BY idle_start_time, time
) subquery;
""", (item, time_threshold))
idle_count = cur.fetchone()[0]
alarm_last_24_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 AND time >= %s;
""", (item, time_threshold))
results = cur.fetchall()
for result in results:
alarm_last_24_nums.append(result[1])
if result[0]:
if float(result[0]) >= 1000:
continue
alarm_last_24_time += float(result[0])
else:
alarm_last_24_time += 0.0
# 返回数据
res['data'][item] = {
'wait_time': last_all_time['run_time'] if last_all_time['run_time'] is not None else 0,
'cut_time': last_all_time['process_time'] if last_all_time['process_time'] is not None else 0,
'cut_24_time': last_24_time['process_time'] if last_24_time['process_time'] is not None else 0,
'power_on_time': last_all_time['power_on_time'] if last_all_time['power_on_time'] is not None else 0,
'power_on_24_time': last_24_time['power_on_time'] if last_24_time['power_on_time'] is not None else 0
'power_on_24_time': last_24_time['power_on_time'] if last_24_time['power_on_time'] is not None else 0,
'alarm_last_24_time': alarm_last_24_time,
'alarm_last_24_nums': len(list(set(alarm_last_24_nums))),
'idle_count': idle_count,
'first_online_time': first_online_duration,
}
conn.close()

View File

@@ -285,26 +285,6 @@ class Machine_ftp(models.Model):
# # 开动率
run_rate = fields.Char('开动率', readonly=True)
# 同步CNC设备到oee
def sync_oee(self):
"""
同步CNC设备到oee
:return:
"""
for record in self:
record.ensure_one()
cnc_oee_dict = {
'equipment_id': record.id,
'type_id': record.type_id.id,
'machine_tool_picture': record.machine_tool_picture,
'equipment_code': record.code,
'function_type': record.function_type,
}
if self.env['maintenance.equipment.oee.logs'].search([('equipment_id', '=', record.id)]):
self.env['maintenance.equipment.oee.logs'].write(cnc_oee_dict)
else:
self.env['maintenance.equipment.oee.logs'].create(cnc_oee_dict)
class WorkCenterBarcode(models.Model):
"""

View File

@@ -14,7 +14,7 @@
<group string='状态监控'>
<group>
<!-- <field name="timestamp"/> -->
<field name="status"/>
<!-- <field name="status"/> -->
<field name="run_status"/>
<field name="run_time"/>
<field name="system_date"/>

View File

@@ -1,17 +0,0 @@
<?xml version="1.0"?>
<odoo>
<!-- 修改设备列表视图-->
<record id="sf_machine_hr_equipment_view_tree_inherit" model="ir.ui.view">
<field name="name">sf.machine.hr.equipment.view.tree.inherit</field>
<field name="model">maintenance.equipment</field>
<field name="inherit_id" ref="maintenance.hr_equipment_view_tree"/>
<field name="arch" type="xml">
<xpath expr="//tree" position="inside">
<header>
<button name="sync_oee" type="object" string="同步设备至OEE"/>
</header>
</xpath>
</field>
</record>
</odoo>

View File

@@ -1,4 +1,5 @@
# -*- coding: utf-8 -*-
import re
import json
import datetime
import requests
@@ -6,6 +7,42 @@ from odoo import api, fields, models, _
from odoo.exceptions import UserError
def convert_to_seconds(time_str):
# 修改正则表达式,使 H、M、S 部分可选
if time_str is None:
return 0
pattern = r"(?:(\d+)H)?(?:(\d+)M)?(?:(\d+)S)?"
match = re.match(pattern, time_str)
if match:
# 提取各时间单位如果某个单位缺失则默认设为0
hours = int(match.group(1)) if match.group(1) else 0
minutes = int(match.group(2)) if match.group(2) else 0
seconds = int(match.group(3)) if match.group(3) else 0
# 计算总秒数
total_seconds = hours * 3600 + minutes * 60 + seconds
if total_seconds == 0:
# return None
pattern = r"(?:(\d+)小时)?(?:(\d+)分钟)?(?:(\d+)秒)?"
match = re.match(pattern, time_str)
if match:
# 提取各时间单位如果某个单位缺失则默认设为0
hours = int(match.group(1)) if match.group(1) else 0
minutes = int(match.group(2)) if match.group(2) else 0
seconds = int(match.group(3)) if match.group(3) else 0
# 计算总秒数
total_seconds = hours * 3600 + minutes * 60 + seconds
return total_seconds
else:
return None
return total_seconds
class SfMaintenanceEquipmentOEE(models.Model):
_name = 'maintenance.equipment.oee'
_description = '设备OEE'
@@ -22,18 +59,27 @@ class SfMaintenanceEquipmentOEE(models.Model):
[("正常", "正常"), ("故障停机", "故障停机"), ("计划维保", "计划维保"), ("空闲", "空闲"),
("封存(报废)", "封存(报废)")],
default='正常', string="机床状态", related='equipment_id.state')
run_time = fields.Float('加工时长(h)')
equipment_time = fields.Float('开机时长(h)')
done_nums = fields.Integer('加工件数')
utilization_rate = fields.Char('可用率')
fault_time = fields.Float('故障时长')
fault_nums = fields.Integer('故障次数')
# 故障率
fault_rate = fields.Char('故障率')
online_time = fields.Char('开机时长(小时)', reaonly='True')
offline_time = fields.Char('关机时长(小时)', reaonly='True')
idle_nums = fields.Integer('待机次数', reaonly='True')
# 待机时长
idle_time = fields.Char('待机时长(小时)', reaonly='True')
# 待机率
idle_rate = fields.Char('待机率(%)', reaonly='True')
work_time = fields.Char('加工时长(小时)', reaonly='True')
work_rate = fields.Char('可用率(%)', reaonly='True')
fault_time = fields.Char('故障时长(小时)', reaonly='True')
fault_rate = fields.Char('故障率(%)', reaonly='True')
fault_nums = fields.Integer('故障次数', reaonly='True')
# 设备故障日志
sf_maintenance_logs_ids = fields.One2many('sf.maintenance.logs', 'maintenance_equipment_oee_id', '设备故障日志',
related='equipment_id.sf_maintenance_logs_ids')
oee_logs = fields.One2many('maintenance.equipment.oee.logs', 'equipment_oee_id', string='运行日志')
day_logs_detail = fields.Html('日运行日志详情')
history_logs_detail = fields.Html('历史运行日志详情')
@@ -42,8 +88,13 @@ class SfMaintenanceEquipmentOEE(models.Model):
# 获取日志详情
def get_day_logs(self):
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
print(base_url)
config = self.env['ir.config_parameter'].sudo()
url = 'http://172.16.10.112:8069/api/logs/list'
# url = 'http://172.16.10.112:8069/api/logs/list'
# url_time = 'http://localhost:9069/api/RunningTimeDetail'
url = base_url + '/api/logs/list'
url_time = base_url + '/api/RunningTimeDetail'
machine_list = [self.equipment_code]
begin_time = datetime.datetime.now().strftime('%Y-%m-%d') + ' 00:00:00'
end_time = datetime.datetime.now().strftime('%Y-%m-%d') + ' 23:59:59'
@@ -55,11 +106,41 @@ class SfMaintenanceEquipmentOEE(models.Model):
"end_time": end_time
}
data_time = {
"machine_list": str(machine_list)
}
print(data)
# 发送POST请求
response = requests.post(url, json={}, data=data)
print(response.json()) # 输出服务器返回的响应
response_time = requests.post(url_time, json={}, data=data_time)
# print(response.json()) # 输出服务器返回的响应
print(response_time.json())
if response_time.status_code == 200:
result_time = response_time.json()
real_dict = result_time['data'][self.equipment_code]
print('=', result_time)
if result_time['status'] == 1:
self.online_time = round((convert_to_seconds(real_dict['power_on_time']) - convert_to_seconds(
real_dict['power_on_24_time'])) / 3600, 2)
self.work_time = round(
(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)
self.idle_time = float(self.online_time) - float(
self.work_time) if self.online_time and self.work_time else 0
self.idle_rate = round(
float(self.idle_time) / (float(self.online_time) if self.online_time else 1) * 100, 2)
self.work_rate = round(
float(self.work_time) / (float(self.online_time) if self.online_time else 1) * 100, 2)
self.fault_time = (float(real_dict['alarm_last_24_time']) if real_dict[
'alarm_last_24_time'] else 0) / 3600
self.fault_rate = round(
float(self.fault_time) / (float(self.online_time) if self.online_time else 1) * 100, 2)
self.fault_nums = real_dict['alarm_last_24_nums']
self.idle_nums = real_dict['idle_count']
if response.status_code == 200:
result = response.json()
print('============', result)
@@ -94,7 +175,10 @@ class SfMaintenanceEquipmentOEE(models.Model):
# 获取历史日志详情
def get_history_logs(self):
config = self.env['ir.config_parameter'].sudo()
url = 'http://172.16.10.112:8069/api/logs/list'
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
# url = 'http://172.16.10.112:8069/api/logs/list'
url = base_url + '/api/logs/list'
url_time = base_url + '/api/RunningTimeDetail'
machine_list = [self.equipment_code]
if not self.begin_time:
raise UserError('请选择开始时间')

View File

@@ -67,6 +67,3 @@ access_sf_cutting_tool_type_admin_sf_group_equipment_user,sf_cutting_tool_type_a
access_sf_cutting_tool_type_group_purchase_director_sf_group_equipment_user,sf_cutting_tool_type_group_purchase_director,sf_base.model_sf_cutting_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
access_sf_cutting_tool_type_group_sale_director_sf_group_equipment_user,sf_cutting_tool_type_group_sale_director,sf_base.model_sf_cutting_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
access_sf_cutting_tool_type_group_plan_director_sf_group_equipment_user,sf_cutting_tool_type_group_plan_director,sf_base.model_sf_cutting_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
access_maintenance_equipment_oee_logs,maintenance_equipment_oee_logs,model_maintenance_equipment_oee_logs,sf_maintenance.sf_group_equipment_manager,1,1,1,1
access_maintenance_equipment_oee_log_detail,maintenance_equipment_oee_log_detail,model_maintenance_equipment_oee_log_detail,sf_maintenance.sf_group_equipment_manager,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
67
68
69

View File

@@ -8,13 +8,13 @@
<field name="arch" type="xml">
<tree>
<field name="equipment_id"/>
<field name="equipment_time"/>
<field name="run_time"/>
<field name="done_nums"/>
<field name="utilization_rate"/>
<field name="online_time"/>
<field name="work_time"/>
<field name="work_rate"/>
<field name="fault_time"/>
<field name="fault_nums"/>
<field name="fault_rate"/>
</tree>
</field>
</record>
@@ -37,19 +37,48 @@
<group>
<group>
<field name="type_id" readonly="1"/>
<field name="equipment_code"/>
<field name="equipment_time"/>
<field name="run_time"/>
<field name="done_nums"/>
<field name="utilization_rate"/>
<field name="fault_time"/>
<field name="fault_nums"/>
<group>
<field name="equipment_id" domain="[('name','ilike','加工中心')]"/>
<field name="type_id"/>
<field name="state"/>
<field name="equipment_code"/>
</group>
</group>
<group>
<field name="machine_tool_picture" widget="image" readonly="1"/>
<group>
<!-- <field name="state" nolabel="1"/> -->
<!-- <field name="state" string=""/> -->
</group>
<group>
<field name="machine_tool_picture" widget="image" nolabel="1"/>
</group>
</group>
</group>
<group>
<group>
<group>
<field name="online_time" readonly="1"/>
<field name="offline_time" readonly="1"/>
<field name="fault_rate" readonly="1"/>
</group>
<group>
<field name="idle_nums" readonly="1"/>
<field name="fault_time" readonly="1"/>
<field name="fault_nums" readonly="1"/>
</group>
</group>
<group>
<group>
<field name="idle_time"/>
<field name="idle_rate"/>
</group>
<group>
<field name="work_time"/>
<field name="work_rate"/>
</group>
</group>
</group>
<notebook>
<page string="24H日志详情">
<group>
@@ -81,28 +110,28 @@
<!-- </div> -->
<!-- </group> -->
</page>
<page string="历史日志详情">
<group>
<group>
<group>
<field name="begin_time"/>
</group>
<group>
<field name="end_time"/>
</group>
</group>
<group>
<group>
<button name="get_history_logs" type="object" string="查看历史日志" t-attf-style="white-space:nowrap;"/>
</group>
<group>
<button name="download_history_logs" type="object" string="下载历史日志" t-attf-style="white-space:nowrap;"/>
</group>
</group>
<!-- <page string="历史日志详情"> -->
<!-- <group> -->
<!-- <group> -->
<!-- <group> -->
<!-- <field name="begin_time"/> -->
<!-- </group> -->
<!-- <group> -->
<!-- <field name="end_time"/> -->
<!-- </group> -->
<!-- </group> -->
<!-- <group> -->
<!-- <group> -->
<!-- <button name="get_history_logs" type="object" string="查看历史日志" t-attf-style="white-space:nowrap;"/> -->
<!-- </group> -->
<!-- <group> -->
<!-- <button name="download_history_logs" type="object" string="下载历史日志" t-attf-style="white-space:nowrap;"/> -->
<!-- </group> -->
<!-- </group> -->
</group>
<field name="history_logs_detail"/>
</page>
<!-- </group> -->
<!-- <field name="history_logs_detail"/> -->
<!-- </page> -->
</notebook>
</sheet>
</form>

View File

@@ -105,249 +105,6 @@
</field>
</record>
<!-- 设备运行日志 -->
<record id="view_maintenance_logs_run_tree" model="ir.ui.view">
<field name="name">maintenance.logs.run.tree</field>
<field name="model">maintenance.equipment.oee.logs</field>
<field name="arch" type="xml">
<tree>
<field name="equipment_id"/>
</tree>
</field>
</record>
<record id="view_maintenance_logs_run_form" model="ir.ui.view">
<field name="name">maintenance.logs.run.form</field>
<field name="model">maintenance.equipment.oee.logs</field>
<field name="arch" type="xml">
<!-- <form string="设备运行日志"> -->
<!-- <header> -->
<!-- <field name="equipment_id" readonly="1"/> -->
<!-- </header> -->
<!-- <sheet> -->
<!-- <div class="oe_title"> -->
<!-- <h1> -->
<!-- <field name="start_time" readonly="1"/> -->
<!-- </h1> -->
<!-- </div> -->
<!-- <group> -->
<!-- <group> -->
<!-- <field name="stop_time" readonly="1"/> -->
<!-- <field name="duration" readonly="1"/> -->
<!-- <field name="oee" readonly="1"/> -->
<!-- </group> -->
<!-- <group> -->
<!-- <field name="note"/> -->
<!-- </group> -->
<!-- </group> -->
<!-- </sheet> -->
<!-- </form> -->
<form string="设备运行日志">
<!-- <header> -->
<!-- <field name="name" readonly="1"/> -->
<!-- </header> -->
<sheet>
<div class="oe_title">
<h1>
<field name="name"/>
</h1>
</div>
<group>
<group>
<group>
<field name="equipment_id" domain="[('name','ilike','加工中心')]"/>
<field name="type_id"/>
<field name="state"/>
<field name="equipment_code"/>
<field name="function_type"/>
</group>
</group>
<group>
<group>
<!-- <field name="state" nolabel="1"/> -->
<field name="state" string=""/>
</group>
<group>
<field name="machine_tool_picture" widget="image" nolabel="1"/>
</group>
</group>
</group>
<group>
<group>
<group>
<field name="online_time" readonly="1"/>
<field name="offline_time" readonly="1"/>
<field name="fault_rate" readonly="1"/>
</group>
<group>
<field name="offline_nums" readonly="1"/>
<field name="fault_time" readonly="1"/>
<field name="fault_nums" readonly="1"/>
</group>
</group>
<group>
<group>
<field name="idle_time"/>
<field name="idle_rate"/>
</group>
<group>
<field name="work_time"/>
<field name="work_rate"/>
</group>
</group>
</group>
<notebook>
<page string="24H日志详情">
<!-- 筛选出24小时内的日志 -->
<!-- <field name="detail_ids" domain="[('time','&lt;',(datetime.datetime.now() - datetime.timedelta(days=1)).strftime('%Y-%m-%d %H:%M:%S'))]"> -->
<field name="detail_ids" domain="[('state','ilike','加工')]">
<tree>
<!-- <field name="sequence"/> -->
<field name="time"/>
<field name="state"/>
<field name="production_name"/>
</tree>
<!-- <form> -->
<!-- <field name="sequence"/> -->
<!-- <field name="time"/> -->
<!-- <field name="state"/> -->
<!-- <field name="production_id"/> -->
<!-- </form> -->
</field>
</page>
<page string="历史日志详情">
<field name="detail_ids">
<tree>
<!-- <field name="sequence"/> -->
<field name="time"/>
<field name="state"/>
<field name="production_name"/>
</tree>
<!-- <form> -->
<!-- <field name="sequence"/> -->
<!-- <field name="time"/> -->
<!-- <field name="state"/> -->
<!-- <field name="production_id"/> -->
<!-- </form> -->
</field>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<!-- <record id="view_maintenance_logs_run_search" model="ir.ui.view"> -->
<!-- <field name="name">maintenance.logs.run.search</field> -->
<!-- <field name="model">maintenance.equipment.oee.logs</field> -->
<!-- <field name="arch" type="xml"> -->
<!-- <search> -->
<!-- <field name="equipment_id"/> -->
<!-- <field name="start_time"/> -->
<!-- <field name="stop_time"/> -->
<!-- <field name="duration"/> -->
<!-- <field name="oee"/> -->
<!-- <field name="note"/> -->
<!-- </search> -->
<!-- </field> -->
<!-- </record> -->
<!-- 设备运行日志详情 -->
<record id="view_maintenance_logs_run_detail_tree" model="ir.ui.view">
<field name="name">maintenance.logs.run.detail.tree</field>
<field name="model">maintenance.equipment.oee.log.detail</field>
<field name="arch" type="xml">
<tree>
<!-- <field name="sequence"/> -->
<field name="time"/>
<field name="state"/>
<field name="production_name"/>
</tree>
</field>
</record>
<record id="view_maintenance_logs_run_detail_form" model="ir.ui.view">
<field name="name">maintenance.logs.run.detail.form</field>
<field name="model">maintenance.equipment.oee.log.detail</field>
<field name="arch" type="xml">
<form string="设备运行日志详情">
<sheet>
<group>
<group>
<field name="state"/>
<!-- <field name="production_id"/> -->
</group>
<group>
<!-- <field name="sequence"/> -->
<field name="time"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
<!-- <record id="view_maintenance_logs_run_detail_search" model="ir.ui.view"> -->
<!-- <field name="name">maintenance.logs.run.detail.search</field> -->
<!-- <field name="model">maintenance.equipment.oee.logs.detail</field> -->
<!-- <field name="arch" type="xml"> -->
<!-- <search> -->
<!-- <field name="equipment_id"/> -->
<!-- <field name="start_time"/> -->
<!-- <field name="stop_time"/> -->
<!-- <field name="duration"/> -->
<!-- <field name="oee"/> -->
<!-- <field name="note"/> -->
<!-- </search> -->
<!-- </field> -->
<!-- </record> -->
<!-- 设备运行日志详情action -->
<!-- <record id="action_maintenance_logs_run_detail" model="ir.actions.act_window"> -->
<!-- <field name="name">设备运行日志详情</field> -->
<!-- <field name="type">ir.actions.act_window</field> -->
<!-- <field name="res_model">maintenance.equipment.oee.logs.detail</field> -->
<!-- <field name="view_mode">tree,form</field> -->
<!-- <field name="view_id" ref="view_maintenance_logs_run_detail_tree"/> -->
<!-- <field name="help" type="html"> -->
<!-- <p class="oe_view_nocontent_create"> -->
<!-- 设备运行日志详情 -->
<!-- </p> -->
<!-- </field> -->
<!-- -->
<!-- </record> -->
<record id="action_maintenance_logs_run" model="ir.actions.act_window">
<field name="name">设备运行日志</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">maintenance.equipment.oee.logs</field>
<!-- <field name="search_view_id" ref="view_maintenance_logs_run_search"/> -->
<field name="view_mode">tree,form</field>
<!-- <field name="view_mode">form</field> -->
<field name="view_id" ref="view_maintenance_logs_run_tree"/>
<field name="help" type="html">
<p class="oe_view_nocontent_create">
设备运行日志
</p>
</field>
</record>
<menuitem name="设备运行日志" id="menu_maintenance_logs_run" parent="maintenance.menu_m_request"
sequence="10" action="action_maintenance_logs_run"/>
<!-- Action -->
<record id="action_maintenance_logs" model="ir.actions.act_window">

View File

@@ -1,4 +1,5 @@
import datetime
import logging
from datetime import timedelta, time
from collections import defaultdict
from odoo import fields, models, api
@@ -6,6 +7,8 @@ from odoo.addons.resource.models.resource import Intervals
from odoo.exceptions import UserError, ValidationError
import math
_logger = logging.getLogger(__name__)
class ResWorkcenter(models.Model):
_name = "mrp.workcenter"
@@ -163,6 +166,19 @@ class ResWorkcenter(models.Model):
else:
record.effective_working_hours_day = 0
# 计算传入时间日有效工作时长
def _compute_effective_working_hours_day1(self, date):
effective_working_hours_day = 0
for record in self:
attendance_ids = [p for p in record.resource_calendar_id.attendance_ids if
p.dayofweek == self.get_current_day_of_week(date)]
if attendance_ids:
for attendance_id in attendance_ids:
if attendance_id.hour_from and attendance_id.hour_to:
effective_working_hours_day += attendance_id.hour_to - attendance_id.hour_from
return effective_working_hours_day
# 获取传入时间是星期几
def get_current_day_of_week(self, datetime):
day_num = datetime.weekday()
@@ -211,7 +227,12 @@ class ResWorkcenter(models.Model):
('state', 'not in', ['draft', 'cancel'])])
if plan_ids:
sum_qty = sum([p.product_qty for p in plan_ids])
if sum_qty >= self.default_capacity:
date_planned_working_hours = self._compute_effective_working_hours_day1(date_planned)
default_capacity = round(
self.production_line_hour_capacity * date_planned_working_hours, 2)
_logger.info('排程日期:%s,计划数量:%s,日产能:%s,日工时:%s' % (
date_planned, sum_qty, default_capacity, date_planned_working_hours))
if sum_qty >= default_capacity:
return False
return True

View File

@@ -1,5 +1,5 @@
import re
import json
import json, tempfile
import logging
import base64
import urllib.parse
@@ -1527,7 +1527,8 @@ class CNCprocessing(models.Model):
# 将FTP的多面的程序单文件下载到临时目录
def download_file_tmp(self, production_no, processing_panel):
remotepath = os.path.join('/home/ftp/ftp_root/NC', production_no, 'return', processing_panel)
serverdir = os.path.join('/tmp', production_no, 'return', processing_panel)
tmp_path = tempfile.gettempdir()
serverdir = os.path.join(tmp_path, production_no, 'return', processing_panel)
ftp_resconfig = self.env['res.config.settings'].get_values()
ftp = FtpController(str(ftp_resconfig['ftp_host']), int(ftp_resconfig['ftp_port']), ftp_resconfig['ftp_user'],
ftp_resconfig['ftp_password'])
@@ -1826,6 +1827,11 @@ class WorkPieceDelivery(models.Model):
return is_free
else:
raise UserError("接驳站暂未反馈站点实时状态,请稍后再试")
def delivery_avg(self):
is_agv_task_dispatch = self.env['ir.config_parameter'].sudo().get_param('is_agv_task_dispatch')
if is_agv_task_dispatch:
self._delivery_avg()
# 配送至avg小车
def _delivery_avg(self):
@@ -1886,7 +1892,7 @@ class WorkPieceDelivery(models.Model):
logging.info('delivery_item-name:%s' % delivery_item.name)
delivery_item.write({
'task_delivery_time': fields.Datetime.now(),
'status': '待配送'
'status': '已下发'
})
if delivery_item.type == "上产线":
delivery_item.workorder_id.write({'is_delivery': True})

View File

@@ -797,7 +797,7 @@
<field name="feeder_station_start_id" readonly="1" force_save="1"/>
<!-- <field name="type" readonly="1"/>-->
<field name="feeder_station_destination_id" readonly="1" force_save="1"/>
<button name="button_delivery" type="object" string="配送" class="oe_highlight"/>
<button name="delivery_avg" type="object" string="配送" class="oe_highlight"/>
<button name="action_delivery_history" type="object" class="btn btn-link text-info" icon="fa-history"
string="历史"/>
</tree>

View File

@@ -11,10 +11,12 @@
""",
'category': 'sf',
'website': 'https://www.sf.jikimo.com',
'depends': ['sale', 'purchase', 'sf_plan', 'jikimo_message_notify','stock', 'sf_tool_management', 'sf_manufacturing', 'sf_hr'],
'depends': ['sale', 'purchase', 'sf_plan', 'jikimo_message_notify', 'stock'],
'data': [
'data/bussiness_node.xml',
# 'data/cron_data.xml',
'data/template_data.xml',
],
'test': [
],

View File

@@ -1,6 +1,7 @@
<?xml version="1.0" ?>
<odoo>
<data noupdate="1">
<!--销售订单-->
<record id="bussiness_pending_order" model="jikimo.message.bussiness.node">
<field name="name">待接单</field>
<field name="model">sale.order</field>
@@ -10,6 +11,17 @@
<field name="name">确认接单</field>
<field name="model">sale.order</field>
</record>
<!-- <record id="bussiness_sale_order_overdue_warning" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">销售订单逾期预警</field>-->
<!-- <field name="model">sale.order</field>-->
<!-- </record>-->
<!-- <record id="bussiness_sale_order_overdue" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">销售订单已逾期</field>-->
<!-- <field name="model">sale.order</field>-->
<!-- </record>-->
<record id="transfer_inventory" model="jikimo.message.bussiness.node">
<field name="name">调拨入库</field>
<field name="model">stock.picking</field>
@@ -30,9 +42,48 @@
<field name="name">坯料发料提醒</field>
<field name="model">stock.picking</field>
</record>
<!--工单-->
<record id="bussiness_mrp_workorder_remind" model="jikimo.message.bussiness.node">
<field name="name">工单已下发通知</field>
<field name="model">mrp.workorder</field>
</record>
<!-- <record id="bussiness_mrp_workorder_pre_overdue_warning" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">装夹预调工单逾期预警</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<!-- <record id="bussiness_mrp_workorder_pre_overdue" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">装夹预调工单已逾期</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<!-- <record id="bussiness_mrp_workorder_cnc_overdue_warning" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">CNC工单逾期预警</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<!-- <record id="bussiness_mrp_workorder_cnc_overdue" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">CNC工单已逾期</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<!-- <record id="bussiness_mrp_workorder_unclamp_overdue_warning" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">解除装夹工单逾期预警</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<!-- <record id="bussiness_mrp_workorder_unclamp_overdue" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">解除装夹工单已逾期</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<!-- <record id="bussiness_mrp_workorder_surface_overdue_warning" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">表面工艺工单逾期预警</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
<!-- <record id="bussiness_mrp_workorder_surface_overdue" model="jikimo.message.bussiness.node">-->
<!-- <field name="name">表面工艺工单已逾期</field>-->
<!-- <field name="model">mrp.workorder</field>-->
<!-- </record>-->
</data>
</odoo>

View File

@@ -0,0 +1,160 @@
<odoo>
<data noupdate="1">
<record model="ir.cron" id="ir_cron_sale_order_overdue_warning">
<field name="name">销售订单逾期预警</field>
<field name="model_id" ref="model_sale_order"/>
<field name="state">code</field>
<field name="code">model._overdue_warning_func()</field>
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="True"/>
</record>
<record model="ir.cron" id="ir_cron_sale_order_overdue">
<field name="name">销售订单已逾期</field>
<field name="model_id" ref="model_sale_order"/>
<field name="state">code</field>
<field name="code">model._overdue_func()</field>
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="True"/>
</record>
<record model="ir.cron" id="ir_cron_mrp_workorder_overdue_warning">
<field name="name">装夹预调工单逾期预警</field>
<field name="model_id" ref="model_mrp_workorder"/>
<field name="state">code</field>
<field name="code">model._overdue_warning_func()</field>
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="True"/>
</record>
<record model="ir.cron" id="ir_cron_mrp_workorder_overdue">
<field name="name">工单已逾期</field>
<field name="model_id" ref="model_mrp_workorder"/>
<field name="state">code</field>
<field name="code">model._overdue_func()</field>
<field name="interval_number">1</field>
<field name="interval_type">minutes</field>
<field name="numbercall">-1</field>
<field name="doall" eval="False"/>
<field name="user_id" ref="base.user_root"/>
<field name="active" eval="True"/>
</record>
<!-- -->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_overdue_warning">-->
<!-- <field name="name">工单逾期预警</field>-->
<!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">model._overdue_warning_func()</field>-->
<!-- <field name="interval_number">1</field>-->
<!-- <field name="interval_type">minutes</field>-->
<!-- <field name="numbercall">-1</field>-->
<!-- <field name="doall" eval="False"/>-->
<!-- <field name="user_id" ref="base.user_root"/>-->
<!-- <field name="active" eval="True"/>-->
<!-- </record>-->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_pre_overdue">-->
<!-- <field name="name">工单已逾期</field>-->
<!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">model._overdue_func()</field>-->
<!-- <field name="interval_number">1</field>-->
<!-- <field name="interval_type">minutes</field>-->
<!-- <field name="numbercall">-1</field>-->
<!-- <field name="doall" eval="False"/>-->
<!-- <field name="user_id" ref="base.user_root"/>-->
<!-- <field name="active" eval="True"/>-->
<!-- </record>-->
<!-- -->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_pre_overdue_warning">-->
<!-- <field name="name">工单逾期预警</field>-->
<!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">model._overdue_warning_func()</field>-->
<!-- <field name="interval_number">1</field>-->
<!-- <field name="interval_type">minutes</field>-->
<!-- <field name="numbercall">-1</field>-->
<!-- <field name="doall" eval="False"/>-->
<!-- <field name="user_id" ref="base.user_root"/>-->
<!-- <field name="active" eval="True"/>-->
<!-- </record>-->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_pre_overdue">-->
<!-- <field name="name">工单已逾期</field>-->
<!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">model._overdue_func()</field>-->
<!-- <field name="interval_number">1</field>-->
<!-- <field name="interval_type">minutes</field>-->
<!-- <field name="numbercall">-1</field>-->
<!-- <field name="doall" eval="False"/>-->
<!-- <field name="user_id" ref="base.user_root"/>-->
<!-- <field name="active" eval="True"/>-->
<!-- </record>-->
<!-- -->
<!-- -->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_pre_overdue_warning">-->
<!-- <field name="name">工单逾期预警</field>-->
<!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">model._overdue_warning_func()</field>-->
<!-- <field name="interval_number">1</field>-->
<!-- <field name="interval_type">minutes</field>-->
<!-- <field name="numbercall">-1</field>-->
<!-- <field name="doall" eval="False"/>-->
<!-- <field name="user_id" ref="base.user_root"/>-->
<!-- <field name="active" eval="True"/>-->
<!-- </record>-->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_pre_overdue">-->
<!-- <field name="name">工单已逾期</field>-->
<!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">model._overdue_func()</field>-->
<!-- <field name="interval_number">1</field>-->
<!-- <field name="interval_type">minutes</field>-->
<!-- <field name="numbercall">-1</field>-->
<!-- <field name="doall" eval="False"/>-->
<!-- <field name="user_id" ref="base.user_root"/>-->
<!-- <field name="active" eval="True"/>-->
<!-- </record>-->
<!-- -->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_pre_overdue_warning">-->
<!-- <field name="name">工单逾期预警</field>-->
<!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">model._overdue_warning_func()</field>-->
<!-- <field name="interval_number">1</field>-->
<!-- <field name="interval_type">minutes</field>-->
<!-- <field name="numbercall">-1</field>-->
<!-- <field name="doall" eval="False"/>-->
<!-- <field name="user_id" ref="base.user_root"/>-->
<!-- <field name="active" eval="True"/>-->
<!-- </record>-->
<!-- <record model="ir.cron" id="ir_cron_mrp_workorder_pre_overdue">-->
<!-- <field name="name">工单已逾期</field>-->
<!-- <field name="model_id" ref="model_mrp_workorder"/>-->
<!-- <field name="state">code</field>-->
<!-- <field name="code">model._overdue_func()</field>-->
<!-- <field name="interval_number">1</field>-->
<!-- <field name="interval_type">minutes</field>-->
<!-- <field name="numbercall">-1</field>-->
<!-- <field name="doall" eval="False"/>-->
<!-- <field name="user_id" ref="base.user_root"/>-->
<!-- <field name="active" eval="True"/>-->
<!-- </record>-->
</data>
</odoo>

View File

@@ -1,6 +1,32 @@
<?xml version="1.0" ?>
<odoo>
<data noupdate="1">
<record id="template_pending_order" model="jikimo.message.template">
<field name="name">待接单</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="model">sale.order</field>
<field name="bussiness_node_id" ref="bussiness_pending_order"/>
<field name="msgtype">markdown</field>
<field name="urgency">normal</field>
<field name="content">### 待接单提醒:
单号:销售订单[{{name}}]({{url}})
事项:请确认是否接单。
</field>
</record>
<record id="template_to_be_confirm" model="jikimo.message.template">
<field name="name">确认接单</field>
<field name="model_id" ref="sale.model_sale_order"/>
<field name="model">sale.order</field>
<field name="bussiness_node_id" ref="bussiness_to_be_confirm"/>
<field name="msgtype">markdown</field>
<field name="urgency">normal</field>
<field name="content">### 待排程提醒:
单号:产品[{{product_id}}]({{url}})
事项:{{mrp_production_count}}个制造订单待计划排程
</field>
</record>
<record id="template_material_purchase_remind" model="jikimo.message.template">
<field name="name">坯料采购提醒</field>
<field name="model_id" ref="purchase.model_purchase_order"/>

View File

@@ -19,9 +19,7 @@ class SFMessagePurchase(models.Model):
return contents
def request_url(self, id):
we_config_info = self.env['we.config'].sudo().search([], limit=1)
redirect_domain = self.env['we.app'].sudo().search([('id', '=', we_config_info.odoo_app_id.id)]).redirect_domain
full_url = 'https://%s/' % redirect_domain
url = self.env['ir.config_parameter'].get_param('web.base.url')
action_id = self.env.ref('purchase.purchase_form_action').id
menu_id = self.env['ir.model.data'].search([('name', '=', 'module_website_payment')]).id
# 查询参数
@@ -31,5 +29,5 @@ class SFMessagePurchase(models.Model):
# 拼接查询参数
query_string = urlencode(params)
# 拼接URL
full_url = full_url + "web#" + query_string
full_url = url + "/web#" + query_string
return full_url

View File

@@ -40,21 +40,34 @@ class SFMessageSale(models.Model):
# 继承并重写jikimo.message.dispatch的_get_message()
def _get_message(self, message_queue_ids):
res = super(SFMessageSale, self)._get_message(message_queue_ids)
new_res = []
processed_messages = set() # 用于跟踪已经处理过的消息
contents = []
url = self.env['ir.config_parameter'].get_param('web.base.url')
for item in message_queue_ids:
if item.message_template_id.bussiness_node_id.name == '确认接单':
# 待接单的处理
if item.message_template_id.bussiness_node_id.name == '待接单':
content = super(SFMessageSale, self)._get_message(item)
action_id = self.env.ref('sale.action_quotations_with_onboarding').id
url = f"{url}/web#id={item.res_id}&view_type=form&action={action_id}"
content = content[0].replace('{{url}}', url)
contents.append(content)
# 确认接单的处理
elif item.message_template_id.bussiness_node_id.name == '确认接单':
content = super(SFMessageSale, self)._get_message(item)
sale_order_line = self.env['sale.order.line'].search([('order_id', '=', int(item.res_id))])
if len(sale_order_line) == 1:
product = sale_order_line[0].product_id.name
elif len(sale_order_line) > 1:
product = '%s...' % sale_order_line[0].product_id.name
for message in res:
message_text = message.replace('{{product_id}}', product)
if message_text not in processed_messages:
new_res.append(message_text)
processed_messages.add(message_text)
if new_res:
res = new_res
return res
product = sale_order_line[0].product_id.name if len(sale_order_line) == 1 else '%s...' % \
sale_order_line[
0].product_id.name
action_id = self.env.ref('sf_plan.sf_production_plan_action1').id
url = f"{url}/web#view_type=list&action={action_id}"
content = content[0].replace('{{product_id}}', product).replace('{{url}}', url)
contents.append(content)
return contents
# # 销售订单逾期预警
# def _overdue_warning_func(self):
# sale_order_
# return 1
#
# # 销售订单已逾期
# def _overdue_func(self):
# return 1

View File

@@ -52,9 +52,7 @@ class SFMessageStockPicking(models.Model):
return res
def request_url(self):
we_config_info = self.env['we.config'].sudo().search([], limit=1)
redirect_domain = self.env['we.app'].sudo().search([('id', '=', we_config_info.odoo_app_id.id)]).redirect_domain
full_url = 'https://%s/' % redirect_domain
url = self.env['ir.config_parameter'].get_param('web.base.url')
action_id = self.env.ref('stock.stock_picking_type_action').id
menu_id = self.env['ir.model.data'].search([('name', '=', 'module_theme_treehouse')]).id
# 查询参数
@@ -63,5 +61,5 @@ class SFMessageStockPicking(models.Model):
# 拼接查询参数
query_string = urlencode(params)
# 拼接URL
full_url = full_url + "web#" + query_string
full_url = url + "/web#" + query_string
return full_url

View File

@@ -40,9 +40,7 @@ class SFMessageWork(models.Model):
return contents
def request_url(self):
we_config_info = self.env['we.config'].sudo().search([], limit=1)
redirect_domain = self.env['we.app'].sudo().search([('id', '=', we_config_info.odoo_app_id.id)]).redirect_domain
full_url = 'https://%s/' % redirect_domain
url = self.env['ir.config_parameter'].get_param('web.base.url')
action_id = self.env.ref('sf_manufacturing.mrp_workorder_action_tablet').id
menu_id = self.env['ir.model.data'].search([('name', '=', 'module_stock_dropshipping')]).id
# 查询参数
@@ -51,5 +49,6 @@ class SFMessageWork(models.Model):
# 拼接查询参数
query_string = urlencode(params)
# 拼接URL
full_url = full_url + "web#" + query_string
full_url = url + "/web#" + query_string
return full_url

View File

@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import logging
import os
import tempfile
import json
import base64
from odoo import http
@@ -23,6 +24,7 @@ class Sf_Mrs_Connect(http.Controller):
datas = request.httprequest.data
ret = json.loads(datas)
ret = json.loads(ret['result'])
tmp_path = tempfile.gettempdir()
logging.info('下发编程单:%s' % ret)
domain = [('programming_no', '=', ret['programming_no'])]
if ret['manufacturing_type'] == 'scrap':
@@ -32,7 +34,7 @@ class Sf_Mrs_Connect(http.Controller):
if productions:
# 拉取所有加工面的程序文件
for r in ret['processing_panel'].split(','):
program_path_tmp_r = os.path.join('/tmp', ret['folder_name'], 'return', r)
program_path_tmp_r = os.path.join(tmp_path, ret['folder_name'], 'return', r)
if os.path.exists(program_path_tmp_r):
files_r = os.listdir(program_path_tmp_r)
if files_r:
@@ -75,7 +77,7 @@ class Sf_Mrs_Connect(http.Controller):
if cnc_workorder:
# program_path_tmp_panel = os.path.join('C://Users//43484//Desktop//fsdownload//test',
# panel)
program_path_tmp_panel = os.path.join('/tmp', ret['folder_name'], 'return', panel)
program_path_tmp_panel = os.path.join(tmp_path, ret['folder_name'], 'return', panel)
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
files_panel = os.listdir(program_path_tmp_panel)
if files_panel:

View File

@@ -18,7 +18,7 @@ class OrderPrice(models.Model):
return True
except ValueError:
return False
@api.depends('sale_order_id.remark')
@api.depends('sale_order_id.order_line.remark')
def _compute_bfm_amount_total(self):
for record in self:
amount_total = 0

View File

@@ -3013,8 +3013,7 @@ class CuttingToolBasicParameters(models.Model):
})
if 'basic_parameters_cutter_head' in result['cutting_tool_basic_parameters_yesterday_list']:
if result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_cutter_head']:
basic_parameters_cutter_head_list = json.loads(
result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_cutter_head'])
basic_parameters_cutter_head_list = result['cutting_tool_basic_parameters_yesterday_list']['basic_parameters_cutter_head']
if basic_parameters_cutter_head_list:
for cutter_head_item in basic_parameters_cutter_head_list:
cutter_head = self.search(

View File

@@ -339,7 +339,7 @@
name="空料架配送"
sequence="11"
action="sf_manufacturing.sf_workpiece_delivery_empty_racks_act"
groups="base.group_system"
groups="sf_base.group_sf_order_user,sf_base.group_sf_mrp_manager,sf_base.group_sf_equipment_user"
parent="mrp.menu_mrp_manufacturing"
/>
<!-- <menuitem -->