Compare commits

...

96 Commits

Author SHA1 Message Date
guanhuan
9665cdfc84 发送消息添加权限 2024-10-29 08:58:33 +08:00
guanhuan
b4fbbd48fb 精度显示修改 2024-10-28 11:46:36 +08:00
guanhuan
3559d67c05 精度显示修改 2024-10-28 11:43:10 +08:00
guanhuan
18a7dbbff9 辅助文件上传 2024-10-28 10:21:33 +08:00
guanhuan
5363557faf 快速订单创建报错 2024-10-25 16:36:54 +08:00
guanhuan
4f1d518ef3 加工精度修改 2024-10-25 14:02:37 +08:00
guanhuan
86d97ef331 2D加工图纸和质检标准位置调整 2024-10-25 11:55:43 +08:00
guanhuan
519ce0d5bb 工单下发调整 2024-10-25 11:29:13 +08:00
管欢
ab10271b4d Accept Merge Request #1460: (feature/machining_accuracy_sync -> 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/1460
2024-10-25 09:04:47 +08:00
guanhuan
516a98e102 Merge remote-tracking branch 'origin/feature/machining_accuracy_sync' into feature/machining_accuracy_sync 2024-10-25 08:58:34 +08:00
guanhuan
390213881a 加工精度修改 2024-10-25 08:58:05 +08:00
杨金灵
ee148239d2 Accept Merge Request #1459: (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/1459
2024-10-24 17:35:44 +08:00
jinling.yang
4cc03aee9b 优化模版 2024-10-24 17:35:21 +08:00
jinling.yang
31a703952c 修复销售订单和工单消息提醒 2024-10-24 17:32:40 +08:00
jinling.yang
ae08c5b56e Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 16:55:43 +08:00
jinling.yang
dc76dcdc2f Merge branch 'feature/修复销售订单完成时效' into develop 2024-10-24 16:52:08 +08:00
杨金灵
6a040d16ea Accept Merge Request #1458: (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/1458?initial=true
2024-10-24 16:51:52 +08:00
jinling.yang
30e8d04b70 添加销售订单是否完成并恢复正常时效定时器 2024-10-24 16:50:27 +08:00
jinling.yang
2b3375ad41 修复销售订单完成时效 2024-10-24 16:40:25 +08:00
jinling.yang
8a059a5520 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 16:20:38 +08:00
jinling.yang
49a2f02b54 Merge branch 'feature/修复工单提醒' into develop 2024-10-24 16:20:09 +08:00
禹翔辉
ef92f24d35 Accept Merge Request #1456: (feature/维保请求优化 -> develop)
Merge Request: 1、添加维保请求的相关权限;2、优化维保请求tree视图、form视图和搜索视图;

Created By: @禹翔辉
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1456
2024-10-24 16:18:08 +08:00
杨金灵
0207914592 Accept Merge Request #1457: (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/1457
2024-10-24 16:17:54 +08:00
jinling.yang
5776c97744 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复工单提醒 2024-10-24 16:16:11 +08:00
jinling.yang
180cdf2a08 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 16:15:51 +08:00
jinling.yang
47720948ff 修复工单提醒 2024-10-24 16:15:30 +08:00
yuxianghui
7814a2b622 Merge branch 'feature/工单状态优化' into feature/维保请求优化 2024-10-24 16:12:57 +08:00
yuxianghui
06981fb894 1、添加维保请求的相关权限;2、优化维保请求tree视图、form视图和搜索视图; 2024-10-24 16:12:09 +08:00
马广威
19dbd9901d Accept Merge Request #1455: (feature/制造功能优化 -> develop)
Merge Request: 处理工单的组件不存在时报错的问题

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1455?initial=true
2024-10-24 16:06:50 +08:00
mgw
4985b0a85d Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-10-24 16:05:03 +08:00
mgw
39f99d6ce7 处理工单的组件不存在时报错的问题 2024-10-24 16:04:38 +08:00
马广威
c8f25ea4b3 Accept Merge Request #1454: (feature/制造功能优化 -> develop)
Merge Request: 增加对Enter的判断

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1454?initial=true
2024-10-24 15:51:11 +08:00
mgw
cab9e08066 增加对Enter的判断 2024-10-24 15:50:32 +08:00
马广威
2b83f82989 Accept Merge Request #1453: (feature/制造功能优化 -> develop)
Merge Request: 将扫描rfid绑定并开启装夹工单写成widget形式

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1453
2024-10-24 15:34:06 +08:00
mgw
598e8fee9c Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-10-24 15:32:41 +08:00
mgw
6f3a788101 将扫描rfid绑定并开启装夹工单写成widget形式 2024-10-24 15:32:15 +08:00
jinling.yang
30ff349b37 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 15:17:59 +08:00
管欢
e264306fed Accept Merge Request #1452: (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/1452
2024-10-24 14:58:34 +08:00
jinling.yang
4018797384 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 14:57:01 +08:00
guanhuan
f557cb8d10 零件图纸,质检标准显示位置修改 2024-10-24 14:55:36 +08:00
jinling.yang
a1efde6ef9 Merge branch 'feature/修复销售订单逾期过期' into develop 2024-10-24 14:41:10 +08:00
杨金灵
cf34e28e35 Accept Merge Request #1451: (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/1451?initial=true
2024-10-24 14:40:28 +08:00
jinling.yang
b7595fe4ec Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复销售订单逾期过期 2024-10-24 14:28:07 +08:00
jinling.yang
2551d82a99 修复销售订单逾期过期 2024-10-24 14:27:44 +08:00
管欢
0cedba8ea4 Accept Merge Request #1450: (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/1450
2024-10-24 14:24:18 +08:00
guanhuan
d64a814251 制造订单零件图纸,质检标准显示 2024-10-24 11:33:10 +08:00
胡尧
86d5de4fa1 Accept Merge Request #1449: (feature/plan_slow -> develop)
Merge Request: 解决排程报错

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1449?initial=true
2024-10-24 11:30:06 +08:00
廖丹龙
0bf9c752f6 Accept Merge Request #1442: (feature/machining_accuracy_sync -> 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/1442
2024-10-24 11:23:20 +08:00
杨金灵
e62eb060fb Accept Merge Request #1448: (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/1448?initial=true
2024-10-24 10:54:00 +08:00
jinling.yang
563b44adb1 添加输出 2024-10-24 10:53:04 +08:00
liaodanlong
a094946428 按钮位置修改 2024-10-24 10:37:50 +08:00
jinling.yang
d28fd5d787 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 10:35:52 +08:00
jinling.yang
41c357d124 Merge branch 'feature/修复设备文件' into develop 2024-10-24 10:32:46 +08:00
杨金灵
f94d52a4d9 Accept Merge Request #1447: (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/1447?initial=true
2024-10-24 10:30:39 +08:00
jinling.yang
74dc31b083 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 10:28:41 +08:00
jinling.yang
3b1fca529a Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 10:28:07 +08:00
jinling.yang
843eeb8a89 修复设备文件 2024-10-24 10:27:46 +08:00
胡尧
12e81ec702 Accept Merge Request #1446: (feature/plan_slow -> develop)
Merge Request: 解决排程慢的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1446
2024-10-24 10:15:55 +08:00
jinling.yang
fe2af8a4ce Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 10:13:28 +08:00
jinling.yang
f337a30aba Merge branch 'feature/优化加工质检' into develop 2024-10-24 10:09:45 +08:00
杨金灵
7f3a8d877f Accept Merge Request #1445: (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/1445
2024-10-24 10:09:29 +08:00
jinling.yang
5e6a7d0a39 还原代码 2024-10-24 10:07:56 +08:00
jinling.yang
5788a157c5 还原代码 2024-10-24 10:03:18 +08:00
jinling.yang
de8ba77bef 优化加工质检页面 2024-10-24 09:22:35 +08:00
管欢
f366b650d0 Accept Merge Request #1444: (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/1444
2024-10-23 17:54:42 +08:00
guanhuan
6054ce39f3 附件文件名 2024-10-23 17:43:03 +08:00
禹翔辉
e1e9dc425b Accept Merge Request #1443: (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/1443
2024-10-23 17:12:17 +08:00
yuxianghui
3a2a942f3b Merge branch 'feature/设备维保优化' into feature/工单状态优化 2024-10-23 17:05:47 +08:00
yuxianghui
bf9d848f10 1、工单状态优化 2024-10-23 17:04:35 +08:00
liaodanlong
add7d404a0 质检单类型翻译 2024-10-23 17:03:16 +08:00
liaodanlong
7e6fa7b6c7 产品类别隐藏 2024-10-23 17:02:24 +08:00
禹翔辉
3fd17302f5 Accept Merge Request #1440: (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/1440
2024-10-23 15:51:06 +08:00
胡尧
db9cee3e28 Accept Merge Request #1441: (feature/workorder_exceptions -> develop)
Merge Request: 修改工单通知筛选条件

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1441?initial=true
2024-10-23 15:50:31 +08:00
胡尧
97a26dfa06 修改工单通知筛选条件 2024-10-23 15:50:01 +08:00
yuxianghui
cebd895811 Merge branch 'feature/设备模块优化' into feature/设备维保优化 2024-10-23 15:49:13 +08:00
yuxianghui
bb6c208d37 设备维保计划优化 2024-10-23 15:48:33 +08:00
胡尧
921f2c3503 Accept Merge Request #1439: (feature/workorder_exceptions -> develop)
Merge Request: 修改工单通知筛选条件

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1439?initial=true
2024-10-23 15:38:55 +08:00
胡尧
1224e0e094 修改工单通知筛选条件 2024-10-23 15:38:09 +08:00
胡尧
a571a870d3 修改工单通知筛选条件 2024-10-23 15:33:48 +08:00
管欢
d4e0d36166 Accept Merge Request #1438: (feature/machining_accuracy_sync -> 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/1438
2024-10-23 14:00:41 +08:00
jinling.yang
39579aef10 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化加工质检
# Conflicts:
#	sf_message/models/sf_message_maintenance_logs.py
2024-10-23 11:56:16 +08:00
jinling.yang
1fe8fd6933 优化定时器代码 2024-10-23 11:55:43 +08:00
liaodanlong
3b1caca62b 还原 2024-10-23 11:00:19 +08:00
liaodanlong
3fe8c957be 加工精度字段信息修改 2024-10-23 10:41:32 +08:00
yuxianghui
98923c1797 1、设备维保优化 2024-10-22 17:52:20 +08:00
guanhuan
8661dd16c1 加工精度同步 2024-10-22 15:37:41 +08:00
guanhuan
7157ea1587 加工精度同步 2024-10-22 15:35:34 +08:00
廖丹龙
a580a12d69 Accept Merge Request #1437: (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/1437?initial=true
2024-10-22 13:56:38 +08:00
liaodanlong
0d512e2e43 制造订单添加订单交期字段信息 2024-10-22 13:55:24 +08:00
廖丹龙
103069c554 Accept Merge Request #1436: (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/1436?initial=true
2024-10-22 13:48:28 +08:00
yuxianghui
f2482b5128 处理功能刀具产生库存移动时,功能刀具列表的功能刀具位置没有实时发生变更的问题 2024-10-22 13:45:08 +08:00
liaodanlong
da38d24111 制造订单添加订单交期字段信息 2024-10-22 13:33:53 +08:00
廖丹龙
1f0ebe71c7 Accept Merge Request #1435: (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/1435?initial=true
2024-10-22 11:56:28 +08:00
liaodanlong
f897955f68 制造订单添加订单交期字段信息 2024-10-22 11:45:08 +08:00
guanhuan
00a04af94f 加工精度 2024-10-18 09:30:20 +08:00
guanhuan
cc40d479a9 加工精度同步 2024-10-17 17:20:51 +08:00
52 changed files with 887 additions and 194 deletions

View File

@@ -1,2 +1,5 @@
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
"access_jikimo_workorder_exception","access.jikimo.workorder.exception","model_jikimo_workorder_exception","mrp.group_mrp_user",1,1,1,0
"access_jikimo_workorder_exception_group_quality","access.jikimo.workorder.exception.group_quality","model_jikimo_workorder_exception","sf_base.group_quality",1,1,1,0
"access_jikimo_workorder_exception_group_quality_director","access.jikimo.workorder.exception.group_quality_director","model_jikimo_workorder_exception","sf_base.group_quality_director",1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_jikimo_workorder_exception access.jikimo.workorder.exception model_jikimo_workorder_exception mrp.group_mrp_user 1 1 1 0
3 access_jikimo_workorder_exception_group_quality access.jikimo.workorder.exception.group_quality model_jikimo_workorder_exception sf_base.group_quality 1 1 1 0
4 access_jikimo_workorder_exception_group_quality_director access.jikimo.workorder.exception.group_quality_director model_jikimo_workorder_exception sf_base.group_quality_director 1 1 1 0
5

View File

@@ -1273,3 +1273,18 @@ msgstr ""
#: model:product.template,description_sale:mrp_workorder.product_template_stool_top
msgid "wooden stool top"
msgstr ""
#. module: mrp_workorder
#: model:quality.point.test_type,name:mrp_workorder.test_type_register_consumed_materials
msgid "Register Consumed Materials"
msgstr "登记消耗材料"
#. module: mrp_workorder
#: model:quality.point.test_type,name:mrp_workorder.test_type_register_byproducts
msgid "Register By-products"
msgstr "按产品注册"
#. module: mrp_workorder
#: model:quality.point.test_type,name:mrp_workorder.test_type_print_label
msgid "Print label"
msgstr "打印标签"

View File

@@ -1050,3 +1050,13 @@ msgstr "工作中心故障"
#: model:ir.model.fields,field_description:quality.field_quality_point_test_type__active
msgid "active"
msgstr "有效"
#. module: quality
#: model:quality.point.test_type,name:quality.test_type_instructions
msgid "Instructions"
msgstr "使用说明"
#. module: quality
#: model:quality.point.test_type,name:quality.test_type_picture
msgid "Take a Picture"
msgstr "照片"

View File

@@ -15,7 +15,7 @@ class TestType(models.Model):
_description = "Quality Control Test Type"
# Used instead of selection field in order to hide a choice depending on the view.
name = fields.Char('Name', required=True)
name = fields.Char('Name', required=True,translate=True)
technical_name = fields.Char('Technical name', required=True)
active = fields.Boolean('active', default=True)

View File

@@ -1185,3 +1185,14 @@ msgstr "请先进行质量检查!"
#: model_terms:ir.ui.view,arch_db:quality_control.quality_alert_team_view_form
msgid "e.g. The QA Masters"
msgstr "例如QA大师"
#. module: quality_control
#: model:quality.point.test_type,name:quality_control.test_type_passfail
msgid "Pass - Fail"
msgstr "通过-失败"
#. module: quality_control
#: model:quality.point.test_type,name:quality_control.test_type_measure
msgid "Measure"
msgstr "测量"

View File

@@ -6,3 +6,4 @@ from . import stock_move
from . import stock_move_line
from . import stock_picking
from . import stock_lot
from . import product_category

View File

@@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from math import sqrt
from dateutil.relativedelta import relativedelta
from datetime import datetime
import random
from odoo import api, models, fields, _
from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT, float_round
from odoo.osv.expression import OR
class ProductCategory(models.Model):
_inherit = 'product.category'
@api.model
def name_search(self, name='', args=None, operator='ilike', limit=100):
if args is None:
args = []
# 添加过滤条件,确保只返回名称为 'abc' 的记录
args += [('name', 'not in', ['Saleable', 'Expenses', 'Deliveries'])]
# 调用父类的 name_search 方法
return super(ProductCategory, self).name_search(name, args=args, operator=operator, limit=limit)

View File

@@ -394,3 +394,11 @@ class MachineToolCategory(models.Model):
active = fields.Boolean('有效', default=True)
category = fields.Selection([('shukong', u'数控'), ('putong', u'普通')], string=u'机床类别',
default='shukong')
class MachiningAccuracy(models.Model):
_name = 'sf.machining.accuracy'
_description = '加工精度'
name = fields.Char('一般公差', index=True)
standard_tolerance = fields.Char(string="标准公差")
sync_id = fields.Char('同步ID')

View File

@@ -247,3 +247,7 @@ access_sf_cutting_tool_type_group_sf_stock_manager,sf_cutting_tool_type_group_sf
access_sf_cutting_tool_material_group_plan_dispatch,sf_cutting_tool_material_group_plan_dispatch,model_sf_cutting_tool_material,sf_base.group_plan_dispatch,1,0,0,0
access_sf_functional_cutting_tool_model_group_plan_dispatch,sf_functional_cutting_tool_model_group_plan_dispatch,model_sf_functional_cutting_tool_model,sf_base.group_plan_dispatch,1,0,0,0
access_sf_cutting_tool_type_group_plan_dispatch,sf_cutting_tool_type_group_plan_dispatch,model_sf_cutting_tool_type,sf_base.group_plan_dispatch,1,0,0,0
access_sf_machining_accuracy,sf_machining_accuracy,model_sf_machining_accuracy,base.group_user,1,0,0,0
access_sf_machining_accuracy_admin,sf_machining_accuracy_admin,model_sf_machining_accuracy,base.group_system,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
247
248
249
250
251
252
253

View File

@@ -614,4 +614,23 @@
<field name="res_model">sf.machine.control_system</field>
<field name="view_mode">tree</field>
</record>
#------------------加工精度------------------
<record model="ir.ui.view" id="tree_sf_machining_accuracy_view">
<field name="name">tree.sf.machining.accuracy</field>
<field name="model">sf.machining.accuracy</field>
<field name="arch" type="xml">
<tree string="加工精度" create="0" edit="0" delete="0">
<field name="name"/>
<field name="standard_tolerance"/>
</tree>
</field>
</record>
<record id="action_sf_machining_accuracy" model="ir.actions.act_window">
<field name="name">加工精度</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sf.machining.accuracy</field>
<field name="view_mode">tree</field>
</record>
</odoo>

View File

@@ -141,12 +141,18 @@
sequence="1"
action="action_sf_machine_brand"/>
<menuitem
id="menu_sf_machining_accuracy"
parent="menu_sf_base"
name="加工精度"
sequence="1"
action="action_sf_machining_accuracy"/>
<menuitem
id="menu_sf_machine_control_system"
parent="menu_sf_base"
name="数控系统"
sequence="1"
sequence="2"
action="action_sf_machine_control_system"/>

View File

@@ -9,7 +9,7 @@
""",
'category': 'sf',
'website': 'https://www.sf.jikimo.com',
'depends': ['sf_sale', 'sf_dlm', 'sf_manufacturing'],
'depends': ['sf_sale', 'sf_dlm', 'sf_manufacturing','jikimo_attachment_viewer'],
'data': [
'data/stock_data.xml',
'views/product_template_management_view.xml',

View File

@@ -16,8 +16,6 @@
<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="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"
@@ -111,6 +109,19 @@
'刀具')], 'required': True}
</attribute>
</xpath>
<xpath expr="//sheet//notebook" position="inside">
<page string="2D加工图纸">
<field name='machining_drawings' attrs="{'invisible': [('categ_type', '!=', '成品')]}"
widget="adaptive_viewer"/>
</page>
</xpath>
<xpath expr="//sheet//notebook" position="inside">
<page string="质检标准">
<field name='quality_standard' attrs="{'invisible': [('categ_type', '!=', '成品')]}"
widget="adaptive_viewer"/>
</page>
</xpath>
<!-- <xpath expr="//field[@name='default_code']" position="attributes">-->
<!-- <attribute name="attrs">{'readonly': [('categ_type', '=', '刀具')], 'invisible':-->
<!-- [('product_variant_count', '>' , 1)]}-->

View File

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

View File

@@ -18,6 +18,7 @@
'views/equipment_maintenance_standards_views.xml',
'views/maintenance_request_views.xml',
'views/maintenance_equipment_category_views.xml',
'wizard/maintenance_request_wizard.xml',
],
'installable': True,
'application': False,

View File

@@ -1,11 +1,12 @@
# -*- coding: utf-8 -*-
import json
import base64
import logging
from datetime import timedelta
import requests
from odoo.addons.sf_base.commons.common import Common
from odoo import api, fields, models, _
from odoo.exceptions import UserError
from odoo.exceptions import UserError, ValidationError
class SfMaintenanceEquipmentCategory(models.Model):
@@ -122,6 +123,13 @@ class SfMaintenanceEquipment(models.Model):
'sf_maintenance_equipment_ids', string='设备维保标准')
eq_maintenance_id = fields.Many2one('equipment.maintenance.standards', string='设备保养标准',
domain="[('maintenance_type','=','保养')]")
initial_action_date = fields.Date(string='重置保养日期')
initial_action_date_old = fields.Date(string='重置保养日期(旧)')
next_action_date = fields.Date(string='下次预防保养')
initial_overhaul_date = fields.Date(string='重置维修日期')
initial_overhaul_date_old = fields.Date(string='重置维修日期(旧)')
overhaul_date = fields.Date(string='下次预防检修')
overhaul_period = fields.Integer(string='预防检修频次')
overhaul_duration = fields.Float(string='检修时长')
@@ -129,6 +137,61 @@ class SfMaintenanceEquipment(models.Model):
overhaul_id = fields.Many2one('equipment.maintenance.standards', string='设备检修标准',
domain="[('maintenance_type','=','检修')]")
def confirm_maintenance(self):
"""
确认保养/检修
"""
context = self.env.context
if context['type'] == '保养':
if not self.initial_action_date:
raise ValidationError('重置保养日期不能为空!!')
elif self.initial_action_date < fields.Date.today():
raise ValidationError('重置保养日期不能小于当前日期!!')
elif context['type'] == '检修':
if not self.initial_overhaul_date:
raise ValidationError('重置检修日期不能为空!!')
elif self.initial_overhaul_date < fields.Date.today():
raise ValidationError('重置检修日期不能小于当前日期!!')
request_ids = self.env['maintenance.request'].search([('stage_id.done', '=', False),
('equipment_id', '=', self.id),
('maintenance_type', '=', 'preventive'),
('sf_maintenance_type', '=', context['type'])])
if not request_ids:
return self.create_maintenance_request(context['type'])
else:
return {
"type": "ir.actions.act_window",
"res_model": "maintenance.request.wizard",
"views": [[False, "form"]],
"target": "new",
'context': {
'equipment_id': self.id
}
}
def create_maintenance_request(self, maintenance_request_type):
"""
根据条件创建维保计划
"""
if maintenance_request_type == '保养':
self._create_new_request(self.initial_action_date + timedelta(days=self.period))
self.initial_action_date_old = self.initial_action_date
elif maintenance_request_type == '检修':
self._create_new_request1(self.initial_overhaul_date + timedelta(days=self.overhaul_period))
self.initial_overhaul_date_old = self.initial_overhaul_date
return {
'type': 'ir.actions.client',
'tag': 'display_notification',
'params': {
'title': f'创建{maintenance_request_type}计划',
'message': f'{maintenance_request_type}维保计划创建成功',
'type': 'success',
'next': {'type': 'ir.actions.act_window_close'},
}
}
@api.onchange('eq_maintenance_id', 'overhaul_id')
def _compute_equipment_maintenance_standards_ids(self):
for record in self:
@@ -591,11 +654,13 @@ class SfMaintenanceEquipment(models.Model):
('equipment_id', '=', equipment.id),
('sf_maintenance_type', '=', '保养'),
('stage_id.done', '!=', True),
('active', '!=', False),
('close_date', '=', False)], order="request_date asc", limit=1)
last_maintenance_done = self.env['maintenance.request'].search([
('equipment_id', '=', equipment.id),
('sf_maintenance_type', '=', '保养'),
('stage_id.done', '=', True),
('active', '!=', False),
('close_date', '!=', False)], order="close_date desc", limit=1)
if next_maintenance_todo and last_maintenance_done:
next_date = next_maintenance_todo.request_date
@@ -624,7 +689,7 @@ class SfMaintenanceEquipment(models.Model):
if next_date < date_now:
next_date = date_now
else:
next_date = equipment.effective_date + timedelta(days=equipment.period)
next_date = equipment.initial_action_date + timedelta(days=equipment.period)
equipment.next_action_date = next_date
else:
self.next_action_date = False
@@ -635,11 +700,13 @@ class SfMaintenanceEquipment(models.Model):
('equipment_id', '=', equipment.id),
('sf_maintenance_type', '=', '检修'),
('stage_id.done', '!=', True),
('active', '!=', False),
('close_date', '=', False)], order="request_date asc", limit=1)
last_maintenance_done = self.env['maintenance.request'].search([
('equipment_id', '=', equipment.id),
('sf_maintenance_type', '=', '检修'),
('stage_id.done', '=', True),
('active', '!=', False),
('close_date', '!=', False)], order="close_date desc", limit=1)
if next_maintenance_todo and last_maintenance_done:
next_date = next_maintenance_todo.request_date
@@ -668,7 +735,7 @@ class SfMaintenanceEquipment(models.Model):
if next_date < date_now:
next_date = date_now
else:
next_date = equipment.effective_date + timedelta(days=equipment.overhaul_period)
next_date = equipment.initial_overhaul_date + timedelta(days=equipment.overhaul_period)
equipment.overhaul_date = next_date
else:
self.overhaul_date = False
@@ -735,6 +802,7 @@ class SfMaintenanceEquipment(models.Model):
next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False),
('equipment_id', '=', equipment.id),
('maintenance_type', '=', 'preventive'),
('active', '=', True),
('request_date', '=', equipment.next_action_date),
('sf_maintenance_type', '=', '保养')])
if not next_requests:
@@ -743,6 +811,7 @@ class SfMaintenanceEquipment(models.Model):
next_requests = self.env['maintenance.request'].search([('stage_id.done', '=', False),
('equipment_id', '=', equipment.id),
('maintenance_type', '=', 'preventive'),
('active', '=', True),
('request_date', '=', equipment.overhaul_date),
('sf_maintenance_type', '=', '检修')])
if not next_requests:

View File

@@ -14,6 +14,8 @@ class SfMaintenanceEquipmentCategory(models.Model):
equipment_maintenance_id = fields.Many2one('equipment.maintenance.standards', string='设备维保标准',
domain="[('maintenance_type','=',sf_maintenance_type)]")
active = fields.Boolean('有效', default=True)
@api.onchange('sf_maintenance_type')
def _compute_equipment_maintenance_request_id(self):
for record in self:

View File

@@ -20,7 +20,12 @@ access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_mainten
access_maintenance_system_user,equipment.request system user,maintenance.model_maintenance_request,base.group_user,1,0,0,0
access_maintenance_system_user,equipment.request system user,maintenance.model_maintenance_request,base.group_user,1,1,1,0
access_maintenance_wizard_system_user,maintenance.request.wizard system user,model_maintenance_request_wizard,base.group_user,1,1,1,0
access_maintenance_sf_group_equipment_user,equipment.request_sf_group_equipment_user,maintenance.model_maintenance_request,sf_group_equipment_user,1,1,1,0
access_maintenance_wizard_sf_group_equipment_user,maintenance_wizard_sf_group_equipment_user,model_maintenance_request_wizard,sf_group_equipment_user,1,1,1,0
access_maintenance_sf_group_equipment_manager,equipment.request_sf_group_equipment_manager,maintenance.model_maintenance_request,sf_group_equipment_manager,1,1,1,0
access_maintenance_wizard_sf_group_equipment_manager,maintenance_wizard_sf_group_equipment_manager,model_maintenance_request_wizard,sf_group_equipment_manager,1,1,1,0
access_maintenance_equipment_group_plan_dispatch,maintenance.equipment,maintenance.model_maintenance_equipment,sf_base.group_plan_dispatch,1,0,0,0
access_maintenance_equipment_oee_group_plan_dispatch,maintenance_equipment_oee,model_maintenance_equipment_oee,sf_base.group_plan_dispatch,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
20 access_maintenance_system_user equipment.request system user maintenance.model_maintenance_request base.group_user 1 0 1 0 1 0
21 access_maintenance_equipment_group_plan_dispatch access_maintenance_wizard_system_user maintenance.equipment maintenance.request.wizard system user maintenance.model_maintenance_equipment model_maintenance_request_wizard sf_base.group_plan_dispatch base.group_user 1 0 1 0 1 0
22 access_maintenance_equipment_oee_group_plan_dispatch access_maintenance_sf_group_equipment_user maintenance_equipment_oee equipment.request_sf_group_equipment_user model_maintenance_equipment_oee maintenance.model_maintenance_request sf_base.group_plan_dispatch sf_group_equipment_user 1 0 1 0 1 0
23 access_sf_maintenance_logs_group_plan_dispatch access_maintenance_wizard_sf_group_equipment_user sf_maintenance_logs maintenance_wizard_sf_group_equipment_user model_sf_maintenance_logs model_maintenance_request_wizard sf_base.group_plan_dispatch sf_group_equipment_user 1 0 1 0 1 0
24 access_maintenance_sf_group_equipment_manager equipment.request_sf_group_equipment_manager maintenance.model_maintenance_request sf_group_equipment_manager 1 1 1 0
25 access_maintenance_wizard_sf_group_equipment_manager maintenance_wizard_sf_group_equipment_manager model_maintenance_request_wizard sf_group_equipment_manager 1 1 1 0
26 access_maintenance_equipment_group_plan_dispatch maintenance.equipment maintenance.model_maintenance_equipment sf_base.group_plan_dispatch 1 0 0 0
27 access_maintenance_equipment_oee_group_plan_dispatch maintenance_equipment_oee model_maintenance_equipment_oee sf_base.group_plan_dispatch 1 0 0 0
28 access_sf_maintenance_logs_group_plan_dispatch sf_maintenance_logs model_sf_maintenance_logs sf_base.group_plan_dispatch 1 0 0 0
29 access_maintenance_standard_image_group_plan_dispatch maintenance_standard_image model_maintenance_standard_image sf_base.group_plan_dispatch 1 0 0 0
30 access_equipment_maintenance_standards_group_plan_dispatch equipment_maintenance_standards model_equipment_maintenance_standards sf_base.group_plan_dispatch 1 0 0 0
31 access_maintenance_standards_group_plan_dispatch maintenance_standards model_maintenance_standards sf_base.group_plan_dispatch 1 0 0 0

View File

@@ -76,33 +76,61 @@
<field name="equipment_maintenance_id"/>
</xpath>
<xpath expr="//field[@name='user_id']" position="replace">
<field name="user_id" string="维保人"/>
</xpath>
<xpath expr="//field[@name='close_date']" position="replace">
<field name="close_date" attrs="{'invisible': [('done', '!=', True)]}" readonly="True" string="维保日期"/>
</xpath>
<xpath expr="//field[@name='user_id']" position="replace">
<field name="user_id" string="维保人"/>
</xpath>
<xpath expr="//field[@name='close_date']" position="replace">
<field name="close_date" attrs="{'invisible': [('done', '!=', True)]}" readonly="True"
string="维保日期"/>
</xpath>
<xpath expr="//field[@name='request_date']" position="attributes">
<attribute name="string">计划维保日期</attribute>
</xpath>
<sheet>
<notebook>
<page string="维保标准" attrs="{'invisible': [('equipment_maintenance_id', '=', False)]}" context="{'default_standard_id': 'id'}">
<page string="维保标准" attrs="{'invisible': [('equipment_maintenance_id', '=', False)]}"
context="{'default_standard_id': 'id'}">
<field name="maintenance_standards" widget="one2many_list">
<tree multi_edit="" editable="">
<field name="name" class="table_custom_required"/>
<field name="maintenance_standards" class="table_custom_required"/>
<field name="images" force_save="1" required="1" class="table_custom_required">
<field name="name" class="table_custom_required"/>
<field name="maintenance_standards" class="table_custom_required"/>
<field name="images" force_save="1" required="1" class="table_custom_required">
</field>
<field name="remark" class="table_custom_required"/>
</tree>
</field>
</page>
</notebook>
</sheet>
</field>
</record>
<record id="maintenance_request_view_tree_sf" model="ir.ui.view">
<field name="name">maintenance.request.view.tree.sf</field>
<field name="model">maintenance.request</field>
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_tree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='request_date']" position="replace">
<field name="request_date" string="计划维保日期"/>
</xpath>
<xpath expr="//field[@name='user_id']" position="after">
<field name="sf_maintenance_type"/>
</xpath>
</field>
</record>
<record id="equipment_request_view_search_sf" model="ir.ui.view">
<field name="name">maintenance.request.view.search.sf</field>
<field name="model">maintenance.request</field>
<field name="inherit_id" ref="maintenance.hr_equipment_request_view_search"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='inactive']" position="replace">
<filter string="不活跃的" name="inactive" domain="[('archive', '=', True)]"/>
<filter string="已归档" name="in_active" domain="[('active', '=', False)]"/>
</xpath>
</field>
</record>
@@ -110,7 +138,7 @@
<record id="hr_equipment_request_action1" model="ir.actions.act_window">
<field name="name">维保计划</field>
<field name="res_model">maintenance.request</field>
<field name="view_mode">kanban,tree,form,pivot,graph,calendar</field>
<field name="view_mode">tree,kanban,form,pivot,graph,calendar</field>
<field name="view_id" ref="maintenance.hr_equipment_request_view_kanban"/>
<field name="context">{'default_user_id': uid}</field>
<field name="help" type="html">

View File

@@ -60,9 +60,9 @@
<field name="function_type"/>
<field name="code" readonly="1"/>
<field name="equipment_type" invisible="1"/>
<field name="brand_id" force_save="1" />
<field name="brand_id" force_save="1"/>
<field name="type_id" attrs="{'required': [('equipment_type', '=', '机床')]}"
domain="[('brand_id', '=', brand_id)]" />
domain="[('brand_id', '=', brand_id)]"/>
<field name="machine_tool_category" readonly="1" attrs="{'invisible': [('type_id', '=', False)]}"
force_save="1"/>
<field name="run_time" force_save="1"/>
@@ -73,7 +73,7 @@
<group>
<group string="基础参数">
<field name="control_system_id" attrs="{'required': [('equipment_type', '=', '机床')]}"
options="{'no_create': True}" />
options="{'no_create': True}"/>
<label for="workbench_L" string="工作台尺寸(mm)"/>
<div class="test_model">
<label for="workbench_L" string="长"/>
@@ -85,7 +85,7 @@
<field name="workbench_W" class="o_address_zip"
attrs="{'required': [('equipment_type', '=', '机床')]}"
options="{'format': false}"/>
<span>&amp;nbsp;</span>
<span>&amp;nbsp;</span>
<label for="workbench_H" string="高"/>
<field name="workbench_H" class="o_address_zip"
attrs="{'required': [('equipment_type', '=', '机床')]}"
@@ -134,7 +134,7 @@
<!-- <field name="guide_rail" required="1"/>-->
<field name="number_of_axles" attrs="{'required': [('equipment_type', '=', '机床')]}"
widget="radio"
options="{'horizontal': true}" />
options="{'horizontal': true}"/>
<label for="x_axis" string="加工行程(mm)"
attrs="{'invisible': [('number_of_axles', '=', False)]}"/>
<div class="test_model"
@@ -196,8 +196,8 @@
<field name="T_tool_time"/>
<field name="C_tool_time"/>
</group>
<group string="主轴">
<field name="taper_type_id" attrs="{'required': [('equipment_type', '=', '机床')]}" />
<group string="主轴">
<field name="taper_type_id" attrs="{'required': [('equipment_type', '=', '机床')]}"/>
<label for="distance_min" string="主轴端面-工作台距离(mm)"/>
<div class="test_model">
<label for="distance_min" string="最小(min)"/>
@@ -237,7 +237,7 @@
<field name="c_precision"/>
<field name="c_precision_repeat"/>
</group>
<group string="进给参数">
<group string="进给参数">
<field name="X_axis_rapid_traverse_speed"/>
<field name="Y_axis_rapid_traverse_speed"/>
<field name="Z_axis_rapid_traverse_speed"/>
@@ -252,21 +252,21 @@
</page>
<page string="AGV运行日志" name="sf_equipment"
<page string="AGV运行日志" name="sf_equipment"
attrs="{'invisible': [('equipment_type', '!=', 'AGV小车')]}">
<field name="agv_logs">
<tree create="1" edit="1" delete="1" editable="bottom">
<field name = 'run_type'/>
<field name = 'run_code'/>
<field name = 'run_first'/>
<field name = 'run_last'/>
<field name = 'production_line'/>
<field name = 'workorder'/>
<field name = 'time'/>
<field name = 'state'/>
</tree>
</field>
</page>
<field name="agv_logs">
<tree create="1" edit="1" delete="1" editable="bottom">
<field name='run_type'/>
<field name='run_code'/>
<field name='run_first'/>
<field name='run_last'/>
<field name='production_line'/>
<field name='workorder'/>
<field name='time'/>
<field name='state'/>
</tree>
</field>
</page>
<page string="设备参数" name="sf_equipment"
attrs="{'invisible': [('equipment_type', '!=', 'AGV小车')]}">
@@ -979,31 +979,58 @@
</group>
</xpath>
<xpath expr="//field[@name='next_action_date']" position="before">
<field name='eq_maintenance_id' force_save="1" widget="many2one"/>
<xpath expr="//page[@name='maintenance']" position="replace">
<page string="维保" name="maintenance">
<group>
<group string="保养">
<field name='eq_maintenance_id' force_save="1" widget="many2one"/>
<field name="initial_action_date"/>
<field name="next_action_date" string="下次预防保养"/>
<label for="period" string="预防保养频次"/>
<div class="o_row">
<field name="period"/>
days
</div>
<label for="maintenance_duration" string="保养时长"/>
<div class="o_row">
<field name="maintenance_duration"/>
hours
</div>
<div class="col-12 col-lg-6 o_setting_box" style="white-space: nowrap">
<button name="confirm_maintenance" string="确认保养" type="object"
class="oe_highlight" context="{'type': '保养'}"/>
</div>
</group>
<group string="检修">
<field name='overhaul_id'/>
<field name="initial_overhaul_date"/>
<field name="overhaul_date" string="下次预防检修"/>
<label for="overhaul_period" string="预防检修频次"/>
<div class="o_row">
<field name="overhaul_period"/>
days
</div>
<label for="overhaul_duration" string="检修时长"/>
<div class="o_row">
<field name="overhaul_duration"/>
hours
</div>
<field name='equipment_maintenance_standards_ids' widget="many2many_tags"
invisible="1"/>
<div class="col-12 col-lg-6 o_setting_box" style="white-space: nowrap">
<button name="confirm_maintenance" string="确认检修" type="object"
class="oe_highlight" context="{'type': '检修'}"/>
</div>
</group>
</group>
</page>
</xpath>
<xpath expr="//div[hasclass('o_row')][field[@name='maintenance_duration']]" position="after">
<field name='overhaul_id' options="{'no_create':True}"/>
<field name="overhaul_date" string="下次预防检修"/>
<label for="overhaul_period" string="预防检修频次"/>
<div class="o_row">
<field name="overhaul_period"/>
days
</div>
<label for="overhaul_duration" string="检修时长"/>
<div class="o_row">
<field name="overhaul_duration"/>
hours
</div>
<field name='equipment_maintenance_standards_ids' widget="many2many_tags" invisible="1"/>
</xpath>
<xpath expr="//page[@name='description']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
@@ -1189,7 +1216,7 @@
<field name="name" readonly="1"/>
<field name="type" readonly="1"/>
<field name="image" widget="image" readonly="1"/>
<!-- <field name="equipment_id"/>-->
<!-- <field name="equipment_id"/>-->
<field name="active" invisible="1"/>
</tree>
</field>

View File

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

View File

@@ -0,0 +1,26 @@
from odoo import fields, models
class MaintenanceRequestWizard(models.TransientModel):
_name = 'maintenance.request.wizard'
_description = '维保二次确认弹窗'
name = fields.Char('')
def submit(self):
context = self.env.context
equipment_id = self.env['maintenance.equipment'].sudo().search([('id', '=', context['equipment_id'])])
request_ids = self.env['maintenance.request'].search([('stage_id.done', '=', False),
('equipment_id', '=', equipment_id.id),
('maintenance_type', '=', 'preventive'),
('sf_maintenance_type', '=', context['type'])])
request_ids.write({'active': False})
return equipment_id.create_maintenance_request(context['type'])
def cancel(self):
context = self.env.context
equipment_id = self.env['maintenance.equipment'].sudo().search([('id', '=', context['equipment_id'])])
if context['type'] == '保养':
equipment_id.initial_action_date = equipment_id.initial_action_date_old
elif context['type'] == '检修':
equipment_id.initial_overhaul_date = equipment_id.initial_overhaul_date_old

View File

@@ -0,0 +1,29 @@
<openerp>
<data>
<record id="action_maintenance_request_wizard" model="ir.actions.act_window">
<field name="name">维保计划</field>
<field name="res_model">maintenance.request.wizard</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<record model="ir.ui.view" id="maintenance_request_wizard_form_view">
<field name="name">maintenance.request.wizard.form.view</field>
<field name="model">maintenance.request.wizard</field>
<field name="arch" type="xml">
<form>
<div>
<field name="name" invisible="1"/>
有未执行的历史维保计划,是否创建新维保计划!!
</div>
<footer>
<button string="确认" name="submit" type="object" class="oe_highlight"/>
<button string="取消" name="cancel" type="object" class="oe_highlight"/>
</footer>
</form>
</field>
</record>
</data>
</openerp>

View File

@@ -10,7 +10,7 @@
""",
'category': 'sf',
'website': 'https://www.sf.jikimo.com',
'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse'],
'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse','jikimo_attachment_viewer'],
'data': [
'data/stock_data.xml',
'data/empty_racks_data.xml',
@@ -45,6 +45,8 @@
'sf_manufacturing/static/src/scss/kanban_change.scss',
'sf_manufacturing/static/src/xml/button_show_on_tree.xml',
'sf_manufacturing/static/src/js/workpiece_delivery_wizard_confirm.js',
'sf_manufacturing/static/src/js/qr.js',
'sf_manufacturing/static/src/xml/qr.xml',
]
},

View File

@@ -37,12 +37,25 @@ class MrpProduction(models.Model):
@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
# 确保 procurement_group_id 和相关字段存在
if production.procurement_group_id:
# 获取相关的 sale_id
sale_order_id = production.procurement_group_id.mrp_production_ids.mapped(
'move_dest_ids.group_id.sale_id')
# 确保 sale_order_id 是有效的 ID 列表
if sale_order_id:
# 获取 sale.order 记录
sale_id = self.env['sale.order'].sudo().browse(sale_order_id.ids) # 使用 mapped 返回的 ID 列表
# 处理 sale_id
if sale_id:
# 假设我们只需要第一个 sale_id
production.deadline_of_delivery = sale_id[0].deadline_of_delivery if sale_id else False
else:
production.deadline_of_delivery = False
else:
production.deadline_of_delivery = False
@api.depends('workorder_ids.tool_state_remark')
def _compute_tool_state_remark(self):
@@ -128,12 +141,12 @@ class MrpProduction(models.Model):
], string='工序状态', default='待装夹')
# 零件图号
part_number = fields.Char('零件图号', readonly=True)
part_number = fields.Char('零件图号', related='product_id.part_number', readonly=True)
# 上传零件图纸
part_drawing = fields.Binary('零件图纸', readonly=True)
part_drawing = fields.Binary('零件图纸', related='product_id.machining_drawings', readonly=True)
quality_standard = fields.Binary('质检标准', readonly=True)
quality_standard = fields.Binary('质检标准', related='product_id.quality_standard', readonly=True)
@api.depends('product_id.manual_quotation')
def _compute_manual_quotation(self):

View File

@@ -59,7 +59,8 @@ class ResMrpWorkOrder(models.Model):
compute='_compute_state', store=True,
default='pending', copy=False, readonly=True, recursive=True, index=True, tracking=True)
delivery_warning = fields.Selection([('normal', '正常'), ('warning', '告警'), ('overdue', '逾期')], string='时效')
delivery_warning = fields.Selection([('normal', '正常'), ('warning', '告警'), ('overdue', '逾期')], string='时效',
tracking=True)
@api.depends('production_id.manual_quotation')
def _compute_manual_quotation(self):
@@ -1051,6 +1052,17 @@ class ResMrpWorkOrder(models.Model):
if workorder.production_id.tool_state in ['1', '2'] and workorder.state == 'ready':
workorder.state = 'waiting'
continue
if (workorder.production_id.tool_state in ['1', '2']
and not workorder.production_id.workorder_ids.filtered(lambda a: a.sequence == 0)
and workorder.production_id.programming_state == '编程中' and workorder.name == '装夹预调'):
if workorder.state == 'pending' and workorder == self.search(
[('production_id', '=', workorder.production_id.id),
('routing_type', '=', '装夹预调'),
('state', 'not in', ['rework', 'done', 'cancel'])],
limit=1,
order="sequence"):
workorder.state = 'waiting'
continue
# elif workorder.routing_type == 'CNC加工' and workorder.state not in ['done', 'cancel', 'progress',
# 'rework']:
@@ -1094,9 +1106,11 @@ class ResMrpWorkOrder(models.Model):
if self.routing_type == '装夹预调':
# 判断是否有坯料的序列号信息
boolean = False
if self.production_id.move_raw_ids[0].move_line_ids:
if self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name:
boolean = True
if self.production_id.move_raw_ids:
if self.production_id.move_raw_ids[0].move_line_ids:
if self.production_id.move_raw_ids[0].move_line_ids:
if self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name:
boolean = True
if not boolean:
raise UserError('制造订单【%s】缺少组件的序列号信息!' % self.production_id.name)
self.pro_code = self.production_id.move_raw_ids[0].move_line_ids[0].lot_id.name

View File

@@ -16,6 +16,12 @@ from OCC.Extend.DataExchange import write_stl_file
class ResProductMo(models.Model):
_inherit = 'product.template'
def _get_machining_precision(self):
machinings = self.env['sf.machining.accuracy'].sudo().search([])
list = [(m.sync_id, m.name) for m in machinings]
return list
model_file = fields.Binary('模型文件')
categ_type = fields.Selection(string='产品的类别', related='categ_id.type', store=True)
model_name = fields.Char('模型名称')
@@ -23,12 +29,7 @@ class ResProductMo(models.Model):
model_width = fields.Float('模型宽(mm)', digits=(16, 3))
model_height = fields.Float('模型高(mm)', digits=(16, 3))
model_volume = fields.Float('模型体积(m³)')
model_machining_precision = fields.Selection([
('0.10', '±0.10mm'),
('0.05', '±0.05mm'),
('0.03', '±0.03mm'),
('0.02', '±0.02mm'),
('0.01', '±0.01mm')], string='加工精度')
model_machining_precision = fields.Selection(selection=_get_machining_precision, string='加工精度')
model_processing_panel = fields.Char('模型加工面板')
model_remark = fields.Char('模型备注说明')
length = fields.Float('长(mm)', digits=(16, 3))
@@ -837,6 +838,11 @@ class ResProductMo(models.Model):
else:
return self.env.ref('sf_dlm.product_uom_cubic_millimeter')
def attachment_update(self, name, res_id, res_field, mimetype):
attachment_info = self.env['ir.attachment'].sudo().search(
[('res_id', '=', res_id), ('res_field', '=', res_field)], limit=1)
attachment_info.write({'name': name, 'mimetype': mimetype})
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品
def product_create(self, product_id, item, order_id, order_number, i):
copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
@@ -875,8 +881,9 @@ 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')])
@@ -884,6 +891,12 @@ class ResProductMo(models.Model):
vals.update({'taxes_id': [(6, 0, [int(tax_id)])]})
copy_product_id.sudo().write(vals)
product_id.product_tmpl_id.active = False
if item['machining_drawings'] and item['machining_drawings_name'] and item['machining_drawings_mimetype']:
self.attachment_update(item['machining_drawings_name'], copy_product_id.product_tmpl_id.id,
'machining_drawings', item['machining_drawings_mimetype'])
if item['quality_standard'] and item['quality_standard_name'] and item['quality_standard_mimetype']:
self.attachment_update(item['quality_standard_name'], copy_product_id.product_tmpl_id.id,
'quality_standard', item['quality_standard_mimetype'])
return copy_product_id
def _get_ids(self, param):

View File

@@ -182,6 +182,11 @@ class StockRule(models.Model):
moves._action_confirm()
return True
def attachment_update(self, name, res_id, res_field):
attachment_info = self.env['ir.attachment'].sudo().search(
[('res_id', '=', res_id), ('res_field', '=', res_field)], limit=1)
attachment_info.write({'name': name})
@api.model
def _run_manufacture(self, procurements):
productions_values_by_company = defaultdict(list)
@@ -267,15 +272,6 @@ class StockRule(models.Model):
workorder_duration += workorder.duration_expected
sale_order = self.env['sale.order'].sudo().search([('name', '=', production.origin)])
# 根据销售订单号查询快速订单
quick_easy_order = self.env['quick.easy.order'].sudo().search([('sale_order_id', '=', sale_order.id)])
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

@@ -0,0 +1,115 @@
/** @odoo-module **/
import { registry } from '@web/core/registry';
import { Component } from '@odoo/owl';
class QRCodeWidget extends Component {
// 初始化组件
setup() {
console.log('QRCodeWidget setup');
this.qrCodeValue = ''; // 初始化为空字符串,用于存储条码
this.inputBuffer = ''; // 存储临时输入的字符
this.inputTimer = null; // 定时器
// 显式绑定上下文
this.onGlobalKeyDown = this.onGlobalKeyDown.bind(this);
window.addEventListener('keydown', this.onGlobalKeyDown);
}
// 清理事件监听器,防止内存泄漏
willUnmount() {
window.removeEventListener('keydown', this.onGlobalKeyDown);
if (this.inputTimer) {
clearTimeout(this.inputTimer);
}
}
// 全局键盘事件监听器
onGlobalKeyDown(event) {
// 如果是Tab键表示扫码输入结束
if (event.key === 'Tab' || event.key === 'Enter') {
this.qrCodeValue = this.inputBuffer; // 完整条码赋值
console.log('完整条码:', this.qrCodeValue);
this.onQRCodeChange(this.qrCodeValue); // 调用父组件的 onQRCodeChange 方法
this.inputBuffer = ''; // 清空临时缓冲区
event.preventDefault(); // 阻止Tab键的默认行为
return;
}
// 只处理可打印字符
if (event.key.length === 1) {
this.inputBuffer += event.key; // 添加到缓冲区
// console.log('当前缓冲区:', this.inputBuffer);
// 清除之前的定时器,重新开始计时
if (this.inputTimer) {
clearTimeout(this.inputTimer);
}
// 启动一个定时器如果500ms内没有新的输入则认为条码输入完成
this.inputTimer = setTimeout(() => {
this.qrCodeValue = this.inputBuffer;
// console.log('定时器触发,完整条码:', this.qrCodeValue);
this.inputBuffer = ''; // 清空缓冲区
}, 500); // 可以根据需要调整时间
}
}
// 处理二维码输入变更
async onQRCodeChange(qrCodeValue) {
console.log('onQRCodeChange二维码输入变更', qrCodeValue); // 检查二维码的输入是否被捕获
if (qrCodeValue) {
// console.log('二维码输入变更');
try {
// 发起 RPC 请求
const result = await this.env.services.rpc('/web/dataset/call_kw', {
model: 'mrp.workorder',
method: 'search_read',
args: [
[['rfid_code', '=', qrCodeValue]], // 查询条件
['id'] // 返回的字段
],
kwargs: {}
});
if (result.length > 0) {
console.log('该二维码对应的工单存在!');
} else {
console.log('未找到对应的工单。');
const routingTypeField = document.querySelector('[name="routing_type"]');
if (routingTypeField) {
let fieldValue = routingTypeField.querySelector('span').getAttribute('raw-value');
console.log('Routing Type Value:', fieldValue);
// 清理多余的引号
fieldValue = fieldValue ? fieldValue.replace(/["]+/g, '') : null;
console.log(fieldValue);
if (fieldValue && fieldValue === '装夹预调') {
// console.log('routing_type 为装夹预调');
// 检查 RFID 值
if (!qrCodeValue || qrCodeValue.length <= 3) return;
// 查找 name="button_start" 按钮并触发点击事件
const startButton = document.querySelector('[name="button_start"]');
if (startButton) {
startButton.click();
}
}
}
}
} catch (error) {
console.error('查询工单时出错:', error);
}
}
}
// 返回模板名称
static template = 'sf_manufacturing.QRCodeWidgetTemplate';
}
// 将自定义字段注册到字段注册表
registry.category('fields').add('qrcode_widget', QRCodeWidget);

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8" ?>
<templates>
<t t-name="sf_manufacturing.QRCodeWidgetTemplate" owl="1">
<!-- <div> -->
<!-- <input type="text" t-att-value="props.value" placeholder="Scan QR code here" /> -->
<!-- </div> -->
<div t-esc="props.value">
</div>
</t>
</templates>

View File

@@ -98,8 +98,6 @@
<field name="production_line_id" readonly="1"/>
<!-- <field name="production_line_state" readonly="1"/>-->
<field name="part_number" string="成品的零件图号"/>
<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"/>
@@ -330,6 +328,16 @@
<xpath expr="//field[@name='components_availability']" position="attributes">
<attribute name="string">投料状态</attribute>
</xpath>
<xpath expr="//sheet//notebook" position="inside">
<page string="零件图纸">
<field name="part_drawing" widget="adaptive_viewer"/>
</page>
</xpath>
<xpath expr="//sheet//notebook" position="inside">
<page string="质检标准">
<field name="quality_standard" widget="adaptive_viewer"/>
</page>
</xpath>
</field>
</record>

View File

@@ -125,9 +125,9 @@
<field name="model">mrp.workorder</field>
<field name="inherit_id" ref="mrp.mrp_production_workorder_form_view_inherit"/>
<field name="arch" type="xml">
<xpath expr="//form" position="inside">
<script src="sf_manufacturing/static/src/js/customRFID.js"/>
</xpath>
<!-- <xpath expr="//form" position="inside"> -->
<!-- <script src="sf_manufacturing/static/src/js/customRFID.js"/> -->
<!-- </xpath> -->
<xpath expr="//header/field[@name='state']" position="replace">
<field name="state" widget="statusbar"
statusbar_visible="pending,waiting,ready,progress,to be detected,done,rework"/>
@@ -225,6 +225,7 @@
<xpath expr="//label[1]" position="before">
<!-- -->
<field name="production_id" invisible="0"/>
<field name="routing_type" string="工单类型" readonly="1"/>
<field name="duration_expected" invisible="1"/>
<field name="date_planned_start" invisible="1"/>
<field name="date_planned_finished" invisible="1"/>
@@ -246,8 +247,8 @@
<field name='process_state' invisible="1"/>
<field name='tag_type' readonly="1" attrs='{"invisible": [("tag_type","=",False)]}'
decoration-danger="tag_type == '重新加工'"/>
<field name="rfid_code" force_save="1" readonly="0" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}"/>
<field name="rfid_code" force_save="1" readonly="1" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}" widget='qrcode_widget'/>
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
</xpath>
@@ -268,8 +269,6 @@
<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>
@@ -468,6 +467,15 @@
<field name='X_deviation_angle' readonly="1"/>
</group>
</page>
<page string="2D加工图纸" attrs="{'invisible': [('routing_type','!=','装夹预调')]}">
<field name="machining_drawings" widget="adaptive_viewer"/>
</page>
<page string="质检标准" attrs="{'invisible': [('routing_type','!=','装夹预调')]}">
<field name="quality_standard" widget="adaptive_viewer"/>
</page>
<page string="工件配送"
attrs="{'invisible': [('routing_type','!=','装夹预调')]}">
<field name="workpiece_delivery_ids">
@@ -521,6 +529,13 @@
<!-- attrs='{"invisible": ["|","|",("state","!=","progress"),("user_permissions","=",False),("results","=","合格")]}'/>-->
<!-- </div>-->
</page>
<page string="2D加工图纸" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
<field name="machining_drawings" widget="adaptive_viewer"/>
</page>
<page string="质检标准" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
<field name="quality_standard" widget="adaptive_viewer"/>
</page>
</xpath>
<xpath expr="//page[1]" position="before">
<page string="CNC程序" attrs='{"invisible": [("routing_type","!=","CNC加工")]}'>
@@ -591,7 +606,6 @@
mrp.group_mrp_manager,sf_base.group_sf_mrp_manager,sf_base.group_sf_equipment_user,sf_base.group_sf_order_user
</attribute>
</xpath>
</field>
</record>

View File

@@ -17,7 +17,7 @@
'data/cron_data.xml',
'data/template_data.xml',
'security/ir.model.access.csv',
'views/mrp_workorder_views.xml',
],
'test': [
],

View File

@@ -13,6 +13,19 @@
<field name="active" eval="True"/>
</record>
<record model="ir.cron" id="ir_cron_sale_order_recover_time_warning">
<field name="name">检查销售订单是否完成并恢复正常时效</field>
<field name="model_id" ref="model_sale_order"/>
<field name="state">code</field>
<field name="code">model._recover_sale_time_warning_func()</field>
<field name="interval_number">10</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"/>

View File

@@ -97,7 +97,7 @@
<field name="send_type">timing</field>
<field name="urgency">normal</field>
<field name="content">### 工单逾期预警
事项:共有[{{warning_num}}]({{url}})工单有逾期风险</field>
事项:共有[{{warning_num}}]({{url}})工单有逾期风险</field>
</record>
<record id="template_mrp_workorder_pre_overdue" model="jikimo.message.template">
@@ -109,7 +109,7 @@
<field name="send_type">timing</field>
<field name="urgency">normal</field>
<field name="content">### 工单已逾期提醒
事项:共有[{{overdue_num}}]({{url}})工单已逾期</field>
事项:共有[{{overdue_num}}]({{url}})工单已逾期</field>
</record>
<record id="template_mrp_workorder_cnc_overdue_warning" model="jikimo.message.template">
@@ -121,7 +121,7 @@
<field name="send_type">timing</field>
<field name="urgency">normal</field>
<field name="content">### 工单逾期预警
事项:共有[{{warning_num}}]({{url}})工单有逾期风险</field>
事项:共有[{{warning_num}}]({{url}})工单有逾期风险</field>
</record>
<record id="template_mrp_workorder_cnc_overdue" model="jikimo.message.template">
@@ -133,7 +133,7 @@
<field name="send_type">timing</field>
<field name="urgency">normal</field>
<field name="content">### 工单已逾期提醒
事项:共有[{{overdue_num}}]({{url}})工单已逾期</field>
事项:共有[{{overdue_num}}]({{url}})工单已逾期</field>
</record>
<record id="template_mrp_workorder_unclamp_overdue_warning" model="jikimo.message.template">
@@ -145,7 +145,7 @@
<field name="send_type">timing</field>
<field name="urgency">normal</field>
<field name="content">### 工单逾期预警
事项:共有[{{warning_num}}]({{url}})工单有逾期风险</field>
事项:共有[{{warning_num}}]({{url}})工单有逾期风险</field>
</record>
<record id="template_mrp_workorder_unclamp_overdue" model="jikimo.message.template">
@@ -157,7 +157,7 @@
<field name="send_type">timing</field>
<field name="urgency">normal</field>
<field name="content">### 工单已逾期提醒
事项:共有[{{overdue_num}}]({{url}})工单已逾期</field>
事项:共有[{{overdue_num}}]({{url}})工单已逾期</field>
</record>
<record id="template_mrp_workorder_surface_overdue_warning" model="jikimo.message.template">
@@ -169,7 +169,7 @@
<field name="send_type">timing</field>
<field name="urgency">normal</field>
<field name="content">### 工单逾期预警
事项:共有[{{warning_num}}]({{url}})工单有逾期风险</field>
事项:共有[{{warning_num}}]({{url}})工单有逾期风险</field>
</record>
<record id="template_mrp_workorder_surface_overdue" model="jikimo.message.template">
@@ -181,7 +181,7 @@
<field name="send_type">timing</field>
<field name="urgency">normal</field>
<field name="content">### 工单已逾期提醒
事项:共有[{{overdue_num}}]({{url}})工单已逾期</field>
事项:共有[{{overdue_num}}]({{url}})工单已逾期</field>
</record>

View File

@@ -1,3 +1,4 @@
# -*- coding: utf-8 -*-
from odoo import models, fields, api
class SFMessageMaintenanceLogs(models.Model):

View File

@@ -34,7 +34,7 @@ class SFMessageSale(models.Model):
picking_id.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id).ids
purchase_order_id.extend(purchase_order_ids)
if purchase_order_id:
purchase_order_list = self.env['purchase.order'].search([('id', 'in', purchase_order_id)])
purchase_order_list = self.env['purchase.order'].sudo().search([('id', 'in', purchase_order_id)])
for purchase_order_info in purchase_order_list:
purchase_order_info.add_queue('坯料采购提醒')
except Exception as e:
@@ -45,7 +45,7 @@ class SFMessageSale(models.Model):
def _get_message(self, message_queue_ids):
contents = []
bussiness_node = None
url = self.env['ir.config_parameter'].get_param('web.base.url')
url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
current_time_strf = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_time = self.env['sf.sync.common'].sudo().get_add_time(current_time_strf)
current_time_datetime = datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S')
@@ -60,7 +60,7 @@ class SFMessageSale(models.Model):
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))])
sale_order_line = self.env['sale.order.line'].sudo().search([('order_id', '=', int(item.res_id))])
product = sale_order_line[0].product_id.name if len(sale_order_line) == 1 else '%s...' % \
sale_order_line[
0].product_id.name
@@ -103,39 +103,70 @@ class SFMessageSale(models.Model):
today = datetime.today().date()
deadline_check = today + timedelta(days=1)
logging.info(f"today: {today}, deadline_check: {deadline_check}")
sale_order = self.sudo().search([('state', 'in', ['sale']), ('deadline_of_delivery', '!=', False)])
sale_order = self.sudo().search(
[('state', 'in', ['sale']), ('deadline_of_delivery', '!=', False), ('delivery_status', '!=', 'full')])
for item in sale_order:
production = self.env['mrp.production'].search([('origin', '=', item.name)])
production = self.env['mrp.production'].sudo().search([('origin', '=', item.name)])
production_not_done = production.filtered(lambda p: p.state not in ['done', 'scrap', 'cancel'])
production_done_count = len(production.filtered(lambda p: p.state in ['done', 'scrap', 'cancel']))
if len(production_not_done) != item.mrp_production_count:
if deadline_check == item.deadline_of_delivery:
if (len(production_not_done) >= 1 and len(production_not_done) != item.mrp_production_count) or len(
production_not_done) != production_done_count:
# logging.info("-----不等于----")
# logging.info(f"name: {item.name}")
# logging.info(
# f"production_not_done: {len(production_not_done)}, production_done_count: {production_done_count}")
# logging.info(f"deadline_of_delivery: {item.deadline_of_delivery}")
if deadline_check == item.deadline_of_delivery and item.delivery_warning not in ['warning']:
item.delivery_warning = 'warning'
elif today == item.deadline_of_delivery:
elif today >= item.deadline_of_delivery and item.delivery_warning not in ['overdue']:
item.delivery_warning = 'overdue'
elif production_done_count == item.mrp_production_count:
# logging.info("-----等于----")
# logging.info(f"name: {item.name}")
# logging.info(
# f"production_not_done: {len(production_not_done)}, production_done_count: {production_done_count}")
# logging.info(f"deadline_of_delivery: {item.deadline_of_delivery}")
if item.delivery_status in ['pending', 'partial']:
if deadline_check == item.deadline_of_delivery:
if deadline_check == item.deadline_of_delivery and item.delivery_warning not in ['warning']:
item.delivery_warning = 'warning'
elif today == item.deadline_of_delivery:
elif today >= item.deadline_of_delivery and item.delivery_warning not in ['overdue']:
item.delivery_warning = 'overdue'
else:
# logging.info("-----1111111----")
# logging.info(f"name: {item.name}")
# logging.info(
# f"production_not_done: {len(production_not_done)}, production_done_count: {production_done_count}")
continue
# 获取业务节点
business_node_ids = {
'warning': self.env.ref('sf_message.bussiness_sale_order_overdue_warning').id,
'overdue': self.env.ref('sf_message.bussiness_sale_order_overdue').id
}
overdue_orders = self.sudo().search([('delivery_warning', 'in', ['warning', 'overdue'])])
for wo in overdue_orders:
message_template = self.env["jikimo.message.template"].search([
("model", "=", self._name),
("bussiness_node_id", "=", self.env.ref('sf_message.bussiness_sale_order_overdue_warning').id)
])
sale_order_has = self.env['jikimo.message.queue'].search([
('res_id', '=', wo.id),
('message_status', '=', 'pending'),
('message_template_id', '=', message_template.id)
])
if not sale_order_has:
if wo.delivery_warning == 'warning':
wo.add_queue('销售订单逾期预警')
elif wo.delivery_warning == 'overdue':
wo.add_queue('销售订单已逾期')
business_node_id = business_node_ids.get(wo.delivery_warning)
if business_node_id:
message_template = self.env["jikimo.message.template"].sudo().search([
("model", "=", self._name),
("bussiness_node_id", "=", business_node_id)
], limit=1)
sale_order_has = self.env['jikimo.message.queue'].sudo().search([
('res_id', '=', wo.id),
('message_status', '=', 'pending'),
('message_template_id', '=', message_template.id)
])
if not sale_order_has:
message_name = '销售订单逾期预警' if wo.delivery_warning == 'warning' else '销售订单已逾期'
wo.add_queue(message_name)
def _recover_sale_time_warning_func(self):
sale_order_done = self.sudo().search([('state', 'in', ['sale']), ('delivery_status', '=', 'full')])
sale_order_overdue = sale_order_done.filtered(lambda x: x.delivery_warning in ['overdue', 'warning'])
if sale_order_overdue:
sale_order_overdue.write({'delivery_warning': 'normal'})
message_queue_ids = self.env["jikimo.message.queue"].sudo().search([
("message_status", "=", "pending"),
("res_id", "in", [item.id for item in sale_order_overdue])
])
if message_queue_ids:
message_queue_ids.write({'message_status': 'cancel'})

View File

@@ -29,14 +29,14 @@ class SFMessageStockPicking(models.Model):
[('origin', '=', record.origin), ('state', '!=', 'done'),
('picking_type_id.sequence_code', '=', 'SFP')])
if not stock_picking_sfp:
stock_picking_send = self.env["jikimo.message.queue"].search([('res_id', '=', record.id)])
stock_picking_send = self.env["jikimo.message.queue"].sudo().search([('res_id', '=', record.id)])
if not stock_picking_send:
record.add_queue('订单发货提醒')
def deal_stock_picking_sfp(self, message_queue_id): # 处理订单发货提醒
content = None
stock_picking = self.env['stock.picking'].search([('id', '=', int(message_queue_id.res_id))])
stock_picking_out = self.env['stock.picking'].search(
stock_picking = self.env['stock.picking'].sudo().search([('id', '=', int(message_queue_id.res_id))])
stock_picking_out = self.env['stock.picking'].sudo().search(
[('origin', '=', stock_picking.origin), ('state', '=', 'assigned'),
('picking_type_id.sequence_code', '=', 'OUT')])
if stock_picking_out and len(stock_picking_out) > 0:
@@ -54,10 +54,10 @@ class SFMessageStockPicking(models.Model):
i = 0
if message_queue_id.message_template_id.name == '坯料发料提醒':
content = message_queue_id.message_template_id.content
stock_picking_line = self.env['stock.picking'].search([('id', '=', int(message_queue_id.res_id))])
mrp_production_info = self.env['mrp.production'].search(
stock_picking_line = self.env['stock.picking'].sudo().search([('id', '=', int(message_queue_id.res_id))])
mrp_production_info = self.env['mrp.production'].sudo().search(
[('name', '=', stock_picking_line.origin)])
mrp_production_list = self.env['mrp.production'].search(
mrp_production_list = self.env['mrp.production'].sudo().search(
[('product_id', '=', mrp_production_info.product_id.id)])
for mrp_production_line in mrp_production_list:
picking_ids = mrp_production_line.picking_ids
@@ -87,9 +87,9 @@ class SFMessageStockPicking(models.Model):
return super(SFMessageStockPicking, self).get_special_url(id, tmplate_name, special_name, model_id)
def request_url(self):
url = self.env['ir.config_parameter'].get_param('web.base.url')
url = self.env['ir.config_parameter'].sudo().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
menu_id = self.env['ir.model.data'].sudo().search([('name', '=', 'module_theme_treehouse')]).id
# 查询参数
params = {'menu_id': menu_id, 'action': action_id, 'model': 'stock.picking',
'view_type': 'kanban'}
@@ -100,9 +100,9 @@ class SFMessageStockPicking(models.Model):
return full_url
def request_url1(self, id):
url = self.env['ir.config_parameter'].get_param('web.base.url')
url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
action_id = self.env.ref('stock.action_picking_tree_all').id
menu_id = self.env['ir.model.data'].search([('name', '=', 'module_theme_treehouse')]).id
menu_id = self.env['ir.model.data'].sudo().search([('name', '=', 'module_theme_treehouse')]).id
# 查询参数
params = {'id': id, 'menu_id': menu_id, 'action': action_id, 'model': 'stock.picking',
'view_type': 'form'}

View File

@@ -26,7 +26,7 @@ class SFMessageWork(models.Model):
contents = []
product_id = []
bussiness_node = None
url = self.env['ir.config_parameter'].get_param('web.base.url')
url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
current_time_strf = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
current_time = self.env['sf.sync.common'].sudo().get_add_time(current_time_strf)
current_time_datetime = datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S')
@@ -39,8 +39,8 @@ class SFMessageWork(models.Model):
for message_queue_id in message_queue_ids:
if message_queue_id.message_template_id.name == '工单已下发通知':
content = message_queue_id.message_template_id.content
mrp_workorder_line = self.env['mrp.workorder'].search([('id', '=', int(message_queue_id.res_id))])
mrp_workorder_list = self.env['mrp.workorder'].search(
mrp_workorder_line = self.env['mrp.workorder'].sudo().search([('id', '=', int(message_queue_id.res_id))])
mrp_workorder_list = self.env['mrp.workorder'].sudo().search(
[('product_id', '=', mrp_workorder_line.product_id.id), ('state', '=', 'ready'),
('routing_type', '=', '装夹预调')])
if len(mrp_workorder_list) > 0 and mrp_workorder_line.product_id.id not in product_id:
@@ -69,11 +69,11 @@ class SFMessageWork(models.Model):
search_condition = [
('delivery_warning', '=', 'warning')] if bussiness_node in template_names['预警'] else [
('delivery_warning', '=', 'overdue')]
record = self.sudo().search(search_condition + [('id', '=', int(item.res_id))])
record = self.sudo().search(search_condition + [('id', '=', int(message_queue_id.res_id))])
if record:
i += 1
if i >= 1:
action_id = self.env.ref('sf_manufacturing.mrp_workorder_action_tablet').id
action_id = self.env.ref('sf_message.mrp_workorder_action_notify').id
url_with_id = f"{url}/web#view_type=list&action={action_id}"
content_template = content.replace('{{url}}', url_with_id)
if bussiness_node in template_names['预警']:
@@ -84,12 +84,13 @@ class SFMessageWork(models.Model):
return contents
def request_url(self):
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
url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
action_id = self.env.ref('sf_message.mrp_workorder_issued_action').id
menu_id = self.env['ir.model.data'].sudo().search([('name', '=', 'module_stock_dropshipping')]).id
active_id = self.env['mrp.workcenter'].sudo().search([('name', '=', '工件装夹中心')]).id
# 查询参数
params = {'menu_id': menu_id, 'action': action_id, 'model': 'mrp.workorder',
'view_type': 'list', 'active_id': 1}
'view_type': 'list', 'active_id': active_id}
# 拼接查询参数
query_string = urlencode(params)
# 拼接URL
@@ -115,21 +116,26 @@ class SFMessageWork(models.Model):
item.date_planned_finished.strftime("%Y-%m-%d %H:%M:%S"))
date_planned_finished = datetime.strptime(date_planned_finished_str, '%Y-%m-%d %H:%M:%S')
twelve_hours_ago = current_time_datetime - timedelta(hours=12)
if current_time_datetime >= date_planned_finished:
if current_time_datetime >= date_planned_finished and item.delivery_warning not in ['overdue']:
logging.info("------overdue-------")
logging.info(f"Workorder: {item.production_id.name}, Current Time: {current_time_datetime}, "
f"Planned Finish: {date_planned_finished}")
item.delivery_warning = 'overdue'
elif twelve_hours_ago <= current_time_datetime <= date_planned_finished:
elif twelve_hours_ago <= current_time_datetime <= date_planned_finished and item.delivery_warning not in [
'warning']:
logging.info("------warning-------")
logging.info(f"Workorder: {item.production_id.name}, Current Time: {current_time_datetime}, "
f"Planned Finish: {date_planned_finished}")
item.delivery_warning = 'warning'
business_node_ids = {
'装夹预调': self.env.ref('sf_message.bussiness_mrp_workorder_pre_overdue_warning').id,
'CNC加工': self.env.ref('sf_message.bussiness_mrp_workorder_cnc_overdue_warning').id,
'解除装夹': self.env.ref('sf_message.bussiness_mrp_workorder_unclamp_overdue_warning').id,
'表面工艺': self.env.ref('sf_message.bussiness_mrp_workorder_surface_overdue_warning').id,
'装夹预调_overdue': self.env.ref('sf_message.bussiness_mrp_workorder_pre_overdue').id,
'装夹预调_warning': self.env.ref('sf_message.bussiness_mrp_workorder_pre_overdue_warning').id,
'CNC加工_overdue': self.env.ref('sf_message.bussiness_mrp_workorder_cnc_overdue').id,
'CNC加工_warning': self.env.ref('sf_message.bussiness_mrp_workorder_cnc_overdue_warning').id,
'解除装夹_overdue': self.env.ref('sf_message.bussiness_mrp_workorder_unclamp_overdue').id,
'解除装夹_warning': self.env.ref('sf_message.bussiness_mrp_workorder_unclamp_overdue_warning').id,
'表面工艺_overdue': self.env.ref('sf_message.bussiness_mrp_workorder_surface_overdue').id,
'表面工艺_warning': self.env.ref('sf_message.bussiness_mrp_workorder_surface_overdue_warning').id,
}
message_templates = {key: self.env["jikimo.message.template"].sudo().search([
("model", "=", self._name),
@@ -137,13 +143,17 @@ class SFMessageWork(models.Model):
]) for key in business_node_ids}
for item in orders:
if item.delivery_warning in ['overdue', 'warning']:
bussiness_node_id = business_node_ids.get(item.routing_type)
if bussiness_node_id and message_templates[item.routing_type]:
message_queue_ids = self.env["jikimo.message.queue"].sudo().search([
("message_template_id", "=", message_templates[item.routing_type].id),
("message_status", "=", "pending"),
("res_id", "=", item.id)
])
warning_type = 'warning' if item.delivery_warning == 'warning' else 'overdue'
key = f"{item.routing_type}_{warning_type}"
bussiness_node_id = business_node_ids.get(key, None)
if bussiness_node_id:
message_template = message_templates.get(key)
if message_template and message_template.id:
message_queue_ids = self.env["jikimo.message.queue"].sudo().search([
("message_template_id", "=", message_template.id),
("message_status", "=", "pending"),
("res_id", "=", item.id)
], limit=1)
if not message_queue_ids:
overdue_message = '工单已逾期' if item.delivery_warning == 'overdue' else '工单逾期预警'
queue_method_name = f'add_queue'
@@ -155,4 +165,11 @@ class SFMessageWork(models.Model):
def _recover_time_warning_func(self):
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'})
if workorder_overdue:
workorder_overdue.write({'delivery_warning': 'normal'})
message_queue_ids = self.env["jikimo.message.queue"].sudo().search([
("message_status", "=", "pending"),
("res_id", "in", [item.id for item in workorder_overdue])
])
if message_queue_ids:
message_queue_ids.write({'message_status': 'cancel'})

View File

@@ -0,0 +1,65 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.actions.act_window" id="mrp_workorder_action_notify">
<field name="name">工单</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.workorder</field>
<field name="view_mode">tree,form</field>
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('mrp.mrp_production_workorder_tree_editable_view')}) ]"/>
<!-- (0, 0, {'view_mode': 'kanban', 'view_id': ref('mrp.workcenter_line_kanban')})-->
<!-- <field name="target">fullscreen</field>-->
<field name="target">current</field>
<field name="domain">[('state', '!=', 'cancel'),('schedule_state', '=', '已排')]</field>
<field name="context">{'search_default_product': 1, 'search_default_workcenter_id':
active_id,'search_default_filter_order_warning':1,'search_default_filter_order_overdue':1,
'search_default_ready': 1, 'search_default_progress': 1}
</field>
<field name="help" type="html">
<p class="o_view_nocontent_workorder">
没有工单要做!
</p>
<p>
工作订单是作为制造订单的一部分执行的操作。
工序在物料清单中定义或直接添加到制造订单中。
</p>
<p>
使用工作台工作中心控制面板直接登记车间中的操作.
平板电脑为您的工人提供工作表,并允许他们报废产品,跟踪时间,
发起维护请求,执行质量测试等.
</p>
</field>
</record>
<record model="ir.actions.act_window" id="mrp_workorder_issued_action">
<field name="name">工单</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">mrp.workorder</field>
<field name="view_mode">tree,form</field>
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('mrp.mrp_production_workorder_tree_editable_view')}) ]"/>
<!-- (0, 0, {'view_mode': 'kanban', 'view_id': ref('mrp.workcenter_line_kanban')})-->
<!-- <field name="target">fullscreen</field>-->
<field name="target">current</field>
<field name="domain">[('state', '!=', 'cancel'),('schedule_state', '=', '已排')]</field>
<field name="context">{'search_default_product': 1, 'search_default_workcenter_id':
active_id,'search_default_ready': 1, 'search_default_progress': 1}
</field>
<field name="help" type="html">
<p class="o_view_nocontent_workorder">
没有工单要做!
</p>
<p>
工作订单是作为制造订单的一部分执行的操作。
工序在物料清单中定义或直接添加到制造订单中。
</p>
<p>
使用工作台工作中心控制面板直接登记车间中的操作.
平板电脑为您的工人提供工作表,并允许他们报废产品,跟踪时间,
发起维护请求,执行质量测试等.
</p>
</field>
</record>
</odoo>

View File

@@ -84,6 +84,8 @@ class ResConfigSettings(models.TransientModel):
_logger.info("同步刀具物料切削速度完成")
self.env['sf.feed.per.tooth'].sync_all_feed_per_tooth()
_logger.info("同步刀具物料每齿走刀量完成")
self.env['sf.machining.accuracy'].sync_machining_accuracy_all()
_logger.info("同步加工精度完成")
except Exception as e:
_logger.info("sf_all_sync error: %s" % e)

View File

@@ -74,6 +74,8 @@ class MrStaticResourceDataSync(models.Model):
_logger.info("同步刀具物料切削速度完成")
self.env['sf.feed.per.tooth'].sync_feed_per_tooth_yesterday()
_logger.info("同步刀具物料每齿走刀量完成")
self.env['sf.machining.accuracy'].sync_machining_accuracy_all()
_logger.info("同步加工精度完成")
except Exception as e:
traceback_error = traceback.format_exc()
logging.error("同步静态资源库失败:%s" % traceback_error)
@@ -3133,3 +3135,36 @@ class CuttingToolBasicParameters(models.Model):
})
else:
raise ValidationError("刀具物料基本参数认证未通过")
class MachiningAccuracySync(models.Model):
_inherit = 'sf.machining.accuracy'
_description = '加工精度'
url = '/api/machining_accuracy/list'
def sync_machining_accuracy_all(self):
config = self.env['res.config.settings'].get_values()
headers = Common.get_headers(self, config['token'], config['sf_secret_key'])
strUrl = config['sf_url'] + self.url
r = requests.post(strUrl, json={}, data=None, headers=headers)
r = r.json()
result = json.loads(r['result'])
_logger.info('加工精度:%s' % result)
if result['status'] == 1:
machining_accuracy_all_list = result['machining_accuracy_all_list']
# 获取同步的id集合
ids = [obj['id'] for obj in machining_accuracy_all_list]
self.env['sf.machining.accuracy'].sudo().search(
[('sync_id', 'not in', ids)]).unlink()
for time in machining_accuracy_all_list:
machining_accuracy = self.env['sf.machining.accuracy'].sudo().search(
[('sync_id', '=', time['id'])])
if machining_accuracy:
machining_accuracy.name = time['name']
machining_accuracy.standard_tolerance = time['standard_tolerance']
else:
self.env['sf.machining.accuracy'].sudo().create({
"sync_id": time['id'],
"name": time['name'],
"standard_tolerance": time['standard_tolerance'],
})

View File

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

View File

@@ -31,8 +31,8 @@ class SfQualityCncTest(models.Model):
("technology", "工艺"), ("customer redrawing", "客户改图")], string="原因")
detailed_reason = fields.Text('详细原因')
# machining_drawings = fields.Binary(related='workorder_id.machining_drawings', string='2D加工图纸', readonly=True)
# quality_standard = fields.Binary(related='workorder_id.quality_standard', string='质检标准', readonly=True)
machining_drawings = fields.Binary('2D加工图纸', related='workorder_id.machining_drawings', readonly=True)
quality_standard = fields.Binary('质检标准', related='workorder_id.quality_standard', readonly=True)
def submit_pass(self):
if self.test_results in ['返工', '报废']:

View File

@@ -107,10 +107,10 @@
</group>
</page>
<page string="2D图纸">
<!-- <field name="machining_drawings" string="" widget="pdf_viewer"/>-->
<field name="machining_drawings" string="" widget="adaptive_viewer"/>
</page>
<page string="客户质量标准">
<!-- <field name="quality_standard" string=""/>-->
<field name="quality_standard" string="" widget="adaptive_viewer"/>
</page>
<page string="其他" attrs="{'invisible': [('state','=', 'waiting')]}">
<group>

View File

@@ -20,6 +20,12 @@ class QuickEasyOrder(models.Model):
_description = '简易下单'
_order = 'id desc'
def _get_machining_precision(self):
machinings = self.env['sf.machining.accuracy'].sudo().search([])
list = [(m.sync_id, m.name) for m in machinings]
return list
name = fields.Char('订单编号', default=lambda self: self.env['ir.sequence'].next_by_code('quick.easy.order'))
model_length = fields.Float('长(mm)', digits=(16, 3))
model_width = fields.Float('宽(mm)', digits=(16, 3))
@@ -27,12 +33,7 @@ class QuickEasyOrder(models.Model):
model_volume = fields.Float('体积(mm³)', digits=(16, 3))
model_processing_side = fields.Char('加工面', default='A')
model_feature = fields.Char('特征')
machining_precision = fields.Selection([
('0.10', '±0.10mm'),
('0.05', '±0.05mm'),
('0.03', '±0.03mm'),
('0.02', '±0.02mm'),
('0.01', '±0.01mm')], string='加工精度', default='0.10')
machining_precision = fields.Selection(selection=_get_machining_precision, string='加工精度')
material_id = fields.Many2one('sf.production.materials', '材料', tracking=True)
material_model_id = fields.Many2one('sf.materials.model', '型号', domain="[('materials_id', '=', material_id)]",
tracking=True)
@@ -219,7 +220,14 @@ class QuickEasyOrder(models.Model):
'total_amount': item.price,
'remark': '',
'manual_quotation': True,
'barcode': barcode
'barcode': barcode,
'part_number': item.part_drawing_number,
'machining_drawings_name': '',
'quality_standard_name': '',
'machining_drawings_mimetype': '',
'quality_standard_mimetype': '',
'machining_drawings': item.machining_drawings,
'quality_standard': '',
})
# res['bfm_process_order_list'] = json.dumps(res['bfm_process_order_list'])
product_id = self.env.ref('sf_dlm.product_template_sf').sudo()

View File

@@ -55,7 +55,8 @@ class ReSaleOrder(models.Model):
store=True, readonly=False, copy=False, precompute=True,
states=READONLY_FIELD_STATES, default=fields.Datetime.now)
delivery_warning = fields.Selection([('normal', '正常'), ('warning', '告警'), ('overdue', '逾期')], string='时效')
delivery_warning = fields.Selection([('normal', '正常'), ('warning', '告警'), ('overdue', '逾期')], string='时效',
tracking=True)
# 业务平台分配工厂后在智能工厂先创建销售订单
def sale_order_create(self, company_id, delivery_name, delivery_telephone, delivery_address,
@@ -117,12 +118,16 @@ class ReSaleOrder(models.Model):
# 业务平台分配工厂时在创建完产品后再创建销售明细信息
def sale_order_create_line(self, product, item):
machining_accuracy_name = ''
if product.model_machining_precision:
machining_accuracy_name = self.env['sf.machining.accuracy'].sudo().search(
[('sync_id', '=', product.model_machining_precision)]).name
vals = {
'order_id': self.id,
'product_id': product.id,
'name': '%s/%s/%s/%s/±%s/%s' % (
'name': '%s/%s/%s/%s/%s/%s' % (
product.model_long, product.model_width, product.model_height, product.model_volume,
product.model_machining_precision,
machining_accuracy_name,
product.materials_id.name),
'price_unit': product.list_price,
'product_uom_qty': item['number'],

View File

@@ -6,6 +6,25 @@
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"/>
<field name="arch" type="xml">
<xpath expr="//header/button[@name='action_rfq_send'][1]" position="before">
<button name="button_confirm" type="object" states="sent" string="Confirm Order"
context="{'validate_analytic': True}" class="oe_highlight" id="bid_confirm"
data-hotkey="v"/>
<button name="button_confirm" type="object" states="draft" context="{'validate_analytic': True}"
string="Confirm Order" id="draft_confirm"/>
<button name="button_cancel" states="draft,to approve,sent,purchase" string="Cancel" type="object" data-hotkey="x" />
</xpath>
<xpath expr="//header/button[@name='button_cancel'][2]" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//header/button[@name='button_confirm'][3]" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//header/button[@name='button_confirm'][4]" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<field name="partner_id" position="replace">
<field name="partner_id" widget="res_partner_many2one" context="{'is_supplier': True }"/>
</field>

View File

@@ -80,8 +80,8 @@
<field name="unit_price"/>
<field name="price" options="{'format': false}"/>
<field name="part_drawing_number"/>
<!-- <field name="machining_drawings" filename="machining_drawings_name" widget="pdf_viewer"/>-->
<!-- <field name="machining_drawings_name" invisible="1"/>-->
<field name="machining_drawings" filename="machining_drawings_name" widget="pdf_viewer"/>
<field name="machining_drawings_name" invisible="1"/>
<field name="sale_order_id"
attrs='{"invisible": [("sale_order_id","=",False)],"readonly": [("sale_order_id","!=",False)]}'/>
</group>

View File

@@ -95,7 +95,7 @@
<attribute name="attrs">{'readonly': [('state', 'in', ['cancel','sale'])]}</attribute>
</field>
<field name="payment_term_id" position="after">
<field name="deadline_of_delivery" readonly="1"/>
<field name="deadline_of_delivery" readonly="0"/>
<field name="payments_way" attrs="{'readonly': [('state', 'in', ('sale','cancel'))]}"/>
<field name="pay_way" attrs="{'readonly': [('state', 'in', ('sale','cancel'))]}"/>
<!-- <field name="schedule_status" readonly="1"/> -->

View File

@@ -51,6 +51,8 @@ class FunctionalCuttingToolEntity(models.Model):
string='位置', compute='_compute_current_location_id', store=True)
image = fields.Binary('图片', readonly=True)
stock_num = fields.Integer('库存变更次数', default=0)
safe_inventory_id = fields.Many2one('sf.real.time.distribution.of.functional.tools',
string='功能刀具安全库存', readonly=True)
@@ -71,7 +73,7 @@ class FunctionalCuttingToolEntity(models.Model):
})
@api.depends('barcode_id.quant_ids', 'barcode_id.quant_ids.location_id', 'functional_tool_status',
'current_shelf_location_id')
'current_shelf_location_id', 'stock_num')
def _compute_current_location_id(self):
for record in self:
if record.functional_tool_status == '已拆除':

View File

@@ -53,6 +53,13 @@ class StockMoveLine(models.Model):
[('barcode_id', '=', line_id.lot_id.id),
('functional_tool_status', '=', '正常')]).cnc_function_tool_use_verify()
for move_line in move_lines:
if move_line.lot_id:
tool_id = self.env['sf.functional.cutting.tool.entity'].sudo().search(
[('barcode_id', '=', move_line.lot_id.id),
('functional_tool_status', '=', '正常')])
tool_id.stock_num += tool_id.stock_num
class StockPicking(models.Model):
_inherit = 'stock.picking'