Compare commits

..

160 Commits

Author SHA1 Message Date
guanhuan
ed6189a963 Merge remote-tracking branch 'origin/feature/manufactur_order' into feature/manufactur_order 2024-12-09 09:36:08 +08:00
guanhuan
a6979b213b 手动创建的采购单生成的内部调拨单没有源单据 2024-12-09 09:35:41 +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
guanhuan
27ec5b1b74 多个制造订单菜单修复 2024-12-04 16:13:55 +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
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
42 changed files with 713 additions and 401 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

@@ -12,10 +12,6 @@ def _data_install(cr, registry):
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})
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': '坯料'})
# 为三步制造增加规则
warehouse = env['stock.warehouse'].search([('company_id', '=', env.company.id)], limit=1)

View File

@@ -6,12 +6,11 @@
'author': 'fox',
'website': '',
'category': '',
'depends': ['sf_dlm', 'sale_stock', 'sf_sale'],
'depends': ['sf_dlm', 'sale_stock', 'sf_sale', 'sale'],
"data": [
'security/ir.model.access.csv',
'data/stock_routes.xml',
'data/product_data.xml',
'views/sale_order_views.xml',
# 'views/product_product_views.xml',
],'assets': {
# 'web.assets_backend': [

View File

@@ -1,2 +1 @@
# -*- coding: utf-8 -*-
from . import main

View File

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

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

@@ -1,4 +1,5 @@
import logging
from itertools import groupby
from odoo import models, fields, api, _
@@ -7,11 +8,10 @@ class StockRuleInherit(models.Model):
@api.model
def _run_buy(self, procurements):
# 首先调用父类的 _run_buy 方法,以保留原有逻辑
super(StockRuleInherit, self)._run_buy(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)
@@ -23,21 +23,65 @@ class StockRuleInherit(models.Model):
# 检查路线
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
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', '=', 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

@@ -12,6 +12,7 @@
<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,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': """
@@ -37,6 +37,7 @@
'views/agv_setting_views.xml',
'views/sf_maintenance_equipment.xml',
'views/res_config_settings_views.xml',
'views/sale_order_views.xml',
],
'assets': {

View File

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

View File

@@ -1,5 +1,7 @@
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
@@ -44,7 +46,8 @@ class JikimoSaleRoutePicking(Sf_Bf_Connect):
i += 1
res['factory_order_no'] = order_id.name
except Exception as e:
_logger.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

@@ -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

@@ -13,3 +13,5 @@ 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

@@ -7,7 +7,7 @@ class ModelType(models.Model):
name = fields.Char('名称')
# embryo_tolerance = fields.Char('坯料容余')
embryo_tolerance_id = fields.Many2one('sf.embryo.redundancy', string='坯料')
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',

View File

@@ -278,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', 'programming_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:
@@ -309,22 +309,32 @@ class MrpProduction(models.Model):
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 == '未排':
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:
production.state = 'confirmed'
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'
@@ -383,9 +393,12 @@ class MrpProduction(models.Model):
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)])
@@ -399,6 +412,8 @@ class MrpProduction(models.Model):
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)))
# 判断同一个加工面的标准工序的顺序是否依次排序
@@ -640,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中没有工序时
# 根据产品对应的模板类型中工序,去生成工单;
@@ -681,7 +696,7 @@ class MrpProduction(models.Model):
# # 根据工序设计生成工单
for route in production.technology_design_ids:
workorder_has = self.env['mrp.workorder'].search(
[('name', '=', route.route_id.name), ('production_id', '=', production.id)])
[('technology_design_id', '=', route.id), ('production_id', '=', production.id)])
if not workorder_has:
if route.route_id.routing_type not in ['表面工艺']:
workorders_values.append(
@@ -714,40 +729,14 @@ class MrpProduction(models.Model):
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:
# 创建外协出入库单和采购订单
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)
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:
# 立即创建外协出入库单和采购订单
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:
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
self.env['purchase.order'].get_purchase_order(consecutive_workorders, production,
if not workorder.picking_ids:
self.env['stock.picking'].create_outcontract_picking(workorder, production)
# if not workorder.
if not workorder.purchase_id:
self.env['purchase.order'].get_purchase_order(workorder, production,
product_id_to_production_names)
# 工单排序
def _reset_work_order_sequence1(self, k):
for rec in self:
@@ -832,17 +821,22 @@ class MrpProduction(models.Model):
# workorder.picking_ids.move_ids = False
workorder.picking_ids = False
purchase_order = self.env['purchase.order'].search(
[('state', '=', 'draft'), ('origin', '=', ','.join(production_process)),
[('state', '=', 'draft'), ('origin', '=', item.name),
('purchase_type', '=', 'consignment')])
for line in purchase_order.order_line:
server_template = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', workorder.surface_technics_parameters_id.id),
('detailed_type', '=', 'service')])
purchase_order_line = self.env['purchase.order.line'].search(
[('product_id', '=', server_template.product_variant_id.id), ('id', '=', line.id),
('product_qty', '=', len(production_process))], limit=1, order='id desc')
if purchase_order_line:
line.unlink()
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):
"""
@@ -876,6 +870,12 @@ class MrpProduction(models.Model):
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):
"""
@@ -1127,13 +1127,13 @@ class MrpProduction(models.Model):
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_ids = []
work_id_list = []
if result_ids:
for result_id in result_ids:
work_ids.append(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)
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',
@@ -1142,7 +1142,8 @@ class MrpProduction(models.Model):
'target': 'new',
'context': {
'default_production_id': self.id,
'default_workorder_ids': work_ids,
'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
@@ -1296,14 +1297,14 @@ 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:
domain = []
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')]
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})
@@ -1322,7 +1323,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)])
@@ -1423,23 +1423,29 @@ class MrpProduction(models.Model):
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')
@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)
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)
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')
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),
])
@@ -1450,6 +1456,33 @@ class MrpProduction(models.Model):
])
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'
_description = "检测结果"

View File

@@ -86,9 +86,12 @@ class ResMrpRoutingWorkcenter(models.Model):
@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'))])
route_ids = [t.route_id.id for t in technology_design]
domain = [('id', 'not in', route_ids)]
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',
@@ -126,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程序")
@@ -135,7 +138,7 @@ class ResMrpWorkOrder(models.Model):
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='外协采购单')
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')
@@ -235,15 +238,15 @@ class ResMrpWorkOrder(models.Model):
for workorder in self:
if workorder.routing_type == '表面工艺':
domain = [('origin', '=', workorder.production_id.name), ('state', 'not in', ['cancel']),
('partner_id', '!=', False)]
('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:
if previous_workorder.supplier_id != workorder.supplier_id:
process_product = self.env['product.template']._get_process_parameters_product(
previous_workorder.surface_technics_parameters_id)
domain += [('partner_id', '=', process_product.partner_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
@@ -267,52 +270,64 @@ 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 == '表面工艺':
if order.production_id.production_type == '自动化产线加工':
domain = [('programming_no', '=', order.production_id.programming_no)]
else:
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)
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', '=', ','.join(production_list))]
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 line in purchase.order_line:
if line.product_id.server_product_process_parameters_id == order.surface_technics_parameters_id:
if line.product_qty == len(production_no_remanufacture):
order.surface_technics_purchase_count = len(purchase)
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()
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]
# 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:
domain = [('origin', '=', ','.join(production_list)), ('purchase_type', '=', 'consignment')]
domain = [('origin', '=', self.production_id.name), ('purchase_type', '=', 'consignment'),
('state', '!=', 'cancel')]
purchase_orders = self.env['purchase.order'].search(domain)
purchase_orders_id = None
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.id
result = {
"type": "ir.actions.act_window",
"res_model": "purchase.order",
"res_id": purchase_orders.id,
"res_id": purchase_orders_id,
# "domain": [['id', 'in', self.purchase_id]],
"name": _("Purchase Orders"),
'view_mode': 'form',
@@ -1062,7 +1077,7 @@ class ResMrpWorkOrder(models.Model):
if workorder.production_id.workorder_ids.filtered(lambda wk: wk.sequence == 0):
continue
# ===== 对所有按序号排序的非[进行中、完成、返工、取消]状态的工单,除了第一条之外的工单状态都设置为[等待其他工单] =====
logging.info(workorder.state)
# 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:
@@ -1075,11 +1090,17 @@ class ResMrpWorkOrder(models.Model):
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):
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 len(
workorder.production_id.picking_ids.filtered(lambda w: w.state not in ['done', 'cancel'])) != 0
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':
@@ -1111,7 +1132,7 @@ class ResMrpWorkOrder(models.Model):
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':
if all(pur_order.state == 'purchase' for pur_order in purchase_orders):
workorder.state = 'ready'
else:
workorder.state = 'waiting'
@@ -1184,22 +1205,29 @@ class ResMrpWorkOrder(models.Model):
})
if self.sequence == 1:
# 判断工单状态是否为等待组件
if self.state == 'waiting':
raise UserError('制造订单【%s】缺少组件信息!' % self.production_id.name)
# 判断是否有坯料的序列号信息
boolean = False
if self.production_id.move_raw_ids:
if self.production_id.move_raw_ids[0].move_line_ids:
if self.production_id.move_raw_ids[0].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[0].lot_id.name:
boolean = True
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':
@@ -1221,10 +1249,14 @@ class ResMrpWorkOrder(models.Model):
[('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))
('origin', '=', self.production_id.name), ('state', 'not in', ['cancel', 'done'])])
for mo in move_out:
pick = self.env['stock.picking'].search([('id', '=', mo.picking_id.id), ('name', 'ilike', 'OCOUT'),
('partner_id', '=', self.supplier_id.id)])
if pick:
if mo.state != 'done':
mo.write({'state': 'assigned', 'production_id': False})
self.env['stock.move.line'].create(mo.get_move_line(self.production_id, self))
# move_out._action_assign()
if self.state == 'waiting' or self.state == 'ready' or self.state == 'progress':
@@ -1347,7 +1379,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
@@ -1364,7 +1396,8 @@ 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

View File

@@ -859,12 +859,12 @@ class ResProductMo(models.Model):
raise UserError('请先配置模型类型内的坯料冗余')
vals = {
'name': '%s-%s-%s' % ('P', order_id.name, i),
'model_long': item['model_long'] + embryo_redundancy_id.long,
'model_width': item['model_width'] + embryo_redundancy_id.width,
'model_height': item['model_height'] + embryo_redundancy_id.height,
'model_volume': (item['model_long'] + embryo_redundancy_id.long) * (
'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),
item['model_height'] + embryo_redundancy_id.height)),
'product_model_type_id': model_type.id,
'model_processing_panel': item['processing_panel_detail'],
'model_machining_precision': item['model_machining_precision'],
@@ -874,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,
@@ -908,6 +908,20 @@ class ResProductMo(models.Model):
'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 = []
if not param:
@@ -924,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',

View File

@@ -43,6 +43,8 @@ class SaleOrder(models.Model):
# 复制成品模板上的属性
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
@@ -155,3 +157,10 @@ class SaleOrderLine(models.Model):
('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

@@ -10,8 +10,14 @@ class SfProductionProcessParameter(models.Model):
@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'))])
domain = [('process_id', '=', routing.surface_technics_id.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

@@ -281,19 +281,26 @@ class StockRule(models.Model):
workorder_duration += workorder.duration_expected
sale_order = self.env['sale.order'].sudo().search([('name', '=', production.origin)])
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',
})
technology_design_values = []
# 如果订单为空,则获取来源制造订单的销售单
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:
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对应的生产订单名称列表
@@ -303,6 +310,7 @@ 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)],
@@ -310,77 +318,77 @@ class StockRule(models.Model):
if production_item.product_id.id in product_id_to_production_names:
# 同一个产品多个制造订单对应一个编程单和模型库
# 只调用一次fetchCNC并将所有生产订单的名称作为字符串传递
if not production_item.programming_no and production.production_type == '自动化产线加工':
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': '编程中'})
if not technology_design_values:
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(',')):
i += 1
for route in product_routing_workcenter:
technology_design_values.append(
self.env['sf.technology.design'].json_technology_design_str(k, route, i, False))
else:
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(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:
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_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))
productions.technology_design_ids = technology_design_values
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
@@ -415,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)
@@ -625,48 +635,37 @@ class StockPicking(models.Model):
return '%s%s' % (rescode, num)
def button_validate(self):
if self.picking_type_id.barcode == 'OCOUT':
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)])
res = super().button_validate()
if res is True and self.picking_type_id.sequence_code == 'OCOUT':
# 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), ('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 and self.picking_type_id.barcode == 'OCIN':
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))
('origin', '=', self.origin), ('state', 'not in', ['cancel', 'done'])])
production = self.env['mrp.production'].search([('name', '=', self.origin)])
for mi in move_in:
pick = self.env['stock.picking'].search([('id', '=', mi.picking_id.id), ('name', 'ilike', 'OCIN'),
('partner_id', '=', self.partner_id.id)])
if pick:
if mi.state != 'done':
mi.write({'state': 'assigned'})
self.env['stock.move.line'].create(mi.get_move_line(production, None))
return res
# 创建 外协出库入单
def create_outcontract_picking(self, sorted_workorders_arr, item):
domain = [('origin', '=', item.name), ('name', 'ilike', 'OCOUT')]
if len(sorted_workorders_arr) > 1:
sorted_workorders_arr = sorted_workorders_arr[0]
stock_picking = self.env['stock.picking'].search([('origin', '=', item.name), ('name', 'ilike', 'OCOUT')])
if not stock_picking or sorted_workorders_arr:
else:
domain += [
('surface_technics_parameters_id', '=', sorted_workorders_arr[0].surface_technics_parameters_id.id)]
stock_picking = self.env['stock.picking'].search(domain)
if not stock_picking:
for sorted_workorders in sorted_workorders_arr:
# pick_ids = []
if not sorted_workorders.picking_ids:
@@ -958,7 +957,7 @@ class ReStockMove(models.Model):
合并制造订单的完成move单据
"""
res = super(ReStockMove, self)._merge_moves_fields()
if self[0].origin and self.picking_type_id.name in ['生产发料', '内部调拨']:
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)])
@@ -970,19 +969,22 @@ class ReStockMove(models.Model):
创建调拨单时,在此新增或修改调拨单的数据
"""
res = super(ReStockMove, self)._get_new_picking_values()
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
## 制造订单报废生成的新制造订单不走合并
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)])
if productions.mapped('name'):
res['origin'] = ','.join(productions.mapped('name'))
res['retrospect_ref'] = production.product_id.name
return res
def _single_manufactuing_mo_generate_origin(self, res):
"""
单个制造订单的完成move单据修改来源为该制造订单关联的销售订单下所有成品相同的制造订单
"""
class ReStockQuant(models.Model):
_inherit = 'stock.quant'

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
@@ -166,16 +167,18 @@ access_sf_agv_scheduling_group_sf_mrp_manager,sf_agv_scheduling_group_sf_mrp_man
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,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,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,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
167 access_sf_production_technology_re_adjust_wizard_group_production_engineer access_sf_production_technology_re_adjust_wizard_group_plan_dispatch sf_production_technology_re_adjust_wizard_group_production_engineer sf_production_technology_re_adjust_wizard_group_plan_dispatch model_sf_production_technology_re_adjust_wizard sf_base.group_production_engineer sf_base.group_plan_dispatch 1 1 1 0
168 access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user access_sf_production_technology_re_adjust_wizard_group_sf_mrp_manager sf_manual_product_model_type_routing_sort sf_production_technology_re_adjust_wizard_group_sf_mrp_manager model_sf_manual_product_model_type_routing_sort model_sf_production_technology_re_adjust_wizard sf_base.group_sf_mrp_user sf_base.group_sf_mrp_manager 1 0 1 0 1 0
169 access_sf_manual_product_model_type_routing_sort_manager access_sf_production_technology_re_adjust_wizard_group_production_engineer sf_manual_product_model_type_routing_sort sf_production_technology_re_adjust_wizard_group_production_engineer model_sf_manual_product_model_type_routing_sort model_sf_production_technology_re_adjust_wizard sf_base.group_sf_mrp_manager sf_base.group_production_engineer 1 1 1 0
170 access_sf_manual_product_model_type_routing_sort_group_plan_dispatch access_sf_manual_product_model_type_routing_sort_group_sf_mrp_user sf_manual_product_model_type_routing_sort_group_plan_dispatch sf_manual_product_model_type_routing_sort model_sf_manual_product_model_type_routing_sort sf_base.group_plan_dispatch sf_base.group_sf_mrp_user 1 0 0 0
171 access_sf_detection_result_manager access_sf_manual_product_model_type_routing_sort_manager sf_detection_result_manager sf_manual_product_model_type_routing_sort model_sf_detection_result 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

@@ -31,7 +31,7 @@
<form string="模型类型">
<group>
<field name="name" required="1"/>
<field name="embryo_tolerance_id" required="1" string="坯料容余(mm)"/>
<field name="embryo_tolerance_id" required="1"/>
</group>
<group>
<field name='product_routing_tmpl_ids'>

View File

@@ -120,7 +120,8 @@
<!-- <field name="production_line_state" readonly="1"/>-->
<field name="part_name"/>
<field name="part_number" string="零件图号"/>
<field name="tool_state" attrs="{'invisible': [('production_type', 'not in', ['自动化产线加工'])]}"/>
<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"/>
@@ -365,8 +366,10 @@
<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)]}"
string="参数" context="{'route_id':route_id}" 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'"
@@ -387,13 +390,16 @@
</page>
</xpath>
<xpath expr="//sheet/group/group/div[@class='d-flex flex-row align-items-start']/span[last()]" position="attributes">
<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">
<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">
<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>
@@ -732,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

@@ -32,6 +32,7 @@
</field>
<xpath expr="//field[@name='qty_remaining']" position="after">
<field name="manual_quotation" optional="show"/>
<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 == '预警'"
@@ -138,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"/>
@@ -199,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="解绑托盘"
@@ -251,7 +252,7 @@
decoration-danger="tag_type == '重新加工'"/>
<field name="is_test_env" invisible="1"/>
<field name="rfid_code" force_save="1" readonly="1" cache="True"
attrs="{'invisible': [('rfid_code_old', '!=', False)]}" />
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)]}"/>

View File

@@ -1,17 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<odoo>
<record id="view_order_form_inherit_sf" model="ir.ui.view">
<field name="name">view.sale.order.form.inherit.sf</field>
<field name="inherit_id" ref="sale_stock.view_order_form_inherit_sale_stock_qty"/>
<field name="model">sale.order</field>
<field name="arch" type="xml">
<xpath expr="//page/field[@name='order_line']/form/group/group/div[@name='ordered_qty']/widget[@name='qty_at_date_widget']" position="replace">
</xpath>
<xpath expr="//page/field[@name='order_line']/tree/widget[@name='qty_at_date_widget']" position="replace">
</xpath>
</field>
</record>
<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"/>
@@ -103,6 +91,4 @@
<field name="groups_id" eval="[(4, ref('sf_base.group_production_engineer'))]"/>
</record>
</odoo>

View File

@@ -51,5 +51,10 @@
</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

@@ -14,7 +14,7 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
def confirm(self):
if self.is_technology_re_adjust is True:
domain = [('origin', '=', self.origin), ('state', '=', 'technology_to_confirmed'),
domain = [('origin', '=', self.origin), ('state', '=', 'confirmed'),
('product_id', '=', self.production_id.product_id.id)]
else:
domain = [('id', '=', self.production_id.id)]
@@ -49,8 +49,8 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
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 += [('name', 'ilike', display_name)]
# 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)
@@ -62,29 +62,34 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
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)]
else:
domain += [('name', '=', special.route_id.name)]
domain += [('technology_design_id', '=', special.id)]
workorder = self.env['mrp.workorder'].search(domain)
if workorder.state != 'cancel':
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.origin)])
[('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:
if special.route_id.routing_type == '表面工艺':
display_name = special.process_parameters_id.display_name
else:
display_name = special.route_id.display_name
workorder = self.env['mrp.workorder'].search(
[('name', '=', display_name), ('production_id', '=', special.production_id.id)])
[('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id)])
if not workorder:
if special.route_id.routing_type == '表面工艺':
product_production_process = self.env['product.template'].search(
@@ -99,11 +104,13 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
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:
workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0]
if workorder.blocked_by_workorder_ids:
workorder.blocked_by_workorder_ids = blocked_by_workorder_ids[0]
productions._reset_work_order_sequence()
if self.production_id.product_id.categ_id.type == '成品':
productions._reset_subcontract_pick_purchase()
@@ -113,5 +120,6 @@ class ProductionTechnologyReAdjustWizard(models.TransientModel):
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 workorder[0].production_id.product_id.categ_id.type == '成品' and item.programming_state != '已编程':
if workorders[
0].production_id.product_id.categ_id.type == '成品' and item.programming_state != '已编程':
workorders[0].state = 'waiting'

View File

@@ -46,16 +46,68 @@ class ProductionTechnologyWizard(models.TransientModel):
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 += [('name', 'ilike', display_name)]
# 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 = production.technology_design_ids.filtered(
# lambda td: td.is_auto is False and td.process_parameters_id is not False)
# # if special:
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)]
else:
domain += [('technology_design_id', '=', special.id)]
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:
if special.production_id.workorder_ids:
workorder = self.env['mrp.workorder'].search(
[('technology_design_id', '=', special.id), ('production_id', '=', special.production_id.id)])
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()
@@ -65,4 +117,4 @@ class ProductionTechnologyWizard(models.TransientModel):
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 != '已编程':
workorders[0].state = 'waiting'
workorder[0].state = 'waiting'

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):
@@ -15,6 +16,7 @@ class ReworkWizard(models.TransientModel):
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", "操机"),
@@ -36,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
@@ -50,9 +76,26 @@ class ReworkWizard(models.TransientModel):
'test_report': self.workorder_id.detection_report})]})
self.workorder_id.button_finish()
else:
if self.workorder_ids:
rework_workorder_ids = self.production_id.workorder_ids.filtered(
lambda ap: ap.id in self.workorder_ids.ids)
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:
# 限制

View File

@@ -12,9 +12,15 @@
<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="workorder_ids" string="工序" attrs='{"invisible": [("routing_type","=","装夹预调")]}'>
<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>

View File

@@ -32,6 +32,12 @@ class Sf_Mrs_Connect(http.Controller, MultiInheritController):
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(','):

View File

@@ -231,26 +231,39 @@ class sf_production_plan(models.Model):
if not record.production_line_id:
raise ValidationError("未选择生产线")
else:
# 自动化产线加工
if record.production_id.workorder_ids:
last_cnc_start = record.date_planned_start if record.date_planned_start else datetime.now()
for item in record.production_id.workorder_ids:
if item.name == 'CNC加工':
# 将同一个面的所有工单筛选出来
workorder_list = record.production_id.workorder_ids.filtered(lambda x: x.processing_panel == item.processing_panel)
routing_workcenter = record.env['mrp.routing.workcenter'].sudo().search(
[('name', '=', 'CNC加工')], limit=1)
# 设置一个小的开始时间
item.date_planned_start = datetime.now() - timedelta(days=100)
item.date_planned_finished = last_cnc_start + timedelta(
minutes=routing_workcenter.time_cycle)
item.date_planned_start = last_cnc_start
record.sudo().production_id.plan_start_processing_time = item.date_planned_start
item.duration_expected = routing_workcenter.time_cycle
pre_duration , next_duration = record.calculate_plan_time(item, workorder_list)
record.date_planned_finished = item.date_planned_finished
# 计算下一个cnc工单的开始时间
last_cnc_start = workorder_list[-1].date_planned_finished + timedelta(minutes=pre_duration)
# 没有工单也能排程
# 自动化产线加工
if record.production_id.production_type == '自动化产线加工':
# 找到第一张CNC加工工单
first_cnc_workorder = record.production_id.workorder_ids.filtered(lambda x: x.name == 'CNC加工')[0]
date_start = record.date_planned_start if record.date_planned_start else datetime.now()
routing_workcenter = first_cnc_workorder.technology_design_id.route_id
# 设置一个小的开始时间
first_cnc_workorder.date_planned_start = datetime.now() - timedelta(days=100)
first_cnc_workorder.date_planned_finished = date_start + timedelta(
minutes=routing_workcenter.time_cycle + routing_workcenter.reserved_duration)
first_cnc_workorder.date_planned_start = date_start
record.sudo().production_id.plan_start_processing_time = first_cnc_workorder.date_planned_start
first_cnc_workorder.duration_expected = routing_workcenter.time_cycle + routing_workcenter.reserved_duration
record.calculate_plan_time(first_cnc_workorder, record.production_id.workorder_ids)
# 找到最后一张CNC加工工单
last_cnc_workorder = record.production_id.workorder_ids.filtered(lambda x: x.name == 'CNC加工')[-1]
record.date_planned_finished = last_cnc_workorder.date_planned_finished
else:
# 人工线下加工只排第一张工单
item = record.production_id.workorder_ids[0]
wo_start = record.date_planned_start if record.date_planned_start else datetime.now()
routing_workcenter = item.technology_design_id.route_id
item.date_planned_start = datetime.now() - timedelta(days=100)
item.date_planned_finished = wo_start + timedelta(
minutes=routing_workcenter.time_cycle + routing_workcenter.reserved_duration)
item.date_planned_start = wo_start
record.sudo().production_id.plan_start_processing_time = item.date_planned_start
item.duration_expected = routing_workcenter.time_cycle + routing_workcenter.reserved_duration
record.calculate_plan_time(item, record.production_id.workorder_ids)
last_cnc_workorder = record.production_id.workorder_ids[-1]
record.date_planned_finished = last_cnc_workorder.date_planned_finished
record.state = 'done'
# record.production_id.schedule_state = '已排'
record.sudo().production_id.schedule_state = '已排'
@@ -259,10 +272,10 @@ class sf_production_plan(models.Model):
# sale_obj = self.env['sale.order'].search([('name', '=', record.origin)])
# if 'S' in sale_obj.name:
# sale_obj.schedule_status = 'to process'
mrp_production_ids = record.production_id._get_children().ids
print('mrp_production_ids', mrp_production_ids)
for i in mrp_production_ids:
record.env['mrp.production'].sudo().browse(i).schedule_state = '已排'
# mrp_production_ids = record.production_id._get_children().ids
# print('mrp_production_ids', mrp_production_ids)
# for i in mrp_production_ids:
# record.env['mrp.production'].sudo().browse(i).schedule_state = '已排'
# record.production_id.date_planned_start = record.date_planned_start
# record.production_id.date_planned_finished = record.date_planned_finished
record.sudo().production_id.production_line_id = record.production_line_id.id
@@ -306,44 +319,40 @@ class sf_production_plan(models.Model):
def calculate_plan_time(self, item, workorder_list):
"""
根据CNC工单的时间去计算之前的其他工单的开始结束时间
param:
item: 基准工单(根据该工单的开始结束时间去计算其他工单的开始结束时间)
workorder_list: 需排程的工单列表
"""
item_position = 0
for index, workorder in enumerate(workorder_list):
if workorder.id == item.id:
item_position = index
break
routing_workcenters = self.env['mrp.routing.workcenter'].sudo().search([])
# 记录所有前序工序时长
previous_workorder_duration = 0
for i in range(item_position, -1, -1):
if i < 1:
break
current_workorder = workorder_list[i]
next_workorder = workorder_list[i - 1]
routing_workcenter = routing_workcenters.filtered(lambda x: x.name == next_workorder.name)[0]
routing_workcenter = next_workorder.technology_design_id.route_id
# 设置一个小的开始时间
next_workorder.date_planned_start = datetime.now() - timedelta(days=100)
next_workorder.date_planned_finished = current_workorder.date_planned_start
next_workorder.date_planned_start = next_workorder.date_planned_finished - timedelta(
minutes=routing_workcenter.time_cycle)
next_workorder.duration_expected = routing_workcenter.time_cycle
previous_workorder_duration += routing_workcenter.time_cycle
# 记录所有后续工序时长
next_workorder_duration = 0
minutes=routing_workcenter.time_cycle + routing_workcenter.reserved_duration)
next_workorder.duration_expected = routing_workcenter.time_cycle + routing_workcenter.reserved_duration
for i in range(item_position, len(workorder_list) - 1):
if i > len(workorder_list) - 1:
break
current_workorder = workorder_list[i]
next_workorder = workorder_list[i + 1]
routing_workcenter = routing_workcenters.filtered(lambda x: x.name == next_workorder.name)[0]
routing_workcenter = next_workorder.technology_design_id.route_id
# 设置一个小的开始时间
next_workorder.date_planned_start = datetime.now() - timedelta(days=100)
next_workorder.date_planned_finished = current_workorder.date_planned_finished + timedelta(
minutes=routing_workcenter.time_cycle)
minutes=routing_workcenter.time_cycle + routing_workcenter.reserved_duration)
next_workorder.date_planned_start = current_workorder.date_planned_finished
next_workorder.duration_expected = routing_workcenter.time_cycle
next_workorder_duration += routing_workcenter.time_cycle
return previous_workorder_duration, next_workorder_duration
next_workorder.duration_expected = routing_workcenter.time_cycle + routing_workcenter.reserved_duration
def calculate_plan_time_after(self, item, workorder_id_list):
"""

View File

@@ -15907,7 +15907,7 @@ msgstr "内部参考"
#: model_terms:ir.ui.view,arch_db:account.account_journal_dashboard_kanban_view
#, python-format
msgid "Internal Transfer"
msgstr "内部转账"
msgstr "厂内出入库"
#. module: account
#: model:ir.model.fields,field_description:account.field_res_config_settings__transfer_account_id
@@ -16133,7 +16133,7 @@ msgstr "库存概览"
#. module: stock
#: model:ir.actions.act_window,name:stock.stock_picking_type_action
msgid "Internal Transfers"
msgstr "厂内出入库"
msgstr "库存概览"
#. module: stock
#: model:ir.model.fields,field_description:stock.field_stock_quant__inventory_quantity_set

View File

@@ -25,7 +25,7 @@ class SfQualityCncTest(models.Model):
('pass', '合格'),
('fail', '不合格')], string='判定结果')
number = fields.Integer('数量', default=1)
test_results = fields.Selection([("合格", "合格"), ("返工", "返工"), ("报废", "报废")], string="检测结果")
test_results = fields.Selection([("合格", "合格")], string="检测结果")
reason = fields.Selection(
[("programming", "编程"), ("cutter", "刀具"), ("clamping", "装夹"), ("operate computer", "操机"),
("technology", "工艺"), ("customer redrawing", "客户改图")], string="原因")

View File

@@ -11,6 +11,7 @@ access_quality_point_group_sf_mrp_manager,quality_point_group_sf_mrp_manager,qua
access_quality_check_group_quality,quality_check_group_quality,quality.model_quality_check,sf_base.group_quality,1,1,1,0
access_quality_check_group_quality_director,quality_check_group_quality_director,quality.model_quality_check,sf_base.group_quality_director,1,1,1,0
access_quality_check_group_plan_dispatch,quality_check_group_plan_dispatch,quality.model_quality_check,sf_base.group_plan_dispatch,1,0,0,0
access_quality_check_group_sf_stock_user,quality_check_group_sf_stock_user,quality.model_quality_check,sf_base.group_sf_stock_user,1,0,0,0
access_quality_check_group_plan_director,quality_check_group_plan_director,quality.model_quality_check,sf_base.group_plan_director,1,0,0,0
access_quality_check_group_purchase,quality_check_group_purchase,quality.model_quality_check,sf_base.group_purchase,1,0,0,0
access_quality_check_group_purchase_director,quality_check_group_purchase_director,quality.model_quality_check,sf_base.group_purchase_director,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
11 access_quality_check_group_quality_director quality_check_group_quality_director quality.model_quality_check sf_base.group_quality_director 1 1 1 0
12 access_quality_check_group_plan_dispatch quality_check_group_plan_dispatch quality.model_quality_check sf_base.group_plan_dispatch 1 0 0 0
13 access_quality_check_group_plan_director access_quality_check_group_sf_stock_user quality_check_group_plan_director quality_check_group_sf_stock_user quality.model_quality_check sf_base.group_plan_director sf_base.group_sf_stock_user 1 0 0 0
14 access_quality_check_group_plan_director quality_check_group_plan_director quality.model_quality_check sf_base.group_plan_director 1 0 0 0
15 access_quality_check_group_purchase quality_check_group_purchase quality.model_quality_check sf_base.group_purchase 1 0 0 0
16 access_quality_check_group_purchase_director quality_check_group_purchase_director quality.model_quality_check sf_base.group_purchase_director 1 0 0 0
17 access_quality_check_group_sf_equipment_user quality_check_group_sf_equipment_user quality.model_quality_check sf_base.group_sf_equipment_user 1 0 0 0

View File

@@ -131,7 +131,7 @@ class ReSaleOrder(models.Model):
product.materials_id.name),
'price_unit': product.list_price,
'product_uom_qty': item['number'],
'model_glb_file': base64.b64decode(item['model_file']),
'model_glb_file': base64.b64decode(item['model_file']) if item['model_file'] else None,
'remark': item.get('remark'),
'embryo_redundancy_id': item.get('embryo_redundancy_id'),
'is_incoming_material': True if item.get('embryo_redundancy_id') else False,
@@ -250,38 +250,43 @@ class RePurchaseOrder(models.Model):
server_product_process = []
production_process = product_id_to_production_names.get(
production.product_id.id)
purchase_order = self.env['purchase.order'].search(
[('state', '=', 'draft'), ('origin', '=', production.name),
('purchase_type', '=', 'consignment')], order='name asc')
for pp in consecutive_process_parameters:
server_template = self.env['product.template'].search(
[('server_product_process_parameters_id', '=', pp.surface_technics_parameters_id.id),
('detailed_type', '=', 'service')])
purchase_order_line = self.env['purchase.order.line'].search(
[('product_id', '=', server_template.product_variant_id.id),
('product_qty', '=', len(production_process))], limit=1, order='id desc')
if not purchase_order_line:
if not purchase_order:
server_product_process.append((0, 0, {
'product_id': server_template.product_variant_id.id,
'product_qty': len(production_process),
'product_qty': 1,
'product_uom': server_template.uom_id.id
}))
else:
if production.name in production_process:
purchase_order = self.env['purchase.order'].search(
[('state', '=', 'draft'), ('origin', '=', ','.join(production_process)),
('purchase_type', '=', 'consignment')])
if not purchase_order:
server_product_process.append((0, 0, {
'product_id': server_template.product_variant_id.id,
'product_qty': len(production_process),
'product_uom': server_template.uom_id.id
}))
for purchase in purchase_order:
for po in purchase.order_line:
if po.product_id == server_template.product_variant_id:
continue
if server_template.server_product_process_parameters_id != po.product_id.server_product_process_parameters_id:
purchase_order_line = self.env['purchase.order.line'].search(
[('product_id', '=', server_template.product_variant_id.id),
('product_qty', '=', 1.0), ('id', '=', purchase.id)], limit=1,
order='id desc')
if not purchase_order_line:
server_product_process.append((0, 0, {
'product_id': server_template.product_variant_id.id,
'product_qty': 1,
'product_uom': server_template.uom_id.id
}))
if server_product_process:
self.env['purchase.order'].sudo().create({
purchase_order = self.env['purchase.order'].sudo().create({
'partner_id': server_template.seller_ids[0].partner_id.id,
'origin': ','.join(production_process),
'origin': production.name,
'state': 'draft',
'purchase_type': 'consignment',
'order_line': server_product_process})
consecutive_process_parameters.purchase_id = [(6, 0, [purchase_order.id])]
# self.env.cr.commit()
@api.onchange('order_line')

View File

@@ -117,7 +117,7 @@ access_sf_detection_result_group_sale_director,sf_detection_result_group_sale_di
access_stock_scrap_group_sale_salemanager,stock_scrap_group_sale_salemanager,stock.model_stock_scrap,sf_base.group_sale_salemanager,1,0,0,0
access_stock_scrap_group_sale_director,stock_scrap_group_sale_director,stock.model_stock_scrap,sf_base.group_sale_director,1,0,0,0
access_account_move_group_plan_dispatch,account_move_group_plan_dispatch,account.model_account_move,sf_base.group_plan_dispatch,1,1,1,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
117
118
119
120
121
122
123

View File

@@ -25,7 +25,7 @@
'data': [
# 'security/ir.model.access.csv',
'views/stock_picking.xml',
'views/stock_product_template.xml'
'views/stock_product_template.xml',
],
# only loaded in demonstration mode
'demo': [

View File

@@ -221,5 +221,6 @@ class MrpProduction(models.Model):
logging.info('调用CAM工单程序用刀计划创建方法')
self.env['sf.cam.work.order.program.knife.plan'].sudo().create_cam_work_plan(cnc_ids)
if not invalid_tool and not missing_tool_1:
self.sudo().write({'tool_state': '0'})
logging.info('校验cnc用刀正常!')
logging.info('工单cnc程序用刀校验完成')

View File

@@ -602,7 +602,7 @@ var GanttRow = Widget.extend({
// pill._color = self._getColor(pill[self.colorField]);
// 设置pill背景颜色2 修改时间2024年6月25日17:09:43
let isDelay = false
if(pill.state != 'processing' && pill.state != 'finished') { // 判断待加工
if(pill.state != 'processing' && pill.state != 'finished' && pill.order_deadline) { // 判断待加工
isDelay = pill.order_deadline.isBefore(new Date())
}
if(isDelay) {