Compare commits

..

575 Commits

Author SHA1 Message Date
胡尧
fc378df597 Merge branch 'release/release_2.6' 2024-12-08 19:56:05 +08:00
mgw
ab692dfb25 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-12-05 18:25:08 +08:00
马广威
6f9cea2759 Accept Merge Request #1606: (feature/制造功能优化 -> develop)
Merge Request: 特殊表面工艺采购单还是有合并的情况-且重复了

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1606?initial=true
2024-12-05 17:03:08 +08:00
mgw
0601e123fb Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-12-05 17:01:36 +08:00
mgw
08e4541a96 特殊表面工艺采购单还是有合并的情况-且重复了 2024-12-05 17:01:10 +08:00
胡尧
66acc19e89 Accept Merge Request #1605: (feature/sale_order_route_pick -> develop)
Merge Request: 工艺设计新增工序只选择了参数时确认增加提示

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1605?initial=true
2024-12-05 16:56:20 +08:00
胡尧
5b94a0624c 工艺设计新增工序只选择了参数时确认增加提示 2024-12-05 16:55:51 +08:00
胡尧
1b5b2fd6f9 Accept Merge Request #1604: (feature/sale_order_route_pick -> develop)
Merge Request: 处理供应商相同的特殊表面工艺不能删除的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1604?initial=true
2024-12-05 16:36:55 +08:00
胡尧
54c502dd64 处理供应商相同的特殊表面工艺不能删除的问题 2024-12-05 16:36:33 +08:00
胡尧
e3db40ae25 Accept Merge Request #1603: (feature/sale_order_route_pick -> develop)
Merge Request: 解决删除表面工艺,多增加了采购单的bug

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1603
2024-12-05 15:09:49 +08:00
胡尧
52ab962ace 解决删除表面工艺,多增加了采购单的bug 2024-12-05 15:09:04 +08:00
胡尧
05247ee8d9 Accept Merge Request #1602: (feature/sale_order_route_pick -> develop)
Merge Request: 特殊表面工艺工单没有完成对应采购单时工单处于等待组件

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1602?initial=true
2024-12-05 13:42:33 +08:00
胡尧
dbf75684ee 特殊表面工艺工单没有完成对应采购单时工单处于等待组件 2024-12-05 13:42:07 +08:00
马广威
cb2319492b Accept Merge Request #1601: (feature/制造功能优化 -> develop)
Merge Request: 制造订单退回调整-删除表面工艺后对应的外协出入库单没有变成取消状态

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1601
2024-12-05 11:49:03 +08:00
mgw
731e6abc90 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化
# Conflicts:
#	sf_manufacturing/models/mrp_workorder.py
2024-12-05 11:48:07 +08:00
mgw
58b33b6c8d 制造订单退回调整-删除表面工艺后对应的外协出入库单没有变成取消状态 2024-12-05 11:05:43 +08:00
胡尧
43c8bbda71 Accept Merge Request #1600: (feature/sale_order_route_pick -> develop)
Merge Request: 解决表面工艺工单完成后,生产入库单未就绪的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1600?initial=true
2024-12-05 09:32:00 +08:00
胡尧
e011e4cfd6 解决表面工艺工单完成后,生产入库单未就绪的问题 2024-12-05 09:31:06 +08:00
胡尧
c8fd2d69bd Accept Merge Request #1599: (feature/sale_order_route_pick -> develop)
Merge Request: 修改工艺外协工单

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1599?initial=true
2024-12-05 08:37:05 +08:00
胡尧
ef1f7b1d08 解决冲突 2024-12-05 08:36:48 +08:00
胡尧
5f12976d8f 修改表面工艺外协工单流程 2024-12-05 01:33:46 +08:00
胡尧
ef60f36c90 修改工艺外协工单 2024-12-04 20:42:34 +08:00
廖丹龙
c8ed45b1a7 Accept Merge Request #1598: (feature/manufactur_order -> 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/1598?initial=true
2024-12-04 16:43:58 +08:00
liaodanlong
57fe68bae8 Merge remote-tracking branch 'origin/feature/manufactur_order' into feature/manufactur_order 2024-12-04 16:42:13 +08:00
liaodanlong
aa32fdcd07 坯料长宽高修改 2024-12-04 16:41:42 +08:00
管欢
d0d59135e3 Accept Merge Request #1597: (feature/manufactur_order -> 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/1597
2024-12-04 16:39:44 +08:00
guanhuan
27ec5b1b74 多个制造订单菜单修复 2024-12-04 16:13:55 +08:00
禹翔辉
2c1caabce6 Accept Merge Request #1596: (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/1596
2024-12-04 15:41:11 +08:00
yuxianghui
8f3cd9ff36 Merge branch 'feature/隐藏返工入口' into feature/界面优化 2024-12-04 15:39:05 +08:00
yuxianghui
6366904c91 添加客供料入库单的合并选项 2024-12-04 15:37:58 +08:00
马广威
7f3e6de127 Accept Merge Request #1595: (feature/制造功能优化 -> develop)
Merge Request: 处理“制造订单退回调整删除特殊表面工艺后对应坯料的采购单也变成取消状态了”

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1595?initial=true
2024-12-04 12:24:18 +08:00
yuxianghui
5b43cceb94 计划模块的【制造订单生产计划】页面菜单名称改为【CNC产线计划排程】 2024-12-04 11:56:38 +08:00
mgw
d933416b2d 处理“制造订单退回调整删除特殊表面工艺后对应坯料的采购单也变成取消状态了” 2024-12-04 11:52:52 +08:00
yuxianghui
e260ef01f0 隐藏销售模块的 快速订单 菜单 2024-12-04 11:43:02 +08:00
廖丹龙
0fef3d7a63 Accept Merge Request #1594: (feature/manufactur_order -> 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/1594?initial=true
2024-12-04 10:49:12 +08:00
liaodanlong
dc5c0b1d1e Merge branch 'refs/heads/develop' into feature/manufactur_order 2024-12-04 10:46:38 +08:00
liaodanlong
9a1cde6abc 表面工艺采购单与调拨单拆分 2024-12-04 10:45:46 +08:00
胡尧
29864b8bb2 Accept Merge Request #1591: (feature/manufactur_order -> 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/1591
2024-12-04 10:23:35 +08:00
胡尧
aa5294f110 Accept Merge Request #1593: (feature/sale_order_route_pick -> develop)
Merge Request: 处理报错是英文的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1593?initial=true
2024-12-04 10:23:19 +08:00
胡尧
4387d343b5 处理报错是英文的问题 2024-12-04 10:22:50 +08:00
胡尧
ff979aa34b Accept Merge Request #1592: (feature/sale_order_route_pick -> develop)
Merge Request: 解决外协调拨单不能完成的bug

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1592?initial=true
2024-12-04 10:17:34 +08:00
胡尧
21af368068 解决外协调拨单不能完成的bug 2024-12-04 10:16:30 +08:00
guanhuan
d6afd556d3 询价单查询 2024-12-03 15:59:10 +08:00
胡尧
778d2c4ec5 Accept Merge Request #1590: (feature/sale_order_route_pick -> develop)
Merge Request: 去掉多余的视图

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1590?initial=true
2024-12-03 10:04:29 +08:00
禹翔辉
fff29b36ee Accept Merge Request #1587: (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/1587
2024-12-03 10:04:23 +08:00
胡尧
fedb79a142 去掉多余的视图 2024-12-03 10:03:05 +08:00
胡尧
d06816052f Accept Merge Request #1589: (feature/sale_order_route_pick -> develop)
Merge Request: 修改文件位置

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1589?initial=true
2024-12-02 19:48:02 +08:00
胡尧
5739e167f4 修改文件位置 2024-12-02 19:46:45 +08:00
胡尧
a249548a20 Accept Merge Request #1588: (feature/sale_order_route_pick -> develop)
Merge Request: 修改文件位置

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1588?initial=true
2024-12-02 16:37:26 +08:00
胡尧
7b6538d01e 修改文件位置 2024-12-02 16:29:33 +08:00
yuxianghui
7025bde56e 隐藏手动返工报废入口 2024-12-02 13:46:20 +08:00
胡尧
3585af0cea Accept Merge Request #1586: (feature/sale_order_route_pick -> develop)
Merge Request: 调整文件结构

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1586?initial=true
2024-12-02 11:03:46 +08:00
胡尧
5406224c6f 调整文件结构 2024-12-02 11:02:32 +08:00
胡尧
18ff0bba54 Accept Merge Request #1585: (feature/sale_order_route_pick -> develop)
Merge Request: 调整文件结构

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1585?initial=true
2024-12-02 10:36:36 +08:00
胡尧
7c13e57ea2 调整文件结构 2024-12-02 10:36:06 +08:00
胡尧
b8605b9a97 Accept Merge Request #1584: (feature/sale_order_route_pick -> develop)
Merge Request: 调整文件结构,解决依赖问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1584?initial=true
2024-12-02 10:07:11 +08:00
胡尧
4baa7a9b44 调整文件结构,解决依赖问题 2024-12-02 10:06:11 +08:00
黄焱
3af2f3e03b Accept Merge Request #1583: (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/1583?initial=true
2024-11-29 16:27:46 +08:00
hy
dc68ecb584 计划排程列表和工单列表筛选项和数量显示重叠了 2024-11-29 16:26:32 +08:00
马广威
421f107728 Accept Merge Request #1582: (feature/制造功能优化 -> develop)
Merge Request: 调整库存概览翻译

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1582?initial=true
2024-11-29 15:59:40 +08:00
mgw
1f1bdd08ed 调整库存概览翻译 2024-11-29 15:59:04 +08:00
黄焱
1a7059aad1 Accept Merge Request #1581: (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/1581
2024-11-29 14:40:43 +08:00
hy
8d461e61b3 甘特图增加判断 2024-11-29 14:37:48 +08:00
马广威
fa0ca83709 Accept Merge Request #1580: (feature/制造功能优化 -> develop)
Merge Request: 调整内部转账翻译

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1580?initial=true
2024-11-29 14:33:46 +08:00
mgw
a783f9c271 调整内部转账翻译 2024-11-29 14:32:58 +08:00
胡尧
b4901e89d6 Accept Merge Request #1579: (feature/sale_order_route_pick -> develop)
Merge Request: 权限调整

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1579
2024-11-29 14:15:06 +08:00
胡尧
6690d3f2cb 权限调整 2024-11-29 14:14:14 +08:00
马广威
21d6989182 Accept Merge Request #1578: (feature/制造功能优化 -> develop)
Merge Request: 调整计划调度岗对工单的权限

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1578?initial=true
2024-11-29 11:30:30 +08:00
mgw
97ad3567e3 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-11-29 11:24:50 +08:00
mgw
22a69df31b 调整计划调度岗对工单的权限 2024-11-29 11:24:27 +08:00
胡尧
c0ad9d8977 Accept Merge Request #1577: (feature/sale_order_route_pick -> develop)
Merge Request: 解决单个制造的bug

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1577?initial=true
2024-11-29 10:49:24 +08:00
胡尧
a927d0e9cb 解决单个制造的bug 2024-11-29 10:44:48 +08:00
杨金灵
5759ca1ca5 Accept Merge Request #1576: (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/1576
2024-11-29 10:07:57 +08:00
jinling.yang
9955157dd3 还原代码 2024-11-29 10:07:17 +08:00
jinling.yang
d42de42709 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复外协出入库单 2024-11-29 10:04:23 +08:00
jinling.yang
a7dc3a1227 修复表面外协 2024-11-29 10:03:44 +08:00
胡尧
9c5f525e90 Accept Merge Request #1575: (feature/sale_order_route_pick -> develop)
Merge Request: 处理工单中的工艺外协按钮点击报错的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1575?initial=true
2024-11-29 09:45:38 +08:00
胡尧
db8bd659c3 处理工单中的工艺外协按钮点击报错的问题 2024-11-29 09:45:06 +08:00
胡尧
0dab394d1b Accept Merge Request #1574: (feature/sale_order_route_pick -> develop)
Merge Request: 解决精坯料计算精度问题,排程加上预留时间

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1574?initial=true
2024-11-29 09:00:32 +08:00
胡尧
9a9e47b4ff 解决精坯料计算精度问题,排程加上预留时间 2024-11-29 08:59:52 +08:00
jinling.yang
deb2f6ca64 修复采购 2024-11-28 18:01:29 +08:00
禹翔辉
5bce9bb816 Accept Merge Request #1573: (feature/坯料制造序号优化 -> develop)
Merge Request: 处理 坯料的制造订单生成的批次序列号不对 的bug

Created By: @禹翔辉
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1573
2024-11-28 17:52:46 +08:00
yuxianghui
ccda6b627d Merge branch 'feature/制造订单状态优化_1' into feature/坯料制造序号优化 2024-11-28 17:51:22 +08:00
yuxianghui
20cfbf7230 处理 坯料的制造订单生成的批次序列号不对 的bug 2024-11-28 17:50:12 +08:00
jinling.yang
805eabd07e Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复外协出入库单 2024-11-28 16:01:11 +08:00
jinling.yang
c42c053d66 修复表面工艺外协及工艺设计 2024-11-28 15:59:17 +08:00
禹翔辉
d8e51f44ac Accept Merge Request #1572: (feature/制造订单状态优化_1 -> 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/1572
2024-11-28 15:54:12 +08:00
yuxianghui
0b5645496b Merge branch 'feature/工单状态优化_2' into feature/制造订单状态优化_1 2024-11-28 15:52:31 +08:00
yuxianghui
2c37dbf5c4 制造订单状态优化 2024-11-28 15:51:54 +08:00
胡尧
cd6dc7a47e Accept Merge Request #1571: (feature/sale_order_route_pick -> develop)
Merge Request: 修改坯料冗余描述

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1571?initial=true
2024-11-28 15:42:05 +08:00
胡尧
7362f0cd30 修改坯料冗余描述 2024-11-28 15:41:39 +08:00
胡尧
de2924883c Accept Merge Request #1570: (feature/sale_order_route_pick -> develop)
Merge Request: 修改排程逻辑

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1570?initial=true
2024-11-28 15:22:23 +08:00
胡尧
942aa469e3 修改排程逻辑 2024-11-28 15:21:54 +08:00
胡尧
d57cc59115 修改排程逻辑 2024-11-28 15:20:56 +08:00
禹翔辉
f8ff3a18a0 Accept Merge Request #1569: (feature/工单状态优化_2 -> 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/1569?initial=true
2024-11-28 15:11:30 +08:00
胡尧
96171013d6 修改排程 2024-11-28 15:10:45 +08:00
yuxianghui
d741d6ccf5 Merge branch 'feature/制造订单状态优化' into feature/工单状态优化_2 2024-11-28 15:09:51 +08:00
yuxianghui
8ff73d5647 工单状态优化 2024-11-28 15:09:11 +08:00
胡尧
5d3d04b5d3 Accept Merge Request #1567: (feature/sale_order_route_pick -> develop)
Merge Request: 解决询价单中自动化产线加工的订单不生成编程单的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1567
2024-11-28 15:05:57 +08:00
马广威
75ed1a6889 Accept Merge Request #1568: (feature/制造功能优化 -> develop)
Merge Request: 修复仓储岗角色权限问题

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1568?initial=true
2024-11-28 13:39:47 +08:00
mgw
9bfbea11db Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-11-28 13:38:43 +08:00
mgw
5eea260618 修复仓储岗角色权限问题 2024-11-28 13:38:14 +08:00
胡尧
f1e70d2c66 解决询价单中自动化产线加工的订单不生成编程单的问题 2024-11-28 11:36:32 +08:00
jinling.yang
da22cb301e Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-28 10:48:28 +08:00
jinling.yang
2b93f2a253 Merge branch 'feature/修复制造订单-采购单' into develop 2024-11-28 10:46:42 +08:00
杨金灵
8ab42ff7da Accept Merge Request #1566: (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/1566?initial=true
2024-11-28 10:45:25 +08:00
jinling.yang
9bf57005f0 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复制造订单-采购单 2024-11-28 10:41:13 +08:00
jinling.yang
a80d498eab 修复制造订单-采购单 2024-11-28 10:40:48 +08:00
胡尧
4847596072 Accept Merge Request #1565: (feature/sale_order_route_pick -> develop)
Merge Request: 修改排程单的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1565?initial=true
2024-11-28 10:18:35 +08:00
胡尧
d4ba58b55a 修改排程单的问题 2024-11-28 10:17:03 +08:00
杨金灵
306d5074f2 Accept Merge Request #1563: (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/1563
2024-11-28 10:03:05 +08:00
马广威
745abaab2e Accept Merge Request #1564: (feature/制造功能优化 -> develop)
Merge Request: 修复计划调度岗和生产总监权限问题

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1564?initial=true
2024-11-28 10:00:24 +08:00
jinling.yang
c22b91f9d9 优化采购:一个制造订单对应一个采购单 2024-11-28 09:59:01 +08:00
yuxianghui
0bea93ea46 1、添加返工向导中选择返工工单限制条件 2024-11-27 17:54:59 +08:00
jinling.yang
ecf683e663 修复采购 2024-11-27 17:54:31 +08:00
胡尧
0af7ef905d Accept Merge Request #1562: (feature/sale_order_route_pick -> develop)
Merge Request: 解决工单完成的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1562?initial=true
2024-11-27 17:40:58 +08:00
胡尧
c169c0a80b 解决工单完成的问题 2024-11-27 17:40:35 +08:00
禹翔辉
878d62f483 Accept Merge Request #1561: (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/1561?initial=true
2024-11-27 16:31:34 +08:00
yuxianghui
8a33cea8bd Merge branch 'feature/工序排序优化' into feature/制造订单状态优化 2024-11-27 16:19:18 +08:00
yuxianghui
d6c194eaa8 处理制造订单状态问题。 2024-11-27 16:18:18 +08:00
胡尧
13d32c26b6 Accept Merge Request #1560: (feature/sale_order_route_pick -> develop)
Merge Request: 成品委外,坯料自加工的制造排程单生成

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1560?initial=true
2024-11-27 15:03:51 +08:00
胡尧
df146a4b58 成品委外,坯料自加工的制造排程单生成 2024-11-27 15:02:42 +08:00
廖丹龙
4a02034ee3 Accept Merge Request #1559: (feature/delivery_status -> 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/1559
2024-11-27 14:52:18 +08:00
liaodanlong
acb24d69e3 排程 采购单条件判断 2024-11-27 14:42:41 +08:00
胡尧
56cfeac214 修改坯料冗余描述 2024-11-27 11:16:11 +08:00
胡尧
b86ad6e5bb Accept Merge Request #1558: (release/release_2.6 -> develop)
Merge Request: 修改数据初始化

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1558?initial=true
2024-11-27 11:15:36 +08:00
胡尧
f57c95496a 修改数据初始化 2024-11-27 11:06:05 +08:00
禹翔辉
826b2c3e94 Accept Merge Request #1557: (feature/工序排序优化 -> develop)
Merge Request: 1、工序排序方法优化;2、返工优化

Created By: @禹翔辉
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1557?initial=true
2024-11-27 11:05:30 +08:00
yuxianghui
29b43c6ab8 Merge branch 'feature/返工优化_5' into feature/工序排序优化 2024-11-27 11:01:49 +08:00
yuxianghui
a434227807 1、工序排序方法优化;2、返工优化 2024-11-27 11:01:10 +08:00
胡尧
3a7fb81276 Accept Merge Request #1556: (feature/sale_order_route_pick -> develop)
Merge Request: 解决工单开始结束的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1556?initial=true
2024-11-27 09:54:04 +08:00
胡尧
12224fc892 解决工单开始结束的问题 2024-11-27 09:53:17 +08:00
胡尧
64fdedf726 修改工单开始 2024-11-27 08:37:12 +08:00
yuxianghui
d3b61f320f 1、返工优化 2024-11-26 18:01:02 +08:00
jinling.yang
6be7c05415 优化代码 2024-11-26 17:05:45 +08:00
mgw
92b924754d 修复计划调度岗和生产总监权限问题 2024-11-26 16:56:47 +08:00
jinling.yang
40ddfdd48f Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-26 16:47:22 +08:00
杨金灵
afa5ad36f2 Accept Merge Request #1554: (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/1554
2024-11-26 16:32:47 +08:00
黄焱
916a5c1054 Accept Merge Request #1555: (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/1555?initial=true
2024-11-26 16:31:28 +08:00
jinling.yang
ea914be4c7 修复采购链接 2024-11-26 16:21:17 +08:00
jinling.yang
e6eb41ad24 优化代码 2024-11-26 16:15:50 +08:00
jinling.yang
43ee2d1836 回滚代码 2024-11-26 16:08:30 +08:00
jinling.yang
3bd4e6723e Merge branch 'feature/修复表面工艺' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺 2024-11-26 16:05:52 +08:00
jinling.yang
0e763c2ca6 还原代码 2024-11-26 16:05:37 +08:00
jinling.yang
34353e3614 修复表面工艺 2024-11-26 16:05:23 +08:00
jinling.yang
d91c7b22d7 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-26 16:04:10 +08:00
jinling.yang
ac4861c76e Merge branch 'feature/修复表面工艺' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺 2024-11-26 16:01:59 +08:00
jinling.yang
6edd124556 优化 2024-11-26 16:01:20 +08:00
jinling.yang
f426183d22 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺 2024-11-26 15:59:31 +08:00
jinling.yang
33db91f799 Revert "修复表面工艺"
This reverts commit b5beaad7bf.
2024-11-26 15:56:22 +08:00
jinling.yang
8803380a30 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/new1 2024-11-26 15:37:40 +08:00
jinling.yang
b5beaad7bf 修复表面工艺 2024-11-26 15:37:19 +08:00
hy
304259c653 增加列表多选配置 2024-11-26 15:22:41 +08:00
胡尧
5ccc836b20 Accept Merge Request #1553: (feature/sale_order_route_pick -> develop)
Merge Request: 修改排程单bug

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1553?initial=true
2024-11-26 11:51:47 +08:00
胡尧
087bb0e8fe 取消制造订单排程时,将其下所有子制造订单改为已排状态的逻辑 2024-11-26 11:51:09 +08:00
胡尧
09a476ffa5 修改子制造订单的销售订单 2024-11-26 11:26:17 +08:00
禹翔辉
429ad2b77c Accept Merge Request #1552: (feature/返工优化_5 -> develop)
Merge Request: 1、返工向导模型添加新的工单字段;2、工单tree视图添加重新加工分类

Created By: @禹翔辉
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1552
2024-11-26 11:17:22 +08:00
yuxianghui
c215e3dc27 Merge branch 'feature/采购优化' into feature/返工优化_5 2024-11-26 11:15:56 +08:00
yuxianghui
0a1da79487 1、返工向导模型添加新的工单字段;2、工单tree视图添加重新加工分类 2024-11-26 11:14:45 +08:00
jinling.yang
42e4e15cdb Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-26 10:58:20 +08:00
胡尧
a3e7a23979 Accept Merge Request #1551: (feature/sale_order_route_pick -> develop)
Merge Request: 采购单根据采购类型拆分

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1551
2024-11-26 10:48:25 +08:00
胡尧
430a628e18 Merge branch 'develop' into feature/sale_order_route_pick 2024-11-26 10:47:32 +08:00
胡尧
5f70690af5 采购单根据采购类型拆分 2024-11-26 10:45:43 +08:00
杨金灵
b852933a9e Accept Merge Request #1550: (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/1550
2024-11-26 10:44:56 +08:00
jinling.yang
074c45aa3d Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复制造订单问题
# Conflicts:
#	sf_manufacturing/models/stock.py
2024-11-26 10:41:30 +08:00
jinling.yang
a52545d19a Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-26 10:39:23 +08:00
jinling.yang
3e55bb4717 修复制造订单批量调整 2024-11-26 10:39:04 +08:00
jinling.yang
be408b98de 修复制造订单相关问题 2024-11-25 18:00:06 +08:00
马广威
12cc5fd0d2 Accept Merge Request #1549: (feature/制造功能优化 -> develop)
Merge Request: 内部调拨单缺少源单据

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1549?initial=true
2024-11-25 17:25:38 +08:00
mgw
589df289be 内部调拨单缺少源单据 2024-11-25 17:24:14 +08:00
胡尧
7abc88f2c3 Accept Merge Request #1548: (feature/sale_order_route_pick -> develop)
Merge Request: 测试坯料采购单根据采购类型合并

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1548?initial=true
2024-11-25 17:19:22 +08:00
胡尧
f318dc758b 测试坯料采购单根据采购类型合并 2024-11-25 17:18:57 +08:00
胡尧
6628e22ac0 Accept Merge Request #1547: (feature/sale_order_route_pick -> develop)
Merge Request: 子制造订单增加拍承担

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1547?initial=true
2024-11-25 16:46:33 +08:00
管欢
c4cf4e2392 Accept Merge Request #1546: (feature/model_type_update -> 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/1546?initial=true
2024-11-25 16:44:45 +08:00
胡尧
56dfb98df5 子制造订单增加拍承担 2024-11-25 16:43:46 +08:00
guanhuan
4251e6dec7 修复模型类型详情界面的配置工序不能删除 2024-11-25 16:41:47 +08:00
jinling.yang
bcc9f0301c Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-25 16:23:09 +08:00
jinling.yang
17f2571be3 Merge branch 'feature/修复工序' into develop 2024-11-25 16:22:53 +08:00
杨金灵
a9b24f7961 Accept Merge Request #1545: (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/1545
2024-11-25 16:22:38 +08:00
jinling.yang
321125adf6 还原代码 2024-11-25 16:18:41 +08:00
jinling.yang
5c0db45223 修复工单开始 2024-11-25 16:03:40 +08:00
jinling.yang
76cc8845d2 修复工序 2024-11-25 15:40:41 +08:00
jinling.yang
38031a2537 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-25 15:02:08 +08:00
jinling.yang
1fe64e2b5d Merge branch 'feature/修复制造订单问题' into develop 2024-11-25 15:01:26 +08:00
杨金灵
d572529a9d Accept Merge Request #1544: (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/1544
2024-11-25 15:00:40 +08:00
jinling.yang
cb29baa698 还原代码 2024-11-25 14:31:02 +08:00
jinling.yang
696d0e2a40 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复制造订单问题 2024-11-25 14:00:04 +08:00
jinling.yang
75bbcd23a4 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-25 13:59:40 +08:00
jinling.yang
25002406b8 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复制造订单问题 2024-11-25 13:59:22 +08:00
廖丹龙
ed3ea32f45 Accept Merge Request #1543: (feature/delivery_status -> 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/1543
2024-11-25 11:52:20 +08:00
jinling.yang
63b1f732db 注释代码 2024-11-25 11:40:33 +08:00
liaodanlong
84ebce0786 智能工厂空模型处理 2024-11-25 11:40:01 +08:00
胡尧
ed747ae4d9 Accept Merge Request #1542: (feature/sale_order_route_pick -> develop)
Merge Request: 人工编程不能选择自动化产线加工

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1542?initial=true
2024-11-25 10:44:10 +08:00
胡尧
8a103a7555 人工编程不能选择自动化产线加工 2024-11-25 10:43:34 +08:00
jinling.yang
e8c166be31 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-25 10:25:52 +08:00
jinling.yang
d887a89988 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/new 2024-11-25 10:25:28 +08:00
禹翔辉
cb02319453 Accept Merge Request #1541: (feature/采购优化 -> develop)
Merge Request: 1、优化返工按钮;2、优化工单状态;3、采购单优化

Created By: @禹翔辉
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1541
2024-11-25 09:20:26 +08:00
yuxianghui
7f5f65f07f Merge branch 'feature/客供料入库单优化' into feature/采购优化 2024-11-25 09:17:40 +08:00
yuxianghui
c45200aaee 采购单优化 2024-11-25 09:04:41 +08:00
jinling.yang
d2351a67b0 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-25 08:53:14 +08:00
杨金灵
52873021cb Accept Merge Request #1540: (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/1540
2024-11-25 08:50:32 +08:00
yuxianghui
3f276f4177 1、优化返工按钮;2、优化工单状态; 2024-11-22 17:57:18 +08:00
jinling.yang
f01a300aae 还原代码 2024-11-22 17:56:59 +08:00
jinling.yang
8e11ef6e72 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化制造订单报废
# Conflicts:
#	sf_manufacturing/models/stock.py
2024-11-22 17:54:21 +08:00
jinling.yang
52c0df9b83 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-22 17:51:52 +08:00
jinling.yang
33b9c48e87 优化制造订单报废 2024-11-22 17:51:40 +08:00
禹翔辉
aa2f562ca8 Accept Merge Request #1539: (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/1539
2024-11-22 09:53:39 +08:00
yuxianghui
77ce078e91 1 2024-11-22 09:52:03 +08:00
yuxianghui
5450c9996f Merge branch 'feature/返工优化_1' into feature/客供料入库单优化
# Conflicts:
#	sf_manufacturing/models/stock.py
2024-11-22 09:46:42 +08:00
jinling.yang
70f8aadd66 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化制造订单报废 2024-11-22 09:42:38 +08:00
jinling.yang
119083ac2b Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-22 09:42:11 +08:00
jinling.yang
dd768e938c Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化制造订单报废 2024-11-22 09:41:06 +08:00
yuxianghui
611aa0fe05 1、优化客供料入库单的追溯参考字段自动计算方法 2024-11-22 09:40:33 +08:00
马广威
73564d574c Accept Merge Request #1538: (feature/制造功能优化 -> develop)
Merge Request: 调整开料要求展示范围

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1538?initial=true
2024-11-22 09:24:49 +08:00
mgw
ea5231adff Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-11-22 09:23:59 +08:00
mgw
2b3da48e9b 调整开料要求展示范围 2024-11-22 09:23:36 +08:00
jinling.yang
2632c4a5a0 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-22 09:22:54 +08:00
胡尧
2420987f95 Accept Merge Request #1537: (feature/sale_order_route_pick -> develop)
Merge Request: 修改调拨单的追溯参考

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1537
2024-11-22 08:57:33 +08:00
胡尧
d80f3c4d5c 修改调拨单的追溯参考 2024-11-21 17:56:57 +08:00
jinling.yang
5cb726bb2d 注释代码 2024-11-21 17:45:53 +08:00
胡尧
f6b8fa5665 Accept Merge Request #1536: (feature/sale_order_route_pick -> develop)
Merge Request: 增加追踪参考

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1536?initial=true
2024-11-21 17:45:10 +08:00
胡尧
113d0abb4b 增加追踪参考 2024-11-21 17:44:55 +08:00
胡尧
3f3c494f7f 增加追踪参考 2024-11-21 17:43:50 +08:00
jinling.yang
3632a3f98f Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-21 17:43:04 +08:00
jinling.yang
73402d1c5a Merge branch 'feature/工单添加工艺设计id字段' into develop 2024-11-21 17:42:22 +08:00
杨金灵
4e41efd423 Accept Merge Request #1535: (feature/工单添加工艺设计id字段 -> develop)
Merge Request: 工单添加工艺设计id字段

Created By: @杨金灵
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @杨金灵
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1535?initial=true
2024-11-21 17:42:06 +08:00
jinling.yang
0b931f8255 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/工单添加工艺设计id字段 2024-11-21 17:41:07 +08:00
jinling.yang
b49135f5f9 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-21 17:40:26 +08:00
jinling.yang
ed6d28cc21 工单添加工艺设计id字段 2024-11-21 17:40:04 +08:00
禹翔辉
9857787d5a Accept Merge Request #1534: (feature/返工优化_1 -> 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/1534
2024-11-21 17:32:57 +08:00
yuxianghui
c6e62f65b6 Merge remote-tracking branch 'origin/feature/返工优化' into feature/返工优化_1
# Conflicts:
#	sf_manufacturing/models/mrp_workorder.py
2024-11-21 17:26:49 +08:00
jinling.yang
6c0b034147 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-21 17:24:19 +08:00
jinling.yang
c0d520a47f Merge branch 'feature/优化外协采购和出入库单(工艺退回调整)' into develop 2024-11-21 17:23:57 +08:00
杨金灵
de11c57800 Accept Merge Request #1533: (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/1533
2024-11-21 17:23:18 +08:00
jinling.yang
d4ff4be32e 还原注释代码 2024-11-21 17:19:41 +08:00
jinling.yang
48371b01cd 还原注释代码 2024-11-21 17:13:38 +08:00
jinling.yang
310d8b33df 优化制造订单报废 2024-11-21 17:12:50 +08:00
yuxianghui
6d61e45028 删除无用的模块引用 2024-11-21 17:08:40 +08:00
yuxianghui
fff22a74b1 工单状态优化 2024-11-21 17:02:32 +08:00
胡尧
3588288434 Accept Merge Request #1532: (feature/sale_order_route_pick -> develop)
Merge Request: 处理订单客供料的问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1532?initial=true
2024-11-21 15:48:50 +08:00
胡尧
7408cc00f9 处理订单客供料的问题 2024-11-21 15:48:17 +08:00
马广威
9b3d1170b0 Accept Merge Request #1531: (feature/制造功能优化 -> develop)
Merge Request: 线切割、人工线下加工生成工单异常处理

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1531
2024-11-21 15:38:04 +08:00
mgw
a774c74e6a Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-11-21 15:36:45 +08:00
mgw
1d53f47488 线切割、人工线下加工生成工单异常处理 2024-11-21 15:36:16 +08:00
jinling.yang
60cc49238c Merge branch 'feature/返工优化' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化外协采购和出入库单(工艺退回调整) 2024-11-21 11:46:54 +08:00
jinling.yang
b415278997 优化坯料的制造订单 2024-11-21 11:45:48 +08:00
胡尧
ac32494944 Accept Merge Request #1530: (feature/sale_order_route_pick -> develop)
Merge Request: 更新模块时不更新初始化数据,修改子MO子为子MO

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1530?initial=true
2024-11-21 11:34:11 +08:00
胡尧
8c81315c33 更新时不更新初始化数据 2024-11-21 11:33:04 +08:00
yuxianghui
1d66c1dbea 工单状态优化 2024-11-21 11:25:00 +08:00
jinling.yang
085d26669f Merge branch 'feature/返工优化' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化外协采购和出入库单(工艺退回调整) 2024-11-21 10:44:51 +08:00
jinling.yang
bb7b72b540 优化工序设计 2024-11-21 10:44:11 +08:00
yuxianghui
ded0d06f86 工单状态方法优化 2024-11-21 10:43:22 +08:00
马广威
fe08ee4173 Accept Merge Request #1529: (feature/制造功能优化 -> develop)
Merge Request: 工序类型增加项目

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1529?initial=true
2024-11-21 10:42:28 +08:00
mgw
25ee849796 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-11-21 10:41:41 +08:00
mgw
bafcf35ac9 工序类型增加项目 2024-11-21 10:41:07 +08:00
胡尧
cc1455b22c 修改制造订单中子MO子为子MO 2024-11-21 10:21:18 +08:00
胡尧
1d38334c81 Accept Merge Request #1528: (feature/sale_order_route_pick -> develop)
Merge Request: 解决bug

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1528?initial=true
2024-11-21 10:01:01 +08:00
胡尧
13d99b1bcc 成品的零件图号修改为零件图号 2024-11-21 09:49:12 +08:00
胡尧
269be36d86 隐藏制造订单待生产按钮,人工线下加工状态下的功能刀具 2024-11-21 09:48:26 +08:00
胡尧
ebd76afb29 Accept Merge Request #1527: (feature/sale_order_route_pick -> develop)
Merge Request: 修复不同产品调拨单合并的bug

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1527
2024-11-21 09:28:04 +08:00
胡尧
a1807e05db 修复不同产品调拨单合并的bug 2024-11-21 09:26:23 +08:00
jinling.yang
11866629c5 修复工艺设计 2024-11-20 17:56:29 +08:00
yuxianghui
f8f5286568 返工流程优化 2024-11-20 17:34:46 +08:00
胡尧
36908f13d3 Accept Merge Request #1525: (feature/sale_order_route_pick -> develop)
Merge Request: 修改订单客供料显示,修改内部调拨、生产发料合并单据

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1525?initial=true
2024-11-20 16:53:50 +08:00
胡尧
a7ed317b09 修改订单客供料显示,修改内部调拨、生产发料合并单据 2024-11-20 16:53:15 +08:00
jinling.yang
fe4346b802 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化外协采购和出入库单(工艺退回调整) 2024-11-20 16:08:54 +08:00
jinling.yang
23da273af1 修复bug和优化制造订单报废 2024-11-20 16:08:27 +08:00
廖丹龙
68fdea4520 Accept Merge Request #1523: (feature/delivery_status -> 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/1523
2024-11-20 15:32:01 +08:00
liaodanlong
c5ac62060d Merge branch 'refs/heads/develop' into feature/delivery_status
# Conflicts:
#	sf_manufacturing/models/mrp_production.py
2024-11-20 15:23:07 +08:00
马广威
350cf0a74b Accept Merge Request #1524: (feature/制造功能优化 -> develop)
Merge Request: 调整采购单查找逻辑

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1524?initial=true
2024-11-20 15:19:08 +08:00
mgw
e204d693cf 调整采购单查找逻辑 2024-11-20 15:18:08 +08:00
mgw
a6422330b6 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-11-20 12:01:38 +08:00
mgw
230e87a9f1 增加日志输出 2024-11-20 10:29:32 +08:00
jinling.yang
e634e9726f 优化工艺设计显示 2024-11-19 17:56:21 +08:00
liaodanlong
e8d07abe05 人工线下加工工单的计划时间计算优化需求 2024-11-19 14:18:44 +08:00
胡尧
808bbd7b22 Accept Merge Request #1522: (feature/sale_order_route_pick -> develop)
Merge Request: 排程单过滤掉关联制造订单处于草稿跟工艺设计状态

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1522?initial=true
2024-11-19 14:18:08 +08:00
胡尧
fabcca1188 排程单过滤掉关联制造订单处于草稿跟工艺设计状态 2024-11-19 14:15:29 +08:00
胡尧
97c8b1dcc1 Accept Merge Request #1521: (feature/sale_order_route_pick -> develop)
Merge Request: 修改坯料冗余

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1521?initial=true
2024-11-19 11:57:29 +08:00
胡尧
f99a35932f 修改坯料冗余 2024-11-19 11:56:49 +08:00
胡尧
ce7dfdbd36 Accept Merge Request #1520: (feature/sale_order_route_pick -> develop)
Merge Request: 增加坯料冗余量

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1520?initial=true
2024-11-19 09:00:38 +08:00
胡尧
d53f3837c3 增加坯料冗余量 2024-11-19 08:59:52 +08:00
jinling.yang
1cb646ec48 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/优化外协采购和出入库单(工艺退回调整) 2024-11-18 17:41:10 +08:00
jinling.yang
c73706555f 优化外协采购和出入库单(工艺退回调整) 2024-11-18 17:40:41 +08:00
胡尧
21f961d893 Accept Merge Request #1519: (feature/sale_order_route_pick -> develop)
Merge Request: 增加坯料冗余量

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1519
2024-11-18 15:00:56 +08:00
胡尧
08a682143f 增加坯料冗余量 2024-11-18 15:00:05 +08:00
杨金灵
ebdeb95b0e Accept Merge Request #1518: (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/1518
2024-11-18 11:45:12 +08:00
杨金灵
0f26cac68d Merge branch refs/heads/develop into refs/heads/feature/新增工艺退回调整 2024-11-18 11:43:12 +08:00
jinling.yang
45c96276ff 还原代码 2024-11-18 11:42:35 +08:00
jinling.yang
a2855f1f08 还原代码 2024-11-18 11:40:24 +08:00
jinling.yang
e8c006d495 还原代码 2024-11-18 11:25:19 +08:00
jinling.yang
9671efeced 外协出入库修复 2024-11-18 11:24:32 +08:00
胡尧
1e3fd6bc09 Accept Merge Request #1517: (feature/sale_order_route_pick -> develop)
Merge Request: 增加依赖

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1517?initial=true
2024-11-18 10:55:08 +08:00
胡尧
73aa4af118 增加依赖 2024-11-18 10:54:48 +08:00
胡尧
38a8a298b5 Accept Merge Request #1516: (feature/sale_order_route_pick -> develop)
Merge Request: 增加坯料冗余量,调整坯料客供料的名称

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1516?initial=true
2024-11-18 09:45:48 +08:00
胡尧
bc0b8bdecb 增加坯料冗余量,调整坯料客供料的名称 2024-11-18 09:44:50 +08:00
jinling.yang
a8e9fe40ac Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/新增工艺退回调整
# Conflicts:
#	sf_manufacturing/models/mrp_production.py
#	sf_manufacturing/views/mrp_production_addional_change.xml
2024-11-15 18:08:31 +08:00
jinling.yang
5c5606749a 优化制造订单 2024-11-15 18:06:32 +08:00
jinling.yang
8add4b5ad1 优化制造订单 2024-11-15 17:31:28 +08:00
胡尧
f579c8928c Accept Merge Request #1515: (feature/sale_order_route_pick -> develop)
Merge Request: 增加制造类型字段,增加依赖

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1515
2024-11-15 15:31:22 +08:00
胡尧
9410ca82db 解决冲突 2024-11-15 15:30:35 +08:00
胡尧
73c986cd50 增加制造类型字段,增加依赖 2024-11-15 15:29:04 +08:00
胡尧
f8a9a38778 Accept Merge Request #1514: (feature/sale_order_route_pick -> develop)
Merge Request: 修改人工线下加工状态的继承位置

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1514?initial=true
2024-11-15 15:03:31 +08:00
胡尧
9d723c5e00 修改人工线下加工状态的继承位置 2024-11-15 15:03:06 +08:00
liaodanlong
722a044707 移动deadline_of_delivery 方法位置 2024-11-15 11:37:14 +08:00
廖丹龙
967effe8f1 Accept Merge Request #1505: (feature/delivery_status -> 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/1505
2024-11-15 10:44:10 +08:00
liaodanlong
5f5877699c 交期状态修改 2024-11-15 10:39:45 +08:00
liaodanlong
4787cb451d Merge branch 'refs/heads/develop' into feature/delivery_status
# Conflicts:
#	sf_manufacturing/__manifest__.py
2024-11-15 10:37:13 +08:00
liaodanlong
811a79c7c1 交期状态修改 2024-11-15 10:33:47 +08:00
胡尧
153f599fe8 Accept Merge Request #1513: (feature/sale_order_route_pick -> develop)
Merge Request: 给坯料模板增加按订单补给

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1513?initial=true
2024-11-15 09:13:16 +08:00
胡尧
f6f9d14f0a 给坯料模板增加按订单补给 2024-11-15 09:12:34 +08:00
jinling.yang
018d51e25f 批量处理工艺调整 2024-11-14 18:02:24 +08:00
胡尧
ac03192119 Accept Merge Request #1512: (feature/sale_order_route_pick -> develop)
Merge Request: 增加依赖

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1512?initial=true
2024-11-14 16:59:40 +08:00
胡尧
b8d5d655ea 增加依赖 2024-11-14 16:59:18 +08:00
胡尧
00f986cdb5 Accept Merge Request #1511: (feature/sale_order_route_pick -> develop)
Merge Request: 增加加工类型

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1511?initial=true
2024-11-14 16:53:19 +08:00
胡尧
5dc5c814c8 增加加工类型 2024-11-14 16:52:58 +08:00
胡尧
c64ede58fd Accept Merge Request #1510: (feature/sale_order_route_pick -> develop)
Merge Request: 增加是否线下加工日志

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1510?initial=true
2024-11-14 16:36:46 +08:00
胡尧
6e17bb933f 增加是否线下加工日志 2024-11-14 16:36:02 +08:00
胡尧
99aa161834 Accept Merge Request #1509: (feature/sale_order_route_pick -> develop)
Merge Request: 修改注释

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1509?initial=true
2024-11-14 15:36:24 +08:00
胡尧
ed641c85b3 修改注释 2024-11-14 15:36:01 +08:00
胡尧
cf7756f51e Accept Merge Request #1508: (feature/sale_order_route_pick -> develop)
Merge Request: 增加制造类型

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1508?initial=true
2024-11-14 15:15:22 +08:00
胡尧
a75269b3a3 增加制造类型 2024-11-14 15:14:57 +08:00
胡尧
6b184d7df3 Accept Merge Request #1507: (feature/sale_order_route_pick -> develop)
Merge Request: 将数据初始化由产品辩题改为为模板

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1507?initial=true
2024-11-14 15:04:50 +08:00
胡尧
daba7d5155 将数据初始化由产品辩题改为为模板 2024-11-14 15:02:11 +08:00
jinling.yang
33a1837274 优化工单 2024-11-13 17:59:47 +08:00
禹翔辉
6b3e3aa49c Accept Merge Request #1506: (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/1506?initial=true
2024-11-13 17:36:06 +08:00
yuxianghui
a7b5fc898e 优化自动生成批次序列号方法 2024-11-13 17:34:39 +08:00
liaodanlong
9a9bfd198b 交期状态 2024-11-13 14:46:58 +08:00
禹翔辉
2446065172 Accept Merge Request #1504: (feature/单据页面优化 -> develop)
Merge Request: 处理sf工厂单据页面优化需求

Created By: @禹翔辉
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1504?initial=true
2024-11-13 13:41:58 +08:00
yuxianghui
7565094077 Merge branch 'feature/工单工序优化_y' into feature/单据页面优化 2024-11-13 13:40:25 +08:00
yuxianghui
ac2708404a 处理sf工厂单据页面优化需求 2024-11-13 13:39:41 +08:00
胡尧
63b9f495e9 Merge branch 'develop' into feature/sale_order_route_pick 2024-11-13 11:49:02 +08:00
胡尧
012bb9fd54 初始化更新模板categ_type字段 2024-11-13 11:37:16 +08:00
廖丹龙
7bcb54861b Accept Merge Request #1503: (feature/delivery_status -> 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/1503
2024-11-13 11:25:12 +08:00
胡尧
2f64a3a612 Accept Merge Request #1502: (feature/sale_order_route_pick -> develop)
Merge Request: 修改细节

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1502?initial=true
2024-11-13 10:51:32 +08:00
胡尧
5365211f49 修改细节 2024-11-13 10:50:48 +08:00
liaodanlong
e38407c0a5 交期状态开发 2024-11-13 10:37:19 +08:00
胡尧
13ef106c0e Accept Merge Request #1501: (feature/sale_order_route_pick -> develop)
Merge Request: 修改工艺工程师菜单权限

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1501?initial=true
2024-11-13 09:08:01 +08:00
胡尧
433f3bd2dc 修改工艺工程师菜单权限 2024-11-13 09:07:14 +08:00
jinling.yang
ff072a32bb 添加退回调整 2024-11-12 17:53:17 +08:00
胡尧
de7098a7d4 Accept Merge Request #1500: (feature/sale_order_route_pick -> develop)
Merge Request: 多供货路线选择提交

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1500?initial=true
2024-11-12 15:21:06 +08:00
胡尧
205bfd0538 修改人工线下加工工序domain 2024-11-12 15:19:57 +08:00
胡尧
37538141bf 修改材料型号获取方式名称 2024-11-12 14:57:59 +08:00
胡尧
975ced08cb 增加成品工序模板(人工线下加工) 2024-11-12 14:00:27 +08:00
jinling.yang
d646019c93 修复表面工艺 2024-11-12 13:56:40 +08:00
jinling.yang
efa1e2b60f 表面工艺生成采购单 2024-11-12 11:51:18 +08:00
jinling.yang
8bbc65ef88 新增退回调整 2024-11-12 11:43:40 +08:00
胡尧
e1121cc3b5 增加快速订单逻辑,修改报价筛选逻辑 2024-11-12 11:16:42 +08:00
jinling.yang
026bf17a68 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/新增工艺退回调整 2024-11-12 09:12:37 +08:00
马广威
fdcd825142 Accept Merge Request #1499: (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/1499
2024-11-12 09:02:39 +08:00
jinling.yang
317f44d6c2 修复工艺设计 2024-11-12 09:00:45 +08:00
jinling.yang
7d5c7bceb1 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-12 08:59:47 +08:00
jinling.yang
359fd40ed3 添加工艺退回调整 2024-11-11 17:55:05 +08:00
禹翔辉
13a930b59c Accept Merge Request #1497: (feature/工单工序优化_y -> 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/1497
2024-11-11 16:53:50 +08:00
jinling.yang
359a246793 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-11 16:42:30 +08:00
胡尧
2b658d7be0 Accept Merge Request #1498: (feature/sale_order_route_pick -> develop)
Merge Request: 多供货方式选择

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1498?initial=true
2024-11-11 16:40:49 +08:00
胡尧
cd9f485fc0 增加零件名称 2024-11-11 16:38:28 +08:00
yuxianghui
dda627f20a 工单工序排序方法重构 2024-11-11 16:38:06 +08:00
jinling.yang
e8858559f6 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-11 16:35:41 +08:00
胡尧
d68a9249c6 解决冲突 2024-11-11 16:32:54 +08:00
胡尧
eebb143778 多供货方式选择 2024-11-11 16:26:45 +08:00
杨金灵
a12eb12678 Accept Merge Request #1495: (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/1495
2024-11-11 15:41:36 +08:00
禹翔辉
f5f67c52af Accept Merge Request #1496: (feature/sf视图展示界面优化 -> 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/1496
2024-11-11 14:58:07 +08:00
yuxianghui
3df2306e1b Merge branch 'feature/客供料入库单优化_1' into feature/sf视图展示界面优化 2024-11-11 14:55:23 +08:00
yuxianghui
5dae0ea973 1、sf视图展示界面优化 2024-11-11 14:52:44 +08:00
jinling.yang
e7b18233f0 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺工单完成入库操作 2024-11-11 14:51:11 +08:00
jinling.yang
e55e42fe6b Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-11 14:50:52 +08:00
jinling.yang
741f2ad8b2 还原代码 2024-11-11 14:50:38 +08:00
胡尧
1b87a81a5a 多供货方式选择 2024-11-11 11:06:56 +08:00
管欢
7042eb0d7b Accept Merge Request #1494: (feature/10月迭代优化 -> 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/1494
2024-11-11 10:32:21 +08:00
胡尧
28788e2a81 Merge branch 'develop' into feature/sale_order_route_pick 2024-11-11 10:24:14 +08:00
胡尧
0f37b45b30 开发 2024-11-11 10:22:53 +08:00
jinling.yang
38c4aba45c 根据工序生成工单 2024-11-08 18:01:23 +08:00
guanhuan
3b686a8272 新增零件名称 2024-11-08 16:56:00 +08:00
胡尧
2798ce6183 开发 2024-11-08 16:23:34 +08:00
jinling.yang
e981d68805 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺工单完成入库操作
# Conflicts:
#	sf_manufacturing/models/stock.py
#	sf_manufacturing/security/ir.model.access.csv
2024-11-08 09:27:45 +08:00
jinling.yang
cd3ab04728 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-08 09:26:14 +08:00
jinling.yang
d419efa3c3 优化工艺确认 2024-11-07 17:59:28 +08:00
马广威
8b4eb325ef Accept Merge Request #1493: (feature/制造功能优化 -> develop)
Merge Request: 询价单区分类型

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1493?initial=true
2024-11-07 16:40:11 +08:00
yuxianghui
330726007d 1、添加只有客供料入库单才能看见收货人/联系地址/电话号码等字段; 2024-11-07 16:26:48 +08:00
mgw
4d7b1f557b 询价单区分类型 2024-11-07 14:26:33 +08:00
禹翔辉
1699f61d3f Accept Merge Request #1492: (feature/客供料入库单优化_1 -> 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/1492?initial=true
2024-11-07 11:24:19 +08:00
yuxianghui
a0eec00749 暂时删除权限 2024-11-07 11:22:31 +08:00
禹翔辉
f5365b4a3a Accept Merge Request #1491: (feature/客供料入库单优化_1 -> develop)
Merge Request: 1、处理销售单的依赖导致的更新报错问题;2、优化客供料单据获取销售单字段信息和成品信息方法;

Created By: @禹翔辉
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @禹翔辉
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1491?initial=true
2024-11-07 10:45:30 +08:00
yuxianghui
8b9aa1c454 Merge branch 'feature/客供料入库单优化' into feature/客供料入库单优化_1 2024-11-07 10:43:58 +08:00
yuxianghui
9a4d7e87ec 1、处理销售单的依赖导致的更新报错问题;2、优化客供料单据获取销售单字段信息和成品信息方法; 2024-11-07 10:43:08 +08:00
胡尧
6679c200e1 开发 2024-11-07 08:41:25 +08:00
jinling.yang
01df55ef35 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺工单完成入库操作
# Conflicts:
#	sf_manufacturing/security/ir.model.access.csv
2024-11-06 17:54:29 +08:00
胡尧
d2b028ed4e Merge branch 'develop' into feature/sale_order_route_pick 2024-11-06 17:53:52 +08:00
jinling.yang
de1b97bfb7 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-11-06 17:53:44 +08:00
胡尧
111c0f6dae 开发 2024-11-06 17:53:33 +08:00
jinling.yang
11da893b17 Merge branch 'feature/添加工艺工程师权限组' into develop 2024-11-06 17:50:57 +08:00
杨金灵
b434329fc4 Accept Merge Request #1490: (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/1490
2024-11-06 17:50:43 +08:00
jinling.yang
72998f04c6 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/添加工艺工程师权限组 2024-11-06 17:49:01 +08:00
jinling.yang
23db164452 制造模块添加工艺工程师权限组 2024-11-06 17:48:27 +08:00
jinling.yang
1f11d188c1 添加工艺工程师权限组 2024-11-06 17:46:14 +08:00
jinling.yang
fa30e0c1da 添加工艺设计 2024-11-06 17:44:13 +08:00
禹翔辉
5106768330 Accept Merge Request #1489: (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/1489?initial=true
2024-11-06 17:27:52 +08:00
yuxianghui
6c0d9486fc Merge branch 'feature/报价单优化' into feature/客供料入库单优化 2024-11-06 17:24:57 +08:00
yuxianghui
211d74d9ff 处理 客供料入库单优化 需求 2024-11-06 17:24:10 +08:00
jinling.yang
84db3a92be 表面工艺外协采购单添加“采购类型",默认consignment(委外加工) 2024-11-06 10:46:21 +08:00
jinling.yang
487a2936c3 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺工单完成入库操作 2024-11-06 10:41:27 +08:00
jinling.yang
aa9bdfe372 添加工艺设计 2024-11-06 10:40:11 +08:00
马广威
6134ac3b4c Accept Merge Request #1488: (feature/制造功能优化 -> develop)
Merge Request: 添加采购类型字段

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1488
2024-11-06 09:24:43 +08:00
mgw
85c24e3d94 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-11-06 09:23:42 +08:00
mgw
106945fba7 添加采购类型字段 2024-11-06 09:23:14 +08:00
yuxianghui
8ea72198ea 1、完成报价单优化需求;2、修改制造订单内装夹工单的‘返工’按钮为’异常反馈‘ 2024-11-05 17:52:18 +08:00
禹翔辉
41cd76ad14 Accept Merge Request #1486: (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/1486?initial=true
2024-11-05 09:53:48 +08:00
yuxianghui
e20510bc4f Merge branch 'feature/工单优化_返工' into feature/部分警告信息处理 2024-11-05 09:52:07 +08:00
yuxianghui
1d14ab27af 警告信息处理 2024-11-05 09:50:24 +08:00
胡尧
0575d89227 Merge branch 'release/release_2.5' 2024-11-04 19:49:05 +08:00
jinling.yang
7d6699fe7a Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺工单完成入库操作 2024-11-01 16:00:53 +08:00
胡尧
fd55abec72 Accept Merge Request #1485: (release/release_2.5 -> develop)
Merge Request: 在下发编程单时,如果已经排程,在修改工单起止时间时先设置大的结束时间,避免设置时间出错

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1485
2024-10-31 11:34:46 +08:00
胡尧
76597f6ccb 在下发编程单时,如果已经排程,在修改工单起止时间时先设置大的结束时间,避免设置时间出错 2024-10-31 11:15:06 +08:00
管欢
d7779e969d Accept Merge Request #1483: (feature/weid_sync_update -> develop)
Merge Request: 用户创建员工同时修改用户的企微id

Created By: @管欢
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @管欢
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1483
2024-10-29 15:55:39 +08:00
guanhuan
9d28eccd1b 用户创建员工同时修改用户的企微id 2024-10-29 15:50:38 +08:00
管欢
27339afaae Accept Merge Request #1482: (feature/weid_sync_update -> develop)
Merge Request: 修改员工绑定用户同时修改用户的企微id

Created By: @管欢
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @管欢
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1482
2024-10-29 15:05:59 +08:00
guanhuan
8dc3f2698b 修改员工绑定用户同时修改用户的企微id 2024-10-29 14:50:00 +08:00
马广威
4fd7ad8d03 Accept Merge Request #1481: (feature/制造功能优化 -> develop)
Merge Request: rfid手动输入推送

Created By: @马广威
Accepted By: @马广威
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1481?initial=true
2024-10-29 14:30:06 +08:00
mgw
3bc33fe2fc Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/制造功能优化 2024-10-29 14:28:44 +08:00
mgw
c21319a127 rfid手动输入推送 2024-10-29 14:28:24 +08:00
管欢
02e21a8fde Accept Merge Request #1480: (feature/weid_sync_update -> develop)
Merge Request: 修改和新增员工时根据邮箱获取企微id

Created By: @管欢
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @管欢
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1480
2024-10-29 11:10:47 +08:00
管欢
2cf578de65 Accept Merge Request #1479: (feature/message_update -> 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/1479
2024-10-29 09:02:03 +08:00
guanhuan
9665cdfc84 发送消息添加权限 2024-10-29 08:58:33 +08:00
胡尧
bef7376827 Accept Merge Request #1478: (feature/plan_slow -> develop)
Merge Request: 增加日志

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1478?initial=true
2024-10-28 17:43:21 +08:00
胡尧
e73e9d6960 增加日志 2024-10-28 17:42:44 +08:00
胡尧
892f5d0e70 Accept Merge Request #1477: (feature/plan_slow -> develop)
Merge Request: 增加销售订单确认日志

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1477?initial=true
2024-10-28 17:26:58 +08:00
胡尧
61339da204 增加销售订单确认日志 2024-10-28 17:26:27 +08:00
胡尧
25db392864 Accept Merge Request #1476: (feature/plan_slow -> develop)
Merge Request: 增加销售订单确认日志

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1476?initial=true
2024-10-28 17:23:00 +08:00
胡尧
745fd429c2 增加销售订单确认日志 2024-10-28 17:21:51 +08:00
胡尧
5c59a27a81 增加采购总监消息推送权限 2024-10-28 16:30:46 +08:00
管欢
9bac3675f6 Accept Merge Request #1475: (feature/message_update -> 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/1475
2024-10-28 11:54:04 +08:00
guanhuan
b4fbbd48fb 精度显示修改 2024-10-28 11:46:36 +08:00
guanhuan
3559d67c05 精度显示修改 2024-10-28 11:43:10 +08:00
禹翔辉
816623b1fe Accept Merge Request #1474: (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/1474
2024-10-28 11:00:03 +08:00
yuxianghui
91b913a7bd Merge branch 'feature/维保请求优化' into feature/工单优化_返工 2024-10-28 10:58:04 +08:00
yuxianghui
ba8393a8c7 返工操作时工单状态优化 2024-10-28 10:55:18 +08:00
管欢
06d061165b Accept Merge Request #1473: (feature/message_update -> 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/1473
2024-10-28 10:30:02 +08:00
guanhuan
18a7dbbff9 辅助文件上传 2024-10-28 10:21:33 +08:00
胡尧
dc545e6d49 Accept Merge Request #1472: (feature/plan_slow -> develop)
Merge Request: 修改排程逻辑

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1472?initial=true
2024-10-28 09:45:24 +08:00
胡尧
1467dbf88c 修改排程逻辑 2024-10-28 09:44:52 +08:00
胡尧
e9caf78b81 Accept Merge Request #1471: (feature/plan_slow -> develop)
Merge Request: 修复未编程的制造订单排程问题

Created By: @胡尧
Accepted By: @胡尧
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1471?initial=true
2024-10-28 09:43:42 +08:00
胡尧
aa1353cf99 修改排程逻辑 2024-10-28 09:38:50 +08:00
管欢
14d49f2944 Accept Merge Request #1469: (feature/message_update -> 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/1469
2024-10-25 17:41:02 +08:00
杨金灵
8560069b19 Accept Merge Request #1470: (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/1470
2024-10-25 17:24:07 +08:00
jinling.yang
8dc23a638f 去掉注释 2024-10-25 17:21:45 +08:00
jinling.yang
537fbf7e14 添加注释 2024-10-25 17:19:10 +08:00
guanhuan
5363557faf 快速订单创建报错 2024-10-25 16:36:54 +08:00
jinling.yang
3e684a308c Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复表面工艺工单完成入库操作 2024-10-25 15:52:32 +08:00
杨金灵
3c026004f3 Accept Merge Request #1468: (feature/修复CNC工单消息提醒跳转 -> develop)
Merge Request: 修复CNC工单消息提醒跳转

Created By: @杨金灵
Reviewed By: @马广威
Approved By: @马广威 
Accepted By: @杨金灵
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1468
2024-10-25 15:42:56 +08:00
jinling.yang
651c8f266b 修复CNC工单消息提醒跳转 2024-10-25 15:41:23 +08:00
杨金灵
a3bfbe66c4 Accept Merge Request #1467: (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/1467
2024-10-25 15:18:25 +08:00
jinling.yang
563e40adc6 修复工单链接跳转 2024-10-25 15:15:11 +08:00
jinling.yang
f88a784a87 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-25 14:58:44 +08:00
jinling.yang
7227e1e59c 注释occ代码 2024-10-25 14:58:29 +08:00
廖丹龙
01df5e86cd Accept Merge Request #1466: (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/1466
2024-10-25 14:42:12 +08:00
管欢
41f853b6c9 Accept Merge Request #1465: (feature/message_update -> 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/1465
2024-10-25 14:27:06 +08:00
liaodanlong
906a0ea767 采购按钮位置修改 2024-10-25 14:25:47 +08:00
jinling.yang
6162c731f2 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-25 14:11:56 +08:00
guanhuan
4f1d518ef3 加工精度修改 2024-10-25 14:02:37 +08:00
liaodanlong
06eaebd098 产品类别过滤缺陷 2024-10-25 14:02:37 +08:00
liaodanlong
8578a9a538 Merge remote-tracking branch 'origin/feature/machining_accuracy_sync' into feature/machining_accuracy_sync 2024-10-25 14:01:52 +08:00
liaodanlong
b9039ef466 刀具标准库page样式问题 2024-10-25 14:01:38 +08:00
杨金灵
a97f581c99 Accept Merge Request #1464: (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/1464?initial=true
2024-10-25 13:52:15 +08:00
jinling.yang
036179ec4d Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/工单消息提醒添加已排过滤 2024-10-25 13:50:28 +08:00
jinling.yang
d33188dedf Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-25 13:50:07 +08:00
jinling.yang
7033f95273 工单消息提醒添加已排过滤 2024-10-25 13:49:55 +08:00
管欢
00689d76cc Accept Merge Request #1463: (feature/message_update -> develop)
Merge Request: 工单下发url调整,加工精度取值调整,2D加工图纸和质检标准位置调整

Created By: @管欢
Reviewed By: @胡尧
Approved By: @胡尧 
Accepted By: @管欢
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1463
2024-10-25 13:38:25 +08:00
guanhuan
86d97ef331 2D加工图纸和质检标准位置调整 2024-10-25 11:55:43 +08:00
jinling.yang
05a183f46f Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-25 11:36:12 +08:00
jinling.yang
50959d2e9c Merge branch 'feature/修复消息提醒时区问题' into develop 2024-10-25 11:35:56 +08:00
guanhuan
519ce0d5bb 工单下发调整 2024-10-25 11:29:13 +08:00
杨金灵
f06842cdcb Accept Merge Request #1461: (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/1461
2024-10-25 11:28:41 +08:00
jinling.yang
d5a1caad10 还原代码 2024-10-25 11:26:18 +08:00
jinling.yang
e51fff4120 修复消息提醒时区问题 2024-10-25 11:25:37 +08:00
guanhuan
2fe8e0e356 工单下发调整 2024-10-25 11:11:24 +08:00
guanhuan
bbe2e5792f Merge branch 'refs/heads/develop' into feature/machining_accuracy_sync 2024-10-25 09:58:45 +08:00
jinling.yang
a1a520ec39 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into feature/修复消息提醒时区问题 2024-10-25 09:55:12 +08:00
jinling.yang
1b714a9962 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-25 09:54:51 +08:00
jinling.yang
9d133096c7 修复消息提醒时区问题 2024-10-25 09:54:37 +08:00
guanhuan
69f3453134 加工精度修改 2024-10-25 09:48:57 +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
jinling.yang
ac2eba4734 Merge branch 'develop' of https://e.coding.net/jikimo-hn/jikimo_sfs/jikimo_sf into develop 2024-10-24 17:39:36 +08:00
jinling.yang
b64893436b Merge branch 'feature/修复销售订单和工单消息提醒' into develop 2024-10-24 17:36:00 +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
guanhuan
69c63f708d 修改和新增员工时根据邮箱获取企微id 2024-10-24 17:06:31 +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
胡尧
3f84972bfd 删除多余代码 2024-10-24 13:57:26 +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
胡尧
ed15958319 解决报错 2024-10-24 11:29:36 +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
胡尧
0b70447333 修改排程逻辑 2024-10-24 09:47:20 +08:00
jinling.yang
de8ba77bef 优化加工质检页面 2024-10-24 09:22:35 +08:00
胡尧
1026c0edd0 修改排程逻辑 2024-10-24 09:18:21 +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
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
胡尧
a28d20b3bf 修改排程逻辑 2024-10-23 15:30:05 +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
胡尧
39afc99b8f Merge branch 'release/release_2.4' 2024-10-11 09:29:34 +08:00
杨金灵
f230ad55fb Accept Merge Request #1284: (hotfix/修复报废-外协入库验证 -> master)
Merge Request: 修复报废-外协入库验证

Created By: @杨金灵
Accepted By: @杨金灵
URL: https://jikimo-hn.coding.net/p/jikimo_sfs/d/jikimo_sf/git/merge/1284
2024-09-06 13:47:55 +08:00
124 changed files with 4804 additions and 1369 deletions

View File

@@ -536,3 +536,7 @@ div:has(.o_required_modifier) > label::before {
position: unset;
}
// 修复搜索面板checkbox样式
.o_search_panel .form-check .form-check-label span {
position: relative;
}

View File

@@ -190,7 +190,7 @@ def _create(self, data_list):
# 如果该用户组被限制创建或更新操作
if rec['is_create_or_update']:
raise UserError(
_("You are restricted from performing this operation. Please contact the administrator."))
_("您没有执行此操作的权限。请联系管理员"))
else:
# 如果 'access.right' 模型不存在,可以在这里定义备选逻辑
# 例如,记录日志、发送通知或者简单地跳过这部分逻辑

View File

@@ -0,0 +1,139 @@
# -*- coding: utf-8 -*-
from . import models
from . import controllers
from odoo import api, SUPERUSER_ID
def _data_install(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
# 获取所有需要设置的产品模板
env.ref('jikimo_sale_multiple_supply_methods.product_template_purchase').product_variant_id.write({'active': False, 'is_bfm': True})
env.ref('jikimo_sale_multiple_supply_methods.product_template_manual_processing').product_variant_id.write({'active': False, 'single_manufacturing': True, 'is_bfm': True})
env.ref('jikimo_sale_multiple_supply_methods.product_template_default').product_variant_id.write({'active': False, 'is_bfm': True})
env.ref('jikimo_sale_multiple_supply_methods.product_template_embryo_customer_provided').product_variant_id.write({'active': False})
env.ref('jikimo_sale_multiple_supply_methods.product_template_outsourcing').product_variant_id.write({'active': False, 'is_bfm': True})
# 为三步制造增加规则
warehouse = env['stock.warehouse'].search([('company_id', '=', env.company.id)], limit=1)
product_route_id = warehouse.pbm_route_id
# 创建规则:原料存货区 -> 制造前, 坯料存货区 -> 制造前, 制造后 -> 坯料存货区, 制造后 -> 成品存货区
raw_material_location_id = env['stock.location'].search([('name', '=', '坯料存货区')], limit=1)
picking_type_production = warehouse.pbm_type_id
picking_type_stock = warehouse.sam_type_id
material_location_id = env['stock.location'].search([('name', '=', '原料存货区')], limit=1)
# 为mto增加规则
mto_route_id = env.ref('stock.route_warehouse0_mto')
# 创建规则:原料存货区 -> 外包位置, 坯料存货区 -> 外包位置
subcontracting_location_id = env.company.subcontracting_location_id
picking_type_subcontracting = warehouse.subcontracting_resupply_type_id
# 为补给外包商增加规则
resupply_route_id = warehouse.subcontracting_route_id
rules_data = [
{
'name': 'WH: 原料存货区 → 制造前',
'location_src_id': material_location_id.id,
'location_dest_id': warehouse.pbm_loc_id.id,
'route_id': product_route_id.id,
'picking_type_id': picking_type_production.id,
'action': 'pull',
'sequence': 20,
'warehouse_id': warehouse.id,
'procure_method': 'mts_else_mto',
},
{
'name': 'WH: 坯料存货区 → 制造前',
'location_src_id': raw_material_location_id.id,
'location_dest_id': warehouse.pbm_loc_id.id,
'route_id': product_route_id.id,
'picking_type_id': picking_type_production.id,
'action': 'pull',
'sequence': 21,
'warehouse_id': warehouse.id,
'procure_method': 'mts_else_mto',
},
{
'name': 'WH: 制造后 → 坯料存货区',
'location_src_id': warehouse.sam_loc_id.id,
'location_dest_id': raw_material_location_id.id,
'route_id': product_route_id.id,
'picking_type_id': picking_type_stock.id,
'action': 'push',
'sequence': 23,
},
{
'name': 'WH: 制造后 → 成品存货区',
'location_src_id': warehouse.sam_loc_id.id,
'location_dest_id': env['stock.location'].search([('name', '=', '成品存货区')], limit=1).id,
'route_id': product_route_id.id,
'picking_type_id': picking_type_stock.id,
'action': 'push',
'sequence': 24,
},
{
'name': 'WH: 原料存货区 → 外包位置 (MTO)',
'location_src_id': material_location_id.id,
'location_dest_id': subcontracting_location_id.id,
'route_id': mto_route_id.id,
'picking_type_id': picking_type_subcontracting.id,
'action': 'pull',
'sequence': 24,
'warehouse_id': warehouse.id,
'procure_method': 'mts_else_mto',
},
{
'name': 'WH: 坯料存货区 → 外包位置 (MTO)',
'location_src_id': raw_material_location_id.id,
'location_dest_id': subcontracting_location_id.id,
'route_id': mto_route_id.id,
'picking_type_id': picking_type_subcontracting.id,
'action': 'pull',
'sequence': 25,
'warehouse_id': warehouse.id,
'procure_method': 'mts_else_mto',
},
{
'name': 'WH: 坯料存货区 → 外包位置',
'location_src_id': raw_material_location_id.id,
'location_dest_id': subcontracting_location_id.id,
'route_id': resupply_route_id.id,
'picking_type_id': picking_type_subcontracting.id,
'action': 'pull',
'sequence': 26,
'warehouse_id': warehouse.id,
'procure_method': 'make_to_stock',
}
]
# 遍历每个规则数据,执行创建或更新操作
for rule_data in rules_data:
_create_or_update_stock_rule(env, rule_data)
def _create_or_update_stock_rule(env, rule_data):
# 尝试查找现有的 stock.rule
existing_rule = env['stock.rule'].search([
('name', '=', rule_data['name']),
('route_id', '=', rule_data.get('route_id'))
], limit=1)
if existing_rule:
# 如果存在,更新现有记录
existing_rule.write(rule_data)
else:
# 如果不存在,创建新记录
env['stock.rule'].create(rule_data)
def _data_uninstall(cr, registry):
env = api.Environment(cr, SUPERUSER_ID, {})
warehouse = env['stock.warehouse'].search([('company_id', '=', env.company.id)], limit=1)
product_route_id = warehouse.pbm_route_id
resupply_route_id = warehouse.subcontracting_route_id
mto_route_id = env.ref('stock.route_warehouse0_mto')
# Fail unlink means that the route is used somewhere (e.g. route_id on stock.rule). In this case
# we don't try to do anything.
try:
with env.cr.savepoint():
env['stock.rule'].search([('name', 'in', ('WH: 原料存货区 → 制造前', 'WH: 坯料存货区 → 制造前', 'WH: 制造后 → 坯料存货区', 'WH: 制造后 → 成品存货区')), ('route_id', '=', product_route_id.id)]).unlink()
env['stock.rule'].search([('name', 'in', ('WH: 原料存货区 → 外包位置 (MTO)', 'WH: 坯料存货区 → 外包位置 (MTO)')), ('route_id', '=', mto_route_id.id)]).unlink()
env['stock.rule'].search([('name', '=', 'WH: 坯料存货区 → 外包位置'), ('route_id', '=', resupply_route_id.id)]).unlink()
except:
pass

View File

@@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
{
'name': '机企猫 多供货方式',
'version': '16.0.1.0.0',
'summary': """ 报价单提供(自动化产线加工/人工线下加工/外购/委外加工)多种供货方式选择 """,
'author': 'fox',
'website': '',
'category': '',
'depends': ['sf_dlm', 'sale_stock', 'sf_sale', 'sale'],
"data": [
'security/ir.model.access.csv',
'data/stock_routes.xml',
'data/product_data.xml',
# 'views/product_product_views.xml',
],'assets': {
# 'web.assets_backend': [
# 'jikimo_sale_multiple_supply_methods/static/src/**/*'
# ],
},
'post_init_hook': '_data_install',
'uninstall_hook': '_data_uninstall',
'application': True,
'installable': True,
'auto_install': False,
'license': 'LGPL-3',
}

View File

@@ -0,0 +1 @@
# -*- coding: utf-8 -*-

View File

@@ -0,0 +1,98 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data noupdate="1">
<record id="product_template_manual_processing" model="product.template">
<field name="name">人工线下加工模板</field>
<field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_finished_sf"/>
<field name="route_ids"
eval="[ref('stock.route_warehouse0_mto'), ref('mrp.route_warehouse0_manufacture')]"/>
<field name="invoice_policy">delivery</field>
<field name="detailed_type">product</field>
<field name="purchase_ok">false</field>
<field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/>
<field name="single_manufacturing">true</field>
<field name="tracking">serial</field>
<!-- <field name="categ_type">成品</field> -->
<field name="is_manual_processing">true</field>
</record>
<record id="product_template_purchase" model="product.template">
<field name="name">成品外购模板</field>
<field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_finished_sf"/>
<field name="route_ids"
eval="[ref('stock.route_warehouse0_mto'), ref('purchase_stock.route_warehouse0_buy')]"/>
<field name="tracking">serial</field>
<field name="detailed_type">product</field>
<field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/>
<!-- <field name="categ_type">成品</field> -->
</record>
<record id="product_template_outsourcing" model="product.template">
<field name="name">成品委外加工模板</field>
<field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_finished_sf"/>
<field name="route_ids"
eval="[ref('stock.route_warehouse0_mto'), ref('purchase_stock.route_warehouse0_buy'), ref('mrp_subcontracting.route_resupply_subcontractor_mto')]"/>
<field name="tracking">serial</field>
<field name="detailed_type">product</field>
<field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/>
<!-- <field name="categ_type">成品</field> -->
</record>
<record id="product_template_default" model="product.template">
<field name="name">成品初始化模板</field>
<field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_finished_sf"/>
<field name="route_ids" eval="[]"/>
<field name="tracking">serial</field>
<field name="detailed_type">product</field>
<field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/>
<!-- <field name="categ_type">成品</field> -->
</record>
<!-- 供应商信息业务平台由于数据是python创建只能指定ID -->
<record id="product_supplierinfo_bfm" model="product.supplierinfo">
<field name="partner_id" eval="91"/>
</record>
<record id="product_template_embryo_customer_provided" model="product.template">
<field name="name">坯料客供料模板</field>
<field name="active" eval="False"/>
<field name="categ_id" ref="sf_dlm.product_category_embryo_sf"/>
<field name="route_ids" eval="[
ref('stock.route_warehouse0_mto'),
ref('mrp_subcontracting.route_resupply_subcontractor_mto'),
ref('jikimo_sale_multiple_supply_methods.route_material_processing')]"/>
<field name="sale_ok">false</field>
<field name="tracking">serial</field>
<field name="detailed_type">product</field>
<field name="uom_id" ref="uom.product_uom_unit"/>
<field name="uom_po_id" ref="uom.product_uom_unit"/>
<field name="company_id" ref="base.main_company"/>
<!-- <field name="categ_type">坯料</field> -->
<field name="seller_ids" eval="[ref('jikimo_sale_multiple_supply_methods.product_supplierinfo_bfm')]"/>
</record>
<record id="sf_dlm.product_embryo_sf_self_machining" model="product.product">
<field name="is_manual_processing">true</field>
</record>
<record id="sf_dlm.product_embryo_sf_self_machining" model="product.product">
<field name="route_ids" eval="[(4, ref('mrp_subcontracting.route_resupply_subcontractor_mto'))]"/>
</record>
<record id="sf_dlm.product_embryo_sf_purchase" model="product.product">
<field name="route_ids" eval="[(4, ref('mrp_subcontracting.route_resupply_subcontractor_mto'))]"/>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<data noupdate="1">
<record id="route_material_processing" model="stock.route">
<field name="name">带料加工</field>
<field name="product_selectable">true</field>
<field name="warehouse_selectable">true</field>
<field name="warehouse_ids" eval="[ref('stock.warehouse0')]"/>
<field name="sequence">16</field>
</record>
<record id="material_picking_in" model="stock.picking.type">
<field name="name">客供料入库</field>
<field name="code">incoming</field>
<field name="active">true</field>
<field name="company_id" ref="base.main_company"/>
<field name="sequence_code">DL</field>
<field name="warehouse_id" ref="stock.warehouse0"/>
<field name="default_location_src_id" ref="stock.stock_location_customers"/>
<field name="default_location_dest_id" eval="25"/>
</record>
<record id="rule_material_receiving" model="stock.rule">
<field name="name">带料收货</field>
<field name="route_id" ref="route_material_processing"/>
<field name="location_dest_id" ref="stock.stock_location_company"/>
<field name="location_src_id" ref="stock.stock_location_customers"/>
<field name="picking_type_id" ref="material_picking_in"/>
<field name="action">pull</field>
</record>
</data>
</odoo>

View File

@@ -0,0 +1,3 @@
# -*- coding: utf-8 -*-
from . import product_template
from . import mrp_bom

View File

@@ -0,0 +1,13 @@
from odoo import models, fields
class MrpBom(models.Model):
_inherit = 'mrp.bom'
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品后再次进行创建bom
def bom_create(self, product, bom_type, product_type):
bom_id = super(MrpBom, self).bom_create(product, bom_type, product_type)
# 成品的供应商从模板中获取
if product_type == 'product':
bom_id.subcontractor_id = product.product_tmpl_id.seller_ids.partner_id.id
return bom_id

View File

@@ -0,0 +1,26 @@
from odoo import models, fields, api
class ProductTemplate(models.Model):
_inherit = 'product.template'
is_manual_processing = fields.Boolean(string='人工线下加工')
is_customer_provided = fields.Boolean(string='客供料')
def copy_template(self, product_template_id):
if not isinstance(product_template_id, ProductTemplate):
raise ValueError('%s必须是ProductTemplate类型' % product_template_id)
self.route_ids = product_template_id.route_ids
self.categ_id = product_template_id.categ_id
self.invoice_policy = product_template_id.invoice_policy
self.detailed_type = product_template_id.detailed_type
self.purchase_ok = product_template_id.purchase_ok
self.uom_id = product_template_id.uom_id
self.uom_po_id = product_template_id.uom_po_id
self.company_id = product_template_id.company_id
self.single_manufacturing = product_template_id.single_manufacturing
self.tracking = product_template_id.tracking
self.is_bfm = product_template_id.is_bfm
self.is_manual_processing = product_template_id.is_manual_processing
# 复制 seller_ids
self.seller_ids = [(0, 0, {'partner_id': seller.partner_id.id, 'delay': 1.0}) for seller in product_template_id.seller_ids]

View File

@@ -0,0 +1,8 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_sale_order_group_production_engineer,sale.order_group_production_engineer,sale.model_sale_order,sf_base.group_production_engineer,1,1,0,0
access_sale_order_line_group_production_engineer,sale_order_line_group_production_engineer,sale.model_sale_order_line,sf_base.group_production_engineer,1,1,0,0
access_product_product_group_production_engineer,product_product_group_production_engineer,product.model_product_product,sf_base.group_production_engineer,1,0,0,0
access_product_template_group_production_engineer,product_template_group_production_engineer,product.model_product_template,sf_base.group_production_engineer,1,0,0,0
access_stock_picking_group_production_engineer,stock_picking_group_production_engineer,stock.model_stock_picking,sf_base.group_production_engineer,1,0,0,0
access_stock_move_group_production_engineer,stock_move_group_production_engineer,stock.model_stock_move,sf_base.group_production_engineer,1,0,0,0
access_mrp_bom_group_production_engineer,mrp_bom_group_production_engineer,mrp.model_mrp_bom,sf_base.group_production_engineer,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_sale_order_group_production_engineer sale.order_group_production_engineer sale.model_sale_order sf_base.group_production_engineer 1 1 0 0
3 access_sale_order_line_group_production_engineer sale_order_line_group_production_engineer sale.model_sale_order_line sf_base.group_production_engineer 1 1 0 0
4 access_product_product_group_production_engineer product_product_group_production_engineer product.model_product_product sf_base.group_production_engineer 1 0 0 0
5 access_product_template_group_production_engineer product_template_group_production_engineer product.model_product_template sf_base.group_production_engineer 1 0 0 0
6 access_stock_picking_group_production_engineer stock_picking_group_production_engineer stock.model_stock_picking sf_base.group_production_engineer 1 0 0 0
7 access_stock_move_group_production_engineer stock_move_group_production_engineer stock.model_stock_move sf_base.group_production_engineer 1 0 0 0
8 access_mrp_bom_group_production_engineer mrp_bom_group_production_engineer mrp.model_mrp_bom sf_base.group_production_engineer 1 0 0 0

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<!-- 由于该模块不能依赖sf_dlm_management, 该功能只能在sf_dlm_management中实现并且依赖该模块-->
<record id="view_product_product_form_inherit_sf" model="ir.ui.view">
<field name="name">view.product.template.form.inherit.sf</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="sf_dlm_management.view_sale_product_template_form_inherit_sf"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='manual_quotation']" position="after">
<field name="is_customer_provided" attrs="{'invisible': [('categ_type', 'not in', ['成品', '坯料'])], 'readonly': True}" />
</xpath>
</field>
</record>
</odoo>

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,32 @@
# -*- 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)
@api.model
def search(self, args, limit=100, offset=0, order=None, count=False):
# 添加过滤条件,确保只返回名称不在指定列表中的记录
args += [('name', 'not in', ['Saleable', 'Expenses', 'Deliveries'])]
# 调用父类的 search 方法
return super(ProductCategory, self).search(args, limit=limit, offset=offset, order=order, count=count)

View File

@@ -203,7 +203,7 @@
<record id="quality_alert_action_check" model="ir.actions.act_window">
<field name="name">Quality Alerts</field>
<field name="res_model">quality.alert</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="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quality alert

View File

@@ -394,3 +394,30 @@ 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')
class ReSaleOrder(models.Model):
_inherit = 'sale.order'
person_of_delivery = fields.Char('收货人')
telephone_of_delivery = fields.Char('电话号码')
address_of_delivery = fields.Char('联系地址')
class EmbryoRedundancy(models.Model):
_name = "sf.embryo.redundancy"
code = fields.Char('编码', required=True)
name = fields.Char('名称', required=True)
long = fields.Float('长度(mm)', required=True)
width = fields.Float('宽度(mm)', required=True)
height = fields.Float('高度(mm)', required=True)
active = fields.Boolean('有效', default=True)

View File

@@ -56,7 +56,7 @@ class MrsMaterialModel(models.Model):
finish_machining = fields.Float("精加工Vc(m/min)")
remark = fields.Text("备注")
gain_way = fields.Selection(
[("自加工", "自加工"), ("外协", "外协"), ("采购", "采购")],
[("自加工", "自加工"), ("外协", "委外加工"), ("采购", "采购")],
default="", string="获取方式")
supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商')
active = fields.Boolean('有效', default=True)
@@ -100,6 +100,7 @@ class MrsProductionProcess(models.Model):
travel_day = fields.Float('路途天数/d')
sequence = fields.Integer('排序')
# class MrsProcessingTechnology(models.Model):
# _name = 'sf.processing.technology'
# _description = '加工工艺'
@@ -157,7 +158,9 @@ class MrsProductionProcessParameter(models.Model):
for parameter in self:
if parameter.process_id:
name = parameter.process_id.name + '-' + parameter.name
result.append((parameter.id, name))
else:
name = parameter.name
result.append((parameter.id, name))
return result
# 获取表面工艺的获取方式

View File

@@ -1,6 +1,6 @@
<odoo>
<data>
<record id="group_quality" model="res.groups">
<record id="group_quality" model="res.groups">
<field name="name">质检岗</field>
<field name="category_id" ref="base.module_category_manufacturing_quality"/>
</record>
@@ -46,6 +46,11 @@
<field name="category_id" ref="base.module_category_manufacturing_manufacturing"/>
</record>
<record id="group_production_engineer" model="res.groups">
<field name="name">工艺工程师</field>
<field name="implied_ids" eval="[(4, ref('group_sf_mrp_user'))]"/>
<field name="category_id" ref="base.module_category_manufacturing_manufacturing"/>
</record>
<record model="ir.module.category" id="module_category_plan">
<field name="name">计划</field>
@@ -65,7 +70,7 @@
<record id="group_plan_dispatch" model="res.groups">
<field name="name">计划调度岗</field>
<field name="category_id" ref="module_category_plan"/>
<!-- <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/> -->
<!-- <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/> -->
</record>
<record id="group_plan_director" model="res.groups">

View File

@@ -247,3 +247,10 @@ 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
access_sf_embryo_redundancy,sf_embryo_redundancy,model_sf_embryo_redundancy,base.group_user,1,0,0,0
access_sf_embryo_redundancy_admin,sf_embryo_redundancy_admin,model_sf_embryo_redundancy,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
254
255
256

View File

@@ -0,0 +1,125 @@
// 获取表格数据
function getDomData() {
const dom = $('div[name=cutting_speed_ids]')
if (!dom.length) return
const table = dom.find('.o_list_table')
const thead = table.children('thead')
const tbody = table.children('tbody')
const tbody_child = tbody.children()
const hideTheadDom = thead.find('[data-name=process_capability]')
hideTheadDom.hide().next().hide()
hideTheadDom.before('<th customTh>精加工</th><th customTh>粗加工</th>')
tbody_child.each(function () {
const dom = $(this).children('[name=process_capability]')
if(!dom.length) return
dom.css('cssText', 'display: none!important').next().css('cssText', 'display: none!important')
const isCu = dom.text() == '粗加工' // 是否粗加工
const v = dom.next().text() // 切削速度
dom.after(`<td customSpeed="1" name="process_capability" is="精加工" val="${ v }">${!isCu ? v : ''}</td><td customSpeed="1" name="process_capability" is="粗加工" val="${ v }">${isCu ? v : ''}</td>`)
setListenClick()
})
return;
handleTbody(tbody, newTableData, ΦList, table)
}
// 监听点击
function setListenClick() {
$(document).click(function (e) {
if ($(e.target).attr('customSpeed')) {
const orginV = $('[customInput=1]').children('input').val()
$('[customInput=1]').parent().html(orginV)
const v = $(e.target).attr('val')
const is = $(e.target).attr('is')
$(e.target).html('')
const input = $('<div customInput="1" is="' + is + '" class="o_field_widget o_field_char"><input class="o_input" type="text" autocomplete="off" maxlength="20"></div>')
input.children('input').val(v)
$(e.target).append(input)
input.children('input').focus()
input.children('input').select()
} else if ($(e.target).attr('customInput')) {
} else {
const orginV = $('[customInput=1]').children('input').val()
$('[customInput=1]').parent().html(orginV)
const v = $(e.target).attr('val')
}
})
$(document).off('change') // 防止重复绑定
$(document).on('change', '[customInput] input', async function () {
$(this).parents('td').attr('val', $(this).val())
$(this).parents('td').siblings('[customspeed]').attr('val', $(this).val())
var eve1 = new Event('change')
var eve2 = new Event('input')
var eve3 = new Event('click')
let patchSpeedDom = $(this).parents('td').siblings('[name=cutting_speed]')
let patchProcessDom = $(this).parents('td').siblings('[name=process_capability]')
$(this).parents('td').siblings('[customspeed]').text('') // 清空其他加工类型的数据
await timeOut(500)
patchProcessDom[0].dispatchEvent(eve3)
await timeOut(200)
const processVal = $(this).parent().attr('is')
patchProcessDom.find('select').val(`"${processVal}"`) // 设置源select的val为“加工类型 is”、
patchProcessDom.attr("data-tooltip", `${processVal}`)
patchProcessDom.find('select')[0].dispatchEvent(eve1)
patchSpeedDom[0].dispatchEvent(eve3)
await timeOut(200)
patchSpeedDom.find('input').val($(this).val())
await timeOut(50)
patchSpeedDom.find('input')[0].dispatchEvent(eve2)
patchSpeedDom.find('input')[0].dispatchEvent(eve1)
})
$(document).off('blur') // 防止重复绑定
$(document).on('blur', '[customInput] input', async function () {
if(!$(this).length) return
$(this).parents('td').siblings('[customspeed]').text('') // 清空其他加工类型的数据
let patchProcessDom = $(this).parents('td').siblings('[name=process_capability]')
try {
patchProcessDom[0].dispatchEvent(new Event('click'))
const processVal = $(this).parent().attr('is')
patchProcessDom.find('select').val(`"${processVal}"`) // 设置源select的val为“加工类型 is”、
patchProcessDom.attr("data-tooltip", `${processVal}`)
patchProcessDom.find('select')[0].dispatchEvent(new Event('change'))
} catch {
}
})
}
function timeOut(time) {
return new Promise(resolve => {
setTimeout(() => {
resolve()
}, time)
})
}
function listenAdd() {
$('td.o_field_x2many_list_row_add a').click(async function () {
await timeOut(500)
const tr = $('.o_list_table').children('tbody').children('tr').eq(-2)
if(tr.children('td').eq(2).text() == '') {
const dom = tr.children('[name=process_capability]')
if(!dom.length) return
dom.css('cssText', 'display: none!important').next().css('cssText', 'display: none!important')
const isCu = dom.text() == '粗加工' // 是否粗加工
const v = dom.next().text() // 切削速度
dom.after(`<td customSpeed="1" name="process_capability" is="精加工" val="${ v }">${!isCu ? v : ''}</td><td customSpeed="1" name="process_capability" is="粗加工" val="${ v }">${isCu ? v : ''}</td>`)
}
})
}
function listenSave() {
$('.o_form_button_save').click( async function () {
await timeOut(1000)
if($(this).parent().next().length) return
$('th[customTh],td[cusomSpeed]').remove()
getDomData()
})
}
listenAdd()
listenSave()
getDomData()

View File

@@ -0,0 +1,47 @@
// 因为表格可以拖动设置宽度所以需要用js设置初始宽度
function setBasicParamTableWidth() {
// const _100px = 'th[data-name="cutting_blade_length"],th[data-name="cutting_blade_length"],th[data-name="name"],th[data-name="tip_handling_size"],th[data-name="cutting_depth_max"],th[data-name="diameter_inner_circle"],th[data-name="diameter_mounting_hole" ],th[data-name="radius_tip_re" ],th[data-name="is_chip_breaker"],th[data-name="chip_breaker_type_code"],th[data-name="blade_profile"]'
// const _65px = 'th[data-name="edge_angle"],th[data-name="relief_angle"],[data-name="total_length"],th[data-name="length"],th[data-name="thickness"],th[data-name="blade_number"]'
// const _80px = 'th[data-name="arbor_diameter"],th[data-name="head_height"],th[data-name="head_width"],th[data-name="head_length"],th[data-name="blade_diameter"],th[data-name="blade_length"] ,th[data-name="neck_length"] ,th[data-name="neck_diameter"] ,th[data-name="shank_diameter"],th[data-name="shank_length"],th[data-name="tip_diameter"],th[data-name="knife_tip_taper"],th[data-name="blade_helix_angle"] ,th[data-name="blade_width"],th[data-name="blade_depth"]'
// const _50px = 'th[data-name="pitch"],th[data-name="width"],th[data-name="height"]'
const basicParamDom = $('.fixTableCss')
// const basicParamDom_100px = basicParamDom.find(_100px) // 四字以上
// const basicParamDom_65px = basicParamDom.find(_65px) // 大概三个字加单位
// const basicParamDom_80px = basicParamDom.find(_80px) // 大概四个字加单位
// const basicParamDom_50px= basicParamDom.find(_50px) // 大概两个字加单位
//
// basicParamDom_100px.css({'width': '100px', 'max-width': 'auto', ',min-width': 'auto'})
// basicParamDom_65px.css({'width': '65px', 'max-width': 'auto', ',min-width': 'auto'})
// basicParamDom_80px.css({'width': '80px', 'max-width': 'auto', ',min-width': 'auto'})
// basicParamDom_50px.css({'width': '50px', 'max-width': 'auto', ',min-width': 'auto'})
let dom = []
try {
dom = basicParamDom.find('table').find('thead').children().children()
} catch {
dom = []
}
if (!dom) return
dom.each(function () {
if ($(this).hasClass('row_no') >= 0) { // 序号列
// 不设置 通过css设置
}
const text = $(this).text().split('(')
if ($(this).attr('data-name') == 'name' || text[0].length > 4) {
$(this).width('100px')
} else if(text[0].length == 4){
$(this).width('80px')
} else if(text[0].length == 3){
$(this).width('65px')
} else if(text[0].length == 2){
$(this).width('50px')
}
})
}
setBasicParamTableWidth()
$('.o_field_many2one_selection').on('click', $('#cutting_tool_material_id + ul'), function () {
setTimeout(setBasicParamTableWidth, 500)
})

View File

@@ -0,0 +1,159 @@
// 获取表格数据
function getDomData() {
const dom = $('#updateTable').prev()
if (!dom.length) return
const table = $('#updateTable').prev().find('.o_list_table')
const customTable = table.clone()
customTable.addClass('customTable')
table.parent().append(customTable)
table.hide()
const thead = customTable.children('thead')
const tbody = customTable.children('tbody')
const tableData = []
const tbody_child = tbody.children()
const tbody_child_len = tbody_child.length
for (let v = 0; v < tbody_child_len; v++) { // 将数据取出来到tableData里面
const data = tbody_child[v].innerText.split('\t')
// console.log('dom data',data)
const [index, deep, name, Φ, value] = data
tableData.push({index, deep, name, Φ, value})
}
const ΦList = [...new Set(tableData.map(_ => _.name))] // ΦList去重
const newTableData = {}
tableData.forEach(_ => {
const key = _.deep + '|' + _.Φ
!newTableData[key] ? newTableData[key] = {i: _.index} : '';
if (_.Φ) { // 去除没有Φ的脏数据
newTableData[key]['Φ' + _.Φ] = _.value
newTableData[key]['Φ' + _.Φ + 'i'] = _.index
}
})
// console.log('qwdh',tableData, ΦList, newTableData);
if (ΦList.filter(_ => _).length == 0) return;
handleThead(thead, ΦList)
handleTbody(tbody, newTableData, ΦList, table)
}
// 重新设置表头、
function handleThead(thead, ΦList) {
const dom = thead.children().eq(0).children()
const len = dom.length
dom.eq(0).attr('rowspan', 2)
dom.eq(1).attr('rowspan', 2)
len == 5 ? dom.eq(2).attr('rowspan', 2) : ''
dom.eq(-2).attr('colspan', ΦList.length)
dom.eq(-1).remove()
const tr = document.createElement('tr')
for (let v = 0; v < ΦList.length; v++) {
const th = document.createElement('th')
th.innerText = 'Φ' + ΦList[v]
tr.append(th)
}
thead.append(tr)
}
// 重新设置表格
function handleTbody(tbody, newTableData, ΦList, table) {
console.log(newTableData)
tbody.html('')
let i = 0
const data = Object.keys(newTableData)
// data.sort((a, b) => {
// a = a.split('=')[1].split('%')[0]
// b = b.split('=')[1].split('%')[0]
// return a - b
// })
// console.log('wqoqw ',ΦList)
data.forEach(_ => {
i++
const tr = $('<tr class="o_data_row"></tr>')
const td0 = $('<td></td>')
td0.text(i)
tr.append(td0)
const lit = _.split('|')
//
const td1 = $('<td></td>')
const td2 = $('<td></td>')
td1.text(lit[0])
td2.text(lit[1] || '')
tr.append(td1)
tr.append(td2)
ΦList.forEach(Φ => {
const td = $('<td class="o_data_cell cursor-pointer o_field_cell o_list_char"></td>')
td.text(newTableData[_]['Φ' + Φ])
td.attr('col', newTableData[_]['Φ' + Φ + 'i'])
td.attr('val', newTableData[_]['Φ' + Φ])
td.attr('coustomTd', 1)
tr.append(td)
})
// // for (let j = 0; j < ΦList.length; j++) {
// // const td = document.createElement('td')
// // td.innerText = newTableData[data[v]][_]
// // th.append(td)
// // }
tbody.append(tr)
})
// $(document).click(function (e) {
// if ($(e.target).attr('coustomTd')) {
// const orginV = $('[coustomInput=1]').children('input').val()
// $('[coustomInput=1]').parent().html(orginV)
// const v = $(e.target).attr('val')
// console.log($(e.target));
// $(e.target).html('')
// const input = $('<div coustomInput="1" name="feed_per_tooth" class="o_field_widget o_field_char"><input class="o_input" type="text" autocomplete="off" maxlength="20"></div>')
// input.children('input').val(v)
// $(e.target).append(input)
// input.children('input').focus()
// input.children('input').select()
// } else if ($(e.target).attr('coustomInput')) {
//
// } else {
// const orginV = $('[coustomInput=1]').children('input').val()
// $('[coustomInput=1]').parent().html(orginV)
// const v = $(e.target).attr('val')
// }
// })
// $(document).off('change') // 防止重复绑定
// $(document).on('change', '[coustomInput] input', function () {
// $(this).parents('td').attr('val', $(this).val());
// var eve1 = new Event('change');
// var eve2 = new Event('input');
// var eve3 = new Event('click');
// const i = $(this).parents('td').attr('col');
// let patchDom = table.find('tbody').children('tr').eq(i - 1);
//
// if (patchDom.length === 0) {
// console.error('No such row found');
// return;
// }
//
// patchDom = patchDom.children().eq(-1);
//
// setTimeout(() => {
// if (patchDom.length === 0) {
// console.error('No such cell found');
// return;
// }
// patchDom[0].dispatchEvent(eve3); // Simulate click event
//
// setTimeout(() => {
// patchDom = patchDom.find('input');
// if (patchDom.length === 0) {
// console.error('No input found in the target cell');
// return;
// }
// patchDom.val($(this).val());
// patchDom[0].dispatchEvent(eve2);
// patchDom[0].dispatchEvent(eve1);
// }, 200);
// }, 500);
// });
}
getDomData()

View File

@@ -0,0 +1,52 @@
.o_list_renderer .o_list_table tbody > tr > td:not(.o_list_record_selector):not(.o_handle_cell):not(.o_list_button):not(.o_list_record_remove) {
white-space: nowrap !important;
}
.text-truncate {
overflow: unset !important;
text-overflow: unset !important;
white-space: unset !important;
}
// 设置表格不超出页面宽度
.o_form_view .o_field_widget .o_list_renderer {
width: calc(100% - 64px) !important;
margin:0 auto;
overflow: auto;
}
// 表格针对处理
.fixTableCss {
text-align: center;
.o_list_number_th,.o_list_number {
text-align: center!important;
}
.ui-sortable {
tr > td:first-child {
padding: 0!important;
}
}
.row_no {
padding: 0!important;;
width: 35px!important;
}
th[data-name="total_length"],th[data-name="length"],th[data-name="thickness"] {
.flex-row-reverse {
span {
text-align: center;
}
}
}
}
// 其他不能用js处理的表格
.otherTableFix {
th[data-name="cutting_tool_material_id"] {
width: 100px!important;
}
th[data-name="ramping_angle_max"],th[data-name="ramping_angle_min"] {
width: 200px!important;
}
}

View File

@@ -14,6 +14,7 @@
.img-fluid {
max-width: unset !important;
width: 40px;
}
.o_inner_group .img-fluid {

View File

@@ -614,4 +614,45 @@
<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>
#------------------坯料冗余量------------------
<record model="ir.ui.view" id="tree_sf_embryo_redundancy_view">
<field name="name">tree.sf.embryo.redundancy</field>
<field name="model">sf.embryo.redundancy</field>
<field name="arch" type="xml">
<tree string="坯料冗余量" create="0" edit="0" delete="0">
<field name="name"/>
<field name="code"/>
<field name="long"/>
<field name="width"/>
<field name="height"/>
</tree>
</field>
</record>
<record id="action_sf_embryo_redundancy" model="ir.actions.act_window">
<field name="name">坯料冗余量</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sf.embryo.redundancy</field>
<field name="view_mode">tree</field>
</record>
</odoo>

View File

@@ -141,12 +141,25 @@
sequence="1"
action="action_sf_machine_brand"/>
<menuitem
id="menu_sf_embryo_redundancy"
parent="menu_sf_base"
name="坯料冗余"
sequence="2"
action="action_sf_embryo_redundancy"/>
<menuitem
id="menu_sf_machining_accuracy"
parent="menu_sf_base"
name="加工精度"
sequence="3"
action="action_sf_machining_accuracy"/>
<menuitem
id="menu_sf_machine_control_system"
parent="menu_sf_base"
name="数控系统"
sequence="1"
sequence="4"
action="action_sf_machine_control_system"/>

View File

@@ -360,6 +360,7 @@
<field name="cooling_jacket"/>
</tree>
</field>
<script src="/sf_base/static/js/setTableWidth.js?time=3"></script>
</page>
<page string="切削速度Vc"
attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀片'))]}">
@@ -380,6 +381,9 @@
<field name="cutting_speed"/>
</tree>
</field>
<script src="/sf_base/static/js/customTable.js?time=3"></script>
<script src="/sf_base/static/js/setTableWidth.js?time=3"></script>
</page>
<page string="每齿走刀量fz"
attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀片'))]}">
@@ -392,6 +396,8 @@
<field name="feed_per_tooth"/>
</tree>
</field>
<div id="updateTable"></div>
<script src="/sf_base/static/js/updateTable.js?time=3"></script>
<field name="feed_per_tooth_ids_3"
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}">
<tree editable="bottom" class="center" create="0" delete="0">

View File

@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
import json
import logging
import traceback
from odoo import http
from odoo.http import request
@@ -123,7 +125,8 @@ class Sf_Bf_Connect(http.Controller):
res['factory_order_no'] = order_id.name
return json.JSONEncoder().encode(res)
except Exception as e:
logging.info('get_bfm_process_order_list error:%s' % e)
traceback_error = traceback.format_exc()
logging.error('get_bfm_process_order_list error: %s' % traceback_error)
res['status'] = -1
res['message'] = '工厂创建销售订单和产品失败,请联系管理员'
request.cr.rollback()

View File

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

View File

@@ -58,7 +58,7 @@
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="//form//sheet//notebook//page[@name='operations']" position="after">
<page string="发货信息" name="tracking">
<page string="发货信息" name="tracking" attrs="{'invisible': [('picking_type_code', '!=', 'outgoing')]}">
<group>
<group>
<field name="senderNickName" attrs="{'invisible': [('check_out', '!=', 'OUT')]}"/>

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
<data noupdate="1">
<record id="product_category_embryo_sf" model="product.category">
<field name="name">坯料</field>
<field name="type">坯料</field>

View File

@@ -1 +1,3 @@
from . import product_supplierinfo
from . import stock_rule_inherit

View File

@@ -0,0 +1,87 @@
import logging
from itertools import groupby
from odoo import models, fields, api, _
class StockRuleInherit(models.Model):
_inherit = 'stock.rule'
@api.model
def _run_buy(self, procurements):
# 判断补货组的采购类型
procurements_group = {'standard': [], 'consignment': []}
for procurement, rule in procurements:
is_consignment = False
product = procurement.product_id
# 获取主 BOM
bom = self.env['mrp.bom'].search([('product_tmpl_id', '=', product.product_tmpl_id.id)], limit=1)
if bom:
# 遍历 BOM 中的组件(即坯料等)
for line in bom.bom_line_ids:
raw_material = line.product_id
# 检查路线
for route in raw_material.route_ids:
# print('route.name:', route.name)
if route.name == '按订单补给外包商':
is_consignment = True
if is_consignment:
procurements_group['consignment'].append((procurement, rule))
else:
procurements_group['standard'].append((procurement, rule))
for key, value in procurements_group.items():
super(StockRuleInherit, self)._run_buy(value)
if key == 'consignment':
for procurement, rule in value:
supplier = procurement.values.get('supplier')
if supplier:
domain = rule._make_po_get_domain(procurement.company_id, procurement.values,
supplier.partner_id)
logging.info("domain=============: %s", domain)
po = self.env['purchase.order'].sudo().search([
('partner_id', '=', supplier.partner_id.id),
('company_id', '=', procurement.company_id.id), # 保证公司一致
('origin', 'like', procurement.origin), # 根据来源匹配
('state', '=', 'draft') # 状态为草稿
], limit=1)
logging.info("po=: %s", po)
if po:
po.write({'purchase_type': 'consignment'})
# # 首先调用父类的 _run_buy 方法,以保留原有逻辑
# super(StockRuleInherit, self)._run_buy(procurements)
# 然后在这里添加自定义的逻辑
# for procurement, rule in procurements:
# product = procurement.product_id
# # 获取主 BOM
# bom = self.env['mrp.bom'].search([('product_tmpl_id', '=', product.product_tmpl_id.id)], limit=1)
# if bom:
# # 遍历 BOM 中的组件(即坯料等)
# for line in bom.bom_line_ids:
# raw_material = line.product_id
# # 检查路线
# for route in raw_material.route_ids:
# # print('route.name:', route.name)
# if route.name == '按订单补给外包商': # 或者用 route.id 检查精确的路线
# print("按订单补给外包商============是")
# # 使用 procurement.values['supplier'] 获取供应商
# supplier = procurement.values.get('supplier')
# if supplier:
# domain = rule._make_po_get_domain(procurement.company_id, procurement.values,
# supplier.partner_id)
# logging.info("domain=============: %s", domain)
# po = self.env['purchase.order'].sudo().search([
# ('partner_id', '=', supplier.partner_id.id),
# ('company_id', '=', procurement.company_id.id), # 保证公司一致
# ('origin', '=', procurement.origin), # 根据来源匹配
# ('state', '=', 'draft') # 状态为草稿
# ], limit=1)
# logging.info("po=: %s", po)
# if po:
# po.write({'purchase_type': 'consignment'})
# break

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

@@ -2,6 +2,7 @@
<odoo>
<data>
<record id="mrp.product_template_action" model="ir.actions.act_window">
<field name="view_mode">tree,kanban,form,activity</field>
<field name="context">
{"search_default_categ_id":1,"search_default_consumable": 1, 'default_detailed_type': 'product'}
</field>
@@ -15,10 +16,10 @@
<field name='categ_id' class="custom_required" attrs="{'readonly': [('id', '!=', False)]}"/>
<field name='is_bfm' invisible="1"/>
<field name='categ_type' invisible="1"/>
<field name='part_name' attrs="{'invisible': [('categ_type', '!=', '成品')]}"/>
<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="is_customer_provided" attrs="{'invisible': [('categ_type', 'not in', ['成品', '坯料'])], 'readonly': True}" />
<field name="upload_model_file"
widget="many2many_binary"
attrs="{'invisible': ['|', '|',('categ_type', '!=', '成品'),('categ_type', '=', False),('is_bfm','=', True)]}"/>
@@ -65,6 +66,9 @@
attrs="{'invisible': [('categ_type', '!=', '夹具')],'required': [('categ_type', '=', '夹具')]}"
domain="[('fixture_model_id','=',fixture_model_id)]"/>
</field>
<xpath expr="//field[@name='uom_id']" position="before">
<field name="is_manual_processing" attrs="{'invisible': [('categ_type', 'not in', ['成品', '坯料'])], 'readonly': True}" />
</xpath>
<xpath expr="//label[@for='volume']" position="before">
<label for="length" string="尺寸"
attrs="{'invisible':[('product_variant_count', '>', 1), ('is_product_variant', '=', False)]}"/>
@@ -111,6 +115,17 @@
'刀具')], 'required': True}
</attribute>
</xpath>
<xpath expr="//sheet//notebook" position="inside">
<page string="2D加工图纸" attrs="{'invisible': [('categ_type', 'not in', ['成品', '坯料'])]}">
<field name='machining_drawings' widget="adaptive_viewer"/>
</page>
</xpath>
<xpath expr="//sheet//notebook" position="inside">
<page string="质检标准" attrs="{'invisible': [('categ_type', 'not in', ['成品', '坯料'])]}">
<field name='quality_standard' 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 @@
from . import hr_employee
from . import res_config_setting
from . import res_users

View File

@@ -11,6 +11,42 @@ class JkmPracticeEmployee(models.Model):
we_id = fields.Char(string='企微ID', index=True)
@api.model_create_multi
def create(self, vals_list):
for val in vals_list:
if 'work_email' in val:
val["we_id"] = self._get_we_id(val.get('work_email'))
return super(JkmPracticeEmployee, self).create(vals_list)
def write(self, vals):
if 'work_email' in vals:
vals["we_id"] = self._get_we_id(vals.get('work_email'))
return super(JkmPracticeEmployee, self).write(vals)
@api.depends('work_contact_id', 'work_contact_id.mobile', 'work_contact_id.email')
def _compute_work_contact_details(self):
for employee in self:
if employee.work_contact_id:
employee.mobile_phone = employee.work_contact_id.mobile
employee.work_email = employee.work_contact_id.email
if employee.work_contact_id.email:
employee.we_id = self._get_we_id(employee.work_contact_id.email)
def _get_we_id(self, work_email):
json1 = {
'params': {
'work_email': work_email
}
}
url = '/api/get/we_id/info'
config = self.env['res.config.settings'].get_values()
ret = requests.post((config['ims_url'] + url), json=json1, data={})
result = ret.json()['result']
if result['code'] == 200:
if result['we_id']:
return result['we_id']
return None
def _employee_info_sync(self):
url = '/api/get/organization'
config = self.env['res.config.settings'].get_values()

15
sf_hr/models/res_users.py Normal file
View File

@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
import random
from odoo import models, fields, api
from odoo.http import request
from odoo.exceptions import AccessDenied
import logging
_logger = logging.getLogger(__name__)
class ResUsers(models.Model):
_inherit = 'res.users'
we_employee_id = fields.Char(string=u'企业微信账号', related='employee_id.we_id', default="")

View File

@@ -1264,6 +1264,7 @@ class Sf_Dashboard_Connect(http.Controller):
"""
获取
"""
logging.info("kw=============:%s" % kw)
res = {'status': 1, 'message': '成功', 'data': {}}
# 连接数据库
conn = psycopg2.connect(**db_config)

View File

@@ -10,6 +10,9 @@
<searchpanel>
<field name="routing_type" select="multi" string="工序类型" icon="fa-building" enable_counters="1"/>
<field name="state" select="multi" string="状态" icon="fa-building" enable_counters="1"/>
<field name="construction_period_status" select="multi" icon="fa-building" enable_counters="1"/>
<field name="tag_type" select="multi" icon="fa-building" enable_counters="1"/>
<!-- <field name="manual_quotation" select="multi" string="" icon="fa-building" enable_counters="1"/>-->
</searchpanel>

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,9 @@ class SfMaintenanceEquipment(models.Model):
if next_date < date_now:
next_date = date_now
else:
next_date = equipment.effective_date + timedelta(days=equipment.period)
if not equipment.initial_action_date:
raise ValidationError('重置保养日期不能为空!!!')
next_date = equipment.initial_action_date + timedelta(days=equipment.period)
equipment.next_action_date = next_date
else:
self.next_action_date = False
@@ -635,11 +702,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 +737,9 @@ class SfMaintenanceEquipment(models.Model):
if next_date < date_now:
next_date = date_now
else:
next_date = equipment.effective_date + timedelta(days=equipment.overhaul_period)
if not equipment.initial_overhaul_date:
raise ValidationError('重置维修日期不能为空')
next_date = equipment.initial_overhaul_date + timedelta(days=equipment.overhaul_period)
equipment.overhaul_date = next_date
else:
self.overhaul_date = False
@@ -735,6 +806,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 +815,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

@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
import re
import json
import logging
import datetime
import requests
from odoo import api, fields, models, _
@@ -62,22 +63,22 @@ class SfMaintenanceEquipmentOEE(models.Model):
("封存(报废)", "封存(报废)")],
default='正常', string="机床状态", related='equipment_id.state')
online_time = fields.Char('开机时长(小时)', reaonly='True')
online_time = fields.Char('开机时长(小时)', readonly='True')
offline_time = fields.Char('关机时长(小时)', reaonly='True')
idle_nums = fields.Integer('待机次数', reaonly='True')
offline_time = fields.Char('关机时长(小时)', readonly='True')
idle_nums = fields.Integer('待机次数', readonly='True')
# 待机时长
idle_time = fields.Char('待机时长(小时)', reaonly='True')
idle_time = fields.Char('待机时长(小时)', readonly='True')
# 待机率
idle_rate = fields.Char('待机率(%)', reaonly='True')
idle_rate = fields.Char('待机率(%)', readonly='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')
work_time = fields.Char('加工时长(小时)', readonly='True')
work_rate = fields.Char('可用率(%)', readonly='True')
fault_time = fields.Char('故障时长(小时)', readonly='True')
fault_rate = fields.Char('故障率(%)', readonly='True')
fault_nums = fields.Integer('故障次数', readonly='True')
# 设备故障日志
sf_maintenance_logs_ids = fields.One2many('sf.maintenance.logs', 'maintenance_equipment_oee_id', '设备故障日志',
@@ -90,11 +91,18 @@ class SfMaintenanceEquipmentOEE(models.Model):
def get_running_datas(self):
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
url_time = base_url + '/api/RunningTimeDetail'
logging.info("base_url=============:%s" % base_url)
# 只有当原始 URL 使用 http 时才替换为 https
if base_url.startswith("http://"):
secure_base_url = base_url.replace("http://", "https://")
else:
secure_base_url = base_url
url_time = secure_base_url + '/api/RunningTimeDetail'
logging.info("url_time=============:%s" % url_time)
cnc_list_obj = self.env['maintenance.equipment'].sudo().search(
[('function_type', '!=', False), ('active', '=', True)])
machine_list = list(map(lambda x: x.code, cnc_list_obj))
# print('machine_list: %s' % machine_list)
logging.info("machine_list=============:%s" % machine_list)
data_time = {
"machine_list": str(machine_list)
@@ -367,25 +375,25 @@ class SfMaintenanceEquipmentOEELog(models.Model):
[("ZXJGZX", "钻铣加工中心"), ("CXJGZX", "车削加工中心"), ("FHJGZX", "复合加工中心")],
default="", string="功能类型")
machine_tool_picture = fields.Binary('设备图片')
type_id = fields.Many2one('sf.machine_tool.type', '品牌型号', reaonly='True')
type_id = fields.Many2one('sf.machine_tool.type', '品牌型号', readonly='True')
state = fields.Selection([("加工", "加工"), ("关机", "关机"), ("待机", "待机"), ("故障", "故障"),
("检修", "检修"), ("保养", "保养")], default="", string="实时状态")
online_time = fields.Char('开机时长', reaonly='True')
online_time = fields.Char('开机时长', readonly='True')
offline_time = fields.Char('关机时长', reaonly='True')
offline_nums = fields.Integer('关机次数', reaonly='True')
offline_time = fields.Char('关机时长', readonly='True')
offline_nums = fields.Integer('关机次数', readonly='True')
# 待机时长
idle_time = fields.Char('待机时长', reaonly='True')
idle_time = fields.Char('待机时长', readonly='True')
# 待机率
idle_rate = fields.Char('待机率', reaonly='True')
idle_rate = fields.Char('待机率', readonly='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')
work_time = fields.Char('加工时长', readonly='True')
work_rate = fields.Char('可用率', readonly='True')
fault_time = fields.Char('故障时长', readonly='True')
fault_rate = fields.Char('故障率', readonly='True')
fault_nums = fields.Integer('故障次数', readonly='True')
detail_ids = fields.One2many('maintenance.equipment.oee.log.detail', 'log_id', string='日志详情')

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,8 +138,8 @@
<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_id" ref="maintenance.hr_equipment_request_view_kanban"/>
<field name="view_mode">tree,kanban,form,pivot,graph,calendar</field>
<field name="view_id" ref="sf_maintenance.maintenance_request_view_tree_sf"/>
<field name="context">{'default_user_id': uid}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">

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

@@ -2,7 +2,7 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
{
'name': '机企猫智能工厂 制造管理',
'version': '1.0',
'version': '1.1',
'summary': '智能工厂制造模块',
'sequence': 1,
'description': """
@@ -10,8 +10,9 @@
""",
'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', 'jikimo_sale_multiple_supply_methods'],
'data': [
'data/cron_data.xml',
'data/stock_data.xml',
'data/empty_racks_data.xml',
'data/panel_data.xml',
@@ -21,6 +22,8 @@
'wizard/workpiece_delivery_views.xml',
'wizard/rework_wizard_views.xml',
'wizard/production_wizard_views.xml',
'wizard/production_technology_wizard_views.xml',
'wizard/production_technology_re_adjust_wizard_views.xml',
'views/mrp_views_menus.xml',
'views/agv_scheduling_views.xml',
'views/stock_lot_views.xml',
@@ -29,10 +32,12 @@
'views/production_line_view.xml',
'views/mrp_workcenter_views.xml',
'views/mrp_workorder_view.xml',
'views/stock_picking_view.xml',
'views/model_type_view.xml',
'views/agv_setting_views.xml',
'views/sf_maintenance_equipment.xml',
'views/res_config_settings_views.xml',
'views/sale_order_views.xml',
],
'assets': {
@@ -45,6 +50,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

@@ -1,2 +1,3 @@
from . import controllers
from . import workpiece
from . import main

View File

@@ -0,0 +1,54 @@
import logging
import json
import traceback
from odoo import http
from odoo.http import request
from odoo.addons.sf_bf_connect.controllers.controllers import Sf_Bf_Connect
_logger = logging.getLogger(__name__)
class JikimoSaleRoutePicking(Sf_Bf_Connect):
@http.route('/api/bfm_process_order/list', type='http', auth='sf_token', methods=['GET', 'POST'], csrf=False,
cors="*")
def get_bfm_process_order_list(self, **kw):
"""
接收业务平台加工订单分配工厂时传送来的订单数据并生成销售订单和产品及坯料
:param kw:
:return:
"""
res = {'status': 1, 'factory_order_no': ''}
# _logger.info('get_bfm_process_order_list:%s' % kw['order_number'])
try:
product_id = request.env.ref('jikimo_sale_multiple_supply_methods.product_template_default').with_context(active_test=False).sudo().product_variant_id
_logger.info('product_id:%s' % product_id)
company_id = request.env.ref('base.main_company').sudo()
bfm_process_order_list = json.loads(kw['bfm_process_order_list'])
order_id = request.env['sale.order'].with_user(request.env.ref("base.user_admin")).sale_order_create(
company_id, kw['delivery_name'], kw['delivery_telephone'], kw['delivery_address'],
kw['delivery_end_date'], kw['payments_way'], kw['pay_way'], state='draft')
i = 1
# 给sale_order的default_code字段赋值
# aa = request.env['sale.order'].sudo().search([('name', '=', order_id.name)])
# _logger.info('get_bfm_process_or===================================:%s' % order_id.name)
order_id.default_code = kw['order_number']
if kw.get('logistics_way'):
order_id.logistics_way = kw['logistics_way']
for item in bfm_process_order_list:
if item.get('embryo_redundancy_id'):
item['embryo_redundancy'] = request.env['sf.embryo.redundancy'].sudo().search([('code', '=', item['embryo_redundancy_id'])], limit=1)
item['embryo_redundancy_id'] = item['embryo_redundancy'].id
product = request.env['product.template'].sudo().product_create(product_id, item, order_id,
kw['order_number'], i)
product.product_tmpl_id.is_customer_provided = True if item['embryo_redundancy_id'] else False
order_id.with_user(request.env.ref("base.user_admin")).sale_order_create_line(product, item)
i += 1
res['factory_order_no'] = order_id.name
except Exception as e:
traceback_error = traceback.format_exc()
logging.error('get_bfm_process_order_list error: %s' % traceback_error)
res['status'] = -1
res['message'] = '工厂创建销售订单和产品失败,请联系管理员'
request.cr.rollback()
return json.JSONEncoder().encode(res)

View File

@@ -0,0 +1,29 @@
<odoo>
<data noupdate="1">
<record model="ir.cron" id="ir_cron_update_construction_period_status">
<field name="name">工期状态变更</field>
<field name="model_id" ref="model_mrp_workorder"/>
<field name="state">code</field>
<field name="code">model._corn_update_construction_period_status()</field>
<field name="interval_number">12</field>
<field name="interval_type">hours</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_update_delivery_status">
<field name="name">交期状态变更</field>
<field name="model_id" ref="model_mrp_production"/>
<field name="state">code</field>
<field name="code">model._corn_update_delivery_status()</field>
<field name="interval_number">12</field>
<field name="interval_type">hours</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

@@ -0,0 +1,12 @@
# migrations/1.1.0/post-migrate.py
from odoo import api, SUPERUSER_ID
def migrate(cr, version):
# 获取环境
env = api.Environment(cr, SUPERUSER_ID, {})
# 示例:添加新字段
env.ref('sf_dlm.product_embryo_sf_self_machining').product_tmpl_id.write({'categ_type': '坯料'})
env.ref('sf_dlm.product_template_sf').product_tmpl_id.write({'categ_type': '成品'})
env.ref('sf_dlm.product_embryo_sf_outsource').product_tmpl_id.write({'categ_type': '坯料'})
env.ref('sf_dlm.product_embryo_sf_purchase').product_tmpl_id.write({'categ_type': '坯料'})

View File

@@ -11,3 +11,7 @@ from . import production_line_base
from . import agv_setting
from . import agv_scheduling
from . import res_config_setting
from . import sf_technology_design
from . import sf_production_common
from . import sale_order
from . import quick_easy_order

View File

@@ -6,42 +6,29 @@ class ModelType(models.Model):
_description = '模型类型'
name = fields.Char('名称')
embryo_tolerance = fields.Integer('坯料容余')
# embryo_tolerance = fields.Char('坯料容余')
embryo_tolerance_id = fields.Many2one('sf.embryo.redundancy', string='坯料冗余')
product_routing_tmpl_ids = fields.One2many('sf.product.model.type.routing.sort', 'product_model_type_id',
'成品工序模板')
'成品工序模板(自动化产线加工')
embryo_routing_tmpl_ids = fields.One2many('sf.embryo.model.type.routing.sort', 'embryo_model_type_id',
'坯料工序模板')
'坯料工序模板(人工线下加工)')
surface_technics_routing_tmpl_ids = fields.One2many('sf.surface_technics.model.type.routing.sort',
'surface_technics_model_type_id',
'表面工艺工序模板')
manual_product_routing_tmpl_ids = fields.One2many('sf.manual.product.model.type.routing.sort',
'manual_product_model_type_id',
'成品工序模板(人工线下加工)')
class ProductModelTypeRoutingSort(models.Model):
_name = 'sf.product.model.type.routing.sort'
_description = '成品工序排序'
_description = '成品工序排序(自动化产线加工)'
sequence = fields.Integer('Sequence')
route_workcenter_id = fields.Many2one('mrp.routing.workcenter',
domain=[('routing_type', 'in', ['装夹预调', 'CNC加工', '解除装夹'])])
is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat')
# routing_type = fields.Selection([
# ('获取CNC加工程序', '获取CNC加工程序'),
# ('装夹', '装夹'),
# ('前置三元定位检测', '前置三元定位检测'),
# ('CNC加工', 'CNC加工'),
# ('后置三元质量检测', '后置三元质量检测'),
# ('解除装夹', '解除装夹'), ('切割', '切割'), ('表面工艺', '表面工艺')
# ], string="工序类型", compute='_compute_route_workcenter_id')
#
# @api.depends('route_workcenter_id')
# def _compute_route_workcenter_id(self):
# for record in self:
# if record:
# record.routing_type = record.route_workcenter_id.routing_type
routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type')
workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids')
product_model_type_id = fields.Many2one('sf.model.type')
@@ -57,24 +44,7 @@ class EmbryoModelTypeRoutingSort(models.Model):
sequence = fields.Integer('Sequence')
route_workcenter_id = fields.Many2one('mrp.routing.workcenter', domain=[('routing_type', 'in', ['切割'])])
is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat')
# routing_type = fields.Selection([
# ('获取CNC加工程序', '获取CNC加工程序'),
# ('装夹', '装夹'),
# ('前置三元定位检测', '前置三元定位检测'),
# ('CNC加工', 'CNC加工'),
# ('后置三元质量检测', '后置三元质量检测'),
# ('解除装夹', '解除装夹'), ('切割', '切割'), ('表面工艺', '表面工艺')
# ], string="工序类型", compute='_compute_route_workcenter_id')
#
# @api.depends('route_workcenter_id')
# def _compute_route_workcenter_id(self):
# for record in self:
# if record:
# record.routing_type = record.route_workcenter_id.routing_type
routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type')
workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids')
embryo_model_type_id = fields.Many2one('sf.model.type')
@@ -90,24 +60,7 @@ class SurfaceTechnicsModelTypeRoutingSort(models.Model):
sequence = fields.Integer('Sequence')
route_workcenter_id = fields.Many2one('mrp.routing.workcenter', domain=[('routing_type', 'in', ['表面工艺'])])
is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat')
# routing_type = fields.Selection([
# ('获取CNC加工程序', '获取CNC加工程序'),
# ('装夹', '装夹'),
# ('前置三元定位检测', '前置三元定位检测'),
# ('CNC加工', 'CNC加工'),
# ('后置三元质量检测', '后置三元质量检测'),
# ('解除装夹', '解除装夹'), ('切割', '切割'), ('表面工艺', '表面工艺')
# ], string="工序类型", compute='_compute_route_workcenter_id')
#
# @api.depends('route_workcenter_id')
# def _compute_route_workcenter_id(self):
# for record in self:
# if record:
# record.routing_type = record.route_workcenter_id.routing_type
routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type')
workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids')
surface_technics_model_type_id = fields.Many2one('sf.model.type')
@@ -116,3 +69,18 @@ class SurfaceTechnicsModelTypeRoutingSort(models.Model):
'route_model_type_uniq', 'unique (route_workcenter_id,surface_technics_model_type_id)',
'表面工艺工序不能重复!')
]
class ManualProductModelTypeRoutingSort(models.Model):
_name = 'sf.manual.product.model.type.routing.sort'
_description = '成品工序排序(人工线下加工)'
sequence = fields.Integer('Sequence')
route_workcenter_id = fields.Many2one('mrp.routing.workcenter')
is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat')
routing_type = fields.Selection(string="工序类型", related='route_workcenter_id.routing_type')
workcenter_ids = fields.Many2many('mrp.workcenter', required=False, related='route_workcenter_id.workcenter_ids')
manual_product_model_type_id = fields.Many2one('sf.model.type')
_sql_constraints = [
('route_model_type_uniq', 'unique (route_workcenter_id,manual_product_model_type_id)', '成品工序不能重复!')
]

View File

@@ -37,12 +37,114 @@ 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
def _compute_default_delivery_status(self):
try:
if self.state == 'cancel':
return False
if not self.deadline_of_delivery:
return False
hours = self.get_hours_diff()
if hours >= 48:
return '正常'
elif hours > 0 and hours < 48 and self.state != 'done':
return '预警'
elif hours > 0 and hours < 48 and self.state == 'done':
return '正常'
else:
return '已逾期'
except Exception as e:
logging.error("Error processing production ID {}: {}".format(self.id, e))
raise e
@api.depends('state', 'deadline_of_delivery')
def _compute_delivery_status(self):
for production in self:
delivery_status = production._compute_default_delivery_status()
if delivery_status and production.delivery_status != delivery_status:
production.delivery_status = delivery_status
delivery_status = fields.Selection([('正常', '正常'), ('预警', '预警'), ('已逾期', '已逾期')], string='交期状态',
store=True,
compute='_compute_delivery_status',
default=lambda self: self._compute_default_delivery_status())
def get_page_all_records(self, model_name, func, domain, page_size=100):
# 获取模型对象
model = self.env[model_name].sudo()
# 初始化分页参数
page_number = 1
while True:
# 计算偏移量
offset = (page_number - 1) * page_size
# 获取当前页的数据
records = model.search(domain, limit=page_size, offset=offset)
# 如果没有更多记录,退出循环
if not records:
break
# 将当前页的数据添加到结果列表
func(records)
# 增加页码
page_number += 1
def run_compute_delivery_status(self, records):
records._compute_delivery_status()
def _corn_update_delivery_status(self):
need_list = [
'draft',
'technology_to_confirmed',
'confirmed',
'pending_cam',
'progress',
'rework',
'scrap',
'to_close',
]
# previous_workorder = self.env['mrp.production'].search([('state', 'in', need_list)])
self.get_page_all_records('mrp.production', self.run_compute_delivery_status,
[('state', 'in', need_list)], 100)
def get_hours_diff(self):
# 获取当前日期和时间
current_datetime = fields.Datetime.now()
# 将 date_field 转换为 datetime 对象
if self.deadline_of_delivery:
date_obj = fields.Date.from_string(self.deadline_of_delivery)
# 将 date 对象转换为 datetime 对象,设置时间为 00:00:00
date_obj = datetime.datetime.combine(date_obj, datetime.time.min)
# 计算两个日期之间的差值
delta = date_obj - current_datetime
# 返回差值的小时数
return int(delta.total_seconds() / 3600)
else:
return 0.0
@api.depends('workorder_ids.tool_state_remark')
def _compute_tool_state_remark(self):
@@ -85,6 +187,7 @@ class MrpProduction(models.Model):
# ])
state = fields.Selection([
('draft', '草稿'),
('technology_to_confirmed', '待工艺确认'),
('confirmed', '待排程'),
('pending_cam', '待加工'),
('progress', '加工中'),
@@ -128,12 +231,14 @@ 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)
part_name = fields.Char(string='零件名称', related='product_id.part_name', readonly=True)
@api.depends('product_id.manual_quotation')
def _compute_manual_quotation(self):
@@ -145,6 +250,8 @@ class MrpProduction(models.Model):
is_remanufacture = fields.Boolean('是否重新制造', default=False)
remanufacture_count = fields.Integer("重新制造订单数量", compute='_compute_remanufacture_production_ids')
remanufacture_production_id = fields.Many2one('mrp.production', string='')
technology_design_ids = fields.One2many('sf.technology.design', 'production_id', string='工艺设计')
is_adjust = fields.Boolean('是否退回调整', default=False)
@api.depends('remanufacture_production_id')
def _compute_remanufacture_production_ids(self):
@@ -171,7 +278,7 @@ class MrpProduction(models.Model):
@api.depends(
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state', 'tool_state',
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state')
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state', 'programming_state', 'is_adjust')
def _compute_state(self):
for production in self:
if not production.state or not production.product_uom_id:
@@ -201,22 +308,33 @@ class MrpProduction(models.Model):
precision_rounding=move.product_uom.rounding or move.product_id.uom_id.rounding)
for move in production.move_raw_ids if move.product_id):
production.state = 'progress'
# # 新添加的状态逻辑
if (
production.state == 'to_close' or production.state == 'progress') and production.schedule_state == '未排':
production.state = 'confirmed'
# 新添加的状态逻辑
if production.state in ['to_close', 'progress',
'technology_to_confirmed'] and production.schedule_state == '未排':
if not production.workorder_ids or production.is_adjust is True:
production.state = 'technology_to_confirmed'
else:
if production.is_adjust is True:
production.state = 'technology_to_confirmed'
else:
production.state = 'confirmed'
elif production.state == 'pending_cam' and production.schedule_state == '未排':
production.state = 'confirmed'
elif production.state == 'to_close' and production.schedule_state == '已排':
production.state = 'pending_cam'
elif production.state == 'confirmed' and production.is_adjust is True:
production.state = 'technology_to_confirmed'
if production.state == 'confirmed' and production.schedule_state == '已排':
production.state = 'pending_cam'
if production.state == 'progress':
if all(wo_state not in ('progress', 'done', 'rework', 'scrap') for wo_state in
production.workorder_ids.mapped('state')):
production.state = 'pending_cam'
if production.is_rework is True:
production.state = 'rework'
if (production.state == 'rework' and production.tool_state == '0'
and production.schedule_state == '已排' and production.is_rework is False):
production.state = 'pending_cam'
# if production.state == 'pending_cam':
# if all(wo_state in 'done' for wo_state in production.workorder_ids.mapped('state')):
# production.state = 'done'
@@ -239,6 +357,104 @@ class MrpProduction(models.Model):
if production.tool_state == '2':
production.state = 'rework'
# 退回调整
def technology_back_adjust(self):
process_parameters = []
domain = [('state', '=', 'confirmed'), ('origin', '=', self.origin)]
if self.production_type == '自动化产线加工':
cloud_programming = self._cron_get_programming_state()
if cloud_programming['send_state'] == 'sending':
raise UserError(_("编程文件正在下发中,请稍后重试"))
domain += [('programming_no', '=', self.programming_no)]
# 带排程的制造订单
production_confirmed = self.env['mrp.production'].search(domain)
for special in production_confirmed.technology_design_ids:
if special.process_parameters_id:
product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', special.process_parameters_id.id)])
if not product_production_process:
if special.process_parameters_id not in process_parameters:
process_parameters.append(special.process_parameters_id.display_name)
if process_parameters:
raise UserError(_("【工艺设计】-【参数】为%s的在【产品】中不存在,请先创建", ", ".join(process_parameters)))
if production_confirmed:
return {
'name': _('退回调整'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'sf.production.technology.re_adjust.wizard',
'target': 'new',
'context': {
'default_production_id': self.id,
'default_origin': self.origin,
}}
# 工艺确认
def technology_confirm(self):
process_parameters = []
account_moves = []
parameters_not = []
special_design = self.technology_design_ids.filtered(
lambda a: a.routing_tag == 'special' and a.is_auto is False)
for special in special_design:
if special.route_id.routing_type == '表面工艺' and not special.process_parameters_id:
parameters_not.append(special.route_id.name)
if special.process_parameters_id:
product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', special.process_parameters_id.id)])
if not product_production_process:
if special.process_parameters_id not in process_parameters:
process_parameters.append(special.process_parameters_id.display_name)
purchase = self.env['purchase.order'].search([('origin', '=', special.production_id.name)])
account = self.env['account.move'].search([('id', 'in', purchase.invoice_ids)])
if account.state not in ['cancel', False]:
if purchase.name not in account_moves:
account_moves.append(purchase.name)
if account_moves:
raise UserError(_("请联系工厂生产经理对采购订单为%s生成的账单进行取消", ", ".join(account_moves)))
if parameters_not:
raise UserError(_("【工艺设计】-【工序】为%s未选择参数,请选择", ", ".join(parameters_not)))
if process_parameters:
raise UserError(_("【工艺设计】-【参数】为%s的在【产品】中不存在,请先创建", ", ".join(process_parameters)))
# 判断同一个加工面的标准工序的顺序是否依次排序
error_panel = []
technology_design = self.technology_design_ids.filtered(lambda a: a.routing_tag == 'standard').sorted(
key=lambda m: m.sequence)
for index, design in enumerate(technology_design):
routing_type = design.route_id.routing_type
if index < len(technology_design) - 1:
next_index = index + 1
next_design = technology_design[next_index]
next_design_routing_type = next_design.route_id.routing_type
# logging.info('当前工序和加工面: %s-%s' % (design.route_id.name, design.panel))
# logging.info('下一个工序和加工面: %s-%s' % (next_design.route_id.name, next_design.panel))
if design.panel is not False:
if design.panel != next_design.panel:
if index == 0:
raise UserError('【加工面】为%s的标准工序里含有其他加工面的工序,请调整后重试' % design.panel)
if routing_type not in ['解除装夹']:
raise UserError('【加工面】为%s的标准工序顺序有误,请调整后重试' % design.panel)
if design.panel == next_design.panel:
if (routing_type == '装夹预调' and next_design_routing_type == '解除装夹') or (
routing_type == 'CNC加工' and next_design_routing_type == '装夹预调'):
if design.panel not in error_panel:
error_panel.append(design.panel)
else:
if not error_panel and not process_parameters:
return {
'name': _('工艺确认'),
'type': 'ir.actions.act_window',
'view_mode': 'form',
'res_model': 'sf.production.technology.wizard',
'target': 'new',
'context': {
'default_production_id': self.id,
'default_origin': self.origin,
}}
if error_panel:
raise UserError(_("【加工面】为%s的标准工序顺序有误,请调整后重试", ", ".join(error_panel)))
return True
def action_check(self):
"""
审核启用
@@ -439,8 +655,8 @@ class MrpProduction(models.Model):
if self.move_finished_ids.filtered(lambda m: m.product_id == self.product_id).move_line_ids:
self.move_finished_ids.filtered(
lambda m: m.product_id == self.product_id).move_line_ids.lot_id = self.lot_producing_id
if self.product_id.tracking == 'serial':
self._set_qty_producing()
# if self.product_id.tracking == 'serial':
# self._set_qty_producing()
# 重载根据工序生成工单的程序如果产品BOM中没有工序时
# 根据产品对应的模板类型中工序,去生成工单;
@@ -476,122 +692,88 @@ class MrpProduction(models.Model):
'operation_id': operation.id,
'state': 'pending',
}]
if production.product_id.categ_id.type == '成品':
# # 根据加工面板的面数及对应的工序模板生成工单
i = 0
processing_panel_len = len(production.product_id.model_processing_panel.split(','))
for k in (production.product_id.model_processing_panel.split(',')):
product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search(
[('product_model_type_id', '=', production.product_id.product_model_type_id.id)],
order='sequence asc'
)
i += 1
for route in product_routing_workcenter:
if route.is_repeat is True:
if production.product_id.categ_id.type in ['成品', '坯料']:
# # 根据工序设计生成工单
for route in production.technology_design_ids:
workorder_has = self.env['mrp.workorder'].search(
[('technology_design_id', '=', route.id), ('production_id', '=', production.id)])
if not workorder_has:
if route.route_id.routing_type not in ['表面工艺']:
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(k, production, route, item))
# if i == processing_panel_len and route.routing_type == '解除装夹':
# workorders_values.append(
# self.env['mrp.workorder'].json_workorder_str(k, production, route))
# 表面工艺工序
# 获取表面工艺id
# 工序id
surface_technics_arr = []
route_workcenter_arr = []
for item in production.product_id.product_model_type_id.surface_technics_routing_tmpl_ids:
if item.route_workcenter_id.surface_technics_id.id:
for process_param in production.product_id.model_process_parameters_ids:
logging.info('process_param:%s%s' % (process_param.id, process_param.name))
if item.route_workcenter_id.surface_technics_id == process_param.process_id:
logging.info(
'surface_technics_id:%s%s' % (item.route_workcenter_id.surface_technics_id.id,
item.route_workcenter_id.surface_technics_id.name))
surface_technics_arr.append(item.route_workcenter_id.surface_technics_id.id)
route_workcenter_arr.append(item.route_workcenter_id.id)
if surface_technics_arr:
production_process = self.env['sf.production.process'].search(
[('id', 'in', surface_technics_arr)],
order='sequence asc'
)
for p in production_process:
logging.info('production_process:%s' % p.name)
# if production_process:
process_parameter = production.product_id.model_process_parameters_ids.filtered(
lambda pm: pm.process_id.id == p.id)
if process_parameter:
# 产品为表面工艺服务的供应商
self.env['mrp.workorder'].json_workorder_str(production, route))
else:
product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', process_parameter.id)])
if product_production_process:
route_production_process = self.env[
'mrp.routing.workcenter'].search(
[('surface_technics_id', '=', p.id),
('id', 'in', route_workcenter_arr)])
if route_production_process:
workorders_values.append(
self.env[
'mrp.workorder']._json_workorder_surface_process_str(
production, route_production_process,
process_parameter,
product_production_process.seller_ids[0].partner_id.id))
elif production.product_id.categ_id.type == '坯料':
embryo_routing_workcenter = self.env['sf.embryo.model.type.routing.sort'].search(
[('embryo_model_type_id', '=', production.product_id.embryo_model_type_id.id)],
order='sequence asc'
)
for route in embryo_routing_workcenter:
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str('', production, route))
[('server_product_process_parameters_id', '=', route.process_parameters_id.id)])
workorders_values.append(
self.env[
'mrp.workorder']._json_workorder_surface_process_str(
production, route, product_production_process.seller_ids[0].partner_id.id))
production.workorder_ids = workorders_values
# for production_item in productions:
process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id),
('is_subcontract', '=', True)])
if process_parameter_workorder:
is_pick = False
consecutive_workorders = []
m = 0
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id)
for i in range(len(sorted_workorders) - 1):
if m == 0:
is_pick = False
if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \
sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \
sorted_workorders[i].id == sorted_workorders[i + 1].id - 1:
if sorted_workorders[i] not in consecutive_workorders:
consecutive_workorders.append(sorted_workorders[i])
consecutive_workorders.append(sorted_workorders[i + 1])
m += 1
continue
else:
if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
production)
if sorted_workorders[i] in consecutive_workorders:
is_pick = True
consecutive_workorders = []
m = 0
# 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单
if is_pick is False:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i],
production)
if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders,
production)
if sorted_workorders[i] in consecutive_workorders:
is_pick = True
consecutive_workorders = []
m = 0
if m == len(consecutive_workorders) - 1 and m != 0:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
if is_pick is False and m == 0:
if len(sorted_workorders) == 1:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production)
else:
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production)
for workorder in production.workorder_ids:
workorder.duration_expected = workorder._get_duration_expected()
# 外协出入库单处理
def get_subcontract_pick_purchase(self):
production_all = self.sorted(lambda x: x.id)
product_id_to_production_names = {}
grouped_product_ids = {k: list(g) for k, g in
groupby(production_all, key=lambda x: x.product_id.id)}
for product_id, pd in grouped_product_ids.items():
product_id_to_production_names[product_id] = [p.name for p in pd]
for production in production_all:
proc_workorders = []
process_parameter_workorder = self.env['mrp.workorder'].search(
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id),
('is_subcontract', '=', True), ('state', '!=', 'cancel')], order='sequence asc')
if process_parameter_workorder:
# 将这些特殊表面工艺工单的采购单与调拨单置为失效
for workorder in process_parameter_workorder:
workorder._get_surface_technics_purchase_ids().write({'state': 'cancel'})
workorder.move_subcontract_workorder_ids.write({'state': 'cancel'})
workorder.move_subcontract_workorder_ids.picking_id.write({'state': 'cancel'})
consecutive_workorders = []
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.sequence)
for i, workorder in enumerate(sorted_workorders):
# 检查当前工作订单和下一个工作订单是否连续,并且供应商相同
if i == 0:
consecutive_workorders.append(workorder)
elif workorder.sequence == sorted_workorders[
i - 1].sequence + 1 and workorder.supplier_id.id == sorted_workorders[i - 1].supplier_id.id:
consecutive_workorders.append(workorder)
else:
# 处理连续组,如果它不为空
if consecutive_workorders:
proc_workorders.append(consecutive_workorders)
# 创建外协出入库单和采购订单
# self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production, sorted_workorders)
# self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
# product_id_to_production_names)
if i < len(sorted_workorders) - 1:
# 重置连续组,并添加当前工作订单
consecutive_workorders = [workorder]
else:
# 判断最后一笔:
if workorder.sequence == sorted_workorders[
i - 1].sequence and workorder.supplier_id.id == sorted_workorders[
i - 1].supplier_id.id:
consecutive_workorders = [workorder]
else:
proc_workorders.append([workorder])
# 立即创建外协出入库单和采购订单
# self.env['stock.picking'].create_outcontract_picking(workorder, production)
# self.env['purchase.order'].get_purchase_order(workorder, production,
# product_id_to_production_names)
consecutive_workorders = []
# 处理最后一个组,即使它可能只有一个工作订单
if consecutive_workorders:
proc_workorders.append(consecutive_workorders)
# self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
# self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
# product_id_to_production_names)
for workorders in reversed(proc_workorders):
self.env['stock.picking'].create_outcontract_picking(workorders, production, sorted_workorders)
self.env['purchase.order'].get_purchase_order(workorders, production, product_id_to_production_names)
# 工单排序
def _reset_work_order_sequence1(self, k):
for rec in self:
@@ -658,7 +840,84 @@ class MrpProduction(models.Model):
self._reset_work_order_sequence1(k)
return True
# 需对不连续工单对应的采购单和外协出入库单做处理
def _reset_subcontract_pick_purchase(self):
production_all = self.sorted(lambda x: x.id)
product_id_to_production_names = {}
grouped_product_ids = {k: list(g) for k, g in
groupby(production_all, key=lambda x: x.product_id.id)}
for product_id, pd in grouped_product_ids.items():
product_id_to_production_names[product_id] = [p.name for p in pd]
for item in production_all:
production_process = product_id_to_production_names.get(item.product_id.id)
workorder_sf = item.workorder_ids.filtered(lambda sf: sf.routing_type == '表面工艺')
for i, workorder in enumerate(workorder_sf):
if i == 0:
continue
elif workorder.sequence != workorder_sf[i - 1].sequence + 1:
# workorder.picking_ids.move_ids = False
workorder.picking_ids = False
purchase_order = self.env['purchase.order'].search(
[('state', '=', 'draft'), ('origin', '=', item.name),
('purchase_type', '=', 'consignment')])
server_template = self.env['product.template'].search(
[('server_product_process_parameters_id', '=',
workorder.surface_technics_parameters_id.id),
('detailed_type', '=', 'service')])
for po in purchase_order:
for line in po.order_line:
if line.product_id == server_template.product_variant_id:
continue
if server_template.server_product_process_parameters_id != line.product_id.server_product_process_parameters_id:
purchase_order_line = self.env['purchase.order.line'].search(
[('product_id', '=', server_template.product_variant_id.id), ('id', '=', line.id),
('product_qty', '=', 1)], limit=1, order='id desc')
if purchase_order_line:
line.unlink()
def _reset_work_order_sequence(self):
"""
工单工序排序方法(新)
"""
for rec in self:
workorder_ids = rec.workorder_ids
technology_design_ids = rec.technology_design_ids
if workorder_ids.filtered(lambda item: item.state in ('返工', 'rework')):
# 获取返工后新生成的工单
work_ids = workorder_ids.filtered(lambda item: item.sequence == 0)
# 对工单进行逐个插入
for work_id in work_ids:
for order_id in rec.workorder_ids.filtered(lambda item: item.sequence > 0):
if work_id.name == order_id.name:
work_id.sequence = order_id.sequence + 1
break
# 对该工单之后的工单工序进行加一
work_order_ids = rec.workorder_ids.filtered(
lambda item: item.sequence >= work_id.sequence and item.id != work_id.id)
for work in work_order_ids:
work.sequence = work.sequence + 1
else:
# 将工艺设计生成的工单序号赋值给工单的序号
for work in workorder_ids:
td_ids = technology_design_ids.filtered(
lambda item: (item.route_id.name in work.name and item.process_parameters_id
and item.process_parameters_id == work.surface_technics_parameters_id) or
(item.route_id.name == work.name and item.panel
and item.panel == work.processing_panel))
if td_ids:
work.sequence = td_ids[0].sequence
cancel_work_ids = workorder_ids.filtered(lambda item: item.state in ('已取消', 'cancel'))
if cancel_work_ids:
sequence = max(workorder_ids.filtered(lambda item: item.state not in ('已取消', 'cancel')),
key=lambda w: w.sequence).sequence
for cw in cancel_work_ids:
cw.sequence = sequence + 1
def _reset_work_order_sequence_1(self):
"""
工单工序排序方法(旧)
"""
for rec in self:
workorder_ids = rec.workorder_ids.filtered(lambda item: item.state in ('返工', 'rework'))
# 产品模型类型
@@ -754,52 +1013,32 @@ class MrpProduction(models.Model):
self._reset_work_order_sequence()
return True
def production_process(self, pro_plan):
type_map = {'装夹预调': False, 'CNC加工': False, '解除装夹': False}
# 最后一次加工结束时间
last_time = pro_plan.date_planned_start
# 预置时间
works = self.workorder_ids
for index, work in enumerate(works):
count = type_map.get(work.routing_type)
date_planned_end = None
date_planned_start = None
if self.production_type == '自动化产线加工':
date_planned_start, date_planned_end, last_time = work.auto_production_process(last_time, count,
type_map)
elif self.production_type == '':
date_planned_start, date_planned_end, last_time = work.manual_offline_process(last_time, index)
work.update_work_start_end(date_planned_start, date_planned_end)
# def
def process_range_time(self):
for production in self:
works = production.workorder_ids
pro_plan = self.env['sf.production.plan'].search([('production_id', '=', production.id)], limit=1)
if not pro_plan:
continue
type_map = {'装夹预调': False, 'CNC加工': False, '解除装夹': False}
# 最后一次加工结束时间
last_time = pro_plan.date_planned_start
# 预置时间
for work in works:
count = type_map.get(work.routing_type)
date_planned_end = None
date_planned_start = None
duration_expected = datetime.timedelta(minutes=work.duration_expected)
reserve_time = datetime.timedelta(minutes=work.reserved_duration)
if not count:
# 第一轮加工
if work.routing_type == '装夹预调':
date_planned_end = last_time - reserve_time
date_planned_start = date_planned_end - duration_expected
elif work.routing_type == 'CNC加工':
date_planned_start = last_time
date_planned_end = last_time + duration_expected
last_time = date_planned_end
else:
date_planned_start = last_time + reserve_time
date_planned_end = date_planned_start + duration_expected
last_time = date_planned_end
type_map.update({work.routing_type: True})
else:
date_planned_start = last_time + reserve_time
date_planned_end = date_planned_start + duration_expected
last_time = date_planned_end
work.leave_id.write({
'date_from': date_planned_start,
'date_to': date_planned_end,
})
# work.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end})
work.date_planned_start = date_planned_start
work.date_planned_finished = date_planned_end
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', work.routing_type)])
work.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end,
'duration_expected': routing_workcenter.time_cycle})
if production.production_type:
production.production_process(pro_plan)
# 修改标记已完成方法
def button_mark_done1(self):
@@ -823,6 +1062,7 @@ class MrpProduction(models.Model):
backorders = backorders - productions_to_backorder
productions_not_to_backorder._post_inventory(cancel_backorder=True)
# 查出最后一张工单完成入库操作
# if self.workorder_ids.filtered(lambda w: w.routing_type in ['表面工艺']):
# move_finish = self.env['stock.move'].search([('created_production_id', '=', self.id)])
# if move_finish:
@@ -923,6 +1163,14 @@ class MrpProduction(models.Model):
cloud_programming = None
if self.programming_state in ['已编程']:
cloud_programming = self._cron_get_programming_state()
result_ids = self.detection_result_ids.filtered(lambda dr: dr.handle_result == '待处理')
work_id_list = []
if result_ids:
work_id_list = [self.workorder_ids.filtered(
lambda wk: (wk.name == result_id.routing_type and wk.processing_panel == result_id.processing_panel
and wk.state == 'done')).id
for result_id in result_ids]
return {
'name': _('返工'),
'type': 'ir.actions.act_window',
@@ -931,6 +1179,8 @@ class MrpProduction(models.Model):
'target': 'new',
'context': {
'default_production_id': self.id,
'default_workorder_ids': self.workorder_ids.ids,
'default_hidden_workorder_ids': ','.join(map(str, work_id_list)) if work_id_list != [] else '',
'default_reprogramming_num': cloud_programming['reprogramming_num'],
'default_programming_state': cloud_programming['programming_state'],
'default_is_reprogramming': True if cloud_programming['programming_state'] in ['已下发'] else False
@@ -1084,13 +1334,15 @@ class MrpProduction(models.Model):
raise_user_error=not self.env.context.get('from_orderpoint'))
productions = self.env['mrp.production'].sudo().search(
[('origin', '=', self.origin)], order='id desc', limit=1)
productions.write({'programming_no': self.programming_no, 'is_remanufacture': True})
move = self.env['stock.move'].search([('origin', '=', productions.name)], order='id desc')
for mo in move:
if mo.procure_method == 'make_to_order' and mo.name != productions.name:
if mo.name == '/':
domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')]
elif mo.name == '':
domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')]
domain = []
if mo.location_id.barcode == 'WH-POSTPRODUCTION' and mo.rule_id.picking_type_id.barcode == 'PC':
domain = [('barcode', '=', 'WH-PC'), ('sequence_code', '=', 'PC')]
elif mo.location_id.barcode == 'PL' and mo.rule_id.picking_type_id.barcode == 'INT':
domain = [('barcode', '=', 'WH-INTERNAL'), ('sequence_code', '=', 'INT')]
if domain:
picking_type = self.env['stock.picking.type'].search(domain)
mo.write({'picking_type_id': picking_type.id})
mo._assign_picking()
@@ -1108,7 +1360,6 @@ class MrpProduction(models.Model):
mo_move.write({'reference': sfp_move.reference, 'partner_id': sfp_move.partner_id.id,
'picking_id': sfp_move.picking_id.id, 'picking_type_id': sfp_move.picking_type_id.id,
'production_id': False})
productions.write({'programming_no': self.programming_no, 'is_remanufacture': True})
# productions.procurement_group_id.mrp_production_ids.move_dest_ids.write(
# {'group_id': self.env['procurement.group'].search([('name', '=', sale_order.name)])})
stock_picking_remanufacture = self.env['stock.picking'].search([('origin', '=', productions.name)])
@@ -1142,7 +1393,6 @@ class MrpProduction(models.Model):
if purchase_orders.origin.find(productions.name) == -1:
purchase_orders.origin += ',' + productions.name
if item['is_reprogramming'] is False:
productions._create_workorder(item)
productions.programming_state = '已编程'
else:
productions.programming_state = '编程中'
@@ -1172,6 +1422,103 @@ class MrpProduction(models.Model):
'user_id': production.user_id.id}
return production_values_str
# 增加制造订单类型
production_type = fields.Selection(
[('自动化产线加工', '自动化产线加工'), ('人工线下加工', '人工线下加工')],
string='制造类型',
compute='_compute_production_type',
store=True
)
@api.depends('product_id.is_manual_processing')
def _compute_production_type(self):
for production in self:
production.production_type = '自动化产线加工' if not production.product_id.is_manual_processing else '人工线下加工'
@api.model_create_multi
def create(self, vals_list):
"""
重载创建制造订单的方法,单个制造订单,同一成品只创建一个采购组,用于后续单据的创建
"""
product_group_id = {}
for vals in vals_list:
if not vals.get('name', False) or vals['name'] == _('New'):
picking_type_id = vals.get('picking_type_id')
if not picking_type_id:
picking_type_id = self._get_default_picking_type_id(vals.get('company_id', self.env.company.id))
vals['picking_type_id'] = picking_type_id
vals['name'] = self.env['stock.picking.type'].browse(picking_type_id).sequence_id.next_by_id()
if not vals.get('procurement_group_id'):
product_id = self.env['product.product'].browse(vals['product_id'])
if product_id.product_tmpl_id.single_manufacturing:
if product_id.id not in product_group_id.keys():
procurement_group_vals = self._prepare_procurement_group_vals(vals)
group_id = self.env["procurement.group"].create(procurement_group_vals).id
vals['procurement_group_id'] = group_id
product_group_id[product_id.id] = group_id
else:
vals['procurement_group_id'] = product_group_id[product_id.id]
return super(MrpProduction, self).create(vals_list)
@api.depends('procurement_group_id.stock_move_ids.created_purchase_line_id.order_id',
'procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id')
def _compute_purchase_order_count(self):
for production in self:
# 找到来源的第一张制造订单的采购组
if production.product_id.product_tmpl_id.single_manufacturing == True:
first_production = self.env['mrp.production'].search(
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)], limit=1,
order='id asc')
production.purchase_order_count = len(
first_production.procurement_group_id.stock_move_ids.created_purchase_line_id.order_id |
first_production.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id)
else:
production.purchase_order_count = len(
production.procurement_group_id.stock_move_ids.created_purchase_line_id.order_id |
production.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id)
@api.depends('procurement_group_id', 'procurement_group_id.stock_move_ids.group_id')
def _compute_picking_ids(self):
for order in self:
if order.product_id.product_tmpl_id.single_manufacturing == True:
first_order = self.env['mrp.production'].search(
[('origin', '=', order.origin), ('product_id', '=', order.product_id.id)], limit=1, order='id asc')
order.picking_ids = self.env['stock.picking'].search([
('group_id', '=', first_order.procurement_group_id.id), ('group_id', '!=', False),
])
order.delivery_count = len(first_order.picking_ids)
else:
order.picking_ids = self.env['stock.picking'].search([
('group_id', '=', order.procurement_group_id.id), ('group_id', '!=', False),
])
order.delivery_count = len(order.picking_ids)
def action_view_purchase_orders(self):
self.ensure_one()
if self.product_id.product_tmpl_id.single_manufacturing == True:
production = self.env['mrp.production'].search(
[('origin', '=', self.origin), ('product_id', '=', self.product_id.id)], limit=1, order='id asc')
else:
production = self
purchase_order_ids = (
production.procurement_group_id.stock_move_ids.created_purchase_line_id.order_id | production.procurement_group_id.stock_move_ids.move_orig_ids.purchase_line_id.order_id).ids
action = {
'res_model': 'purchase.order',
'type': 'ir.actions.act_window',
}
if len(purchase_order_ids) == 1:
action.update({
'view_mode': 'form',
'res_id': purchase_order_ids[0],
})
else:
action.update({
'name': _("Purchase Order generated from %s", self.name),
'domain': [('id', 'in', purchase_order_ids)],
'view_mode': 'tree,form',
})
return action
class sf_detection_result(models.Model):
_name = 'sf.detection.result'
@@ -1201,10 +1548,6 @@ class sf_detection_result(models.Model):
'type': 'ir.actions.act_window',
'res_id': self.id,
'views': [(self.env.ref('sf_manufacturing.sf_test_report_form').id, 'form')],
# 'view_mode': 'form',
# 'context': {
# 'default_id': self.id
# },
'target': 'new'
}

View File

@@ -7,21 +7,25 @@ class ResMrpRoutingWorkcenter(models.Model):
_inherit = 'mrp.routing.workcenter'
routing_type = fields.Selection([
# ('获取CNC加工程序', '获取CNC加工程序'),
('装夹预调', '装夹预调'),
# ('前置三元定位检测', '前置三元定位检测'),
('CNC加工', 'CNC加工'),
# ('后置三元质量检测', '后置三元质量检测'),
('解除装夹', '解除装夹'),
('切割', '切割'),
('表面工艺', '表面工艺')
('表面工艺', '表面工艺'),
('线切割', '线切割'),
('人工线下加工', '人工线下加工')
], string="工序类型")
routing_tag = fields.Selection([
('standard', '标准'),
('special', '特殊')
], string="标签")
is_repeat = fields.Boolean('重复', default=False)
workcenter_id = fields.Many2one('mrp.workcenter', required=False)
workcenter_ids = fields.Many2many('mrp.workcenter', 'rel_workcenter_route', required=True)
bom_id = fields.Many2one('mrp.bom', required=False)
surface_technics_id = fields.Many2one('sf.production.process', string="表面工艺")
reserved_duration = fields.Float('预留时长', default=30, tracking=True)
def get_no(self):
international_standards = self.search(
[('code', '!=', ''), ('active', 'in', [True, False])],
@@ -78,3 +82,16 @@ class ResMrpRoutingWorkcenter(models.Model):
else:
workcenter_id = workcenter_ids[0]
return workcenter_id
@api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
if self._context.get('production_id'):
route_ids = []
technology_design = self.env['sf.technology.design'].search(
[('production_id', '=', self._context.get('production_id'))])
for t in technology_design.filtered(lambda a: a.routing_tag == 'special'):
if not t.process_parameters_id:
route_ids.append(t.route_id.surface_technics_id.id)
domain = [('id', 'not in', route_ids), ('routing_tag', '=', 'special')]
return self._search(domain, limit=limit, access_rights_uid=name_get_uid)
return super()._name_search(name, args, operator, limit, name_get_uid)

View File

@@ -23,12 +23,15 @@ class ResMrpWorkOrder(models.Model):
product_tmpl_name = fields.Char('坯料产品名称', related='production_bom_id.bom_line_ids.product_id.name')
product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True,
string="坯料度(mm)")
product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True,
string="坯料宽度(mm)")
product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True,
string="坯料高度(mm)")
product_tmpl_id_length = fields.Float(string='坯料长度(mm)', related='material_length', readonly=True, store=False)
product_tmpl_id_width = fields.Float(string='坯料度(mm)', related='material_width', readonly=True, store=False)
product_tmpl_id_height = fields.Float(string='坯料高度(mm)', related='material_height', readonly=True, store=False)
# product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True,
# string="坯料长度(mm)")
# product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True,
# string="坯料宽度(mm)")
# product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True,
# string="坯料高度(mm)")
product_tmpl_id_materials_id = fields.Many2one(related='production_id.product_tmpl_id.materials_id', readonly=True,
store=True, check_company=True, string="材料")
product_tmpl_id_materials_type_id = fields.Many2one(related='production_id.product_tmpl_id.materials_type_id',
@@ -38,13 +41,10 @@ class ResMrpWorkOrder(models.Model):
processing_panel = fields.Char('加工面')
sequence = fields.Integer(string='工序')
routing_type = fields.Selection([
# ('获取CNC加工程序', '获取CNC加工程序'),
('装夹预调', '装夹预调'),
# ('前置三元定位检测', '前置三元定位检测'),
('CNC加工', 'CNC加工'),
# ('后置三元质量检测', '后置三元质量检测'),
('解除装夹', '解除装夹'),
('切割', '切割'), ('表面工艺', '表面工艺')
('切割', '切割'), ('表面工艺', '表面工艺'), ('线切割', '线切割'), ('人工线下加工', '人工线下加工')
], string="工序类型")
results = fields.Char('结果')
state = fields.Selection([
@@ -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):
@@ -128,7 +129,7 @@ class ResMrpWorkOrder(models.Model):
Y10_axis = fields.Float(default=0)
Z10_axis = fields.Float(default=0)
X_deviation_angle = fields.Integer(string="X轴偏差度", default=0)
test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], default='合格',
test_results = fields.Selection([("合格", "合格")], default='合格',
string="检测结果", tracking=True)
cnc_ids = fields.One2many("sf.cnc.processing", 'workorder_id', string="CNC加工程序")
cmm_ids = fields.One2many("sf.cmm.program", 'workorder_id', string="CMM程序")
@@ -136,8 +137,10 @@ class ResMrpWorkOrder(models.Model):
glb_file = fields.Binary("glb模型文件", related='production_id.model_file')
is_subcontract = fields.Boolean(string='是否外协')
surface_technics_parameters_id = fields.Many2one('sf.production.process.parameter', string="表面工艺可选参数")
picking_ids = fields.Many2many('stock.picking', string='外协出入库单')
# purchase_id = fields.Many2one('purchase.order', string='外协采购单')
picking_ids = fields.Many2many('stock.picking', string='外协出入库单', compute='_compute_surface_technics_picking_ids')
purchase_id = fields.Many2many('purchase.order', string='外协采购单')
surface_technics_picking_count = fields.Integer("外协出入库", compute='_compute_surface_technics_picking_ids')
surface_technics_purchase_count = fields.Integer("外协采购", compute='_compute_surface_technics_purchase_ids')
@@ -145,21 +148,107 @@ class ResMrpWorkOrder(models.Model):
is_trayed = fields.Boolean(string='是否绑定托盘', default=False)
tag_type = fields.Selection([("重新加工", "重新加工")], string="标签", tracking=True)
technology_design_id = fields.Many2one('sf.technology.design')
def _compute_default_construction_period_status(self):
need_list = ['pending', 'waiting', 'ready', 'progress', 'to be detected', 'done']
try:
if self.state not in need_list:
return False
if not self.date_planned_finished:
return False
hours = self.get_hours_diff()
if hours >= 12:
return '正常'
elif hours > 0 and hours < 12 and self.state != 'done':
return '预警'
elif hours > 0 and hours < 12 and self.state == 'done':
return '正常'
else:
return '已逾期'
except Exception as e:
logging.error("Error processing production ID {}: {}".format(self.id, e))
raise e
@api.depends('state', 'date_planned_finished')
def _compute_construction_period_status(self):
for worker in self:
construction_period_status = worker._compute_default_construction_period_status()
if construction_period_status and worker.construction_period_status != construction_period_status:
worker.construction_period_status = construction_period_status
construction_period_status = fields.Selection([('正常', '正常'), ('预警', '预警'), ('已逾期', '已逾期')],
string='工期状态',
store=True,
compute='_compute_construction_period_status',
default=lambda
self: self._compute_default_construction_period_status())
def get_page_all_records(self, model_name, func, domain, page_size=100):
# 获取模型对象
model = self.env[model_name].sudo()
# 初始化分页参数
page_number = 1
while True:
# 计算偏移量
offset = (page_number - 1) * page_size
# 获取当前页的数据
records = model.search(domain, limit=page_size, offset=offset)
# 如果没有更多记录,退出循环
if not records:
break
# 将当前页的数据添加到结果列表
func(records)
# 增加页码
page_number += 1
def run_compute_construction_period_status(self, records):
records._compute_construction_period_status()
def _corn_update_construction_period_status(self):
need_list = ['pending', 'waiting', 'ready', 'progress', 'to be detected']
# need_list = [
# 'progress',
# 'to be detected']
self.get_page_all_records('mrp.workorder', self.run_compute_construction_period_status,
[('state', 'in', need_list)], 100)
def get_hours_diff(self):
# 获取当前日期和时间
current_datetime = fields.Datetime.now()
# 将 date_field 转换为 datetime 对象
if self.date_planned_finished:
date_obj = fields.Datetime.from_string(self.date_planned_finished)
# 将 date 对象转换为 datetime 对象,设置时间为 00:00:00
# date_obj = datetime.datetime.combine(date_obj, datetime.time.min)
# 计算两个日期之间的差值
delta = date_obj - current_datetime
# 返回差值的小时数
return int(delta.total_seconds() / 3600)
else:
return 0.0
@api.depends('name', 'production_id.name')
def _compute_surface_technics_picking_ids(self):
for workorder in self:
if workorder.routing_type == '表面工艺':
domain = [('origin', '=', workorder.production_id.name)]
domain = [('origin', '=', workorder.production_id.name), ('state', 'not in', ['cancel']),
('partner_id', '=', workorder.supplier_id.id)]
previous_workorder = self.env['mrp.workorder'].search(
[('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'),
('production_id', '=', workorder.production_id.id)])
if previous_workorder:
process_product = self.env['product.template']._get_process_parameters_product(
previous_workorder.surface_technics_parameters_id)
domain += [('partner_id', '=', process_product.partner_id.id)]
else:
domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)]
# if previous_workorder:
# if previous_workorder.supplier_id != workorder.supplier_id:
# domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)]
# else:
domain += [('surface_technics_parameters_id', '=', workorder.surface_technics_parameters_id.id)]
picking_ids = self.env['stock.picking'].search(domain, order='id asc')
workorder.surface_technics_picking_count = len(picking_ids)
workorder.picking_ids = picking_ids.ids
@@ -183,34 +272,72 @@ class ResMrpWorkOrder(models.Model):
@api.depends('state', 'production_id.name')
def _compute_surface_technics_purchase_ids(self):
for order in self:
if order.routing_type == '表面工艺':
production_programming = self.env['mrp.production'].search(
[('programming_no', '=', order.production_id.programming_no)], order='name asc')
production_no_remanufacture = production_programming.filtered(lambda a: a.is_remanufacture is False)
production_list = [production.name for production in production_programming]
purchase = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
for line in purchase.order_line:
if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id and line.product_qty == len(
production_no_remanufacture):
order.surface_technics_purchase_count = len(purchase)
if order.routing_type == '表面工艺' and order.state not in ['cancel']:
# if order.production_id.production_type == '自动化产线加工':
# domain = [('programming_no', '=', order.production_id.programming_no)]
# else:buzhdiao
# domain = [('origin', '=', order.production_id.origin)]
# production_programming = self.env['mrp.production'].search(domain, order='name asc')
# production_list = [production.name for production in production_programming]
# production_no_remanufacture = production_programming.filtered(lambda a: a.is_remanufacture is False)
# technology_design = self.env['sf.technology.design'].search(
# [('process_parameters_id', '=', order.surface_technics_parameters_id.id),
# ('production_id', '=', order.production_id.id)])
# if technology_design.is_auto is False:
# domain = [('origin', '=', order.production_id.name)]
# else:
domain = [('purchase_type', '=', 'consignment'), ('origin', '=', order.production_id.name),
('state', '!=', 'cancel')]
purchase = self.env['purchase.order'].search(domain)
purchase_num = 0
if not purchase:
order.surface_technics_purchase_count = 0
for po in purchase:
for line in po.order_line:
if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id:
if line.product_qty == 1:
purchase_num += 1
order.surface_technics_purchase_count = purchase_num
else:
order.surface_technics_purchase_count = 0
def action_view_surface_technics_purchase(self):
self.ensure_one()
production_programming = self.env['mrp.production'].search(
[('programming_no', '=', self.production_id.programming_no)], order='name asc')
production_list = [production.name for production in production_programming]
purchase_orders = self.env['purchase.order'].search([('origin', '=', ','.join(production_list))])
# if self.routing_type == '表面工艺':
# if self.production_id.production_type == '自动化产线加工':
# domain = [('programming_no', '=', self.production_id.programming_no)]
# else:
# domain = [('origin', '=', self.production_id.origin)]
# production_programming = self.env['mrp.production'].search(domain, order='name asc')
# production_list = [production.name for production in production_programming]
# production_no_remanufacture = production_programming.filtered(lambda a: a.is_remanufacture is False)
# technology_design = self.env['sf.technology.design'].search(
# [('process_parameters_id', '=', self.surface_technics_parameters_id.id),
# ('production_id', '=', self.production_id.id)])
# if technology_design.is_auto is False:
# domain = [('origin', '=', self.production_id.name)]
# else:
purchase_orders_id = self._get_surface_technics_purchase_ids()
result = {
"type": "ir.actions.act_window",
"res_model": "purchase.order",
"res_id": purchase_orders.id,
"res_id": purchase_orders_id.id,
# "domain": [['id', 'in', self.purchase_id]],
"name": _("Purchase Orders"),
'view_mode': 'form',
}
return result
def _get_surface_technics_purchase_ids(self):
domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment')]
purchase_orders = self.env['purchase.order'].search(domain)
purchase_orders_id = self.env['purchase.order']
for po in purchase_orders:
for line in po.order_line:
if line.product_id.server_product_process_parameters_id == self.surface_technics_parameters_id:
if line.product_qty == 1:
purchase_orders_id = line.order_id
return purchase_orders_id
supplier_id = fields.Many2one('res.partner', string='外协供应商')
equipment_id = fields.Many2one('maintenance.equipment', string='加工设备', tracking=True)
@@ -227,6 +354,7 @@ class ResMrpWorkOrder(models.Model):
part_number = fields.Char(related='production_id.part_number', string='零件图号')
machining_drawings = fields.Binary('2D加工图纸', related='production_id.part_drawing', readonly=True)
quality_standard = fields.Binary('质检标准', related='production_id.quality_standard', readonly=True)
part_name = fields.Char(related='production_id.part_name', string='零件名称')
# 工序状态
process_state = fields.Selection([
@@ -278,8 +406,11 @@ class ResMrpWorkOrder(models.Model):
保存名称
"""
for record in self:
tem_name = record.production_id.name.replace('/', '_')
record.save_name = tem_name + '_' + record.processing_panel
if record.processing_panel:
tem_name = record.production_id.name.replace('/', '_')
record.save_name = tem_name + '_' + record.processing_panel
else:
record.save_name = ''
schedule_state = fields.Selection(related='production_id.schedule_state', store=True)
# 工件装夹信息
@@ -305,6 +436,7 @@ class ResMrpWorkOrder(models.Model):
is_delivery = fields.Boolean('是否配送完成', default=False)
rfid_code = fields.Char('RFID码')
rfid_code_old = fields.Char('RFID码(已解除)')
is_test_env = fields.Boolean('测试环境', default=False)
production_line_id = fields.Many2one('sf.production.line', related='production_id.production_line_id',
string='生产线', store=True, tracking=True)
@@ -320,9 +452,13 @@ class ResMrpWorkOrder(models.Model):
detailed_reason = fields.Text('详细原因')
is_rework = fields.Boolean(string='是否返工', default=False)
def button_change_env(self):
self.is_test_env = not self.is_test_env
@api.constrains('blocked_by_workorder_ids')
def _check_no_cyclic_dependencies(self):
if self.production_id.state not in ['rework'] and self.state not in ['rework']:
if self.production_id.state not in ['rework', 'technology_to_confirmed', 'confirmed'] and self.state not in [
'rework']:
if not self._check_m2m_recursion('blocked_by_workorder_ids'):
raise ValidationError(_("您不能创建周期性的依赖关系."))
@@ -333,8 +469,9 @@ class ResMrpWorkOrder(models.Model):
for workorder in self.blocked_by_workorder_ids:
if workorder.state in ['done', 'cancel', 'rework']:
continue
workorder._plan_workorder(replan)
start_date = max(start_date, workorder.date_planned_finished)
if workorder.production_id.state not in ['technology_to_confirmed', 'confirmed']:
workorder._plan_workorder(replan)
start_date = max(start_date, workorder.date_planned_finished)
# Plan only suitable workorders
if self.state not in ['pending', 'waiting', 'ready']:
return
@@ -664,35 +801,14 @@ class ResMrpWorkOrder(models.Model):
}}
# 拼接工单对象属性值
def json_workorder_str(self, k, production, route, item):
def json_workorder_str(self, production, route):
# 计算预计时长duration_expected
routing_types = ['切割', '装夹预调', 'CNC加工', '解除装夹']
if route.routing_type in routing_types:
if route.route_id.routing_type in routing_types:
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', route.routing_type)])
[('name', '=', route.routing_type if hasattr(route, 'routing_type') else route.route_id.routing_type)])
duration_expected = routing_workcenter.time_cycle
reserved_duration = routing_workcenter.reserved_duration
# if route.routing_type == '切割':
# duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
# [('name', '=', '切割')]).time_cycle
# # elif route.routing_type == '获取CNC加工程序':
# # duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
# # [('name', '=', '获取CNC加工程序')]).time_cycle
# elif route.routing_type == '装夹预调':
# duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
# [('name', '=', '装夹预调')]).time_cycle
# # elif route.routing_type == '前置三元定位检测':
# # duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
# # [('name', '=', '前置三元定位检测')]).time_cycle
# elif route.routing_type == 'CNC加工':
# duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
# [('name', '=', 'CNC加工')]).time_cycle
# # elif route.routing_type == '后置三元质量检测':
# # duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
# # [('name', '=', '后置三元质量检测')]).time_cycle
# elif route.routing_type == '解除装夹':
# duration_expected = self.env['mrp.routing.workcenter'].sudo().search(
# [('name', '=', '解除装夹')]).time_cycle
else:
duration_expected = 60
reserved_duration = 30
@@ -700,26 +816,22 @@ class ResMrpWorkOrder(models.Model):
'product_uom_id': production.product_uom_id.id,
'qty_producing': 0,
'operation_id': False,
'name': route.route_workcenter_id.name,
'processing_panel': k,
'quality_point_ids': route.route_workcenter_id.quality_point_ids,
'routing_type': route.routing_type,
# 'work_state': '待发起',
'workcenter_id': self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids,
route.routing_type,
production.product_id),
'name': route.name if hasattr(route, 'routing_type') else route.route_id.name,
'processing_panel': False if hasattr(route, 'routing_type') else route.panel,
'sequence': route.sequence,
'quality_point_ids': False if hasattr(route, 'routing_type') else route.route_id.quality_point_ids,
'routing_type': route.routing_type if hasattr(route, 'routing_type') else route.route_id.routing_type,
'workcenter_id': False if hasattr(route, 'routing_type') else self.env[
'mrp.routing.workcenter'].get_workcenter(route.route_id.workcenter_ids.ids,
route.route_id.routing_type,
production.product_id),
# 设定初始化值避免出现变成bool问题
'date_planned_start': datetime.now(),
'date_planned_finished': datetime.now() + timedelta(days=1),
'duration_expected': duration_expected,
'duration': 0,
'tag_type': '重新加工' if item is False else False,
'cnc_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cnc.processing']._json_cnc_processing(
k, item),
'cmm_ids': False if route.routing_type != 'CNC加工' else self.env['sf.cmm.program']._json_cmm_program(k,
item),
# 'workpiece_delivery_ids': False if not route.routing_type == '装夹预调' else self._json_workpiece_delivery_list(
# production)
'technology_design_id': route.id,
# 'tag_type': '重新加工' if item is False else False,
'reserved_duration': reserved_duration,
}]
return workorders_values_str
@@ -750,22 +862,24 @@ class ResMrpWorkOrder(models.Model):
]
# 拼接工单对象属性值(表面工艺)
def _json_workorder_surface_process_str(self, production, route, process_parameter, supplier_id):
def _json_workorder_surface_process_str(self, production, route, supplier_id):
workorders_values_str = [0, '', {
'product_uom_id': production.product_uom_id.id,
'qty_producing': 0,
'operation_id': False,
'name': '%s-%s' % (route.name, process_parameter.name),
'name': route.process_parameters_id.display_name,
'processing_panel': '',
'sequence': route.sequence,
'technology_design_id': route.id,
'routing_type': '表面工艺',
'surface_technics_parameters_id': process_parameter.id,
'surface_technics_parameters_id': route.process_parameters_id.id,
'work_state': '',
'supplier_id': supplier_id,
'is_subcontract': True if process_parameter.gain_way == '外协' else False,
'is_subcontract': True if route.process_parameters_id.gain_way == '外协' else False,
'workcenter_id': self.env[
'mrp.workcenter'].get_process_outsourcing_workcenter() if process_parameter.gain_way == '外协' else
self.env['mrp.routing.workcenter'].get_workcenter(route.workcenter_ids.ids,
route.routing_type,
'mrp.workcenter'].get_process_outsourcing_workcenter() if route.process_parameters_id.gain_way == '外协' else
self.env['mrp.routing.workcenter'].get_workcenter(route.route_id.workcenter_ids.ids,
route.route_id.routing_type,
production.product_id),
'date_planned_start': datetime.now(),
'date_planned_finished': datetime.now() + timedelta(days=1),
@@ -917,195 +1031,223 @@ class ResMrpWorkOrder(models.Model):
return workorders_values_str
@api.depends('production_availability', 'blocked_by_workorder_ids', 'blocked_by_workorder_ids.state',
'production_id.tool_state')
'production_id.tool_state', 'production_id.schedule_state', 'sequence',
'production_id.programming_state')
def _compute_state(self):
super()._compute_state()
for workorder in self:
re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id),
('processing_panel', '=', workorder.processing_panel),
('is_rework', '=', True), ('state', 'in', ['done', 'rework'])])
cnc_workorder = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id),
('processing_panel', '=', workorder.processing_panel),
('routing_type', '=', 'CNC加工'), ('state', 'in', ['done', 'rework']),
('test_results', '=', '返工')])
cnc_workorder_pending = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id),
('processing_panel', '=', workorder.processing_panel),
('routing_type', '=', 'CNC加工'), ('state', 'in', ['pending'])])
unclamp_workorder = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id),
('sequence', '=', workorder.sequence - 1),
('state', 'in', ['done'])])
if workorder.state not in ['cancel', 'progress', 'rework']:
if workorder.production_id.state == 'rework':
if workorder.routing_type == '装夹预调' and workorder.state not in ['done', 'rework',
'cancel']:
# # 有返工工单
# if re_work:
# 新工单
if workorder.is_rework is False:
if workorder.production_id.programming_state == '已编程' and workorder.production_id.is_rework is False:
if re_work or cnc_workorder:
workorder.state = 'ready'
else:
if workorder.production_id.is_rework is True:
if re_work or cnc_workorder:
workorder.state = 'waiting'
elif workorder.routing_type == 'CNC加工' and workorder.state not in ['done', 'rework', 'cancel']:
pre_workorder = self.env['mrp.workorder'].search(
[('production_id', '=', workorder.production_id.id),
('processing_panel', '=', workorder.processing_panel),
('routing_type', '=', '装夹预调'), ('state', '=', 'done')])
if pre_workorder:
if re_work:
workorder.state = 'waiting'
elif workorder.routing_type == '解除装夹' and workorder.state not in ['done', 'rework', 'cancel']:
if cnc_workorder:
if not cnc_workorder_pending or unclamp_workorder.test_results == '报废':
workorder.state = 'waiting'
# else:
# if workorder.production_id.is_rework is True:
# workorder.state = 'waiting'
elif workorder.production_id.state == 'progress':
if workorder.routing_type == '装夹预调' and workorder.production_id.programming_state == '已编程' and \
workorder.is_rework is False and workorder.state not in [
'done', 'rework',
'cancel']:
if workorder.production_id.is_rework is False:
if re_work or cnc_workorder or unclamp_workorder:
workorder.state = 'ready'
# if (re_work or cnc_workorder) and workorder.production_id.is_rework is False:
# workorder.state = 'ready'
if workorder.routing_type == '表面工艺' and workorder.state not in ['done', 'progress']:
if unclamp_workorder:
if workorder.is_subcontract is False:
workorder.state = 'ready'
else:
production_programming = self.env['mrp.production'].search(
[('programming_no', '=', self.production_id.programming_no)], order='name asc')
production_no_remanufacture = production_programming.filtered(
lambda a: a.is_remanufacture is False)
production_list = [production.name for production in production_programming]
purchase_orders = self.env['purchase.order'].search(
[('origin', 'ilike', ','.join(production_list))])
for line in purchase_orders.order_line:
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id and line.product_qty == len(
production_no_remanufacture):
if purchase_orders.state == 'purchase':
workorder.state = 'ready'
else:
workorder.state = 'waiting'
elif workorder.production_id.state == 'scrap':
if workorder.routing_type == '解除装夹' and unclamp_workorder.test_results == '报废':
workorder.state = 'waiting'
if workorder.routing_type == '装夹预调' and workorder.state in ['waiting', 'ready', 'pending']:
workorder_ids = workorder.production_id.workorder_ids
work_bo = True
for wo in workorder_ids.filtered(lambda a: a.routing_type == '装夹预调' and a.state == 'rework'):
if not workorder_ids.filtered(
lambda a: (a.routing_type == '装夹预调' and a.state not in ['rework', 'cancel']
and a.processing_panel == wo.processing_panel)):
work_bo = False
break
if (workorder.production_id.programming_state == '已编程' and work_bo
and not workorder_ids.filtered(lambda a: a.sequence == 0)):
# 当工单对应制造订单的功能刀具状态为 【无效刀】时,先对的第一个装夹预调工单状态设置为 【等待组件】
if workorder.production_id.tool_state in ['1', '2']:
if workorder.state in ['ready']:
workorder.state = 'waiting'
continue
elif workorder.state in ['waiting']:
continue
elif 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.production_id.tool_state in ['0']:
if workorder_ids.filtered(lambda a: a.state == 'rework'):
if not workorder_ids.filtered(
lambda a: (a.routing_type not in ['装夹预调'] and
a.state not in ['pending', 'done', 'rework', 'cancel'])):
# 查询工序最小的非完工、非返工的装夹预调工单
work_id = self.search(
[('production_id', '=', workorder.production_id.id),
('state', 'not in', ['rework', 'done', 'cancel'])],
limit=1,
order="sequence")
if work_id.routing_type == '装夹预调':
if workorder == work_id:
if workorder.production_id.reservation_state == 'assigned':
workorder.state = 'ready'
elif workorder.production_id.reservation_state != 'assigned':
workorder.state = 'waiting'
continue
elif (workorder.name == '装夹预调' and
workorder.state not in ['rework', 'done', 'cancel']):
if workorder.state != 'pending':
workorder.state = 'pending'
if workorder.production_id.tool_state in ['1', '2'] and workorder.state == 'ready':
workorder.state = 'waiting'
continue
# elif workorder.routing_type == 'CNC加工' and workorder.state not in ['done', 'cancel', 'progress',
# 'rework']:
# per_work = self.env['mrp.workorder'].search(
# [('routing_type', '=', '装夹预调'), ('production_id', '=', workorder.production_id.id),
# ('processing_panel', '=', workorder.processing_panel), ('is_rework', '=', True)])
# if per_work:
# workorder.state = 'waiting'
# if workorder.routing_type == 'CNC加工' and workorder.state == 'progress':
# workorder.state = 'to be detected'
# super()._compute_state()
# for workorder in self:
# if workorder.is_rework is True and workorder.state == 'done':
# cnc_work = self.env['mrp.workorder'].search([('routing_type','=','CNC加工'),('production_id','=',workorder.production_id.id)])
# if cnc_work:
# cnc_work.state = 'waiting'
# if workorder.sequence != 1:
# previous_workorder = self.env['mrp.workorder'].search(
# [('production_id', '=', workorder.production_id.id),
# ('sequence', '=', workorder.sequence - 1)])
# if workorder.state == 'pending':
# if all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
# workorder.state = 'ready' if workorder.production_id.reservation_state == 'assigned' else 'waiting'
# continue
# if workorder.production_id.reservation_state == 'assigned' and workorder.production_id.schedule_state == '已排':
# if ((workorder.sequence == 1 and not workorder.blocked_by_workorder_ids)
# or (workorder.blocked_by_workorder_ids.state in ('done', 'cancel')
# and workorder.blocked_by_workorder_ids.test_results not in ['报废', '返工'])
# or (previous_workorder.state in ('done', 'cancel')
# and not workorder.blocked_by_workorder_ids
# and previous_workorder.test_results not in ['报废', '返工'])
# ):
# workorder.state = 'ready'
# continue
# if workorder.production_id.schedule_state == '未排' and workorder.state in ('waiting', 'ready'):
# if workorder.sequence != 1:
# workorder.state = 'pending'
# continue
# if workorder.state not in ('waiting', 'ready'):
# continue
# if workorder.state in (
# 'waiting') and workorder.sequence == 1 and workorder.production_id.schedule_state == '已排':
# workorder.state = 'ready'
# continue
# if not all([wo.state in ('done', 'cancel') for wo in workorder.blocked_by_workorder_ids]):
# workorder.state = 'pending'
# if workorder.state in ['waiting']:
# if previous_workorder.state == 'waiting':
# workorder.state = 'pending'
# if workorder.sequence == 1 and workorder.state == 'pending':
# workorder.state = 'waiting'
# continue
# if workorder.production_id.reservation_state not in ('waiting', 'confirmed', 'assigned'):
# continue
# if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting':
# if workorder.production_id.reservation_state == 'assigned' and workorder.state == 'waiting' and workorder.production_id.schedule_state == '已排':
# workorder.state = 'ready'
# elif workorder.production_id.reservation_state != 'assigned' and workorder.state == 'ready':
# workorder.state = 'waiting'
for workorder in self:
# 如果工单的工序没有进行排序则跳出循环
if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0):
continue
# ===== 对所有按序号排序的非[进行中、完成、返工、取消]状态的工单,除了第一条之外的工单状态都设置为[等待其他工单] =====
# logging.info(workorder.state)
work_ids = workorder.production_id.workorder_ids.filtered(
lambda wk: wk.state not in ['done', 'rework', 'cancel'])
if not work_ids:
continue
min_sequence_wk = min(work_ids, key=lambda wk: wk.sequence)
if workorder.state in ['done', 'rework', 'cancel', 'progress', 'to be detected']:
continue
else:
if workorder != min_sequence_wk:
if workorder.state != 'pending':
workorder.state = 'pending'
continue
# ================= 如果制造订单制造类型为【人工线下加工】==========================
if (workorder.production_id.production_type == '人工线下加工'
and workorder.production_id.schedule_state == '已排'
and len(workorder.production_id.picking_ids.filtered(
lambda w: w.state not in ['done', 'cancel'])) == 0):
if workorder.is_subcontract is True:
purchase_orders_id = self._get_surface_technics_purchase_ids()
if purchase_orders_id.state == 'purchase':
workorder.state = 'ready'
continue
else:
workorder.state = 'waiting'
continue
else:
workorder.state = 'ready'
continue
# ================= 如果制造订单刀具状态为[无效刀、缺刀] 或者 制造订单状态为[返工]==========================
if (workorder.production_id.tool_state in ['1', '2'] or workorder.production_id.state == 'rework'
or workorder.production_id.schedule_state != '已排'
or workorder.production_id.reservation_state not in ['assigned']
or workorder.production_id.workorder_ids.filtered(
lambda wk: wk.sequence == workorder.sequence - 1).test_results in ['报废', '返工']):
if workorder.state != 'waiting':
workorder.state = 'waiting'
continue
if workorder.production_id.programming_state == '已编程':
workorder.state = 'ready'
elif workorder.state != 'waiting':
workorder.state = 'waiting'
# =========== 特殊工艺工单处理 ===================
# if workorder.routing_type == '表面工艺' and workorder.is_subcontrac:
# purchase_order = self.env['purchase.order'].search(
# [('origin', 'ilike', workorder.production_id.name)])
# if purchase_order.picking_ids.filtered(lambda p: p.state in ['waiting', 'confirmed', 'assigned']):
# workorder.state = 'waiting'
# continue
if workorder.technology_design_id.routing_tag == 'special':
if workorder.is_subcontract is False:
workorder.state = 'ready'
else:
# production_programming = self.env['mrp.production'].search(
# [('origin', '=', self.production_id.origin)], order='name asc')
# production_no_remanufacture = production_programming.filtered(
# lambda a: a.is_remanufacture is False)
# production_list = [production.name for production in production_programming]
# purchase_orders = self.env['purchase.order'].search(
# [('origin', 'ilike', ','.join(production_list))])
# for line in purchase_orders.order_line:
# if (
# line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id
# and line.product_qty == len(production_no_remanufacture)):
# if all(pur_order.state == 'purchase' for pur_order in purchase_orders):
# workorder.state = 'ready'
# else:
# workorder.state = 'waiting'
purchase_orders_id = self._get_surface_technics_purchase_ids()
if purchase_orders_id:
workorder.state = 'ready' if purchase_orders_id.state == 'purchase' else 'waiting'
else:
workorder.state = 'waiting'
# re_work = self.env['mrp.workorder'].search([('production_id', '=', workorder.production_id.id),
# ('processing_panel', '=', workorder.processing_panel),
# ('is_rework', '=', True), ('state', 'in', ['done', 'rework'])])
# cnc_workorder = self.env['mrp.workorder'].search(
# [('production_id', '=', workorder.production_id.id),
# ('processing_panel', '=', workorder.processing_panel),
# ('routing_type', '=', 'CNC加工'), ('state', 'in', ['done', 'rework']),
# ('test_results', '=', '返工')])
# cnc_workorder_pending = self.env['mrp.workorder'].search(
# [('production_id', '=', workorder.production_id.id),
# ('processing_panel', '=', workorder.processing_panel),
# ('routing_type', '=', 'CNC加工'), ('state', 'in', ['pending'])])
# unclamp_workorder = self.env['mrp.workorder'].search(
# [('production_id', '=', workorder.production_id.id),
# ('sequence', '=', workorder.sequence - 1),
# ('state', 'in', ['done'])])
# if workorder.state not in ['cancel', 'progress', 'rework']:
# if workorder.production_id.state == 'rework':
# if workorder.routing_type == '装夹预调':
# # # 有返工工单
# # if re_work:
# # 新工单
# if workorder.is_rework is False:
# if (workorder.production_id.programming_state == '已编程'
# and workorder.production_id.is_rework is False):
# if re_work or cnc_workorder:
# workorder.state = 'ready'
# else:
# if workorder.production_id.is_rework is True:
# if re_work or cnc_workorder:
# workorder.state = 'waiting'
#
# elif workorder.routing_type == 'CNC加工':
# pre_workorder = self.env['mrp.workorder'].search(
# [('production_id', '=', workorder.production_id.id),
# ('processing_panel', '=', workorder.processing_panel),
# ('routing_type', '=', '装夹预调'), ('state', '=', 'done')])
# if pre_workorder:
# if re_work:
# workorder.state = 'waiting'
# elif workorder.routing_type == '解除装夹':
# if cnc_workorder:
# if not cnc_workorder_pending or unclamp_workorder.test_results == '报废':
# workorder.state = 'waiting'
# # else:
# # if workorder.production_id.is_rework is True:
# # workorder.state = 'waiting'
# elif workorder.production_id.state == 'progress':
# if (workorder.routing_type == '装夹预调' and workorder.production_id.programming_state == '已编程'
# and workorder.is_rework is False and workorder.state not in ['done', 'rework', 'cancel']):
# if workorder.production_id.is_rework is False:
# if re_work or cnc_workorder or unclamp_workorder:
# workorder.state = 'ready'
# # if (re_work or cnc_workorder) and workorder.production_id.is_rework is False:
# # workorder.state = 'ready'
# elif workorder.production_id.state == 'scrap':
# if workorder.routing_type == '解除装夹' and unclamp_workorder.test_results == '报废':
# workorder.state = 'waiting'
# 重写工单开始按钮方法
def button_start(self):
# 判断工单状态是否为等待组件
if self.state in ['waiting', 'pending']:
raise UserError('制造订单【%s】缺少组件信息!' % self.production_id.name)
if self.routing_type == 'CNC加工':
self.env['sf.production.plan'].sudo().search([('name', '=', self.production_id.name)]).write({
'state': 'processing',
'actual_start_time': datetime.now()
})
if self.routing_type == '装夹预调':
if self.sequence == 1:
# 判断是否有坯料的序列号信息
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:
if self.production_id.move_raw_ids:
if self.production_id.move_raw_ids[0].product_id.categ_type == '坯料':
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
else:
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
# cnc校验
cnc_workorder = self.search(
[('production_id', '=', self.production_id.id), ('routing_type', '=', 'CNC加工')],
limit=1, order='id asc')
if not cnc_workorder.cnc_ids:
raise UserError(_('该制造订单还未下发CNC程序请稍后再试'))
if self.production_id.production_type == '自动化产线加工':
cnc_workorder = self.search(
[('production_id', '=', self.production_id.id), ('routing_type', '=', 'CNC加工')],
limit=1, order='id asc')
# if not cnc_workorder.cnc_ids:
# raise UserError(_('该制造订单还未下发CNC程序请稍后再试'))
else:
if self.production_id.tool_state in ['1', '2']:
if self.production_id.tool_state == '1':
@@ -1122,15 +1264,33 @@ class ResMrpWorkOrder(models.Model):
# 表面工艺外协出库单
if self.routing_type == '表面工艺':
if self.is_subcontract is True:
move_out = self.env['stock.move'].search(
[('location_id', '=', self.env['stock.location'].search(
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
('location_dest_id', '=', self.env['stock.location'].search(
[('barcode', 'ilike', 'VL-SPOC')]).id),
('origin', '=', self.production_id.name)])
if move_out.state != 'done':
move_out.write({'state': 'assigned', 'production_id': False})
self.env['stock.move.line'].create(move_out.get_move_line(self.production_id, self))
move_out = self.move_subcontract_workorder_ids[1]
# move_out = self.env['stock.move'].search(
# [('location_id', '=', self.env['stock.location'].search(
# [('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
# ('location_dest_id', '=', self.env['stock.location'].search(
# [('barcode', 'ilike', 'VL-SPOC')]).id),
# ('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])])
for mo in move_out:
if mo.state != 'done':
mo.write({'state': 'assigned', 'production_id': False})
if not mo.move_line_ids:
self.env['stock.move.line'].create(mo.get_move_line(self.production_id, self))
# product_qty = mo.product_uom._compute_quantity(
# mo.product_uom_qty, mo.product_id.uom_id, rounding_method='HALF-UP')
# available_quantity = self.env['stock.quant']._get_available_quantity(
# mo.product_id,
# mo.location_id,
# lot_id=mo.move_line_ids.lot_id,
# strict=False,
# )
# mo._update_reserved_quantity(
# product_qty,
# available_quantity,
# mo.location_id,
# lot_id=mo.move_line_ids.lot_id,
# strict=False,
# )
# move_out._action_assign()
if self.state == 'waiting' or self.state == 'ready' or self.state == 'progress':
@@ -1200,8 +1360,8 @@ class ResMrpWorkOrder(models.Model):
if record.is_rework is False:
if not record.material_center_point:
raise UserError("坯料中心点为空,请检查")
# if record.X_deviation_angle <= 0:
# raise UserError("X偏差角度小于等于0请检查本次计算的X偏差角度为%s" % record.X_deviation_angle)
# if record.X_deviation_angle <= 0:
# raise UserError("X偏差角度小于等于0请检查本次计算的X偏差角度为%s" % record.X_deviation_angle)
record.process_state = '待加工'
# record.write({'process_state': '待加工'})
record.production_id.process_state = '待加工'
@@ -1231,23 +1391,17 @@ class ResMrpWorkOrder(models.Model):
'''
record.date_finished = datetime.now()
if record.routing_type == '表面工艺':
logging.info('record.picking_ids:%s' % record.picking_ids)
logging.info('record.picking_out:%s' % record.picking_ids[0])
if record.picking_ids:
for pick_item in record.picking_ids:
if pick_item.state not in ['done']:
raise UserError(
'请先完成该工单的工艺外协再进行操作')
picking_out = record.env['stock.move.line'].search(
[('picking_id', '=', record.picking_ids[0].id)])
logging.info('picking_out:%s' % picking_out.picking_id.name)
# if picking_out:
# order_line_ids = []
# logging.info('surface_technics_parameters_id:%s' % record.surface_technics_parameters_id.name)
#
# else:
# raise UserError(
# '请先在产品中配置表面工艺为%s相关的外协服务产品' % item.surface_technics_parameters_id.name)
picks = record.picking_ids.filtered(lambda p: p.state not in ('done'))
if picks:
raise UserError('请先完成该工单的工艺外协再进行操作')
# 表面工艺外协,最后一张工单
workorders = self.production_id.workorder_ids
subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence')
if self == subcontract_workorders[-1]:
# 给下一个库存移动就绪
self.move_subcontract_workorder_ids[0].move_dest_ids._action_done()
# self.production_id.button_mark_done()
tem_date_planned_finished = record.date_planned_finished
tem_date_finished = record.date_finished
logging.info('routing_type:%s' % record.routing_type)
@@ -1266,7 +1420,7 @@ class ResMrpWorkOrder(models.Model):
# record.recreateManufacturingOrWorkerOrder()
is_production_id = False
rework_workorder = record.production_id.workorder_ids.filtered(lambda p: p.state == 'rework')
done_workorder = record.production_id.workorder_ids.filtered(lambda p1: p1.state == 'done')
done_workorder = record.production_id.workorder_ids.filtered(lambda p1: p1.state in ['done'])
if (len(rework_workorder) + len(done_workorder) == len(record.production_id.workorder_ids)) or (
len(done_workorder) == len(record.production_id.workorder_ids)):
is_production_id = True
@@ -1283,19 +1437,20 @@ class ResMrpWorkOrder(models.Model):
# workorder.rfid_code_old = rfid_code
# workorder.rfid_code = False
logging.info('workorder.rfid_code:%s' % workorder.rfid_code)
if is_production_id is True and record.routing_type in ['解除装夹', '表面工艺']:
# if is_production_id is True and record.routing_type in ['解除装夹', '表面工艺', '切割']:
if is_production_id is True:
logging.info('product_qty:%s' % record.production_id.product_qty)
for move_raw_id in record.production_id.move_raw_ids:
move_raw_id.quantity_done = move_raw_id.product_uom_qty
record.process_state = '已完工'
record.production_id.process_state = '已完工'
if record.routing_type in ['表面工艺']:
raw_move = self.env['stock.move'].sudo().search(
[('origin', '=', record.production_id.name),
('procure_method', 'in', ['make_to_order', 'make_to_stock']),
('state', '!=', 'done')])
if raw_move:
raw_move.write({'state': 'done'})
# if record.routing_type in ['表面工艺']:
# raw_move = self.env['stock.move'].sudo().search(
# [('origin', '=', record.production_id.name),
# ('procure_method', 'in', ['make_to_order', 'make_to_stock']),
# ('state', '!=', 'done')])
# if raw_move:
# raw_move.write({'state': 'done'})
record.production_id.button_mark_done1()
# record.production_id.state = 'done'
@@ -1415,6 +1570,8 @@ class ResMrpWorkOrder(models.Model):
'default_confirm_button': '确认解除',
# 'default_feeder_station_start_id': feeder_station_start_id,
}}
move_subcontract_workorder_ids = fields.One2many('stock.move', 'subcontract_workorder_id', string='组件')
class CNCprocessing(models.Model):
@@ -1829,7 +1986,7 @@ 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:
@@ -1938,3 +2095,56 @@ class CMMprogram(models.Model):
'program_create_date': datetime.strptime(item['program_create_date'], '%Y-%m-%d %H:%M:%S'),
}))
return cmm_program
def update_work_start_end(self, date_planned_start, date_planned_end):
self.leave_id.write({
'date_from': date_planned_start,
'date_to': date_planned_end,
})
self.date_planned_finished = datetime.datetime.today() + datetime.timedelta(days=100)
self.date_planned_start = date_planned_start
self.date_planned_finished = date_planned_end
routing_workcenter = self.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', self.routing_type)])
self.write({'date_planned_start': date_planned_start, 'date_planned_finished': date_planned_end,
'duration_expected': routing_workcenter.time_cycle})
def auto_production_process(self, last_time, is_first, type_map):
date_planned_end = None
date_planned_start = None
duration_expected = datetime.timedelta(minutes=self.duration_expected)
reserve_time = datetime.timedelta(minutes=self.reserved_duration)
if is_first:
# 第一轮加工
if self.routing_type == '装夹预调':
date_planned_end = last_time - reserve_time
date_planned_start = date_planned_end - duration_expected
elif self.routing_type == 'CNC加工':
date_planned_start = last_time
date_planned_end = last_time + duration_expected
last_time = date_planned_end
else:
date_planned_start = last_time + reserve_time
date_planned_end = date_planned_start + duration_expected
last_time = date_planned_end
type_map.update({self.routing_type: True})
else:
date_planned_start = last_time + reserve_time
date_planned_end = date_planned_start + duration_expected
last_time = date_planned_end
return date_planned_start, date_planned_end, last_time
def manual_offline_process(self, last_time, is_first):
date_planned_end = None
date_planned_start = None
duration_expected = datetime.timedelta(minutes=self.duration_expected)
reserve_time = datetime.timedelta(minutes=self.reserved_duration)
if is_first:
date_planned_start = last_time
date_planned_end = last_time + duration_expected
else:
date_planned_start = last_time + reserve_time
date_planned_end = date_planned_start + duration_expected
return date_planned_start, date_planned_end, last_time

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))
@@ -140,11 +141,11 @@ class ResProductMo(models.Model):
cutting_tool_coarse_medium_fine = fields.Selection(related='cutting_tool_model_id.integral_coarse_medium_fine', string='粗/中/精')
# cutting_tool_model_id.integral_coarse_medium_fine
# cutting_tool_run_out_accuracy_max = fields.Float('端跳精度max', digits=(6, 1))
cutting_tool_run_out_accuracy_max = fields.Char(related='cutting_tool_model_id.integral_run_out_accuracy_max', string='端跳精度max', digits=(6, 1))
cutting_tool_run_out_accuracy_max = fields.Char(related='cutting_tool_model_id.integral_run_out_accuracy_max', string='端跳精度max')
# cutting_tool_model_id.integral_run_out_accuracy_max
# cutting_tool_run_out_accuracy_min = fields.Float('端跳精度min', digits=(6, 1))
cutting_tool_run_out_accuracy_min = fields.Char(related='cutting_tool_model_id.integral_run_out_accuracy_min',
string='端跳精度min', digits=(6, 1))
string='端跳精度min')
# cutting_tool_model_id.integral_run_out_accuracy_min
# cutting_tool_blade_tip_working_size = fields.Char('刀尖倒角度(°)', size=20)
cutting_tool_blade_tip_working_size = fields.Char(related='specification_id.blade_tip_working_size',
@@ -776,6 +777,7 @@ class ResProductMo(models.Model):
part_number = fields.Char(string='零件图号', readonly=True)
machining_drawings = fields.Binary('2D加工图纸', readonly=True)
quality_standard = fields.Binary('质检标准', readonly=True)
part_name = fields.Char(string='零件名称', readonly=True)
@api.constrains('tool_length')
def _check_tool_length_size(self):
@@ -837,22 +839,34 @@ 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()
copy_product_id.product_tmpl_id.active = True
model_type = self.env['sf.model.type'].search([], limit=1)
attachment = self.attachment_create(item['model_name'], item['model_data'])
# 获取坯料冗余配置
if not item.get('embryo_redundancy'):
embryo_redundancy_id = model_type.embryo_tolerance_id
else:
embryo_redundancy_id = item.get('embryo_redundancy')
if not embryo_redundancy_id:
raise UserError('请先配置模型类型内的坯料冗余')
vals = {
'name': '%s-%s-%s' % ('P', order_id.name, i),
'model_long': item['model_long'] + model_type.embryo_tolerance,
'model_width': item['model_width'] + model_type.embryo_tolerance,
'model_height': item['model_height'] + model_type.embryo_tolerance,
'model_volume': (item['model_long'] + model_type.embryo_tolerance) * (
item['model_width'] + model_type.embryo_tolerance) * (
item['model_height'] + model_type.embryo_tolerance),
'model_long': self.format_float(item['model_long'] + embryo_redundancy_id.long),
'model_width': self.format_float(item['model_width'] + embryo_redundancy_id.width),
'model_height': self.format_float(item['model_height'] + embryo_redundancy_id.height),
'model_volume': self.format_float((item['model_long'] + embryo_redundancy_id.long) * (
item['model_width'] + embryo_redundancy_id.width) * (
item['model_height'] + embryo_redundancy_id.height)),
'product_model_type_id': model_type.id,
# 'model_processing_panel': 'R',
'model_processing_panel': item['processing_panel_detail'],
'model_machining_precision': item['model_machining_precision'],
'model_code': item['barcode'],
'length': item['model_long'],
@@ -860,8 +874,8 @@ class ResProductMo(models.Model):
'height': item['model_height'],
'volume': item['model_long'] * item['model_width'] * item['model_height'],
'model_file': '' if not item['model_file'] else base64.b64decode(item['model_file']),
'model_name': attachment.name,
'upload_model_file': [(6, 0, [attachment.id])],
'model_name': attachment.name if attachment else None,
'upload_model_file': [(6, 0, [attachment.id])] if attachment else None,
'list_price': item['price'],
'materials_id': self.env['sf.production.materials'].search(
[('materials_no', '=', item['texture_code'])]).id,
@@ -875,8 +889,10 @@ 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']),
'part_name': item['part_name'],
}
tax_id = self.env['account.tax'].sudo().search(
[('type_tax_use', '=', 'sale'), ('amount', '=', item.get('tax')), ('price_include', '=', 'True')])
@@ -884,7 +900,27 @@ 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 format_float(self, value):
# 将浮点数转换为字符串
value_str = str(value)
# 检查小数点的位置
if '.' in value_str:
# 获取小数部分
decimal_part = value_str.split('.')[1]
# 判断小数位数是否超过2位
if len(decimal_part) > 2:
# 超过2位则保留2位小数
return "{:.2f}".format(value)
# 否则保持原来的位数
return float(value_str)
def _get_ids(self, param):
type_ids = []
@@ -902,6 +938,8 @@ class ResProductMo(models.Model):
return [(6, 0, process_parameters_ids)]
def attachment_create(self, name, data):
if not data:
return None
attachment = self.env['ir.attachment'].create({
'datas': base64.b64decode(data),
'type': 'binary',
@@ -919,31 +957,40 @@ class ResProductMo(models.Model):
# if surface_technology:
# no_bom_copy_product_id.route_ids |= surface_technology
no_bom_copy_product_id.product_tmpl_id.active = True
logging.info('no_bom_copy_product_id[is_manual_processing]:%s' % no_bom_copy_product_id.is_manual_processing)
materials_id = self.env['sf.production.materials'].search(
[('materials_no', '=', item['texture_code'])])
materials_type_id = self.env['sf.materials.model'].search(
[('materials_no', '=', item['texture_type_code'])])
model_type = self.env['sf.model.type'].search([], limit=1)
supplier = self.env['mrp.bom'].get_supplier(materials_type_id)
# 获取坯料冗余配置
if not item.get('embryo_redundancy_id'):
embryo_redundancy_id = model_type.embryo_tolerance_id
else:
embryo_redundancy_id = item.get('embryo_redundancy_id')
if not embryo_redundancy_id:
raise UserError('请先配置模型类型内的坯料冗余')
logging.info('no_bom_copy_product_supplier-vals:%s' % supplier)
vals = {
'name': '%s-%s-%s [%s %s-%s * %s * %s]' % ('R',
order_id.name, i, materials_id.name, materials_type_id.name,
item['model_long'] + model_type.embryo_tolerance,
item['model_width'] + model_type.embryo_tolerance,
item['model_height'] + model_type.embryo_tolerance),
'length': item['model_long'] + model_type.embryo_tolerance,
'width': item['model_width'] + model_type.embryo_tolerance,
'height': item['model_height'] + model_type.embryo_tolerance,
'volume': (item['model_long'] + model_type.embryo_tolerance) * (
item['model_width'] + model_type.embryo_tolerance) * (
item['model_height'] + model_type.embryo_tolerance),
item['model_long'] + embryo_redundancy_id.long,
item['model_width'] + embryo_redundancy_id.width,
item['model_height'] + embryo_redundancy_id.height),
'length': item['model_long'] + embryo_redundancy_id.long,
'width': item['model_width'] + embryo_redundancy_id.width,
'height': item['model_height'] + embryo_redundancy_id.height,
'volume': (item['model_long'] + embryo_redundancy_id.long) * (
item['model_width'] + embryo_redundancy_id.width) * (
item['model_height'] + embryo_redundancy_id.height),
'embryo_model_type_id': model_type.id,
'list_price': item['price'],
'materials_id': materials_id.id,
'materials_type_id': materials_type_id.id,
'single_manufacturing': product_id.single_manufacturing,
'is_bfm': True,
'active': True
'active': True,
}
# 外协和采购生成的坯料需要根据材料型号绑定供应商
if route_type == 'subcontract' or route_type == 'purchase':

View File

@@ -0,0 +1,71 @@
from datetime import datetime
from odoo import models
import logging
import base64
import hashlib
_logger = logging.getLogger(__name__)
class QuickEasyOrder(models.Model):
_inherit = 'quick.easy.order'
def distribute_to_factory(self, obj):
"""
多供货方式,重写派单到工厂
:return:
"""
try:
_logger.info('---------派单到工厂-------')
res = {'bfm_process_order_list': []}
for item in obj:
attachment = item.upload_model_file[0]
base64_data = base64.b64encode(attachment.datas)
base64_datas = base64_data.decode('utf-8')
barcode = hashlib.sha1(base64_datas.encode('utf-8')).hexdigest()
# logging.info('model_file-size: %s' % len(item.model_file))
res['bfm_process_order_list'].append({
'model_long': item.model_length,
'model_width': item.model_width,
'model_height': item.model_height,
'model_volume': item.model_volume,
'model_machining_precision': item.machining_precision,
'model_name': attachment.name,
'model_data': base64_datas,
'model_file': base64.b64encode(item.model_file).decode('utf-8'),
'texture_code': item.material_id.materials_no,
'texture_type_code': item.material_model_id.materials_no,
# 'surface_process_code': self.env['jikimo.surface.process']._json_surface_process_code(item),
'process_parameters_code': self.env[
'sf.production.process.parameter']._json_production_process_item_code(
item),
'price': item.price,
'number': item.quantity,
'total_amount': item.price,
'remark': '',
'manual_quotation': True,
'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': '',
'part_name': '',
})
company_id = self.env.ref('base.main_company').sudo()
product_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_default').sudo().with_context(active_test=False).product_variant_id
# user_id = request.env.ref('base.user_admin').sudo()
order_id = self.env['sale.order'].sale_order_create(company_id, 'XXXXX', 'XXXXX', 'XXXXX',
str(datetime.now()), '现结', '支付宝', state='draft')
order_id.default_code = obj.name
i = 1
for item in res['bfm_process_order_list']:
product = self.env['product.template'].sudo().product_create(product_id, item, order_id,
obj.name, i)
order_id.with_user(self.env.ref("base.user_admin")).sale_order_create_line(product, item)
return order_id
except Exception as e:
return UserError('工厂创建销售订单和产品失败,请联系管理员')

View File

@@ -0,0 +1,166 @@
import logging
import json
from odoo import models, fields, api
from odoo.exceptions import UserError
_logger = logging.getLogger(__name__)
class SaleOrder(models.Model):
_inherit = 'sale.order'
state = fields.Selection([
('draft', "报价"),
('sent', "报价已发送"),
('supply method', "供货方式待确认"),
('sale', "销售订单"),
('done', "已锁定"),
('cancel', "已取消"),
])
def confirm_to_supply_method(self):
self.state = 'supply method'
def action_confirm(self):
# 判断是否所有产品都选择了供货方式
filter_line = self.order_line.filtered(lambda line: not line.supply_method)
if filter_line:
raise UserError('当前订单内(%s)产品未选择路线,请选择后重试' % ','.join(filter_line.mapped('product_id.name')))
for line in self.order_line:
bom_type = ''
# 根据供货方式修改成品模板
if line.supply_method == 'automation':
bom_type = 'normal'
product_template_id = self.env.ref('sf_dlm.product_template_sf').sudo().product_tmpl_id
elif line.supply_method == 'outsourcing':
bom_type = 'subcontract'
product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_outsourcing').sudo()
elif line.supply_method == 'purchase':
product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_purchase').sudo()
elif line.supply_method == 'manual':
bom_type = 'normal'
product_template_id = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_manual_processing').sudo()
# 复制成品模板上的属性
line.product_id.product_tmpl_id.copy_template(product_template_id)
# 将模板上的single_manufacturing属性复制到成品上
line.product_id.single_manufacturing = product_template_id.single_manufacturing
order_id = self
product = line.product_id
# 拼接方法需要的item结构
item = {
'texture_code': product.materials_id.materials_no,
'texture_type_code': product.materials_type_id.materials_no,
'model_long': product.length,
'model_width': product.width,
'model_height': product.height,
'price': product.list_price,
'embryo_redundancy_id': line.embryo_redundancy_id,
}
# 获取成品名结尾-n的n
product_seria = int(product.name.split('-')[-1])
# 成品供货方式为采购则不生成bom
if line.supply_method != 'purchase':
bom_data = self.env['mrp.bom'].with_user(self.env.ref("base.user_admin")).get_bom(product)
_logger.info('bom_data:%s' % bom_data)
if bom_data:
bom = self.env['mrp.bom'].with_user(self.env.ref("base.user_admin")).bom_create(product, 'normal', False)
bom.with_user(self.env.ref("base.user_admin")).bom_create_line_has(bom_data)
else:
# 当成品上带有客供料选项时,生成坯料时选择“客供料”路线
if line.embryo_redundancy_id:
# 将成品模板的内容复制到成品上
customer_provided_embryo = self.env.ref('jikimo_sale_multiple_supply_methods.product_template_embryo_customer_provided').sudo()
# 创建坯料客供料的批量不需要创建bom
material_customer_provided_embryo = self.env['product.template'].sudo().no_bom_product_create(
customer_provided_embryo.with_context(active_test=False).product_variant_id,
item,
order_id, 'material_customer_provided', product_seria, product)
# 成品配置bom
product_bom_material_customer_provided = self.env['mrp.bom'].with_user(
self.env.ref("base.user_admin")).bom_create(
product, bom_type, 'product')
product_bom_material_customer_provided.with_user(self.env.ref("base.user_admin")).bom_create_line_has(
material_customer_provided_embryo)
elif line.product_id.materials_type_id.gain_way == '自加工':
self_machining_id = self.env.ref('sf_dlm.product_embryo_sf_self_machining').sudo()
# 创建坯料
self_machining_embryo = self.env['product.template'].sudo().no_bom_product_create(
self_machining_id,
item,
order_id, 'self_machining', product_seria, product)
# 创建坯料的bom
self_machining_bom = self.env['mrp.bom'].with_user(
self.env.ref("base.user_admin")).bom_create(
self_machining_embryo, 'normal', False)
# 创建坯料里bom的组件
self_machining_bom_line = self_machining_bom.with_user(
self.env.ref("base.user_admin")).bom_create_line(
self_machining_embryo)
if not self_machining_bom_line:
raise UserError('该订单模型的材料型号暂未有原材料,请先配置再进行分配')
# 产品配置bom
product_bom_self_machining = self.env['mrp.bom'].with_user(
self.env.ref("base.user_admin")).bom_create(
product, bom_type, 'product')
product_bom_self_machining.with_user(self.env.ref("base.user_admin")).bom_create_line_has(
self_machining_embryo)
elif line.product_id.materials_type_id.gain_way == '外协':
outsource_id = self.env.ref('sf_dlm.product_embryo_sf_outsource').sudo()
# 创建坯料
outsource_embryo = self.env['product.template'].sudo().no_bom_product_create(outsource_id,
item,
order_id,
'subcontract',
product_seria, product)
if outsource_embryo == -3:
raise UserError('该订单模型的材料型号暂未设置获取方式和供应商,请先配置再进行分配')
# 创建坯料的bom
outsource_bom = self.env['mrp.bom'].with_user(self.env.ref("base.user_admin")).bom_create(
outsource_embryo,
'subcontract', True)
# 创建坯料的bom的组件
outsource_bom_line = outsource_bom.with_user(
self.env.ref("base.user_admin")).bom_create_line(outsource_embryo)
if not outsource_bom_line:
raise UserError('该订单模型的材料型号暂未有原材料,请先配置再进行分配')
# 产品配置bom
product_bom_outsource = self.env['mrp.bom'].with_user(
self.env.ref("base.user_admin")).bom_create(product, bom_type, 'product')
product_bom_outsource.with_user(self.env.ref("base.user_admin")).bom_create_line_has(
outsource_embryo)
elif line.product_id.materials_type_id.gain_way == '采购':
purchase_id = self.env.ref('sf_dlm.product_embryo_sf_purchase').sudo()
purchase_embryo = self.env['product.template'].sudo().no_bom_product_create(purchase_id,
item,
order_id,
'purchase', product_seria,
product)
if purchase_embryo == -3:
raise UserError('该订单模型的材料型号暂未设置获取方式和供应商,请先配置再进行分配')
else:
# 产品配置bom
product_bom_purchase = self.env['mrp.bom'].with_user(
self.env.ref("base.user_admin")).bom_create(product, bom_type, 'product')
product_bom_purchase.with_user(self.env.ref("base.user_admin")).bom_create_line_has(
purchase_embryo)
return super(SaleOrder, self).action_confirm()
class SaleOrderLine(models.Model):
_inherit = 'sale.order.line'
# 供货方式
supply_method = fields.Selection([
('automation', "自动化产线加工"),
('manual', "人工线下加工"),
('purchase', "外购"),
('outsourcing', "委外加工"),
], string='供货方式')
def write(self, vals):
if 'supply_method' in vals:
for line in self:
if vals['supply_method'] == 'automation' and line.manual_quotation:
raise UserError('当前(%s)产品为人工编程产品,不能选择自动化产线加工' % ','.join(line.mapped('product_id.name')))
return super(SaleOrderLine, self).write(vals)

View File

@@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
import logging
from odoo import fields, models, api
from odoo.exceptions import UserError
class SfProductionProcessParameter(models.Model):
_inherit = 'sf.production.process.parameter'
@api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
if self._context.get('route_id'):
parameter = []
routing = self.env['mrp.routing.workcenter'].search([('id', '=', self._context.get('route_id'))])
technology_design = self.env['sf.technology.design'].search(
[('production_id', '=', self._context.get('production_id')), ('routing_tag', '=', 'special'),
('route_id', '=', self._context.get('route_id'))])
for t in technology_design:
if t.process_parameters_id:
parameter.append(t.process_parameters_id.id)
domain = [('process_id', '=', routing.surface_technics_id.id), ('id', 'not in', parameter)]
return self._search(domain, limit=limit, access_rights_uid=name_get_uid)
return super()._name_search(name, args, operator, limit, name_get_uid)

View File

@@ -0,0 +1,40 @@
# -*- coding: utf-8 -*-
from odoo import fields, models, api, _
from odoo.exceptions import ValidationError
class sf_technology_design(models.Model):
_name = 'sf.technology.design'
_description = "工艺设计"
sequence = fields.Integer('序号')
route_id = fields.Many2one('mrp.routing.workcenter', '工序')
process_parameters_id = fields.Many2one('sf.production.process.parameter', string='表面工艺参数')
panel = fields.Char('加工面')
routing_tag = fields.Selection(related='route_id.routing_tag', string='标签', store=True)
time_cycle_manual = fields.Float(related='route_id.time_cycle_manual', string='预计时长')
production_id = fields.Many2one('mrp.production')
is_auto = fields.Boolean('是否自动生成', default=False)
active = fields.Boolean('有效', default=True)
def json_technology_design_str(self, k, route, i, process_parameter):
workorders_values_str = [0, '', {
'route_id': route.id if route.routing_type in ['表面工艺'] else route.route_workcenter_id.id,
'panel': k,
'process_parameters_id': False if route.routing_type != '表面工艺' else self.env[
'sf.production.process.parameter'].search(
[('id', '=', process_parameter.id)]).id,
'sequence': i,
'is_auto': True}]
return workorders_values_str
def unlink_technology_design(self):
self.active = False
@api.model_create_multi
def create(self, vals_list):
for vals in vals_list:
if not vals.get('route_id'):
raise ValidationError(_("工序不能为空"))
return super(sf_technology_design, self).create(vals_list)

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)
@@ -203,6 +208,15 @@ class StockRule(models.Model):
'''创建制造订单'''
productions = self.env['mrp.production'].with_user(SUPERUSER_ID).sudo().with_company(company_id).create(
productions_values)
# 将这一批制造订单的采购组根据成品设置为不同的采购组
product_group_id = {}
for index, production in enumerate(productions):
if production.product_id.id not in product_group_id.keys():
product_group_id[production.product_id.id] = production.procurement_group_id.id
else:
productions_values[index].update({'name': production.name})
procurement_group_vals = production._prepare_procurement_group_vals(productions_values[index])
production.procurement_group_id = self.env["procurement.group"].create(procurement_group_vals).id
# self.env['stock.move'].sudo().create(productions._get_moves_raw_values())
# self.env['stock.move'].sudo().create(productions._get_moves_finished_values())
@@ -267,27 +281,26 @@ 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})
# 如果订单为空,则获取来源制造订单的销售
if not sale_order:
mrp_production = self.env['mrp.production'].sudo().search([('name', '=', production.origin)],
limit=1)
if mrp_production:
sale_order = self.env['sale.order'].sudo().search([('name', '=', mrp_production.origin)])
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({
'name': production.name,
'order_deadline': sale_order.deadline_of_delivery,
'production_id': production.id,
'date_planned_start': production.date_planned_start,
'origin': production.origin,
'product_qty': production.product_qty,
'product_id': production.product_id.id,
'state': 'draft',
})
mrp_production = production
# if sale_order:
# sale_order.write({'schedule_status': 'to schedule'})
self.env['sf.production.plan'].sudo().with_company(company_id).create({
'name': production.name,
'order_deadline': sale_order.deadline_of_delivery,
'production_id': production.id,
'date_planned_start': production.date_planned_start,
'origin': mrp_production.origin,
'product_qty': production.product_qty,
'product_id': production.product_id.id,
'state': 'draft',
})
all_production = productions
grouped_product_ids = {k: list(g) for k, g in groupby(all_production, key=lambda x: x.product_id.id)}
# 初始化一个字典来存储每个product_id对应的生产订单名称列表
@@ -297,78 +310,86 @@ class StockRule(models.Model):
# 为同一个product_id创建一个生产订单名称列表
product_id_to_production_names[product_id] = [production.name for production in all_production]
for production_item in productions:
technology_design_values = []
production_programming = self.env['mrp.production'].search(
[('product_id.id', '=', production_item.product_id.id),
('origin', '=', production_item.origin)],
limit=1, order='id asc')
if production_item.product_id.id in product_id_to_production_names:
if not production_programming.programming_no:
if production_item.product_id.model_process_parameters_ids:
is_purchase = False
sorted_process_parameters = sorted(production_item.product_id.model_process_parameters_ids,
key=lambda w: w.id)
consecutive_process_parameters = []
m = 0
for i in range(len(sorted_process_parameters) - 1):
if m == 0:
is_purchase = False
if self.env['product.template']._get_process_parameters_product(
sorted_process_parameters[i]).partner_id == self.env[
'product.template']._get_process_parameters_product(sorted_process_parameters[
i + 1]).partner_id and \
sorted_process_parameters[i].gain_way == '外协':
if sorted_process_parameters[i] not in consecutive_process_parameters:
consecutive_process_parameters.append(sorted_process_parameters[i])
consecutive_process_parameters.append(sorted_process_parameters[i + 1])
m += 1
continue
else:
if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if sorted_process_parameters[i] in consecutive_process_parameters:
is_purchase = True
consecutive_process_parameters = []
m = 0
# 当前面的连续外协采购单生成再生成当前外协采购单
if is_purchase is False:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if sorted_process_parameters[i] in consecutive_process_parameters:
is_purchase = True
consecutive_process_parameters = []
m = 0
if m == len(consecutive_process_parameters) - 1 and m != 0:
self.env['purchase.order'].get_purchase_order(consecutive_process_parameters,
production_item,
product_id_to_production_names)
if is_purchase is False and m == 0:
if len(sorted_process_parameters) == 1:
self.env['purchase.order'].get_purchase_order(sorted_process_parameters,
production_item,
product_id_to_production_names)
else:
self.env['purchase.order'].get_purchase_order(sorted_process_parameters[i],
production_item,
product_id_to_production_names)
# # 同一个产品多个制造订单对应一个编程单和模型库
# # 只调用一次fetchCNC并将所有生产订单的名称作为字符串传递
if not production_item.programming_no:
# 同一个产品多个制造订单对应一个编程单和模型库
# 只调用一次fetchCNC并将所有生产订单的名称作为字符串传递
if not production_item.programming_no and production_item.production_type == '自动化产线加工':
if not production_programming.programming_no:
production_item.fetchCNC(
', '.join(product_id_to_production_names[production_item.product_id.id]))
else:
production_item.write({'programming_no': production_programming.programming_no,
'programming_state': '编程中'})
return True
i = 0
if production_item.product_id.categ_id.type == '成品':
# 根据加工面板的面数及成品工序模板生成工序设计
if production_item.production_type == '自动化产线加工':
model = 'sf.product.model.type.routing.sort'
domain = [
('product_model_type_id', '=', production_item.product_id.product_model_type_id.id)]
else:
model = 'sf.manual.product.model.type.routing.sort'
domain = [('manual_product_model_type_id', '=',
production_item.product_id.product_model_type_id.id)]
product_routing_workcenter = self.env[model].search(domain, order='sequence asc')
if production_item.production_type == '自动化产线加工':
for k in (production_item.product_id.model_processing_panel.split(',')):
for route in product_routing_workcenter:
i += 1
technology_design_values.append(
self.env['sf.technology.design'].json_technology_design_str(k, route, i, False))
else:
for route in product_routing_workcenter:
i += 1
technology_design_values.append(
self.env['sf.technology.design'].json_technology_design_str(False, route, i, False))
elif production_item.product_id.categ_id.type == '坯料':
embryo_routing_workcenter = self.env['sf.embryo.model.type.routing.sort'].search(
[('embryo_model_type_id', '=', production_item.product_id.embryo_model_type_id.id)],
order='sequence asc'
)
for route_embryo in embryo_routing_workcenter:
i += 1
technology_design_values.append(
self.env['sf.technology.design'].json_technology_design_str(False, route_embryo, i,
False))
surface_technics_arr = []
route_workcenter_arr = []
for item in production_item.product_id.product_model_type_id.surface_technics_routing_tmpl_ids:
if item.route_workcenter_id.surface_technics_id.id:
for process_param in production_item.product_id.model_process_parameters_ids:
if item.route_workcenter_id.surface_technics_id == process_param.process_id:
surface_technics_arr.append(
item.route_workcenter_id.surface_technics_id.id)
route_workcenter_arr.append(item.route_workcenter_id.id)
if surface_technics_arr:
production_process = self.env['sf.production.process'].search(
[('id', 'in', surface_technics_arr)],
order='sequence asc'
)
for p in production_process:
logging.info('production_process:%s' % p.name)
process_parameter = production_item.product_id.model_process_parameters_ids.filtered(
lambda pm: pm.process_id.id == p.id)
if process_parameter:
i += 1
route_production_process = self.env[
'mrp.routing.workcenter'].search(
[('surface_technics_id', '=', p.id),
('id', 'in', route_workcenter_arr)])
technology_design_values.append(
self.env['sf.technology.design'].json_technology_design_str(False,
route_production_process,
i,
process_parameter))
production_item.technology_design_ids = technology_design_values
productions.write({'state': 'technology_to_confirmed'})
return True
class ProductionLot(models.Model):
@@ -402,6 +423,8 @@ class ProductionLot(models.Model):
"""Generate `lot_names` from a string."""
if first_lot.__contains__(display_name):
first_lot = first_lot[(len(display_name) + 1):]
else:
first_lot = first_lot[-3:]
# We look if the first lot contains at least one digit.
caught_initial_number = regex_findall(r"\d+", first_lot)
@@ -456,6 +479,14 @@ class ProductionLot(models.Model):
if product.categ_id.name == '刀具':
return self.env['stock.lot'].get_tool_generate_lot_names1(company, product)
else:
# 对last_serial的name进行检测如果不是以产品名称+数字的形式的就重新搜索
if product.name.split('[')[0] not in last_serial.name:
last_serial = self.env['stock.lot'].search(
[('company_id', '=', company.id), ('product_id', '=', product.id),
('name', 'ilike', product.name.split('[')[0])],
limit=1, order='name desc')
if not last_serial:
return "%s-%03d" % (product.name, 1)
return self.env['stock.lot'].generate_lot_names1(product.name, last_serial.name, 2)[1]
now = datetime.now().strftime("%Y%m%d")
if product.cutting_tool_model_id:
@@ -552,6 +583,45 @@ class StockPicking(models.Model):
_inherit = 'stock.picking'
surface_technics_parameters_id = fields.Many2one('sf.production.process.parameter', string="表面工艺可选参数")
person_of_delivery = fields.Char('收货人', compute='_compute_move_ids', store=True)
telephone_of_delivery = fields.Char('电话号码', compute='_compute_move_ids', store=True)
address_of_delivery = fields.Char('联系地址', compute='_compute_move_ids', store=True)
retrospect_ref = fields.Char('追溯参考', compute='_compute_move_ids', store=True)
picking_type_sequence_code = fields.Char(related='picking_type_id.sequence_code')
@api.depends('move_ids', 'move_ids.product_id')
def _compute_move_ids(self):
for item in self:
if item.move_ids:
if item.picking_type_id.sequence_code == 'DL':
sale_name = item.move_ids[0].product_id.name.split('-')[1]
if 'S' in sale_name:
sale_id = self.env['sale.order'].sudo().search([('name', '=', sale_name)])
item.person_of_delivery = sale_id.person_of_delivery
item.telephone_of_delivery = sale_id.telephone_of_delivery
item.address_of_delivery = sale_id.address_of_delivery
else:
raise ValidationError('坯料名称格式错误,正确格式为[R-S???-?]')
move_ids = []
for move_id in item.move_ids:
move_ids.append(move_id.product_id.id)
boms = self.env['mrp.bom'].sudo().search([('bom_line_ids.product_id', 'in', move_ids)])
if boms:
codes_list = []
for bom in boms:
if bom.product_tmpl_id.default_code:
code_list = bom.product_tmpl_id.default_code.split('-')
if len(code_list) >= 4:
code = '-'.join(code_list[:4])
if code not in codes_list:
codes_list.append(code)
else:
raise ValidationError('坯料成品的内部参考值格式错误')
item.retrospect_ref = ','.join(codes_list)
elif item.picking_type_id.sequence_code in ['INT', 'PC']:
pass
# 设置外协出入单的名称
def _get_name_Res(self, rescode):
@@ -565,84 +635,79 @@ class StockPicking(models.Model):
return '%s%s' % (rescode, num)
def button_validate(self):
move_out = self.env['stock.move'].search(
[('location_id', '=', self.env['stock.location'].search(
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
('location_dest_id', '=', self.env['stock.location'].search(
[('barcode', 'ilike', 'VL-SPOC')]).id),
('origin', '=', self.origin)])
# if self.id == move_out.picking_id.id:
# if move_out.move_line_ids.workorder_id.state not in ['progress']:
# raise UserError(
# _('该出库单里源单据内的单号为%s的工单还未开始不能进行验证操作' % move_out.move_line_ids.workorder_id.name))
# 入库单验证
move_in = self.env['stock.move'].search(
[('location_dest_id', '=', self.env['stock.location'].search(
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
('location_id', '=', self.env['stock.location'].search(
[('barcode', 'ilike', 'VL-SPOC')]).id),
('origin', '=', self.origin), ('picking_id', '=', self.id)])
if self.location_id == move_in.location_id and self.location_dest_id == move_in.location_dest_id:
if move_out.origin == move_in.origin:
move_in.write({'production_id': False})
if move_out.picking_id.state != 'done':
raise UserError(
_('该入库单对应的单号为%s的出库单还未完成,不能进行验证操作!' % move_out.picking_id.name))
res = super().button_validate()
if res is True:
if self.id == move_out.picking_id.id:
# if move_out.move_line_ids.workorder_id.state == 'progress':
move_in = self.env['stock.move'].search(
[('location_dest_id', '=', self.env['stock.location'].search(
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id),
('location_id', '=', self.env['stock.location'].search(
[('barcode', 'ilike', 'VL-SPOC')]).id),
('origin', '=', self.origin)])
production = self.env['mrp.production'].search([('name', '=', self.origin)])
if move_in.state != 'done':
move_in.write({'state': 'assigned'})
self.env['stock.move.line'].create(move_in.get_move_line(production, None))
picking_type_in = self.env.ref('sf_manufacturing.outcontract_picking_in').id
if res is True and self.picking_type_id.id == picking_type_in:
# 如果是最后一张外协入库单,则设置库存位置的预留数量
move_in = self.move_ids
if move_in:
workorder = move_in.subcontract_workorder_id
workorders = workorder.production_id.workorder_ids
subcontract_workorders = workorders.filtered(lambda wo: wo.is_subcontract == True).sorted('sequence')
if workorder == subcontract_workorders[-1]:
self.env['stock.quant']._update_reserved_quantity(
move_in.product_id, move_in.location_dest_id, move_in.product_uom_qty, lot_id=move_in.move_line_ids.lot_id,
package_id=False, owner_id=False, strict=False
)
return res
# 创建 外协出库入单
def create_outcontract_picking(self, sorted_workorders_arr, item):
m = 0
for sorted_workorders in sorted_workorders_arr:
# pick_ids = []
if m == 0:
outcontract_stock_move = self.env['stock.move'].search(
[('workorder_id', '=', sorted_workorders.id), ('production_id', '=', item.id)])
if not outcontract_stock_move:
new_picking = True
location_id = self.env['stock.location'].search(
[('barcode', 'ilike', 'VL-SPOC')]).id,
location_dest_id = self.env['stock.location'].search(
[('barcode', 'ilike', 'WH-PREPRODUCTION')]).id,
outcontract_picking_type_in = self.env.ref(
'sf_manufacturing.outcontract_picking_in').id,
outcontract_picking_type_out = self.env.ref(
'sf_manufacturing.outcontract_picking_out').id,
moves_out = self.env['stock.move'].sudo().create(
self.env['stock.move']._get_stock_move_values_Res(item, location_dest_id, location_id,
outcontract_picking_type_out))
picking_out = self.create(
moves_out._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCOUT/'))
# pick_ids.append(picking_out.id)
moves_out.write(
{'picking_id': picking_out.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id})
moves_out._assign_picking_post_process(new=new_picking)
moves_in = self.env['stock.move'].sudo().create(
self.env['stock.move']._get_stock_move_values_Res(item, location_id, location_dest_id,
outcontract_picking_type_in))
picking_in = self.create(
moves_in._get_new_picking_values_Res(item, sorted_workorders, 'WH/OCIN/'))
# pick_ids.append(picking_in.id)
moves_in.write(
{'picking_id': picking_in.id, 'state': 'waiting', 'workorder_id': sorted_workorders.id})
moves_in._assign_picking_post_process(new=new_picking)
m += 1
# sorted_workorders.write({'picking_ids': [(6, 0, pick_ids)]})
def create_outcontract_picking(self, workorders, item, sorted_workorders):
for workorder in workorders:
if workorder.move_subcontract_workorder_ids:
workorder.move_subcontract_workorder_ids.write({'state': 'draft'})
workorder.move_subcontract_workorder_ids.picking_id.write({'state': 'draft'})
else:
# 创建一个新的补货组
procurement_group_id = self.env['procurement.group'].create({
'name': workorder.name,
'partner_id': self.partner_id.id,
})
move_dest_id = False
# 如果当前工单是是制造订单的最后一个工单
if workorder == item.workorder_ids[-1]:
move_dest_id = item.move_raw_ids[0].id
else:
# 从sorted_workorders中找到上一工单的move
if sorted_workorders.index(workorder) > 0:
move_dest_id = sorted_workorders[sorted_workorders.index(workorder) - 1].move_subcontract_workorder_ids[1].id
new_picking = True
outcontract_picking_type_in = self.env.ref(
'sf_manufacturing.outcontract_picking_in').id,
outcontract_picking_type_out = self.env.ref(
'sf_manufacturing.outcontract_picking_out').id,
moves_in = self.env['stock.move'].sudo().create(
self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_in, procurement_group_id.id, move_dest_id))
picking_in = self.create(
moves_in._get_new_picking_values_Res(item, workorder, 'WH/OCIN/'))
# pick_ids.append(picking_in.id)
moves_in.write(
{'picking_id': picking_in.id, 'state': 'waiting'})
moves_in._assign_picking_post_process(new=new_picking)
moves_out = self.env['stock.move'].sudo().create(
self.env['stock.move']._get_stock_move_values_Res(item, outcontract_picking_type_out, procurement_group_id.id, moves_in.id))
workorder.write({'move_subcontract_workorder_ids': [(6, 0, [moves_in.id, moves_out.id])]})
picking_out = self.create(
moves_out._get_new_picking_values_Res(item, workorder, 'WH/OCOUT/'))
# pick_ids.append(picking_out.id)
moves_out.write(
{'picking_id': picking_out.id, 'state': 'waiting'})
moves_out._assign_picking_post_process(new=new_picking)
@api.depends('move_type', 'immediate_transfer', 'move_ids.state', 'move_ids.picking_id')
def _compute_state(self):
super(StockPicking, self)._compute_state()
for picking in self:
# 外协出库单根据工单状态,采购单状态来确定
picking_type_id = self.env.ref('sf_manufacturing.outcontract_picking_out').id
if picking.picking_type_id.id == picking_type_id:
if picking.move_ids:
workorder = picking.move_ids[0].subcontract_workorder_id
if picking.state == 'assigned':
if workorder.state in ['pending', 'waiting'] or workorder._get_surface_technics_purchase_ids().state in ['draft', 'sent']:
picking.state = 'waiting'
class ReStockMove(models.Model):
@@ -652,17 +717,20 @@ class ReStockMove(models.Model):
materiel_width = fields.Float(string='物料宽度', digits=(16, 4))
materiel_height = fields.Float(string='物料高度', digits=(16, 4))
def _get_stock_move_values_Res(self, item, location_src_id, location_dest_id, picking_type_id):
route = self.env['stock.route'].sudo().search([('name', '=', '表面工艺外协')])
def _get_stock_move_values_Res(self, item, picking_type_id, group_id, move_dest_ids=False):
route_id = self.env.ref('sf_manufacturing.route_surface_technology_outsourcing').id
stock_rule = self.env['stock.rule'].sudo().search([('route_id', '=', route_id), ('picking_type_id', '=', picking_type_id)])
move_values = {
'name': '',
'company_id': item.company_id.id,
'product_id': item.bom_id.bom_line_ids.product_id.id,
'product_uom': item.bom_id.bom_line_ids.product_uom_id.id,
'product_uom_qty': 1.0,
'location_id': location_src_id,
'location_dest_id': location_dest_id,
'location_id': stock_rule.location_src_id.id,
'location_dest_id': stock_rule.location_dest_id.id,
'origin': item.name,
'group_id': group_id,
'move_dest_ids': [(6, 0, [move_dest_ids])] if move_dest_ids else False,
# 'route_ids': False if not route else [(4, route.id)],
'date_deadline': datetime.now(),
'picking_type_id': picking_type_id,
@@ -686,7 +754,7 @@ class ReStockMove(models.Model):
'picking_type_id': picking_type_id,
'location_id': self.mapped('location_id').id,
'location_dest_id': self.mapped('location_dest_id').id,
'state': 'confirmed',
'state': 'waiting',
}
def get_move_line(self, production_id, sorted_workorders):
@@ -699,7 +767,7 @@ class ReStockMove(models.Model):
'picking_id': self.picking_id.id,
'reserved_uom_qty': 1.0,
'lot_id': production_id.move_line_raw_ids.lot_id.id,
'company_id': self.company_id.id,
'company_id': self.env.company.id,
# 'workorder_id': '' if not sorted_workorders else sorted_workorders.id,
# 'production_id': '' if not sorted_workorders else sorted_workorders.production_id.id,
'state': 'assigned',
@@ -743,6 +811,8 @@ class ReStockMove(models.Model):
self.next_serial = self._get_tool_next_serial(self.company_id, self.product_id, self.origin)
else:
self.next_serial = self.env['stock.lot']._get_next_serial(self.company_id, self.product_id)
if self.picking_type_id.sequence_code == 'DL' and not self.move_line_nosuggest_ids:
self.action_assign_serial_show_details()
elif self.product_id.tracking == "lot":
self._put_tool_lot(self.company_id, self.product_id, self.origin)
@@ -895,6 +965,40 @@ class ReStockMove(models.Model):
qty_by_location[loc.id] += 1
return move_lines_commands
def _merge_moves_fields(self):
"""
合并制造订单的完成move单据
"""
res = super(ReStockMove, self)._merge_moves_fields()
if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨', '生产入库', '客供料入库']:
production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc')
productions = self.env['mrp.production'].search(
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)])
res['origin'] = ','.join(productions.mapped('name'))
return res
def _get_new_picking_values(self):
"""
创建调拨单时,在此新增或修改调拨单的数据
"""
res = super(ReStockMove, self)._get_new_picking_values()
## 制造订单报废生成的新制造订单不走合并
production_remanufacture = None
if 'origin' in res:
if self.picking_type_id.name in ['生产发料', '内部调拨']:
production_remanufacture = self.env['mrp.production'].search(
[('name', '=', res['origin']), ('is_remanufacture', '=', True)])
if not production_remanufacture:
if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨']:
production = self.env['mrp.production'].search([('name', '=', self[0].origin)], limit=1, order='id asc')
productions = self.env['mrp.production'].search(
[('origin', '=', production.origin), ('product_id', '=', production.product_id.id)])
res['origin'] = ','.join(productions.mapped('name'))
res['retrospect_ref'] = production.product_id.name
return res
subcontract_workorder_id = fields.Many2one('mrp.workorder', '外协工单组件', check_company=True, index='btree_not_null')
class ReStockQuant(models.Model):
_inherit = 'stock.quant'

View File

@@ -1,5 +1,9 @@
<odoo>
<data>
<data noupdate="1">
<record id="group_show_button" model="res.groups">
<field name="name">演示模式</field>
<field name="category_id" ref="base.module_category_hidden"/>
</record>
</data>
</odoo>
</odoo>

View File

@@ -11,11 +11,11 @@ access_sf_model_type_group_sale_director,sf_model_type_group_sale_director,model
access_sf_model_type_group_purchase_director,sf_model_type_group_purchase_director,model_sf_model_type,sf_base.group_purchase_director,1,0,0,0
access_sf_model_type_group_plan_director,sf_model_type_group_plan_director,model_sf_model_type,sf_base.group_plan_director,1,0,0,0
access_sf_product_model_type_routing_sort_group_sf_mrp_user,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_product_model_type_routing_sort_manager,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_product_model_type_routing_sort_manager,sf_product_model_type_routing_sort,model_sf_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
access_sf_embryo_model_type_routing_sort_group_sf_mrp_user,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_embryo_model_type_routing_sort_manager,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_embryo_model_type_routing_sort_manager,sf_embryo_model_type_routing_sort,model_sf_embryo_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
access_sf_surface_technics_model_type_routing_sort,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_surface_technics_model_type_routing_sort_manager,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_surface_technics_model_type_routing_sort_manager,sf_surface_technics_model_type_routing_sort,model_sf_surface_technics_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
access_sf_production_line_group_sf_mrp_user,sf.production.line,model_sf_production_line,sf_base.group_sf_mrp_user,1,1,1,0
access_sf_production_line_manager,sf.production.line,model_sf_production_line,sf_base.group_sf_mrp_manager,1,1,1,0
access_maintenance_equipment_tool_group_sf_mrp_user,maintenance_equipment_tool,model_maintenance_equipment_tool,sf_base.group_sf_mrp_user,1,0,0,0
@@ -52,6 +52,7 @@ access_mrp_routing_workcenter_manager_group_sf_mrp_user,mrp.routing.workcenter.m
access_mrp_bom_manager_group_sf_mrp_user,mrp.bom.manager,mrp.model_mrp_bom,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_bom_line_manager_group_sf_mrp_user,mrp.bom.line.manager,mrp.model_mrp_bom_line,sf_base.group_sf_mrp_user,1,1,1,0
access_mrp_bom_line_group_plan_director,mrp_bom_line_group_plan_director,mrp.model_mrp_bom_line,sf_base.group_plan_director,1,1,1,0
access_mrp_bom_line_group_sf_stock_user,mrp_bom_line_group_sf_stock_user,mrp.model_mrp_bom_line,sf_base.group_sf_stock_user,1,1,1,0
access_mrp_bom_line_group_sale_director,mrp_bom_line_group_sale_director,mrp.model_mrp_bom_line,sf_base.group_sale_director,1,1,1,0
access_mrp_bom_line_group_sale_salemanager,mrp_bom_line_group_sale_salemanager,mrp.model_mrp_bom_line,sf_base.group_sale_salemanager,1,0,1,0
access_mrp_bom_line_group_purchase_director,mrp_bom_line_group_purchase_director,mrp.model_mrp_bom_line,sf_base.group_purchase_director,1,1,1,0
@@ -116,7 +117,7 @@ access_mrp_production_group_quality,mrp_production,model_mrp_production,sf_base.
access_mrp_production_group_quality_director,mrp_production,model_mrp_production,sf_base.group_quality_director,1,1,0,0
access_mrp_workorder_group_quality,mrp_workorder,model_mrp_workorder,sf_base.group_quality,1,1,0,0
access_mrp_workorder_group_quality_director,mrp_workorder,model_mrp_workorder,sf_base.group_quality_director,1,1,0,0
access_mrp_workorder,mrp_workorder,model_mrp_workorder,sf_base.group_plan_dispatch,1,1,0,0
access_mrp_workorder,mrp_workorder,model_mrp_workorder,sf_base.group_plan_dispatch,1,1,1,0
access_sf_production_line_group_plan_dispatch,sf.production.line,model_sf_production_line,sf_base.group_plan_dispatch,1,0,0,0
access_sf_production_line_group_plan_director,sf.production.line,model_sf_production_line,sf_base.group_plan_director,1,1,1,0
access_sf_production_line,sf.production.line,model_sf_production_line,sf_maintenance.sf_group_equipment_user,1,1,1,0
@@ -165,7 +166,19 @@ access_sf_agv_scheduling_group_sf_order_user,sf_agv_scheduling_group_sf_order_us
access_sf_agv_scheduling_group_sf_mrp_manager,sf_agv_scheduling_group_sf_mrp_manager,model_sf_agv_scheduling,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_agv_scheduling_group_sf_equipment_user,sf_agv_scheduling_group_sf_equipment_user,model_sf_agv_scheduling,sf_base.group_sf_equipment_user,1,1,1,0
access_sf_technology_design_group_plan_dispatch,sf_technology_design_group_plan_dispatch,model_sf_technology_design,sf_base.group_plan_dispatch,1,1,1,0
access_sf_technology_design_group_sf_mrp_manager,sf_technology_design_group_sf_mrp_manager,model_sf_technology_design,sf_base.group_sf_mrp_manager,1,0,0,0
access_sf_technology_design_group_production_engineer,sf_technology_design_group_production_engineer,model_sf_technology_design,sf_base.group_production_engineer,1,1,1,0
access_sf_technology_design_group_sf_equipment_user,sf_technology_design_group_sf_equipment_user,model_sf_technology_design,sf_base.group_sf_equipment_user,1,0,0,0
access_sf_technology_design_group_sf_order_user,sf_technology_design_group_sf_order_user,model_sf_technology_design,sf_base.group_sf_order_user,1,0,0,0
access_sf_production_technology_wizard_group_plan_dispatch,sf_production_technology_wizard_group_plan_dispatch,model_sf_production_technology_wizard,sf_base.group_plan_dispatch,1,1,1,0
access_sf_production_technology_wizard_group_sf_mrp_manager,sf_production_technology_wizard_group_sf_mrp_manager,model_sf_production_technology_wizard,sf_base.group_sf_mrp_manager,1,0,0,0
access_sf_production_technology_wizard_group_production_engineer,sf_production_technology_wizard_group_production_engineer,model_sf_production_technology_wizard,sf_base.group_production_engineer,1,1,1,0
access_sf_production_technology_re_adjust_wizard_group_plan_dispatch,sf_production_technology_re_adjust_wizard_group_plan_dispatch,model_sf_production_technology_re_adjust_wizard,sf_base.group_plan_dispatch,1,1,1,0
access_sf_production_technology_re_adjust_wizard_group_sf_mrp_manager,sf_production_technology_re_adjust_wizard_group_sf_mrp_manager,model_sf_production_technology_re_adjust_wizard,sf_base.group_sf_mrp_manager,1,1,1,0
access_sf_production_technology_re_adjust_wizard_group_production_engineer,sf_production_technology_re_adjust_wizard_group_production_engineer,model_sf_production_technology_re_adjust_wizard,sf_base.group_production_engineer,1,1,1,0
access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_user,1,0,0,0
access_sf_manual_product_model_type_routing_sort_manager,sf_manual_product_model_type_routing_sort,model_sf_manual_product_model_type_routing_sort,sf_base.group_sf_mrp_manager,1,1,1,1
access_sf_manual_product_model_type_routing_sort_group_plan_dispatch,sf_manual_product_model_type_routing_sort_group_plan_dispatch,model_sf_manual_product_model_type_routing_sort,sf_base.group_plan_dispatch,1,0,0,0
access_sf_detection_result_manager,sf_detection_result_manager,model_sf_detection_result,,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
11 access_sf_model_type_group_purchase_director sf_model_type_group_purchase_director model_sf_model_type sf_base.group_purchase_director 1 0 0 0
12 access_sf_model_type_group_plan_director sf_model_type_group_plan_director model_sf_model_type sf_base.group_plan_director 1 0 0 0
13 access_sf_product_model_type_routing_sort_group_sf_mrp_user sf_product_model_type_routing_sort model_sf_product_model_type_routing_sort sf_base.group_sf_mrp_user 1 0 0 0
14 access_sf_product_model_type_routing_sort_manager sf_product_model_type_routing_sort model_sf_product_model_type_routing_sort sf_base.group_sf_mrp_manager 1 1 1 0 1
15 access_sf_embryo_model_type_routing_sort_group_sf_mrp_user sf_embryo_model_type_routing_sort model_sf_embryo_model_type_routing_sort sf_base.group_sf_mrp_user 1 0 0 0
16 access_sf_embryo_model_type_routing_sort_manager sf_embryo_model_type_routing_sort model_sf_embryo_model_type_routing_sort sf_base.group_sf_mrp_manager 1 1 1 0 1
17 access_sf_surface_technics_model_type_routing_sort sf_surface_technics_model_type_routing_sort model_sf_surface_technics_model_type_routing_sort sf_base.group_sf_mrp_user 1 0 0 0
18 access_sf_surface_technics_model_type_routing_sort_manager sf_surface_technics_model_type_routing_sort model_sf_surface_technics_model_type_routing_sort sf_base.group_sf_mrp_manager 1 1 1 0 1
19 access_sf_production_line_group_sf_mrp_user sf.production.line model_sf_production_line sf_base.group_sf_mrp_user 1 1 1 0
20 access_sf_production_line_manager sf.production.line model_sf_production_line sf_base.group_sf_mrp_manager 1 1 1 0
21 access_maintenance_equipment_tool_group_sf_mrp_user maintenance_equipment_tool model_maintenance_equipment_tool sf_base.group_sf_mrp_user 1 0 0 0
52 access_mrp_bom_line_manager_group_sf_mrp_user mrp.bom.line.manager mrp.model_mrp_bom_line sf_base.group_sf_mrp_user 1 1 1 0
53 access_mrp_bom_line_group_plan_director mrp_bom_line_group_plan_director mrp.model_mrp_bom_line sf_base.group_plan_director 1 1 1 0
54 access_mrp_bom_line_group_sale_director access_mrp_bom_line_group_sf_stock_user mrp_bom_line_group_sale_director mrp_bom_line_group_sf_stock_user mrp.model_mrp_bom_line sf_base.group_sale_director sf_base.group_sf_stock_user 1 1 1 0
55 access_mrp_bom_line_group_sale_director mrp_bom_line_group_sale_director mrp.model_mrp_bom_line sf_base.group_sale_director 1 1 1 0
56 access_mrp_bom_line_group_sale_salemanager mrp_bom_line_group_sale_salemanager mrp.model_mrp_bom_line sf_base.group_sale_salemanager 1 0 1 0
57 access_mrp_bom_line_group_purchase_director mrp_bom_line_group_purchase_director mrp.model_mrp_bom_line sf_base.group_purchase_director 1 1 1 0
58 access_mrp_bom_byproduct_manager_group_sf_mrp_user mrp.bom.byproduct manager mrp.model_mrp_bom_byproduct sf_base.group_sf_mrp_user 1 1 1 0
117 access_mrp_workorder_group_quality mrp_workorder model_mrp_workorder sf_base.group_quality 1 1 0 0
118 access_mrp_workorder_group_quality_director mrp_workorder model_mrp_workorder sf_base.group_quality_director 1 1 0 0
119 access_mrp_workorder mrp_workorder model_mrp_workorder sf_base.group_plan_dispatch 1 1 0 1 0
120 access_sf_production_line_group_plan_dispatch sf.production.line model_sf_production_line sf_base.group_plan_dispatch 1 0 0 0
121 access_sf_production_line_group_plan_director sf.production.line model_sf_production_line sf_base.group_plan_director 1 1 1 0
122 access_sf_production_line sf.production.line model_sf_production_line sf_maintenance.sf_group_equipment_user 1 1 1 0
123 access_mrp_workcenter mrp_workcenter model_mrp_workcenter sf_base.group_plan_dispatch 1 1 1 0
166 access_sf_production_technology_wizard_group_production_engineer sf_production_technology_wizard_group_production_engineer model_sf_production_technology_wizard sf_base.group_production_engineer 1 1 1 0
167 access_sf_production_technology_re_adjust_wizard_group_plan_dispatch sf_production_technology_re_adjust_wizard_group_plan_dispatch model_sf_production_technology_re_adjust_wizard sf_base.group_plan_dispatch 1 1 1 0
168 access_sf_production_technology_re_adjust_wizard_group_sf_mrp_manager sf_production_technology_re_adjust_wizard_group_sf_mrp_manager model_sf_production_technology_re_adjust_wizard sf_base.group_sf_mrp_manager 1 1 1 0
169 access_sf_production_technology_re_adjust_wizard_group_production_engineer sf_production_technology_re_adjust_wizard_group_production_engineer model_sf_production_technology_re_adjust_wizard sf_base.group_production_engineer 1 1 1 0
170 access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user sf_manual_product_model_type_routing_sort model_sf_manual_product_model_type_routing_sort sf_base.group_sf_mrp_user 1 0 0 0
171 access_sf_manual_product_model_type_routing_sort_manager sf_manual_product_model_type_routing_sort model_sf_manual_product_model_type_routing_sort sf_base.group_sf_mrp_manager 1 1 1 1
172 access_sf_manual_product_model_type_routing_sort_group_plan_dispatch sf_manual_product_model_type_routing_sort_group_plan_dispatch model_sf_manual_product_model_type_routing_sort sf_base.group_plan_dispatch 1 0 0 0
173 access_sf_detection_result_manager sf_detection_result_manager model_sf_detection_result 1 1 1 1
174
175
176
177
178
179
180
181
182
183
184

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

@@ -31,7 +31,7 @@
<form string="模型类型">
<group>
<field name="name" required="1"/>
<field name="embryo_tolerance" required="1" string="坯料容余(mm)"/>
<field name="embryo_tolerance_id" required="1"/>
</group>
<group>
<field name='product_routing_tmpl_ids'>
@@ -44,6 +44,17 @@
</tree>
</field>
</group>
<group>
<field name='manual_product_routing_tmpl_ids'>
<tree editable='bottom'>
<field name="sequence" widget="handle" string="序号"/>
<field name="route_workcenter_id" string="工序" options="{'no_create': True}"/>
<field name="routing_type" string="类型"/>
<field name="is_repeat" string="重复"/>
<field name="workcenter_ids" string="工作中心" widget="many2many_tags"/>
</tree>
</field>
</group>
<group>
<field name='embryo_routing_tmpl_ids'>
<tree editable='bottom'>

View File

@@ -35,9 +35,10 @@
<field name="reservation_state" optional="hide" decoration-danger="reservation_state == 'confirmed'"
decoration-success="reservation_state == 'assigned'"/>
</xpath>
<!-- <xpath expr="//field[@name='state']" position="before"> -->
<!-- <field name="schedule_state" optional="show"/> -->
<!-- </xpath> -->
<xpath expr="//field[@name='state']" position="before">
<field name="production_type" widget="badge" decoration-warning="production_type == '人工线下加工'"
decoration-success="production_type == '自动化产线加工'" optional="show"/>
</xpath>
<xpath expr="//field[@name='activity_ids']" position="replace">
<field name="activity_ids" string="下一个活动" widget="list_activity" optional="hide"/>
</xpath>
@@ -56,6 +57,16 @@
<!-- <button name="action_view_production_schedule" string="生产排程" type="object" attrs="{'invisible': [('state', 'in', ['draft', 'cancel','已排程','progress','done','to_close'])]}"/> -->
<!-- <button name="cancel_plan" string="取消排程" type="object" attrs="{'invisible': [('state', 'in', ['draft', 'cancel','progress','done','to_close','confirmed'])]}"/> -->
<!-- </xpath> -->
<xpath expr="//field[@name='production_real_duration']" position="before">
<field name="delivery_status" optional="show" widget="badge"
decoration-success="delivery_status == '正常'"
decoration-warning="delivery_status == '预警'"
decoration-danger="delivery_status == '已逾期'"/>
</xpath>
<xpath expr="//field[@name='production_real_duration']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
</field>
</record>
@@ -70,9 +81,15 @@
<!-- <attribute name="statusbar_visible">draft,confirmed,progress,pending_processing,completed,done -->
<!-- </attribute> -->
<attribute name="statusbar_visible">
confirmed,pending_cam,progress,rework,scrap,done
technology_to_confirmed,confirmed,pending_cam,progress,rework,scrap,done
</attribute>
</xpath>
<xpath expr="//div[@class='d-flex flex-row align-items-start']//span[1]" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//button[@name='action_product_forecast_report']" position="attributes">
<attribute name="invisible">1</attribute>
</xpath>
<xpath expr="//sheet//group//group[2]//label" position="before">
<!-- <field name="process_state"/> -->
<field name="state" readonly="1"/>
@@ -80,9 +97,13 @@
</xpath>
<xpath expr="//sheet//group//group//div[3]" position="after">
<field name="manual_quotation" readonly="1"/>
<field name="programming_no" readonly="1"/>
<field name="production_type" readonly="1"/>
<field name="manual_quotation" readonly="1"
attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/>
<field name="programming_no" readonly="1"
attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/>
<field name="programming_state" readonly="1"
attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"
decoration-success="programming_state == '已编程'"
decoration-warning="programming_state =='编程中'"
decoration-danger="programming_state =='已编程未下发'"/>
@@ -97,10 +118,10 @@
<xpath expr="//field[@name='user_id']" position="after">
<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="part_name"/>
<field name="part_number" string="零件图号"/>
<field name="tool_state"
attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/>
<field name="tool_state_remark" string="备注" attrs="{'invisible': [('tool_state', '!=', '1')]}"/>
<field name="deadline_of_delivery" readonly="1"/>
<field name="tool_state_remark2" invisible="1"/>
@@ -124,6 +145,10 @@
groups="sf_base.group_sf_mrp_user"/>
</xpath>
<xpath expr="(//header//button[@name='button_scrap'])" position="replace">
<button name="technology_confirm" string="工艺确认" type="object" class="oe_highlight"
attrs="{'invisible': [('state', '!=', 'technology_to_confirmed')]}"></button>
<button name="technology_back_adjust" string="退回调整" type="object" class="oe_highlight"
attrs="{'invisible': [('state', '!=', 'confirmed')]}"></button>
<button name="button_scrap" invisible="1"/>
<button name="do_update_program" string="更新程序" type="object" groups="sf_base.group_sf_mrp_user"
confirm="是否确认更新程序"
@@ -293,8 +318,7 @@
</xpath>
<xpath expr="//sheet//notebook//page[@name='operations']" position="attributes">
<attribute name="attrs">{'invisible': ['|',('schedule_state', '=', '未排'),('workorder_ids', '=',
[])]}
<attribute name="attrs">{'invisible': [('workorder_ids', '=', [])]}
</attribute>
</xpath>
@@ -330,6 +354,54 @@
<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//page[@name='components']" position="before">
<page string="工艺设计" attrs="{'invisible': [('state', '!=', 'technology_to_confirmed')]}">
<field name="technology_design_ids" widget="one2many">
<tree editable="bottom">
<field name="sequence" widget="handle"/>
<field name="route_id" context="{'production_id': production_id}"
attrs="{'readonly': [('id', '!=', False)]}" options="{'no_create': True}"/>
<field name="process_parameters_id"
attrs="{'readonly': [('id', '!=', False),('routing_tag', '=', 'standard')]}"
string="参数" context="{'route_id':route_id,'production_id': production_id}"
options="{'no_create': True}"/>
<field name="panel" readonly="1"/>
<field name="routing_tag" readonly="1" widget="badge"
decoration-success="routing_tag == 'standard'"
decoration-warning="routing_tag == 'special'"/>
<field name="time_cycle_manual" attrs="{'readonly': [('id', '!=', False)]}"/>
<field name="is_auto" invisible="1"/>
<field name="production_id" invisible="1"/>
<button name="unlink_technology_design" confirm="是否确认删除?" class="oe_highlight"
attrs="{'invisible': [('is_auto', '=', True)]}" type="object"
string="删除"></button>
</tree>
</field>
</page>
</xpath>
<xpath expr="//sheet//notebook" position="inside">
<page string="质检标准">
<field name="quality_standard" widget="adaptive_viewer"/>
</page>
</xpath>
<xpath expr="//sheet/group/group/div[@class='d-flex flex-row align-items-start']/span[last()]"
position="attributes">
<attribute name="invisible">True</attribute>
</xpath>
<xpath expr="//sheet/group/group/div[@class='d-flex flex-row align-items-start']/button[@name='action_product_forecast_report']"
position="attributes">
<attribute name="invisible">True</attribute>
</xpath>
<xpath expr="//sheet/div[@class='oe_button_box']/button[@name='action_view_mrp_production_childs']/div/span[last()]"
position="replace">
<span class="o_stat_text">子MO</span>
</xpath>
</field>
</record>
@@ -509,8 +581,9 @@
<separator/>
</xpath>
<xpath expr="//search" position="inside">
<searchpanel class="account_root">
<searchpanel>
<field name="state" icon="fa-filter" enable_counters="1"/>
<field name="delivery_status" icon="fa-filter" enable_counters="1"/>
</searchpanel>
</xpath>
<filter name='todo' position="replace"/>
@@ -665,5 +738,19 @@
<!-- parent="mrp.menu_mrp_manufacturing"-->
<!-- sequence="1"/>-->
<menuitem id="mrp.menu_mrp_production_action"
name="制造订单"
parent="mrp.menu_mrp_manufacturing"
action="mrp.mrp_production_action"
groups="sf_base.group_plan_dispatch,sf_base.group_sf_mrp_manager"
sequence="1"/>
<menuitem id="stock_picking_type_menu"
name="驾驶舱"
parent="stock.menu_stock_root"
action="stock.stock_picking_type_action"
groups="sf_base.group_sf_stock_user"
sequence="0"/>
</data>
</odoo>

View File

@@ -16,6 +16,7 @@
</field>
<field name="bom_product_template_attribute_value_ids" position="after">
<field name="routing_type" required="1"/>
<field name="routing_tag" required="1" string="工序标签"/>
<field name="is_repeat"/>
<field name="reserved_duration"/>
</field>

View File

@@ -32,8 +32,11 @@
</field>
<xpath expr="//field[@name='qty_remaining']" position="after">
<field name="manual_quotation" optional="show"/>
<field name='tag_type' widget="badge"
decoration-danger="tag_type == '重新加工'"/>
<field name="tag_type" optional="show"/>
<field name="construction_period_status" optional="show" widget="badge"
decoration-success="construction_period_status == '正常'"
decoration-warning="construction_period_status == '预警'"
decoration-danger="construction_period_status == '已逾期'"/>
</xpath>
<xpath expr="//field[@name='date_planned_start']" position="replace">
<field name="date_planned_start" string="计划开始日期" optional="show"/>
@@ -102,7 +105,7 @@
<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}
active_id,'search_default_filter_order_warning':1,'search_default_filter_order_overdue':1,'search_default_filter_order_normal':1}
</field>
<field name="help" type="html">
<p class="o_view_nocontent_workorder">
@@ -125,9 +128,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"/>
@@ -136,7 +139,7 @@
<button type="object" name="action_view_surface_technics_purchase" class="oe_stat_button"
icon="fa-credit-card"
groups="base.group_user,sf_base.group_sf_order_user"
attrs="{'invisible': [('surface_technics_purchase_count', '=', 0),('routing_type', '!=', '表面工艺')]}">
attrs="{'invisible': [('surface_technics_purchase_count', '=', 0)]}">
<div class="o_field_widget o_stat_info">
<span class="o_stat_value">
<field name="surface_technics_purchase_count"/>
@@ -197,7 +200,7 @@
<!-- attrs="{'invisible': ['|', '|', ('production_state', 'in', ('draft', 'done', 'cancel')), ('working_state', '!=', 'blocked'),('state','=','done')]}"/> -->
<!-- <button name="button_workpiece_delivery" type="object" string="工件配送" class="btn-primary"-->
<!-- attrs="{'invisible': ['|','|','|','|',('routing_type','!=','装夹预调'),('is_delivery','=',True),('state','!=','done'),('is_rework','=',True),'&amp;',('rfid_code','in',['',False]),('state','=','done')]}"/>-->
<button name="button_rework_pre" type="object" string="返工"
<button name="button_rework_pre" type="object" string="异常反馈" invisible="1"
class="btn-primary"
attrs="{'invisible': ['|','|',('routing_type','!=','装夹预调'),('state','!=','progress'),('is_rework','=',True)]}"/>
<button name="unbind_tray" type="object" string="解绑托盘"
@@ -207,7 +210,7 @@
attrs="{'invisible': ['|',('routing_type','!=','解除装夹'),('state','!=','done')]}"/>
</xpath>
<xpath expr="//page[1]" position="before">
<page string="开料要求" attrs='{"invisible": [("routing_type","!=","切割")]}'>
<page string="开料要求" attrs='{"invisible": [("routing_type","not in",("切割", "线切割", "人工线下加工"))]}'>
<group>
<group>
<field name="product_tmpl_id_materials_id" widget="many2one"/>
@@ -225,6 +228,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,11 +250,25 @@
<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="is_test_env" invisible="1"/>
<field name="rfid_code" force_save="1" readonly="1" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}" widget="qrcode_widget"/>
<field name="rfid_code" string="RFID码(手动输入框)" force_save="1" readonly="0" cache="True"
attrs="{'invisible': ['|',('rfid_code_old', '!=', False), ('is_test_env', '=', False)]}"/>
<field name="rfid_code_old" readonly="1" attrs="{'invisible': [('rfid_code_old', '=', False)]}"/>
</xpath>
<xpath expr="//header" position="inside">
<div class="o_statusbar_buttons">
<button name="button_change_env"
type="object"
string="演示模式"
class="btn-primary"
groups="sf_manufacturing.group_show_button"/>
</div>
</xpath>
<xpath expr="//form//sheet//group//group//div[2]" position="replace">
</xpath>
<xpath expr="//form//sheet//group//group//div[1]" position="after">
@@ -267,9 +285,8 @@
<label for="material_height" string="高"/>
<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加工')]}"/>
<field name="part_name"/>
<field name="part_number" string="零件图号"/>
</xpath>
<xpath expr="//label[1]" position="attributes">
<attribute name="string">计划加工时间</attribute>
@@ -468,6 +485,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 +547,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 +624,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>
@@ -632,6 +664,7 @@
<separator/>
<filter string="预警" name="filter_order_warning" domain="[('delivery_warning', '=', 'warning')]"/>
<filter string="逾期" name="filter_order_overdue" domain="[('delivery_warning', '=', 'overdue')]"/>
<filter string="正常" name="filter_order_normal" domain="[('delivery_warning', '=', 'normal')]"/>
<separator/>
</xpath>
</field>

View File

@@ -0,0 +1,94 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_order_form_inherit_supply_method" model="ir.ui.view">
<field name="name">view.sale.order.form.inherit.supply.method</field>
<field name="inherit_id" ref="sf_sale.view_sale_order_form_inherit_sf"/>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<xpath expr="//header/button[@name='action_confirm'][last()]" position="attributes">
<attribute name="attrs">{'invisible': [('state', '!=', 'draft')]}</attribute>
<attribute name="name">confirm_to_supply_method</attribute>
</xpath>
<xpath expr="//header/button[@name='confirm_to_supply_method']" position="before">
<button name="action_confirm" string="供货方式确认" type="object" attrs="{'invisible': [('state', '!=', 'supply method')]}" confirm="确认供货方式"/>
</xpath>
<xpath expr="//header/field[@name='state']" position="attributes">
<attribute name="statusbar_visible">draft,sent,supply method,sale</attribute>
</xpath>
<xpath expr="//page/field[@name='order_line']/tree/field[@name='remark']" position="before">
<field name="supply_method" attrs="{'invisible': [('state', '=', 'draft')], 'required': [('state', '=', 'supply method')]}" />
</xpath>
<xpath expr="//header/button[@name='action_cancel']" position="attributes">
<attribute name="attrs">{'invisible': [('state', '!=', 'draft')]}</attribute>
</xpath>
<xpath expr="//header/button[@name='action_cancel']" position="attributes">
<attribute name="attrs">{'invisible': [('state', '!=', 'draft')]}</attribute>
</xpath>
<xpath expr="//header/button[@name='action_quotation_send'][5]" position="attributes">
<attribute name="attrs">{'invisible': ['|','&amp;',('check_status', '!=', 'approved'),('state', 'in', ['draft','cancel','supply method']),'&amp;',('check_status', '=', 'approved'),('state', 'in', ['sale','cancel','supply method'])]}</attribute>
</xpath>
</field>
</record>
<record id="jikimo_sale_order_view_search_inherit_quotation_supply_method" model="ir.ui.view">
<field name="name">jikimo.sale.order.search.inherit.quotation.supply.method</field>
<field name="model">sale.order</field>
<field name="mode">primary</field>
<field name="inherit_id" ref="sale.sale_order_view_search_inherit_quotation"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='my_quotation']" position="attributes">
<attribute name="domain">[('state', 'in', ('draft', 'sent')), ('user_id', '=', uid)]</attribute>
</xpath>
<xpath expr="//filter[@name='draft']" position="after">
<filter string="供货方式待确认" name="supply_method" domain="[('state', '=', 'supply method')]"/>
</xpath>
</field>
</record>
<record id="sale.action_quotations_with_onboarding" model="ir.actions.act_window">
<field name="search_view_id" ref="jikimo_sale_order_view_search_inherit_quotation_supply_method"/>
<field name="context">{'search_default_draft': 1}</field>
</record>
<record id="action_quotations_supply_method" model="ir.actions.act_window">
<field name="name">报价单</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">sale.order</field>
<field name="view_mode">tree,kanban,form,calendar,pivot,graph,activity</field>
<field name="view_id" ref="sale.view_quotation_tree_with_onboarding"/>
<field name="search_view_id" ref="jikimo_sale_order_view_search_inherit_quotation_supply_method"/>
<field name="context">{'search_default_supply_method': 1}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Create a new quotation, the first step of a new sale!
</p><p>
Once the quotation is confirmed by the customer, it becomes a sales order.<br/> You will be able to create an invoice and collect the payment.
</p>
</field>
</record>
<menuitem
id="sale.sale_menu_root"
groups="sf_base.group_production_engineer,sf_base.group_sale_director,sf_base.group_sale_salemanager"
/>
<!--供货路线专员菜单-->
<menuitem
id="sale_order_menu_quotations_supply_method"
name="报价"
action="action_quotations_supply_method"
parent="sale.sale_order_menu"
groups="sf_base.group_production_engineer"
sequence="2"/>
<record id="sale.menu_sale_order" model="ir.ui.menu">
<field name="groups_id" eval="[(4, ref('sf_base.group_production_engineer'))]"/>
</record>
<record id="sale.report_sales_team" model="ir.ui.menu">
<field name="groups_id" eval="[(4, ref('sf_base.group_production_engineer'))]"/>
</record>
<record id="sale.res_partner_menu" model="ir.ui.menu">
<field name="groups_id" eval="[(4, ref('sf_base.group_production_engineer'))]"/>
</record>
</odoo>

View File

@@ -1,23 +1,60 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<data>
<record id="view_stock_move_operations_inherit_sf" model="ir.ui.view">
<field name="name">stock.move.operations.form.inherit.sf</field>
<field name="model">stock.move</field>
<field name="inherit_id" ref="stock.view_stock_move_operations"/>
<field name="arch" type="xml">
<xpath expr="//button[@name='action_assign_serial_show_details']" position="after">
<button name="print_serial_numbers" string="序列号打印" type="object"/>
</xpath>
</field>
</record>
<!-- <record id="view_stock_move_operations_inherit_sf" model="ir.ui.view">-->
<!-- <field name="name">stock.move.operations.form.inherit.sf</field>-->
<!-- <field name="model">stock.move</field>-->
<!-- <field name="inherit_id" ref="stock.view_stock_move_operations"/>-->
<!-- <field name="arch" type="xml">-->
<!-- <xpath expr="//button[@name='action_assign_serial_show_details']" position="after">-->
<!-- <button name="print_serial_numbers" string="序列号打印" type="object"/>-->
<!-- </xpath>-->
<!-- </field>-->
<!-- </record>-->
<record model="ir.ui.view" id="view_picking_form_inherit_sf">
<record model="ir.ui.view" id="view_picking_form_inherit_sf_1">
<field name="name">stock.picking.form.inherit.sf</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_form"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='user_id']" position="after">
<field name="picking_type_sequence_code" invisible="1"/>
<field name="retrospect_ref"
attrs="{'invisible':[('picking_type_sequence_code','not in',['DL', 'INT', 'PC'])]}"/>
<field name="person_of_delivery" attrs="{'invisible':[('picking_type_sequence_code','!=','DL')]}"/>
<field name="telephone_of_delivery"
attrs="{'invisible':[('picking_type_sequence_code','!=','DL')]}"/>
<field name="address_of_delivery" attrs="{'invisible':[('picking_type_sequence_code','!=','DL')]}"/>
</xpath>
</field>
</record>
<record id="sf_vpicktree_1" model="ir.ui.view">
<field name="name">sf.vpicktree.1</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.vpicktree"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='origin']" position="after">
<field name="retrospect_ref"/>
</xpath>
</field>
</record>
<record id="view_picking_internal_search_sf" model="ir.ui.view">
<field name="name">stock.picking.search</field>
<field name="model">stock.picking</field>
<field name="inherit_id" ref="stock.view_picking_internal_search"/>
<field name="arch" type="xml">
<xpath expr="//filter[@name='picking_type']" position="after">
<filter string="追溯参考" name="retrospect_ref" domain="[]"
context="{'group_by': 'retrospect_ref'}"/>
</xpath>
</field>
</record>
<record id="stock.action_picking_tree_all" model="ir.actions.act_window">
<field name="view_ids" eval="[(5, 0, 0),
(0, 0, {'view_mode': 'tree', 'view_id': ref('stock.vpicktree')})]"/>
</record>
</data>
</odoo>

View File

@@ -1,3 +1,5 @@
from . import workpiece_delivery_wizard
from . import rework_wizard
from . import production_wizard
from . import production_technology_wizard
from . import production_technology_re_adjust_wizard

View File

@@ -0,0 +1,126 @@
# -*- coding: utf-8 -*-
import logging
from itertools import groupby
from odoo import models, api, fields, _
class ProductionTechnologyReAdjustWizard(models.TransientModel):
_name = 'sf.production.technology.re_adjust.wizard'
_description = '制造订单工艺调整'
production_id = fields.Many2one('mrp.production', string='制造订单号')
origin = fields.Char(string='源单据')
is_technology_re_adjust = fields.Boolean(default=False)
def confirm(self):
if self.is_technology_re_adjust is True:
domain = [('origin', '=', self.origin), ('state', '=', 'confirmed'),
('product_id', '=', self.production_id.product_id.id)]
else:
domain = [('id', '=', self.production_id.id)]
technology_designs = self.env['sf.technology.design'].sudo().search(
[('production_id', '=', self.production_id.id), ('active', 'in', [True, False])])
productions = self.env['mrp.production'].search(domain)
for production_item in productions:
# 该制造订单的其他同一销售订单的制造订单的工艺设计处理
if production_item != self.production_id:
for td_other in production_item.technology_design_ids:
if td_other.is_auto is False:
td_del = technology_designs.filtered(lambda tdo: tdo.route_id.id == td_other.route_id.id)
if not td_del or td_del.active is False:
td_other.write({'active': False})
for td_main in technology_designs:
route_other = production_item.technology_design_ids.filtered(
lambda td: td.route_id.id == td_main.route_id.id)
if not route_other and td_main.active is True:
production_item.write({'technology_design_ids': [(0, 0, {
'route_id': td_main.route_id.id,
'process_parameters_id': False if td_main.process_parameters_id is False else
self.env[
'sf.production.process.parameter'].search(
[('id', '=', td_main.process_parameters_id.id)]).id,
'sequence': td_main.sequence,
'is_auto': td_main.is_auto})]})
else:
for ro in route_other:
domain = [('production_id', '=', self.production_id.id),
('active', 'in', [True, False]),
('route_id', '=', ro.route_id.id)]
if ro.route_id.routing_type == '表面工艺':
domain += [('process_parameters_id', '=', ro.process_parameters_id.id)]
elif ro.route_id.routing_tag == 'special' and ro.is_auto is False:
# display_name = ro.route_id.display_name
domain += [('id', '=', ro.id)]
elif ro.panel is not False:
domain += [('panel', '=', ro.panel)]
td_upd = self.env['sf.technology.design'].sudo().search(domain)
if td_upd:
ro.write({'sequence': td_upd.sequence, 'active': td_upd.active})
special_design = self.env['sf.technology.design'].sudo().search(
[('routing_tag', '=', 'special'), ('production_id', '=', production_item.id),
('is_auto', '=', False), ('active', 'in', [True, False])])
for special in special_design:
workorders_values = []
if special.active is False:
is_cancel = False
# 工单采购单外协出入库单皆需取消
domain = [('production_id', '=', special.production_id.id)]
if special.process_parameters_id:
domain += [('surface_technics_parameters_id', '=', special.process_parameters_id.id), ('state', '!=', 'cancel')]
else:
domain += [('technology_design_id', '=', special.id), ('state', '!=', 'cancel')]
workorder = self.env['mrp.workorder'].search(domain)
# previous_workorder = self.env['mrp.workorder'].search(
# [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'),
# ('production_id', '=', workorder.production_id.id)])
# if previous_workorder:
# if previous_workorder.supplier_id != workorder.supplier_id:
# is_cancel = True
# else:
# is_cancel = True
# if workorder.state != 'cancel' and is_cancel is True:
# workorder.write({'state': 'cancel'})
# workorder.picking_ids.write({'state': 'cancel'})
# workorder.picking_ids.move_ids.write({'state': 'cancel'})
# purchase_order = self.env['purchase.order'].search(
# [('origin', '=', workorder.production_id.name)])
# for line in purchase_order.order_line:
# if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id:
# purchase_order.write({'state': 'cancel'})
else:
workorder = self.env['mrp.workorder'].search(
[('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id), ('state', '!=', 'cancel')])
if not workorder:
if special.route_id.routing_type == '表面工艺':
product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', special.process_parameters_id.id)])
workorders_values.append(
self.env[
'mrp.workorder']._json_workorder_surface_process_str(special.production_id, special,
product_production_process.seller_ids[
0].partner_id.id))
else:
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(special.production_id, special))
special.production_id.write({'workorder_ids': workorders_values})
else:
logging.info(workorder.blocked_by_workorder_ids)
if len(workorder.blocked_by_workorder_ids) > 1:
if workorder.sequence == 1:
workorder.blocked_by_workorder_ids = None
else:
if workorder.blocked_by_workorder_ids:
workorder.blocked_by_workorder_ids = workorder.blocked_by_workorder_ids[0]
productions._reset_work_order_sequence()
# 退回时不对外协出入库单和采购单做处理
# if self.production_id.product_id.categ_id.type == '成品':
# productions._reset_subcontract_pick_purchase()
# productions.get_subcontract_pick_purchase()
productions.is_adjust = True
for item in productions:
workorders = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted(
key=lambda a: a.sequence)
if workorders[0].state in ['pending']:
if workorders[
0].production_id.product_id.categ_id.type == '成品' and item.programming_state != '已编程':
workorders[0].state = 'waiting'

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="sf_production_technology_re_adjust_wizard_form_view">
<field name="name">sf.production.technology.re_adjust.wizard.form.view</field>
<field name="model">sf.production.technology.re_adjust.wizard</field>
<field name="arch" type="xml">
<form>
<sheet>
<field name="production_id" invisible="1"/>
<field name="origin" invisible="1"/>
<div>
<field name="is_technology_re_adjust" force_save="1"/>
当前制造订单,同一销售订单相同产品所生成的制造订单是否统一进行退回调整操作
</div>
<footer>
<button string="确认" name="confirm" type="object" class="oe_highlight" confirm="是否确认退回调整"/>
<button string="取消" class="btn btn-secondary" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
<record id="action_sf_production_technology_re_adjust_wizard" model="ir.actions.act_window">
<field name="name">工艺退回调整</field>
<field name="res_model">sf.production.technology.re_adjust.wizard</field>
<field name="view_mode">form</field>
<!-- <field name="context">{-->
<!-- 'default_production_id': active_id}-->
<!-- </field>-->
<field name="target">new</field>
</record>
</odoo>

View File

@@ -0,0 +1,118 @@
# -*- coding: utf-8 -*-
# Part of YiZuo. See LICENSE file for full copyright and licensing details.
import logging
from itertools import groupby
from odoo import models, api, fields, _
class ProductionTechnologyWizard(models.TransientModel):
_name = 'sf.production.technology.wizard'
_description = '制造订单工艺确认向导'
production_id = fields.Many2one('mrp.production', string='制造订单号')
origin = fields.Char(string='源单据')
is_technology_confirm = fields.Boolean(default=False)
def confirm(self):
if self.is_technology_confirm is True and self.production_id.product_id.categ_id.type == '成品':
domain = [('origin', '=', self.origin), ('state', '=', 'technology_to_confirmed'),
('product_id', '=', self.production_id.product_id.id)]
else:
domain = [('id', '=', self.production_id.id)]
technology_designs = self.production_id.technology_design_ids
productions = self.env['mrp.production'].search(domain)
for production in productions:
if production != self.production_id:
for td_other in production.technology_design_ids:
if td_other.is_auto is False:
td_del = technology_designs.filtered(lambda tdo: tdo.route_id.id == td_other.route_id.id)
if not td_del or td_del.active is False:
td_other.write({'active': False})
for td_main in technology_designs:
route_other = production.technology_design_ids.filtered(
lambda td: td.route_id.id == td_main.route_id.id)
if not route_other and td_main.active is True:
production.write({'technology_design_ids': [(0, 0, {
'route_id': td_main.route_id.id,
'process_parameters_id': False if td_main.process_parameters_id is False else self.env[
'sf.production.process.parameter'].search(
[('id', '=', td_main.process_parameters_id.id)]).id,
'sequence': td_main.sequence})]})
else:
for ro in route_other:
domain = [('production_id', '=', self.production_id.id),
('active', 'in', [True, False]),
('route_id', '=', ro.route_id.id)]
if ro.route_id.routing_type == '表面工艺':
domain += [('process_parameters_id', '=', ro.process_parameters_id.id)]
elif ro.route_id.routing_tag == 'special' and ro.is_auto is False:
# display_name = ro.route_id.display_name
domain += [('id', '=', ro.id)]
elif ro.panel is not False:
domain += [('panel', '=', ro.panel)]
td_upd = self.env['sf.technology.design'].sudo().search(domain)
if td_upd:
ro.write({'sequence': td_upd.sequence, 'active': td_upd.active})
special_design = self.env['sf.technology.design'].sudo().search(
[('routing_tag', '=', 'special'), ('production_id', '=', production.id),
('is_auto', '=', False), ('active', 'in', [True, False])])
for special in special_design:
workorders_values = []
if special.active is False:
# is_cancel = False
# 工单采购单外协出入库单皆需取消
domain = [('production_id', '=', special.production_id.id)]
if special.process_parameters_id:
domain += [('surface_technics_parameters_id', '=', special.process_parameters_id.id), ('state', '!=', 'cancel')]
else:
domain += [('technology_design_id', '=', special.id), ('state', '!=', 'cancel')]
workorder = self.env['mrp.workorder'].search(domain)
# previous_workorder = self.env['mrp.workorder'].search(
# [('sequence', '=', workorder.sequence - 1), ('routing_type', '=', '表面工艺'),
# ('production_id', '=', workorder.production_id.id)])
# if previous_workorder:
# if previous_workorder.supplier_id != workorder.supplier_id:
# is_cancel = True
# if workorder.state != 'cancel' and is_cancel is True:
workorder.write({'state': 'cancel'})
workorder.picking_ids.write({'state': 'cancel'})
workorder.picking_ids.move_ids.write({'state': 'cancel'})
purchase_order = self.env['purchase.order'].search(
[('origin', '=', workorder.production_id.name), ('purchase_type', '=', 'consignment')])
for line in purchase_order.order_line:
if line.product_id.server_product_process_parameters_id == workorder.surface_technics_parameters_id:
purchase_order.write({'state': 'cancel'})
else:
if special.production_id.workorder_ids:
workorder = self.env['mrp.workorder'].search(
[('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id), ('state', '!=', 'cancel')])
if not workorder:
if special.route_id.routing_type == '表面工艺':
product_production_process = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', special.process_parameters_id.id)])
workorders_values.append(
self.env[
'mrp.workorder']._json_workorder_surface_process_str(special.production_id, special,
product_production_process.seller_ids[
0].partner_id.id))
else:
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(special.production_id, special))
special.production_id.write({'workorder_ids': workorders_values})
else:
if len(workorder.blocked_by_workorder_ids) > 1:
if workorder.sequence == 1:
workorder.blocked_by_workorder_ids = None
else:
if workorder.blocked_by_workorder_ids:
workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0]
productions._create_workorder(False)
if self.production_id.product_id.categ_id.type == '成品':
productions.get_subcontract_pick_purchase()
productions.is_adjust = False
for item in productions:
workorder = item.workorder_ids.filtered(lambda wo: wo.state not in ('cancel')).sorted(
key=lambda a: a.sequence)
if workorder[0].state in ['pending']:
if workorder[0].production_id.product_id.categ_id.type == '成品' and item.programming_state != '已编程':
workorder[0].state = 'waiting'

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record model="ir.ui.view" id="sf_production_technology_wizard_form_view">
<field name="name">sf.production.technology.wizard.form.view</field>
<field name="model">sf.production.technology.wizard</field>
<field name="arch" type="xml">
<form>
<sheet>
<field name="production_id" invisible="1"/>
<field name="origin" invisible="1"/>
<div>
<field name="is_technology_confirm" force_save="1"/>
对当前制造订单,同一销售订单相同产品所生成的制造订单统一进行工艺调整与确认
</div>
<footer>
<button string="确认" name="confirm" type="object" class="oe_highlight" confirm="是否确认工艺调整"/>
<button string="取消" class="btn btn-secondary" special="cancel"/>
</footer>
</sheet>
</form>
</field>
</record>
<record id="action_sf_production_technology_wizard" model="ir.actions.act_window">
<field name="name">工艺确认</field>
<field name="res_model">sf.production.technology.wizard</field>
<field name="view_mode">form</field>
<!-- <field name="context">{-->
<!-- 'default_production_id': active_id}-->
<!-- </field>-->
<field name="target">new</field>
</record>
</odoo>

View File

@@ -46,58 +46,5 @@ class ProductionWizard(models.TransientModel):
ret = {'programming_list': [], 'is_reprogramming': self.is_reprogramming}
if self.is_reprogramming is True:
self.production_id.update_programming_state()
else:
scrap_cnc = self.production_id.workorder_ids.filtered(lambda crw: crw.routing_type == 'CNC加工').cnc_ids
scrap_cmm = self.production_id.workorder_ids.filtered(lambda cm: cm.routing_type == 'CNC加工').cmm_ids
for item_line in scrap_cnc:
vals = {
'sequence_number': item_line.sequence_number,
'program_name': item_line.program_name,
'cutting_tool_name': item_line.cutting_tool_name,
'cutting_tool_no': item_line.cutting_tool_no,
'processing_type': item_line.processing_type,
'margin_x_y': item_line.margin_x_y,
'margin_z': item_line.margin_z,
'depth_of_processing_z': item_line.depth_of_processing_z,
'cutting_tool_extension_length': item_line.cutting_tool_extension_length,
'estimated_processing_time': item_line.estimated_processing_time,
'cutting_tool_handle_type': item_line.cutting_tool_handle_type,
'ftp_path': item_line.program_path,
'processing_panel': item_line.workorder_id.processing_panel,
'program_create_date': datetime.strftime(item_line.program_create_date,
'%Y-%m-%d %H:%M:%S'),
'remark': item_line.remark
}
ret['programming_list'].append(vals)
for cmm_line in scrap_cmm:
vals = {
'sequence_number': cmm_line.sequence_number,
'program_name': cmm_line.program_name,
'ftp_path': cmm_line.program_path,
'processing_panel': item_line.workorder_id.processing_panel,
'program_create_date': datetime.strftime(
cmm_line.program_create_date,
'%Y-%m-%d %H:%M:%S')
}
ret['programming_list'].append(vals)
new_production = self.production_id.recreateManufacturing(ret)
self.production_id.write({'remanufacture_production_id': new_production.id})
if self.is_reprogramming is False:
for panel in new_production.product_id.model_processing_panel.split(','):
scrap_cnc_workorder = max(
self.production_id.workorder_ids.filtered(
lambda
scn: scn.processing_panel == panel and scn.routing_type == 'CNC加工'),
key=lambda w: w.create_date)
scrap_pre_workorder = max(self.production_id.workorder_ids.filtered(
lambda
pr: pr.processing_panel == panel and pr.routing_type == '装夹预调'),
key=lambda w1: w1.create_date)
new_cnc_workorder = new_production.workorder_ids.filtered(
lambda
nc: nc.processing_panel == panel and nc.routing_type == 'CNC加工')
new_cnc_workorder.write({'cnc_worksheet': scrap_cnc_workorder.cnc_worksheet})
new_pre_workorder = new_production.workorder_ids.filtered(lambda
p: p.routing_type == '装夹预调' and p.processing_panel == panel)
new_pre_workorder.write({'processing_drawing': scrap_pre_workorder.processing_drawing})

View File

@@ -4,6 +4,7 @@ import logging
from odoo.exceptions import UserError, ValidationError
from datetime import datetime
from odoo import models, api, fields, _
from odoo.tools import groupby
class ReworkWizard(models.TransientModel):
@@ -13,6 +14,9 @@ class ReworkWizard(models.TransientModel):
workorder_id = fields.Many2one('mrp.workorder', string='工单')
product_id = fields.Many2one('product.product')
production_id = fields.Many2one('mrp.production', string='制造订单号')
workorder_ids = fields.Many2many('mrp.workorder', 'rework_wizard_to_work_order', string='所有工单',
domain="[('production_id', '=', production_id),('state','=','done')]")
hidden_workorder_ids = fields.Char('')
rework_reason = fields.Selection(
[("programming", "编程"), ("cutter", "刀具"), ("clamping", "装夹"),
("operate computer", "操机"),
@@ -34,6 +38,30 @@ class ReworkWizard(models.TransientModel):
tool_state = fields.Selection(string='功能刀具状态', related='production_id.tool_state')
@api.onchange('hidden_workorder_ids')
def _onchange_hidden_workorder_ids(self):
for item in self:
if item.hidden_workorder_ids not in ['', None, False]:
hidden_workorder_list = item.hidden_workorder_ids.split(',')
# 获取加工面对应需要返工的工单
rw_ids = item.workorder_ids.filtered(
lambda w: str(w.ids[0]) in hidden_workorder_list and w.processing_panel not in ['', None, False])
grouped_rw_ids = {key: list(group) for key, group in groupby(rw_ids, key=lambda w: w.processing_panel)}
for panel, panel_rw_ids in grouped_rw_ids.items():
work_ids = item.workorder_ids.filtered(lambda w: w.state == 'done' and w.processing_panel == panel)
if len(work_ids) == 3 and len(panel_rw_ids) != 3:
for work_id in work_ids:
if work_id not in panel_rw_ids:
hidden_workorder_list.append(str(work_id.ids[0]))
elif len(work_ids) == 2 and len(panel_rw_ids) < 2 and panel_rw_ids[0].name == 'CNC加工':
if rw_ids.filtered(lambda w: (w.sequence < panel_rw_ids[0].sequence
and w.processing_panel != panel_rw_ids[0].processing_panel)):
hidden_workorder_list.append(str(work_ids.filtered(
lambda w: (w.processing_panel == panel_rw_ids[0].processing_panel
and w.name == '装夹预调')).ids[0]))
hidden_workorder_list.sort()
item.hidden_workorder_ids = ','.join(hidden_workorder_list)
def confirm(self):
if self.routing_type in ['装夹预调', 'CNC加工']:
self.is_clamp_measure = False
@@ -48,100 +76,122 @@ class ReworkWizard(models.TransientModel):
'test_report': self.workorder_id.detection_report})]})
self.workorder_id.button_finish()
else:
if self.production_id.workorder_ids:
handle_result = self.production_id.detection_result_ids.filtered(
lambda dr: dr.handle_result == '待处理')
if handle_result:
processing_panels_to_handle = set(handle_item.processing_panel for handle_item in handle_result)
processing_panels_choice = set(dr_panel.name for dr_panel in self.processing_panel_id)
# 使用集合的差集操作找出那些待处理结果中有但实际可用加工面中没有的加工面
processing_panels_missing = processing_panels_to_handle - processing_panels_choice
# 存在不一致的加工面
if processing_panels_missing:
processing_panels_str = ','.join(processing_panels_missing)
raise UserError('您还有待处理的检测结果中为%s的加工面未选择' % processing_panels_str)
for panel in self.processing_panel_id:
panel_workorder = self.production_id.workorder_ids.filtered(
lambda ap: ap.processing_panel == panel.name and ap.state != 'rework')
if panel_workorder:
panel_workorder.write({'state': 'rework'})
rework_clamp_workorder = max(panel_workorder.filtered(
lambda
rp: rp.processing_panel == panel.name and rp.routing_type == '装夹预调' and rp.state in [
'done', 'rework']))
# panel_workorder.filtered(
# lambda wo: wo.routing_type == '装夹预调').workpiece_delivery_ids.filtered(
# lambda wd: wd.status == '待下发').write({'status': '已取消'})
# workpiece = self.env['sf.workpiece.delivery'].search([('status', '=', '待下发'), (
# 'workorder_id', '=',
# panel_workorder.filtered(lambda wd: wd.routing_type == '装夹预调').id)])
product_routing_workcenter = self.env['sf.product.model.type.routing.sort'].search(
[('product_model_type_id', '=', self.production_id.product_id.product_model_type_id.id)],
order='sequence asc'
)
workorders_values = []
for route in product_routing_workcenter:
if route.is_repeat is True:
workorders_values.append(
self.env['mrp.workorder'].json_workorder_str(panel.name,
self.production_id, route, False))
if workorders_values:
self.production_id.write({'workorder_ids': workorders_values, 'is_rework': True})
self.production_id._reset_work_order_sequence()
self.production_id.detection_result_ids.filtered(
lambda ap1: ap1.processing_panel == panel.name and ap1.handle_result == '待处理').write(
{'handle_result': '已处理'})
new_pre_workorder = self.production_id.workorder_ids.filtered(lambda
p: p.routing_type == '装夹预调' and p.processing_panel == panel.name and p.state not in (
'rework', 'done'))
if new_pre_workorder and rework_clamp_workorder and self.is_clamp_measure is True:
new_pre_workorder.write(
{'X1_axis': rework_clamp_workorder.X1_axis, 'Y1_axis': rework_clamp_workorder.Y1_axis
, 'Z1_axis': rework_clamp_workorder.Z1_axis,
'X2_axis': rework_clamp_workorder.X2_axis
, 'Y2_axis': rework_clamp_workorder.Y2_axis,
'Z2_axis': rework_clamp_workorder.Z2_axis
, 'X3_axis': rework_clamp_workorder.X3_axis,
'Y3_axis': rework_clamp_workorder.Y3_axis
, 'Z3_axis': rework_clamp_workorder.Z3_axis,
'X4_axis': rework_clamp_workorder.X4_axis
, 'Y4_axis': rework_clamp_workorder.Y4_axis,
'Z4_axis': rework_clamp_workorder.Z4_axis
, 'X5_axis': rework_clamp_workorder.X5_axis,
'Y5_axis': rework_clamp_workorder.Y5_axis
, 'Z5_axis': rework_clamp_workorder.Z5_axis,
'X6_axis': rework_clamp_workorder.X6_axis
, 'Y6_axis': rework_clamp_workorder.Y6_axis,
'Z6_axis': rework_clamp_workorder.Z6_axis
, 'X7_axis': rework_clamp_workorder.X7_axis,
'Y7_axis': rework_clamp_workorder.Y7_axis
, 'Z7_axis': rework_clamp_workorder.Z7_axis,
'X8_axis': rework_clamp_workorder.X8_axis
, 'Y8_axis': rework_clamp_workorder.Y8_axis,
'Z8_axis': rework_clamp_workorder.Z8_axis
, 'X9_axis': rework_clamp_workorder.X9_axis,
'Y9_axis': rework_clamp_workorder.Y9_axis
, 'Z9_axis': rework_clamp_workorder.Z9_axis,
'X10_axis': rework_clamp_workorder.X10_axis
, 'Y10_axis': rework_clamp_workorder.Y10_axis,
'Z10_axis': rework_clamp_workorder.Z10_axis
, 'X_deviation_angle': rework_clamp_workorder.X_deviation_angle,
'material_center_point': rework_clamp_workorder.material_center_point
})
if self.is_reprogramming is False:
if self.programming_state in ['已编程', '已下发']:
if self.reprogramming_num >= 1 and self.programming_state == '已编程':
self.production_id.get_new_program(panel.name)
if self.reprogramming_num >= 0 and self.programming_state == '已下发':
if self.hidden_workorder_ids:
hidden_workorder_list = self.hidden_workorder_ids.split(',')
rework_workorder_ids = self.workorder_ids.filtered(lambda w: str(w.id) in hidden_workorder_list)
# 限制判断
# 1、当制造订单内ZM面的工单都已完成时返工勾选工序时只能勾选上ZM面的所有工序进行返工
# 2、当FM工单在CNC工单进行选择返工并将已全部完成的ZM面工序全部勾选上时FM工单上所有的已完成的工单装夹预调工单也必须进行勾选
# 获取已完成的标准工单
# done_normative_workorder_ids = self.workorder_ids.filtered(
# lambda w: w.state == 'done' and w.processing_panel is not False)
# # 获取需要返工的标准工单
# rework_normative_workorder_ids = rework_workorder_ids.filtered(
# lambda w: w.processing_panel is not False)
# if rework_normative_workorder_ids:
# for rw in rework_normative_workorder_ids:
# if len(done_normative_workorder_ids.filtered(
# lambda w: w.processing_panel == rw.processing_panel)) == 3:
# pass
else:
raise ValidationError('请选择返工工单!!!')
if rework_workorder_ids:
clamp_workorder_ids = None
if rework_workorder_ids:
# 限制
# 1、单独返工CNC工单则不解绑托盘RFID如单独返工装夹预调工单则自动解绑托盘RFID
# 2、返工CNC工单和装夹预调工单则自动解绑RFID
clamp_workorder_ids = rework_workorder_ids.filtered(lambda rp: rp.routing_type == '装夹预调')
if clamp_workorder_ids:
for clamp_workorder_id in clamp_workorder_ids:
self.production_id.workorder_ids.filtered(
lambda wk: wk.processing_panel == clamp_workorder_id.processing_panel).write(
{'rfid_code': False})
# 返工工单状态设置为【返工】
rework_workorder_ids.write({'state': 'rework'})
# 查询返工工单对应的工艺设计记录,并调用方法拼接数据,用于创建新的工单
workorders_values = []
for work in rework_workorder_ids:
route = self.production_id.technology_design_ids.filtered(
lambda item: (item.route_id.name in work.name and item.process_parameters_id
and item.process_parameters_id == work.surface_technics_parameters_id) or
(item.route_id.name == work.name and item.panel
and item.panel == work.processing_panel))
if route:
work_list = self.env['mrp.workorder'].json_workorder_str(self.production_id, route[0])
work_list[2].update({'tag_type': '重新加工'})
workorders_values.append(work_list)
# 创建新工单,并进行返工配置的相关操作
if workorders_values:
# 创建新工单、工序排序、完成检测结果单据
self.production_id.write({'workorder_ids': workorders_values, 'is_rework': True})
new_work_ids = self.production_id.workorder_ids.filtered(lambda kw: kw.sequence == 0)
new_pre_workorder_ids = self.production_id.workorder_ids.filtered(
lambda kw: kw.routing_type == '装夹预调' and kw.sequence == 0)
self.production_id._reset_work_order_sequence()
self.production_id.detection_result_ids.filtered(
lambda ap1: ap1.handle_result == '待处理').write({'handle_result': '已处理'})
panels = [] # 返工的加工面
# ===================保留装夹测量数据=====================
if self.is_clamp_measure and clamp_workorder_ids and new_pre_workorder_ids:
for new_pre_workorder in new_pre_workorder_ids:
if new_pre_workorder.processing_panel and new_pre_workorder.processing_panel not in panels:
panels.append(new_pre_workorder.processing_panel)
for rework_clamp_workorder in clamp_workorder_ids:
if new_pre_workorder.sequence == rework_clamp_workorder.sequence + 1:
new_pre_workorder.write(
{'X1_axis': rework_clamp_workorder.X1_axis,
'Y1_axis': rework_clamp_workorder.Y1_axis
, 'Z1_axis': rework_clamp_workorder.Z1_axis,
'X2_axis': rework_clamp_workorder.X2_axis
, 'Y2_axis': rework_clamp_workorder.Y2_axis,
'Z2_axis': rework_clamp_workorder.Z2_axis
, 'X3_axis': rework_clamp_workorder.X3_axis,
'Y3_axis': rework_clamp_workorder.Y3_axis
, 'Z3_axis': rework_clamp_workorder.Z3_axis,
'X4_axis': rework_clamp_workorder.X4_axis
, 'Y4_axis': rework_clamp_workorder.Y4_axis,
'Z4_axis': rework_clamp_workorder.Z4_axis
, 'X5_axis': rework_clamp_workorder.X5_axis,
'Y5_axis': rework_clamp_workorder.Y5_axis
, 'Z5_axis': rework_clamp_workorder.Z5_axis,
'X6_axis': rework_clamp_workorder.X6_axis
, 'Y6_axis': rework_clamp_workorder.Y6_axis,
'Z6_axis': rework_clamp_workorder.Z6_axis
, 'X7_axis': rework_clamp_workorder.X7_axis,
'Y7_axis': rework_clamp_workorder.Y7_axis
, 'Z7_axis': rework_clamp_workorder.Z7_axis,
'X8_axis': rework_clamp_workorder.X8_axis
, 'Y8_axis': rework_clamp_workorder.Y8_axis,
'Z8_axis': rework_clamp_workorder.Z8_axis
, 'X9_axis': rework_clamp_workorder.X9_axis,
'Y9_axis': rework_clamp_workorder.Y9_axis
, 'Z9_axis': rework_clamp_workorder.Z9_axis,
'X10_axis': rework_clamp_workorder.X10_axis
, 'Y10_axis': rework_clamp_workorder.Y10_axis,
'Z10_axis': rework_clamp_workorder.Z10_axis
, 'X_deviation_angle': rework_clamp_workorder.X_deviation_angle,
'material_center_point': rework_clamp_workorder.material_center_point
})
break
# =====================不申请重新编程====================
if self.is_reprogramming is False:
if self.programming_state in ['已编程', '已下发']:
if self.reprogramming_num >= 1 and self.programming_state == '已编程':
for panel_name in panels:
self.production_id.get_new_program(panel_name)
if self.reprogramming_num >= 0 and self.programming_state == '已下发':
# ============= 处理CNC加工加工工单的 CNC程序和cmm程序 信息=============
for cnc_work in new_work_ids.filtered(lambda wk: wk.name == 'CNC加工'):
ret = {'programming_list': []}
cnc_rework = max(
self.production_id.workorder_ids.filtered(
lambda
crw: crw.processing_panel == panel.name and crw.state == 'rework' and crw.routing_type == 'CNC加工'),
old_cnc_rework = max(self.production_id.workorder_ids.filtered(
lambda crw: crw.processing_panel == cnc_work.processing_panel
and crw.state == 'rework' and crw.routing_type == 'CNC加工'),
key=lambda w: w.create_date
)
if cnc_rework.cnc_ids:
for item_line in cnc_rework.cnc_ids:
# 获取当前工单的CNC程序和cmm程序
if old_cnc_rework.cnc_ids:
for item_line in old_cnc_rework.cnc_ids:
vals = {
'sequence_number': item_line.sequence_number,
'program_name': item_line.program_name,
@@ -156,46 +206,50 @@ class ReworkWizard(models.TransientModel):
'cutting_tool_handle_type': item_line.cutting_tool_handle_type,
'program_path': item_line.program_path,
'ftp_path': item_line.program_path,
'processing_panel': panel.name,
'processing_panel': cnc_work.processing_panel,
'program_create_date': datetime.strftime(item_line.program_create_date,
'%Y-%m-%d %H:%M:%S'),
'remark': item_line.remark
}
ret['programming_list'].append(vals)
for cmm_line in cnc_rework.cmm_ids:
for cmm_line in old_cnc_rework.cmm_ids:
vals = {
'sequence_number': cmm_line.sequence_number,
'program_name': cmm_line.program_name,
'program_path': cmm_line.program_path,
'ftp_path': cmm_line.program_path,
'processing_panel': panel.name,
'processing_panel': cnc_work.processing_panel,
'program_create_date': datetime.strftime(
cmm_line.program_create_date,
'%Y-%m-%d %H:%M:%S')
}
ret['programming_list'].append(vals)
# 获取新的
new_cnc_workorder = self.production_id.workorder_ids.filtered(
lambda ap1: ap1.processing_panel == panel.name and ap1.state not in (
'rework', 'done') and ap1.routing_type == 'CNC加工')
lambda ap1: ap1.processing_panel == cnc_work.processing_panel
and ap1.state not in (
'rework', 'done') and ap1.routing_type == 'CNC加工'
)
if not new_cnc_workorder.cnc_ids:
new_cnc_workorder.write({
'cnc_ids': new_cnc_workorder.cnc_ids.sudo()._json_cnc_processing(panel.name,
ret),
'cmm_ids': new_cnc_workorder.cmm_ids.sudo()._json_cmm_program(panel.name,
ret),
'cnc_worksheet': cnc_rework.cnc_worksheet})
if new_pre_workorder:
pre_rework = max(self.production_id.workorder_ids.filtered(
lambda pr: pr.processing_panel == panel.name and pr.state in (
'rework') and pr.routing_type == '装夹预调'),
key=lambda w1: w1.create_date)
new_pre_workorder.write(
{'processing_drawing': pre_rework.processing_drawing})
self.production_id.write({'state': 'progress', 'is_rework': False})
elif self.programming_state in ['待编程', '编程中']:
self.production_id.write(
{'programming_state': '编程中', 'work_state': '编程中', 'is_rework': True})
'cnc_ids': new_cnc_workorder.cnc_ids.sudo()._json_cnc_processing(
cnc_work.processing_panel, ret),
'cmm_ids': new_cnc_workorder.cmm_ids.sudo()._json_cmm_program(
cnc_work.processing_panel, ret),
'cnc_worksheet': old_cnc_rework.cnc_worksheet})
# ========== 处理装夹预调 【装夹图纸】 数据 ================
for new_pre_work in new_pre_workorder_ids:
pre_rework = max(self.production_id.workorder_ids.filtered(
lambda pr: (pr.processing_panel == new_pre_work.processing_panel
and pr.state in ['rework'] and pr.routing_type == '装夹预调')),
key=lambda w1: w1.create_date)
new_pre_work.write(
{'processing_drawing': pre_rework.processing_drawing})
self.production_id.write({'state': 'progress', 'is_rework': False})
elif self.programming_state in ['待编程', '编程中']:
self.production_id.write(
{'programming_state': '编程中', 'work_state': '编程中', 'is_rework': True})
# ==================申请重新编程=======================
if self.is_reprogramming is True:
self.production_id.update_programming_state()
self.production_id.write(

View File

@@ -11,10 +11,20 @@
<field name="product_id" invisible="True"/>
<field name="tool_state" invisible="True"/>
<field name="routing_type" invisible="True"/>
<field name="processing_panel_id" invisible="1"/>
<field name="hidden_workorder_ids" class="css_not_available_msg"/>
<group>
<field name="processing_panel_id" options="{'no_create': True}"
attrs='{"invisible": [("routing_type","=","装夹预调")]}' widget="many2many_tags"/>
<field name="hidden_workorder_ids"/>
<field options="{'no_create': True,'no_open': True}" readonly="1" name="workorder_ids"
widget="jikimo_subtree_selector_field"
jikimo_selector="True" replace_context="hidden_workorder_ids" string="工序"
attrs='{"invisible": [("routing_type","=","装夹预调")]}'>
<tree create="0" editable='bottom' delete="0">
<field name="sequence" readonly="1" string="工序"/>
<field name="processing_panel" readonly="1"/>
<field name="name" readonly="1"/>
</tree>
</field>
</group>
<div attrs='{"invisible": [("routing_type","=","装夹预调")]}'>
<span style='font-weight:bold;'>保留装夹测量数据

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

@@ -36,7 +36,7 @@
<field name="msgtype">markdown</field>
<field name="urgency">normal</field>
<field name="content">### 销售订单逾期预警
事项:共有[{{warning_num}}]({{url}})个销售订单有逾期风险
事项:[共有{{warning_num}}个销售订单有逾期风险]({{url}})
</field>
</record>
@@ -48,7 +48,7 @@
<field name="msgtype">markdown</field>
<field name="urgency">urgent</field>
<field name="content">### 销售订单已逾期提醒
事项:共有[{{overdue_num}}]({{url}})个销售订单已逾期
事项:[共有{{overdue_num}}个销售订单已逾期]({{url}})
</field>
</record>
@@ -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>
@@ -262,7 +262,7 @@
<field name="msgtype">markdown</field>
<field name="urgency">normal</field>
<field name="content">### 待质量判定提醒
事项:共有[{{judge_num}}]({{url}})个工单需判定质量结果</field>
事项:[共有{{judge_num}}个工单需判定质量结果]({{url}})</field>
</record>
<record id="template_maintenance_logs" model="jikimo.message.template">
<field name="name">设备故障</field>

View File

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

View File

@@ -34,18 +34,19 @@ 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:
logging.info('add_queue error:%s' % e)
logging.info('action_confirm res:%s' % res)
return res
# 继承并重写jikimo.message.dispatch的_get_message()
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 +61,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
@@ -100,42 +101,97 @@ class SFMessageSale(models.Model):
# # 销售订单逾期预警和已逾期
def _overdue_or_warning_func(self):
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)])
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)
today_str = datetime.strptime(current_time, '%Y-%m-%d %H:%M:%S')
today = today_str.strftime("%Y-%m-%d")
# 计算下一天的日期
deadline_check_str = today_str + timedelta(days=1)
deadline_check = deadline_check_str.strftime("%Y-%m-%d")
logging.info(
f"today: {today}, deadline_check: {deadline_check},current_time_strf: {current_time_strf}, current_time: {current_time}'")
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:
deadline_of_delivery = item.deadline_of_delivery.strftime("%Y-%m-%d")
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 == deadline_of_delivery and item.delivery_warning not in ['warning']:
item.delivery_warning = 'warning'
elif today == item.deadline_of_delivery:
elif today >= 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 == deadline_of_delivery and item.delivery_warning not in ['warning']:
item.delivery_warning = 'warning'
elif today == item.deadline_of_delivery:
elif today >= 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)
if wo.delivery_warning == 'overdue':
# 把消息队列中销售订单预警的状态改为取消发送
business_node_id_warning = business_node_ids['warning']
if business_node_id_warning:
message_template_warning = self.env["jikimo.message.template"].search([
("model", "=", self._name),
("bussiness_node_id", "=", business_node_id_warning)
], limit=1)
if message_template_warning:
sale_order_warning = self.env['jikimo.message.queue'].search([
('res_id', '=', wo.id),
('message_status', '=', 'pending'),
('message_template_id', '=', message_template_warning.id)
])
if sale_order_warning:
logging.info('取消发送:%s' % sale_order_warning)
sale_order_warning.write({'message_status': 'cancel'})
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:
@@ -61,20 +61,32 @@ class SFMessageWork(models.Model):
second=0,
microsecond=0
)
logging.info(current_time)
logging.info(target_time)
logging.info(target_time - time_range)
logging.info(target_time + time_range)
# logging.info(current_time)
# logging.info(target_time)
# logging.info(target_time - time_range)
# logging.info(target_time + time_range)
if target_time - time_range <= current_time_datetime <= target_time + time_range:
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:
bussiness_node = item.bussiness_node_id.name
# 分割业务节点名称,提取出业务节点关键字
business_node_key = bussiness_node.split('工单')[0].strip()
workcenter_mapping = {
'装夹预调': '工件装夹',
'CNC加工': '自动生产',
'解除装夹': '工件拆卸',
'表面工艺': '表面工艺外协',
}
workcenter_name = workcenter_mapping.get(business_node_key)
active_id = self.env['mrp.workcenter'].search([('name', 'ilike', workcenter_name)],
limit=1).id
i += 1
if i >= 1:
action_id = self.env.ref('sf_message.mrp_workorder_action_notify').id
url_with_id = f"{url}/web#view_type=list&action={action_id}"
url_with_id = f"{url}/web#view_type=list&action={action_id}&active_id={active_id}"
content_template = content.replace('{{url}}', url_with_id)
if bussiness_node in template_names['预警']:
content = content_template.replace('{{warning_num}}', str(i))
@@ -84,12 +96,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_message.mrp_workorder_action_notify').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
@@ -97,7 +110,8 @@ class SFMessageWork(models.Model):
return full_url
def _overdue_or_warning_func(self):
workorders = self.env['mrp.workorder'].search([("state", "in", ["ready", "progress", "to be detected"])])
workorders = self.env['mrp.workorder'].search(
[("state", "in", ["ready", "progress", "to be detected"]), ('schedule_state', '=', '已排')])
grouped_workorders = {}
for workorder in workorders:
routing_type = workorder.routing_type
@@ -115,21 +129,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:
logging.info("------overdue-------")
logging.info(f"Workorder: {item.production_id.name}, Current Time: {current_time_datetime}, "
f"Planned Finish: {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:
logging.info("------warning-------")
logging.info(f"Workorder: {item.production_id.name}, Current Time: {current_time_datetime}, "
f"Planned Finish: {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 +156,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'
@@ -151,8 +174,33 @@ class SFMessageWork(models.Model):
args = [f'{item.routing_type}{overdue_message}']
# 获取add_queue方法并调用它传入参数列表
getattr(item, queue_method_name)(*args)
if item.delivery_warning == 'overdue':
# 把消息队列中销售订单预警的状态改为取消发送
key = f"{item.routing_type}_{'warning'}"
business_node_id_warning = business_node_ids.get(key, None)
if business_node_id_warning:
message_template_warning = self.env["jikimo.message.template"].search([
("model", "=", self._name),
("bussiness_node_id", "=", business_node_id_warning)
], limit=1)
if message_template_warning:
work_order_warning = self.env['jikimo.message.queue'].search([
('res_id', '=', item.id),
('message_status', '=', 'pending'),
('message_template_id', '=', message_template_warning.id)
])
if work_order_warning:
logging.info('取消发送:%s' % work_order_warning)
work_order_warning.write({'message_status': 'cancel'})
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

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

View File

@@ -30,5 +30,36 @@
</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

@@ -28,8 +28,16 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
domain = [('programming_no', '=', ret['programming_no'])]
if ret['manufacturing_type'] in ('scrap', 'invalid_tool_rework'):
domain += [('state', 'not in', ['done', 'scrap', 'cancel'])]
else:
domain += [('state', 'in', ['confirmed', 'pending_cam'])]
productions = request.env['mrp.production'].with_user(
request.env.ref("base.user_admin")).search(domain)
productions_technology_to_confirmed = request.env['mrp.production'].with_user(
request.env.ref("base.user_admin")).search(
[('programming_no', '=', ret['programming_no']), ('state', 'in', ['technology_to_confirmed'])])
if productions_technology_to_confirmed:
res = {'status': -2, 'message': '查询到待工艺确认的制造订单'}
return json.JSONEncoder().encode(res)
if productions:
# 拉取所有加工面的程序文件
for r in ret['processing_panel'].split(','):
@@ -48,26 +56,22 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
res['message'] = '编程单号为%s的CNC程序文件从FTP拉取失败' % (ret['programming_no'])
return json.JSONEncoder().encode(res)
for production in productions:
if not production.workorder_ids:
production.product_id.model_processing_panel = ret['processing_panel']
production._create_workorder(ret)
productions.process_range_time()
else:
for panel in ret['processing_panel'].split(','):
# 查询状态为进行中且工序类型为CNC加工的工单
cnc_workorder_has = production.workorder_ids.filtered(
lambda ach: ach.routing_type == 'CNC加工' and ach.state not in ['progress', 'done',
'rework',
'cancel'] and ach.processing_panel == panel)
if cnc_workorder_has:
if cnc_workorder_has.cnc_ids:
cnc_workorder_has.cmm_ids.sudo().unlink()
cnc_workorder_has.cnc_ids.sudo().unlink()
# request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
# production)
cnc_workorder_has.write(
{'cnc_ids': cnc_workorder_has.cnc_ids.sudo()._json_cnc_processing(panel, ret),
'cmm_ids': cnc_workorder_has.cmm_ids.sudo()._json_cmm_program(panel, ret)})
production.write({'programming_state': '已编程', 'work_state': '已编程'})
for panel in ret['processing_panel'].split(','):
# 查询状态为进行中且工序类型为CNC加工的工单
cnc_workorder_has = production.workorder_ids.filtered(
lambda ach: ach.routing_type == 'CNC加工' and ach.state not in ['progress', 'done',
'rework',
'cancel'] and ach.processing_panel == panel)
if cnc_workorder_has:
if cnc_workorder_has.cnc_ids:
cnc_workorder_has.cmm_ids.sudo().unlink()
cnc_workorder_has.cnc_ids.sudo().unlink()
# request.env['sf.cam.work.order.program.knife.plan'].sudo().unlink_cam_plan(
# production)
cnc_workorder_has.write(
{'cnc_ids': cnc_workorder_has.cnc_ids.sudo()._json_cnc_processing(panel, ret),
'cmm_ids': cnc_workorder_has.cmm_ids.sudo()._json_cmm_program(panel, ret)})
for panel in ret['processing_panel'].split(','):
# 查询状态为进行中且工序类型为CNC加工的工单
cnc_workorder = productions.workorder_ids.filtered(
@@ -77,7 +81,6 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
# 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)
logging.info('program_path_tmp_panel:%s' % program_path_tmp_panel)
files_panel = os.listdir(program_path_tmp_panel)
if files_panel:
for file in files_panel:
@@ -85,17 +88,13 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
if file_extension.lower() == '.pdf':
panel_file_path = os.path.join(program_path_tmp_panel, file)
logging.info('panel_file_path:%s' % panel_file_path)
logging.info('更新工作指令:%s' % cnc_workorder)
cnc_workorder.write({'cnc_worksheet': base64.b64encode(open(panel_file_path, 'rb').read())})
logging.info('更新工作指令完成:%s' % cnc_workorder)
pre_workorder = productions.workorder_ids.filtered(
lambda ap: ap.routing_type == '装夹预调' and ap.state not in ['done', 'rework'
'cancel'] and ap.processing_panel == panel)
if pre_workorder:
logging.info('更新加工图纸:%s' % pre_workorder)
pre_workorder.write(
{'processing_drawing': base64.b64encode(open(panel_file_path, 'rb').read())})
logging.info('更新加工图纸完成:%s' % pre_workorder)
productions.write({'programming_state': '已编程', 'work_state': '已编程'})
logging.info('已更新制造订单编程状态:%s' % productions.ids)
res.update({
@@ -112,7 +111,7 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
return json.JSONEncoder().encode(res)
else:
res = {'status': 0, 'message': '该制造订单暂未开始'}
res = {'status': 0, 'message': '没有查询到该制造订单'}
return json.JSONEncoder().encode(res)
except Exception as e:
res = {'status': -1, 'message': '系统解析失败'}

View File

@@ -84,6 +84,10 @@ 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("同步加工精度完成")
self.env['sf.embryo.redundancy'].sync_embryo_redundancy_all()
_logger.info("同步坯料冗余完成")
except Exception as e:
_logger.info("sf_all_sync error: %s" % e)

Some files were not shown because too many files have changed in this diff Show More