Compare commits
759 Commits
feature/产品
...
master_sf_
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8ced717b1c | ||
|
|
187495eb67 | ||
|
|
5fccd41e07 | ||
|
|
0ae0ad2ba8 | ||
|
|
afb5316d8a | ||
|
|
585e7236a1 | ||
|
|
3afa76b79c | ||
|
|
6d503968a5 | ||
|
|
cc7963cb5a | ||
|
|
e2fdfbf1ee | ||
|
|
cdf164ec2c | ||
|
|
f9cca591bb | ||
|
|
6f3d423da1 | ||
|
|
1bcd1f2e33 | ||
|
|
9284701ed4 | ||
|
|
2c5cc91ef7 | ||
|
|
c6039215a3 | ||
|
|
21027a8cb6 | ||
|
|
80cd385df4 | ||
|
|
d7bcb0e4f3 | ||
|
|
f62994878c | ||
|
|
50b0c37e46 | ||
|
|
dc381faae6 | ||
|
|
f05301320c | ||
|
|
d87fcb35ba | ||
|
|
be69e76d2f | ||
|
|
debd788864 | ||
|
|
2546dd73b2 | ||
|
|
9f2415cfac | ||
|
|
2e151a2292 | ||
|
|
9b2ff6268c | ||
|
|
d1c08023b9 | ||
|
|
5f02de8b0c | ||
|
|
0f5b94e8ca | ||
|
|
795b4d43a8 | ||
|
|
d9d1f86407 | ||
|
|
337fecb4cb | ||
|
|
4be83d8aab | ||
|
|
049521064b | ||
|
|
9e2091597b | ||
|
|
01f82fcb5d | ||
|
|
939aa974e6 | ||
|
|
829c971848 | ||
|
|
a4b2d5bb42 | ||
|
|
ebdc1ec2ff | ||
|
|
f0d66b7730 | ||
|
|
a935112134 | ||
|
|
70bc2ed718 | ||
|
|
c230e550a9 | ||
|
|
297bf76809 | ||
|
|
2dc9866735 | ||
|
|
305e91e7f1 | ||
|
|
a5b9b63b41 | ||
|
|
1a0e96bbdd | ||
|
|
095c15cba4 | ||
|
|
fe6bb46d54 | ||
|
|
432a012596 | ||
|
|
27b5e92563 | ||
|
|
e5164454f2 | ||
|
|
b79cdea926 | ||
|
|
836a598cf8 | ||
|
|
3a0a4b0f15 | ||
|
|
cda0b6d345 | ||
|
|
7e31869d1f | ||
|
|
ea1ed43c92 | ||
|
|
eb83114e54 | ||
|
|
af45775040 | ||
|
|
03f5027f49 | ||
|
|
20ecd9d949 | ||
|
|
ed2c119803 | ||
|
|
37cf4ca435 | ||
|
|
1c441d388f | ||
|
|
d244409d9c | ||
|
|
1a66d6728e | ||
|
|
002c5c06b4 | ||
|
|
de62801ef1 | ||
|
|
62ec721c69 | ||
|
|
2194374aa2 | ||
|
|
eff6ce9f1b | ||
|
|
9fcfaee8d1 | ||
|
|
90aae4dad9 | ||
|
|
934b59d213 | ||
|
|
ed9b575fb5 | ||
|
|
bcd7ae9dd1 | ||
|
|
48782cb62b | ||
|
|
0f47f7c3b8 | ||
|
|
d9f339c4b0 | ||
|
|
d4b22d228b | ||
|
|
e916e4e155 | ||
|
|
9dccee84c4 | ||
|
|
97ce5d81c8 | ||
|
|
c6638ac3f3 | ||
|
|
05e8507000 | ||
|
|
1afc48a20e | ||
|
|
053cd5fd89 | ||
|
|
391a172016 | ||
|
|
d3677b9c89 | ||
|
|
384b032ef3 | ||
|
|
0ddf2ce1bd | ||
|
|
05307fa25e | ||
|
|
76b7d00643 | ||
|
|
0f8c4e8765 | ||
|
|
a1081fe8cc | ||
|
|
47ed09152d | ||
|
|
50dc25a8b7 | ||
|
|
b80df25e0a | ||
|
|
999959b6a1 | ||
|
|
ec01b89242 | ||
|
|
c932fa035a | ||
|
|
2bffc5964a | ||
|
|
7d7096a36c | ||
|
|
6c70f43b1b | ||
|
|
016a279453 | ||
|
|
52bbc6f6cd | ||
|
|
1dfa890a4d | ||
|
|
d9543d42fd | ||
|
|
b5c9387d8c | ||
|
|
c4609e35a5 | ||
|
|
3d56e54fb2 | ||
|
|
494b6c69da | ||
|
|
e2d3b36683 | ||
|
|
138e22255e | ||
|
|
7200d03733 | ||
|
|
f3c98c9727 | ||
|
|
6a4fd4d922 | ||
|
|
38298f4a32 | ||
|
|
41603f4caa | ||
|
|
1a63f82f4b | ||
|
|
0ea3d6f0b3 | ||
|
|
54a08802d9 | ||
|
|
388b0b4e4c | ||
|
|
db7382826e | ||
|
|
07cf13dce7 | ||
|
|
28f4adb293 | ||
|
|
ac3081d3bf | ||
|
|
4e84562ba7 | ||
|
|
72d59c11db | ||
|
|
8c279828be | ||
|
|
95a77574ae | ||
|
|
5c68dd45ee | ||
|
|
af822c9039 | ||
|
|
92ea9b2a4f | ||
|
|
5eacc01755 | ||
|
|
72ea4c8a2c | ||
|
|
4bea41b8fd | ||
|
|
f6373366b6 | ||
|
|
339c6ec2ee | ||
|
|
e7ca8ebd9b | ||
|
|
d964a9feb1 | ||
|
|
da139ad30b | ||
|
|
30053c5493 | ||
|
|
fda43deeea | ||
|
|
cb5cfec82a | ||
|
|
8b533475b8 | ||
|
|
7cbe1cb35d | ||
|
|
b8196cc4a9 | ||
|
|
ed41667477 | ||
|
|
ca3cdd9132 | ||
|
|
5551cc51e2 | ||
|
|
178edd645e | ||
|
|
848fe9f2f0 | ||
|
|
2cd666c4ae | ||
|
|
9d157d6083 | ||
|
|
ab73deeeaa | ||
|
|
68c4c18642 | ||
|
|
402a4e1740 | ||
|
|
68d8c36755 | ||
|
|
b45ffcc0d2 | ||
|
|
58e1754ae2 | ||
|
|
a1f0a580a6 | ||
|
|
952c24eb26 | ||
|
|
fbfd932561 | ||
|
|
cc590134f5 | ||
|
|
338d620d5b | ||
|
|
58344b09d2 | ||
|
|
3d76d5f0b9 | ||
|
|
b1d42b9421 | ||
|
|
cec066c082 | ||
|
|
239be9f4ea | ||
|
|
537e890926 | ||
|
|
9e10382dd7 | ||
|
|
3a22c817df | ||
|
|
782e266988 | ||
|
|
f3f138e93c | ||
|
|
8c78a24f7e | ||
|
|
45220d75af | ||
|
|
9d9b454ba5 | ||
|
|
bc2c0f7fb0 | ||
|
|
809f5a196e | ||
|
|
281b041a31 | ||
|
|
1fa45a36f1 | ||
|
|
24722f474c | ||
|
|
5eb946d936 | ||
|
|
b7f7f0cdff | ||
|
|
42178e3e1e | ||
|
|
2ebd543d39 | ||
|
|
f452f0018f | ||
|
|
cd3feb787f | ||
|
|
d0e7dbefc9 | ||
|
|
8f9781dd13 | ||
|
|
50aae8a1e8 | ||
|
|
41e551fe48 | ||
|
|
1293c327c6 | ||
|
|
74deef3d41 | ||
|
|
466dfa4889 | ||
|
|
66dcc2f982 | ||
|
|
9362a78f2a | ||
|
|
9eb891dd0b | ||
|
|
84b82cac1d | ||
|
|
761efbceaa | ||
|
|
4bcd6b9944 | ||
|
|
da22015d35 | ||
|
|
eb2b37eb06 | ||
|
|
cd6a4b0a38 | ||
|
|
8bbb18b6f4 | ||
|
|
11864feaa4 | ||
|
|
735f602f2d | ||
|
|
53ed0d76a6 | ||
|
|
9d96e0681c | ||
|
|
961f7bfdc5 | ||
|
|
9374bab0ce | ||
|
|
780944047f | ||
|
|
edd1f9a1ee | ||
|
|
be18124186 | ||
|
|
a400beb0a4 | ||
|
|
f4433ac3cc | ||
|
|
b237e353a9 | ||
|
|
0bcd077914 | ||
|
|
212f2df830 | ||
|
|
192aecb17d | ||
|
|
6f2043e7e7 | ||
|
|
0473e79fcf | ||
|
|
6ecc69590b | ||
|
|
f570eb9b50 | ||
|
|
d4aa71975e | ||
|
|
3e7bef095c | ||
|
|
673a1c6448 | ||
|
|
231536089d | ||
|
|
347e7f3efe | ||
|
|
31e3f53873 | ||
|
|
b6334caf97 | ||
|
|
a83b8bcd14 | ||
|
|
59c8631c15 | ||
|
|
24d8c2426c | ||
|
|
9778245ee7 | ||
|
|
228770cb76 | ||
|
|
b80ba02c8f | ||
|
|
1344bd7219 | ||
|
|
90d1f96857 | ||
|
|
ca01b055b8 | ||
|
|
1d54066664 | ||
|
|
5488846c85 | ||
|
|
d2f59f6c6a | ||
|
|
c1addd823e | ||
|
|
c56886aebe | ||
|
|
1979b33c32 | ||
|
|
1fa5ebd80a | ||
|
|
f1dad7701f | ||
|
|
8bc23f5136 | ||
|
|
bcff104013 | ||
|
|
307e052740 | ||
|
|
f236b149d8 | ||
|
|
9cfc084c5c | ||
|
|
da48e0aea2 | ||
|
|
4e94b8b4c8 | ||
|
|
6af611b7c9 | ||
|
|
9a157125ba | ||
|
|
49e4f92a91 | ||
|
|
080a3d7175 | ||
|
|
b526565ac4 | ||
|
|
690a66b6a1 | ||
|
|
c0db402f5e | ||
|
|
d634cf20ba | ||
|
|
220af93ed6 | ||
|
|
eb6607be00 | ||
|
|
4b2e58a66d | ||
|
|
9c5b3d7c4e | ||
|
|
9cb1b8c5aa | ||
|
|
e108e2d5d6 | ||
|
|
90c87f7ddb | ||
|
|
f0bfd18549 | ||
|
|
c86fd099eb | ||
|
|
857d5d8916 | ||
|
|
5cb1e3c838 | ||
|
|
45b300f8a1 | ||
|
|
a30c620823 | ||
|
|
263b8ddec7 | ||
|
|
89eccb40ac | ||
|
|
761d0b0417 | ||
|
|
f22ee428b6 | ||
|
|
1a860a5eb9 | ||
|
|
96a4ee4e26 | ||
|
|
80f0284c3c | ||
|
|
bcba08042b | ||
|
|
25ee2136c3 | ||
|
|
50f5815070 | ||
|
|
b43c3496a1 | ||
|
|
f1972ca572 | ||
|
|
5f2600c96f | ||
|
|
040b3b16f0 | ||
|
|
67f3c312de | ||
|
|
f26b4510cf | ||
|
|
053fa3feb3 | ||
|
|
59670fb3d7 | ||
|
|
8dfef16b51 | ||
|
|
3d1dd533b5 | ||
|
|
83d1d397f5 | ||
|
|
0a9cfd916a | ||
|
|
2e5dd55a7b | ||
|
|
4fb57373d5 | ||
|
|
8a85581347 | ||
|
|
22c388f52c | ||
|
|
0103024f1c | ||
|
|
988241a1bd | ||
|
|
92af278451 | ||
|
|
19b062f5ac | ||
|
|
7897e6e55b | ||
|
|
259f12a11f | ||
|
|
c6b1c5e047 | ||
|
|
38c89a4167 | ||
|
|
59683790b7 | ||
|
|
ceae788ecc | ||
|
|
f04cbac8d9 | ||
|
|
36db60812e | ||
|
|
3c47553be6 | ||
|
|
c535808d5f | ||
|
|
d8a876796a | ||
|
|
d777970a9b | ||
|
|
d1e9254996 | ||
|
|
028eb18dd8 | ||
|
|
c4ddd067e7 | ||
|
|
48cba4274b | ||
|
|
9df62129b7 | ||
|
|
65330b083b | ||
|
|
543f1a8e9b | ||
|
|
19156f5944 | ||
|
|
9ac3ef7c93 | ||
|
|
3f9eb762f9 | ||
|
|
ef0e09ba4b | ||
|
|
eb2db1dfdd | ||
|
|
180db6b91e | ||
|
|
482dbb9baa | ||
|
|
4391a4e145 | ||
|
|
010fbb23b0 | ||
|
|
7f6444cc89 | ||
|
|
b5767970a4 | ||
|
|
422e4bda6c | ||
|
|
29790b7760 | ||
|
|
310a2de34f | ||
|
|
12a54d1f2a | ||
|
|
f19a1a282a | ||
|
|
cc7a72d6f4 | ||
|
|
1681e9e4da | ||
|
|
cf3514e407 | ||
|
|
abdb636176 | ||
|
|
85649daef6 | ||
|
|
8eee9d9173 | ||
|
|
c104ecf24b | ||
|
|
961b4f8e2d | ||
|
|
0a4c86f601 | ||
|
|
9e5843c4a8 | ||
|
|
e9bca64f20 | ||
|
|
34ea140941 | ||
|
|
0dc94fa69b | ||
|
|
4c9fbab471 | ||
|
|
51685ba68b | ||
|
|
04de8fe9de | ||
|
|
bb29db2ff5 | ||
|
|
3f86dd48ec | ||
|
|
00802f9fc0 | ||
|
|
07230703d8 | ||
|
|
4cd2cbe1a7 | ||
|
|
6bddc4c262 | ||
|
|
4faeda11b8 | ||
|
|
3a484682fa | ||
|
|
556c3cb4bb | ||
|
|
000280e53a | ||
|
|
4dd733c466 | ||
|
|
92e522905c | ||
|
|
2ef832c17e | ||
|
|
7fd92e44b3 | ||
|
|
392784041c | ||
|
|
02e5972272 | ||
|
|
eb3583222c | ||
|
|
aac5195b4d | ||
|
|
715119d250 | ||
|
|
9ed3930a1b | ||
|
|
2580e0c795 | ||
|
|
f4f1c9f839 | ||
|
|
827e056dc8 | ||
|
|
02e4987281 | ||
|
|
e89b8ac65c | ||
|
|
f0b972e705 | ||
|
|
5c220af28c | ||
|
|
82947a909e | ||
|
|
18dcb79116 | ||
|
|
8d1e4a89c2 | ||
|
|
48809cd654 | ||
|
|
35fd1e329d | ||
|
|
af289b7030 | ||
|
|
5b3ee99bf3 | ||
|
|
be975ea901 | ||
|
|
1451539bb4 | ||
|
|
154e7de8a4 | ||
|
|
d21b25467b | ||
|
|
71b7b07949 | ||
|
|
4115bbb05e | ||
|
|
c380d99a26 | ||
|
|
a0d50edc84 | ||
|
|
2aa29e5cbf | ||
|
|
32907109ef | ||
|
|
303fcfaabd | ||
|
|
f767433a96 | ||
|
|
3eae506e48 | ||
|
|
0ddefacda7 | ||
|
|
42a748e0f8 | ||
|
|
63263e3509 | ||
|
|
aaf782b4a1 | ||
|
|
ce069e8b50 | ||
|
|
609ea62d0d | ||
|
|
f7f9cf1e43 | ||
|
|
75eb359c5a | ||
|
|
7906ff2836 | ||
|
|
5e97747ec1 | ||
|
|
ead758d34c | ||
|
|
decb6c7792 | ||
|
|
b83e5575dc | ||
|
|
a003987111 | ||
|
|
db2052a019 | ||
|
|
ca06d11d79 | ||
|
|
e63eed3405 | ||
|
|
d05c0951eb | ||
|
|
0500a2dd02 | ||
|
|
37ea48dbee | ||
|
|
48cd8399f4 | ||
|
|
ee3c0d702d | ||
|
|
1212ea0930 | ||
|
|
ed8c39d005 | ||
|
|
fe4782eecf | ||
|
|
57bfec02eb | ||
|
|
53c4b01a74 | ||
|
|
5b535fae18 | ||
|
|
ba79b358a9 | ||
|
|
c788392b36 | ||
|
|
d3819e818b | ||
|
|
0725b7a7ba | ||
|
|
a07563e166 | ||
|
|
2407d2cfc7 | ||
|
|
f38c062804 | ||
|
|
0363f8c8a3 | ||
|
|
2e83fc2e44 | ||
|
|
952e663b31 | ||
|
|
bb78404772 | ||
|
|
e5b6f2dcdc | ||
|
|
3458deef09 | ||
|
|
f8d1bff5d3 | ||
|
|
d3e050bd21 | ||
|
|
c470935cc5 | ||
|
|
b053edd655 | ||
|
|
0324acd4fd | ||
|
|
3eb274aa01 | ||
|
|
d4c786ff1e | ||
|
|
ab58f5b40c | ||
|
|
83327136eb | ||
|
|
cfd2910ead | ||
|
|
e444e27cad | ||
|
|
64050ac461 | ||
|
|
6062ebdf9c | ||
|
|
698ea31d31 | ||
|
|
d52c208ba9 | ||
|
|
38e3f5f31c | ||
|
|
4477b12f8d | ||
|
|
76ce105289 | ||
|
|
0b9f64fbfc | ||
|
|
7dac3ad21a | ||
|
|
aeca8ef2b2 | ||
|
|
3b7e120eb2 | ||
|
|
56dacd0815 | ||
|
|
415717ee10 | ||
|
|
716e04a0a8 | ||
|
|
8ebf71dc23 | ||
|
|
1a702512e5 | ||
|
|
d5a1a82c72 | ||
|
|
5e3aff31e0 | ||
|
|
d1eba51f61 | ||
|
|
df42932630 | ||
|
|
3c700e57d1 | ||
|
|
fa66b45373 | ||
|
|
0facdee321 | ||
|
|
4d45b81ebc | ||
|
|
4765e34c09 | ||
|
|
7717731a22 | ||
|
|
f639e59b91 | ||
|
|
2352f862ee | ||
|
|
c3bd0b1391 | ||
|
|
776877f7a4 | ||
|
|
cdf8e7227c | ||
|
|
827b8337bd | ||
|
|
603f9e3f34 | ||
|
|
f971216c03 | ||
|
|
cfc044b7bc | ||
|
|
9120ebe6f7 | ||
|
|
02f1805505 | ||
|
|
b937372f82 | ||
|
|
89f3f4b493 | ||
|
|
9a47a4c094 | ||
|
|
20436ff6ac | ||
|
|
70218f29ac | ||
|
|
59677c0304 | ||
|
|
35e2e4354a | ||
|
|
5743ba5fac | ||
|
|
86ec97bad1 | ||
|
|
5e0b4aa509 | ||
|
|
8117715a02 | ||
|
|
cf5fa70f28 | ||
|
|
1e81ef9174 | ||
|
|
d6c4eb7479 | ||
|
|
0957bded16 | ||
|
|
0c44bba5f2 | ||
|
|
26942afc27 | ||
|
|
fbce395321 | ||
|
|
0289e2f9ff | ||
|
|
b24355dd67 | ||
|
|
b315f4b3fe | ||
|
|
a705d805c9 | ||
|
|
e3b8b0a43d | ||
|
|
2044db4d3e | ||
|
|
8a800e909f | ||
|
|
0f2e6b165c | ||
|
|
b16d2c2864 | ||
|
|
61b0b57b87 | ||
|
|
cfdc7f93ed | ||
|
|
d9cbc52928 | ||
|
|
62e5105191 | ||
|
|
1b6e474b9e | ||
|
|
a7e43ad9af | ||
|
|
47692a9b43 | ||
|
|
21ebbc877a | ||
|
|
457035e464 | ||
|
|
71cb09c08b | ||
|
|
70d6fb5660 | ||
|
|
b4e0436b41 | ||
|
|
0262d709eb | ||
|
|
1a50a8220e | ||
|
|
f2213bd5f4 | ||
|
|
fcbe33714e | ||
|
|
184ca7940b | ||
|
|
dceaf7fe8d | ||
|
|
d85b05f999 | ||
|
|
9d2bad977c | ||
|
|
4c8ba67cad | ||
|
|
3ca5c02880 | ||
|
|
3c0649392e | ||
|
|
8a2d6df43b | ||
|
|
98103bac73 | ||
|
|
6cbc21cc4e | ||
|
|
7edeb59853 | ||
|
|
806f921ad2 | ||
|
|
ec54c8e014 | ||
|
|
b7be5251b8 | ||
|
|
33dc25f400 | ||
|
|
e761ff9140 | ||
|
|
2f26a42b68 | ||
|
|
2ed7aa60ff | ||
|
|
7e4a3251c8 | ||
|
|
b73e46dbc4 | ||
|
|
4185b79e0d | ||
|
|
3f037b2051 | ||
|
|
51c6b7ef9b | ||
|
|
ceffbd012e | ||
|
|
12c3869794 | ||
|
|
5a348ae685 | ||
|
|
c1da64fc36 | ||
|
|
c262110b9a | ||
|
|
dac0c4e767 | ||
|
|
25e65b39bc | ||
|
|
3c569fd485 | ||
|
|
7c3b6de41b | ||
|
|
abdc522f9f | ||
|
|
ec5297937d | ||
|
|
ff768a6e5d | ||
|
|
e0ffe68446 | ||
|
|
0bc055b1a7 | ||
|
|
6b8789a54b | ||
|
|
d270eaefd0 | ||
|
|
5dd89d3afc | ||
|
|
556e6ba261 | ||
|
|
75354c67db | ||
|
|
cf7da65ff9 | ||
|
|
17b167f1de | ||
|
|
6937d59b9f | ||
|
|
e2e8b0a287 | ||
|
|
c89f3623f6 | ||
|
|
a5122e2e18 | ||
|
|
7d96963b60 | ||
|
|
b6acb48dbf | ||
|
|
0538763059 | ||
|
|
6a07c09686 | ||
|
|
19be421875 | ||
|
|
1c6544ffbf | ||
|
|
58d2367f02 | ||
|
|
569e28b229 | ||
|
|
ab6a3f8b6b | ||
|
|
f2c8bd7333 | ||
|
|
9d2e8d020b | ||
|
|
586216fa01 | ||
|
|
70038e05c8 | ||
|
|
e301a4d211 | ||
|
|
659f869d63 | ||
|
|
0952bc9b70 | ||
|
|
0f8bee120b | ||
|
|
e4e03e1765 | ||
|
|
27c83f7d3c | ||
|
|
391dedc7b1 | ||
|
|
fdddf19d13 | ||
|
|
46f74405a1 | ||
|
|
de6db3c313 | ||
|
|
2ddff54311 | ||
|
|
a423d0c3bf | ||
|
|
d684dfe8d0 | ||
|
|
e22e4801c1 | ||
|
|
8b7de5ec25 | ||
|
|
a1afcc517a | ||
|
|
25eab5c203 | ||
|
|
545c1a0407 | ||
|
|
42acd22978 | ||
|
|
3ff8e6d0f8 | ||
|
|
424754db1a | ||
|
|
dfada55cf7 | ||
|
|
7f50a3f1d3 | ||
|
|
ed1a528fa7 | ||
|
|
c9825805db | ||
|
|
e70a91d1ec | ||
|
|
bf7926acf4 | ||
|
|
1fcc0d2ae3 | ||
|
|
74678a56f7 | ||
|
|
2a39320fc3 | ||
|
|
c528c62536 | ||
|
|
28a080d1cd | ||
|
|
267667b3f5 | ||
|
|
0b6f5db9ff | ||
|
|
a103f84635 | ||
|
|
da89b2f00d | ||
|
|
30e7c616a2 | ||
|
|
690c388143 | ||
|
|
dbdc2e1238 | ||
|
|
6c98ea7781 | ||
|
|
85f4d01cee | ||
|
|
33b456d991 | ||
|
|
8c8aa63b3a | ||
|
|
5e97f0ef2d | ||
|
|
a255155b4d | ||
|
|
97165a0a82 | ||
|
|
db48ef396e | ||
|
|
1cd05f53b1 | ||
|
|
e126b812b6 | ||
|
|
4fcbf57e97 | ||
|
|
6b2608e419 | ||
|
|
9c1365f45e | ||
|
|
acf99d3e05 | ||
|
|
73ee29246f | ||
|
|
73e4106dc9 | ||
|
|
96cdc2aba8 | ||
|
|
342ff9e025 | ||
|
|
c2ad923581 | ||
|
|
6a7cff656b | ||
|
|
7a00108852 | ||
|
|
e1d6726d8b | ||
|
|
dcd0f5f892 | ||
|
|
40fdc1f804 | ||
|
|
33e88eb9cc | ||
|
|
8b8c8ebd26 | ||
|
|
bfe7005962 | ||
|
|
45fa6931d7 | ||
|
|
6f82feddeb | ||
|
|
998900955d | ||
|
|
1c2b50a343 | ||
|
|
49d77c736e | ||
|
|
6711543567 | ||
|
|
397cae4f87 | ||
|
|
c726bb614c | ||
|
|
6fa8bfffe7 | ||
|
|
2e62915b41 | ||
|
|
a80f62c87f | ||
|
|
99ba2d0a4d | ||
|
|
b045854a63 | ||
|
|
f015cbb9fd | ||
|
|
2b9c088d1d | ||
|
|
9ecd95faa0 | ||
|
|
7062289c89 | ||
|
|
d2b80ea42c | ||
|
|
39381ac5b0 | ||
|
|
cc7b3ea25e | ||
|
|
85a4fa49a4 | ||
|
|
935b317fe6 | ||
|
|
ad0b9983bf | ||
|
|
648954faa3 | ||
|
|
e885d7b372 | ||
|
|
5fcff90c01 | ||
|
|
8c4c8b0323 | ||
|
|
f8101c2a16 | ||
|
|
b7c64d9eb4 | ||
|
|
e456b811f2 | ||
|
|
01c4e13198 | ||
|
|
7bf2316c09 | ||
|
|
e55f7c59e6 | ||
|
|
5916b4a740 | ||
|
|
a3f6946823 | ||
|
|
87cda7e641 | ||
|
|
247b82e816 | ||
|
|
4d745b48cf | ||
|
|
fc2588140b | ||
|
|
e619e6660e | ||
|
|
475b45b293 | ||
|
|
3c4a2b58b1 | ||
|
|
a8fb541568 | ||
|
|
90c499f9c7 | ||
|
|
e6bef9d1ab | ||
|
|
5d22318f7d | ||
|
|
da97fce6d5 | ||
|
|
b34611d1b3 | ||
|
|
75e2b2fabe | ||
|
|
df57b33e19 | ||
|
|
0ca4165219 | ||
|
|
9ce4cf779b | ||
|
|
4ccebfac29 | ||
|
|
1142400e9c | ||
|
|
abcada8466 | ||
|
|
a8bedd0425 | ||
|
|
fe89a971a6 | ||
|
|
6df562a8ab | ||
|
|
c086bd03f0 | ||
|
|
9e591c3813 | ||
|
|
0be75bc54f | ||
|
|
d94e4469f6 | ||
|
|
4b4fd649e6 | ||
|
|
fad44a5413 | ||
|
|
8910b3493e | ||
|
|
20fe65c73c | ||
|
|
3fe9c9e532 | ||
|
|
259d723ec9 | ||
|
|
0d755a50ae | ||
|
|
e27f2f72bf | ||
|
|
b6ea81d07f | ||
|
|
ed8cbb1f81 | ||
|
|
65b5f7f30a | ||
|
|
bc30c0558d | ||
|
|
8913d2f65f | ||
|
|
907f5db4e2 | ||
|
|
79c6459adf | ||
|
|
87e9ecb9e2 | ||
|
|
e5129fe55f | ||
|
|
5f760cf94b | ||
|
|
ce01127664 | ||
|
|
ef3219a098 | ||
|
|
473a8ea6fe | ||
|
|
bb321f90a5 | ||
|
|
af725fa363 | ||
|
|
0077d97cfa |
1
jikimo_auto_backup/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
from . import models
|
||||
36
jikimo_auto_backup/__manifest__.py
Normal file
@@ -0,0 +1,36 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': "Database auto-backup",
|
||||
'summary': 'Automated backups',
|
||||
'description': """
|
||||
The Database Auto-Backup module enables the user to make configurations for the automatic backup of the database.
|
||||
Backups can be taken on the local system or on a remote server, through SFTP.
|
||||
You only have to specify the hostname, port, backup location and databasename (all will be pre-filled by default with correct data.
|
||||
If you want to write to an external server with SFTP you will need to provide the IP, username and password for the remote backups.
|
||||
The base of this module is taken from Odoo SA V6.1 (https://www.odoo.com/apps/modules/6.0/auto_backup/) and then upgraded and heavily expanded.
|
||||
This module is made and provided by Yenthe Van Ginneken (Oocademy).
|
||||
Automatic backup for all such configured databases can then be scheduled as follows:
|
||||
|
||||
1) Go to Settings / Technical / Automation / Scheduled actions.
|
||||
2) Search the action 'Backup scheduler'.
|
||||
3) Set it active and choose how often you wish to take backups.
|
||||
4) If you want to write backups to a remote location you should fill in the SFTP details.
|
||||
""",
|
||||
'author': "Yenthe Van Ginneken",
|
||||
'website': "http://www.odoo.yenthevg.com",
|
||||
'category': 'Administration',
|
||||
'version': '16.0.0.1',
|
||||
'installable': True,
|
||||
'license': 'LGPL-3',
|
||||
|
||||
# any module necessary for this one to work correctly
|
||||
'depends': ['base'],
|
||||
|
||||
# always loaded
|
||||
'data': [
|
||||
'security/user_groups.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'views/backup_view.xml',
|
||||
'data/backup_data.xml',
|
||||
],
|
||||
}
|
||||
17
jikimo_auto_backup/data/backup_data.xml
Normal file
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" ?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="backup_scheduler" model="ir.cron">
|
||||
<field name="interval_type">days</field>
|
||||
<field name="name">Backup scheduler</field>
|
||||
<field name="numbercall">-1</field>
|
||||
<field name="priority">5</field>
|
||||
<field name="doall">False</field>
|
||||
<field name="active">False</field>
|
||||
<field name="interval_number">1</field>
|
||||
<field name="model_id" ref="model_db_backup"/>
|
||||
<field name="state">code</field>
|
||||
<field name="code">model.schedule_backup()</field>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
314
jikimo_auto_backup/i18n/ar.po
Normal file
@@ -0,0 +1,314 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * auto_backup
|
||||
#
|
||||
# SaFi J. <info@daleeltech.com>, 2015.
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 8.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2015-03-26 14:17+0000\n"
|
||||
"PO-Revision-Date: 2015-12-13 10:46+0300\n"
|
||||
"Last-Translator: SaFi J. <info@daleeltech.com>\n"
|
||||
"Language-Team: team@daleeltech.com\n"
|
||||
"Language: ar\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
|
||||
|
||||
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/backup_scheduler.py:137
|
||||
#, python-format
|
||||
msgid "%s"
|
||||
msgstr "%s"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,bkp_dir:0
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr "المسار الكامل لحفظ النسخ الاحتياطي"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,sendmailsftpfail:0
|
||||
msgid "Auto. E-mail on backup fail"
|
||||
msgstr "إرسال بريد إلكتروني تلقائياً في حالة فشل النسخ الاحتياطي"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,autoremove:0
|
||||
msgid "Auto. Remove Backups"
|
||||
msgstr "إزالة النسخ الاحتياطية تلقائياً"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Automatic backups of the database can be scheduled as follows:"
|
||||
msgstr "النسخ الاحتياطي التلقائي لقاعدة البيانات يمكن جدولته كالتالي"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,bkp_dir:0
|
||||
msgid "Backup Directory"
|
||||
msgstr "دليل النسخ الاحتياطي"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_tree
|
||||
msgid "Backups"
|
||||
msgstr "النسخ الاحتياطية"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,daystokeepsftp:0
|
||||
msgid "Choose after how many days the backup should be deleted from the FTP server. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days from the FTP server."
|
||||
msgstr ""
|
||||
"اختر بعد كم من الأيام سيتم حذف النسخ الاحتياطي من خادم FTP مثلاً :\n إذا أدخلت "
|
||||
"5 فإن النسخ الاحتياطية سيتم إزالتها من خادم FTP بعد 5 أيام."
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,daystokeep:0
|
||||
msgid "Choose after how many days the backup should be deleted. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days."
|
||||
msgstr ""
|
||||
"اختر بعد كم من الأيام سيتم حذف النسخ الاحتياطي مثلاً :\n إذا أدخلت 5 فإن النسخ "
|
||||
"الاحتياطية سيتم إزالتها بعد 5 أيام."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure Backup"
|
||||
msgstr "إعدادات النسخ الإحتياطي"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Contact us!"
|
||||
msgstr "اتصل بنا!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,create_uid:0
|
||||
msgid "Created by"
|
||||
msgstr "تم ألإنشاء بواسطة"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,create_date:0
|
||||
msgid "Created on"
|
||||
msgstr "تم ألإنشاء في"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,name:0
|
||||
msgid "Database"
|
||||
msgstr "قاعدة البيانات"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,name:0
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr "قاعدة البيانات التي تريد جدولة النسخ الاحتياطي لها"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,emailtonotify:0
|
||||
msgid "E-mail to notify"
|
||||
msgstr "تنبيه البريد الإلكتروني"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/backup_scheduler.py:106
|
||||
#: constraint:db.backup:0
|
||||
#, python-format
|
||||
msgid "Error ! No such database exists!"
|
||||
msgstr "خطأ ! لا وجود لقاعدة البيانات هذه !"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,emailtonotify:0
|
||||
msgid "Fill in the e-mail where you want to be notified that the backup failed on the FTP."
|
||||
msgstr ""
|
||||
"ادخل عنوان البريد الإلكتروني الذي تريد تنبيهك من خلاله عند فشل النسخ "
|
||||
"الاحتياطي على FTP."
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "For example: /odoo/backups/"
|
||||
msgstr "مثلاً : /odoo/backups/"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
|
||||
msgstr "اذهب إلى الإعدادات / التقني / ألأتمته / جدولة الإخزاءات."
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Help"
|
||||
msgstr "المساعدة"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,host:0
|
||||
msgid "Host"
|
||||
msgstr "المضيف"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,id:0
|
||||
msgid "ID"
|
||||
msgstr "المعرف"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,sftpip:0
|
||||
msgid "IP Address SFTP Server"
|
||||
msgstr "عنوان بروتوكول الأنترنت لخادم SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,sendmailsftpfail:0
|
||||
msgid "If you check this option you can choose to automaticly get e-mailed when the backup to the external server failed."
|
||||
msgstr ""
|
||||
"إذا قمت بتأشير هذا الخيار ستستطيع اختيار استلام البريد الإلكتروني تلقائياً "
|
||||
"عند فشل النسخ الاحتياطي للخادوم الخارجي."
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,autoremove:0
|
||||
msgid "If you check this option you can choose to automaticly remove the backup after xx days"
|
||||
msgstr ""
|
||||
"إذا قمت بتأشير هذا الخيار ستستطيع اختيار الإزالة التلقائية للنسخ الاحتياطي "
|
||||
"بعد س من الأيام"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,sftpwrite:0
|
||||
msgid "If you check this option you can specify the details needed to write to a remote server with SFTP."
|
||||
msgstr ""
|
||||
"إذا قمت بتأشير هذا الخيار ستستطيع تحديد التفاصيل المطلوبة للكتابة على الخادم "
|
||||
"البعيد من خلال SFTP."
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,write_uid:0
|
||||
msgid "Last Updated by"
|
||||
msgstr "آخر تحديث بواسطة"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,write_date:0
|
||||
msgid "Last Updated on"
|
||||
msgstr "آخر تحديث في"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Local backup configuration"
|
||||
msgstr "إعدادات النسخ الاحتياطي المحلي"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Need more help?"
|
||||
msgstr "هل تحتاج لمزيد من المساعدة ؟"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,sftppassword:0
|
||||
msgid "Password User SFTP Server"
|
||||
msgstr "كلمة المرور لمستخدم خادم SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,sftppath:0
|
||||
msgid "Path external server"
|
||||
msgstr "المسار الخارجي للخادم"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,port:0
|
||||
msgid "Port"
|
||||
msgstr "المنفذ"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,daystokeepsftp:0
|
||||
msgid "Remove SFTP after x days"
|
||||
msgstr "الإزالة من خادم SFTP بعد س من الأيام"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,daystokeep:0
|
||||
msgid "Remove after x days"
|
||||
msgstr "الإزالة بعد س من الأيام"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "SFTP"
|
||||
msgstr "SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,sftpport:0
|
||||
msgid "SFTP Port"
|
||||
msgstr "منفذ SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_search
|
||||
msgid "Search options"
|
||||
msgstr "خيارات البحث"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Search the action named 'Backup scheduler'."
|
||||
msgstr "ابحث عن الأجزاء المسمى 'Backup scheduler'."
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Set the scheduler to active and fill in how often you want backups generated."
|
||||
msgstr "قم بتفعيل الجدولة واملأ كم تربد عادة توليد النسخ الاحتياطي."
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Test"
|
||||
msgstr "اختبار"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Test SFTP Connection"
|
||||
msgstr "اختبار توصيل SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,sftpip:0
|
||||
msgid "The IP address from your remote server. For example 192.168.0.1"
|
||||
msgstr "عنوان بروتوكول الإنترنت من خادومك البعيد. مثلاً 192.168.0.1"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,sftppath:0
|
||||
msgid "The location to the folder where the dumps should be written to. For example /odoo/backups/.\n"
|
||||
"Files will then be written to /odoo/backups/ on your remote server."
|
||||
msgstr ""
|
||||
"موقع المجلد التي يجب كتابة ملفات النسخ عليه. مثلاً /odoo/backups/.\n"
|
||||
"وحينها سيتم كتابة الملفات إلى /odoo/backups/ على خادومك البعيد."
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,sftppassword:0
|
||||
msgid "The password from the user where the SFTP connection should be made with. This is the password from the user on the external server."
|
||||
msgstr ""
|
||||
"كلمة المرور الذي من المفترض عمل اتصال SFTP من بها. هذا هي كلمة المرور على "
|
||||
"الخادم الخارجي."
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,sftpport:0
|
||||
msgid "The port on the FTP server that accepts SSH/SFTP calls."
|
||||
msgstr "المنفذ على خادم FTP الذي يقبل طلبات SSH/SFTP."
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,sftpusername:0
|
||||
msgid "The username where the SFTP connection should be made with. This is the user on the external server."
|
||||
msgstr ""
|
||||
"اسم المستخدم الذي من المفترض عمل اتصال SFTP من به. هذا هو المستخدم على "
|
||||
"الخادم الخارجي."
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "This configures the scheduler for automatic backup of the given database running on given host at given port on regular intervals."
|
||||
msgstr ""
|
||||
"هذا الإعداد سيجدول النسخ الاحتياطي التلقائي لقاعدة بيانات معينة وسينفذ على "
|
||||
"مضيف معين بمنفذ معين خلال فترات متتابعة. "
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Use SFTP with caution! This writes files to external servers under the path you specify."
|
||||
msgstr ""
|
||||
"استخدم SFTP بحذر ! لأن هذا يؤدي لكتابة ملفات لخوادم خارجية على المسار الذي "
|
||||
"حددته."
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,sftpusername:0
|
||||
msgid "Username SFTP Server"
|
||||
msgstr "أسم المستخدم لخادم SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:auto_backup.view_backup_conf_form
|
||||
msgid "Warning:"
|
||||
msgstr "تحذير :"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,sftpwrite:0
|
||||
msgid "Write to external server with sftp"
|
||||
msgstr "الكتابة على خادم خارجي من خلال sftp"
|
||||
158
jikimo_auto_backup/i18n/bg.po
Normal file
@@ -0,0 +1,158 @@
|
||||
# Bulgarian translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-11-24 13:49+0000\n"
|
||||
"PO-Revision-Date: 2011-03-30 07:20+0000\n"
|
||||
"Last-Translator: Dimitar Markov <dimitar.markov@gmail.com>\n"
|
||||
"Language-Team: Bulgarian <bg@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-04-20 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16567)\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,name:0
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"Името на обекта трябва да започва с x_ и не може да никакви специални знаци !"
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "Невалидно име на модел при задаване на действие"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "db.backup"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure Backup"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Test"
|
||||
msgstr "Тестване"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "IP Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,bkp_dir:0
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,shortdesc:auto_backup.module_meta_information
|
||||
msgid "Database Auto-Backup"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Database Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "4) Set other values as per your preference"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,host:0
|
||||
msgid "Host"
|
||||
msgstr "Хост"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"Automatic backup of all the databases under this can be scheduled as "
|
||||
"follows: "
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,bkp_dir:0
|
||||
msgid "Backup Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,name:0
|
||||
msgid "Database"
|
||||
msgstr "База данни"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "2) Schedule new action(create a new record)"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,description:auto_backup.module_meta_information
|
||||
msgid ""
|
||||
"The generic Open ERP Database Auto-Backup system enables the user to make "
|
||||
"configurations for the automatic backup of the database.\n"
|
||||
"User simply requires to specify host & port under IP Configuration & "
|
||||
"database(on specified host running at specified port) and backup "
|
||||
"directory(in which all the backups of the specified database will be stored) "
|
||||
"under Database Configuration.\n"
|
||||
"\n"
|
||||
"Automatic backup for all such configured databases under this can then be "
|
||||
"scheduled as follows: \n"
|
||||
" \n"
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions\n"
|
||||
"2) Schedule new action(create a new record)\n"
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'\n"
|
||||
"4) Set other values as per your preference"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Help"
|
||||
msgstr "Помощ"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database "
|
||||
"running on given host at given port on regular intervals."
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,port:0
|
||||
msgid "Port"
|
||||
msgstr "Порт"
|
||||
157
jikimo_auto_backup/i18n/ca.po
Normal file
@@ -0,0 +1,157 @@
|
||||
# Catalan translation for openobject-addons
|
||||
# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-11-24 13:49+0000\n"
|
||||
"PO-Revision-Date: 2014-10-20 06:41+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Catalan <ca@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2014-10-21 06:30+0000\n"
|
||||
"X-Generator: Launchpad (build 17203)\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,name:0
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "db.backup"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure Backup"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Test"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "IP Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,bkp_dir:0
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,shortdesc:auto_backup.module_meta_information
|
||||
msgid "Database Auto-Backup"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Database Configuration"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "4) Set other values as per your preference"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,host:0
|
||||
msgid "Host"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"Automatic backup of all the databases under this can be scheduled as "
|
||||
"follows: "
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,bkp_dir:0
|
||||
msgid "Backup Directory"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,name:0
|
||||
msgid "Database"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "2) Schedule new action(create a new record)"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,description:auto_backup.module_meta_information
|
||||
msgid ""
|
||||
"The generic Open ERP Database Auto-Backup system enables the user to make "
|
||||
"configurations for the automatic backup of the database.\n"
|
||||
"User simply requires to specify host & port under IP Configuration & "
|
||||
"database(on specified host running at specified port) and backup "
|
||||
"directory(in which all the backups of the specified database will be stored) "
|
||||
"under Database Configuration.\n"
|
||||
"\n"
|
||||
"Automatic backup for all such configured databases under this can then be "
|
||||
"scheduled as follows: \n"
|
||||
" \n"
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions\n"
|
||||
"2) Schedule new action(create a new record)\n"
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'\n"
|
||||
"4) Set other values as per your preference"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Help"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database "
|
||||
"running on given host at given port on regular intervals."
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,port:0
|
||||
msgid "Port"
|
||||
msgstr ""
|
||||
166
jikimo_auto_backup/i18n/es.po
Normal file
@@ -0,0 +1,166 @@
|
||||
# Spanish translation for openobject-addons
|
||||
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-11-24 13:49+0000\n"
|
||||
"PO-Revision-Date: 2011-08-23 19:48+0000\n"
|
||||
"Last-Translator: mgaja (GrupoIsep.com) <Unknown>\n"
|
||||
"Language-Team: Spanish <es@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-04-20 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16567)\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,name:0
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr "Base de datos que desea programar copias de seguridad para"
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"¡El objeto debe empezar con x_ y no puede contener ningún carácter especial!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "Nombre del modelo inválido en la definición de acción."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "db.backup"
|
||||
msgstr "backup.BBDD"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions"
|
||||
msgstr ""
|
||||
"1) Vaya a Administración / Configuración / Programador / Acciones programadas"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure Backup"
|
||||
msgstr "Configurar copia de seguridad"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Test"
|
||||
msgstr "Prueba"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "IP Configuration"
|
||||
msgstr "Configuración IP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,bkp_dir:0
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr "Ruta absoluta para el almacenamiento de las copias de seguridad"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,shortdesc:auto_backup.module_meta_information
|
||||
msgid "Database Auto-Backup"
|
||||
msgstr "Copia de seguridad automática de Base de datos"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Database Configuration"
|
||||
msgstr "Configuración de Base de Datos"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "4) Set other values as per your preference"
|
||||
msgstr "4) Establecer los demás valores según su preferencia"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,host:0
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"Automatic backup of all the databases under this can be scheduled as "
|
||||
"follows: "
|
||||
msgstr ""
|
||||
"Copia de seguridad automática de las bases de datos en virtud de este puede "
|
||||
"ser programado de la siguiente manera: "
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "¡XML inválido para la definición de la vista!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,bkp_dir:0
|
||||
msgid "Backup Directory"
|
||||
msgstr "Directorio de la copia de seguridad"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,name:0
|
||||
msgid "Database"
|
||||
msgstr "Base de datos"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "2) Schedule new action(create a new record)"
|
||||
msgstr "2) Lista de nuevas acciones (crear un nuevo registro)"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,description:auto_backup.module_meta_information
|
||||
msgid ""
|
||||
"The generic Open ERP Database Auto-Backup system enables the user to make "
|
||||
"configurations for the automatic backup of the database.\n"
|
||||
"User simply requires to specify host & port under IP Configuration & "
|
||||
"database(on specified host running at specified port) and backup "
|
||||
"directory(in which all the backups of the specified database will be stored) "
|
||||
"under Database Configuration.\n"
|
||||
"\n"
|
||||
"Automatic backup for all such configured databases under this can then be "
|
||||
"scheduled as follows: \n"
|
||||
" \n"
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions\n"
|
||||
"2) Schedule new action(create a new record)\n"
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'\n"
|
||||
"4) Set other values as per your preference"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'"
|
||||
msgstr ""
|
||||
"3) Ajuste \"objeto\" a \"db.backup\" y \"función\" a \"programar copias de "
|
||||
"seguridad\" en la página \"Datos Técnicos\""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Help"
|
||||
msgstr "Ayuda"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database "
|
||||
"running on given host at given port on regular intervals."
|
||||
msgstr ""
|
||||
"Esto configura el planificador de copia de seguridad automática de la base "
|
||||
"de datos dado que se ejecutan en el host dado en el puerto en intervalos "
|
||||
"regulares."
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,port:0
|
||||
msgid "Port"
|
||||
msgstr "Puerto"
|
||||
395
jikimo_auto_backup/i18n/ko_KR.po
Normal file
@@ -0,0 +1,395 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * auto_backup
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 11.0-20180205\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2018-02-08 03:22+0000\n"
|
||||
"PO-Revision-Date: 2018-02-08 12:47+0900\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Poedit 2.0.6\n"
|
||||
"Last-Translator: \n"
|
||||
"Language: ko_KR\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"<b>Warning:</b>\n"
|
||||
" Use SFTP with caution! This writes files to external "
|
||||
"servers under the path you specify."
|
||||
msgstr ""
|
||||
"<b>경고:</b>\n"
|
||||
" 조심해서 SFTP를 사용하세요! 이것은 당신이 지정한 경로"
|
||||
"밑에 외부서버들로 파일들을 쓰게됩니다."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_folder
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr "백업저장용 절대경로명"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.category,name:auto_backup.module_management
|
||||
msgid "Auto backup access"
|
||||
msgstr "자동으로 백업 액세스하기"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_send_mail_sftp_fail
|
||||
msgid "Auto. E-mail on backup fail"
|
||||
msgstr "백업실패시에 이메일로 알려주기 (자동)"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_autoremove
|
||||
msgid "Auto. Remove Backups"
|
||||
msgstr "백업제거하기 (자동)"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Back-up view"
|
||||
msgstr "백업보기"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.menu,name:auto_backup.auto_backup_menu
|
||||
msgid "Back-ups"
|
||||
msgstr "백업"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_folder
|
||||
msgid "Backup Directory"
|
||||
msgstr "백업디렉토리"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_backup_type
|
||||
msgid "Backup Type"
|
||||
msgstr "백업타입"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.server,name:auto_backup.backup_scheduler_ir_actions_server
|
||||
#: model:ir.cron,cron_name:auto_backup.backup_scheduler
|
||||
#: model:ir.cron,name:auto_backup.backup_scheduler
|
||||
msgid "Backup scheduler"
|
||||
msgstr "백업스케줄러"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_tree
|
||||
msgid "Backups"
|
||||
msgstr "백업"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_days_to_keep_sftp
|
||||
msgid ""
|
||||
"Choose after how many days the backup should be deleted from the FTP server. "
|
||||
"For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days from the FTP "
|
||||
"server."
|
||||
msgstr ""
|
||||
"FTP서버로부터 몇일지난 백업본을 삭제할지 선택하세요. 예를들면:\n"
|
||||
"만약 5를 기입하면 그 백업본들은 FTP서버에서 5일후에 삭제됩니다."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_days_to_keep
|
||||
msgid ""
|
||||
"Choose after how many days the backup should be deleted. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days."
|
||||
msgstr ""
|
||||
"FTP서버로부터 몇일지난 백업본을 삭제할지 선택하세요. 예를들면:\n"
|
||||
"만약 5를 기입하면 그 백업본들은 FTP서버에서 5일후에 삭제됩니다."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure back-ups"
|
||||
msgstr "백업구성하기"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:129
|
||||
#, python-format
|
||||
msgid "Connection Test Failed!"
|
||||
msgstr "연결테스트실패~"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:124
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Connection Test Succeeded!\n"
|
||||
"Everything seems properly set up for FTP back-ups!"
|
||||
msgstr ""
|
||||
"연결테스트성공!\n"
|
||||
"모든게 적절히 세팅된거 같습니다!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Contact me!"
|
||||
msgstr "저에게 연락하세요~"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_create_uid
|
||||
msgid "Created by"
|
||||
msgstr "생성됨"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_create_date
|
||||
msgid "Created on"
|
||||
msgstr "생성됨"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_name
|
||||
msgid "Database"
|
||||
msgstr "데이터베이스"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_name
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr "백업을 스케줄하기 원하는 데이터베이스"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_display_name
|
||||
msgid "Display Name"
|
||||
msgstr "표시이름"
|
||||
|
||||
#. module: auto_backup
|
||||
#: selection:db.backup,backup_type:0
|
||||
msgid "Dump"
|
||||
msgstr "덤프"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_email_to_notify
|
||||
msgid "E-mail to notify"
|
||||
msgstr "통보할 이메일주소"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:98 constraint:db.backup:0
|
||||
#, python-format
|
||||
msgid "Error ! No such database exists!"
|
||||
msgstr "에러~ 그런 데이터베이스가 존재하지 않습니다"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_email_to_notify
|
||||
msgid ""
|
||||
"Fill in the e-mail where you want to be notified that the backup failed on "
|
||||
"the FTP."
|
||||
msgstr "FTP서버상에서 백업실패할때 알림받기원하는 이메일주소를 채워넣으세요"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "For example: /odoo/backups/"
|
||||
msgstr "예: /odoo/backups/"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
|
||||
msgstr "Settings / Technical / Automation / Scheduled Actions 으로 가세요."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Help"
|
||||
msgstr "도움말"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:132
|
||||
#, python-format
|
||||
msgid "Here is what we got instead:\n"
|
||||
msgstr "우리가 대신하는것이 여기있습니다:\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_host
|
||||
msgid "Host"
|
||||
msgstr "호스트"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_sftp_host
|
||||
msgid "IP Address SFTP Server"
|
||||
msgstr "SFTP서버 IP주소"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_send_mail_sftp_fail
|
||||
msgid ""
|
||||
"If you check this option you can choose to automaticly get e-mailed when the "
|
||||
"backup to the external server failed."
|
||||
msgstr ""
|
||||
"이 옵션을 체크하면 외부서버에서 백업실패할때 자동적으로 이메일하도록 선택할 "
|
||||
"수 있습니다."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_autoremove
|
||||
msgid ""
|
||||
"If you check this option you can choose to automaticly remove the backup "
|
||||
"after xx days"
|
||||
msgstr ""
|
||||
"이 옵션을 선택하면 자동적으로 며칠(xx days)후에 백업을 제거하도록 선택할 수 "
|
||||
"있습니다"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_sftp_write
|
||||
msgid ""
|
||||
"If you check this option you can specify the details needed to write to a "
|
||||
"remote server with SFTP."
|
||||
msgstr ""
|
||||
"이 옵션을 선택하면 SFTP 원격서버로 쓰려고 할때 요구되는 정보를 지정할 수 있습"
|
||||
"니다."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup___last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "최근수정일자"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "최근수정자"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "최근업데이트일자"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Local backup configuration"
|
||||
msgstr "로컬백업환경설정"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:res.groups,name:auto_backup.group_manager
|
||||
msgid "Manager"
|
||||
msgstr "관리자"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Need more help?"
|
||||
msgstr "더 도움이 필요하세요?"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_sftp_password
|
||||
msgid "Password User SFTP Server"
|
||||
msgstr "SFTP서버 사용자 패스워드"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_sftp_path
|
||||
msgid "Path external server"
|
||||
msgstr "외부서버경로"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_port
|
||||
msgid "Port"
|
||||
msgstr "포트"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_days_to_keep_sftp
|
||||
msgid "Remove SFTP after x days"
|
||||
msgstr "몇일후에 SFTP 제거"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_days_to_keep
|
||||
msgid "Remove after x days"
|
||||
msgstr "몇일후에 제거하기"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "SFTP"
|
||||
msgstr "SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_sftp_port
|
||||
msgid "SFTP Port"
|
||||
msgstr "SFTP 포트"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Search the action named 'Backup scheduler'."
|
||||
msgstr "'백업스케줄러'라고 명명된 액션을 검색하세요"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"Set the scheduler to active and fill in how often you want backups generated."
|
||||
msgstr "스케줄러를 활성화로 세팅하고 백업주기를 채워넣으세요"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Test SFTP Connection"
|
||||
msgstr "SFTP연결테스트"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_sftp_host
|
||||
msgid "The IP address from your remote server. For example 192.168.0.1"
|
||||
msgstr "원격서버로부터의 IP주소. 예를들자면, 192.168.0.1"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_sftp_path
|
||||
msgid ""
|
||||
"The location to the folder where the dumps should be written to. For "
|
||||
"example /odoo/backups/.\n"
|
||||
"Files will then be written to /odoo/backups/ on your remote server."
|
||||
msgstr ""
|
||||
"덤프파일이 씌어져야하는 폴더위치. 예를들어보자면 /odoo/backups/.\n"
|
||||
"그 다음에 파일들은 당신서버상의 /odoo/backups/ 로 쓰여질겁니다."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_sftp_password
|
||||
msgid ""
|
||||
"The password from the user where the SFTP connection should be made with. "
|
||||
"This is the password from the user on the external server."
|
||||
msgstr ""
|
||||
"SFTP연결이 만들어져야하는 그 사용자의 비밀번호. 이것은 외부서버상의 그 사용자"
|
||||
"의 비밀번호예요~"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_sftp_port
|
||||
msgid "The port on the FTP server that accepts SSH/SFTP calls."
|
||||
msgstr "SSH/SFTP접속을 허용하는 FTP서버상의 포트"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup_sftp_user
|
||||
msgid ""
|
||||
"The username where the SFTP connection should be made with. This is the user "
|
||||
"on the external server."
|
||||
msgstr "SFTP연결할 사용자명. 외부서버상의 사용자명이예요~ "
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database "
|
||||
"running on given host\n"
|
||||
" at given port on regular intervals.\n"
|
||||
" <br/>\n"
|
||||
" Automatic backups of the database can be scheduled "
|
||||
"as follows:"
|
||||
msgstr ""
|
||||
"이것은 정기적인 간격으로 해당 호스트상에서 실행중인 데이터베이스의 자동백업용"
|
||||
"으로 스케줄러를 구성합니다. 그 데이터베이스의 자동백업들은 아래처럼 스케줄될 "
|
||||
"수 있습니다:"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.category,description:auto_backup.module_management
|
||||
msgid "User access level for this module"
|
||||
msgstr "이 모듈용 사용자접근레벨"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_sftp_user
|
||||
msgid "Username SFTP Server"
|
||||
msgstr "SFTP서버 사용자명"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup_sftp_write
|
||||
msgid "Write to external server with sftp"
|
||||
msgstr "sftp와 함께 외부서버로 쓰기"
|
||||
|
||||
#. module: auto_backup
|
||||
#: selection:db.backup,backup_type:0
|
||||
msgid "Zip"
|
||||
msgstr "Zip"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "db.backup"
|
||||
msgstr "db.backup"
|
||||
380
jikimo_auto_backup/i18n/nl.po
Normal file
@@ -0,0 +1,380 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * auto_backup
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 13.0+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-10-20 13:29+0000\n"
|
||||
"PO-Revision-Date: 2019-10-20 13:29+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"<b>Warning:</b>\n"
|
||||
" Use SFTP with caution! This writes files to external servers under the path you specify."
|
||||
msgstr "<b>Waarschuwing:</b>\n"
|
||||
" Gebruik SFTP voorzichtig! Dit schrijft bestanden naar externe servers onder het pad dat u opgeeft."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr "Absoluut pad om backups te bewaren"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.category,name:auto_backup.module_management
|
||||
msgid "Auto backup access"
|
||||
msgstr "Auto backup toegang"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__send_mail_sftp_fail
|
||||
msgid "Auto. E-mail on backup fail"
|
||||
msgstr "Auto. e-mail bij mislukte back-up"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__autoremove
|
||||
msgid "Auto. Remove Backups"
|
||||
msgstr "Auto. e-mailen wanneer backup mislukt"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Back-up view"
|
||||
msgstr "Back-up weergave"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.menu,name:auto_backup.auto_backup_menu
|
||||
msgid "Back-ups"
|
||||
msgstr "Back-ups"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
|
||||
msgid "Backup Directory"
|
||||
msgstr "Backup folder"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_type
|
||||
msgid "Backup Type"
|
||||
msgstr "Soort back-up"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "Backup configuration record"
|
||||
msgstr "Back-up configuratie"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.server,name:auto_backup.backup_scheduler_ir_actions_server
|
||||
#: model:ir.cron,cron_name:auto_backup.backup_scheduler
|
||||
#: model:ir.cron,name:auto_backup.backup_scheduler
|
||||
msgid "Backup scheduler"
|
||||
msgstr "Backup planner"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_tree
|
||||
msgid "Backups"
|
||||
msgstr "Back-ups"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep_sftp
|
||||
msgid ""
|
||||
"Choose after how many days the backup should be deleted from the FTP server. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days from the FTP server."
|
||||
msgstr "Kies na hoeveel dagen de backups verwijderd moeten worden van de FTP server. Bijvoorbeeld:\n"
|
||||
"Als u 5 invult zal de backup na 5 dagen verwijderd worden van de FTP server."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
|
||||
msgid ""
|
||||
"Choose after how many days the backup should be deleted. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days."
|
||||
msgstr "Kies na hoeveel dagen de backups verwijderd moeten worden van de FTP server. Bijvoorbeeld:\n"
|
||||
"Als u 5 invult zal de backup na 5 dagen verwijderd worden van de FTP server."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure back-ups"
|
||||
msgstr "Configureer back-ups"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid "Connection Test Failed!"
|
||||
msgstr "Connectie test mislukt!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Connection Test Succeeded!\n"
|
||||
"Everything seems properly set up for FTP back-ups!"
|
||||
msgstr "Connectie test succesvol!\n"
|
||||
"Alles lijkt correct opgezet voor FTP back-ups!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Contact me!"
|
||||
msgstr "Contacteer mij!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Aangemaakt door"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Aangemaakt op"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
|
||||
msgid "Database"
|
||||
msgstr "Database"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr "Dataabse waar u back-ups voor wilt plannen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Schermnaam"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_type__dump
|
||||
msgid "Dump"
|
||||
msgstr "Dump"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__email_to_notify
|
||||
msgid "E-mail to notify"
|
||||
msgstr "E-mail om te verwittigen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid "Error ! No such database exists!"
|
||||
msgstr "Fout! Deze database bestaat niet!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__email_to_notify
|
||||
msgid ""
|
||||
"Fill in the e-mail where you want to be notified that the backup failed on "
|
||||
"the FTP."
|
||||
msgstr "Vul de e-mail in waarop u wilt verwittigd worden als de backup mislukt op de FTP."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "For example: /odoo/backups/"
|
||||
msgstr "Bijvoorbeeld: /odoo/backups/"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
|
||||
msgstr "Ga naar Instellingen / Technisch / Automatisering / Geplande acties."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Help"
|
||||
msgstr "Help"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid "Here is what we got instead:\n"
|
||||
msgstr "Hier is wat we in de plaats terugkregen:\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__host
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
|
||||
msgid "IP Address SFTP Server"
|
||||
msgstr "IP adres SFTP server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__send_mail_sftp_fail
|
||||
msgid ""
|
||||
"If you check this option you can choose to automaticly get e-mailed when the"
|
||||
" backup to the external server failed."
|
||||
msgstr "Als u deze optie aanvinkt kan u kiezen om automatisch een e-mail aan te krijgen als de backuaar de externe server mislukt."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__autoremove
|
||||
msgid ""
|
||||
"If you check this option you can choose to automaticly remove the backup "
|
||||
"after xx days"
|
||||
msgstr "Als u deze optie aanvinkt kan u kiezen om automatisch backups te verwijderen "
|
||||
"na xx dagen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_write
|
||||
msgid ""
|
||||
"If you check this option you can specify the details needed to write to a "
|
||||
"remote server with SFTP."
|
||||
msgstr "Als u deze optie aanvinkt kan u de details invullen die nodig zijn om te connecteren met de "
|
||||
" externe SFTP server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Laatst gewijzigd op"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Laatst bijgewerkt door"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Laatst bijgewerkt op"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Local backup configuration"
|
||||
msgstr "Lokale back-up configuratie"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:res.groups,name:auto_backup.group_manager
|
||||
msgid "Manager"
|
||||
msgstr "Beheerder"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Need more help?"
|
||||
msgstr "Meer hulp nodig?"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
|
||||
msgid "Password User SFTP Server"
|
||||
msgstr "Wachtwoord gebruiker SFTP server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_path
|
||||
msgid "Path external server"
|
||||
msgstr "Pad externe server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__port
|
||||
msgid "Port"
|
||||
msgstr "Poort"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep_sftp
|
||||
msgid "Remove SFTP after x days"
|
||||
msgstr "Verwijderd SFTP na x dagen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
|
||||
msgid "Remove after x days"
|
||||
msgstr "Verwijder na x dagen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "SFTP"
|
||||
msgstr "SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
|
||||
msgid "SFTP Port"
|
||||
msgstr "SFTP poort"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Search the action named 'Backup scheduler'."
|
||||
msgstr "Zoek de actie met de naam 'Backup planner'."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"Set the scheduler to active and fill in how often you want backups "
|
||||
"generated."
|
||||
msgstr "Zet de planner actief en vul in hoe vaak u wilt dat er backups gegenereerd "
|
||||
"worden."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Test SFTP Connection"
|
||||
msgstr "Test SFTP verbinding"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
|
||||
msgid "The IP address from your remote server. For example 192.168.0.1"
|
||||
msgstr "Het IP adres van uw externe server. Bijvoorbeeld: 192.168.0.1"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_path
|
||||
msgid ""
|
||||
"The location to the folder where the dumps should be written to. For example /odoo/backups/.\n"
|
||||
"Files will then be written to /odoo/backups/ on your remote server."
|
||||
msgstr "De locatie naar de folder waar de backup naar toe moet geschreven worden. Bijvoorbeeld odoo/backups/\n"
|
||||
"Bestanden worden dan naar /odoo/backups/ geschreven op de externe server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
|
||||
msgid ""
|
||||
"The password from the user where the SFTP connection should be made with. "
|
||||
"This is the password from the user on the external server."
|
||||
msgstr "Het wachtwoord van de gebruiker waar de SFTP connectie mee moet gemaakt worden. "
|
||||
"Dit is het wachtwoord van de gebruiker op de externe server."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
|
||||
msgid "The port on the FTP server that accepts SSH/SFTP calls."
|
||||
msgstr "De poort op de FTP server die SSH/SFTP accepteert."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
|
||||
msgid ""
|
||||
"The username where the SFTP connection should be made with. This is the user"
|
||||
" on the external server."
|
||||
msgstr "De gebruikersnaam waar de SFTP connectie mee gemaakt moet worden. Dit is de gebruiker"
|
||||
" op de externe server."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database running on given host\n"
|
||||
" at given port on regular intervals.\n"
|
||||
" <br/>\n"
|
||||
" Automatic backups of the database can be scheduled as follows:"
|
||||
msgstr "Dit configureert de planner om automatische backups van de opgegeven database te maken die op deze host,\n"
|
||||
" op een bepaalde poort draaien, op regelmatige intervals.\n"
|
||||
" <br/>\n"
|
||||
" Automatische backups kunnen als volgt ingepland worden:"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.category,description:auto_backup.module_management
|
||||
msgid "User access level for this module"
|
||||
msgstr "Gebruikerstoegang voor deze module"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
|
||||
msgid "Username SFTP Server"
|
||||
msgstr "Gebruikersnaam SFTP server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_write
|
||||
msgid "Write to external server with sftp"
|
||||
msgstr "Schrijf naar externe server met SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_type__zip
|
||||
msgid "Zip"
|
||||
msgstr "ZIP"
|
||||
|
||||
380
jikimo_auto_backup/i18n/nl_BE.po
Normal file
@@ -0,0 +1,380 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * auto_backup
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 13.0+e\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2019-10-20 13:29+0000\n"
|
||||
"PO-Revision-Date: 2019-10-20 13:29+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"<b>Warning:</b>\n"
|
||||
" Use SFTP with caution! This writes files to external servers under the path you specify."
|
||||
msgstr "<b>Waarschuwing:</b>\n"
|
||||
" Gebruik SFTP voorzichtig! Dit schrijft bestanden naar externe servers onder het pad dat u opgeeft."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr "Absoluut pad om backups te bewaren"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.category,name:auto_backup.module_management
|
||||
msgid "Auto backup access"
|
||||
msgstr "Auto backup toegang"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__send_mail_sftp_fail
|
||||
msgid "Auto. E-mail on backup fail"
|
||||
msgstr "Auto. e-mail bij mislukte back-up"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__autoremove
|
||||
msgid "Auto. Remove Backups"
|
||||
msgstr "Auto. e-mailen wanneer backup mislukt"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Back-up view"
|
||||
msgstr "Back-up weergave"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.menu,name:auto_backup.auto_backup_menu
|
||||
msgid "Back-ups"
|
||||
msgstr "Back-ups"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
|
||||
msgid "Backup Directory"
|
||||
msgstr "Backup folder"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_type
|
||||
msgid "Backup Type"
|
||||
msgstr "Soort back-up"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "Backup configuration record"
|
||||
msgstr "Back-up configuratie"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.server,name:auto_backup.backup_scheduler_ir_actions_server
|
||||
#: model:ir.cron,cron_name:auto_backup.backup_scheduler
|
||||
#: model:ir.cron,name:auto_backup.backup_scheduler
|
||||
msgid "Backup scheduler"
|
||||
msgstr "Backup planner"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_tree
|
||||
msgid "Backups"
|
||||
msgstr "Back-ups"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep_sftp
|
||||
msgid ""
|
||||
"Choose after how many days the backup should be deleted from the FTP server. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days from the FTP server."
|
||||
msgstr "Kies na hoeveel dagen de backups verwijderd moeten worden van de FTP server. Bijvoorbeeld:\n"
|
||||
"Als u 5 invult zal de backup na 5 dagen verwijderd worden van de FTP server."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
|
||||
msgid ""
|
||||
"Choose after how many days the backup should be deleted. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days."
|
||||
msgstr "Kies na hoeveel dagen de backups verwijderd moeten worden van de FTP server. Bijvoorbeeld:\n"
|
||||
"Als u 5 invult zal de backup na 5 dagen verwijderd worden van de FTP server."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure back-ups"
|
||||
msgstr "Configureer back-ups"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid "Connection Test Failed!"
|
||||
msgstr "Connectie test mislukt!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Connection Test Succeeded!\n"
|
||||
"Everything seems properly set up for FTP back-ups!"
|
||||
msgstr "Connectie test succesvol!\n"
|
||||
"Alles lijkt correct opgezet voor FTP backups!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Contact me!"
|
||||
msgstr "Contacteer mij!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "Aangemaakt door"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
|
||||
msgid "Created on"
|
||||
msgstr "Aangemaakt op"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
|
||||
msgid "Database"
|
||||
msgstr "Database"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr "Dataabse waar u back-ups voor wilt plannen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "Schermnaam"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_type__dump
|
||||
msgid "Dump"
|
||||
msgstr "Dump"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__email_to_notify
|
||||
msgid "E-mail to notify"
|
||||
msgstr "E-mail om te verwittigen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid "Error ! No such database exists!"
|
||||
msgstr "Fout! Deze database bestaat niet!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__email_to_notify
|
||||
msgid ""
|
||||
"Fill in the e-mail where you want to be notified that the backup failed on "
|
||||
"the FTP."
|
||||
msgstr "Vul de e-mail in waarop u wilt verwittigd worden als de backup mislukt op de FTP."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "For example: /odoo/backups/"
|
||||
msgstr "Bijvoorbeeld: /odoo/backups/"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
|
||||
msgstr "Ga naar Instellingen / Technisch / Automatisering / Geplande acties."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Help"
|
||||
msgstr "Help"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid "Here is what we got instead:\n"
|
||||
msgstr "Hier is wat we in de plaats terugkregen:\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__host
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
|
||||
msgid "ID"
|
||||
msgstr "ID"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
|
||||
msgid "IP Address SFTP Server"
|
||||
msgstr "IP adres SFTP server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__send_mail_sftp_fail
|
||||
msgid ""
|
||||
"If you check this option you can choose to automaticly get e-mailed when the"
|
||||
" backup to the external server failed."
|
||||
msgstr "Als u deze optie aanvinkt kan u kiezen om automatisch een e-mail aan te krijgen als de backuaar de externe server mislukt."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__autoremove
|
||||
msgid ""
|
||||
"If you check this option you can choose to automaticly remove the backup "
|
||||
"after xx days"
|
||||
msgstr "Als u deze optie aanvinkt kan u kiezen om automatisch backups te verwijderen "
|
||||
"na xx dagen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_write
|
||||
msgid ""
|
||||
"If you check this option you can specify the details needed to write to a "
|
||||
"remote server with SFTP."
|
||||
msgstr "Als u deze optie aanvinkt kan u de details invullen die nodig zijn om te connecteren met de "
|
||||
" externe SFTP server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "Laatst gewijzigd op"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "Laatst bijgewerkt door"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "Laatst bijgewerkt op"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Local backup configuration"
|
||||
msgstr "Lokale back-up configuratie"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:res.groups,name:auto_backup.group_manager
|
||||
msgid "Manager"
|
||||
msgstr "Beheerder"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Need more help?"
|
||||
msgstr "Meer hulp nodig?"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
|
||||
msgid "Password User SFTP Server"
|
||||
msgstr "Wachtwoord gebruiker SFTP server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_path
|
||||
msgid "Path external server"
|
||||
msgstr "Pad externe server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__port
|
||||
msgid "Port"
|
||||
msgstr "Poort"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep_sftp
|
||||
msgid "Remove SFTP after x days"
|
||||
msgstr "Verwijderd SFTP na x dagen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
|
||||
msgid "Remove after x days"
|
||||
msgstr "Verwijder na x dagen"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "SFTP"
|
||||
msgstr "SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
|
||||
msgid "SFTP Port"
|
||||
msgstr "SFTP poort"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Search the action named 'Backup scheduler'."
|
||||
msgstr "Zoek de actie met de naam 'Backup planner'."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"Set the scheduler to active and fill in how often you want backups "
|
||||
"generated."
|
||||
msgstr "Zet de planner actief en vul in hoe vaak u wilt dat er backups gegenereerd "
|
||||
"worden."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Test SFTP Connection"
|
||||
msgstr "Test SFTP verbinding"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
|
||||
msgid "The IP address from your remote server. For example 192.168.0.1"
|
||||
msgstr "Het IP adres van uw externe server. Bijvoorbeeld: 192.168.0.1"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_path
|
||||
msgid ""
|
||||
"The location to the folder where the dumps should be written to. For example /odoo/backups/.\n"
|
||||
"Files will then be written to /odoo/backups/ on your remote server."
|
||||
msgstr "De locatie naar de folder waar de backup naar toe moet geschreven worden. Bijvoorbeeld odoo/backups/\n"
|
||||
"Bestanden worden dan naar /odoo/backups/ geschreven op de externe server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
|
||||
msgid ""
|
||||
"The password from the user where the SFTP connection should be made with. "
|
||||
"This is the password from the user on the external server."
|
||||
msgstr "Het wachtwoord van de gebruiker waar de SFTP connectie mee moet gemaakt worden. "
|
||||
"Dit is het wachtwoord van de gebruiker op de externe server."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
|
||||
msgid "The port on the FTP server that accepts SSH/SFTP calls."
|
||||
msgstr "De poort op de FTP server die SSH/SFTP accepteert."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
|
||||
msgid ""
|
||||
"The username where the SFTP connection should be made with. This is the user"
|
||||
" on the external server."
|
||||
msgstr "De gebruikersnaam waar de SFTP connectie mee gemaakt moet worden. Dit is de gebruiker"
|
||||
" op de externe server."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database running on given host\n"
|
||||
" at given port on regular intervals.\n"
|
||||
" <br/>\n"
|
||||
" Automatic backups of the database can be scheduled as follows:"
|
||||
msgstr "Dit configureert de planner om automatische backups van de opgegeven database te maken die op deze host,\n"
|
||||
" op een bepaalde poort draaien, op regelmatige intervals.\n"
|
||||
" <br/>\n"
|
||||
" Automatische backups kunnen als volgt ingepland worden:"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.category,description:auto_backup.module_management
|
||||
msgid "User access level for this module"
|
||||
msgstr "Gebruikerstoegang voor deze module"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
|
||||
msgid "Username SFTP Server"
|
||||
msgstr "Gebruikersnaam SFTP server"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_write
|
||||
msgid "Write to external server with sftp"
|
||||
msgstr "Schrijf naar externe server met SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_type__zip
|
||||
msgid "Zip"
|
||||
msgstr "ZIP"
|
||||
|
||||
178
jikimo_auto_backup/i18n/pl.po
Normal file
@@ -0,0 +1,178 @@
|
||||
# Polish translation for openobject-addons
|
||||
# Copyright (c) 2010 Rosetta Contributors and Canonical Ltd 2010
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2010.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-11-24 13:49+0000\n"
|
||||
"PO-Revision-Date: 2011-02-15 15:01+0000\n"
|
||||
"Last-Translator: OpenERP Administrators <Unknown>\n"
|
||||
"Language-Team: Polish <pl@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-04-20 05:35+0000\n"
|
||||
"X-Generator: Launchpad (build 16567)\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,name:0
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr "Baza danych, dla której chcesz zaplanować robienie kopii zapasowej"
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"Nazwa obiektu musi zaczynać się od x_ oraz nie może zawierać znaków "
|
||||
"specjalnych !"
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "Nieprawidłowa nazwa modelu w definicji akcji."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "db.backup"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions"
|
||||
msgstr "1) Idź do Administracja / Konfirguracja / Planista / Planowane akcje"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure Backup"
|
||||
msgstr "Konfiguruj kopie zapasowe"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Test"
|
||||
msgstr "Przetestuj"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "IP Configuration"
|
||||
msgstr "Konfiguracja adresu IP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,bkp_dir:0
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr "Pełna ścieżka dla kopii zapasowych"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,shortdesc:auto_backup.module_meta_information
|
||||
msgid "Database Auto-Backup"
|
||||
msgstr "Automatyczne kopie zapasowe bazy danych"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Database Configuration"
|
||||
msgstr "Konfiguracja bazy danych"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "4) Set other values as per your preference"
|
||||
msgstr "4) Ustaw inne dane według uznania"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,host:0
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"Automatic backup of all the databases under this can be scheduled as "
|
||||
"follows: "
|
||||
msgstr ""
|
||||
"Automatyczne kopie wszystkich baz danych mogą być zaplanowane następująco: "
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "XML niewłaściwy dla tej architektury wyświetlania!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,bkp_dir:0
|
||||
msgid "Backup Directory"
|
||||
msgstr "Katalog kopii zapasowych"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,name:0
|
||||
msgid "Database"
|
||||
msgstr "Baza danych"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "2) Schedule new action(create a new record)"
|
||||
msgstr "2) Zaplanuj nową akcję (utwórz nowy rekord)"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,description:auto_backup.module_meta_information
|
||||
msgid ""
|
||||
"The generic Open ERP Database Auto-Backup system enables the user to make "
|
||||
"configurations for the automatic backup of the database.\n"
|
||||
"User simply requires to specify host & port under IP Configuration & "
|
||||
"database(on specified host running at specified port) and backup "
|
||||
"directory(in which all the backups of the specified database will be stored) "
|
||||
"under Database Configuration.\n"
|
||||
"\n"
|
||||
"Automatic backup for all such configured databases under this can then be "
|
||||
"scheduled as follows: \n"
|
||||
" \n"
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions\n"
|
||||
"2) Schedule new action(create a new record)\n"
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'\n"
|
||||
"4) Set other values as per your preference"
|
||||
msgstr ""
|
||||
"System Open ERP Database Auto-Backup pozwala użytkownikowi utworzyć "
|
||||
"konfiguracje dla automatycznego zachowywania kopii zapasowych baz danych.\n"
|
||||
"Użytkownik musi tylko podać host i port w Konfiguracji IP i bazę danych "
|
||||
"oraz katalog dla kopii zapasowej Konfiguracji bazy danych.\n"
|
||||
"\n"
|
||||
"Automatyczne kopie wszystkich baz danych mogą być zaplanowane następująco: "
|
||||
"\n"
|
||||
" \n"
|
||||
"1) Idź do Administracja / Konfirguracja / Planista / Planowane akcje\n"
|
||||
"2) Zaplanuj nową akcję (utwórz nowy rekord)\n"
|
||||
"3) Ustaw 'Obiekt' na 'db.backup' i 'Funkcja' na 'schedule_backup' na stronie "
|
||||
"'Dane techniczne'.\n"
|
||||
"4) Ustaw inne dane według uznania"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'"
|
||||
msgstr ""
|
||||
"3) Ustaw 'Obiekt' na 'db.backup' i 'Funkcja' na 'schedule_backup' na stronie "
|
||||
"'Dane techniczne'."
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Help"
|
||||
msgstr "Pomoc"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database "
|
||||
"running on given host at given port on regular intervals."
|
||||
msgstr ""
|
||||
"Tu konfigurujesz planistę do automatycznego zapisywania kopii zapasowych dla "
|
||||
"określonej bazy danych na na określonym hoście (komputerze) na określonym "
|
||||
"porcie w regularnych terminach."
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,port:0
|
||||
msgid "Port"
|
||||
msgstr "Port"
|
||||
183
jikimo_auto_backup/i18n/pt_BR.po
Normal file
@@ -0,0 +1,183 @@
|
||||
# Brazilian Portuguese translation for openobject-addons
|
||||
# Copyright (c) 2013 Rosetta Contributors and Canonical Ltd 2013
|
||||
# This file is distributed under the same license as the openobject-addons package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, 2013.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: openobject-addons\n"
|
||||
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"POT-Creation-Date: 2009-11-24 13:49+0000\n"
|
||||
"PO-Revision-Date: 2013-07-20 09:39+0000\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: Brazilian Portuguese <pt_BR@li.org>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Launchpad-Export-Date: 2013-07-22 05:50+0000\n"
|
||||
"X-Generator: Launchpad (build 16696)\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,name:0
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr "Banco de dados que você deseja agendar backups para"
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.model:0
|
||||
msgid ""
|
||||
"The Object name must start with x_ and not contain any special character !"
|
||||
msgstr ""
|
||||
"O nome do objeto deve iniciar com x_ e não conter qualquer caractere "
|
||||
"especial!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.actions.act_window:0
|
||||
msgid "Invalid model name in the action definition."
|
||||
msgstr "Nome do modelo inválida na definição da ação."
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "db.backup"
|
||||
msgstr "db.backup"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions"
|
||||
msgstr ""
|
||||
"1) Vá para Administração / Configuração / Programador / Ações Programadas"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup_conf_form
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure Backup"
|
||||
msgstr "Configurar backup"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Test"
|
||||
msgstr "Teste"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "IP Configuration"
|
||||
msgstr "Configuração de IP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: help:db.backup,bkp_dir:0
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr "Caminho absoluto para armazenar os backups"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,shortdesc:auto_backup.module_meta_information
|
||||
msgid "Database Auto-Backup"
|
||||
msgstr "Banco de Dados Auto-Backup"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Database Configuration"
|
||||
msgstr "Configuração do Banco de Dados"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "4) Set other values as per your preference"
|
||||
msgstr "4) Defina outros valores como por sua preferência"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,host:0
|
||||
msgid "Host"
|
||||
msgstr "Host"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"Automatic backup of all the databases under this can be scheduled as "
|
||||
"follows: "
|
||||
msgstr ""
|
||||
"Backup automático de todos os bancos de dados sob este pode ser programado "
|
||||
"como segue: "
|
||||
|
||||
#. module: auto_backup
|
||||
#: constraint:ir.ui.view:0
|
||||
msgid "Invalid XML for View Architecture!"
|
||||
msgstr "Inválido XML para Ver Arquitetura!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,bkp_dir:0
|
||||
msgid "Backup Directory"
|
||||
msgstr "Diretório de backup"
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,name:0
|
||||
msgid "Database"
|
||||
msgstr "Banco de Dados"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "2) Schedule new action(create a new record)"
|
||||
msgstr "2) Programe nova ação (criar um novo registro)"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.module,description:auto_backup.module_meta_information
|
||||
msgid ""
|
||||
"The generic Open ERP Database Auto-Backup system enables the user to make "
|
||||
"configurations for the automatic backup of the database.\n"
|
||||
"User simply requires to specify host & port under IP Configuration & "
|
||||
"database(on specified host running at specified port) and backup "
|
||||
"directory(in which all the backups of the specified database will be stored) "
|
||||
"under Database Configuration.\n"
|
||||
"\n"
|
||||
"Automatic backup for all such configured databases under this can then be "
|
||||
"scheduled as follows: \n"
|
||||
" \n"
|
||||
"1) Go to Administration / Configuration / Scheduler / Scheduled Actions\n"
|
||||
"2) Schedule new action(create a new record)\n"
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'\n"
|
||||
"4) Set other values as per your preference"
|
||||
msgstr ""
|
||||
"O sistema Auto-Backup genérico Aberto ERP banco de dados permite que o "
|
||||
"usuário faça configurações para o backup automático do banco de dados. \n"
|
||||
"usuário requer simplesmente para especificar anfitrião e porta em "
|
||||
"Configuração do IP e banco de dados (on especificado host executando na "
|
||||
"porta especificada) eo diretório de backup (em . que todos os backups de "
|
||||
"banco de dados especificado serão armazenados) em Configuração do banco de "
|
||||
"dados \n"
|
||||
"de backup automático de todos esses bancos de dados configurados sob este "
|
||||
"pode ser programado como segue:\n"
|
||||
" \n"
|
||||
" \n"
|
||||
"1) Vá para Administração / Configuração / Programador / Ações Programadas \n"
|
||||
"2) Programe nova ação (criar um novo registro) \n"
|
||||
"3) Defina 'objeto' para 'db.backup' e 'função' para 'schedule_backup' em "
|
||||
"página \"Dados Técnicos\" \n"
|
||||
"4 ) Defina outros valores de acordo com sua preferência"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"3) Set 'Object' to 'db.backup' and 'Function' to 'schedule_backup' under "
|
||||
"page 'Technical Data'"
|
||||
msgstr ""
|
||||
"3) Defina 'objeto' para 'db.backup' e 'função' para 'schedule_backup \"em\" "
|
||||
"Dados Técnicos \"página"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid "Help"
|
||||
msgstr "Ajudar"
|
||||
|
||||
#. module: auto_backup
|
||||
#: view:db.backup:0
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database "
|
||||
"running on given host at given port on regular intervals."
|
||||
msgstr ""
|
||||
"Isso configura o agendador de backup automático de um determinado banco de "
|
||||
"dados rodando em determinado host em determinada porta em intervalos "
|
||||
"regulares."
|
||||
|
||||
#. module: auto_backup
|
||||
#: field:db.backup,port:0
|
||||
msgid "Port"
|
||||
msgstr "Porto"
|
||||
358
jikimo_auto_backup/i18n/zh_CN.po
Normal file
@@ -0,0 +1,358 @@
|
||||
# Translation of Odoo Server.
|
||||
# This file contains the translation of the following modules:
|
||||
# * auto_backup
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: Odoo Server 16.0\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-04-19 08:18+0000\n"
|
||||
"PO-Revision-Date: 2024-04-19 08:18+0000\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: \n"
|
||||
"Plural-Forms: \n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"<b>Warning:</b>\n"
|
||||
" Use SFTP with caution! This writes files to external servers under the path you specify."
|
||||
msgstr "谨慎使用SFTP!这会将文件写入您指定路径下的外部服务器。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__folder
|
||||
msgid "Absolute path for storing the backups"
|
||||
msgstr "备份绝对路径"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.category,name:auto_backup.module_management
|
||||
msgid "Auto backup access"
|
||||
msgstr "自动备份权限"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__send_mail_sftp_fail
|
||||
msgid "Auto. E-mail on backup fail"
|
||||
msgstr "FTP备份失败自动邮件通知你"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__autoremove
|
||||
msgid "Auto. Remove Backups"
|
||||
msgstr "自动删除备份"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Back-up view"
|
||||
msgstr "备份视图"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.ui.menu,name:auto_backup.auto_backup_menu
|
||||
msgid "Back-ups"
|
||||
msgstr "备份"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__folder
|
||||
msgid "Backup Directory"
|
||||
msgstr "备份目录"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__backup_type
|
||||
msgid "Backup Type"
|
||||
msgstr "备份类型"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model,name:auto_backup.model_db_backup
|
||||
msgid "Backup configuration record"
|
||||
msgstr "备份配置记录"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.server,name:auto_backup.backup_scheduler_ir_actions_server
|
||||
#: model:ir.cron,cron_name:auto_backup.backup_scheduler
|
||||
#: model:ir.cron,name:auto_backup.backup_scheduler
|
||||
msgid "Backup scheduler"
|
||||
msgstr "备份调度器"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep_sftp
|
||||
msgid ""
|
||||
"Choose after how many days the backup should be deleted from the FTP server. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days from the FTP server."
|
||||
msgstr "选择备份应在FTP服务器上删除的天数。例如:\n如果您填写5,则备份将在5天后从FTP服务器上删除。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__days_to_keep
|
||||
msgid ""
|
||||
"Choose after how many days the backup should be deleted. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days."
|
||||
msgstr "选择备份应删除的天数。例如:\n如果您填写5,则备份将在5天后删除。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.actions.act_window,name:auto_backup.action_backup
|
||||
#: model:ir.ui.menu,name:auto_backup.backup_conf_menu
|
||||
msgid "Configure back-ups"
|
||||
msgstr "配置备份"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid "Connection Test Failed!"
|
||||
msgstr "连接测试失败!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"Connection Test Succeeded!\n"
|
||||
"Everything seems properly set up for FTP back-ups!"
|
||||
msgstr "连接测试成功!\nFTP备份似乎已正确设置!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Contact me!"
|
||||
msgstr "联系我!"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_uid
|
||||
msgid "Created by"
|
||||
msgstr "创建者"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__create_date
|
||||
msgid "Created on"
|
||||
msgstr "创建日期"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__name
|
||||
msgid "Database"
|
||||
msgstr "数据库"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__name
|
||||
msgid "Database you want to schedule backups for"
|
||||
msgstr "您要安排备份的数据库"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__display_name
|
||||
msgid "Display Name"
|
||||
msgstr "显示名称"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_type__dump
|
||||
msgid "Dump"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__email_to_notify
|
||||
msgid "E-mail to notify"
|
||||
msgstr "通知邮件"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__email_to_notify
|
||||
msgid ""
|
||||
"Fill in the e-mail where you want to be notified that the backup failed on "
|
||||
"the FTP."
|
||||
msgstr "填写您希望在FTP上备份失败时收到通知的电子邮件"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "For example: /odoo/backups/"
|
||||
msgstr "例如:/odoo/backups/"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Go to Settings / Technical / Automation / Scheduled Actions."
|
||||
msgstr "前往 设置/技术/自动化/计划任务。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Help"
|
||||
msgstr "帮助"
|
||||
|
||||
#. module: auto_backup
|
||||
#: code:addons/auto_backup/models/db_backup.py:0
|
||||
#, python-format
|
||||
msgid "Here is what we got instead:\n"
|
||||
msgstr "这是我们得到的内容:\n"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__host
|
||||
msgid "Host"
|
||||
msgstr "主机"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__id
|
||||
msgid "ID"
|
||||
msgstr "标识"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_host
|
||||
msgid "IP Address SFTP Server"
|
||||
msgstr "SFTP服务器的IP地址"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__send_mail_sftp_fail
|
||||
msgid ""
|
||||
"If you check this option you can choose to automaticly get e-mailed when the"
|
||||
" backup to the external server failed."
|
||||
msgstr "如果您选中此选项,当备份到外部服务器失败时,您可以选择自动接收邮件通知。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__autoremove
|
||||
msgid ""
|
||||
"If you check this option you can choose to automaticly remove the backup "
|
||||
"after xx days"
|
||||
msgstr "如果您选中此选项,您可以选择在xx天后自动删除备份"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_write
|
||||
msgid ""
|
||||
"If you check this option you can specify the details needed to write to a "
|
||||
"remote server with SFTP."
|
||||
msgstr "如果您选中此选项,您可以指定使用SFTP向远程服务器写入所需的详细信息。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup____last_update
|
||||
msgid "Last Modified on"
|
||||
msgstr "最后修改时间"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_uid
|
||||
msgid "Last Updated by"
|
||||
msgstr "最后更新者"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__write_date
|
||||
msgid "Last Updated on"
|
||||
msgstr "最后更新时间"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Local backup configuration"
|
||||
msgstr "本地备份配置"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:res.groups,name:auto_backup.group_manager
|
||||
msgid "Manager"
|
||||
msgstr "管理者"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Need more help?"
|
||||
msgstr "需要更多帮助?"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_password
|
||||
msgid "Password User SFTP Server"
|
||||
msgstr "SFTP服务器用户密码"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_path
|
||||
msgid "Path external server"
|
||||
msgstr "外部服务器路径"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__port
|
||||
msgid "Port"
|
||||
msgstr "端口"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep_sftp
|
||||
msgid "Remove SFTP after x days"
|
||||
msgstr "x天后删除SFTP"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__days_to_keep
|
||||
msgid "Remove after x days"
|
||||
msgstr "x天后删除"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "SFTP"
|
||||
msgstr ""
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_port
|
||||
msgid "SFTP Port"
|
||||
msgstr "SFTP端口"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Search the action named 'Backup scheduler'."
|
||||
msgstr "搜索名为'备份调度器'的操作。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"Set the scheduler to active and fill in how often you want backups "
|
||||
"generated."
|
||||
msgstr "将调度器设置为激活状态,并填写您希望生成备份的频率。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid "Test SFTP Connection"
|
||||
msgstr "测试SFTP连接"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_host
|
||||
msgid "The IP address from your remote server. For example 192.168.0.1"
|
||||
msgstr "远程服务器的IP地址。例如192.168.0.1"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_path
|
||||
msgid ""
|
||||
"The location to the folder where the dumps should be written to. For example /odoo/backups/.\n"
|
||||
"Files will then be written to /odoo/backups/ on your remote server."
|
||||
msgstr "转储文件应该写入的文件夹位置。例如 /odoo/backups/。\n文件将被写入远程服务器上的 /odoo/backups/。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_password
|
||||
msgid ""
|
||||
"The password from the user where the SFTP connection should be made with. "
|
||||
"This is the password from the user on the external server."
|
||||
msgstr "应与之建立SFTP连接的用户的密码。\n这是外部服务器上用户的密码。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_port
|
||||
msgid "The port on the FTP server that accepts SSH/SFTP calls."
|
||||
msgstr "FTP服务器上接受SSH/SFTP调用的端口。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,help:auto_backup.field_db_backup__sftp_user
|
||||
msgid ""
|
||||
"The username where the SFTP connection should be made with. This is the user"
|
||||
" on the external server."
|
||||
msgstr "应与之建立SFTP连接的用户名。这是外部服务器上的用户。"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model_terms:ir.ui.view,arch_db:auto_backup.view_backup_config_form
|
||||
msgid ""
|
||||
"This configures the scheduler for automatic backup of the given database running on given host\n"
|
||||
" at given port on regular intervals.\n"
|
||||
" <br/>\n"
|
||||
" Automatic backups of the database can be scheduled as follows:"
|
||||
msgstr "这将配置调度器,以定期自动备份在指定主机上运行的给定数据库\n"
|
||||
" 在给定端口上。\n"
|
||||
" <br/>\n"
|
||||
" 可以如下安排数据库的自动备份:"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.module.category,description:auto_backup.module_management
|
||||
msgid "User access level for this module"
|
||||
msgstr "此模块的用户访问级别"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_user
|
||||
msgid "Username SFTP Server"
|
||||
msgstr "SFTP服务器用户名"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields,field_description:auto_backup.field_db_backup__sftp_write
|
||||
msgid "Write to external server with sftp"
|
||||
msgstr "通过SFTP向外部服务器写入"
|
||||
|
||||
#. module: auto_backup
|
||||
#: model:ir.model.fields.selection,name:auto_backup.selection__db_backup__backup_type__zip
|
||||
msgid "Zip"
|
||||
msgstr ""
|
||||
2
jikimo_auto_backup/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
|
||||
from . import db_backup
|
||||
328
jikimo_auto_backup/models/db_backup.py
Normal file
@@ -0,0 +1,328 @@
|
||||
|
||||
import os
|
||||
import datetime
|
||||
import time
|
||||
import shutil
|
||||
import json
|
||||
import tempfile
|
||||
|
||||
from odoo import models, fields, api, tools, _
|
||||
from odoo.exceptions import Warning, AccessDenied
|
||||
import odoo
|
||||
|
||||
import logging
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
import paramiko
|
||||
except ImportError:
|
||||
raise ImportError(
|
||||
'This module needs paramiko to automatically write backups to the FTP through SFTP. '
|
||||
'Please install paramiko on your system. (sudo pip3 install paramiko)')
|
||||
|
||||
|
||||
class DbBackup(models.Model):
|
||||
_name = 'db.backup'
|
||||
_description = 'Backup configuration record'
|
||||
|
||||
def _get_db_name(self):
|
||||
dbName = self._cr.dbname
|
||||
return dbName
|
||||
|
||||
# Columns for local server configuration
|
||||
host = fields.Char('Host', required=True, default='localhost')
|
||||
port = fields.Char('Port', required=True, default=8069)
|
||||
name = fields.Char('Database', required=True, help='Database you want to schedule backups for',
|
||||
default=_get_db_name)
|
||||
folder = fields.Char('Backup Directory', help='Absolute path for storing the backups', required='True',
|
||||
default='/odoo/backups')
|
||||
backup_type = fields.Selection([('zip', 'Zip'), ('dump', 'Dump')], 'Backup Type', required=True, default='zip')
|
||||
autoremove = fields.Boolean('Auto. Remove Backups',
|
||||
help='If you check this option you can choose to automaticly remove the backup '
|
||||
'after xx days')
|
||||
days_to_keep = fields.Integer('Remove after x days',
|
||||
help="Choose after how many days the backup should be deleted. For example:\n"
|
||||
"If you fill in 5 the backups will be removed after 5 days.",
|
||||
required=True)
|
||||
|
||||
# Columns for external server (SFTP)
|
||||
sftp_write = fields.Boolean('Write to external server with sftp',
|
||||
help="If you check this option you can specify the details needed to write to a remote "
|
||||
"server with SFTP.")
|
||||
sftp_path = fields.Char('Path external server',
|
||||
help='The location to the folder where the dumps should be written to. For example '
|
||||
'/odoo/backups/.\nFiles will then be written to /odoo/backups/ on your remote server.')
|
||||
sftp_host = fields.Char('IP Address SFTP Server',
|
||||
help='The IP address from your remote server. For example 192.168.0.1')
|
||||
sftp_port = fields.Integer('SFTP Port', help='The port on the FTP server that accepts SSH/SFTP calls.', default=22)
|
||||
sftp_user = fields.Char('Username SFTP Server',
|
||||
help='The username where the SFTP connection should be made with. This is the user on the '
|
||||
'external server.')
|
||||
sftp_password = fields.Char('Password User SFTP Server',
|
||||
help='The password from the user where the SFTP connection should be made with. This '
|
||||
'is the password from the user on the external server.')
|
||||
days_to_keep_sftp = fields.Integer('Remove SFTP after x days',
|
||||
help='Choose after how many days the backup should be deleted from the FTP '
|
||||
'server. For example:\nIf you fill in 5 the backups will be removed after '
|
||||
'5 days from the FTP server.',
|
||||
default=30)
|
||||
send_mail_sftp_fail = fields.Boolean('Auto. E-mail on backup fail',
|
||||
help='If you check this option you can choose to automaticly get e-mailed '
|
||||
'when the backup to the external server failed.')
|
||||
email_to_notify = fields.Char('E-mail to notify',
|
||||
help='Fill in the e-mail where you want to be notified that the backup failed on '
|
||||
'the FTP.')
|
||||
|
||||
def test_sftp_connection(self, context=None):
|
||||
self.ensure_one()
|
||||
|
||||
# Check if there is a success or fail and write messages
|
||||
message_title = ""
|
||||
message_content = ""
|
||||
error = ""
|
||||
has_failed = False
|
||||
|
||||
for rec in self:
|
||||
ip_host = rec.sftp_host
|
||||
port_host = rec.sftp_port
|
||||
username_login = rec.sftp_user
|
||||
password_login = rec.sftp_password
|
||||
|
||||
# Connect with external server over SFTP, so we know sure that everything works.
|
||||
try:
|
||||
s = paramiko.SSHClient()
|
||||
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
s.connect(ip_host, port_host, username_login, password_login, timeout=10)
|
||||
sftp = s.open_sftp()
|
||||
sftp.close()
|
||||
message_title = _("Connection Test Succeeded!\nEverything seems properly set up for FTP back-ups!")
|
||||
except Exception as e:
|
||||
_logger.critical('There was a problem connecting to the remote ftp: %s', str(e))
|
||||
error += str(e)
|
||||
has_failed = True
|
||||
message_title = _("Connection Test Failed!")
|
||||
if len(rec.sftp_host) < 8:
|
||||
message_content += "\nYour IP address seems to be too short.\n"
|
||||
message_content += _("Here is what we got instead:\n")
|
||||
finally:
|
||||
if s:
|
||||
s.close()
|
||||
|
||||
if has_failed:
|
||||
raise Warning(message_title + '\n\n' + message_content + "%s" % str(error))
|
||||
else:
|
||||
raise Warning(message_title + '\n\n' + message_content)
|
||||
|
||||
@api.model
|
||||
def schedule_backup(self):
|
||||
conf_ids = self.search([])
|
||||
for rec in conf_ids:
|
||||
|
||||
try:
|
||||
if not os.path.isdir(rec.folder):
|
||||
os.makedirs(rec.folder)
|
||||
except:
|
||||
raise
|
||||
# Create name for dumpfile.
|
||||
bkp_file = '%s_%s.%s' % (time.strftime('%Y_%m_%d_%H_%M_%S'), rec.name, rec.backup_type)
|
||||
file_path = os.path.join(rec.folder, bkp_file)
|
||||
try:
|
||||
# try to backup database and write it away
|
||||
fp = open(file_path, 'wb')
|
||||
self._take_dump(rec.name, fp, 'db.backup', rec.backup_type)
|
||||
fp.close()
|
||||
except Exception as error:
|
||||
_logger.debug(
|
||||
"Couldn't backup database %s. Bad database administrator password for server running at "
|
||||
"http://%s:%s" % (rec.name, rec.host, rec.port))
|
||||
_logger.debug("Exact error from the exception: %s", str(error))
|
||||
continue
|
||||
|
||||
# Check if user wants to write to SFTP or not.
|
||||
if rec.sftp_write is True:
|
||||
try:
|
||||
# Store all values in variables
|
||||
dir = rec.folder
|
||||
path_to_write_to = rec.sftp_path
|
||||
ip_host = rec.sftp_host
|
||||
port_host = rec.sftp_port
|
||||
username_login = rec.sftp_user
|
||||
password_login = rec.sftp_password
|
||||
_logger.debug('sftp remote path: %s', path_to_write_to)
|
||||
|
||||
try:
|
||||
s = paramiko.SSHClient()
|
||||
s.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||
s.connect(ip_host, port_host, username_login, password_login, timeout=20)
|
||||
sftp = s.open_sftp()
|
||||
except Exception as error:
|
||||
_logger.critical('Error connecting to remote server! Error: %s', str(error))
|
||||
|
||||
try:
|
||||
sftp.chdir(path_to_write_to)
|
||||
except IOError:
|
||||
# Create directory and subdirs if they do not exist.
|
||||
current_directory = ''
|
||||
for dirElement in path_to_write_to.split('/'):
|
||||
current_directory += dirElement + '/'
|
||||
try:
|
||||
sftp.chdir(current_directory)
|
||||
except:
|
||||
_logger.info('(Part of the) path didn\'t exist. Creating it now at %s',
|
||||
current_directory)
|
||||
# Make directory and then navigate into it
|
||||
sftp.mkdir(current_directory, 777)
|
||||
sftp.chdir(current_directory)
|
||||
pass
|
||||
sftp.chdir(path_to_write_to)
|
||||
# Loop over all files in the directory.
|
||||
for f in os.listdir(dir):
|
||||
if rec.name in f:
|
||||
fullpath = os.path.join(dir, f)
|
||||
if os.path.isfile(fullpath):
|
||||
try:
|
||||
sftp.stat(os.path.join(path_to_write_to, f))
|
||||
_logger.debug(
|
||||
'File %s already exists on the remote FTP Server ------ skipped', fullpath)
|
||||
# This means the file does not exist (remote) yet!
|
||||
except IOError:
|
||||
try:
|
||||
sftp.put(fullpath, os.path.join(path_to_write_to, f))
|
||||
_logger.info('Copying File % s------ success', fullpath)
|
||||
except Exception as err:
|
||||
_logger.critical(
|
||||
'We couldn\'t write the file to the remote server. Error: %s', str(err))
|
||||
|
||||
# Navigate in to the correct folder.
|
||||
sftp.chdir(path_to_write_to)
|
||||
|
||||
_logger.debug("Checking expired files")
|
||||
# Loop over all files in the directory from the back-ups.
|
||||
# We will check the creation date of every back-up.
|
||||
for file in sftp.listdir(path_to_write_to):
|
||||
if rec.name in file:
|
||||
# Get the full path
|
||||
fullpath = os.path.join(path_to_write_to, file)
|
||||
# Get the timestamp from the file on the external server
|
||||
timestamp = sftp.stat(fullpath).st_mtime
|
||||
createtime = datetime.datetime.fromtimestamp(timestamp)
|
||||
now = datetime.datetime.now()
|
||||
delta = now - createtime
|
||||
# If the file is older than the days_to_keep_sftp (the days to keep that the user filled in
|
||||
# on the Odoo form it will be removed.
|
||||
if delta.days >= rec.days_to_keep_sftp:
|
||||
# Only delete files, no directories!
|
||||
if ".dump" in file or '.zip' in file:
|
||||
_logger.info("Delete too old file from SFTP servers: %s", file)
|
||||
sftp.unlink(file)
|
||||
# Close the SFTP session.
|
||||
sftp.close()
|
||||
s.close()
|
||||
except Exception as e:
|
||||
try:
|
||||
sftp.close()
|
||||
s.close()
|
||||
except:
|
||||
pass
|
||||
_logger.error('Exception! We couldn\'t back up to the FTP server. Here is what we got back '
|
||||
'instead: %s', str(e))
|
||||
# At this point the SFTP backup failed. We will now check if the user wants
|
||||
# an e-mail notification about this.
|
||||
if rec.send_mail_sftp_fail:
|
||||
try:
|
||||
ir_mail_server = self.env['ir.mail_server'].search([], order='sequence asc', limit=1)
|
||||
message = "Dear,\n\nThe backup for the server " + rec.host + " (IP: " + rec.sftp_host + \
|
||||
") failed. Please check the following details:\n\nIP address SFTP server: " + \
|
||||
rec.sftp_host + "\nUsername: " + rec.sftp_user + \
|
||||
"\n\nError details: " + tools.ustr(e) + \
|
||||
"\n\nWith kind regards"
|
||||
catch_all_domain = self.env["ir.config_parameter"].sudo().get_param("mail.catchall.domain")
|
||||
response_mail = "auto_backup@%s" % catch_all_domain if catch_all_domain else self.env.user.partner_id.email
|
||||
msg = ir_mail_server.build_email(response_mail, [rec.email_to_notify],
|
||||
"Backup from " + rec.host + "(" + rec.sftp_host +
|
||||
") failed",
|
||||
message)
|
||||
ir_mail_server.send_email(msg)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Remove all old files (on local server) in case this is configured..
|
||||
if rec.autoremove:
|
||||
directory = rec.folder
|
||||
# Loop over all files in the directory.
|
||||
for f in os.listdir(directory):
|
||||
fullpath = os.path.join(directory, f)
|
||||
# Only delete the ones wich are from the current database
|
||||
# (Makes it possible to save different databases in the same folder)
|
||||
if rec.name in fullpath:
|
||||
timestamp = os.stat(fullpath).st_ctime
|
||||
createtime = datetime.datetime.fromtimestamp(timestamp)
|
||||
now = datetime.datetime.now()
|
||||
delta = now - createtime
|
||||
if delta.days >= rec.days_to_keep:
|
||||
# Only delete files (which are .dump and .zip), no directories.
|
||||
if os.path.isfile(fullpath) and (".dump" in f or '.zip' in f):
|
||||
_logger.info("Delete local out-of-date file: %s", fullpath)
|
||||
os.remove(fullpath)
|
||||
|
||||
# This is more or less the same as the default Odoo function at
|
||||
# https://github.com/odoo/odoo/blob/e649200ab44718b8faefc11c2f8a9d11f2db7753/odoo/service/db.py#L209
|
||||
# The main difference is that we do not do have a wrapper for the function check_db_management_enabled here and
|
||||
# that we authenticate based on the cron its user id and by checking if we have 'db.backup' defined in the function
|
||||
# call. Since this function is called from the cron and since we have these security checks on model and on user_id
|
||||
# its pretty impossible to hack any way to take a backup. This allows us to disable the Odoo database manager
|
||||
# which is a MUCH safer way
|
||||
def _take_dump(self, db_name, stream, model, backup_format='zip'):
|
||||
"""Dump database `db` into file-like object `stream` if stream is None
|
||||
return a file object with the dump """
|
||||
|
||||
cron_user_id = self.env.ref('jikimo_auto_backup.backup_scheduler').user_id.id
|
||||
if self._name != 'db.backup' or cron_user_id != self.env.user.id:
|
||||
_logger.error('Unauthorized database operation. Backups should only be available from the cron job.')
|
||||
raise AccessDenied()
|
||||
|
||||
_logger.info('DUMP DB: %s format %s', db_name, backup_format)
|
||||
|
||||
cmd = ['pg_dump', '--no-owner']
|
||||
cmd.append(db_name)
|
||||
|
||||
if backup_format == 'zip':
|
||||
with tempfile.TemporaryDirectory() as dump_dir:
|
||||
filestore = odoo.tools.config.filestore(db_name)
|
||||
if os.path.exists(filestore):
|
||||
shutil.copytree(filestore, os.path.join(dump_dir, 'filestore'))
|
||||
with open(os.path.join(dump_dir, 'manifest.json'), 'w') as fh:
|
||||
db = odoo.sql_db.db_connect(db_name)
|
||||
with db.cursor() as cr:
|
||||
json.dump(self._dump_db_manifest(cr), fh, indent=4)
|
||||
cmd.insert(-1, '--file=' + os.path.join(dump_dir, 'dump.sql'))
|
||||
odoo.tools.exec_pg_command(*cmd)
|
||||
if stream:
|
||||
odoo.tools.osutil.zip_dir(dump_dir, stream, include_dir=False, fnct_sort=lambda file_name: file_name != 'dump.sql')
|
||||
else:
|
||||
t=tempfile.TemporaryFile()
|
||||
odoo.tools.osutil.zip_dir(dump_dir, t, include_dir=False, fnct_sort=lambda file_name: file_name != 'dump.sql')
|
||||
t.seek(0)
|
||||
return t
|
||||
else:
|
||||
cmd.insert(-1, '--format=c')
|
||||
stdin, stdout = odoo.tools.exec_pg_command_pipe(*cmd)
|
||||
if stream:
|
||||
shutil.copyfileobj(stdout, stream)
|
||||
else:
|
||||
return stdout
|
||||
|
||||
def _dump_db_manifest(self, cr):
|
||||
pg_version = "%d.%d" % divmod(cr._obj.connection.server_version / 100, 100)
|
||||
cr.execute("SELECT name, latest_version FROM ir_module_module WHERE state = 'installed'")
|
||||
modules = dict(cr.fetchall())
|
||||
manifest = {
|
||||
'odoo_dump': '1',
|
||||
'db_name': cr.dbname,
|
||||
'version': odoo.release.version,
|
||||
'version_info': odoo.release.version_info,
|
||||
'major_version': odoo.release.major_version,
|
||||
'pg_version': pg_version,
|
||||
'modules': modules,
|
||||
}
|
||||
return manifest
|
||||
1
jikimo_auto_backup/requirments.txt
Normal file
@@ -0,0 +1 @@
|
||||
# pip3 install paramiko
|
||||
3
jikimo_auto_backup/security/ir.model.access.csv
Normal file
@@ -0,0 +1,3 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
admin_access, db_backup admin access,model_db_backup,base.group_no_one,1,1,1,1
|
||||
admin_security_rule, Model db_backup admin access,model_db_backup,jikimo_auto_backup.group_manager,1,1,1,1
|
||||
|
15
jikimo_auto_backup/security/user_groups.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record model="ir.module.category" id="module_management">
|
||||
<field name="name">Auto backup access</field>
|
||||
<field name="description">User access level for this module</field>
|
||||
<field name="sequence">3</field>
|
||||
</record>
|
||||
|
||||
<record id="group_manager" model="res.groups">
|
||||
<field name="name">Manager</field>
|
||||
<field name="category_id" ref="jikimo_auto_backup.module_management"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
BIN
jikimo_auto_backup/static/description/emailnotification.png
Normal file
|
After Width: | Height: | Size: 45 KiB |
BIN
jikimo_auto_backup/static/description/icon.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
95
jikimo_auto_backup/static/description/index.html
Normal file
@@ -0,0 +1,95 @@
|
||||
<section class="oe_container">
|
||||
<div class="oe_row oe_spaced">
|
||||
<div class="oe_span12">
|
||||
<h2 class="oe_slogan">Automated backups</h2>
|
||||
<h3 class="oe_slogan">A tool for all your back-ups, internal and external!</h3>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_demo oe_picture oe_screenshot">
|
||||
<img src="overview.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<p class="oe_mt32">
|
||||
Keep your Odoo data safe with this module. Take automated back-ups, remove them automatically
|
||||
and even write them to an external server through an encrypted tunnel.
|
||||
You can even specify how long local backups and external backups should be kept, automatically!
|
||||
</p>
|
||||
<div class="oe_centeralign oe_websiteonly">
|
||||
<a href="http://www.openerp.com/start?app=mail" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Second block -->
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row oe_spaced">
|
||||
<h2 class="oe_slogan">Connect with an FTP Server</h2>
|
||||
<h3 class="oe_slogan">Keep your data safe, through an SSH tunnel!</h3>
|
||||
<div class="oe_span6">
|
||||
<p class="oe_mt32">
|
||||
Want to go even further and write your backups to an external server?
|
||||
You can with this module! Specify the credentials to the server, specify a path and everything will be backed up automatically. This is done through an SSH (encrypted) tunnel, thanks to pysftp, so your data is safe!
|
||||
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture oe_screenshot" src="terminalssh.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!--Third block -->
|
||||
<section class="oe_container">
|
||||
<div class="oe_row oe_spaced">
|
||||
<div class="oe_span12">
|
||||
<h2 class="oe_slogan">Test connection</h2>
|
||||
<h3 class="oe_slogan">Checks your credentials in one click</h3>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_demo oe_picture oe_screenshot">
|
||||
<img src="testconnection.png">
|
||||
<img src="testconnectionfailed.png">
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<p class="oe_mt32">
|
||||
Want to make sure if the connection details are correct and if Odoo can automatically write them to the remote server? Simply click on the 'Test SFTP Connection' button and you will get message telling you if everything is OK, or what is wrong!
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!-- Fourth block -->
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row oe_spaced">
|
||||
<h2 class="oe_slogan">E-mail on backup failure</h2>
|
||||
<h3 class="oe_slogan">Stay informed of problems, automatically!</h3>
|
||||
<div class="oe_span6">
|
||||
<p class="oe_mt32">
|
||||
Do you want to know if the database backup failed? Check the checkbox 'Auto. E-mail on backup fail' and fill in your e-mail.
|
||||
Every time a backup fails you will get an e-mail in your mailbox with technical details.
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<div class="oe_row_img oe_centered">
|
||||
<img class="oe_picture oe_screenshot" src="emailnotification.png">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!--Fifth block -->
|
||||
<section class="oe_container">
|
||||
<div class="oe_row oe_spaced">
|
||||
<div class="oe_span12">
|
||||
<h2 class="oe_slogan">Contact / Support</h2>
|
||||
<h3 class="oe_slogan">Need help or want extra features?</h3>
|
||||
</div>
|
||||
<div class="oe_span6">
|
||||
<p class="oe_mt32">
|
||||
Need help with the configuration or want this module to have more functionalities?
|
||||
Please create a bug report <a href="https://github.com/Yenthe666/auto_backup/issues">on the Github issue tracker</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
BIN
jikimo_auto_backup/static/description/overview.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
jikimo_auto_backup/static/description/terminalssh.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
jikimo_auto_backup/static/description/testconnection.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
jikimo_auto_backup/static/description/testconnectionfailed.png
Normal file
|
After Width: | Height: | Size: 4.0 KiB |
105
jikimo_auto_backup/views/backup_view.xml
Normal file
@@ -0,0 +1,105 @@
|
||||
<odoo>
|
||||
<record id="view_backup_config_form" model="ir.ui.view">
|
||||
<field name="name">db.backup.form</field>
|
||||
<field name="model">db.backup</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Back-up view">
|
||||
<sheet>
|
||||
<group col="4" colspan="4">
|
||||
<separator col="2" string="Local backup configuration"/>
|
||||
</group>
|
||||
<group name="configuration">
|
||||
<field name="host" colspan="2"/>
|
||||
<field name="name"/>
|
||||
<field name="port"/>
|
||||
<field name="backup_type"/>
|
||||
<field name="folder"/>
|
||||
<field name="autoremove"/>
|
||||
<field name="days_to_keep" attrs="{'invisible': [('autoremove','=',False)]}"/>
|
||||
</group>
|
||||
<group name="allow_stfp" col="4" colspan="4">
|
||||
<separator col="2" string="SFTP"/>
|
||||
</group>
|
||||
<div style="width:50%;border-radius:10px;margin: 10px 0px;padding:15px 10px 15px 10px;
|
||||
background-repeat: no-repeat;background-position: 10px center;color: #9F6000;
|
||||
background-color: #FEEFB3;"
|
||||
attrs="{'invisible': [('sftp_write','=',False)]}">
|
||||
<b>Warning:</b>
|
||||
Use SFTP with caution! This writes files to external servers under the path you specify.
|
||||
</div>
|
||||
<group name="sftp_configuration">
|
||||
<field name="sftp_write"/>
|
||||
<field name="sftp_host"
|
||||
attrs="{'invisible':[('sftp_write', '=', False)],'required':[('sftp_write', '=', True)]}"/>
|
||||
<field name="sftp_port"
|
||||
attrs="{'invisible':[('sftp_write', '=', False)],'required':[('sftp_write', '=', True)]}"/>
|
||||
<field name="sftp_user"
|
||||
attrs="{'invisible':[('sftp_write', '=', False)], 'required':[('sftp_write', '=', True)]}"/>
|
||||
<field name="sftp_password"
|
||||
attrs="{'invisible':[('sftp_write', '=', False)],'required': [('sftp_write', '=', True)]}"
|
||||
password="True"/>
|
||||
<field name="sftp_path"
|
||||
attrs="{'invisible':[('sftp_write', '==', False)],'required':[('sftp_write', '==', True)]}"
|
||||
placeholder="For example: /odoo/backups/"/>
|
||||
<field name="days_to_keep_sftp"
|
||||
attrs="{'invisible': [('sftp_write', '=', False)], 'required': [('sftp_write', '=', True)]}"/>
|
||||
<field name="send_mail_sftp_fail" attrs="{'invisible': [('sftp_write','=',False)]}"/>
|
||||
<field name="email_to_notify"
|
||||
attrs="{'invisible':['|',('send_mail_sftp_fail', '==', False), ('sftp_write', '=', False)], 'required': [('send_mail_sftp_fail', '=', True)]}"/>
|
||||
<button name="test_sftp_connection" type="object"
|
||||
attrs="{'invisible': [('sftp_write','=',False)]}" string="Test SFTP Connection"/>
|
||||
</group>
|
||||
<separator string="Help" colspan="2"/>
|
||||
<div name="configuration_details">
|
||||
This configures the scheduler for automatic backup of the given database running on given host
|
||||
at given port on regular intervals.
|
||||
<br/>
|
||||
Automatic backups of the database can be scheduled as follows:
|
||||
<ol>
|
||||
<li>
|
||||
Go to Settings / Technical / Automation / Scheduled Actions.
|
||||
</li>
|
||||
<li>
|
||||
Search the action named 'Backup scheduler'.
|
||||
</li>
|
||||
<li>
|
||||
Set the scheduler to active and fill in how often you want backups generated.
|
||||
</li>
|
||||
</ol>
|
||||
<p style="font-size:18px;">
|
||||
Need more help?
|
||||
<a href="https://github.com/Yenthe666/auto_backup/issues">Contact me!</a>
|
||||
</p>
|
||||
</div>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_backup_config_tree" model="ir.ui.view">
|
||||
<field name="name">db.backup.tree</field>
|
||||
<field name="model">db.backup</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree>
|
||||
<field name='host'/>
|
||||
<field name='port'/>
|
||||
<field name='name'/>
|
||||
<field name='folder'/>
|
||||
<field name="autoremove"/>
|
||||
<field name="sftp_host"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_backup" model="ir.actions.act_window">
|
||||
<field name="name">Configure back-ups</field>
|
||||
<field name="res_model">db.backup</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="view_id" ref="view_backup_config_tree"/>
|
||||
</record>
|
||||
|
||||
<menuitem id="auto_backup_menu" name="Back-ups" parent="base.menu_custom"/>
|
||||
<menuitem parent="auto_backup_menu" action="action_backup" id="backup_conf_menu"/>
|
||||
</odoo>
|
||||
@@ -10,9 +10,9 @@
|
||||
""",
|
||||
'category': 'sf',
|
||||
'website': 'https://www.sf.jikimo.com',
|
||||
'depends': ['web', 'purchase'],
|
||||
'depends': ['web', 'purchase', 'base_setup'],
|
||||
'data': [
|
||||
|
||||
'views/bye_odoo.xml',
|
||||
],
|
||||
'demo': [
|
||||
],
|
||||
@@ -23,6 +23,8 @@
|
||||
'web.assets_backend': [
|
||||
'jikimo_frontend/static/src/fields/custom_many2many_checkboxes/*',
|
||||
'jikimo_frontend/static/src/fields/Many2OneRadioField/*',
|
||||
# 移除odoo相关标识
|
||||
'jikimo_frontend/static/src/bye_odoo/*',
|
||||
'jikimo_frontend/static/src/scss/custom_style.scss',
|
||||
# 'jikimo_frontend/static/src/views/list_nums/list_nbCols.js',
|
||||
'jikimo_frontend/static/src/views/list_nums/list_nums.xml',
|
||||
@@ -36,7 +38,7 @@
|
||||
# 'jikimo_frontend/static/src/list/custom_import.js',
|
||||
# 'jikimo_frontend/static/src/list/custom_width.js',
|
||||
'jikimo_frontend/static/src/views/list_nums/extent_purchase.xml',
|
||||
# 'jikimo_frontend/static/src/css/list_border_styles.css',
|
||||
'jikimo_frontend/static/src/css/list_border_styles.css',
|
||||
|
||||
],
|
||||
|
||||
|
||||
23
jikimo_frontend/data/demo_data.xml
Normal file
@@ -0,0 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="partner_demo_company" model="res.partner">
|
||||
<field name="name">JKM</field>
|
||||
<field name="street">B-25</field>
|
||||
<field name="city">USA</field>
|
||||
<!-- Use the correct reference or actual ID for the country -->
|
||||
<field name="country_id" ref="base.bd"/>
|
||||
<field name="zip">1229</field>
|
||||
<field name="phone">+8801-712901764</field>
|
||||
<field name="email">info@kolpolok.com</field>
|
||||
<field name="website">www.kolpoloktechnologies.com</field>
|
||||
</record>
|
||||
|
||||
<record id="demo_company" model="res.company">
|
||||
<field name="name">Custom</field>
|
||||
<field name="logo" type="base64" file="kolpolok_custom_title_and_favicon/static/src/img/favicon.ico"/>
|
||||
<field name="favicon" type="base64" file="kolpolok_custom_title_and_favicon/static/src/img/favicon.ico"/>
|
||||
<field name="partner_id" ref="partner_demo_company"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
16
jikimo_frontend/static/src/bye_odoo/extended_user_menu.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/** @odoo-module **/
|
||||
import { UserMenu } from "@web/webclient/user_menu/user_menu";
|
||||
import { patch } from "@web/core/utils/patch";
|
||||
import { registry } from "@web/core/registry";
|
||||
const userMenuRegistry = registry.category("user_menuitems");
|
||||
|
||||
|
||||
patch(UserMenu.prototype, "legion_hide_odoo.UserMenu", {
|
||||
setup() {
|
||||
this._super.apply(this, arguments);
|
||||
userMenuRegistry.remove("documentation");
|
||||
userMenuRegistry.remove("support");
|
||||
userMenuRegistry.remove("odoo_account");
|
||||
},
|
||||
|
||||
});
|
||||
11
jikimo_frontend/static/src/bye_odoo/favicon.js
Normal file
@@ -0,0 +1,11 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { WebClient } from "@web/webclient/webclient";
|
||||
import { patch } from "web.utils";
|
||||
|
||||
patch(WebClient.prototype, "kolpolok_custom_title_and_favicon.WebClient", {
|
||||
setup() {
|
||||
this._super();
|
||||
this.title.setParts({ zopenerp: "JIKIMO" });
|
||||
},
|
||||
});
|
||||
BIN
jikimo_frontend/static/src/img/favicon.ico
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
BIN
jikimo_frontend/static/src/img/jikimo-logo.ico
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
jikimo_frontend/static/src/img/jikimo.ico
Normal file
|
After Width: | Height: | Size: 3.1 KiB |
@@ -4,59 +4,239 @@ import {patch} from '@web/core/utils/patch';
|
||||
// import { Dialog } from "@web/core/dialog/dialog";
|
||||
import {_t} from "@web/core/l10n/translation";
|
||||
import {FormStatusIndicator} from "@web/views/form/form_status_indicator/form_status_indicator";
|
||||
import {ListRenderer} from "@web/views/list/list_renderer";
|
||||
import {StatusBarField} from "@web/views/fields/statusbar/statusbar_field";
|
||||
|
||||
import {Field} from "@web/views/fields/field";
|
||||
|
||||
var Dialog = require('web.Dialog');
|
||||
// var {patch} = require("web.utils") 这句话也行
|
||||
const filedRequiredList = {
|
||||
// 设备大模块
|
||||
'control_system_id': { multiple: false, noLabel: false },
|
||||
'workbench_L': { multiple: true, noLabel: false },
|
||||
'number_of_axles': { multiple: true, noLabel: false },
|
||||
'x_axis': { multiple: true, noLabel: false },
|
||||
'number_of_knife_library': { multiple: false, noLabel: false },
|
||||
'brand_id': { multiple: false, noLabel: false },
|
||||
'type_id': { multiple: false, noLabel: false },
|
||||
'taper_type_id': { multiple: false, noLabel: false },
|
||||
'eq_maintenance_id': { multiple: false, noLabel: false },
|
||||
'overhaul_id': { multiple: false, noLabel: false },
|
||||
'overhaul_period': { multiple: false, noLabel: false },
|
||||
'maintenance_equipment_category_id': { multiple: false, noLabel: false },
|
||||
'maintenance_type': { multiple: false, noLabel: false },
|
||||
|
||||
// 销售大模块
|
||||
'partner_id': { multiple: false, noLabel: false },
|
||||
'validity_date': { multiple: false, noLabel: false },
|
||||
'vat': { multiple: false, noLabel: false },
|
||||
'phone': { multiple: false, noLabel: false },
|
||||
'mobile': { multiple: false, noLabel: false },
|
||||
'email': { multiple: false, noLabel: false },
|
||||
'category_id': { multiple: false, noLabel: false },
|
||||
'radio_field_1_person': { multiple: false, noLabel: true },
|
||||
|
||||
// 采购大模块
|
||||
'date_order': { multiple: false, noLabel: false },
|
||||
'picking_type_id': { multiple: false, noLabel: false },
|
||||
|
||||
// 制造大模块
|
||||
'production_line_id': { multiple: false, noLabel: false },
|
||||
'date_approve': { multiple: false, noLabel: false },
|
||||
'date_planned_start': { multiple: false, noLabel: false },
|
||||
'date_planned_finished': { multiple: false, noLabel: false },
|
||||
}
|
||||
const tableRequiredList = [
|
||||
'product_template_id', 'product_uom_qty', 'price_unit','product_id','product_qty',
|
||||
'name', 'fault_type', 'maintenance_standards', 'Period'
|
||||
]
|
||||
|
||||
patch(FormStatusIndicator.prototype, 'jikimo_frontend.FormStatusIndicator', {
|
||||
// 你可以重写或者添加一些方法和属性
|
||||
async _onDiscardChanges() {
|
||||
// var self = this;
|
||||
Dialog.confirm(this, _t("Are you sure you want to discard changes?"), {
|
||||
title: _t("Discard Changes"),
|
||||
// 你可以重写或者添加一些方法和属性
|
||||
async _onDiscardChanges() {
|
||||
// var self = this;
|
||||
Dialog.confirm(this, _t("Are you sure you want to discard changes?"), {
|
||||
title: _t("Discard Changes"),
|
||||
|
||||
// confirm_callback: function () {
|
||||
// self.model.discardChanges(self.handle);
|
||||
// },
|
||||
});
|
||||
},
|
||||
// confirm_callback: function () {
|
||||
// self.model.discardChanges(self.handle);
|
||||
// },
|
||||
});
|
||||
},
|
||||
|
||||
async discard() {
|
||||
// if (window.confirm("Are you sure you want to discard changes?")) {
|
||||
// await this.props.discard();
|
||||
// }
|
||||
// const result = await this._confirmDiscardChange();
|
||||
await this._confirmDiscardChange();
|
||||
await this.props.discard();
|
||||
},
|
||||
async discard() {
|
||||
// if (window.confirm("Are you sure you want to discard changes?")) {
|
||||
// await this.props.discard();
|
||||
// }
|
||||
// const result = await this._confirmDiscardChange();
|
||||
await this._confirmDiscardChange();
|
||||
await this.props.discard();
|
||||
},
|
||||
|
||||
_confirmDiscardChange(){
|
||||
var self = this;
|
||||
var def = new Promise(function (resolve, reject) {
|
||||
var message = _t("请确认是否要舍弃之前的更改?");
|
||||
var dialog = Dialog.confirm(self, message, {
|
||||
title: _t("Warning"),
|
||||
confirm_callback: resolve.bind(self, true),
|
||||
cancel_callback: reject,
|
||||
});
|
||||
dialog.on('closed', self, reject);
|
||||
});
|
||||
return def;
|
||||
},
|
||||
_confirmDiscardChange() {
|
||||
var self = this;
|
||||
var def = new Promise(function (resolve, reject) {
|
||||
var message = _t("请确认是否要舍弃之前的更改?");
|
||||
var dialog = Dialog.confirm(self, message, {
|
||||
title: _t("Warning"),
|
||||
confirm_callback: resolve.bind(self, true),
|
||||
cancel_callback: reject,
|
||||
});
|
||||
dialog.on('closed', self, reject);
|
||||
});
|
||||
return def;
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
patch(Field.prototype, 'jikimo_frontend.Field', {
|
||||
setup() {
|
||||
owl.onMounted(this.setRequired);
|
||||
return this._super(...arguments);
|
||||
},
|
||||
setRequired() {
|
||||
const id = this.props.id
|
||||
const isRequired = filedRequiredList[id]
|
||||
if(id == 'number_of_axles') {
|
||||
console.log(isRequired)
|
||||
}
|
||||
if(isRequired) {
|
||||
let dom;
|
||||
dom = $(`label[for=${id}]`)
|
||||
if(isRequired.multiple && dom.length > 1) {
|
||||
dom = dom.eq(-1)
|
||||
dom = dom.parent().parent().next().find('label')
|
||||
}
|
||||
if(isRequired.noLabel) {
|
||||
dom = dom.parent().parent()
|
||||
}
|
||||
let t = dom.html()
|
||||
t = '<i class="c* r" style="color: red;margin-left: -4px">*</i>' + t
|
||||
dom.html(t)
|
||||
}
|
||||
}
|
||||
})
|
||||
patch(ListRenderer.prototype, 'jikimo_frontend.ListRenderer', {
|
||||
setup(){
|
||||
owl.onMounted(() => {
|
||||
this.activeElement = this.uiService.activeElement;
|
||||
this.setRequired()
|
||||
})
|
||||
return this._super(...arguments);
|
||||
},
|
||||
setRequired() {
|
||||
this.allColumns.forEach(_ => {
|
||||
if( tableRequiredList.indexOf(_.name) >= 0 ) {
|
||||
const dom = $(`th[data-name=${_.name}]`)
|
||||
dom.addClass('addRequired')
|
||||
}
|
||||
})
|
||||
try {
|
||||
const dom = this.tableRef.el
|
||||
if(dom ) {
|
||||
const tfoot = $(dom).children('tfoot')
|
||||
const tbooy = $(dom).children('tbody')
|
||||
if(tfoot.length) {
|
||||
const tfoot_tr = tfoot.children().eq(0)
|
||||
const tbody_tr = tbooy.children().eq(0)
|
||||
if(tfoot_tr.children().length < tbody_tr.children().length) {
|
||||
tfoot_tr.prepend('<td class="prepend">')
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$(function (){
|
||||
|
||||
// 根据进度条设置水印
|
||||
const statusbar_params = {
|
||||
'已完工': 'bg-primary',
|
||||
'完成': 'bg-primary',
|
||||
'采购订单': 'bg-primary',
|
||||
'作废': 'bg-danger',
|
||||
'封存(报废)': 'bg-danger',
|
||||
}
|
||||
patch(StatusBarField.prototype, 'jikimo_frontend.StatusBarField', {
|
||||
setup() {
|
||||
owl.onMounted(this.ribbons);
|
||||
return this._super(...arguments);
|
||||
},
|
||||
ribbons() {
|
||||
try {
|
||||
const dom = $('.o_form_sheet.position-relative')
|
||||
const status = statusbar_params[this.currentName]
|
||||
if(status && dom.length) {
|
||||
dom.prepend(`<div class="o_widget o_widget_web_ribbon">
|
||||
<div class="ribbon ribbon-top-right">
|
||||
<span class="bg-opacity-75 ${status}" title="">${this.currentName}</span>
|
||||
</div>
|
||||
</div>`)
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
$(function () {
|
||||
document.addEventListener('click', function () {
|
||||
const dom = $('.o_form_status_indicator_buttons ')
|
||||
if(dom) {
|
||||
if (dom) {
|
||||
const dom1 = dom.children().eq(0)
|
||||
const dom2 = dom.children().eq(1)
|
||||
if(!dom1.text()) {
|
||||
if (!dom1.text()) {
|
||||
dom1.append('保存')
|
||||
dom2.append('取消')
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
function customRequired() {
|
||||
let timer = null
|
||||
let timer_count = 0
|
||||
clearInterval(timer)
|
||||
timer = setInterval(() => {
|
||||
timer_count++
|
||||
const dom = $('.custom_required')
|
||||
let tableDom = $('.table_custom_required')
|
||||
if (tableDom.length) {
|
||||
tableDom = tableDom.eq(0).parents('tr').children('.table_custom_required')
|
||||
tableDom.each(function () {
|
||||
const i = $(this).index()
|
||||
const requiredDom = $(this).parents('table').find('thead').find('th').eq(i).find('span').eq(0)
|
||||
const t = requiredDom.text().replace('*', '')
|
||||
requiredDom.html('<i style="color: red;margin-left: -4px">*</i>' + t)
|
||||
})
|
||||
clearInterval(timer)
|
||||
}
|
||||
if (dom.length) {
|
||||
dom.each(function () {
|
||||
const requiredDom = $(this).parent().prev().find('label')
|
||||
let t = requiredDom.html()
|
||||
if (t && t.indexOf('c*') < 0) {
|
||||
t = '<i class="c*" style="color: red;margin-left: -4px">*</i>' + t
|
||||
}
|
||||
requiredDom.html(t)
|
||||
})
|
||||
clearInterval(timer)
|
||||
}
|
||||
if (timer_count == 20) {
|
||||
clearInterval(timer)
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
|
||||
var currentUrl = location.href
|
||||
const listenerUrl = setInterval(() => {
|
||||
const isChange = currentUrl != location.href
|
||||
if (isChange) {
|
||||
currentUrl = location.href
|
||||
customRequired()
|
||||
}
|
||||
}, 500)
|
||||
customRequired()
|
||||
})
|
||||
|
||||
@@ -3,6 +3,15 @@
|
||||
import { registry } from "@web/core/registry";
|
||||
import { url } from "@web/core/utils/urls";
|
||||
import { ImageField, imageCacheKey } from '@web/views/fields/image/image_field';
|
||||
import { isBinarySize } from "@web/core/utils/binary";
|
||||
export const fileTypeMagicWordMap = {
|
||||
"/": "jpg",
|
||||
R: "gif",
|
||||
i: "png",
|
||||
P: "svg+xml",
|
||||
};
|
||||
|
||||
const placeholder = "/web/static/img/placeholder.png";
|
||||
|
||||
export class CustomImageField extends ImageField {
|
||||
setup() {
|
||||
@@ -13,7 +22,7 @@ export class CustomImageField extends ImageField {
|
||||
getUrl(previewFieldName) {
|
||||
console.log('8888888888886666666666666666666')
|
||||
if (this.state.isValid && this.props.value) {
|
||||
if (1) {
|
||||
if (isBinarySize(this.props.value) || this.props.value.length < 50) {
|
||||
if (!this.rawCacheKey) {
|
||||
this.rawCacheKey = this.props.record.data.__last_update;
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ div:has(.o_required_modifier) > label::before {
|
||||
color: red !important;
|
||||
padding: 0 4px !important;
|
||||
vertical-align: top !important;
|
||||
font-size: 1.5rem !important;
|
||||
font-size: unset !important;
|
||||
}
|
||||
|
||||
.my-image div {
|
||||
@@ -325,7 +325,7 @@ div[class="o_content o_component_with_search_panel"] .show_state span {
|
||||
|
||||
div:has(.o_required_modifier) > label::before {
|
||||
position: absolute;
|
||||
left: -3px;
|
||||
left: 24px;
|
||||
}
|
||||
|
||||
//.o_form_view .o_form_label {
|
||||
@@ -449,4 +449,58 @@ div:has(.o_required_modifier) > label::before {
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// 更改表格底部按钮样式
|
||||
.o_list_renderer .o_field_x2many_list_row_add a,.treeHeaderBtn,.o_x2m_control_panel .o_cp_buttons .btn{
|
||||
display: inline-block;
|
||||
margin: 5px 0;
|
||||
font-size: 14px;
|
||||
color: #71639e;
|
||||
border: 1px solid #71639e;
|
||||
padding: 0.2rem 0.6rem;
|
||||
font-size: 1.08333333rem;
|
||||
border-radius: 0.25rem;
|
||||
transition: all .3s;
|
||||
}
|
||||
.o_list_renderer .o_field_x2many_list_row_add a:hover,.treeHeaderBtn:hover,.o_x2m_control_panel .o_cp_buttons .btn:hover{
|
||||
background: #71639e;
|
||||
color: #fff
|
||||
}
|
||||
|
||||
// 修改时间输入框宽度
|
||||
.o_datepicker_input.o_input.datetimepicker-input {
|
||||
width: 200px;
|
||||
}
|
||||
|
||||
|
||||
.o_form_view .o_form_editable .o_row > .o_field_widget, .o_form_view .o_form_editable .o_row > .o_field_widget.o_field_float_time {
|
||||
width: auto !important;
|
||||
flex: unset;
|
||||
}
|
||||
.addRequired {
|
||||
padding-left: calc(0.3rem + 2px)!important;
|
||||
}
|
||||
.addRequired:before {
|
||||
content: '*';
|
||||
color: red;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
.o_list_renderer .o_list_table tfoot .o_list_number {
|
||||
text-align: left !important;
|
||||
}
|
||||
|
||||
.o_field_widget.o_readonly_modifier.o_required_modifier.o_field_many2one[name=production_id] .o_form_uri {
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
// 修改 【批量排程】【配送】 按钮UI
|
||||
.btn-secondary {
|
||||
color: #fff;
|
||||
background-color: #4A4F59;
|
||||
border-color: #4A4F59;
|
||||
}
|
||||
35
jikimo_frontend/views/bye_odoo.xml
Normal file
@@ -0,0 +1,35 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<!-- 修改页面头部图标及文字 -->
|
||||
<template id="favicon_icon" inherit_id="web.layout" name="Web layout">
|
||||
<!-- change the title with reliance partner -->
|
||||
<xpath expr="//head//title" position="before">
|
||||
<title t-esc="'JIKIMO'"/>
|
||||
</xpath>
|
||||
<!-- change the default favicon icon with -->
|
||||
<xpath expr="//head//link[@rel='shortcut icon']" position="replace">
|
||||
<link type="image/x-icon" rel="shortcut icon" href="/jikimo_frontend/static/src/img/jikimo-logo.ico"/>
|
||||
</xpath>
|
||||
</template>
|
||||
|
||||
<!-- hide 登录页面 powerd by odoo 及管理数据库 -->
|
||||
<template id="login_page_layout" inherit_id="web.login_layout" name="Login Page Layout">
|
||||
<xpath expr="//div[@class='card-body']//div[last()]" position="replace"></xpath>
|
||||
</template>
|
||||
|
||||
<!-- 隐藏odoo版本信息 -->
|
||||
<record id="jikimo_res_config_settings_view_form" model="ir.ui.view">
|
||||
<field name="name">jikimo.res.config.settings.view.form.inherit.base.setup</field>
|
||||
<field name="model">res.config.settings</field>
|
||||
<field name="inherit_id" ref="base_setup.res_config_settings_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@id='about']" position="replace">
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -4,7 +4,8 @@ csv_internal_sep = ,
|
||||
data_dir = /var/lib/odoo
|
||||
db_host = 172.17.0.2
|
||||
db_maxconn = 64
|
||||
db_name = sf_t2cs_003
|
||||
# db_name = sf_t_0430
|
||||
db_name = t_240509
|
||||
db_password = sf
|
||||
db_port = 5432
|
||||
db_sslmode = prefer
|
||||
|
||||
@@ -263,6 +263,8 @@ class QualityCheck(models.Model):
|
||||
picture = fields.Binary('Picture', attachment=True)
|
||||
additional_note = fields.Text(
|
||||
'Additional Note', help="Additional remarks concerning this check.")
|
||||
report_result = fields.Char('检测结果', readonly=True)
|
||||
report_pdf = fields.Binary('检测报告', readonly=True)
|
||||
|
||||
def _compute_alert_count(self):
|
||||
alert_data = self.env['quality.alert'].read_group([('check_id', 'in', self.ids)], ['check_id'], ['check_id'])
|
||||
@@ -408,3 +410,5 @@ class QualityAlert(models.Model):
|
||||
domain = [('team_ids', '=', False)]
|
||||
stage_ids = stages._search(domain, order=order, access_rights_uid=SUPERUSER_ID)
|
||||
return stages.browse(stage_ids)
|
||||
|
||||
|
||||
|
||||
@@ -9,8 +9,10 @@ access_quality_point_user,quality.point,quality.model_quality_point,quality.grou
|
||||
access_quality_point_test_type_user,quality.point.test_type,quality.model_quality_point_test_type,quality.group_quality_user,1,0,0,0
|
||||
access_quality_check_stock_user,quality.check,quality.model_quality_check,stock.group_stock_user,1,1,1,0
|
||||
access_stock_lot_user,stock.lot,stock.model_stock_lot,quality.group_quality_user,1,0,0,0
|
||||
|
||||
access_stock_pack_user,stock.move.line,stock.model_stock_move_line,quality.group_quality_user,1,0,0,0
|
||||
access_stock_picking,stock.move.line,stock.model_stock_picking,quality.group_quality_user,1,0,0,0
|
||||
access_stock_picking_group_quality_user,stock_picking_group_quality_user,stock.model_stock_picking,quality.group_quality_user,1,0,0,0
|
||||
|
||||
access_quality_alert_team_manager,quality.alert.team,quality.model_quality_alert_team,quality.group_quality_manager,1,1,1,1
|
||||
access_quality_check_manager,quality.check,quality.model_quality_check,quality.group_quality_manager,1,1,1,1
|
||||
access_quality_alert_manager,quality.alert,quality.model_quality_alert,quality.group_quality_manager,1,1,1,1
|
||||
|
||||
|
@@ -32,7 +32,9 @@
|
||||
<field name="tag_ids"/>
|
||||
</div>
|
||||
<div>
|
||||
<strong><field name="product_tmpl_id"/></strong>
|
||||
<strong>
|
||||
<field name="product_tmpl_id"/>
|
||||
</strong>
|
||||
</div>
|
||||
<div>
|
||||
<field name="display_name"/>
|
||||
@@ -65,20 +67,28 @@
|
||||
<field name="company_id" invisible="1"/>
|
||||
<field name="product_id" invisible="1"/>
|
||||
<div class="oe_button_box">
|
||||
<button name="action_see_check" type="object" attrs="{'invisible': [('check_id', '=', False)]}" class="oe_stat_button" icon="fa-check-square-o">
|
||||
<button name="action_see_check" type="object" attrs="{'invisible': [('check_id', '=', False)]}"
|
||||
class="oe_stat_button" icon="fa-check-square-o">
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value"><field name="check_id" readonly="1"/></span>
|
||||
<span class="o_stat_value">
|
||||
<field name="check_id" readonly="1"/>
|
||||
</span>
|
||||
<span class="o_stat_text">Quality Check</span>
|
||||
</div>
|
||||
</button>
|
||||
</div>
|
||||
<div class="oe_title"><h1><field name="name" readonly="1"/></h1></div>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" readonly="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="title"/>
|
||||
<field name="product_tmpl_id"/>
|
||||
<field name="product_id" groups="product.group_product_variant"/>
|
||||
<field name="lot_id" context="{'default_product_id': product_id}" groups="stock.group_production_lot"/>
|
||||
<field name="lot_id" context="{'default_product_id': product_id}"
|
||||
groups="stock.group_production_lot"/>
|
||||
<field name="picking_id"/>
|
||||
</group>
|
||||
<group>
|
||||
@@ -144,25 +154,25 @@
|
||||
</record>
|
||||
|
||||
<record id="quality_alert_view_pivot" model="ir.ui.view">
|
||||
<field name="name">quality.alert.view.pivot</field>
|
||||
<field name="model">quality.alert</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Quality Alert Analysis" sample="1">
|
||||
<field name="stage_id" type="col"/>
|
||||
<field name="team_id" type="row"/>
|
||||
</pivot>
|
||||
</field>
|
||||
<field name="name">quality.alert.view.pivot</field>
|
||||
<field name="model">quality.alert</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Quality Alert Analysis" sample="1">
|
||||
<field name="stage_id" type="col"/>
|
||||
<field name="team_id" type="row"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="quality_alert_view_graph" model="ir.ui.view">
|
||||
<field name="name">quality.alert.view.graph</field>
|
||||
<field name="model">quality.alert</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Quality Alert Analysis" sample="1">
|
||||
<field name="reason_id"/>
|
||||
<field name="stage_id"/>
|
||||
</graph>
|
||||
</field>
|
||||
<field name="name">quality.alert.view.graph</field>
|
||||
<field name="model">quality.alert</field>
|
||||
<field name="arch" type="xml">
|
||||
<graph string="Quality Alert Analysis" sample="1">
|
||||
<field name="reason_id"/>
|
||||
<field name="stage_id"/>
|
||||
</graph>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="quality_alert_view_calendar" model="ir.ui.view">
|
||||
@@ -186,7 +196,8 @@
|
||||
<field name="view_mode">kanban,tree,form,pivot,graph,calendar</field>
|
||||
<field name="domain">[('team_id', '=', active_id)]</field>
|
||||
<field name="context">{'default_team_id': active_id,
|
||||
'search_default_team_id': [active_id]}</field>
|
||||
'search_default_team_id': [active_id]}
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="quality_alert_action_check" model="ir.actions.act_window">
|
||||
@@ -195,7 +206,7 @@
|
||||
<field name="view_mode">kanban,tree,form,pivot,graph,calendar</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new quality alert
|
||||
Create a new quality alert
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
@@ -212,24 +223,35 @@
|
||||
</record>
|
||||
|
||||
<!-- QUALITY.CHECK -->
|
||||
<record id="quality_check_view_form" model="ir.ui.view">
|
||||
<record id="quality_check_view_form" model="ir.ui.view">
|
||||
<field name="name">quality.check.view.form</field>
|
||||
<field name="model">quality.check</field>
|
||||
<field name="arch" type="xml">
|
||||
<form>
|
||||
<header>
|
||||
<button name="do_pass" type="object" class="btn-primary" attrs="{'invisible': [('quality_state', '!=', 'none')]}" string="Pass" data-hotkey="q"/>
|
||||
<button name="do_pass" type="object" attrs="{'invisible': [('quality_state', '!=', 'fail')]}" groups="quality.group_quality_manager" string="Pass" data-hotkey="q"/>
|
||||
<button name="do_fail" type="object" class="btn-primary" attrs="{'invisible': [('quality_state', '!=', 'none')]}" string="Fail" data-hotkey="w"/>
|
||||
<button name="do_fail" type="object" attrs="{'invisible': [('quality_state', '!=', 'pass')]}" groups="quality.group_quality_manager" string="Fail" data-hotkey="w"/>
|
||||
<button name="do_measure" type="object" attrs="{'invisible': ['|', ('test_type', '!=', 'measure'), ('quality_state', '!=', 'none')]}" string="Measure" data-hotkey="v"/>
|
||||
<button name="do_alert" type="object" attrs="{'invisible': ['|', ('alert_ids', '!=', []), ('quality_state', '!=', 'pass')]}" string="Create Alert" data-hotkey="g"/>
|
||||
<button name="do_alert" type="object" class="btn-primary" attrs="{'invisible': ['|', ('alert_ids', '!=', []), ('quality_state', '!=', 'fail')]}" string="Create Alert" data-hotkey="g"/>
|
||||
<button name="do_pass" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('quality_state', '!=', 'none')]}" string="Pass" data-hotkey="q"/>
|
||||
<button name="do_pass" type="object" attrs="{'invisible': [('quality_state', '!=', 'fail')]}"
|
||||
groups="quality.group_quality_manager" string="Pass" data-hotkey="q"/>
|
||||
<button name="do_fail" type="object" class="btn-primary"
|
||||
attrs="{'invisible': [('quality_state', '!=', 'none')]}" string="Fail" data-hotkey="w"/>
|
||||
<button name="do_fail" type="object" attrs="{'invisible': [('quality_state', '!=', 'pass')]}"
|
||||
groups="quality.group_quality_manager" string="Fail" data-hotkey="w"/>
|
||||
<button name="do_measure" type="object"
|
||||
attrs="{'invisible': ['|', ('test_type', '!=', 'measure'), ('quality_state', '!=', 'none')]}"
|
||||
string="Measure" data-hotkey="v"/>
|
||||
<button name="do_alert" type="object"
|
||||
attrs="{'invisible': ['|', ('alert_ids', '!=', []), ('quality_state', '!=', 'pass')]}"
|
||||
string="Create Alert" data-hotkey="g"/>
|
||||
<button name="do_alert" type="object" class="btn-primary"
|
||||
attrs="{'invisible': ['|', ('alert_ids', '!=', []), ('quality_state', '!=', 'fail')]}"
|
||||
string="Create Alert" data-hotkey="g"/>
|
||||
<field name="quality_state" widget="statusbar"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="action_see_alerts" icon="fa-bell" type="object" class="oe_stat_button" attrs="{'invisible': [('alert_count', '=', 0)]}">
|
||||
<button name="action_see_alerts" icon="fa-bell" type="object" class="oe_stat_button"
|
||||
attrs="{'invisible': [('alert_count', '=', 0)]}">
|
||||
<field name="alert_count" string="Alerts" widget="statinfo"/>
|
||||
</button>
|
||||
</div>
|
||||
@@ -242,21 +264,27 @@
|
||||
<field name="move_line_id" invisible="1"/>
|
||||
<field name="product_tracking" invisible="1"/>
|
||||
<field name="is_lot_tested_fractionally" invisible="1"/>
|
||||
<field name="lot_name" attrs="{'invisible': ['|', ('product_tracking', '=', 'none'), '|', ('show_lot_text', '=', False), '|', ('measure_on', '!=', 'move_line'), ('move_line_id', '=', False)]}"/>
|
||||
<field name="lot_id" attrs="{'invisible': ['|', ('product_tracking', '=', 'none'), '|', ('show_lot_text', '=', True), ('measure_on', '!=', 'move_line')]}"/>
|
||||
<field name="lot_name"
|
||||
attrs="{'invisible': ['|', ('product_tracking', '=', 'none'), '|', ('show_lot_text', '=', False), '|', ('measure_on', '!=', 'move_line'), ('move_line_id', '=', False)]}"/>
|
||||
<field name="lot_id"
|
||||
attrs="{'invisible': ['|', ('product_tracking', '=', 'none'), '|', ('show_lot_text', '=', True), ('measure_on', '!=', 'move_line')]}"/>
|
||||
<label for="qty_line" attrs="{'invisible': [('move_line_id', '=', False)]}"/>
|
||||
<div class="o_row" attrs="{'invisible': [('move_line_id', '=', False)]}">
|
||||
<field name="qty_line"/>
|
||||
<field name="qty_line"/>
|
||||
<field name="uom_id"/>
|
||||
</div>
|
||||
<label for="qty_to_test" attrs="{'invisible': ['|', ('move_line_id', '=', False), '|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '=', False)]}"/>
|
||||
<div class="o_row" attrs="{'invisible': ['|', ('move_line_id', '=', False), '|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '=', False)]}">
|
||||
<field name="qty_to_test"/>
|
||||
<label for="qty_to_test"
|
||||
attrs="{'invisible': ['|', ('move_line_id', '=', False), '|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '=', False)]}"/>
|
||||
<div class="o_row"
|
||||
attrs="{'invisible': ['|', ('move_line_id', '=', False), '|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '=', False)]}">
|
||||
<field name="qty_to_test"/>
|
||||
<field name="uom_id"/>
|
||||
</div>
|
||||
<label for="qty_tested" attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '=', False)]}"/>
|
||||
<div class="o_row" attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '=', False)]}">
|
||||
<field name="qty_tested" attrs="{'readonly': [('quality_state', '!=', 'none')]}"/>
|
||||
<label for="qty_tested"
|
||||
attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '=', False)]}"/>
|
||||
<div class="o_row"
|
||||
attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '=', False)]}">
|
||||
<field name="qty_tested" attrs="{'readonly': [('quality_state', '!=', 'none')]}"/>
|
||||
<field name="uom_id"/>
|
||||
</div>
|
||||
<field name="test_type" invisible="1"/>
|
||||
@@ -264,26 +292,32 @@
|
||||
<field name="alert_ids" invisible="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="picking_id" attrs="{'invisible': [('quality_state', 'in', ('pass', 'fail')), ('picking_id', '=', False)]}"/>
|
||||
<field name="picking_id"
|
||||
attrs="{'invisible': [('quality_state', 'in', ('pass', 'fail')), ('picking_id', '=', False)]}"/>
|
||||
<field name="point_id"/>
|
||||
<field string="Type" name="test_type_id" options="{'no_open': True, 'no_create': True}" attrs="{'readonly': [('point_id', '!=', False)]}"/>
|
||||
<field string="Type" name="test_type_id" options="{'no_open': True, 'no_create': True}"
|
||||
attrs="{'readonly': [('point_id', '!=', False)]}"/>
|
||||
<field name="control_date" invisible="1"/>
|
||||
<field name="team_id"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="user_id" string="Control Person" invisible="1"/>
|
||||
<field name="partner_id" string="Partner" attrs="{'invisible': [('partner_id', '=', False)]}"/>
|
||||
<field name="partner_id" string="Partner"
|
||||
attrs="{'invisible': [('partner_id', '=', False)]}"/>
|
||||
</group>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('test_type', '!=', 'picture')]}">
|
||||
<field name="picture" widget="image"/>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="Notes" name="notes">
|
||||
<group>
|
||||
<field string="Instructions" name="note"/>
|
||||
<field string="Notes" name="additional_note"/>
|
||||
</group>
|
||||
</page>
|
||||
<notebook>
|
||||
<page string="Notes" name="notes">
|
||||
<group>
|
||||
<field name="report_result"/>
|
||||
<field name="report_pdf" widget="pdf_viewer"/>
|
||||
<field string="Instructions" name="note"/>
|
||||
<field string="Notes" name="additional_note"/>
|
||||
|
||||
</group>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
<div class="oe_chatter">
|
||||
@@ -311,18 +345,30 @@
|
||||
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
|
||||
<div class="row">
|
||||
<div class="col-6">
|
||||
<strong><span><t t-esc="record.name.value"/></span></strong>
|
||||
<strong>
|
||||
<span>
|
||||
<t t-esc="record.name.value"/>
|
||||
</span>
|
||||
</strong>
|
||||
</div>
|
||||
<div class="col-6">
|
||||
<strong><span t-attf-class="float-end text-end badge #{['none'].indexOf(record.quality_state.raw_value) > -1 ? 'text-bg-secondary' : ['fail'].indexOf(record.quality_state.raw_value) > -1 ? 'text-bg-danger' : ['done'].indexOf(record.quality_state.raw_value) > -1 ? 'text-bg-primary' : 'text-bg-success'}"><t t-esc="record.quality_state.value"/></span></strong>
|
||||
<strong>
|
||||
<span t-attf-class="float-end text-end badge #{['none'].indexOf(record.quality_state.raw_value) > -1 ? 'text-bg-secondary' : ['fail'].indexOf(record.quality_state.raw_value) > -1 ? 'text-bg-danger' : ['done'].indexOf(record.quality_state.raw_value) > -1 ? 'text-bg-primary' : 'text-bg-success'}">
|
||||
<t t-esc="record.quality_state.value"/>
|
||||
</span>
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row text-muted">
|
||||
<div class="col-8">
|
||||
<span><t t-esc="record.product_id.value"/></span>
|
||||
<span>
|
||||
<t t-esc="record.product_id.value"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-4">
|
||||
<span><t t-esc="record.lot_id.value"/></span>
|
||||
<span>
|
||||
<t t-esc="record.lot_id.value"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="oe_kanban_bottom_right float-end">
|
||||
@@ -350,7 +396,8 @@
|
||||
<field name="user_id" string="Checked By" optional="show" widget='many2one_avatar_user'/>
|
||||
<field name="point_id" optional="hide"/>
|
||||
<field name="team_id" optional="show"/>
|
||||
<field name="quality_state" optional="show" widget='badge' decoration-success="quality_state == 'pass'" decoration-info="quality_state == 'none'" decoration-danger="quality_state == 'fail'"/>
|
||||
<field name="quality_state" optional="show" widget='badge' decoration-success="quality_state == 'pass'"
|
||||
decoration-info="quality_state == 'none'" decoration-danger="quality_state == 'fail'"/>
|
||||
<field name="company_id" groups="base.main_company"/>
|
||||
</tree>
|
||||
</field>
|
||||
@@ -368,14 +415,14 @@
|
||||
</record>
|
||||
|
||||
<record id="quality_check_view_pivot" model="ir.ui.view">
|
||||
<field name="name">quality.check.view.pivot</field>
|
||||
<field name="model">quality.check</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Quality Check Analysis" sample="1">
|
||||
<field name="control_date" type="col" interval="day"/>
|
||||
<field name="product_id" type="row"/>
|
||||
</pivot>
|
||||
</field>
|
||||
<field name="name">quality.check.view.pivot</field>
|
||||
<field name="model">quality.check</field>
|
||||
<field name="arch" type="xml">
|
||||
<pivot string="Quality Check Analysis" sample="1">
|
||||
<field name="control_date" type="col" interval="day"/>
|
||||
<field name="product_id" type="row"/>
|
||||
</pivot>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="quality_check_view_search" model="ir.ui.view">
|
||||
@@ -383,7 +430,8 @@
|
||||
<field name="model">quality.check</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="product_id" string="Product" filter_domain="['|', ('product_id', 'ilike', self), ('lot_id', 'ilike', self)]"/>
|
||||
<field name="product_id" string="Product"
|
||||
filter_domain="['|', ('product_id', 'ilike', self), ('lot_id', 'ilike', self)]"/>
|
||||
<field name="picking_id"/>
|
||||
<field name="lot_id"/>
|
||||
<field name="team_id"/>
|
||||
@@ -426,10 +474,11 @@
|
||||
</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No quality check found
|
||||
</p><p>
|
||||
Define Quality Control Points in order to automatically generate
|
||||
quality checks at the right logistic operation: transfers, manufacturing orders.
|
||||
No quality check found
|
||||
</p>
|
||||
<p>
|
||||
Define Quality Control Points in order to automatically generate
|
||||
quality checks at the right logistic operation: transfers, manufacturing orders.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
@@ -458,10 +507,11 @@
|
||||
<field name="view_mode">tree,kanban,form,pivot,graph</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No quality check found
|
||||
</p><p>
|
||||
Define Quality Control Points in order to automatically generate
|
||||
quality checks at the right logistic operation: transfers, manufacturing orders.
|
||||
No quality check found
|
||||
</p>
|
||||
<p>
|
||||
Define Quality Control Points in order to automatically generate
|
||||
quality checks at the right logistic operation: transfers, manufacturing orders.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
@@ -485,17 +535,25 @@
|
||||
<field name="inherit_id" ref="stock.product_template_form_view_procurement_button"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_view_related_putaway_rules']" position="after">
|
||||
<button name="action_see_quality_control_points" type="object" class="oe_stat_button" icon="fa-list" attrs="{'invisible':[('type', 'not in', ['product', 'consu'])]}" groups="quality.group_quality_user">
|
||||
<button name="action_see_quality_control_points" type="object" class="oe_stat_button" icon="fa-list"
|
||||
attrs="{'invisible':[('type', 'not in', ['product', 'consu'])]}"
|
||||
groups="quality.group_quality_user">
|
||||
<field string="Quality Points" name="quality_control_point_qty" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_see_quality_checks" type="object" class="oe_stat_button" icon="fa-check" attrs="{'invisible':['|', ('type', 'not in', ['product', 'consu']), ('quality_pass_qty', '=', 0),('quality_fail_qty', '=', 0)]}" groups="quality.group_quality_user">
|
||||
<button name="action_see_quality_checks" type="object" class="oe_stat_button" icon="fa-check"
|
||||
attrs="{'invisible':['|', ('type', 'not in', ['product', 'consu']), ('quality_pass_qty', '=', 0),('quality_fail_qty', '=', 0)]}"
|
||||
groups="quality.group_quality_user">
|
||||
<div class="o_field_widget o_stat_info mr4">
|
||||
<span class="o_stat_text">Pass:</span>
|
||||
<span class="o_stat_text">Fail:</span>
|
||||
</div>
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value"><field name="quality_pass_qty"/></span>
|
||||
<span class="o_stat_value"><field name="quality_fail_qty"/></span>
|
||||
<span class="o_stat_value">
|
||||
<field name="quality_pass_qty"/>
|
||||
</span>
|
||||
<span class="o_stat_value">
|
||||
<field name="quality_fail_qty"/>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</xpath>
|
||||
@@ -509,17 +567,25 @@
|
||||
<field name="inherit_id" ref="stock.product_form_view_procurement_button"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//button[@name='action_view_related_putaway_rules']" position="after">
|
||||
<button name="action_see_quality_control_points" type="object" icon="fa-list" class="oe_stat_button" attrs="{'invisible':[('type', 'not in', ['product', 'consu'])]}" groups="quality.group_quality_user">
|
||||
<button name="action_see_quality_control_points" type="object" icon="fa-list" class="oe_stat_button"
|
||||
attrs="{'invisible':[('type', 'not in', ['product', 'consu'])]}"
|
||||
groups="quality.group_quality_user">
|
||||
<field string="Quality Points" name="quality_control_point_qty" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_see_quality_checks" type="object" class="oe_stat_button" icon="fa-check" groups="quality.group_quality_user" attrs="{'invisible':[ ('quality_pass_qty', '=', 0),('quality_fail_qty', '=', 0)]}" >
|
||||
<button name="action_see_quality_checks" type="object" class="oe_stat_button" icon="fa-check"
|
||||
groups="quality.group_quality_user"
|
||||
attrs="{'invisible':[ ('quality_pass_qty', '=', 0),('quality_fail_qty', '=', 0)]}">
|
||||
<div class="o_field_widget o_stat_info mr4">
|
||||
<span class="o_stat_text">Pass:</span>
|
||||
<span class="o_stat_text">Fail:</span>
|
||||
</div>
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value"><field name="quality_pass_qty"/></span>
|
||||
<span class="o_stat_value"><field name="quality_fail_qty"/></span>
|
||||
<span class="o_stat_value">
|
||||
<field name="quality_pass_qty"/>
|
||||
</span>
|
||||
<span class="o_stat_value">
|
||||
<field name="quality_fail_qty"/>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</xpath>
|
||||
@@ -533,8 +599,8 @@
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//div[@name='button_box']" position="inside">
|
||||
<button name="%(quality_check_action_production_lot)d" type="action"
|
||||
attrs="{'invisible': [('quality_check_qty', '=', 0)]}"
|
||||
icon="fa-check" class="oe_stat_button" groups="quality.group_quality_user">
|
||||
attrs="{'invisible': [('quality_check_qty', '=', 0)]}"
|
||||
icon="fa-check" class="oe_stat_button" groups="quality.group_quality_user">
|
||||
<field string="Quality Checks" name="quality_check_qty" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
@@ -557,24 +623,36 @@
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="#{kanban_color(record.color.raw_value)}">
|
||||
<span class="oe_kanban_color_help" t-attf-title="In #{kanban_getcolorname(record.color.raw_value)}" role="img" t-attf-aria-label="In #{kanban_getcolorname(record.color.raw_value)}"/>
|
||||
<span class="oe_kanban_color_help"
|
||||
t-attf-title="In #{kanban_getcolorname(record.color.raw_value)}" role="img"
|
||||
t-attf-aria-label="In #{kanban_getcolorname(record.color.raw_value)}"/>
|
||||
<div t-attf-class="o_kanban_card_header">
|
||||
<div class="o_kanban_card_header_title">
|
||||
<div class="o_primary"><field name="name"/></div>
|
||||
<div class="o_primary">
|
||||
<field name="name"/>
|
||||
</div>
|
||||
<div t-if="record.alias_name.value and record.alias_domain.value">
|
||||
<small><i class="fa fa-envelope-o" role="img" aria-label="Domain alias" title="Domain alias"></i>&nbsp; <field name="alias_id"/></small>
|
||||
<small><i class="fa fa-envelope-o" role="img" aria-label="Domain alias"
|
||||
title="Domain alias"></i>&nbsp;
|
||||
<field name="alias_id"/>
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container o_kanban_card_content">
|
||||
<div class="row">
|
||||
<div class="col-6 o_kanban_primary_left">
|
||||
<button class="btn btn-primary" name="%(quality_alert_action_team)d" type="action">
|
||||
<span><field name="alert_count"/> Quality Alerts</span>
|
||||
<button class="btn btn-primary" name="%(quality_alert_action_team)d"
|
||||
type="action">
|
||||
<span>
|
||||
<field name="alert_count"/>
|
||||
Quality Alerts
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="col-6 o_kanban_primary_right">
|
||||
<a class="oe_kanban_stock_picking_type_list" name="%(quality_check_action_team)d" type="action">
|
||||
<a class="oe_kanban_stock_picking_type_list"
|
||||
name="%(quality_check_action_team)d" type="action">
|
||||
<field name="check_count"/>
|
||||
Checks In Progress
|
||||
</a>
|
||||
@@ -585,11 +663,14 @@
|
||||
<div t-if="widget.editable" role="menuitem">
|
||||
<a class="dropdown-item ps-0" type="edit">Configuration</a>
|
||||
</div>
|
||||
<div t-if="widget.editable" role="menuitem" aria-haspopup="true" class="o_no_padding_kanban_colorpicker">
|
||||
<div t-if="widget.editable" role="menuitem" aria-haspopup="true"
|
||||
class="o_no_padding_kanban_colorpicker">
|
||||
<ul class="oe_kanban_colorpicker" data-field="color" role="popup"/>
|
||||
</div>
|
||||
</div>
|
||||
<a class="o_kanban_manage_toggle_button o_left" href="#"><i class="fa fa-ellipsis-v" role="img" aria-label="Manage" title="Manage"/></a>
|
||||
<a class="o_kanban_manage_toggle_button o_left" href="#">
|
||||
<i class="fa fa-ellipsis-v" role="img" aria-label="Manage" title="Manage"/>
|
||||
</a>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -615,13 +696,14 @@
|
||||
<label for="alias_name" string="Email Alias"/>
|
||||
<div name="alias_def">
|
||||
<field name="alias_id" class="oe_read_only oe_inline"
|
||||
string="Email Alias" required="0"/>
|
||||
<div class="oe_edit_only oe_inline" name="edit_alias" style="display: inline;" >
|
||||
<field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/>
|
||||
string="Email Alias" required="0"/>
|
||||
<div class="oe_edit_only oe_inline" name="edit_alias" style="display: inline;">
|
||||
<field name="alias_name" class="oe_inline"/>@
|
||||
<field name="alias_domain" class="oe_inline" readonly="1"/>
|
||||
</div>
|
||||
</div>
|
||||
<field name="alias_contact" class="oe_inline" groups="base.group_no_one"
|
||||
string="Accept Emails From"/>
|
||||
string="Accept Emails From"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
@@ -658,7 +740,9 @@
|
||||
<div t-attf-class="oe_kanban_content oe_kanban_global_click">
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<strong><field name="name"/></strong>
|
||||
<strong>
|
||||
<field name="name"/>
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -672,14 +756,15 @@
|
||||
<field name="name">Quality Overview</field>
|
||||
<field name="res_model">quality.alert.team</field>
|
||||
<field name="view_mode">kanban,form</field>
|
||||
<field name="view_id" ref="quality_alert_team_dashboard_view_kanban" />
|
||||
<field name="view_id" ref="quality_alert_team_dashboard_view_kanban"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_empty_folder">
|
||||
</p><p>
|
||||
Quality Teams group the different quality alerts/checks
|
||||
according to the roles (teams) that need them.
|
||||
</p>
|
||||
</field>
|
||||
<p>
|
||||
Quality Teams group the different quality alerts/checks
|
||||
according to the roles (teams) that need them.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="quality_alert_team_action_config" model="ir.actions.act_window">
|
||||
@@ -716,9 +801,9 @@
|
||||
<field name="res_model">quality.tag</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Add a new tag
|
||||
</p>
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Add a new tag
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -747,7 +832,9 @@
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_global_click">
|
||||
<div>
|
||||
<strong><field name="name"/></strong>
|
||||
<strong>
|
||||
<field name="name"/>
|
||||
</strong>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
@@ -763,8 +850,9 @@
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
Create a new quality alert stage
|
||||
</p><p>
|
||||
Quality Alert stages define the different steps a quality alert should go through.
|
||||
</p>
|
||||
<p>
|
||||
Quality Alert stages define the different steps a quality alert should go through.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
@@ -816,9 +904,19 @@
|
||||
<templates>
|
||||
<t t-name="kanban-box">
|
||||
<div t-attf-class="oe_kanban_card oe_kanban_global_click">
|
||||
<div><strong><t t-esc="record.name.value"/></strong></div>
|
||||
<div><strong>Products :</strong> <t t-esc="record.product_ids.value"/></div>
|
||||
<div><strong>Operations :</strong> <t t-esc="record.picking_type_ids.value"/></div>
|
||||
<div>
|
||||
<strong>
|
||||
<t t-esc="record.name.value"/>
|
||||
</strong>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Products :</strong>
|
||||
<t t-esc="record.product_ids.value"/>
|
||||
</div>
|
||||
<div>
|
||||
<strong>Operations :</strong>
|
||||
<t t-esc="record.picking_type_ids.value"/>
|
||||
</div>
|
||||
</div>
|
||||
</t>
|
||||
</templates>
|
||||
@@ -836,39 +934,54 @@
|
||||
<field string="Quality Checks" name="check_count" widget="statinfo"/>
|
||||
</button>
|
||||
<button name="action_see_spc_control" type="object" class="oe_stat_button"
|
||||
attrs="{'invisible': ['|', ('check_count', '=', 0), ('test_type', '!=', 'measure')]}">
|
||||
<span class="fa fa-2x" data-icon="∑" style="padding-left: 10px;" role="img" aria-label="Statistics" title="Statistics"/>
|
||||
attrs="{'invisible': ['|', ('check_count', '=', 0), ('test_type', '!=', 'measure')]}">
|
||||
<span class="fa fa-2x" data-icon="∑" style="padding-left: 10px;" role="img"
|
||||
aria-label="Statistics" title="Statistics"/>
|
||||
<div class="o_field_widget o_stat_info mr4">
|
||||
<span class="o_stat_text">AVG:</span>
|
||||
<span class="o_stat_text">STD:</span>
|
||||
</div>
|
||||
<div class="o_field_widget o_stat_info">
|
||||
<span class="o_stat_value"><field name="average"/></span>
|
||||
<span class="o_stat_value"><field name="standard_deviation"/></span>
|
||||
<span class="o_stat_value">
|
||||
<field name="average"/>
|
||||
</span>
|
||||
<span class="o_stat_value">
|
||||
<field name="standard_deviation"/>
|
||||
</span>
|
||||
</div>
|
||||
</button>
|
||||
</xpath>
|
||||
<xpath expr="//page[@name='instructions']" position="after">
|
||||
<page string="Message If Failure" name="message_if_failure"
|
||||
attrs="{'invisible': [('test_type', 'in', ['picture', 'instructions', 'register_consumed_materials', 'print_label'])]}">
|
||||
attrs="{'invisible': [('test_type', 'in', ['picture', 'instructions', 'register_consumed_materials', 'print_label'])]}">
|
||||
<field name="failure_message"/>
|
||||
</page>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='test_type']" position="before">
|
||||
<field name="measure_on"/>
|
||||
<field name="measure_frequency_type" string="Control Frequency"/>
|
||||
<label for="measure_frequency_value" string="" attrs="{'invisible': [('measure_frequency_type', '=', 'all')]}"/>
|
||||
<label for="measure_frequency_value" string=""
|
||||
attrs="{'invisible': [('measure_frequency_type', '=', 'all')]}"/>
|
||||
<div class="o_row" attrs="{'invisible': [('measure_frequency_type', '=', 'all')]}">
|
||||
<span attrs="{'invisible': [('measure_frequency_type', '=', 'all')]}">Every </span>
|
||||
<field name="measure_frequency_value" nolabel="1" attrs="{'invisible': [('measure_frequency_type', '!=', 'random')]}"/>
|
||||
<label for="measure_frequency_value" string="% of Operations" attrs="{'invisible': ['|', ('measure_on', '=', 'move_line'), ('measure_frequency_type', '!=', 'random')]}"/>
|
||||
<label for="measure_frequency_value" string="% of Transfers" attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('measure_frequency_type', '!=', 'random')]}"/>
|
||||
<field name="measure_frequency_unit_value" string="Frequency" nolabel="1" attrs="{'invisible': [('measure_frequency_type', '!=', 'periodical')]}"/>
|
||||
<field name="measure_frequency_unit" attrs="{'invisible': [('measure_frequency_type', '!=', 'periodical')], 'required': [('measure_frequency_type', '=', 'periodical')]}"/>
|
||||
<span attrs="{'invisible': [('measure_frequency_type', '=', 'all')]}">Every</span>
|
||||
<field name="measure_frequency_value" nolabel="1"
|
||||
attrs="{'invisible': [('measure_frequency_type', '!=', 'random')]}"/>
|
||||
<label for="measure_frequency_value" string="% of Operations"
|
||||
attrs="{'invisible': ['|', ('measure_on', '=', 'move_line'), ('measure_frequency_type', '!=', 'random')]}"/>
|
||||
<label for="measure_frequency_value" string="% of Transfers"
|
||||
attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('measure_frequency_type', '!=', 'random')]}"/>
|
||||
<field name="measure_frequency_unit_value" string="Frequency" nolabel="1"
|
||||
attrs="{'invisible': [('measure_frequency_type', '!=', 'periodical')]}"/>
|
||||
<field name="measure_frequency_unit"
|
||||
attrs="{'invisible': [('measure_frequency_type', '!=', 'periodical')], 'required': [('measure_frequency_type', '=', 'periodical')]}"/>
|
||||
</div>
|
||||
<field name="is_lot_tested_fractionally" attrs="{'invisible': [('measure_on', '!=', 'move_line')]}" string="Partial Transfer Test"/>
|
||||
<label for="testing_percentage_within_lot" attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '!=', True)]}" string="Percentage"/>
|
||||
<div class="o_row" attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '!=', True)]}">
|
||||
<field name="is_lot_tested_fractionally" attrs="{'invisible': [('measure_on', '!=', 'move_line')]}"
|
||||
string="Partial Transfer Test"/>
|
||||
<label for="testing_percentage_within_lot"
|
||||
attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '!=', True)]}"
|
||||
string="Percentage"/>
|
||||
<div class="o_row"
|
||||
attrs="{'invisible': ['|', ('measure_on', '!=', 'move_line'), ('is_lot_tested_fractionally', '!=', True)]}">
|
||||
<field name="testing_percentage_within_lot" nolabel="1"/>
|
||||
<label for="testing_percentage_within_lot" string="%"/>
|
||||
</div>
|
||||
@@ -877,12 +990,15 @@
|
||||
<label for="norm" attrs="{'invisible': [('test_type', '!=', 'measure')]}"/>
|
||||
<div class="o_row" attrs="{'invisible': [('test_type', '!=', 'measure')]}">
|
||||
<field name="norm" attrs="{'required': [('test_type', '=', 'measure')]}"/>
|
||||
<field name="norm_unit" string="Unit of Measure" attrs="{'required': [('test_type', '=', 'measure')]}"/>
|
||||
<field name="norm_unit" string="Unit of Measure"
|
||||
attrs="{'required': [('test_type', '=', 'measure')]}"/>
|
||||
</div>
|
||||
<label for="tolerance_min" string="Tolerance" attrs="{'invisible': [('test_type', '!=', 'measure')]}"/>
|
||||
<div attrs="{'invisible': [('test_type', '!=', 'measure')]}" class="o_row">
|
||||
<span>from </span> <field name="tolerance_min"/>
|
||||
<span>to </span> <field name="tolerance_max"/>
|
||||
<span>from</span>
|
||||
<field name="tolerance_min"/>
|
||||
<span>to</span>
|
||||
<field name="tolerance_max"/>
|
||||
</div>
|
||||
</xpath>
|
||||
</field>
|
||||
@@ -895,95 +1011,96 @@
|
||||
<field name="search_view_id" ref="quality_point_view_search"/>
|
||||
<field name="help" type="html">
|
||||
<p class="o_view_nocontent_smiling_face">
|
||||
No quality control point found
|
||||
</p><p>
|
||||
Quality control points define the quality checks which should be
|
||||
performed at each operation, for your different products.
|
||||
No quality control point found
|
||||
</p>
|
||||
<p>
|
||||
Quality control points define the quality checks which should be
|
||||
performed at each operation, for your different products.
|
||||
</p>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- Menu structure-->
|
||||
<menuitem
|
||||
id="menu_quality_root"
|
||||
name="Quality"
|
||||
web_icon="quality_control,static/description/icon.svg"
|
||||
sequence="150"
|
||||
groups="quality.group_quality_user"/>
|
||||
id="menu_quality_root"
|
||||
name="Quality"
|
||||
web_icon="quality_control,static/description/icon.svg"
|
||||
sequence="150"
|
||||
groups="quality.group_quality_user"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_quality_dashboard"
|
||||
name="Overview"
|
||||
action="quality_alert_team_action"
|
||||
parent="menu_quality_root"
|
||||
sequence="5"/>
|
||||
id="menu_quality_dashboard"
|
||||
name="Overview"
|
||||
action="quality_alert_team_action"
|
||||
parent="menu_quality_root"
|
||||
sequence="5"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_quality_control"
|
||||
name="Quality Control"
|
||||
parent="menu_quality_root"
|
||||
sequence="15"/>
|
||||
id="menu_quality_control"
|
||||
name="Quality Control"
|
||||
parent="menu_quality_root"
|
||||
sequence="15"/>
|
||||
<menuitem
|
||||
id="menu_quality_control_points"
|
||||
name="Control Points"
|
||||
parent="menu_quality_control"
|
||||
action="quality_point_action"
|
||||
groups="quality.group_quality_manager"
|
||||
sequence="17"/>
|
||||
id="menu_quality_control_points"
|
||||
name="Control Points"
|
||||
parent="menu_quality_control"
|
||||
action="quality_point_action"
|
||||
groups="quality.group_quality_manager"
|
||||
sequence="17"/>
|
||||
<menuitem
|
||||
id="menu_quality_checks"
|
||||
name="Quality Checks"
|
||||
action="quality_check_action_main"
|
||||
parent="menu_quality_control"
|
||||
sequence="18"/>
|
||||
id="menu_quality_checks"
|
||||
name="Quality Checks"
|
||||
action="quality_check_action_main"
|
||||
parent="menu_quality_control"
|
||||
sequence="18"/>
|
||||
<menuitem
|
||||
id="menu_quality_alert"
|
||||
name="Quality Alerts"
|
||||
action="quality_alert_action_check"
|
||||
parent="menu_quality_control"
|
||||
sequence="20"/>
|
||||
id="menu_quality_alert"
|
||||
name="Quality Alerts"
|
||||
action="quality_alert_action_check"
|
||||
parent="menu_quality_control"
|
||||
sequence="20"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_quality_configuration"
|
||||
name="Configuration"
|
||||
groups="quality.group_quality_manager"
|
||||
parent="menu_quality_root"
|
||||
sequence="25"/>
|
||||
id="menu_quality_configuration"
|
||||
name="Configuration"
|
||||
groups="quality.group_quality_manager"
|
||||
parent="menu_quality_root"
|
||||
sequence="25"/>
|
||||
<menuitem
|
||||
id="menu_quality_config_alert_team"
|
||||
name="Quality Teams"
|
||||
action="quality_alert_team_action_config"
|
||||
parent="menu_quality_configuration"
|
||||
sequence="5"/>
|
||||
id="menu_quality_config_alert_team"
|
||||
name="Quality Teams"
|
||||
action="quality_alert_team_action_config"
|
||||
parent="menu_quality_configuration"
|
||||
sequence="5"/>
|
||||
<menuitem
|
||||
id="menu_quality_config_alert_stage"
|
||||
name="Quality Alert Stages"
|
||||
action="quality_alert_stage_action"
|
||||
parent="menu_quality_configuration"
|
||||
groups="base.group_no_one"
|
||||
sequence="15"/>
|
||||
id="menu_quality_config_alert_stage"
|
||||
name="Quality Alert Stages"
|
||||
action="quality_alert_stage_action"
|
||||
parent="menu_quality_configuration"
|
||||
groups="base.group_no_one"
|
||||
sequence="15"/>
|
||||
<menuitem
|
||||
id="menu_config_quality_tags"
|
||||
name="Quality Tags"
|
||||
groups="base.group_no_one"
|
||||
action="quality_tag_action"
|
||||
parent="menu_quality_configuration"
|
||||
sequence="25"/>
|
||||
id="menu_config_quality_tags"
|
||||
name="Quality Tags"
|
||||
groups="base.group_no_one"
|
||||
action="quality_tag_action"
|
||||
parent="menu_quality_configuration"
|
||||
sequence="25"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_quality_reporting"
|
||||
name="Reporting"
|
||||
groups="quality.group_quality_manager"
|
||||
parent="menu_quality_root"
|
||||
sequence="20"/>
|
||||
id="menu_quality_reporting"
|
||||
name="Reporting"
|
||||
groups="quality.group_quality_manager"
|
||||
parent="menu_quality_root"
|
||||
sequence="20"/>
|
||||
<menuitem
|
||||
id="menu_quality_alert_report"
|
||||
action="quality_alert_action_report"
|
||||
parent="menu_quality_reporting"
|
||||
sequence="6"/>
|
||||
id="menu_quality_alert_report"
|
||||
action="quality_alert_action_report"
|
||||
parent="menu_quality_reporting"
|
||||
sequence="6"/>
|
||||
<menuitem
|
||||
id="menu_quality_check_report"
|
||||
action="quality_check_action_report"
|
||||
parent="menu_quality_reporting"
|
||||
sequence="5"/>
|
||||
id="menu_quality_check_report"
|
||||
action="quality_check_action_report"
|
||||
parent="menu_quality_reporting"
|
||||
sequence="5"/>
|
||||
</odoo>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
'views/tool_menu.xml',
|
||||
'views/menu_fixture_view.xml',
|
||||
'views/change_base_view.xml',
|
||||
'views/Printer.xml',
|
||||
|
||||
],
|
||||
'demo': [
|
||||
|
||||
27
sf_base/commons/Email.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class MailSender(models.Model):
|
||||
_name = 'mail.sender'
|
||||
_description = 'Mail Sender'
|
||||
|
||||
def mail_sender(self, mail_server_name, subject_name, email_to, error_message):
|
||||
mail_server = self.env['ir.mail_server'].sudo().search([('name', '=', mail_server_name)], limit=1)
|
||||
if not mail_server:
|
||||
_logger.info('管理员还未配置名称为 %s 的smtp服务器信息,请联系管理员配置!' % mail_server_name)
|
||||
return
|
||||
if not mail_server.smtp_user or not mail_server.smtp_pass:
|
||||
_logger.info("邮件发送账号未正确设置,请联系管理员!")
|
||||
return
|
||||
mail_values = {
|
||||
'message_type': 'email', 'subject': subject_name,
|
||||
'mail_server_id': mail_server.id, 'email_from': mail_server.smtp_user,
|
||||
'email_to': email_to
|
||||
}
|
||||
temp_mail_html = """
|
||||
Hi, <p> 这里是异常提醒通知: </p>
|
||||
"""
|
||||
|
||||
temp_mail_html += """ %s """ % error_message
|
||||
mail_values['body_html'] = temp_mail_html
|
||||
self.env['mail.mail'].sudo().create(mail_values).send(auto_commit=True)
|
||||
28
sf_base/commons/Printer.py
Normal file
@@ -0,0 +1,28 @@
|
||||
from odoo import models, fields
|
||||
|
||||
|
||||
class Printer(models.Model):
|
||||
_name = 'printer'
|
||||
_description = 'Printer'
|
||||
|
||||
name = fields.Char(string='名称', required=True)
|
||||
ip_address = fields.Char(string='IP 地址', required=True)
|
||||
port = fields.Integer(string='端口', default=9100)
|
||||
|
||||
|
||||
class TableStyle(models.Model):
|
||||
_name = 'table.style'
|
||||
_description = '标签样式'
|
||||
|
||||
name = fields.Char(string='名称', required=True)
|
||||
# todo
|
||||
|
||||
|
||||
class PrinterConfiguration(models.Model):
|
||||
_name = 'printer.configuration'
|
||||
_description = 'Printer Configuration'
|
||||
|
||||
name = fields.Char(string='名称', required=True)
|
||||
printer_id = fields.Many2one('printer', string='打印机')
|
||||
model = fields.Many2one('ir.model', string='模型名称')
|
||||
# # 其他相关字段...
|
||||
@@ -1 +1,3 @@
|
||||
from . import common
|
||||
from . import Printer
|
||||
from . import Email
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import time
|
||||
import time, datetime
|
||||
import hashlib
|
||||
from odoo import models
|
||||
|
||||
import socket
|
||||
|
||||
class Common(models.Model):
|
||||
_name = 'sf.sync.common'
|
||||
@@ -29,3 +29,66 @@ class Common(models.Model):
|
||||
d = dt + datetime.timedelta(hours=8)
|
||||
nTime = d.strftime("%Y-%m-%d %H:%M:%S")
|
||||
return nTime
|
||||
|
||||
|
||||
class PrintingUtils(models.AbstractModel):
|
||||
_name = 'printing.utils'
|
||||
_description = 'Utility class for printing functionalities'
|
||||
|
||||
def generate_zpl_code(self, code):
|
||||
# 实现生成ZPL代码的逻辑
|
||||
# 初始化ZPL代码字符串
|
||||
zpl_code = "^XA\n"
|
||||
zpl_code += "^CW1,E:SIMSUN.TTF^FS\n"
|
||||
zpl_code += "^CI28\n"
|
||||
|
||||
# 设置二维码位置
|
||||
zpl_code += "^FO50,50\n" # 调整二维码位置,使其与资产编号在同一行
|
||||
zpl_code += f"^BQN,2,6^FDLM,B0093{code}^FS\n"
|
||||
|
||||
# 设置资产编号文本位置
|
||||
zpl_code += "^FO300,60\n" # 资产编号文本的位置,与二维码在同一行
|
||||
zpl_code += "^A1N,45,45^FD编码名称: ^FS\n"
|
||||
|
||||
# 设置{code}文本位置
|
||||
# 假设{code}文本需要位于资产编号和二维码下方,中间位置
|
||||
# 设置{code}文本位置并启用自动换行
|
||||
zpl_code += "^FO300,120\n" # {code}文本的起始位置
|
||||
zpl_code += "^FB400,4,0,L,0\n" # 定义一个宽度为500点的文本框,最多4行,左对齐
|
||||
zpl_code += f"^A1N,40,40^FD{code}^FS\n"
|
||||
|
||||
# 在{code}文本框周围绘制线框
|
||||
# 假设线框的外部尺寸为宽度500点,高度200点
|
||||
# zpl_code += "^FO300,110^GB500,200,2^FS\n" # 绘制线框,边框粗细为2点
|
||||
|
||||
zpl_code += "^PQ1,0,1,Y\n"
|
||||
zpl_code += "^XZ\n"
|
||||
return zpl_code
|
||||
|
||||
def send_to_printer(self, host, port, zpl_code):
|
||||
|
||||
# 实现发送ZPL代码到打印机的逻辑
|
||||
# 将ZPL代码转换为字节串
|
||||
print('zpl_code', zpl_code)
|
||||
zpl_bytes = zpl_code.encode('utf-8')
|
||||
print(zpl_bytes)
|
||||
|
||||
# 创建socket对象
|
||||
mysocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||
try:
|
||||
mysocket.connect((host, port)) # 连接到打印机
|
||||
mysocket.send(zpl_bytes) # 发送ZPL代码
|
||||
print("ZPL code sent to printer successfully.")
|
||||
except Exception as e:
|
||||
print(f"Error with the connection: {e}")
|
||||
finally:
|
||||
mysocket.close() # 关闭连接
|
||||
|
||||
def print_qr_code(self, lot_name, host, port):
|
||||
# 实现打印二维码的逻辑
|
||||
# 这里需要传入 lot_name 参数,因为我们不能直接访问 self.lot_id.name
|
||||
zpl_code = self.generate_zpl_code(lot_name)
|
||||
# 发送ZPL代码到打印机
|
||||
# host = "192.168.50.110" # 可以作为参数传入,或者在此配置
|
||||
# port = 9100 # 可以作为参数传入,或者在此配置
|
||||
self.send_to_printer(host, port, zpl_code)
|
||||
|
||||
@@ -8,7 +8,7 @@ from odoo.http import request
|
||||
|
||||
class Manufacturing_Connect(http.Controller):
|
||||
|
||||
@http.route('/AutoDeviceApi/MaintenanceToolGroups', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/MachineToolGroup', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def get_maintenance_tool_groups_Info(self, **kw):
|
||||
"""
|
||||
@@ -20,7 +20,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
try:
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
ret = json.loads(ret['result'])
|
||||
# ret = json.loads(ret['result'])
|
||||
logging.info('DeviceId:%s' % ret)
|
||||
tool_groups = request.env['sf.tool.groups'].sudo().search([])
|
||||
|
||||
|
||||
@@ -106,6 +106,7 @@ class MachineTool(models.Model):
|
||||
lead_screw = fields.Char('丝杆')
|
||||
workbench_L = fields.Char('工作台长度(mm)')
|
||||
workbench_W = fields.Char('工作台宽度(mm)')
|
||||
workbench_H = fields.Char('工作台高度(mm)')
|
||||
guide_rail = fields.Char('导轨')
|
||||
machine_tool_L = fields.Char('机床长度(mm)')
|
||||
machine_tool_W = fields.Char('机床宽度(mm)')
|
||||
@@ -193,6 +194,7 @@ class MachineTool(models.Model):
|
||||
item.lead_screw = item.type_id.lead_screw
|
||||
item.workbench_L = item.type_id.workbench_L
|
||||
item.workbench_W = item.type_id.workbench_W
|
||||
item.workbench_H = item.type_id.workbench_H
|
||||
item.guide_rail = item.type_id.guide_rail
|
||||
item.machine_tool_L = item.type_id.machine_tool_L
|
||||
item.machine_tool_W = item.type_id.machine_tool_W
|
||||
@@ -280,6 +282,7 @@ class MachineToolType(models.Model):
|
||||
workpiece_load = fields.Char('工件最大负载(kg)')
|
||||
workbench_L = fields.Char('工作台长度(mm)')
|
||||
workbench_W = fields.Char('工作台宽度(mm)')
|
||||
workbench_H = fields.Char('工作台高度(mm)')
|
||||
machine_tool_L = fields.Char('机床长度(mm)')
|
||||
machine_tool_W = fields.Char('机床宽度(mm)')
|
||||
machine_tool_H = fields.Char('机床高度(mm)')
|
||||
@@ -295,8 +298,9 @@ class MachineToolType(models.Model):
|
||||
x_axis = fields.Integer('X轴')
|
||||
y_axis = fields.Integer('Y轴')
|
||||
z_axis = fields.Integer('Z轴')
|
||||
b_axis = fields.Integer('B轴')
|
||||
c_axis = fields.Integer('C轴')
|
||||
a_axis = fields.Char('a轴')
|
||||
b_axis = fields.Char('B轴')
|
||||
c_axis = fields.Char('C轴')
|
||||
remark = fields.Char('备注')
|
||||
control_system_id = fields.Many2one('sf.machine.control_system',
|
||||
string="控制系统")
|
||||
@@ -309,7 +313,7 @@ class MachineToolType(models.Model):
|
||||
default="", string="轴数")
|
||||
|
||||
# 1212新增字段
|
||||
a_axis = fields.Integer('a轴')
|
||||
|
||||
function_type = fields.Selection(
|
||||
[("ZXJGZX", "钻铣加工中心"), ("CXJGZX", "车削加工中心"), ("FHJGZX", "复合加工中心")],
|
||||
default="", string="功能类型")
|
||||
@@ -335,23 +339,23 @@ class MachineToolType(models.Model):
|
||||
straight_cutting_feed_rate = fields.Char('直线切削进给速度(mm/min)')
|
||||
rotary_cutting_feed_rate = fields.Char('回转切削进给速度(mm/min)')
|
||||
|
||||
X_precision = fields.Float('X轴定位精度(mm)', digits=(12, 3))
|
||||
X_precision_repeat = fields.Float('X轴重复定位精度(mm)', digits=(12, 3))
|
||||
Y_precision = fields.Float('Y轴定位精度(mm)', digits=(12, 3))
|
||||
Y_precision_repeat = fields.Float('Y轴重复定位精度(mm)', digits=(12, 3))
|
||||
Z_precision = fields.Float('Z轴定位精度(mm)', digits=(12, 3))
|
||||
Z_precision_repeat = fields.Float('Z轴重复定位精度(mm)', digits=(12, 3))
|
||||
a_precision = fields.Float('a轴定位精度(mm)', digits=(12, 3))
|
||||
a_precision_repeat = fields.Float('a轴重复定位精度(mm)', digits=(12, 3))
|
||||
b_precision = fields.Float('b轴定位精度(mm)', digits=(12, 3))
|
||||
b_precision_repeat = fields.Float('b轴重复定位精度(mm)', digits=(12, 3))
|
||||
c_precision = fields.Float('c轴定位精度(mm)', digits=(12, 3))
|
||||
c_precision_repeat = fields.Float('c轴重复定位精度(mm)', digits=(12, 3))
|
||||
X_precision = fields.Char('X轴定位精度(mm)')
|
||||
X_precision_repeat = fields.Char('X轴重复定位精度(mm)')
|
||||
Y_precision = fields.Char('Y轴定位精度(mm)')
|
||||
Y_precision_repeat = fields.Char('Y轴重复定位精度(mm)')
|
||||
Z_precision = fields.Char('Z轴定位精度(mm)')
|
||||
Z_precision_repeat = fields.Char('Z轴重复定位精度(mm)')
|
||||
a_precision = fields.Char('a轴定位精度(mm)')
|
||||
a_precision_repeat = fields.Char('a轴重复定位精度(mm)')
|
||||
b_precision = fields.Char('b轴定位精度(mm)')
|
||||
b_precision_repeat = fields.Char('b轴重复定位精度(mm)')
|
||||
c_precision = fields.Char('c轴定位精度(mm)')
|
||||
c_precision_repeat = fields.Char('c轴重复定位精度(mm)')
|
||||
|
||||
tool_full_diameter_max = fields.Float('刀具满刀最大直径(mm)')
|
||||
tool_perimeter_diameter_max = fields.Float('刀具邻空刀最大直径(mm)')
|
||||
T_tool_time = fields.Integer('T-T换刀时间(s)')
|
||||
C_tool_time = fields.Integer('C-C换刀时间(s)')
|
||||
T_tool_time = fields.Float('T-T换刀时间(s)', digits=(12, 1))
|
||||
C_tool_time = fields.Float('C-C换刀时间(s)', digits=(12, 1))
|
||||
|
||||
jg_image_id = fields.Many2many('maintenance.equipment.image', 'jg_equipment_id', string='加工能力',
|
||||
domain="[('type', '=', '加工能力')]")
|
||||
|
||||
@@ -67,186 +67,220 @@ class BasicParametersFixture(models.Model):
|
||||
mounting_hole_depth = fields.Float('安装孔深度(mm)', digits=(16, 2))
|
||||
centering_diameter = fields.Float('定心直径(mm)', digits=(16, 2))
|
||||
|
||||
code = fields.Char('编码')
|
||||
active = fields.Boolean('有效', default=True)
|
||||
|
||||
def _get_basic_parameters_list(self, fixture_materials_data, fixture_materials_name):
|
||||
if fixture_materials_name == '零点卡盘':
|
||||
return self._json_zero_chuck_param(fixture_materials_data)
|
||||
elif fixture_materials_name == '零点托盘':
|
||||
return self._json_zero_tray_param(fixture_materials_data)
|
||||
elif fixture_materials_name == '气动夹具':
|
||||
return self._json_pneumatic_fixture_param(fixture_materials_data)
|
||||
elif fixture_materials_name == '虎钳夹具':
|
||||
return self._json_jaw_vice_fixture_param(fixture_materials_data)
|
||||
elif fixture_materials_name == '磁吸夹具':
|
||||
return self._json_magnet_fixture_param(fixture_materials_data)
|
||||
elif fixture_materials_name == '转接板(锁板)夹具':
|
||||
return self._json_adapter_board_fixture_param(fixture_materials_data)
|
||||
elif fixture_materials_name == '三爪卡盘':
|
||||
return self._json_scroll_chuck_param(fixture_materials_data)
|
||||
return {}
|
||||
|
||||
def _json_zero_chuck_param(self, obj):
|
||||
zero_chuck_param_str = (0, '', {
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'diameter': obj['diameter'],
|
||||
'weight': obj['weight'],
|
||||
'orientation_dish_diameter': obj['orientation_dish_diameter'],
|
||||
'clamping_diameter': obj['clamping_diameter'],
|
||||
'clamping_num': obj['clamping_num'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'repeated_positioning_accuracy': obj['repeated_positioning_accuracy'],
|
||||
'boolean_transposing_hole': obj['boolean_transposing_hole'],
|
||||
'unlocking_method': obj['unlocking_method'],
|
||||
'boolean_chip_blowing_function': obj['boolean_chip_blowing_function'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'rigidity': obj['rigidity'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'machine_tool_type_id': self.env['sf.machine_tool.type'].sudo().search(
|
||||
[('code', '=', obj['machine_tool_type_id']), ('active', '=', True)]).id,
|
||||
})
|
||||
return zero_chuck_param_str
|
||||
"""零点卡盘:将data数据转换成list数据"""
|
||||
return {'code': obj['code'],
|
||||
'fixture_model_id': self.env['sf.fixture.model'].sudo().search(
|
||||
[('code', '=', obj.get('fixture_model_code'))]).id,
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'diameter': obj['diameter'],
|
||||
'weight': obj['weight'],
|
||||
'orientation_dish_diameter': obj['orientation_dish_diameter'],
|
||||
'clamping_diameter': obj['clamping_diameter'],
|
||||
'clamping_num': obj['clamping_num'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'repeated_positioning_accuracy': obj['repeated_positioning_accuracy'],
|
||||
'boolean_transposing_hole': obj['boolean_transposing_hole'],
|
||||
'unlocking_method': obj['unlocking_method'],
|
||||
'boolean_chip_blowing_function': obj['boolean_chip_blowing_function'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'rigidity': obj['rigidity'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'machine_tool_type_id': self.env['sf.machine_tool.type'].sudo().search(
|
||||
[('code', '=', obj['machine_tool_type_id']), ('active', '=', True)]).id,
|
||||
'active': obj['active']}
|
||||
|
||||
def _json_zero_tray_param(self, obj):
|
||||
zero_tray_param_str = (0, '', {
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'diameter': obj['diameter'],
|
||||
'weight': obj['weight'],
|
||||
'clamping_diameter': obj['clamping_diameter'],
|
||||
'connector_diameter': obj['connector_diameter'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'repeated_positioning_accuracy': obj['repeated_positioning_accuracy'],
|
||||
'boolean_chip_blowing_function': obj['boolean_chip_blowing_function'],
|
||||
'way_to_install': obj['way_to_install'],
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
})
|
||||
return zero_tray_param_str
|
||||
"""零点托盘:将data数据转换成list数据"""
|
||||
return {'code': obj['code'],
|
||||
'fixture_model_id': self.env['sf.fixture.model'].sudo().search(
|
||||
[('code', '=', obj.get('fixture_model_code'))]).id,
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'diameter': obj['diameter'],
|
||||
'weight': obj['weight'],
|
||||
'clamping_diameter': obj['clamping_diameter'],
|
||||
'connector_diameter': obj['connector_diameter'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'repeated_positioning_accuracy': obj['repeated_positioning_accuracy'],
|
||||
'boolean_chip_blowing_function': obj['boolean_chip_blowing_function'],
|
||||
'way_to_install': obj['way_to_install'],
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'active': obj['active']}
|
||||
|
||||
def _json_pneumatic_fixture_param(self, obj):
|
||||
pneumatic_fixture_param_str = (0, '', {
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'rated_air_pressure': obj['rated_air_pressure'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'interface_materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
})
|
||||
return pneumatic_fixture_param_str
|
||||
"""气动夹具:将data数据转换成list数据"""
|
||||
return {'code': obj['code'],
|
||||
'fixture_model_id': self.env['sf.fixture.model'].sudo().search(
|
||||
[('code', '=', obj.get('fixture_model_code'))]).id,
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'rated_air_pressure': obj['rated_air_pressure'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'interface_materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
'active': obj['active']}
|
||||
|
||||
def _json_jaw_vice_fixture_param(self, obj):
|
||||
jaw_vice_fixture_param_str = (0, '', {
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'transverse_groove': obj['transverse_groove'],
|
||||
'longitudinal_fitting_groove': obj['longitudinal_fitting_groove'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'interface_materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
})
|
||||
return jaw_vice_fixture_param_str
|
||||
"""虎钳夹具:将data数据转换成list数据"""
|
||||
return {'code': obj['code'],
|
||||
'fixture_model_id': self.env['sf.fixture.model'].sudo().search(
|
||||
[('code', '=', obj.get('fixture_model_code'))]).id,
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'transverse_groove': obj['transverse_groove'],
|
||||
'longitudinal_fitting_groove': obj['longitudinal_fitting_groove'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'interface_materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
'active': obj['active']}
|
||||
|
||||
def _json_magnet_fixture_param(self, obj):
|
||||
magnet_fixture_param_str = (0, '', {
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'height_tolerance_value': obj['height_tolerance_value'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'rated_adsorption_force': obj['rated_adsorption_force'],
|
||||
'magnetic_field_height': obj['magnetic_field_height'],
|
||||
'magnetic_pole_plate_grinding_allowance': obj['magnetic_pole_plate_grinding_allowance'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'interface_materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
})
|
||||
return magnet_fixture_param_str
|
||||
"""磁吸夹具:将data数据转换成list数据"""
|
||||
return {'code': obj['code'],
|
||||
'fixture_model_id': self.env['sf.fixture.model'].sudo().search(
|
||||
[('code', '=', obj.get('fixture_model_code'))]).id,
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'height_tolerance_value': obj['height_tolerance_value'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'rated_adsorption_force': obj['rated_adsorption_force'],
|
||||
'magnetic_field_height': obj['magnetic_field_height'],
|
||||
'magnetic_pole_plate_grinding_allowance': obj['magnetic_pole_plate_grinding_allowance'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'interface_materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
'active': obj['active']}
|
||||
|
||||
def _json_adapter_board_fixture_param(self, obj):
|
||||
adapter_board_fixture_param_str = (0, '', {
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'screw_size': obj['screw_size'],
|
||||
'via_hole_diameter': obj['via_hole_diameter'],
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
})
|
||||
return adapter_board_fixture_param_str
|
||||
"""转接板(锁板)夹具:将data数据转换成list数据"""
|
||||
return {'code': obj['code'],
|
||||
'fixture_model_id': self.env['sf.fixture.model'].sudo().search(
|
||||
[('code', '=', obj.get('fixture_model_code'))]).id,
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'screw_size': obj['screw_size'],
|
||||
'via_hole_diameter': obj['via_hole_diameter'],
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
'active': obj['active']}
|
||||
|
||||
def _json_scroll_chuck_param(self, obj):
|
||||
scroll_chuck_param_str = (0, '', {
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'diameter': obj['diameter'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'mounting_hole_depth': obj['mounting_hole_depth'],
|
||||
'centering_diameter': obj['centering_diameter'],
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
})
|
||||
return scroll_chuck_param_str
|
||||
"""转接板(锁板)夹具:将data数据转换成list数据"""
|
||||
return {'code': obj['code'],
|
||||
'fixture_model_id': self.env['sf.fixture.model'].sudo().search(
|
||||
[('code', '=', obj.get('fixture_model_code'))]).id,
|
||||
'name': obj['name'],
|
||||
'length': obj['length'],
|
||||
'width': obj['width'],
|
||||
'height': obj['height'],
|
||||
'diameter': obj['diameter'],
|
||||
'weight': obj['weight'],
|
||||
'gripper_length_min': obj['gripper_length_min'],
|
||||
'gripper_width_min': obj['gripper_width_min'],
|
||||
'gripper_height_min': obj['gripper_height_min'],
|
||||
'gripper_diameter_min': obj['gripper_diameter_min'],
|
||||
'gripper_length_max': obj['gripper_length_max'],
|
||||
'gripper_width_max': obj['gripper_width_max'],
|
||||
'gripper_height_max': obj['gripper_height_max'],
|
||||
'gripper_diameter_max': obj['gripper_diameter_max'],
|
||||
'chucking_power_max': obj['chucking_power_max'],
|
||||
'carrying_capacity_max': obj['carrying_capacity_max'],
|
||||
'materials_model_id': self.env['sf.materials.model'].sudo().search(
|
||||
[('materials_no', '=', obj['materials_model_id']), ('active', '=', True)]).id,
|
||||
'rigidity': obj['rigidity'],
|
||||
'mounting_hole_depth': obj['mounting_hole_depth'],
|
||||
'centering_diameter': obj['centering_diameter'],
|
||||
'type_of_drive': obj['type_of_drive'],
|
||||
'active': obj['active']}
|
||||
|
||||
@@ -61,10 +61,10 @@ class MrsMaterialModel(models.Model):
|
||||
supplier_ids = fields.One2many('sf.supplier.sort', 'materials_model_id', string='供应商')
|
||||
active = fields.Boolean('有效', default=True)
|
||||
|
||||
@api.constrains('supplier_ids')
|
||||
@api.onchange('gain_way')
|
||||
def _check_gain_way(self):
|
||||
if not self.gain_way:
|
||||
raise UserError("请输入获取方式")
|
||||
raise UserError("请选择获取方式")
|
||||
if self.gain_way in ['外协', '采购']:
|
||||
if not self.supplier_ids:
|
||||
raise UserError("请添加供应商")
|
||||
@@ -90,7 +90,7 @@ class MrsProductionProcess(models.Model):
|
||||
code = fields.Char("编码")
|
||||
name = fields.Char('名称')
|
||||
remark = fields.Text("备注")
|
||||
processing_order_ids = fields.One2many('sf.processing.order', 'production_process_id', string='工序')
|
||||
# processing_order_ids = fields.One2many('sf.processing.order', 'production_process_id', string='工序')
|
||||
partner_process_ids = fields.Many2many('res.partner', 'process_ids', '加工工厂')
|
||||
active = fields.Boolean('有效', default=True)
|
||||
parameter_ids = fields.One2many('sf.production.process.parameter', 'process_id', string='可选参数')
|
||||
@@ -98,25 +98,25 @@ class MrsProductionProcess(models.Model):
|
||||
# workcenter_ids = fields.Many2many('mrp.workcenter', 'rel_workcenter_process', required=True)
|
||||
|
||||
|
||||
class MrsProcessingTechnology(models.Model):
|
||||
_name = 'sf.processing.technology'
|
||||
_description = '加工工艺'
|
||||
|
||||
name = fields.Char('名称', index=True)
|
||||
remark = fields.Text('备注', index=True)
|
||||
code = fields.Char("编码")
|
||||
processing_order_ids = fields.Many2many('sf.processing.order', 'sf_associated_processes',
|
||||
index=True, string='工序')
|
||||
active = fields.Boolean('有效', default=True)
|
||||
# class MrsProcessingTechnology(models.Model):
|
||||
# _name = 'sf.processing.technology'
|
||||
# _description = '加工工艺'
|
||||
#
|
||||
# name = fields.Char('名称', index=True)
|
||||
# remark = fields.Text('备注', index=True)
|
||||
# code = fields.Char("编码")
|
||||
# processing_order_ids = fields.Many2many('sf.processing.order', 'sf_associated_processes',
|
||||
# index=True, string='工序')
|
||||
# active = fields.Boolean('有效', default=True)
|
||||
|
||||
|
||||
class MrsProcessingOrder(models.Model):
|
||||
_name = 'sf.processing.order'
|
||||
_description = '工序'
|
||||
sequence = fields.Integer('Sequence')
|
||||
processing_technology_ids = fields.Many2many('sf.processing.technology', 'sf_associated_processes',
|
||||
index=True, string='加工工艺')
|
||||
production_process_id = fields.Many2one('sf.production.process', string="表面工艺")
|
||||
# class MrsProcessingOrder(models.Model):
|
||||
# _name = 'sf.processing.order'
|
||||
# _description = '工序'
|
||||
# sequence = fields.Integer('Sequence')
|
||||
# processing_technology_ids = fields.Many2many('sf.processing.technology', 'sf_associated_processes',
|
||||
# index=True, string='加工工艺')
|
||||
# production_process_id = fields.Many2one('sf.production.process', string="表面工艺")
|
||||
|
||||
|
||||
class SupplierSort(models.Model):
|
||||
|
||||
@@ -26,10 +26,10 @@ class FixtureModel(models.Model):
|
||||
_name = 'sf.fixture.model'
|
||||
_description = "夹具型号"
|
||||
|
||||
name = fields.Char(string="名称", size=50, required=True)
|
||||
fixture_material_id = fields.Many2one('sf.fixture.material', string="夹具物料", required=True)
|
||||
name = fields.Char(string="名称", size=50)
|
||||
fixture_material_id = fields.Many2one('sf.fixture.material', string="夹具物料")
|
||||
fixture_material_type = fields.Char(string="夹具物料类型", related='fixture_material_id.name')
|
||||
multi_mounting_type_id = fields.Many2one('sf.multi_mounting.type', string="联装类型", required=True)
|
||||
multi_mounting_type_id = fields.Many2one('sf.multi_mounting.type', string="联装类型")
|
||||
brand_id = fields.Many2one('sf.machine.brand', string="品牌")
|
||||
model_file = fields.Binary(string="图片")
|
||||
status = fields.Boolean('状态')
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import json
|
||||
import requests
|
||||
from datetime import date
|
||||
from odoo import fields, models, api
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
from odoo.exceptions import UserError
|
||||
|
||||
|
||||
class CuttingToolMaterial(models.Model):
|
||||
@@ -113,6 +111,24 @@ class CuttingToolModel(models.Model):
|
||||
feed_per_tooth_ids = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz(整体式刀具)')
|
||||
feed_per_tooth_ids_3 = fields.One2many('sf.feed.per.tooth', 'standard_library_id', '每齿走刀量fz(刀片)')
|
||||
material_model_id = fields.Many2one('sf.materials.model', '材料型号')
|
||||
|
||||
@api.onchange('cutting_tool_material_id')
|
||||
def _get_code(self):
|
||||
if self.is_cloud is False:
|
||||
today = date.today().strftime("%Y%m%d")
|
||||
today_code = 'T-DJWL-%s-%s' % (self.cutting_tool_material_id.code, today)
|
||||
cutting_tool_model = self.search(
|
||||
[('code', 'ilike', today_code), ('is_cloud', '=', False),
|
||||
('active', 'in', [True, False])],
|
||||
limit=1,
|
||||
order="id desc")
|
||||
if not cutting_tool_model:
|
||||
num = "%03d" % 1
|
||||
else:
|
||||
m = int(today_code[-3:]) + 1
|
||||
num = "%03d" % m
|
||||
self.code = "%s%s" % (today_code, num)
|
||||
|
||||
# 适用夹头型号可以多选
|
||||
# chuck_ids = fields.Many2many(
|
||||
# 'sf.cutting_tool.standard.library',
|
||||
@@ -189,9 +205,9 @@ class MaintenanceStandardImage(models.Model):
|
||||
('压紧方式', '压紧方式'), ('刀片形状', '刀片形状'), ('冷却方式', '冷却方式')],
|
||||
string='特征')
|
||||
equipment_id = fields.Many2many('maintenance.equipment', 'image_id', string='设备')
|
||||
equipment_lq_id = fields.Many2many('maintenance.equipment', 'image_lq_id', string='设备')
|
||||
equipment_lq_id = fields.Many2many('maintenance.equipment', 'image_lq_id', string='设备能力特征')
|
||||
jg_equipment_id = fields.Many2many('sf.machine_tool.type', 'jg_image_id', string='机床型号')
|
||||
lq_equipment_id = fields.Many2many('sf.machine_tool.type', 'lq_image_id', string='机床型号')
|
||||
lq_equipment_id = fields.Many2many('sf.machine_tool.type', 'lq_image_id', string='机床型号能力特征')
|
||||
|
||||
def _get_ids(self, name_arr):
|
||||
ability_feature_ids = []
|
||||
@@ -254,31 +270,34 @@ class ToolGroups(models.Model):
|
||||
equipment_ids = fields.Many2many('maintenance.equipment', 'ref_maintenance_equipment', string='机台号')
|
||||
remark = fields.Char('备注', size=50)
|
||||
|
||||
active = fields.Boolean(string='已归档', default=True)
|
||||
|
||||
# ==========机床刀具组接口==========
|
||||
def _register_tool_groups(self, obj):
|
||||
create_url = '/AutoDeviceApi/MaintenanceToolGroups'
|
||||
sf_sync_config = self.env['res.config.settings'].get_values()
|
||||
token = sf_sync_config['token']
|
||||
sf_secret_key = sf_sync_config['sf_secret_key']
|
||||
headers = Common.get_headers(obj, token, sf_secret_key)
|
||||
strurl = sf_sync_config['sf_url'] + create_url
|
||||
device_id = ''
|
||||
name = None
|
||||
if obj:
|
||||
for equipment_id in obj.equipment_ids:
|
||||
device_id = '%s,%s' % (device_id, equipment_id.name)
|
||||
name = obj.name
|
||||
val = {
|
||||
'DeviceId': device_id,
|
||||
'GroupName': name,
|
||||
}
|
||||
kw = json.dumps(val, ensure_ascii=False)
|
||||
r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
|
||||
ret = r.json()
|
||||
if r == 200:
|
||||
return "机床刀具组发送成功"
|
||||
else:
|
||||
raise ValidationError("机床刀具组发送失败")
|
||||
# def _register_tool_groups(self, obj):
|
||||
# # create_url = '/AutoDeviceApi/MachineToolGroup'
|
||||
# sf_sync_config = self.env['res.config.settings'].get_values()
|
||||
# token = sf_sync_config['token']
|
||||
# sf_secret_key = sf_sync_config['sf_secret_key']
|
||||
# headers = Common.get_headers(obj, token, sf_secret_key)
|
||||
# strurl = "https://x24467i973.zicp.fun/AutoDeviceApi/MachineToolGroup"
|
||||
# device_id = ''
|
||||
# name = None
|
||||
# if obj:
|
||||
# for equipment_id in obj.equipment_ids:
|
||||
# device_id = '%s,%s' % (device_id, equipment_id.name)
|
||||
# name = obj.name
|
||||
# val = {
|
||||
# 'DeviceId': device_id,
|
||||
# 'GroupName': name,
|
||||
# }
|
||||
# kw = json.dumps(val, ensure_ascii=False)
|
||||
# r = requests.post(strurl, json={}, data={'kw': kw, 'token': token}, headers=headers)
|
||||
# print(r)
|
||||
# ret = r.json()
|
||||
# if r == 200:
|
||||
# return "机床刀具组发送成功"
|
||||
# else:
|
||||
# raise ValidationError("机床刀具组发送失败")
|
||||
|
||||
# def write(self, vals):
|
||||
# obj = super().write(vals)
|
||||
@@ -290,3 +309,41 @@ class ToolGroups(models.Model):
|
||||
# records = super(ToolGroups, self).create(vals_list)
|
||||
# self._register_tool_groups(records)
|
||||
# return records
|
||||
|
||||
|
||||
class ToolInventory(models.Model):
|
||||
_name = 'sf.tool.inventory'
|
||||
_description = '功能刀具清单'
|
||||
|
||||
name = fields.Char('功能刀具名称', required=True)
|
||||
type = fields.Char('类型')
|
||||
functional_cutting_tool_model_id = fields.Many2one('sf.functional.cutting.tool.model', string='功能刀具类型')
|
||||
prefix = fields.Char('前缀')
|
||||
postfix = fields.Char('后缀')
|
||||
diameter = fields.Float('直径(mm)')
|
||||
angle = fields.Float('R角(mm)')
|
||||
tool_length = fields.Float('刀具总长(mm)')
|
||||
blade_length = fields.Float('避空长/刃长(mm)')
|
||||
knife_head_name = fields.Char('刀头名称')
|
||||
cutter_number = fields.Char('刀号')
|
||||
blade_number = fields.Integer('刃数(个)')
|
||||
extension = fields.Float('伸出长度(mm)')
|
||||
work_material = fields.Selection([('钢', '钢'), ('铝', '铝')], string='加工材料')
|
||||
life_span = fields.Float('寿命(min)')
|
||||
|
||||
tool_groups_id = fields.Many2one('sf.tool.groups', string='刀具组')
|
||||
|
||||
active = fields.Boolean('已归档', default=True)
|
||||
|
||||
@api.model_create_multi
|
||||
def create(self, vals_list):
|
||||
# 名称重复校验
|
||||
name_list = []
|
||||
for val in vals_list:
|
||||
tool_inventory = self.search([('name', '=', val['name'])])
|
||||
if tool_inventory:
|
||||
name_list.append(val['name'])
|
||||
if name_list:
|
||||
raise UserError("功能刀具名称%s已存在,请重新输入" % name_list)
|
||||
records = super(ToolInventory, self).create(vals_list)
|
||||
return records
|
||||
|
||||
@@ -10,6 +10,7 @@ class ToolMaterialsBasicParameters(models.Model):
|
||||
standard_library_id = fields.Many2one('sf.cutting_tool.standard.library', string='刀具标准库')
|
||||
cutting_tool_type = fields.Char(related='standard_library_id.cutting_tool_type', string='刀具物料类型',
|
||||
store=True)
|
||||
is_cloud = fields.Boolean(related='standard_library_id.is_cloud', string='云端数据')
|
||||
|
||||
# 整体式刀具参数
|
||||
total_length = fields.Float('总长度(mm)')
|
||||
@@ -21,7 +22,7 @@ class ToolMaterialsBasicParameters(models.Model):
|
||||
handle_diameter = fields.Float('柄部直径(mm)')
|
||||
handle_length = fields.Float('柄部长度(mm)')
|
||||
blade_tip_diameter = fields.Integer('刀尖直径(mm)')
|
||||
blade_tip_working_size = fields.Char('刀尖处理尺寸(R半径mm/倒角)', size=20)
|
||||
blade_tip_working_size = fields.Char('刀尖处理尺寸(R半径mm/倒角度)', size=20)
|
||||
blade_tip_taper = fields.Integer('刀尖锥度(°)')
|
||||
blade_diameter = fields.Float('刃部直径(mm)')
|
||||
blade_length = fields.Float('刃部长度(mm)')
|
||||
@@ -37,7 +38,7 @@ class ToolMaterialsBasicParameters(models.Model):
|
||||
cutting_blade_length = fields.Float('切削刃长(mm)')
|
||||
relief_angle = fields.Integer('后角(°)')
|
||||
blade_tip_circular_arc_radius = fields.Char('刀尖圆弧半径(mm)', size=20)
|
||||
inscribed_circle_diameter = fields.Float('内接圆直径(mm)')
|
||||
inscribed_circle_diameter = fields.Float('内接圆直径IC/D(mm)')
|
||||
install_aperture_diameter = fields.Float('安装孔直径(mm)')
|
||||
chip_breaker_groove = fields.Selection([('无', '无'), ('单面', '单面'), ('双面', '双面')],
|
||||
string='有无断屑槽')
|
||||
@@ -170,8 +171,6 @@ class FeedPerTooth(models.Model):
|
||||
feed_per_tooth = fields.Char('每齿走刀量 (mm/z)', size=20)
|
||||
active = fields.Boolean(string='有效', default=True)
|
||||
|
||||
|
||||
|
||||
# @api.depends('product_template_id')
|
||||
# def _compute_product_template_id(self):
|
||||
# if self.product_template_id is not None:
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
<record id="group_plan_dispatch" model="res.groups">
|
||||
<field name="name">计划调度岗</field>
|
||||
<field name="category_id" ref="module_category_plan"/>
|
||||
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||
<!-- <field name="implied_ids" eval="[(4, ref('base.group_user'))]"/> -->
|
||||
</record>
|
||||
|
||||
<record id="group_plan_director" model="res.groups">
|
||||
@@ -84,6 +84,17 @@
|
||||
<field name="category_id" ref="base.module_category_inventory_purchase"/>
|
||||
</record>
|
||||
|
||||
<record id="group_sf_stock_user" model="res.groups">
|
||||
<field name="name">仓储岗</field>
|
||||
<field name="category_id" ref="base.module_category_inventory_inventory"/>
|
||||
<field name="implied_ids" eval="[(4, ref('base.group_user'))]"/>
|
||||
</record>
|
||||
<record id="group_sf_stock_manager" model="res.groups">
|
||||
<field name="name">仓储总监</field>
|
||||
<field name="category_id" ref="base.module_category_inventory_inventory"/>
|
||||
<field name="implied_ids" eval="[(4, ref('group_sf_stock_user'))]"/>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -9,19 +9,26 @@ access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,b
|
||||
access_sf_machine_brand_tags_admin,sf_machine_brand_tags_admin,model_sf_machine_brand_tags,base.group_system,1,1,1,0
|
||||
access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,base.group_user,1,1,1,0
|
||||
access_sf_machine_control_system_admin,sf_machine_control_system_admin,model_sf_machine_control_system,base.group_system,1,1,1,0
|
||||
access_sf_processing_order,sf_processing_order,model_sf_processing_order,base.group_user,1,1,1,0
|
||||
access_sf_processing_order_admin,sf_processing_order_admin,model_sf_processing_order,base.group_system,1,1,1,0
|
||||
access_sf_production_process_group_sale_director,sf_production_process_group_sale_director,model_sf_production_process,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_production_process_group_sale_salemanager,sf_production_process_group_sale_salemanager,model_sf_production_process,sf_base.group_sale_salemanager,1,0,0,0
|
||||
access_res_partner_category_group_sale_salemanager,res_partner_category_group_sale_salemanager,base.model_res_partner_category,sf_base.group_sale_salemanager,1,0,1,0
|
||||
access_res_partner_category_group_sale_director,res_partner_category_group_sale_director,base.model_res_partner_category,sf_base.group_sale_director,1,0,1,0
|
||||
access_sf_production_process,sf_production_process,model_sf_production_process,base.group_user,1,1,1,0
|
||||
access_sf_production_process_admin,sf_production_process_admin,model_sf_production_process,base.group_system,1,1,1,0
|
||||
access_sf_production_materials,sf_production_materials,model_sf_production_materials,base.group_user,1,1,1,0
|
||||
access_sf_production_materials_group_sale_director,sf_production_materials_group_sale_director,model_sf_production_materials,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_production_materials_group_sale_salemanager,sf_production_materials_group_sale_salemanager,model_sf_production_materials,sf_base.group_sale_salemanager,1,0,0,0
|
||||
|
||||
access_sf_production_materials_admin,sf_production_materials_admin,model_sf_production_materials,base.group_system,1,1,1,0
|
||||
access_sf_materials_model,sf_materials_model,model_sf_materials_model,base.group_user,1,1,1,0
|
||||
access_sf_materials_model_admin,sf_materials_model_admin,model_sf_materials_model,base.group_system,1,1,1,0
|
||||
access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,base.group_user,1,1,1,0
|
||||
access_sf_processing_technology_admin,sf_processing_technology_admin,model_sf_processing_technology,base.group_system,1,1,1,0
|
||||
access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,base.group_user,1,1,1,0
|
||||
access_sf_supplier_sort_admin,sf_supplier_sort_admin,model_sf_supplier_sort,base.group_system,1,1,1,0
|
||||
access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,base.group_user,1,1,1,0
|
||||
access_sf_production_process_parameter_group_sale_director,sf_production_process_parameter_group_sale_director,model_sf_production_process_parameter,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_production_process_parameter_group_sale_salemanager,sf_production_process_parameter_group_sale_salemanager,model_sf_production_process_parameter,sf_base.group_sale_salemanager,1,0,0,0
|
||||
|
||||
|
||||
access_sf_production_process_parameter_group_plan_director,sf_production_process_parameter_group_plan_director,model_sf_production_process_parameter,sf_base.group_plan_director,1,0,0,0
|
||||
access_sf_production_process_parameter_group_purchase_director,sf_production_process_parameter_group_purchase_director,model_sf_production_process_parameter,sf_base.group_purchase_director,1,0,0,0
|
||||
access_sf_production_process_parameter_group_sale_director,sf_production_process_parameter_group_sale_director,model_sf_production_process_parameter,sf_base.group_sale_director,1,0,0,0
|
||||
@@ -37,12 +44,12 @@ access_sf_cutting_tool_type_admin,sf_cutting_tool_type_admin,model_sf_cutting_to
|
||||
access_sf_cutting_tool_type_group_purchase_director,sf_cutting_tool_type_group_purchase_director,model_sf_cutting_tool_type,sf_base.group_purchase_director,1,1,0,0
|
||||
access_sf_cutting_tool_type_group_sale_director,sf_cutting_tool_type_group_sale_director,model_sf_cutting_tool_type,sf_base.group_sale_director,1,1,0,0
|
||||
access_sf_cutting_tool_type_group_plan_director,sf_cutting_tool_type_group_plan_director,model_sf_cutting_tool_type,sf_base.group_plan_director,1,1,0,0
|
||||
|
||||
access_sf_functional_cutting_tool,sf_functional_cutting_tool,model_sf_functional_cutting_tool,base.group_user,1,1,1,0
|
||||
access_sf_functional_cutting_tool_admin,sf_functional_cutting_tool_admin,model_sf_functional_cutting_tool,base.group_system,1,1,1,0
|
||||
access_sf_functional_cutting_tool_model,sf_functional_cutting_tool_model,model_sf_functional_cutting_tool_model,base.group_user,1,1,1,0
|
||||
access_sf_functional_cutting_tool_model_admin,sf_functional_cutting_tool_model_admin,model_sf_functional_cutting_tool_model,base.group_system,1,1,1,0
|
||||
access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,base.group_user,1,1,1,0
|
||||
access_sf_fixture_material_group_sf_stock_user,sf_fixture_material_group_sf_stock_user,model_sf_fixture_material,sf_base.group_sf_stock_user,1,1,1,0
|
||||
access_sf_fixture_material_admin,sf_fixture_material_admin,model_sf_fixture_material,base.group_system,1,1,1,0
|
||||
access_sf_fixture_materials_basic_parameters,sf_fixture_materials_basic_parameters,model_sf_fixture_materials_basic_parameters,base.group_user,1,1,1,0
|
||||
access_sf_fixture_materials_basic_parameters_admin,sf_fixture_materials_basic_parameters_admin,model_sf_fixture_materials_basic_parameters,base.group_system,1,1,1,0
|
||||
@@ -60,6 +67,12 @@ access_sf_international_standards,sf_international_standards,model_sf_internatio
|
||||
access_sf_international_standards_admin,sf_international_standards_admin,model_sf_international_standards,base.group_system,1,1,1,0
|
||||
access_material_apply,material_apply,model_material_apply,base.group_user,1,1,1,0
|
||||
access_material_apply_admin,material_apply_admin,model_material_apply,base.group_system,1,1,1,0
|
||||
access_material_apply_group_purchase_director,material_apply_group_purchase_director,model_material_apply,sf_base.group_purchase_director,1,0,0,0
|
||||
access_material_apply_group_sale_director,material_apply_group_sale_director,model_material_apply,sf_base.group_sale_director,1,0,0,0
|
||||
access_material_apply_group_plan_director,material_apply_group_plan_director,model_material_apply,sf_base.group_plan_director,1,0,0,0
|
||||
access_material_apply_group_purchase_director,material_apply_group_purchase_director,model_material_apply,sf_base.group_purchase_director,1,0,0,0
|
||||
access_material_apply_group_sale_salemanager,material_apply_group_sale_salemanager,model_material_apply,sf_base.group_sale_salemanager,1,0,0,0
|
||||
|
||||
access_sf_cutting_tool_standard_library,sf_cutting_tool_standard_library,model_sf_cutting_tool_standard_library,base.group_user,1,1,1,0
|
||||
access_sf_cutting_tool_standard_library_admin,sf_cutting_tool_standard_library_admin,model_sf_cutting_tool_standard_library,base.group_system,1,1,1,0
|
||||
access_sf_tool_materials_basic_parameters,sf_tool_materials_basic_parameters,model_sf_tool_materials_basic_parameters,base.group_user,1,1,1,0
|
||||
@@ -68,10 +81,17 @@ access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,base.group_user,
|
||||
access_sf_cutting_speed_admin,sf_cutting_speed_admin,model_sf_cutting_speed,base.group_system,1,1,1,0
|
||||
access_sf_cutting_speed_group_purchase_director,sf_cutting_speed_group_purchase_director,model_sf_cutting_speed,sf_base.group_purchase_director,1,1,1,0
|
||||
access_sf_cutting_speed_group_sale_director,sf_cutting_speed_group_sale_director,model_sf_cutting_speed,sf_base.group_sale_director,1,1,1,0
|
||||
access_sf_cutting_speed_group_plan_dispatch,sf_cutting_speed_group_plan_dispatch,model_sf_cutting_speed,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_cutting_speed_group_plan_director,sf_cutting_speed_group_plan_director,model_sf_cutting_speed,sf_base.group_plan_director,1,1,1,0
|
||||
access_sf_cutting_speed_group_quality_director,sf_cutting_speed_group_quality_director,model_sf_cutting_speed,sf_base.group_quality_director,1,1,1,0
|
||||
access_sf_cutting_speed_group_quality,sf_cutting_speed_group_quality,model_sf_cutting_speed,sf_base.group_quality,1,1,1,0
|
||||
access_sf_feed_per_tooth_group_purchase_director,sf_feed_per_tooth_group_purchase_director,model_sf_feed_per_tooth,sf_base.group_purchase_director,1,1,0,0
|
||||
access_sf_feed_per_tooth_group_sale_director,sf_feed_per_tooth_group_sale_director,model_sf_feed_per_tooth,sf_base.group_sale_director,1,1,0,0
|
||||
access_sf_feed_per_tooth_group_plan_dispatch,sf_feed_per_tooth_group_plan_dispatch,model_sf_feed_per_tooth,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_feed_per_tooth_group_plan_director,sf_feed_per_tooth_group_plan_director,model_sf_feed_per_tooth,sf_base.group_plan_director,1,1,0,0
|
||||
access_sf_feed_per_tooth_group_sale_salemanager,sf_feed_per_tooth_group_sale_salemanager,model_sf_feed_per_tooth,sf_base.group_sale_salemanager,1,0,0,0
|
||||
access_sf_feed_per_tooth_group_quality,sf_feed_per_tooth_group_quality,model_sf_feed_per_tooth,sf_base.group_quality,1,1,1,0
|
||||
access_sf_feed_per_tooth_group_quality_director,sf_feed_per_tooth_group_quality_director,model_sf_feed_per_tooth,sf_base.group_quality_director,1,1,1,0
|
||||
access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,base.group_user,1,1,1,0
|
||||
access_sf_feed_per_tooth_admin,sf_feed_per_tooth_admin,model_sf_feed_per_tooth,base.group_system,1,1,1,0
|
||||
access_sf_ramping_angle,sf_ramping_angle,model_sf_ramping_angle,base.group_user,1,1,1,1
|
||||
@@ -86,17 +106,19 @@ access_sf_machine_brand_group_purchase_director,sf_machine_brand_group_purchase_
|
||||
access_sf_machine_brand_group_sale_director,sf_machine_brand_group_sale_director,model_sf_machine_brand,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,base.group_user,1,1,1,1
|
||||
access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_processing_order,sf_processing_order,model_sf_processing_order,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_production_process,sf_production_process,model_sf_production_process,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_production_materials,sf_production_materials,model_sf_production_materials,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_production_materials_group_plan_director,sf_production_materials_group_plan_director,model_sf_production_materials,sf_base.group_plan_director,1,1,0,0
|
||||
access_sf_production_materials_group_purchase_director,sf_production_materials_group_purchase_director,model_sf_production_materials,sf_base.group_purchase_director,1,1,0,0
|
||||
access_sf_production_materials_group_sale_director,sf_production_materials_group_sale_director,model_sf_production_materials,sf_base.group_sale_director,1,1,0,0
|
||||
access_sf_materials_model,sf_materials_model,model_sf_materials_model,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_materials_model_group_sale_salemanager,sf_materials_model_group_sale_salemanager,model_sf_materials_model,sf_base.group_sale_salemanager,1,0,0,0
|
||||
access_sf_materials_model_group_sale_director,sf_materials_model_group_sale_director,model_sf_materials_model,sf_base.group_sale_director,1,0,0,0
|
||||
|
||||
|
||||
access_sf_materials_model_group_plan_director,sf_materials_model_group_plan_director,model_sf_materials_model,sf_base.group_plan_director,1,0,0,0
|
||||
access_sf_materials_model_group_purchase_director,sf_materials_model_group_purchase_director,model_sf_materials_model,sf_base.group_purchase_director,1,0,0,0
|
||||
access_sf_materials_model_group_sale_director,sf_materials_model_group_sale_director,model_sf_materials_model,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
@@ -116,57 +138,45 @@ access_sf_functional_fixture,sf_functional_fixture,model_sf_functional_fixture,s
|
||||
access_sf_sync_common,sf_sync_common,model_sf_sync_common,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_international_standards,sf_international_standards,model_sf_international_standards,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_material_apply,material_apply,model_material_apply,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
|
||||
access_sf_cutting_tool_standard_library_group_sf_mrp_user,sf_cutting_tool_standard_library_group_sf_mrp_user,model_sf_cutting_tool_standard_library,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_cutting_tool_standard_library_group_purchase_director,sf_cutting_tool_standard_library_group_purchase_director,model_sf_cutting_tool_standard_library,sf_base.group_purchase_director,1,0,1,0
|
||||
access_sf_cutting_tool_standard_library_group_plan_director,sf_cutting_tool_standard_library_group_plan_director,model_sf_cutting_tool_standard_library,sf_base.group_plan_director,1,0,1,0
|
||||
access_sf_cutting_tool_standard_library_group_sale_director,sf_cutting_tool_standard_library_group_sale_director,model_sf_cutting_tool_standard_library,sf_base.group_sale_director,1,0,1,0
|
||||
|
||||
access_sf_tool_groups,sf_tool_groups,model_sf_tool_groups,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_tool_materials_basic_parameters_group_sale_director,sf_tool_materials_basic_parameters_group_sale_director,model_sf_tool_materials_basic_parameters,sf_base.group_sale_director,1,0,1,0
|
||||
access_sf_tool_materials_basic_parameters_group_plan_director,sf_tool_materials_basic_parameters_group_plan_director,model_sf_tool_materials_basic_parameters,sf_base.group_plan_director,1,0,1,0
|
||||
access_sf_tool_materials_basic_parameters_group_purchase_director,sf_tool_materials_basic_parameters_group_purchase_director,model_sf_tool_materials_basic_parameters,sf_base.group_purchase_director,1,0,1,0
|
||||
|
||||
access_sf_cutting_speed,sf_cutting_speed,model_sf_cutting_speed,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_cutting_speed_group_purchase,sf_cutting_speed_group_purchase,model_sf_cutting_speed,sf_base.group_purchase,1,0,0,0
|
||||
access_sf_cutting_speed_group_sale_salemanager,sf_cutting_speed_group_sale_salemanager,model_sf_cutting_speed,sf_base.group_sale_salemanager,1,0,0,0
|
||||
|
||||
|
||||
access_sf_feed_per_tooth,sf_feed_per_tooth,model_sf_feed_per_tooth,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_feed_per_tooth_group_purchase,sf_feed_per_tooth_group_purchase,model_sf_feed_per_tooth,sf_base.group_purchase,1,0,0,0
|
||||
access_sf_ramping_angle,sf_ramping_angle,model_sf_ramping_angle,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_ramping_angle_group_purchase,sf_ramping_angle_group_purchase,model_sf_ramping_angle,sf_base.group_purchase,1,0,0,0
|
||||
access_sf_cutting_width_depth,sf_cutting_width_depth,model_sf_cutting_width_depth,sf_base.group_sf_mrp_user,1,0,0,0
|
||||
access_sf_cutting_width_depth_group_purchase,sf_cutting_width_depth_group_purchase,model_sf_cutting_width_depth,sf_base.group_purchase,1,0,0,0
|
||||
|
||||
access_maintenance_equipment_image,maintenance_equipment_image,model_maintenance_equipment_image,base.group_user,1,1,1,1
|
||||
access_purchase_order_group_purchase,access_purchase_order_group_purchase,purchase.model_purchase_order,sf_base.group_purchase,1,1,1,0
|
||||
access_purchase_order_group_purchase_director,access_purchase_order_group_purchase_director,purchase.model_purchase_order,sf_base.group_purchase_director,1,1,1,0
|
||||
access_purchase_order_line_group_purchase,access_purchase_order_line_group_purchase,purchase.model_purchase_order_line,sf_base.group_purchase,1,1,1,0
|
||||
access_purchase_order_line_group_purchase_director,access_purchase_order_line_group_purchase_director,purchase.model_purchase_order_line,sf_base.group_purchase_director,1,1,1,0
|
||||
access_spindle_taper_type,spindle_taper_type,model_spindle_taper_type,base.group_user,1,1,1,1
|
||||
|
||||
access_sf_tool_groups_group_plan_dispatch,sf_tool_groups,model_sf_tool_groups,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_tool_groups_group_plan_director,sf_tool_groups,model_sf_tool_groups,sf_base.group_plan_director,1,1,1,0
|
||||
access_sf_tool_groups_group_sf_tool_user,sf_tool_groups,model_sf_tool_groups,sf_base.group_sf_tool_user,1,1,1,1
|
||||
|
||||
|
||||
|
||||
access_purchase_order,purchase.order,purchase.model_purchase_order,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_res_partner,res.partner,base.model_res_partner,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_purchase_order_line,purchase.order.line,purchase.model_purchase_order_line,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_account_move_line,account.move.line,account.model_account_move_line,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
access_sf_machine_tool_type_group_plan_dispatch,sf.machine_tool.type,model_sf_machine_tool_type,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
access_sf_machine_tool,sf_machine_tool,model_sf_machine_tool,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_machine_tool_type,sf_machine_tool_type,model_sf_machine_tool_type,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_machine_brand,sf_machine_brand,model_sf_machine_brand,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_machine_brand_tags,sf_machine_brand_tags,model_sf_machine_brand_tags,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_machine_control_system,sf_machine_control_system,model_sf_machine_control_system,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_processing_order,sf_processing_order,model_sf_processing_order,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_production_process,sf_production_process,model_sf_production_process,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_production_materials,sf_production_materials,model_sf_production_materials,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_materials_model,sf_materials_model,model_sf_materials_model,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_processing_technology,sf_processing_technology,model_sf_processing_technology,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_supplier_sort,sf_supplier_sort,model_sf_supplier_sort,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_production_process_parameter,sf_production_process_parameter,model_sf_production_process_parameter,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_sf_production_process_category,sf_production_process_category,model_sf_production_process_category,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
@@ -179,10 +189,56 @@ access_sf_fixture_material,sf_fixture_material,model_sf_fixture_material,sf_base
|
||||
access_sf_fixture_materials_basic_parameters,sf_fixture_materials_basic_parameters,model_sf_fixture_materials_basic_parameters,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
access_mrp_production_group_sale_salemanager,mrp_production_group_sale_salemanager,mrp.model_mrp_production,sf_base.group_sale_salemanager,1,0,0,0
|
||||
access_mrp_production_group_sale_director,mrp_production_group_sale_director,mrp.model_mrp_production,sf_base.group_sale_director,1,0,0,0
|
||||
|
||||
|
||||
access_material_apply_group_plan_dispatch,material_apply,model_material_apply,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_machine_brand_tags_group_plan_dispatch,sf_machine_brand_tags,model_sf_machine_brand_tags,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_ir_actions_act_window_group_plan_dispatch,ir.actions.act_window,base.model_ir_actions_act_window,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_ir_actions_act_window_view_group_plan_dispatch,ir.actions.act_window.view,base.model_ir_actions_act_window_view,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_supplier_sort_group_plan_dispatch,sf.supplier.sort,model_sf_supplier_sort,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_supplier_sort_group_plan_dispatch,sf.supplier.sort,model_sf_supplier_sort,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_international_standards_group_sale_salemanager,sf_international_standards_group_sale_salemanager,model_sf_international_standards,sf_base.group_sale_salemanager,1,0,0,0
|
||||
access_sf_international_standards_group_sale_director,sf_international_standards_group_sale_director,model_sf_international_standards,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_international_standards_group_plan_director,sf_international_standards_group_plan_director,model_sf_international_standards,sf_base.group_plan_director,1,0,0,0
|
||||
access_sf_international_standards_group_purchase,sf_international_standards_group_purchase,model_sf_international_standards,sf_base.group_purchase,1,0,0,0
|
||||
access_sf_international_standards_group_purchase_director,sf_international_standards_group_purchase_director,model_sf_international_standards,sf_base.group_purchase_director,1,0,0,0
|
||||
access_sf_machine_brand_tags_group_sale_salemanager,sf_machine_brand_tags_group_sale_salemanager,model_sf_machine_brand_tags,sf_base.group_sale_salemanager,1,0,0,0
|
||||
access_sf_machine_brand_tags_group_sale_director,sf_machine_brand_tags_group_sale_director,model_sf_machine_brand_tags,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_machine_brand_tags_group_plan_director,sf_machine_brand_tags_group_plan_director,model_sf_machine_brand_tags,sf_base.group_plan_director,1,0,0,0
|
||||
access_sf_machine_brand_tags_group_purchase,sf_machine_brand_tags_group_purchase,model_sf_machine_brand_tags,sf_base.group_purchase,1,0,0,0
|
||||
access_sf_machine_brand_tags_group_purchase_director,sf_machine_brand_tags_group_purchase_director,model_sf_machine_brand_tags,sf_base.group_purchase_director,1,0,0,0
|
||||
|
||||
|
||||
access_printer,printer,model_printer,base.group_user,1,1,1,1
|
||||
access_printer_configuration,printer.configuration,model_printer_configuration,base.group_user,1,1,1,1
|
||||
|
||||
access_group_sf_mrp_user,sf_tool_inventory,model_sf_tool_inventory,base.group_user,1,1,1,0
|
||||
access_group_sf_mrp_user_admin,sf_tool_inventory_admin,model_sf_tool_inventory,base.group_system,1,1,1,0
|
||||
access_group_sf_mrp_user_group_purchase_director,sf_tool_inventory_group_purchase_director,model_sf_tool_inventory,sf_base.group_purchase_director,1,0,1,0
|
||||
access_group_sf_mrp_user_group_sale_director,sf_tool_inventory_group_sale_director,model_sf_tool_inventory,sf_base.group_sale_director,1,0,1,0
|
||||
access_sf_cutting_tool_material_group_plan_director,sf_tool_inventory_group_plan_director,model_sf_tool_inventory,sf_base.group_plan_director,1,0,1,0
|
||||
access_group_sf_mrp_user_group_sf_mrp_user,sf_tool_inventory_group_sf_mrp_user,model_sf_tool_inventory,sf_base.group_sf_mrp_user,1,1,0,0
|
||||
|
||||
|
||||
access_sf_fixture_material_group_purchase_director,sf_fixture_material_group_purchase_director,model_sf_fixture_material,sf_base.group_purchase_director,1,0,0,0
|
||||
access_sf_multi_mounting_type_group_purchase_director,sf_multi_mounting_type_group_purchase_director,model_sf_multi_mounting_type,sf_base.group_purchase_director,1,0,0,0
|
||||
access_sf_fixture_model_group_purchase_director,sf_fixture_model_group_purchase_director,model_sf_fixture_model,sf_base.group_purchase_director,1,0,0,0
|
||||
access_sf_fixture_materials_basic_parameters_group_purchase_director,sf_fixture_materials_basic_parameters_group_purchase_director,model_sf_fixture_materials_basic_parameters,sf_base.group_purchase_director,1,0,0,0
|
||||
access_sf_machine_tool_type_group_purchase_director,sf_machine_tool_type_group_purchase_director,model_sf_machine_tool_type,sf_base.group_purchase_director,1,0,0,0
|
||||
|
||||
access_sf_fixture_material_group_sale_director,sf_fixture_material_group_sale_director,model_sf_fixture_material,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_multi_mounting_type_group_sale_director,sf_multi_mounting_type_group_sale_director,model_sf_multi_mounting_type,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_fixture_model_group_sale_director,sf_fixture_model_group_sale_director,model_sf_fixture_model,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_fixture_materials_basic_parameters_group_sale_director,sf_fixture_materials_basic_parameters_group_sale_director,model_sf_fixture_materials_basic_parameters,sf_base.group_sale_director,1,0,0,0
|
||||
access_sf_machine_tool_type_group_sale_director,sf_machine_tool_type_group_sale_director,model_sf_machine_tool_type,sf_base.group_sale_director,1,0,0,0
|
||||
|
||||
access_sf_fixture_material_group_plan_director,sf_fixture_material_group_plan_director,model_sf_fixture_material,sf_base.group_plan_director,1,0,0,0
|
||||
access_sf_fixture_model_group_plan_director,sf_fixture_model_group_plan_director,model_sf_fixture_model,sf_base.group_plan_director,1,0,0,0
|
||||
access_sf_fixture_materials_basic_parameters_group_plan_director,sf_fixture_materials_basic_parameters_group_plan_director,model_sf_fixture_materials_basic_parameters,sf_base.group_plan_director,1,0,0,0
|
||||
access_sf_multi_mounting_type_group_plan_director,sf_multi_mounting_type_group_plan_director,model_sf_multi_mounting_type,sf_base.group_plan_director,1,0,0,0
|
||||
|
||||
access_sf_production_materials_group_sf_stock_manager,sf_production_materials_group_sf_stock_manager,model_sf_production_materials,sf_base.group_sf_stock_manager,1,0,0,0
|
||||
access_sf_materials_model_group_sf_stock_manager,sf_materials_model_group_sf_stock_manager,model_sf_materials_model,sf_base.group_sf_stock_manager,1,0,0,0
|
||||
access_sf_fixture_material_group_sf_stock_manager,sf_fixture_material_group_sf_stock_manager,model_sf_fixture_material,sf_base.group_sf_stock_manager,1,0,0,0
|
||||
access_sf_fixture_model_group_sf_stock_manager,sf_fixture_model_group_sf_stock_manager,model_sf_fixture_model,sf_base.group_sf_stock_manager,1,0,0,0
|
||||
access_sf_fixture_materials_basic_parameters_group_sf_stock_manager,sf_fixture_materials_basic_parameters_group_sf_stock_manager,model_sf_fixture_materials_basic_parameters,sf_base.group_sf_stock_manager,1,0,0,0
|
||||
access_sf_multi_mounting_type_group_sf_stock_manager,sf_multi_mounting_type_group_sf_stock_manager,model_sf_multi_mounting_type,sf_base.group_sf_stock_manager,1,0,0,0
|
||||
access_sf_machine_brand_group_sf_stock_manager,sf_machine_brand_group_sf_stock_manager,model_sf_machine_brand,sf_base.group_sf_stock_manager,1,0,0,0
|
||||
access_sf_cutting_tool_type_group_sf_stock_manager,sf_cutting_tool_type_group_sf_stock_manager,model_sf_cutting_tool_type,sf_base.group_sf_stock_manager,1,0,0,0
|
||||
|
||||
|
@@ -189,3 +189,6 @@ td.o_required_modifier {
|
||||
flex-direction: row !important;
|
||||
}
|
||||
|
||||
.supplier_ids_set_css thead th[data-name=partner_id]{
|
||||
width: 500px!important;
|
||||
}
|
||||
112
sf_base/views/Printer.xml
Normal file
@@ -0,0 +1,112 @@
|
||||
<odoo>
|
||||
<data>
|
||||
|
||||
<record id="view_printer_tree" model="ir.ui.view">
|
||||
<field name="name">printer.tree</field>
|
||||
<field name="model">printer</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Printer">
|
||||
<field name="name"/>
|
||||
<field name="ip_address"/>
|
||||
<field name="port"/>
|
||||
<!-- 其他字段... -->
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_printer_form" model="ir.ui.view">
|
||||
<field name="name">printer.form</field>
|
||||
<field name="model">printer</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Printer">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="ip_address"/>
|
||||
<field name="port"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_printer_configuration_tree" model="ir.ui.view">
|
||||
<field name="name">printer.configuration.tree</field>
|
||||
<field name="model">printer.configuration</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Printer Configuration">
|
||||
<field name="name"/>
|
||||
<field name="printer_id"/>
|
||||
<field name="model"/>
|
||||
<!-- 其他字段... -->
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_printer_configuration_form" model="ir.ui.view">
|
||||
<field name="name">printer.configuration.form</field>
|
||||
<field name="model">printer.configuration</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Printer Configuration">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="printer_id"/>
|
||||
<field name="model"/>
|
||||
<!-- 其他字段... -->
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!-- 其他视图... -->
|
||||
|
||||
<record id="action_printer" model="ir.actions.act_window">
|
||||
<field name="name">打印机</field>
|
||||
<field name="res_model">printer</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<!-- Action to open the printer configuration list -->
|
||||
<record id="action_printer_configuration" model="ir.actions.act_window">
|
||||
<field name="name">打印配置</field>
|
||||
<field name="res_model">printer.configuration</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
<!-- Add a menu item for the printer configuration -->
|
||||
<!-- <record id="menu_printer_configuration" model="ir.ui.menu"> -->
|
||||
<!-- <field name="name">打印配置</field> -->
|
||||
<!-- <field name="action" ref="action_printer_configuration"/> -->
|
||||
<!-- <field name="parent_id" ref="base.menu_administration"/> -->
|
||||
<!-- </record> -->
|
||||
|
||||
<!-- <record id="menu_printer" model="ir.ui.menu"> -->
|
||||
<!-- <field name="name">打印机</field> -->
|
||||
<!-- <field name="action" ref="action_printer"/> -->
|
||||
<!-- <field name="parent_id" ref="menu_printer"/> -->
|
||||
<!-- </record> -->
|
||||
|
||||
<menuitem
|
||||
id="printer_main_menu"
|
||||
name="打印配置"
|
||||
sequence="10"
|
||||
parent="base.menu_administration"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_printer"
|
||||
name="打印机"
|
||||
action="action_printer"
|
||||
sequence="1"
|
||||
parent="printer_main_menu"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_printer_configuration"
|
||||
name="打印配置"
|
||||
action="action_printer_configuration"
|
||||
sequence="2"
|
||||
parent="printer_main_menu"/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -98,6 +98,7 @@
|
||||
<field name="name" string="名称"/>
|
||||
<field name="machine_tool_category"/>
|
||||
<field name="brand_id"/>
|
||||
<field name="function_type"/>
|
||||
<field name="machine_tool_picture" widget="image"/>
|
||||
<field name="remark"/>
|
||||
</tree>
|
||||
@@ -122,6 +123,7 @@
|
||||
domain="[('tag_ids', '=', '机床')]"
|
||||
options="{'no_create': True}"/>
|
||||
<field name="machine_tool_category" required="1"/>
|
||||
<field name="function_type" required="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="machine_tool_picture" widget="image" nolabel="1"/>
|
||||
@@ -171,6 +173,10 @@
|
||||
<label for="workbench_W" string="宽"/>
|
||||
<field name="workbench_W" class="o_address_zip" required="1"
|
||||
options="{'format': false}"/>
|
||||
<span>&nbsp;</span>
|
||||
<label for="workbench_H" string="高"/>
|
||||
<field name="workbench_H" class="o_address_zip" required="1"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
<field name="workpiece_load"/>
|
||||
<label for="machine_tool_L" string="机床尺寸(mm)"/>
|
||||
@@ -237,15 +243,15 @@
|
||||
attrs="{'invisible': [('number_of_axles', '=', '三轴')]}"
|
||||
options="{'format': false}"/>
|
||||
<span>&nbsp;</span>
|
||||
<label for="b_axis" string="b"
|
||||
<label for="c_axis" string="c"
|
||||
attrs="{'invisible': [('number_of_axles', 'in', ['三轴','四轴'])]}"/>
|
||||
<field name="b_axis" class="o_address_zip"
|
||||
<field name="c_axis" class="o_address_zip"
|
||||
attrs="{'invisible': [('number_of_axles', 'in', ['三轴','四轴'])]}"
|
||||
options="{'format': false}"/>
|
||||
<span>&nbsp;</span>
|
||||
<label for="c_axis" string="c"
|
||||
<label for="b_axis" string="b"
|
||||
attrs="{'invisible': [('number_of_axles', 'in', ['三轴','四轴','五轴'])]}"/>
|
||||
<field name="c_axis" class="o_address_zip"
|
||||
<field name="b_axis" class="o_address_zip"
|
||||
attrs="{'invisible': [('number_of_axles', 'in', ['三轴','四轴','五轴'])]}"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!--表面工艺可选参数-->
|
||||
<record model="ir.ui.view" id="mrs_production_process_parameter_tree">
|
||||
<field name="model">sf.production.process.parameter</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="表面工艺可选参数" create="0" delete="0">
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
<field name="gain_way"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="mrs_production_process_parameter_form">
|
||||
<field name="model">sf.production.process.parameter</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="表面工艺可选参数" create="0" delete="0">
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="name" required="1" placeholder="名称"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="code" readonly="1"/>
|
||||
<field name="process_id" readonly="1"/>
|
||||
<field name="gain_way"/>
|
||||
</group>
|
||||
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="适用材料">
|
||||
<field name="materials_model_ids"></field>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="search_mrs_production_process_parameter_view">
|
||||
<field name="name">search.mrs.production.process.parameter</field>
|
||||
<field name="model">sf.production.process.parameter</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<filter name="filter_active" string="已归档" domain="[('active','=',False)]"/>
|
||||
<field name="name" string="名称" filter_domain="[('name','ilike',self)]"/>
|
||||
<field name="code" string="编码" filter_domain="[('codeNum','ilike',self)]"/>
|
||||
<searchpanel class="account_root">
|
||||
<field name="process_id" icon="fa-filter"/>
|
||||
</searchpanel>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--加工工艺-->
|
||||
<!-- <record model="ir.ui.view" id="sf_processing_technology_form">-->
|
||||
<!-- <field name="model">sf.processing.technology</field>-->
|
||||
@@ -20,26 +75,26 @@
|
||||
<!-- </form>-->
|
||||
<!-- </field>-->
|
||||
<!-- </record>-->
|
||||
<record model="ir.ui.view" id="sf_processing_technology_tree">
|
||||
<field name="model">sf.processing.technology</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="加工工艺" create="0" edit="0" delete="1">
|
||||
<field name="code"/>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="search_sf_processing_technology_view">
|
||||
<field name="name">search.sf.processing.technology.type</field>
|
||||
<field name="model">sf.processing.technology</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name" string="名称搜索" filter_domain="[('name','ilike',self)]"/>
|
||||
<field name="code" string="编码搜索" filter_domain="[('code','ilike',self)]"/>
|
||||
<filter name="filter_active" string="已归档" domain="[('active','=',False)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<!-- <record model="ir.ui.view" id="sf_processing_technology_tree">-->
|
||||
<!-- <field name="model">sf.processing.technology</field>-->
|
||||
<!-- <field name="arch" type="xml">-->
|
||||
<!-- <tree string="加工工艺" create="0" edit="0" delete="1">-->
|
||||
<!-- <field name="code"/>-->
|
||||
<!-- <field name="name"/>-->
|
||||
<!-- </tree>-->
|
||||
<!-- </field>-->
|
||||
<!-- </record>-->
|
||||
<!-- <record model="ir.ui.view" id="search_sf_processing_technology_view">-->
|
||||
<!-- <field name="name">search.sf.processing.technology.type</field>-->
|
||||
<!-- <field name="model">sf.processing.technology</field>-->
|
||||
<!-- <field name="arch" type="xml">-->
|
||||
<!-- <search>-->
|
||||
<!-- <field name="name" string="名称搜索" filter_domain="[('name','ilike',self)]"/>-->
|
||||
<!-- <field name="code" string="编码搜索" filter_domain="[('code','ilike',self)]"/>-->
|
||||
<!-- <filter name="filter_active" string="已归档" domain="[('active','=',False)]"/>-->
|
||||
<!-- </search>-->
|
||||
<!-- </field>-->
|
||||
<!-- </record>-->
|
||||
|
||||
<!--表面工艺类别-->
|
||||
<record model="ir.ui.view" id="sf_production_process_category_form">
|
||||
@@ -156,19 +211,7 @@
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="工序">
|
||||
<field name='processing_order_ids' options="{'no_create':True}" widget="one2many">
|
||||
<tree editable='bottom'>
|
||||
<field name="sequence" widget="handle"/>
|
||||
<field name="processing_technology_ids" widget="many2many_tags">
|
||||
</field>
|
||||
</tree>
|
||||
<form>
|
||||
<field name="processing_technology_ids" widget="many2many">
|
||||
</field>
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
|
||||
</notebook>
|
||||
</group>
|
||||
<group>
|
||||
@@ -188,6 +231,9 @@
|
||||
<field name="name" string="名称搜索" filter_domain="[('name','ilike',self)]"/>
|
||||
<field name="code" string="编码搜索" filter_domain="[('code','ilike',self)]"/>
|
||||
<filter name="filter_active" string="已归档" domain="[('active','=',False)]"/>
|
||||
<searchpanel>
|
||||
<field name="category_id" icon="fa-building" enable_counters="1"/>
|
||||
</searchpanel>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
@@ -223,7 +269,7 @@
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="供应商">
|
||||
<field name='supplier_ids'>
|
||||
<field name='supplier_ids' class="supplier_ids_set_css">
|
||||
<tree editable='bottom'>
|
||||
<field name="sequence" widget="handle" string="序号"/>
|
||||
<field name="partner_id" string="名称"/>
|
||||
@@ -241,7 +287,7 @@
|
||||
<record model="ir.ui.view" id="sf_materials_model_tree">
|
||||
<field name="model">sf.materials.model</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="材料型号" delete="0">
|
||||
<tree string="材料型号" delete="0">
|
||||
<field name="materials_no"/>
|
||||
<field name="materials_code"/>
|
||||
<field name="name"/>
|
||||
@@ -350,12 +396,12 @@
|
||||
<field name="res_model">sf.materials.model</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<record id="sf_processing_technology" model="ir.actions.act_window">
|
||||
<field name="name">加工工艺</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.processing.technology</field>
|
||||
<field name="view_mode">tree</field>
|
||||
</record>
|
||||
<!-- <record id="sf_processing_technology" model="ir.actions.act_window">-->
|
||||
<!-- <field name="name">加工工艺</field>-->
|
||||
<!-- <field name="type">ir.actions.act_window</field>-->
|
||||
<!-- <field name="res_model">sf.processing.technology</field>-->
|
||||
<!-- <field name="view_mode">tree</field>-->
|
||||
<!-- </record>-->
|
||||
|
||||
<record id="sf_production_process_category" model="ir.actions.act_window">
|
||||
<field name="name">表面工艺类别</field>
|
||||
@@ -363,6 +409,12 @@
|
||||
<field name="res_model">sf.production.process.category</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<record id="mrs_production_process_parameter_action" model="ir.actions.act_window">
|
||||
<field name="name">表面工艺可选参数</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.production.process.parameter</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
|
||||
|
||||
</data>
|
||||
|
||||
@@ -165,6 +165,7 @@
|
||||
<field name="zero_chuck_ids"
|
||||
attrs="{'invisible': [('fixture_material_type', '!=', '零点卡盘')]}">
|
||||
<tree editable="bottom" class="center" delete="0">
|
||||
<field name="code" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="length"/>
|
||||
<field name="width"/>
|
||||
@@ -190,6 +191,7 @@
|
||||
<field name="zero_tray_ids"
|
||||
attrs="{'invisible': [('fixture_material_type', '!=', '零点托盘')]}">
|
||||
<tree editable="bottom" class="center" delete="0">
|
||||
<field name="code" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="length"/>
|
||||
<field name="width"/>
|
||||
@@ -213,6 +215,7 @@
|
||||
<field name="pneumatic_fixture_ids"
|
||||
attrs="{'invisible': [('fixture_material_type', '!=', '气动夹具')]}">
|
||||
<tree editable="bottom" class="center" delete="0">
|
||||
<field name="code" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="length"/>
|
||||
<field name="width"/>
|
||||
@@ -240,6 +243,7 @@
|
||||
<field name="jaw_vice_fixture_ids"
|
||||
attrs="{'invisible': [('fixture_material_type', '!=', '虎钳夹具')]}">
|
||||
<tree editable="bottom" class="center" delete="0">
|
||||
<field name="code" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="length"/>
|
||||
<field name="width"/>
|
||||
@@ -268,6 +272,7 @@
|
||||
<field name="magnet_fixture_ids"
|
||||
attrs="{'invisible': [('fixture_material_type', '!=', '磁吸夹具')]}">
|
||||
<tree editable="bottom" class="center" delete="0">
|
||||
<field name="code" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="length"/>
|
||||
<field name="width"/>
|
||||
@@ -297,6 +302,7 @@
|
||||
<field name="adapter_board_fixture_ids"
|
||||
attrs="{'invisible': [('fixture_material_type', '!=', '转接板(锁板)夹具')]}">
|
||||
<tree editable="bottom" class="center" delete="0">
|
||||
<field name="code" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="length"/>
|
||||
<field name="width"/>
|
||||
@@ -323,6 +329,7 @@
|
||||
<field name="scroll_chuck_ids"
|
||||
attrs="{'invisible': [('fixture_material_type', '!=', '三爪卡盘')]}">
|
||||
<tree editable="bottom" class="center" delete="0">
|
||||
<field name="code" invisible="1"/>
|
||||
<field name="name"/>
|
||||
<field name="length"/>
|
||||
<field name="width"/>
|
||||
|
||||
@@ -111,13 +111,19 @@
|
||||
|
||||
/>
|
||||
|
||||
|
||||
<menuitem
|
||||
id="menu_sf_processing_technology"
|
||||
name="加工工艺"
|
||||
<menuitem
|
||||
id="mrs_production_process_parameter_view"
|
||||
name="表面工艺可选参数"
|
||||
parent="menu_sf_production_process_1"
|
||||
sequence="3"
|
||||
action="sf_processing_technology"/>
|
||||
sequence="2"
|
||||
action="mrs_production_process_parameter_action"
|
||||
/>
|
||||
<!-- <menuitem-->
|
||||
<!-- id="menu_sf_processing_technology"-->
|
||||
<!-- name="加工工艺"-->
|
||||
<!-- parent="menu_sf_production_process_1"-->
|
||||
<!-- sequence="3"-->
|
||||
<!-- action="sf_processing_technology"/>-->
|
||||
|
||||
<!-- <menuitem-->
|
||||
<!-- id="menu_sf_partner_views"-->
|
||||
@@ -143,5 +149,6 @@
|
||||
sequence="1"
|
||||
action="action_sf_machine_control_system"/>
|
||||
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,132 +1,302 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<!-- ================================================刀具基础参数================================================ -->
|
||||
<record id="view_sf_tool_materials_basic_parameters_integral_tree" model="ir.ui.view">
|
||||
<field name="name">sf.tool.materials.basic.parameters.tree</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="基础参数" delete="0" create="0" edit="0" sample="1">
|
||||
<field name="total_length" />
|
||||
<field name="blade_number" />
|
||||
<field name="neck_diameter"/>
|
||||
<field name="neck_length"/>
|
||||
<field name="handle_diameter" />
|
||||
<field name="handle_length" />
|
||||
<field name="blade_tip_diameter"/>
|
||||
<field name="blade_tip_working_size"/>
|
||||
<field name="blade_tip_taper" />
|
||||
<field name="blade_diameter" />
|
||||
<field name="blade_length"/>
|
||||
<field name="blade_helix_angle"/>
|
||||
<field name="blade_width" />
|
||||
<field name="blade_width" />
|
||||
<field name="pitch"/>
|
||||
<field name="cutting_depth"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<!-- ================================================刀具基础参数================================================ -->
|
||||
<record id="view_sf_tool_materials_basic_parameters_integral_tree" model="ir.ui.view">
|
||||
<field name="name">sf.tool.materials.basic.parameters.tree</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="基础参数" delete="0" create="0" edit="0" sample="1">
|
||||
<field name="total_length"/>
|
||||
<field name="blade_number"/>
|
||||
<field name="neck_diameter"/>
|
||||
<field name="neck_length"/>
|
||||
<field name="handle_diameter"/>
|
||||
<field name="handle_length"/>
|
||||
<field name="blade_tip_diameter"/>
|
||||
<field name="blade_tip_working_size"/>
|
||||
<field name="blade_tip_taper"/>
|
||||
<field name="blade_diameter"/>
|
||||
<field name="blade_length"/>
|
||||
<field name="blade_helix_angle"/>
|
||||
<field name="blade_width"/>
|
||||
<field name="blade_width"/>
|
||||
<field name="pitch"/>
|
||||
<field name="cutting_depth"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_sf_tool_materials_basic_parameters_blade_tree" model="ir.ui.view">
|
||||
<field name="name">sf.tool.materials.basic.parameters.tree</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="基础参数" delete="0" create="0">
|
||||
<field name="total_length" />
|
||||
<field name="length" />
|
||||
<field name="thickness"/>
|
||||
<field name="width"/>
|
||||
<field name="cutting_blade_length" />
|
||||
<field name="relief_angle" />
|
||||
<field name="blade_tip_circular_arc_radius"/>
|
||||
<field name="inscribed_circle_diameter"/>
|
||||
<field name="install_aperture_diameter" />
|
||||
<field name="chip_breaker_groove" />
|
||||
<field name="blade_teeth_model"/>
|
||||
<field name="blade_blade_number"/>
|
||||
<field name="main_included_angle" />
|
||||
<field name="top_angle" />
|
||||
<field name="thread_model"/>
|
||||
<field name="thread_num" />
|
||||
<field name="blade_tip_height_tolerance" />
|
||||
<field name="inscribed_circle_tolerance"/>
|
||||
<field name="thickness_tolerance"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="view_sf_tool_materials_basic_parameters_blade_tree" model="ir.ui.view">
|
||||
<field name="name">sf.tool.materials.basic.parameters.tree</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="基础参数" delete="0" create="0">
|
||||
<field name="total_length"/>
|
||||
<field name="length"/>
|
||||
<field name="thickness"/>
|
||||
<field name="width"/>
|
||||
<field name="cutting_blade_length"/>
|
||||
<field name="relief_angle"/>
|
||||
<field name="blade_tip_circular_arc_radius"/>
|
||||
<field name="inscribed_circle_diameter"/>
|
||||
<field name="install_aperture_diameter"/>
|
||||
<field name="chip_breaker_groove"/>
|
||||
<field name="blade_teeth_model"/>
|
||||
<field name="blade_blade_number"/>
|
||||
<field name="main_included_angle"/>
|
||||
<field name="top_angle"/>
|
||||
<field name="thread_model"/>
|
||||
<field name="thread_num"/>
|
||||
<field name="blade_tip_height_tolerance"/>
|
||||
<field name="inscribed_circle_tolerance"/>
|
||||
<field name="thickness_tolerance"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_sf_tool_materials_basic_parameters_cutter_bar_tree" model="ir.ui.view">
|
||||
<field name="name">sf.tool.materials.basic.parameters.tree</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="基础参数" delete="0" create="0">
|
||||
<field name="total_length" />
|
||||
<field name="height" />
|
||||
<field name="blade_height"/>
|
||||
<field name="cut_depth_max"/>
|
||||
<field name="cutter_arbor_diameter" />
|
||||
<field name="min_machining_aperture" />
|
||||
<field name="install_blade_tip_num"/>
|
||||
<field name="cutting_blade_model"/>
|
||||
<field name="is_cooling_hole" />
|
||||
<field name="locating_slot_code" />
|
||||
<field name="installing_structure"/>
|
||||
<field name="blade_id"/>
|
||||
<field name="tool_shim" />
|
||||
<field name="cotter_pin" />
|
||||
<field name="pressing_plate"/>
|
||||
<field name="screw"/>
|
||||
<field name="spanner" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<field name="name">sf.tool.materials.basic.parameters.tree</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="基础参数" delete="0" create="0">
|
||||
<field name="total_length"/>
|
||||
<field name="height"/>
|
||||
<field name="blade_height"/>
|
||||
<field name="cut_depth_max"/>
|
||||
<field name="cutter_arbor_diameter"/>
|
||||
<field name="min_machining_aperture"/>
|
||||
<field name="install_blade_tip_num"/>
|
||||
<field name="cutting_blade_model"/>
|
||||
<field name="is_cooling_hole"/>
|
||||
<field name="locating_slot_code"/>
|
||||
<field name="installing_structure"/>
|
||||
<field name="blade_id"/>
|
||||
<field name="tool_shim"/>
|
||||
<field name="cotter_pin"/>
|
||||
<field name="pressing_plate"/>
|
||||
<field name="screw"/>
|
||||
<field name="spanner"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record id="view_sf_tool_materials_basic_parameters_tree" model="ir.ui.view">
|
||||
<field name="name">sf.tool.materials.basic.parameters.tree</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="基础参数" >
|
||||
<field name="total_length" />
|
||||
<field name="blade_number" />
|
||||
<field name="neck_diameter"/>
|
||||
<field name="neck_length"/>
|
||||
<field name="handle_diameter" />
|
||||
<field name="handle_length" />
|
||||
<field name="blade_tip_diameter"/>
|
||||
<field name="blade_tip_working_size"/>
|
||||
<field name="blade_tip_taper" />
|
||||
<field name="blade_diameter" />
|
||||
<field name="blade_length"/>
|
||||
<field name="blade_helix_angle"/>
|
||||
<field name="blade_width" />
|
||||
<field name="blade_width" />
|
||||
<field name="pitch"/>
|
||||
<field name="cutting_depth"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<field name="name">sf.tool.materials.basic.parameters.tree</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="基础参数">
|
||||
<field name="total_length"/>
|
||||
<field name="blade_number"/>
|
||||
<field name="neck_diameter"/>
|
||||
<field name="neck_length"/>
|
||||
<field name="handle_diameter"/>
|
||||
<field name="handle_length"/>
|
||||
<field name="blade_tip_diameter"/>
|
||||
<field name="blade_tip_working_size"/>
|
||||
<field name="blade_tip_taper"/>
|
||||
<field name="blade_diameter"/>
|
||||
<field name="blade_length"/>
|
||||
<field name="blade_helix_angle"/>
|
||||
<field name="blade_width"/>
|
||||
<field name="blade_width"/>
|
||||
<field name="pitch"/>
|
||||
<field name="cutting_depth"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_sf_tool_materials_basic_parameters_search">
|
||||
<field name="name">sf.tool.materials.basic.parameters.search</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.ui.view" id="view_sf_tool_materials_basic_parameters_search">
|
||||
<field name="name">sf.tool.materials.basic.parameters.search</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_sf_tool_materials_basic_parameters" model="ir.actions.act_window">
|
||||
<field name="name">基础参数</field>
|
||||
<field name="res_model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<record id="view_sf_tool_materials_basic_parameters_form" model="ir.ui.view">
|
||||
<field name="name">sf.tool.materials.basic.parameters.form</field>
|
||||
<field name="model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="规则">
|
||||
<sheet>
|
||||
<field name="cutting_tool_type" invisible="1"/>
|
||||
<field name="standard_library_id" invisible="1"/>
|
||||
<group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}">
|
||||
<field name="total_length"/>
|
||||
<field name="blade_diameter" class="diameter"/>
|
||||
<field name="blade_length"/>
|
||||
<field name="blade_number"/>
|
||||
<field name="neck_length"/>
|
||||
<field name="neck_diameter" class="diameter"/>
|
||||
<field name="handle_diameter" class="diameter"/>
|
||||
<field name="handle_length"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}">
|
||||
<field name="blade_tip_working_size"/>
|
||||
<field name="blade_tip_diameter" class="diameter"/>
|
||||
<field name="blade_tip_taper"/>
|
||||
<field name="blade_helix_angle"/>
|
||||
<field name="pitch"/>
|
||||
<field name="blade_width"/>
|
||||
<field name="blade_depth"/>
|
||||
<field name="cut_depth_max"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}">
|
||||
<field name="length"/>
|
||||
<field name="thickness"/>
|
||||
<field name="inscribed_circle_diameter" class="diameter"/>
|
||||
<field name="install_aperture_diameter" class="diameter" string="安装孔直径D1(mm)"/>
|
||||
<field name="blade_tip_circular_arc_radius" string="刀尖圆弧半径RE(mm)"/>
|
||||
<field name="cutting_blade_length"/>
|
||||
<field name="relief_angle"/>
|
||||
<field name="chip_breaker_groove"/>
|
||||
<field name="chip_breaker_type_code"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}">
|
||||
<field name="blade_teeth_model"/>
|
||||
<field name="thread_model"/>
|
||||
<field name="pitch"/>
|
||||
<field name="thread_num"/>
|
||||
<field name="cut_depth_max"/>
|
||||
<field name="blade_blade_number" string="刃数"/>
|
||||
<field name="blade_width" string="刃宽"/>
|
||||
<field name="main_included_angle"/>
|
||||
<field name="top_angle"/>
|
||||
<field name="blade_tip_height_tolerance"/>
|
||||
<field name="inscribed_circle_tolerance"/>
|
||||
<field name="thickness_tolerance"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}">
|
||||
<field name="total_length"/>
|
||||
<field name="width"/>
|
||||
<field name="height"/>
|
||||
<label for="knife_head_length" string="刀头尺寸"/>
|
||||
<div class="test_model">
|
||||
<label for="knife_head_length" string="长"/>
|
||||
<field name="knife_head_length" class="o_address_zip"
|
||||
options="{'format': false}"/>
|
||||
<label for="knife_head_width" string="宽"/>
|
||||
<field name="knife_head_width" class="o_address_zip"
|
||||
options="{'format': false}"/>
|
||||
<label for="knife_head_height" string="高"/>
|
||||
<field name="knife_head_height" class="o_address_zip"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
<field name="blade_diameter" class="diameter"/>
|
||||
<field name="cutter_arbor_diameter" class="diameter"/>
|
||||
<field name="is_cooling_hole"/>
|
||||
<field name="locating_slot_code"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}">
|
||||
<field name="main_included_angle"/>
|
||||
<field name="relief_angle"/>
|
||||
<field name="cutting_blade_length"/>
|
||||
<field name="cut_depth_max"/>
|
||||
<field name="min_machining_aperture"/>
|
||||
<field name="install_blade_tip_num"/>
|
||||
<field name="installing_structure"/>
|
||||
<field name="blade_id" options="{'no_create': True}"/>
|
||||
<field name="tool_shim"/>
|
||||
<field name="cotter_pin"/>
|
||||
<field name="pressing_plate"/>
|
||||
<field name="screw"/>
|
||||
<field name="spanner"/>
|
||||
</group>
|
||||
|
||||
<!-- <field name="context">{'selection_mode': 'single'}</field>-->
|
||||
<field name="domain">[]</field>
|
||||
<!-- <field name="multi">false</field>-->
|
||||
</record>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')]}">
|
||||
<field name="install_blade_tip_num"/>
|
||||
<field name="blade_diameter" class="diameter"/>
|
||||
<field name="cutter_head_diameter" class="diameter"/>
|
||||
<field name="interface_diameter" class="diameter"/>
|
||||
<field name="total_length"/>
|
||||
<field name="blade_length"/>
|
||||
<field name="cutting_blade_length"/>
|
||||
<field name="cut_depth_max"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')]}">
|
||||
<field name="main_included_angle"/>
|
||||
<field name="installing_structure"/>
|
||||
<field name="blade_id" options="{'no_create': True}"/>
|
||||
<field name="screw"/>
|
||||
<field name="spanner"/>
|
||||
<field name="is_cooling_hole"/>
|
||||
<field name="locating_slot_code"/>
|
||||
</group>
|
||||
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}">
|
||||
<field name="er_size_model" string="尺寸型号"/>
|
||||
<label for="min_clamping_diameter" string="夹持直径"/>
|
||||
<div class="test_model">
|
||||
<label for="min_clamping_diameter" string="最小"/>
|
||||
<field name="min_clamping_diameter" class="o_address_zip diameter"
|
||||
options="{'format': false}"/>
|
||||
<label for="max_clamping_diameter" string="最大"/>
|
||||
<field name="max_clamping_diameter" class="o_address_zip diameter"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
<field name="total_length"/>
|
||||
<field name="outer_diameter" class="diameter"/>
|
||||
<field name="inner_diameter" class="diameter"/>
|
||||
<field name="taper"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}">
|
||||
<field name="run_out_accuracy"/>
|
||||
<field name="top_diameter" class="diameter"/>
|
||||
<field name="weight"/>
|
||||
<field name="max_load_capacity"/>
|
||||
<field name="cooling_jacket"/>
|
||||
</group>
|
||||
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}">
|
||||
<field name="taper_shank_model"/>
|
||||
<field name="total_length"/>
|
||||
<field name="shank_length"/>
|
||||
<field name="shank_diameter" class="diameter"/>
|
||||
<field name="flange_shank_length"/>
|
||||
<field name="flange_diameter" class="diameter"/>
|
||||
<field name="diameter_slip_accuracy"/>
|
||||
<field name="dynamic_balance_class"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}">
|
||||
<label for="min_clamping_diameter" string="夹持直径"/>
|
||||
<div class="test_model">
|
||||
<label for="min_clamping_diameter" string="最小"/>
|
||||
<field name="min_clamping_diameter" class="o_address_zip diameter"
|
||||
options="{'format': false}"/>
|
||||
<label for="max_clamping_diameter" string="最大"/>
|
||||
<field name="max_clamping_diameter" class="o_address_zip diameter"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
<field name="max_rotate_speed"/>
|
||||
<field name="fit_chuck_size"/>
|
||||
<field name="nut"/>
|
||||
<field name="spanner"/>
|
||||
<field name="clamping_mode"/>
|
||||
<field name="tool_changing_time"/>
|
||||
<field name="cooling_model"/>
|
||||
<field name="is_quick_cutting"/>
|
||||
<field name="is_safe_lock"/>
|
||||
</group>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_sf_tool_materials_basic_parameters" model="ir.actions.act_window">
|
||||
<field name="name">基础参数</field>
|
||||
<field name="res_model">sf.tool.materials.basic.parameters</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="context">{'default_cutting_tool_type': cutting_tool_type}</field>
|
||||
<field name="domain">[]</field>
|
||||
<!-- <field name="multi">false</field>-->
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
<field name="name">刀具标准库</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.cutting_tool.standard.library</field>
|
||||
<!-- <field name="context">{'default_cutting_tool_material_id': cutting_tool_material_id}</field>-->
|
||||
<field name="view_mode">tree,form</field>
|
||||
</record>
|
||||
<!-- 功能刀具action -->
|
||||
@@ -58,46 +59,54 @@
|
||||
id="menu_sf_cutting_tool_type"
|
||||
parent="menu_sf_cutting_tool"
|
||||
name="刀具类型"
|
||||
sequence="2"
|
||||
sequence="10"
|
||||
action="action_sf_cutting_tool_type"
|
||||
/>
|
||||
<menuitem
|
||||
id="menu_sf_cutting_tool_standard_library"
|
||||
parent="menu_sf_cutting_tool"
|
||||
name="刀具标准库"
|
||||
sequence="3"
|
||||
sequence="20"
|
||||
action="action_sf_cutting_tool_standard_library"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_sf_tool_inventory"
|
||||
parent="menu_sf_cutting_tool"
|
||||
name="功能刀具清单"
|
||||
sequence="25"
|
||||
action="action_sf_tool_inventory"
|
||||
/>
|
||||
<!-- 功能刀具 -->
|
||||
<!-- <menuitem-->
|
||||
<!-- id="menu_sf_functional_cutting_tool"-->
|
||||
<!-- parent="menu_sf_cutting_tool"-->
|
||||
<!-- name="功能刀具"-->
|
||||
<!-- sequence="5"-->
|
||||
<!-- action="action_sf_functional_cutting_tool"-->
|
||||
<!-- />-->
|
||||
<!-- <menuitem-->
|
||||
<!-- id="menu_sf_functional_cutting_tool"-->
|
||||
<!-- parent="menu_sf_cutting_tool"-->
|
||||
<!-- name="功能刀具"-->
|
||||
<!-- sequence="5"-->
|
||||
<!-- action="action_sf_functional_cutting_tool"-->
|
||||
<!-- />-->
|
||||
<!-- 功能刀具类型 -->
|
||||
<menuitem
|
||||
id="menu_sf_functional_cutting_tool_model_type"
|
||||
parent="menu_sf_cutting_tool"
|
||||
name="功能刀具类型"
|
||||
sequence="4"
|
||||
sequence="30"
|
||||
action="action_sf_functional_cutting_tool_model_type"
|
||||
/>
|
||||
|
||||
<menuitem
|
||||
id="menu_sf_maintenance_equipment_image"
|
||||
name="能力特征库"
|
||||
parent="menu_sf_cutting_tool"
|
||||
action="action_maintenance_equipment_image"
|
||||
sequence="5"/>
|
||||
id="menu_sf_maintenance_equipment_image"
|
||||
name="能力特征库"
|
||||
parent="menu_sf_cutting_tool"
|
||||
action="action_maintenance_equipment_image"
|
||||
sequence="40"/>
|
||||
|
||||
<menuitem
|
||||
id="menu_sf_tool_groups"
|
||||
name="刀具组"
|
||||
parent="menu_sf_cutting_tool"
|
||||
action="sf_tool_groups_view_act"
|
||||
sequence="10"/>
|
||||
id="menu_sf_tool_groups"
|
||||
name="刀具组"
|
||||
parent="menu_sf_cutting_tool"
|
||||
action="sf_tool_groups_view_act"
|
||||
sequence="50"/>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -123,19 +123,19 @@
|
||||
<form string="刀具标准库" delete="0" create="0" edit="0">
|
||||
<sheet>
|
||||
<field name="image" widget='image' class="oe_avatar"
|
||||
options="{'zoom': true, 'preview_image':'image_128'}"/>
|
||||
required="1"/>
|
||||
<div class="oe_title">
|
||||
<h1>
|
||||
<field name="code"/>
|
||||
<field name="code" readonly="1" force_save="1"/>
|
||||
</h1>
|
||||
</div>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name"/>
|
||||
<field name="cutting_tool_material_id"/>
|
||||
<field name="cutting_tool_type"/>
|
||||
<field name="cutting_tool_type_id"/>
|
||||
<field name="brand_id"/>
|
||||
<field name="cutting_tool_material_id" readonly="1"/>
|
||||
<field name="cutting_tool_type" invisible="1"/>
|
||||
<field name="cutting_tool_type_id" required="1"/>
|
||||
<field name="brand_id" required="1"/>
|
||||
<label for="integral_run_out_accuracy_min" string="端跳精度"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<div class="o_address_format"
|
||||
@@ -165,8 +165,7 @@
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="material_model_id" placeholder="请选择" string="材质"
|
||||
attrs="{'required': [('cutting_tool_type', 'not in', ['刀柄', '夹头'])]}"/>
|
||||
<field name="material_model_id" placeholder="请选择" string="材质"/>
|
||||
<field name="tool_hardness" string="硬度(hrc)" options="{'format': false}"
|
||||
widget="integer"/>
|
||||
<field name="coating_material"/>
|
||||
@@ -505,11 +504,23 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sf_tool_groups_search" model="ir.ui.view">
|
||||
<field name="name">刀具组搜索</field>
|
||||
<field name="model">sf.tool.groups</field>
|
||||
<field name="arch" type="xml">
|
||||
<search>
|
||||
<field name="name"/>
|
||||
<field name="equipment_ids"/>
|
||||
<filter string="已归档" name="inactive" domain="[('active', '=', False)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="sf_tool_groups_view_act" model="ir.actions.act_window">
|
||||
<field name="name">刀具组</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.tool.groups</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="view_mode">tree,search</field>
|
||||
</record>
|
||||
|
||||
<!-- ================================================刀具基础参数================================================ -->
|
||||
@@ -536,7 +547,66 @@
|
||||
<!-- <field name="cutting_depth"/>-->
|
||||
<!-- </tree>-->
|
||||
<!-- </field>-->
|
||||
<!-- </record>-->
|
||||
<!-- </record>-->'
|
||||
|
||||
<!-- ================================================功能刀具清单================================================ -->
|
||||
<record id="view_tool_inventory_tree" model="ir.ui.view">
|
||||
<field name="name">sf.tool.inventory.tree</field>
|
||||
<field name="model">sf.tool.inventory</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="功能刀具清单" create="1" edit="1" delete="0" editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="functional_cutting_tool_model_id"/>
|
||||
<field name="tool_groups_id"/>
|
||||
<field name="work_material"/>
|
||||
<field name="life_span"/>
|
||||
<field name="prefix" optional="hide"/>
|
||||
<field name="postfix" optional="hide"/>
|
||||
<field name="diameter"/>
|
||||
<field name="angle"/>
|
||||
<field name="tool_length"/>
|
||||
<field name="blade_length"/>
|
||||
<field name="knife_head_name" optional="hide"/>
|
||||
<field name="cutter_number"/>
|
||||
<field name="blade_number"/>
|
||||
<field name="extension"/>
|
||||
<field name="create_uid" string="创建人" optional="hide"/>
|
||||
<field name="create_date" string="创建时间" optional="hide"/>
|
||||
<field name="type" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_cutting_tool_material_search">
|
||||
<field name="name">sf.tool.inventory.search</field>
|
||||
<field name="model">sf.tool.inventory</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="功能刀具清单">
|
||||
<field name="name" string="名称搜索" filter_domain="[('name','ilike',self)]"/>
|
||||
<field name="functional_cutting_tool_model_id"/>
|
||||
<field name="tool_groups_id"/>
|
||||
<field name="work_material"/>
|
||||
<field name="life_span"/>
|
||||
<field name="prefix"/>
|
||||
<field name="postfix"/>
|
||||
<field name="diameter"/>
|
||||
<field name="angle"/>
|
||||
<field name="tool_length"/>
|
||||
<field name="blade_length"/>
|
||||
<field name="knife_head_name"/>
|
||||
<field name="cutter_number"/>
|
||||
<field name="blade_number"/>
|
||||
<field name="extension"/>
|
||||
<filter name="filter_active" string="已归档" domain="[('active','=',False)]"/>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_sf_tool_inventory" model="ir.actions.act_window">
|
||||
<field name="name">功能刀具清单</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">sf.tool.inventory</field>
|
||||
<field name="view_mode">tree</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
@@ -16,7 +16,7 @@ class Sf_Bf_Connect(http.Controller):
|
||||
:return:
|
||||
"""
|
||||
res = {'status': 1, 'factory_order_no': ''}
|
||||
logging.info('get_bfm_process_order_list:%s' % kw)
|
||||
logging.info('get_bfm_process_order_list:%s' % kw['order_number'])
|
||||
try:
|
||||
product_id = request.env.ref('sf_dlm.product_template_sf').sudo()
|
||||
self_machining_id = request.env.ref('sf_dlm.product_embryo_sf_self_machining').sudo()
|
||||
@@ -52,7 +52,7 @@ class Sf_Bf_Connect(http.Controller):
|
||||
self_machining_embryo = request.env['product.template'].sudo().no_bom_product_create(
|
||||
self_machining_id,
|
||||
item,
|
||||
order_id, 'self_machining', i)
|
||||
order_id, 'self_machining', i, product)
|
||||
# 创建坯料的bom
|
||||
self_machining_bom = request.env['mrp.bom'].with_user(
|
||||
request.env.ref("base.user_admin")).bom_create(
|
||||
@@ -62,7 +62,7 @@ class Sf_Bf_Connect(http.Controller):
|
||||
request.env.ref("base.user_admin")).bom_create_line(
|
||||
self_machining_embryo)
|
||||
if not self_machining_bom_line:
|
||||
res['status'] = 2
|
||||
res['status'] = -2
|
||||
res['message'] = '该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配'
|
||||
request.cr.rollback()
|
||||
return json.JSONEncoder().encode(res)
|
||||
@@ -78,7 +78,12 @@ class Sf_Bf_Connect(http.Controller):
|
||||
item,
|
||||
order_id,
|
||||
'subcontract',
|
||||
i)
|
||||
i, product)
|
||||
if outsource_embryo == -3:
|
||||
res['status'] = -3
|
||||
res['message'] = '该订单模型的材料型号在您分配的工厂里暂未设置获取方式和供应商,请先配置再进行分配'
|
||||
request.cr.rollback()
|
||||
return json.JSONEncoder().encode(res)
|
||||
# 创建坯料的bom
|
||||
outsource_bom = request.env['mrp.bom'].with_user(request.env.ref("base.user_admin")).bom_create(
|
||||
outsource_embryo,
|
||||
@@ -87,7 +92,7 @@ class Sf_Bf_Connect(http.Controller):
|
||||
outsource_bom_line = outsource_bom.with_user(
|
||||
request.env.ref("base.user_admin")).bom_create_line(outsource_embryo)
|
||||
if not outsource_bom_line:
|
||||
res['status'] = 2
|
||||
res['status'] = -2
|
||||
res['message'] = '该订单模型的材料型号在您分配的工厂里暂未有原材料,请先配置再进行分配'
|
||||
request.cr.rollback()
|
||||
return json.JSONEncoder().encode(res)
|
||||
@@ -100,12 +105,19 @@ class Sf_Bf_Connect(http.Controller):
|
||||
purchase_embryo = request.env['product.template'].sudo().no_bom_product_create(purchase_id,
|
||||
item,
|
||||
order_id,
|
||||
'purchase', i)
|
||||
# 产品配置bom
|
||||
product_bom_purchase = request.env['mrp.bom'].with_user(
|
||||
request.env.ref("base.user_admin")).bom_create(product, 'normal', False)
|
||||
product_bom_purchase.with_user(request.env.ref("base.user_admin")).bom_create_line_has(
|
||||
purchase_embryo)
|
||||
'purchase', i,
|
||||
product)
|
||||
if purchase_embryo == -3:
|
||||
res['status'] = -3
|
||||
res['message'] = '该订单模型的材料型号在您分配的工厂里暂未设置获取方式和供应商,请先配置再进行分配'
|
||||
request.cr.rollback()
|
||||
return json.JSONEncoder().encode(res)
|
||||
else:
|
||||
# 产品配置bom
|
||||
product_bom_purchase = request.env['mrp.bom'].with_user(
|
||||
request.env.ref("base.user_admin")).bom_create(product, 'normal', False)
|
||||
product_bom_purchase.with_user(request.env.ref("base.user_admin")).bom_create_line_has(
|
||||
purchase_embryo)
|
||||
order_id.with_user(request.env.ref("base.user_admin")).sale_order_create_line(product, item)
|
||||
i += 1
|
||||
res['factory_order_no'] = order_id.name
|
||||
@@ -143,3 +155,17 @@ class jdElcp(http.Controller):
|
||||
aa.bill_url = kw['bill']
|
||||
logging.info('get_jd_bill================:%s' %
|
||||
aa.bill_url)
|
||||
|
||||
@http.route('/api/update/order/status', type='http', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def update_order_status(self, **kw):
|
||||
"""
|
||||
根据拿到的商家单号,修改订单状态
|
||||
"""
|
||||
logging.info('change_sale_order_state================:%s', kw)
|
||||
if not kw.get('orderNo'):
|
||||
return json.dumps({'statusCode': 415, 'statusMessage': '订单号不能为空'}, ensure_ascii=False)
|
||||
aa = request.env['sale.order'].sudo().search([('name', '=', kw['orderNo'])])
|
||||
if aa:
|
||||
# aa.schedule_status = 'received'
|
||||
return json.dumps({'statusCode': 200, 'statusMessage': '修改成功'}, ensure_ascii=False)
|
||||
|
||||
@@ -21,7 +21,6 @@ class Http(models.AbstractModel):
|
||||
def _auth_method_sf_token(cls):
|
||||
# 从headers.environ中获取对方传过来的token,timestamp,加密的校验字符串
|
||||
datas = request.httprequest.headers.environ
|
||||
logging.info(datas)
|
||||
if 'HTTP_TOKEN' in datas:
|
||||
_logger.info('token:%s' % datas['HTTP_TOKEN'])
|
||||
# 查询密钥
|
||||
@@ -41,7 +40,11 @@ class Http(models.AbstractModel):
|
||||
raise AuthenticationError('请求已过期')
|
||||
check_str = '%s%s%s' % (datas['HTTP_TOKEN'], post_time, factory_secret.sf_secret_key)
|
||||
check_sf_str = hashlib.sha1(check_str.encode('utf-8')).hexdigest()
|
||||
_logger.info('check_str:%s' % check_sf_str)
|
||||
_logger.info('HTTP_TIMESTAMP:%s' % post_time)
|
||||
_logger.info('HTTP_CHECKSTR:%s' % datas['HTTP_CHECKSTR'])
|
||||
_logger.info('check_sf_str:%s' % check_sf_str)
|
||||
_logger.info('check_str:%s' % check_str)
|
||||
_logger.info('sf_secret_key:%s' % factory_secret.sf_secret_key)
|
||||
if check_sf_str != datas['HTTP_CHECKSTR']:
|
||||
raise AuthenticationError('数据校验不通过')
|
||||
else:
|
||||
|
||||
@@ -56,7 +56,7 @@ class JdEclp(models.Model):
|
||||
"""
|
||||
res = super(JdEclp, self).button_validate()
|
||||
if self.check_out == 'OUT':
|
||||
if self.logistics_way != '自提':
|
||||
if self.logistics_way != '自提' and self.logistics_way:
|
||||
if self.logistics_status != '2':
|
||||
raise ValidationError('非自提订单,必须先下物流单,并获取物流面单后才可出库!')
|
||||
return res
|
||||
@@ -164,6 +164,9 @@ class JdEclp(models.Model):
|
||||
self.is_bill = True
|
||||
self.logistics_status = '1'
|
||||
|
||||
# # 京东物流下单后,销售订单状态改为待收货
|
||||
# self.env['sale.order'].search([('name', '=', self.origin)]).write({'scheduled_status': 'to receive'})
|
||||
|
||||
# else:
|
||||
# raise UserError("选择京东物流才能下单呦")
|
||||
|
||||
|
||||
@@ -35,14 +35,14 @@
|
||||
<field name="type">功能刀具</field>
|
||||
</record>
|
||||
|
||||
<!-- <record id="res_partner_bfm" model="res.partner">-->
|
||||
<!-- <field name="name">业务平台</field>-->
|
||||
<!-- <!– <field name="company_id" ref="base.main_company"/>–>-->
|
||||
<!-- </record>-->
|
||||
<record id="res_partner_bfm" model="res.partner">
|
||||
<field name="name">业务平台</field>
|
||||
<!-- <field name="company_id" ref="base.main_company"/>-->
|
||||
</record>
|
||||
|
||||
<!-- <record id="res_users_bfm" model="res.users">-->
|
||||
<!-- <field name="name">业务平台</field>-->
|
||||
<!-- <field name="partner_id" ref="res_partner_bfm"/>-->
|
||||
<!--<!– <field name="partner_id" ref="res_partner_bfm"/>–>-->
|
||||
<!-- </record>-->
|
||||
|
||||
<record id="product_functional_tool_sf" model="product.product">
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo import models, fields
|
||||
import logging
|
||||
|
||||
import re
|
||||
from odoo import models, fields, api
|
||||
|
||||
|
||||
class ResProductCategory(models.Model):
|
||||
@@ -28,6 +31,20 @@ class ResMrpBomMo(models.Model):
|
||||
_inherit = 'mrp.bom'
|
||||
|
||||
subcontractor_id = fields.Many2one('res.partner', string='外包商')
|
||||
subcontractor_name = fields.Char('', compute='_compute_subcontractor_ids', store=True)
|
||||
|
||||
@api.depends('subcontractor_id')
|
||||
def _compute_subcontractor_ids(self):
|
||||
for item in self:
|
||||
if item.subcontractor_id:
|
||||
logging.info("subcontractor_ids: %s" % item.subcontractor_ids.ids)
|
||||
subcontractor_id = int(re.sub(r"\D", "", str(item.subcontractor_id.id)))
|
||||
item.subcontractor_ids = [subcontractor_id]
|
||||
item.subcontractor_name = item.subcontractor_id.name
|
||||
logging.info("subcontractor_ids: %s" % item.subcontractor_ids.ids)
|
||||
else:
|
||||
item.subcontractor_ids = []
|
||||
item.subcontractor_name = ''
|
||||
|
||||
def bom_create_line_has(self, embryo):
|
||||
vals = {
|
||||
@@ -37,7 +54,7 @@ class ResMrpBomMo(models.Model):
|
||||
'product_qty': 1,
|
||||
'product_uom_id': 1
|
||||
}
|
||||
return self.env['mrp.bom.line'].create(vals)
|
||||
return self.env['mrp.bom.line'].sudo().create(vals)
|
||||
|
||||
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品后再次进行创建bom
|
||||
def bom_create(self, product, bom_type, product_type):
|
||||
@@ -64,7 +81,7 @@ class ResMrpBomMo(models.Model):
|
||||
qty = 1
|
||||
if round(embryo.volume * raw_bom_line.materials_type_id.density / 1000000) > 1:
|
||||
qty = round(embryo.volume * raw_bom_line.materials_type_id.density / 1000000)
|
||||
bom_line = self.env['mrp.bom.line'].create({
|
||||
bom_line = self.env['mrp.bom.line'].sudo().create({
|
||||
'bom_id': self.id,
|
||||
'product_id': raw_bom_line.id,
|
||||
'product_tmpl_id': raw_bom_line.product_tmpl_id.id,
|
||||
@@ -100,7 +117,7 @@ class ResMrpBomMo(models.Model):
|
||||
if rate_of_waste <= 20:
|
||||
return embryo_has
|
||||
else:
|
||||
return
|
||||
return None
|
||||
|
||||
# 查bom的原材料
|
||||
def get_raw_bom(self, product):
|
||||
|
||||
292
sf_dlm/models/product_template.py
Normal file
@@ -0,0 +1,292 @@
|
||||
from odoo import models, fields
|
||||
import logging
|
||||
import base64
|
||||
|
||||
|
||||
class ResProductTemplate(models.Model):
|
||||
_inherit = 'product.template'
|
||||
|
||||
# 模型的长,宽,高,体积,精度,材料
|
||||
model_name = fields.Char('模型名称')
|
||||
categ_type = fields.Selection(
|
||||
[("成品", "成品"), ("胚料", "胚料"), ("原材料", "原材料")], string='产品的类别', related='categ_id.type', store=True)
|
||||
model_long = fields.Float('模型长[mm]', digits=(16, 3))
|
||||
model_width = fields.Float('模型宽[mm]', digits=(16, 3))
|
||||
model_height = fields.Float('模型高[mm]', digits=(16, 3))
|
||||
model_volume = fields.Float('模型体积[m³]')
|
||||
model_machining_precision = fields.Selection([
|
||||
('0.10', '±0.10mm'),
|
||||
('0.05', '±0.05mm'),
|
||||
('0.03', '±0.03mm'),
|
||||
('0.02', '±0.02mm'),
|
||||
('0.01', '±0.01mm')], string='加工精度')
|
||||
product_model_type_id = fields.Many2one('sf.model.type', string='产品模型类型')
|
||||
embryo_model_type_id = fields.Many2one('sf.model.type', string='胚料模型类型')
|
||||
model_processing_panel = fields.Char('模型加工面板')
|
||||
model_surface_process_id = fields.Many2one('sf.production.process', string='表面工艺')
|
||||
model_process_parameters_id = fields.Many2one('sf.processing.technology', string='工艺参数')
|
||||
# model_price = fields.Float('模型单价', digits=(16, 3))
|
||||
model_remark = fields.Char('模型备注说明')
|
||||
length = fields.Float('长[mm]', digits=(16, 3))
|
||||
width = fields.Float('宽[mm]', digits=(16, 3))
|
||||
height = fields.Float('高[mm]', digits=(16, 3))
|
||||
materials_id = fields.Many2one('sf.production.materials', string='材料')
|
||||
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号')
|
||||
single_manufacturing = fields.Boolean(string="单个制造")
|
||||
upload_model_file = fields.Many2many('ir.attachment', 'upload_model_file_attachment_ref', string='上传模型文件')
|
||||
model_code = fields.Char('模型编码')
|
||||
is_bfm = fields.Boolean('业务平台是否自动创建', default=False)
|
||||
|
||||
def _get_volume_uom_id_from_ir_config_parameter(self):
|
||||
product_length_in_feet_param = self.env['ir.config_parameter'].sudo().get_param('product.volume_in_cubic_feet')
|
||||
if product_length_in_feet_param == '1':
|
||||
return self.env.ref('uom.product_uom_cubic_foot')
|
||||
else:
|
||||
return self.env.ref('sf_dlm.product_uom_cubic_millimeter')
|
||||
|
||||
# model_file = fields.Binary('模型文件')
|
||||
|
||||
# 胚料的库存路线设置
|
||||
# def _get_routes(self, route_type):
|
||||
# route_manufacture = self.env.ref('mrp.route_warehouse0_manufacture', raise_if_not_found=False).sudo()
|
||||
# route_mto = self.env.ref('stock.route_warehouse0_mto', raise_if_not_found=False).sudo()
|
||||
# route_purchase = self.env.ref('purchase_stock.route_warehouse0_buy', raise_if_not_found=False).sudo()
|
||||
# if route_manufacture and route_mto:
|
||||
# # 外协
|
||||
# if route_type == 'subcontract':
|
||||
# route_subcontract = self.env.ref('mrp_subcontracting.route_resupply_subcontractor_mto',
|
||||
# raise_if_not_found=False).sudo()
|
||||
# return [route_mto.id, route_purchase.id, route_subcontract.id]
|
||||
# elif route_type == 'purchase':
|
||||
# # 采购
|
||||
# return [route_mto.id, route_purchase.id]
|
||||
# else:
|
||||
# return [route_mto.id, route_manufacture.id]
|
||||
# return []
|
||||
|
||||
# route_ids = fields.Many2many(default=lambda self: self._get_route())
|
||||
|
||||
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品
|
||||
def product_create(self, product_id, item, order_id, order_number, i):
|
||||
copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
|
||||
copy_product_id.product_tmpl_id.active = True
|
||||
model_type = self.env['sf.model.type'].search([], limit=1)
|
||||
attachment = self.attachment_create(item['model_name'], item['model_data'])
|
||||
vals = {
|
||||
'name': '%s-%s-%s' % ('P', order_id.name, i),
|
||||
'model_long': item['model_long'] + model_type.embryo_tolerance,
|
||||
'model_width': item['model_width'] + model_type.embryo_tolerance,
|
||||
'model_height': item['model_height'] + model_type.embryo_tolerance,
|
||||
'model_volume': (item['model_long'] + model_type.embryo_tolerance) * (
|
||||
item['model_width'] + model_type.embryo_tolerance) * (
|
||||
item['model_height'] + model_type.embryo_tolerance),
|
||||
'product_model_type_id': model_type.id,
|
||||
'model_processing_panel': 'R',
|
||||
'model_machining_precision': item['model_machining_precision'],
|
||||
'model_code': item['barcode'],
|
||||
'length': item['model_long'],
|
||||
'width': item['model_width'],
|
||||
'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])],
|
||||
# 'single_manufacturing': True,
|
||||
# 'tracking': 'serial',
|
||||
'list_price': item['price'],
|
||||
# 'categ_id': self.env.ref('sf_dlm.product_category_finished_sf').id,
|
||||
'materials_id': self.env['sf.production.materials'].search(
|
||||
[('materials_no', '=', item['texture_code'])]).id,
|
||||
'materials_type_id': self.env['sf.materials.model'].search(
|
||||
[('materials_no', '=', item['texture_type_code'])]).id,
|
||||
'model_surface_process_id': self.env['sf.production.process'].search(
|
||||
[('process_encode', '=', item['surface_process_code'])]).id,
|
||||
# 'model_process_parameters_id': self.env['sf.processing.technology'].search(
|
||||
# [('process_encode', '=', item['process_parameters_code'])]).id,
|
||||
'model_remark': item['remark'],
|
||||
'default_code': '%s-%s' % (order_number, i),
|
||||
# 'barcode': item['barcode'],
|
||||
'active': True,
|
||||
# 'route_ids': self._get_routes('')
|
||||
}
|
||||
copy_product_id.sudo().write(vals)
|
||||
# product_id.product_tmpl_id.active = False
|
||||
return copy_product_id
|
||||
|
||||
def attachment_create(self, name, data):
|
||||
attachment = self.env['ir.attachment'].create({
|
||||
'datas': base64.b64decode(data),
|
||||
'type': 'binary',
|
||||
'public': True,
|
||||
'description': '模型文件',
|
||||
'name': name
|
||||
})
|
||||
return attachment
|
||||
|
||||
# 创建胚料
|
||||
def no_bom_product_create(self, product_id, item, order_id, route_type, i):
|
||||
no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
|
||||
no_bom_copy_product_id.product_tmpl_id.active = True
|
||||
materials_id = self.env['sf.production.materials'].search(
|
||||
[('materials_no', '=', item['texture_code'])])
|
||||
materials_type_id = self.env['sf.materials.model'].search(
|
||||
[('materials_no', '=', item['texture_type_code'])])
|
||||
model_type = self.env['sf.model.type'].search([], limit=1)
|
||||
supplier = self.env['mrp.bom'].get_supplier(materials_type_id)
|
||||
logging.info('no_bom_copy_product_supplier-vals:%s' % supplier)
|
||||
vals = {
|
||||
'name': '%s-%s-%s [%s %s-%s * %s * %s]' % ('R',
|
||||
order_id.name, i, materials_id.name, materials_type_id.name,
|
||||
item['model_long'] + model_type.embryo_tolerance,
|
||||
item['model_width'] + model_type.embryo_tolerance,
|
||||
item['model_height'] + model_type.embryo_tolerance),
|
||||
'length': item['model_long'] + model_type.embryo_tolerance,
|
||||
'width': item['model_width'] + model_type.embryo_tolerance,
|
||||
'height': item['model_height'] + model_type.embryo_tolerance,
|
||||
'volume': (item['model_long'] + model_type.embryo_tolerance) * (
|
||||
item['model_width'] + model_type.embryo_tolerance) * (
|
||||
item['model_height'] + model_type.embryo_tolerance),
|
||||
'embryo_model_type_id': model_type.id,
|
||||
'list_price': item['price'],
|
||||
'materials_id': materials_id.id,
|
||||
'materials_type_id': materials_type_id.id,
|
||||
'is_bfm': True,
|
||||
# 'route_ids': self._get_routes(route_type),
|
||||
# 'categ_id': self.env.ref('sf_dlm.product_category_embryo_sf').id,
|
||||
# 'model_surface_process_id': self.env['sf.production.process'].search(
|
||||
# [('process_encode', '=', item['surface_process_code'])]).id,
|
||||
# 'model_process_parameters_id': self.env['sf.processing.technology'].search(
|
||||
# [('process_encode', '=', item['process_parameters_code'])]).id,
|
||||
'active': True
|
||||
}
|
||||
# 外协和采购生成的胚料需要根据材料型号绑定供应商
|
||||
if route_type == 'subcontract' or route_type == 'purchase':
|
||||
no_bom_copy_product_id.purchase_ok = True
|
||||
no_bom_copy_product_id.seller_ids = [
|
||||
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})]
|
||||
if route_type == 'subcontract':
|
||||
partner = self.env['res.partner'].search([('id', '=', supplier.partner_id.id)])
|
||||
partner.is_subcontractor = True
|
||||
no_bom_copy_product_id.write(vals)
|
||||
logging.info('no_bom_copy_product_id-vals:%s' % vals)
|
||||
# product_id.product_tmpl_id.active = False
|
||||
return no_bom_copy_product_id
|
||||
|
||||
# @api.onchange('upload_model_file')
|
||||
# def onchange_model_file(self):
|
||||
# for item in self:
|
||||
# if len(item.upload_model_file) > 1:
|
||||
# raise ValidationError('只允许上传一个文件')
|
||||
# if item.upload_model_file:
|
||||
# file_attachment_id = item.upload_model_file[0]
|
||||
# item.model_name = file_attachment_id.name
|
||||
# # 附件路径
|
||||
# report_path = file_attachment_id._full_path(file_attachment_id.store_fname)
|
||||
# shapes = read_step_file(report_path)
|
||||
# output_file = get_resource_path('sf_dlm', 'static/file', 'out.stl')
|
||||
# write_stl_file(shapes, output_file, 'binary', 0.03, 0.5)
|
||||
# # 转化为glb
|
||||
# output_glb_file = get_resource_path('sf_dlm', 'static/file', 'out.glb')
|
||||
# util_path = get_resource_path('sf_dlm', 'static/util')
|
||||
# cmd = 'python %s/stl2gltf.py %s %s -b' % (util_path, output_file, output_glb_file)
|
||||
# os.system(cmd)
|
||||
# # 转base64
|
||||
# with open(output_glb_file, 'rb') as fileObj:
|
||||
# image_data = fileObj.read()
|
||||
# base64_data = base64.b64encode(image_data)
|
||||
# item.model_file = base64_data
|
||||
|
||||
|
||||
class ResMrpBom(models.Model):
|
||||
_inherit = 'mrp.bom'
|
||||
|
||||
subcontractor_id = fields.Many2one('res.partner', string='外包商')
|
||||
|
||||
def bom_create_line_has(self, embryo):
|
||||
vals = {
|
||||
'bom_id': self.id,
|
||||
'product_id': embryo.id,
|
||||
'product_tmpl_id': embryo.product_tmpl_id.id,
|
||||
'product_qty': 1,
|
||||
'product_uom_id': 1
|
||||
}
|
||||
return self.env['mrp.bom.line'].create(vals)
|
||||
|
||||
# 业务平台分配工厂后在智能工厂先创建销售订单再创建该产品后再次进行创建bom
|
||||
def bom_create(self, product, bom_type, product_type):
|
||||
bom_id = self.env['mrp.bom'].create({
|
||||
'product_tmpl_id': product.product_tmpl_id.id,
|
||||
'type': bom_type,
|
||||
# 'subcontractor_id': '' or subcontract.partner_id.id,
|
||||
'product_qty': 1,
|
||||
'product_uom_id': 1
|
||||
})
|
||||
if bom_type == 'subcontract' and product_type is not False:
|
||||
subcontract = self.get_supplier(product.materials_type_id)
|
||||
bom_id.subcontractor_id = subcontract.partner_id.id
|
||||
return bom_id
|
||||
|
||||
# 胚料BOM组件:选取当前胚料原材料,
|
||||
# 然后根据当前的胚料的体积得出需要的原材料重量(立方米m³) *材料密度 * 1000 = 所需原材料重量KG(公斤)
|
||||
# 胚料所需原材料公式:当前的胚料的体积(立方米m³) *材料密度 * 1000 = 所需原材料重量KG(公斤)
|
||||
def bom_create_line(self, embryo):
|
||||
# 选取当前胚料原材料
|
||||
raw_bom_line = self.get_raw_bom(embryo)
|
||||
if raw_bom_line:
|
||||
bom_line = self.env['mrp.bom.line'].create({
|
||||
'bom_id': self.id,
|
||||
'product_id': raw_bom_line.id,
|
||||
'product_tmpl_id': raw_bom_line.product_tmpl_id.id,
|
||||
'product_qty': round(embryo.volume * raw_bom_line.materials_type_id.density / 1000000),
|
||||
'product_uom_id': raw_bom_line.uom_id.id,
|
||||
})
|
||||
return bom_line
|
||||
else:
|
||||
return False
|
||||
|
||||
# 查询材料型号默认排第一的供应商
|
||||
def get_supplier(self, materials_type):
|
||||
seller_id = self.env['sf.supplier.sort'].search(
|
||||
[('materials_model_id', '=', materials_type.id)],
|
||||
limit=1,
|
||||
order='sequence asc')
|
||||
return seller_id
|
||||
|
||||
# 匹配bom
|
||||
def get_bom(self, product):
|
||||
embryo_has = self.env['product.product'].search(
|
||||
[('categ_id.type', '=', '胚料'), ('materials_type_id', '=', product.materials_type_id.id),
|
||||
('length', '>', product.length), ('width', '>', product.width),
|
||||
('height', '>', product.height), ('is_bfm', '=', False)
|
||||
],
|
||||
limit=1,
|
||||
order='volume desc'
|
||||
)
|
||||
logging.info('get_bom-vals:%s' % embryo_has)
|
||||
if embryo_has:
|
||||
rate_of_waste = ((embryo_has.volume - product.model_volume) % embryo_has.volume) * 100
|
||||
if rate_of_waste <= 20:
|
||||
return embryo_has
|
||||
else:
|
||||
return
|
||||
|
||||
# 查bom的原材料
|
||||
def get_raw_bom(self, product):
|
||||
raw_bom = self.env['product.product'].search(
|
||||
[('categ_id.type', '=', '原材料'), ('materials_type_id', '=', product.materials_type_id.id)])
|
||||
return raw_bom
|
||||
|
||||
|
||||
class ResProductCategory(models.Model):
|
||||
_inherit = "product.category"
|
||||
|
||||
type = fields.Selection(
|
||||
[("成品", "成品"), ("胚料", "胚料"), ("原材料", "原材料")],
|
||||
default="", string="类型")
|
||||
|
||||
# @api.constrains('type')
|
||||
# def _check_type(self):
|
||||
# category = self.env['product.category'].search(
|
||||
# [('type', '=', self.type)])
|
||||
# if category:
|
||||
# raise ValidationError("该类别已存在,请选择其他类别")
|
||||
13
sf_dlm/models/product_workorder.py
Normal file
@@ -0,0 +1,13 @@
|
||||
from odoo import api, fields, models
|
||||
|
||||
|
||||
|
||||
class ResMrpWorkOrder(models.Model):
|
||||
_inherit = 'mrp.workorder'
|
||||
_order = 'sequence'
|
||||
|
||||
product_tmpl_id_length = fields.Float(related='production_id.product_tmpl_id.length', readonly=True, store=True, check_company=True, string="胚料长度(mm)")
|
||||
product_tmpl_id_width = fields.Float(related='production_id.product_tmpl_id.width', readonly=True, store=True, check_company=True, string="胚料宽度(mm)")
|
||||
product_tmpl_id_height = fields.Float(related='production_id.product_tmpl_id.height', readonly=True, store=True, check_company=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', readonly=True, store=True, check_company=True, string="型号")
|
||||
BIN
sf_dlm/static/file/out.glb
Normal file
BIN
sf_dlm/static/file/out.stl
Normal file
277
sf_dlm/static/util/stl2gltf.py
Normal file
@@ -0,0 +1,277 @@
|
||||
import os
|
||||
|
||||
def stl_to_gltf(binary_stl_path, out_path, is_binary):
|
||||
import struct
|
||||
|
||||
gltf2 = '''
|
||||
{
|
||||
"scenes" : [
|
||||
{
|
||||
"nodes" : [ 0 ]
|
||||
}
|
||||
],
|
||||
"nodes" : [
|
||||
{
|
||||
"mesh" : 0
|
||||
}
|
||||
],
|
||||
"meshes" : [
|
||||
{
|
||||
"primitives" : [ {
|
||||
"attributes" : {
|
||||
"POSITION" : 1
|
||||
},
|
||||
"indices" : 0
|
||||
} ]
|
||||
}
|
||||
],
|
||||
"buffers" : [
|
||||
{
|
||||
%s
|
||||
"byteLength" : %d
|
||||
}
|
||||
],
|
||||
"bufferViews" : [
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteOffset" : 0,
|
||||
"byteLength" : %d,
|
||||
"target" : 34963
|
||||
},
|
||||
{
|
||||
"buffer" : 0,
|
||||
"byteOffset" : %d,
|
||||
"byteLength" : %d,
|
||||
"target" : 34962
|
||||
}
|
||||
],
|
||||
"accessors" : [
|
||||
{
|
||||
"bufferView" : 0,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5125,
|
||||
"count" : %d,
|
||||
"type" : "SCALAR",
|
||||
"max" : [ %d ],
|
||||
"min" : [ 0 ]
|
||||
},
|
||||
{
|
||||
"bufferView" : 1,
|
||||
"byteOffset" : 0,
|
||||
"componentType" : 5126,
|
||||
"count" : %d,
|
||||
"type" : "VEC3",
|
||||
"min" : [%f, %f, %f],
|
||||
"max" : [%f, %f, %f]
|
||||
}
|
||||
],
|
||||
"asset" : {
|
||||
"version" : "2.0"
|
||||
}
|
||||
}
|
||||
'''
|
||||
|
||||
header_bytes = 80
|
||||
unsigned_long_int_bytes = 4
|
||||
float_bytes = 4
|
||||
vec3_bytes = 4 * 3
|
||||
spacer_bytes = 2
|
||||
num_vertices_in_face = 3
|
||||
|
||||
vertices = {}
|
||||
indices = []
|
||||
|
||||
if not is_binary:
|
||||
out_bin = os.path.join(out_path, "out.bin")
|
||||
out_gltf = os.path.join(out_path, "out.gltf")
|
||||
else:
|
||||
out_bin = out_path
|
||||
|
||||
unpack_face = struct.Struct("<12fH").unpack
|
||||
face_bytes = float_bytes*12 + 2
|
||||
|
||||
with open(path_to_stl, "rb") as f:
|
||||
f.seek(header_bytes) # skip 80 bytes headers
|
||||
|
||||
num_faces_bytes = f.read(unsigned_long_int_bytes)
|
||||
number_faces = struct.unpack("<I", num_faces_bytes)[0]
|
||||
|
||||
# the vec3_bytes is for normal
|
||||
stl_assume_bytes = header_bytes + unsigned_long_int_bytes + number_faces * (vec3_bytes*3 + spacer_bytes + vec3_bytes)
|
||||
assert stl_assume_bytes == os.path.getsize(path_to_stl), "stl is not binary or ill formatted"
|
||||
|
||||
minx, maxx = [9999999, -9999999]
|
||||
miny, maxy = [9999999, -9999999]
|
||||
minz, maxz = [9999999, -9999999]
|
||||
|
||||
vertices_length_counter = 0
|
||||
|
||||
data = struct.unpack("<" + "12fH"*number_faces, f.read())
|
||||
len_data = len(data)
|
||||
|
||||
for i in range(0, len_data, 13):
|
||||
for j in range(3, 12, 3):
|
||||
x, y, z = data[i+j:i+j+3]
|
||||
|
||||
x = int(x*100000)/100000
|
||||
y = int(y*100000)/100000
|
||||
z = int(z*100000)/100000
|
||||
|
||||
tuple_xyz = (x, y, z);
|
||||
|
||||
try:
|
||||
indices.append(vertices[tuple_xyz])
|
||||
except KeyError:
|
||||
vertices[tuple_xyz] = vertices_length_counter
|
||||
vertices_length_counter += 1
|
||||
indices.append(vertices[tuple_xyz])
|
||||
|
||||
|
||||
|
||||
if x < minx: minx = x
|
||||
if x > maxx: maxx = x
|
||||
if y < miny: miny = y
|
||||
if y > maxy: maxy = y
|
||||
if z < minz: minz = z
|
||||
if z > maxz: maxz = z
|
||||
|
||||
# f.seek(spacer_bytes, 1) # skip the spacer
|
||||
|
||||
number_vertices = len(vertices)
|
||||
vertices_bytelength = number_vertices * vec3_bytes # each vec3 has 3 floats, each float is 4 bytes
|
||||
unpadded_indices_bytelength = number_vertices * unsigned_long_int_bytes
|
||||
|
||||
out_number_vertices = len(vertices)
|
||||
out_number_indices = len(indices)
|
||||
|
||||
unpadded_indices_bytelength = out_number_indices * unsigned_long_int_bytes
|
||||
indices_bytelength = (unpadded_indices_bytelength + 3) & ~3
|
||||
|
||||
out_bin_bytelength = vertices_bytelength + indices_bytelength
|
||||
|
||||
if is_binary:
|
||||
out_bin_uir = ""
|
||||
else:
|
||||
out_bin_uir = '"uri": "out.bin",'
|
||||
|
||||
gltf2 = gltf2 % ( out_bin_uir,
|
||||
#buffer
|
||||
out_bin_bytelength,
|
||||
|
||||
# bufferViews[0]
|
||||
indices_bytelength,
|
||||
|
||||
# bufferViews[1]
|
||||
indices_bytelength,
|
||||
vertices_bytelength,
|
||||
|
||||
# accessors[0]
|
||||
out_number_indices,
|
||||
out_number_vertices - 1,
|
||||
|
||||
# accessors[1]
|
||||
out_number_vertices,
|
||||
minx, miny, minz,
|
||||
maxx, maxy, maxz
|
||||
)
|
||||
|
||||
glb_out = bytearray()
|
||||
if is_binary:
|
||||
gltf2 = gltf2.replace(" ", "")
|
||||
gltf2 = gltf2.replace("\n", "")
|
||||
|
||||
scene = bytearray(gltf2.encode())
|
||||
|
||||
scene_len = len(scene)
|
||||
padded_scene_len = (scene_len + 3) & ~3
|
||||
body_offset = padded_scene_len + 12 + 8
|
||||
|
||||
file_len = body_offset + out_bin_bytelength + 8
|
||||
|
||||
# 12-byte header
|
||||
glb_out.extend(struct.pack('<I', 0x46546C67)) # magic number for glTF
|
||||
glb_out.extend(struct.pack('<I', 2))
|
||||
glb_out.extend(struct.pack('<I', file_len))
|
||||
|
||||
# chunk 0
|
||||
glb_out.extend(struct.pack('<I', padded_scene_len))
|
||||
glb_out.extend(struct.pack('<I', 0x4E4F534A)) # magic number for JSON
|
||||
glb_out.extend(scene)
|
||||
|
||||
while len(glb_out) < body_offset:
|
||||
glb_out.extend(b' ')
|
||||
|
||||
# chunk 1
|
||||
glb_out.extend(struct.pack('<I', out_bin_bytelength))
|
||||
glb_out.extend(struct.pack('<I', 0x004E4942)) # magin number for BIN
|
||||
|
||||
# print('<%dI' % len(indices))
|
||||
# print(struct.pack('<%dI' % len(indices), *indices))
|
||||
glb_out.extend(struct.pack('<%dI' % len(indices), *indices))
|
||||
|
||||
for i in range(indices_bytelength - unpadded_indices_bytelength):
|
||||
glb_out.extend(b' ')
|
||||
|
||||
vertices = dict((v, k) for k,v in vertices.items())
|
||||
|
||||
# glb_out.extend(struct.pack('f',
|
||||
# print([each_v for vertices[v_counter] for v_counter in range(number_vertices)]) # magin number for BIN
|
||||
vertices = [vertices[i] for i in range(number_vertices)]
|
||||
flatten = lambda l: [item for sublist in l for item in sublist]
|
||||
|
||||
# for v_counter in :
|
||||
# v_3f = vertices[v_counter]
|
||||
# all_floats_in_vertices.append(v_3f[0])
|
||||
# all_floats_in_vertices.append(v_3f[1])
|
||||
# all_floats_in_vertices.append(v_3f[2])
|
||||
|
||||
# for v_counter in range(number_vertices):
|
||||
glb_out.extend(struct.pack('%df' % number_vertices*3, *flatten(vertices))) # magin number for BIN
|
||||
|
||||
# for v_counter in range(number_vertices):
|
||||
# glb_out.extend(struct.pack('3f', *vertices[v_counter])) # magin number for BIN
|
||||
|
||||
# for (v_x, v_y, v_z), _ in sorted(vertices.items(), key=lambda x: x[1]):
|
||||
# glb_out.extend(struct.pack('3f', v_x, v_y, v_z)) # magin number for BIN
|
||||
# # glb_out.extend(struct.pack('f', v_y)) # magin number for BIN
|
||||
# # glb_out.extend(struct.pack('f', v_z)) # magin number for BIN
|
||||
|
||||
with open(out_bin, "wb") as out:
|
||||
out.write(glb_out)
|
||||
|
||||
if not is_binary:
|
||||
with open(out_gltf, "w") as out:
|
||||
out.write(gltf2)
|
||||
|
||||
print("Done! Exported to %s" %out_path)
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("use it like python3 stl_to_gltf.py /path/to/stl /path/to/gltf/folder")
|
||||
print("or python3 stl_to_gltf.py /path/to/stl /path/to/glb/file -b")
|
||||
sys.exit(1)
|
||||
|
||||
path_to_stl = sys.argv[1]
|
||||
out_path = sys.argv[2]
|
||||
if len(sys.argv) > 3:
|
||||
is_binary = True
|
||||
else:
|
||||
is_binary = False
|
||||
|
||||
if out_path.lower().endswith(".glb"):
|
||||
print("Use binary mode since output file has glb extension")
|
||||
is_binary = True
|
||||
else:
|
||||
if is_binary:
|
||||
print("output file should have glb extension but not %s", out_path)
|
||||
|
||||
if not os.path.exists(path_to_stl):
|
||||
print("stl file does not exists %s" % path_to_stl)
|
||||
|
||||
if not is_binary:
|
||||
if not os.path.isdir(out_path):
|
||||
os.mkdir(out_path)
|
||||
|
||||
stl_to_gltf(path_to_stl, out_path, is_binary)
|
||||
@@ -55,7 +55,7 @@
|
||||
</page>
|
||||
<page name="inventory" position="attributes">
|
||||
<attribute name="groups">
|
||||
stock.group_stock_user,product.group_stock_packaging,sf_base.group_sale_salemanager,sf_base.group_sale_director,sf_base.group_purchase,sf_base.group_purchase_director
|
||||
stock.group_stock_user,product.group_stock_packaging,sf_base.group_sale_salemanager,sf_base.group_sale_director,sf_base.group_purchase,sf_base.group_purchase_director,sf_base.group_plan_dispatch
|
||||
</attribute>
|
||||
</page>
|
||||
</field>
|
||||
@@ -110,6 +110,9 @@
|
||||
<field name="subcontractor_id"
|
||||
attrs="{'invisible': [('type', '!=', 'subcontract')], 'required': [('type', '=', 'subcontract')]}"/>
|
||||
</field>
|
||||
<xpath expr="//group" position="after">
|
||||
<field name="subcontractor_name" attrs="{'invisible': True}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
||||
27
sf_dlm/views/product_workorder.xml
Normal file
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<odoo>
|
||||
<record id="view_mrp_production_workorder_tray_form_inherit_sf1" model="ir.ui.view">
|
||||
<field name="name">production.workorder.dlm</field>
|
||||
<field name="model">mrp.workorder</field>
|
||||
<field name="inherit_id" ref="sf_manufacturing.view_mrp_production_workorder_tray_form_inherit_sf"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//page[1]" position="before">
|
||||
<page string="开料要求" attrs='{"invisible": [("routing_type","!=","切割")]}'>
|
||||
<group>
|
||||
<group>
|
||||
<field name="product_tmpl_id_materials_id" widget="many2one"/>
|
||||
<field name="product_tmpl_id_materials_type_id" widget="many2one"/>
|
||||
|
||||
</group>
|
||||
<group>
|
||||
<field name="product_tmpl_id_length"/>
|
||||
<field name="product_tmpl_id_width"/>
|
||||
<field name="product_tmpl_id_height"/>
|
||||
</group>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
@@ -11,7 +11,7 @@
|
||||
'website': 'https://www.sf.jikimo.com',
|
||||
'depends': ['sf_sale', 'sf_dlm', 'sf_manufacturing'],
|
||||
'data': [
|
||||
# 'data/stock_data.xml',
|
||||
'data/stock_data.xml',
|
||||
'views/product_template_management_view.xml',
|
||||
],
|
||||
'demo': [
|
||||
|
||||
@@ -7,13 +7,10 @@
|
||||
<field name="inherit_id" ref="sf_sale.view_product_template_form_inherit_sf"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="invoice_policy" position="after">
|
||||
<<<<<<< HEAD
|
||||
<field name='categ_id'/>
|
||||
=======
|
||||
<field name='categ_id' attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
<field name='categ_id' class="custom_required" attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
<field name='is_bfm' invisible="1"/>
|
||||
<field name='categ_type' invisible="1"/>
|
||||
<field name='manual_quotation' attrs="{'invisible':[('upload_model_file', '=', [])]}"/>
|
||||
<field name="upload_model_file"
|
||||
widget="many2many_binary"
|
||||
attrs="{'invisible': ['|', '|',('categ_type', '!=', '成品'),('categ_type', '=', False),('is_bfm','=', True)]}"/>
|
||||
@@ -21,55 +18,42 @@
|
||||
attrs="{'invisible': ['|','|', ('categ_type', '!=', '成品'),('categ_type', '=', False),('model_file', '=', False)]}"/>
|
||||
<field name='cutting_tool_type' invisible="1"/>
|
||||
<field name="fixture_material_type" invisible="1"/>
|
||||
<field name="embryo_model_type_id" string="模型类型"
|
||||
<<<<<<< HEAD
|
||||
attrs="{'invisible': ['|',('categ_type', '!=', '坯料'),('categ_type', '=', False)]}"/>
|
||||
<field name="materials_id" string="材料" placeholder="请选择"
|
||||
attrs="{'invisible': [('categ_type', 'not in', ['成品','坯料', '原材料'])]}"/>
|
||||
<field name="materials_type_id" string="型号" placeholder="请选择"
|
||||
domain="[('materials_id', '=', materials_id)]"
|
||||
attrs="{'invisible': [('categ_type', 'not in', ['成品','坯料', '原材料'])]}"/>
|
||||
<field name="server_product_process_parameters_id" string="表面工艺参数"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': ['|',('categ_type', '!=', '表面工艺'),('categ_type', '=', False)]}"/>
|
||||
<field name="cutting_tool_material_id" attrs="{'invisible': [('categ_type', '!=', '刀具')]}"
|
||||
placeholder="请选择"/>
|
||||
<field name="cutting_tool_model_id" placeholder="请选择"
|
||||
attrs="{'invisible': [('categ_type', '!=', '刀具')]}"
|
||||
domain="[('cutting_tool_material_id','=',cutting_tool_material_id)]"/>
|
||||
<field name="specification_id" placeholder="请选择" options='{"limit": 1}'
|
||||
attrs="{'invisible': [('categ_type', '!=', '刀具')]}"
|
||||
=======
|
||||
<field name="embryo_model_type_id" string="模型类型" options="{'no_create': True}"
|
||||
attrs="{'invisible': ['|',('categ_type', '!=', '坯料'),('categ_type', '=', False)],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="materials_id" string="材料" placeholder="请选择"
|
||||
<field name="materials_id" string="材料" placeholder="请选择" options="{'no_create': True}"
|
||||
attrs="{'invisible': [('categ_type', 'not in', ['成品','坯料', '原材料'])],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="materials_type_id" string="型号" placeholder="请选择"
|
||||
domain="[('materials_id', '=', materials_id)]"
|
||||
<field name="materials_type_id" string="型号" placeholder="请选择" options="{'no_create': True}"
|
||||
attrs="{'invisible': [('categ_type', 'not in', ['成品','坯料', '原材料'])],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="server_product_process_parameters_id" string="表面工艺参数"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': ['|',('categ_type', '!=', '表面工艺'),('categ_type', '=', False)]}"/>
|
||||
<field name="cutting_tool_material_id"
|
||||
attrs="{'invisible': [('categ_type', '!=', '刀具')],'readonly': [('id', '!=', False)]}"
|
||||
<field name="cutting_tool_material_id" class="custom_required"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': [('categ_type', '!=', '刀具')],'required': [('categ_type', '=', '刀具')],'readonly': [('id', '!=', False)]}"
|
||||
placeholder="请选择"/>
|
||||
<field name="cutting_tool_model_id" placeholder="请选择"
|
||||
attrs="{'invisible': [('categ_type', '!=', '刀具')],'readonly': [('id', '!=', False)]}"
|
||||
domain="[('cutting_tool_material_id','=',cutting_tool_material_id)]"/>
|
||||
<field name="specification_id" placeholder="请选择"
|
||||
attrs="{'invisible': [('categ_type', '!=', '刀具')],'readonly': [('id', '!=', False)]}"
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
<field name="cutting_tool_model_id" placeholder="请选择" class="custom_required"
|
||||
options="{'no_create': True}"
|
||||
domain="[('cutting_tool_material_id','=',cutting_tool_material_id)]"
|
||||
context="{'default_cutting_tool_material_id': cutting_tool_material_id}"
|
||||
attrs="{'invisible': [('categ_type', '!=', '刀具')],'required': [('categ_type', '=', '刀具')],'readonly': [('id', '!=', False)]}">
|
||||
</field>
|
||||
<!-- <button name="%(sf_base.action_sf_cutting_tool_standard_library)d" string="新建" type="action"-->
|
||||
<!-- context="{'default_cutting_tool_material_id': cutting_tool_material_id}"/>-->
|
||||
<field name="specification_id" placeholder="请选择" class="custom_required"
|
||||
options="{'no_create': True}"
|
||||
context="{'default_cutting_tool_type': cutting_tool_type,'default_standard_library_id':cutting_tool_model_id}"
|
||||
attrs="{'invisible': [('categ_type', '!=', '刀具')],'required': [('categ_type', '=', '刀具')],'readonly': [('id', '!=', False)]}"
|
||||
domain="[('standard_library_id','=',cutting_tool_model_id)]"/>
|
||||
<field name="fixture_material_id" attrs="{'invisible': [('categ_type', '!=', '夹具')]}"
|
||||
placeholder="请选择"/>
|
||||
<field name="fixture_model_id" string="型号" placeholder="请选择"
|
||||
<field name="fixture_material_id"
|
||||
attrs="{'invisible': [('categ_type', '!=', '夹具')],'required': [('categ_type', '=', '夹具')]}"
|
||||
placeholder="请选择" options="{'no_create': True}"/>
|
||||
<field name="fixture_model_id" string="型号" placeholder="请选择" options="{'no_create': True}"
|
||||
attrs="{'invisible': [('categ_type', '!=', '夹具')],'required': [('categ_type', '=', '夹具')]}"
|
||||
domain="[('fixture_material_id','=',fixture_material_id)]"/>
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
<field name="specification_fixture_id" string="规格" placeholder="请选择"
|
||||
attrs="{'invisible': [('categ_type', '!=', '夹具')]}"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': [('categ_type', '!=', '夹具')],'required': [('categ_type', '=', '夹具')]}"
|
||||
domain="[('fixture_model_id','=',fixture_model_id)]"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
</field>
|
||||
<xpath expr="//label[@for='volume']" position="before">
|
||||
<label for="length" string="尺寸"
|
||||
@@ -114,7 +98,7 @@
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_product_template_form_inherit_sf">
|
||||
<record model="ir.ui.view" id="view_product_template_only_form_inherit_sf">
|
||||
<field name="name">product.template.only.form.inherit.sf</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="product.product_template_only_form_view"/>
|
||||
@@ -125,30 +109,10 @@
|
||||
<field name="default_code" position="replace">
|
||||
<field name='default_code' invisible="1"/>
|
||||
</field>
|
||||
<<<<<<< HEAD
|
||||
<xpath expr="//page[@name='variants']" position="before">
|
||||
<page string="刀具物料参数" attrs="{'invisible': [('categ_type', '!=', '刀具')]}">
|
||||
<group>
|
||||
<group attrs="{'invisible': [('categ_type', '!=', '刀具')]}" col="1">
|
||||
<field name="cutting_tool_type_id" options="{'no_create': True}"
|
||||
placeholder="请选择"/>
|
||||
<field name="brand_id" options="{'no_create': True}" placeholder="请选择"/>
|
||||
<field name="cutting_tool_total_length"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀杆','刀盘','夹头','刀柄'))]}"/>
|
||||
<field name="tool_hardness" string="硬度(hrc)"/>
|
||||
<label for="cutting_tool_run_out_accuracy_min" string="端跳精度"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<div class="o_address_format"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}">
|
||||
<label for="cutting_tool_run_out_accuracy_min" string="最小"/>
|
||||
<field name="cutting_tool_run_out_accuracy_min" class="o_address_zip"
|
||||
options="{'format': false}"
|
||||
attrs="{'invisible': [('cutting_tool_type','!=','整体式刀具')]}"/>
|
||||
=======
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.ui.view" id="view_product_template_only_form_inherit_sf">
|
||||
<record model="ir.ui.view" id="view_product_template_only_dlm_form_inherit_sf">
|
||||
<field name="name">product.template.only.form.inherit.sf</field>
|
||||
<field name="model">product.template</field>
|
||||
<field name="inherit_id" ref="sf_dlm_management.view_sale_product_template_form_inherit_sf"/>
|
||||
@@ -174,104 +138,22 @@
|
||||
<field name="cutting_tool_run_out_accuracy_min" class="o_address_zip"
|
||||
options="{'format': false}"
|
||||
attrs="{'invisible': [('cutting_tool_type','!=','整体式刀具')],'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
<span>(mm)&nbsp;</span>
|
||||
<label for="cutting_tool_run_out_accuracy_max" string="最大"/>
|
||||
<field name="cutting_tool_run_out_accuracy_max" class="o_address_zip"
|
||||
options="{'format': false}"
|
||||
<<<<<<< HEAD
|
||||
attrs="{'invisible': [('cutting_tool_type','!=','整体式刀具')]}"/>
|
||||
=======
|
||||
attrs="{'invisible': [('cutting_tool_type','!=','整体式刀具')],'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
<span>(mm)&nbsp;</span>
|
||||
</div>
|
||||
|
||||
<field name="tool_width"
|
||||
<<<<<<< HEAD
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<field name="tool_height"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<field name="cutting_tool_flange_length"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_shank_outer_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_shank_inner_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
|
||||
<!-- <field name="materials_type_id" options="{'no_create': True}" string="刀具材质"-->
|
||||
<!-- attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"-->
|
||||
<!-- placeholder="请选择"/>-->
|
||||
<!-- <field name="tool_hardness" string="刀具硬度(hrc)"-->
|
||||
<!-- attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>-->
|
||||
<!-- <field name="materials_type_id" options="{'no_create': True}" string="夹头材质"-->
|
||||
<!-- attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}"-->
|
||||
<!-- placeholder="请选择"/>-->
|
||||
<!-- <field name="tool_hardness" string="夹头硬度(hrc)"-->
|
||||
<!-- attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}"/>-->
|
||||
<!-- <field name="materials_type_id" options="{'no_create': True}" string="刀柄材质"-->
|
||||
<!-- attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"-->
|
||||
<!-- placeholder="请选择"/>-->
|
||||
<!-- <field name="tool_hardness" string="刀柄硬度(hrc)"-->
|
||||
<!-- attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>-->
|
||||
|
||||
<field name="cutting_tool_blade_diameter" string="刃部直径(mm)" class="diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_blade_length"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_blade_width"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_blade_depth"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_blade_helix_angle"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_blade_number" placeholder="请选择"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_blade_tip_working_size"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_blade_tip_diameter" string="刀尖直径(mm)" class="diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_blade_tip_taper" string="刀尖锥度(°)"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<!--刀片-->
|
||||
<label for="tool_length" string="尺寸(mm)"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<div class="test_model"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}">
|
||||
<label for="tool_length" string="长"/>
|
||||
<field name="tool_length" class="o_address_zip"
|
||||
options="{'format': false}"/>
|
||||
<label for="tool_thickness" string="厚"/>
|
||||
<field name="tool_thickness" class="o_address_zip"
|
||||
options="{'format': false}"/>
|
||||
<label for="tool_width" string="宽"/>
|
||||
<field name="tool_width" class="o_address_zip"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
<field name="cutting_tool_cut_blade_length"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_blade_tip_circular_arc_radius"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_blade_tip_height_tolerance"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_inscribed_circle_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_inscribed_circle_tolerance"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_install_aperture_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_chip_breaker_groove"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_cut_depth_max"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_blade_blade_number" string="刃数"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_blade_width" string="刃宽"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
=======
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="tool_height"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_shank_length" string="刀柄长度(mm)"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_shank_diameter" string="刀柄直径(mm)" class="diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_flange_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_flange_length"
|
||||
@@ -330,7 +212,6 @@
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_cut_depth_max"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')],'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
<!--刀杆-->
|
||||
|
||||
<label for="cutting_tool_knife_head_length" string="刀头尺寸(mm)"
|
||||
@@ -339,37 +220,6 @@
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}">
|
||||
<label for="cutting_tool_knife_head_length" string="长"/>
|
||||
<field name="cutting_tool_knife_head_length" class="o_address_zip"
|
||||
<<<<<<< HEAD
|
||||
options="{'format': false}"/>
|
||||
<label for="cutting_tool_knife_head_width" string="宽"/>
|
||||
<field name="cutting_tool_knife_head_width" class="o_address_zip"
|
||||
options="{'format': false}"/>
|
||||
<label for="cutting_tool_knife_head_height" string="高"/>
|
||||
<field name="cutting_tool_knife_head_height" class="o_address_zip"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
<field name="cutting_tool_blade_diameter" string="刃部直径(mm)" class="diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}"/>
|
||||
|
||||
<field name="cutting_tool_blade_length"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')]}"/>
|
||||
|
||||
<field name="cutting_tool_cutter_arbor_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<field name="cutting_tool_cut_blade_length" string="切削刃长度(mm)"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}"/>
|
||||
<field name="cutting_tool_cut_depth_max"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}"/>
|
||||
<field name="cutting_tool_min_machining_aperture"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<field name="cutting_tool_install_blade_tip_num"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<!--刀盘-->
|
||||
<field name="cutting_tool_cutter_head_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')]}"/>
|
||||
<field name="cutting_tool_interface_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')]}"/>
|
||||
=======
|
||||
options="{'format': false}"
|
||||
attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
<label for="cutting_tool_knife_head_width" string="宽"/>
|
||||
@@ -402,7 +252,6 @@
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_interface_diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')],'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
|
||||
<!--夹头-->
|
||||
<label for="cutting_tool_clamping_diameter_min" string="夹持直径"
|
||||
@@ -412,149 +261,16 @@
|
||||
<label for="cutting_tool_clamping_diameter_min" string="最小"/>
|
||||
<field name="cutting_tool_clamping_diameter_min" class="o_address_zip diameter"
|
||||
options="{'format': false}"
|
||||
<<<<<<< HEAD
|
||||
attrs="{'required': [('cutting_tool_type','not in',('夹头','刀柄'))]}"/>
|
||||
=======
|
||||
attrs="{'required': [('cutting_tool_type','not in',('夹头','刀柄'))],'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
<span>(mm)&nbsp;</span>
|
||||
<label for="cutting_tool_clamping_diameter_max" string="最大"/>
|
||||
<field name="cutting_tool_clamping_diameter_max" class="o_address_zip diameter"
|
||||
options="{'format': false}"
|
||||
<<<<<<< HEAD
|
||||
attrs="{'required': [('cutting_tool_type','not in',('夹头','刀柄'))]}"/>
|
||||
<span>(mm)&nbsp;</span>
|
||||
</div>
|
||||
<field name="cutting_tool_clamping_way"
|
||||
attrs="{'invisible': [('cutting_tool_type','not in',('刀柄','夹头'))]}"/>
|
||||
<field name="cutting_tool_top_diameter" class="diameter"
|
||||
attrs='{"invisible": [("cutting_tool_type","!=","夹头")]}'/>
|
||||
<field name="cutting_tool_outer_diameter" class="diameter"
|
||||
attrs='{"invisible": [("cutting_tool_type","!=","夹头")]}'/>
|
||||
<field name="cutting_tool_inner_diameter" class="diameter"
|
||||
attrs='{"invisible": [("cutting_tool_type","!=","夹头")]}'/>
|
||||
<!--夹头-->
|
||||
|
||||
<field name="cutting_tool_standard_speed"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_speed_max"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_change_time"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_cooling_type"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('categ_type', '!=', '刀具')]}">
|
||||
<field name="materials_type_id" options="{'no_create': True}" placeholder="请选择"
|
||||
string="材质"/>
|
||||
<field name="coating_material"/>
|
||||
<field name="cutting_tool_blade_type"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_coarse_medium_fine" string="粗/中/精" placeholder="请选择"
|
||||
attrs="{'required': [('cutting_tool_type','=','整体式刀具')],'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀片'))]}"/>
|
||||
<!--整体式刀具-->
|
||||
<field name="cutting_tool_shank_diameter" string="柄部直径(mm)" class="diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_shank_length"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_neck_diameter" string="颈部直径(mm)" class="diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_neck_length" string="颈部长度(mm)"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_cut_depth"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="cutting_tool_pitch"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}"/>
|
||||
<field name="tool_weight"
|
||||
attrs='{"invisible": [("cutting_tool_type","not in",("夹头","刀柄"))]}'/>
|
||||
<field name="cutting_tool_taper"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('夹头','刀柄'))]}"/>
|
||||
<field name="cutting_tool_jump_accuracy"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_rear_angle"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>
|
||||
<field name="cutting_tool_main_included_angle"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片','刀杆'))]}"/>
|
||||
<!-- <field name="cutting_tool_front_angle"-->
|
||||
<!-- attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>-->
|
||||
<field name="cutting_tool_top_angle"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀片'))]}"/>
|
||||
<field name="cutting_tool_blade_tip_dip_angle"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_side_cutting_edge_angle"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_pitch"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_bladed_teeth_model"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_thickness_tolerance"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_thread_model"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_thread_num"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_cutter_bar_ids" widget="many2many_tags"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<field name="cutting_tool_cutter_pad_ids" widget="many2many_tags"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀片')]}"/>
|
||||
<!--刀柄-->
|
||||
<field name="cutting_tool_is_rough_finish"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_is_finish"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_is_drill_hole"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_is_high_speed_cutting"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
<field name="cutting_tool_is_safety_lock" string="有无安全锁"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')]}"/>
|
||||
|
||||
|
||||
<field name="cutting_tool_jump_accuracy" string="跳动精度(mm)"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}"/>
|
||||
<field name="cutting_tool_max_load_capacity"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}"/>
|
||||
<field name="cutting_tool_er_size_model"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}"/>
|
||||
<field name="cutting_tool_handle_ids" widget="many2many_tags"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}"/>
|
||||
<field name="cooling_suit_type_ids"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')]}"/>
|
||||
<!-- 刀杆 -->
|
||||
<field name="cutting_tool_rear_angle"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<field name="cutting_tool_installing_structure"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}"/>
|
||||
<field name="cutting_tool_is_cooling_hole"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}"/>
|
||||
<field name="cutting_tool_locating_slot_code"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}"/>
|
||||
<field name="cutting_tool_blade_ids" widget="many2many_tags"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}"/>
|
||||
<field name="cutting_tool_tool_shim"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<field name="cutting_tool_cotter_pin"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<field name="cutting_tool_pressing_plate"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')]}"/>
|
||||
<field name="cutting_tool_screw"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀柄'))]}"/>
|
||||
<field name="cutting_tool_wrench"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀柄'))]}"/>
|
||||
<!-- 刀盘 -->
|
||||
<field name="cutting_tool_blade_ids" widget="many2many_tags"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')]}"/>
|
||||
<field name="cutting_tool_blade_ids" widget="many2many_tags"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')]}"/>
|
||||
=======
|
||||
attrs="{'required': [('cutting_tool_type','not in',('夹头','刀柄'))],'readonly': [('id', '!=', False)]}"/>
|
||||
<span>(mm)&nbsp;</span>
|
||||
</div>
|
||||
<field name="cutting_tool_clamping_way"
|
||||
attrs="{'invisible': [('cutting_tool_type','not in',('刀柄','夹头'))],'readonly': [('id', '!=', False)]}"/>
|
||||
attrs="{'invisible': [('cutting_tool_type','not in',('刀柄'))],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_top_diameter" class="diameter"
|
||||
attrs="{'invisible': [('cutting_tool_type','not in',('夹头'))],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_outer_diameter" class="diameter"
|
||||
@@ -593,7 +309,7 @@
|
||||
<field name="tool_weight"
|
||||
attrs='{"invisible": [("cutting_tool_type","not in",("夹头","刀柄"))],"readonly": [("id", "!=", False)]}'/>
|
||||
<field name="cutting_tool_taper"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('夹头','刀柄'))],'readonly': [('id', '!=', False)]}"/>
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('夹头'))],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_taper_shank_model"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀柄')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_dynamic_balance_class"
|
||||
@@ -636,9 +352,9 @@
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_er_size_model"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_handle_id"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')],'readonly': [('id', '!=', False)]}"/>
|
||||
<!-- <field name="cutting_tool_handle_id"-->
|
||||
<!-- options="{'no_create': True}"-->
|
||||
<!-- attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')],'readonly': [('id', '!=', False)]}"/>-->
|
||||
<field name="cooling_suit_type_ids"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '夹头')],'readonly': [('id', '!=', False)]}"/>
|
||||
<!-- 刀杆 -->
|
||||
@@ -650,7 +366,7 @@
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_locating_slot_code"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_blade_id"
|
||||
<field name="cutting_tool_blade_id" options="{'no_create': True}"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_tool_shim"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀杆')],'readonly': [('id', '!=', False)]}"/>
|
||||
@@ -674,47 +390,29 @@
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')],'readonly': [('id', '!=', False)]}"/>
|
||||
<field name="cutting_tool_wrench"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '刀盘')],'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
|
||||
</group>
|
||||
</group>
|
||||
<group string="适配刀片形状"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'in', ('刀柄','夹头','整体式刀具',False))]}">
|
||||
<<<<<<< HEAD
|
||||
<field name="fit_blade_shape_id" string="" widget="many2one_radio"/>
|
||||
=======
|
||||
<field name="fit_blade_shape_id" string="" widget="many2one_radio"
|
||||
attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
</group>
|
||||
<group string="适合加工方式"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀杆','刀盘','刀片'))]}">
|
||||
<field name="suitable_machining_method_ids" string=""
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
attrs="{'readonly': [('id', '!=', False)]}"
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
widget="custom_many2many_checkboxes"/>
|
||||
</group>
|
||||
<group string="刀尖特征"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀杆','刀盘','刀片'))]}">
|
||||
<field name="blade_tip_characteristics_id" string=""
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
attrs="{'readonly': [('id', '!=', False)]}"
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
widget="many2one_radio"/>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀杆','刀盘','刀片'))]}">
|
||||
<group string="柄部类型"
|
||||
attrs="{'invisible': [('cutting_tool_type', '!=', '整体式刀具')]}">
|
||||
<<<<<<< HEAD
|
||||
<field name="handle_type_id" string="" widget="many2one_radio"/>
|
||||
</group>
|
||||
<group string="压紧方式"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}">
|
||||
<field name="compaction_way_id" string="" widget="many2one_radio"/>
|
||||
=======
|
||||
<field name="handle_type_id" string="" widget="many2one_radio"
|
||||
attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
</group>
|
||||
@@ -722,37 +420,25 @@
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('刀杆','刀盘'))]}">
|
||||
<field name="compaction_way_id" string="" widget="many2one_radio"
|
||||
attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
</group>
|
||||
</group>
|
||||
<group attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀杆','刀盘','刀片'))]}">
|
||||
<group string="走刀方向">
|
||||
<<<<<<< HEAD
|
||||
<field name="cutting_direction_ids" string="" widget="custom_many2many_checkboxes"/>
|
||||
</group>
|
||||
<group string="适合冷却液">
|
||||
<field name="suitable_coolant_ids" string="" widget="custom_many2many_checkboxes"/>
|
||||
=======
|
||||
<field name="cutting_direction_ids" string="" widget="custom_many2many_checkboxes"
|
||||
attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
</group>
|
||||
<group string="适合冷却方式">
|
||||
<field name="suitable_coolant_ids" string="" widget="custom_many2many_checkboxes"
|
||||
attrs="{'readonly': [('id', '!=', False)]}"/>
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
</group>
|
||||
</group>
|
||||
<notebook>
|
||||
<page string="切削速度Vc"
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀片'))]}">
|
||||
<<<<<<< HEAD
|
||||
<field name="cutting_speed_ids" string="" widget="one2many">
|
||||
=======
|
||||
<field name="cutting_speed_ids" string="" widget="one2many"
|
||||
attrs="{'readonly': [('id', '!=', False)]}" class="fixTableCss">
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
<tree editable="bottom">
|
||||
<field name="execution_standard_id"/>
|
||||
<field name="execution_standard_id" options="{'no_create': True}"/>
|
||||
<field name="material_code"/>
|
||||
<field name="material_grade"/>
|
||||
<field name="tensile_strength"/>
|
||||
@@ -763,18 +449,13 @@
|
||||
<script src="/sf_dlm_management/static/js/changeCss.js"></script>
|
||||
</page>
|
||||
<page string="每齿走刀量fz"
|
||||
<<<<<<< HEAD
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀片'))]}">
|
||||
<field name="feed_per_tooth_ids" string="" widget="one2many">
|
||||
=======
|
||||
attrs="{'invisible': [('cutting_tool_type', 'not in', ('整体式刀具','刀片'))],'readonly': [('categ_type', '=', '刀具')]}">
|
||||
<field name="feed_per_tooth_ids" string="" widget="one2many"
|
||||
attrs="{'readonly': [('id', '!=', False)]}">
|
||||
>>>>>>> 8695a66e3d9be860f778caba8db5500885f4548f
|
||||
<tree editable="bottom">
|
||||
<!-- <field name="cutting_speed"-->
|
||||
<!-- attrs="{'readonly': [('materials_type_id','!=',False)]}"/>-->
|
||||
<field name="materials_type_id" placeholder="请选择"/>
|
||||
<field name="materials_type_id" options="{'no_create': True}" placeholder="请选择"/>
|
||||
<field name="blade_diameter"/>
|
||||
<field name="feed_per_tooth"/>
|
||||
</tree>
|
||||
@@ -785,8 +466,8 @@
|
||||
<page string="夹具物料参数" attrs="{'invisible': [('categ_type', '!=', '夹具')]}">
|
||||
<group>
|
||||
<group>
|
||||
<field name="brand_id" placeholder="请选择"/>
|
||||
<field name="multi_mounting_type_id" placeholder="请选择"
|
||||
<field name="brand_id" placeholder="请选择" options="{'no_create': True}"/>
|
||||
<field name="multi_mounting_type_id" placeholder="请选择" options="{'no_create': True}"
|
||||
attrs="{'required': [('categ_type', '=', '夹具')]}"/>
|
||||
<field name="length" string="长度(mm)"/>
|
||||
<field name="width" string="宽度(mm)"/>
|
||||
@@ -874,14 +555,16 @@
|
||||
|
||||
<field name="boolean_chip_blowing_function" string="是否有吹屑功能"
|
||||
attrs="{'invisible': [('fixture_material_type', 'not in', ['零点卡盘','零点托盘'])]}"/>
|
||||
<field name="materials_model_id" placeholder="请选择"/>
|
||||
<field name="materials_model_id" placeholder="请选择" options="{'no_create': True}"/>
|
||||
<field name="interface_materials_model_id" placeholder="请选择" string="接口类型"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': [('fixture_material_type', 'not in', ['气动夹具','虎钳夹具','磁吸夹具'])]}"/>
|
||||
<field name="type_of_drive" placeholder="请选择" string="驱动方式"
|
||||
attrs="{'invisible': [('fixture_material_type', 'not in', ['零点托盘','气动夹具','虎钳夹具','磁吸夹具','转接板(锁板)夹具','三爪卡盘'])]}"/>
|
||||
<field name="unlocking_method" string="解锁方式" placeholder="请选择"
|
||||
attrs="{'invisible': [('fixture_material_type', 'not in', ['零点卡盘'])]}"/>
|
||||
<field name="machine_tool_type_id" string="适用机床型号" placeholder="请选择"
|
||||
options="{'no_create': True}"
|
||||
attrs="{'invisible': [('fixture_material_type', 'not in', ['零点卡盘'])]}"/>
|
||||
|
||||
</group>
|
||||
|
||||
82
sf_machine_connect/static/src/js/test.js
Normal file
@@ -0,0 +1,82 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import { browser } from "@web/core/browser/browser";
|
||||
import { Dialog } from "@web/core/dialog/dialog";
|
||||
import { _lt } from "@web/core/l10n/translation";
|
||||
import { useChildRef, useOwnedDialogs, useService } from "@web/core/utils/hooks";
|
||||
import { sprintf } from "@web/core/utils/strings";
|
||||
import { isMobileOS } from "@web/core/browser/feature_detection";
|
||||
import * as BarcodeScanner from "@web/webclient/barcode/barcode_scanner";
|
||||
|
||||
const {xml, Component} = owl;
|
||||
import { standardFieldProps } from "@web/views/fields/standard_field_props";
|
||||
// Import the registry
|
||||
import {registry} from "@web/core/registry";
|
||||
|
||||
|
||||
export class CodeField extends Component {
|
||||
setup() {
|
||||
super.setup();
|
||||
}
|
||||
async onBarcodeBtnClick() {
|
||||
const barcode = await BarcodeScanner.scanBarcode();
|
||||
if (barcode) {
|
||||
await this.onBarcodeScanned(barcode);
|
||||
if ("vibrate" in browser.navigator) {
|
||||
browser.navigator.vibrate(100);
|
||||
}
|
||||
} else {
|
||||
this.notification.add(this.env._t("Please, scan again !"), {
|
||||
type: "warning",
|
||||
});
|
||||
}
|
||||
}
|
||||
async search(barcode) {
|
||||
const results = await this.orm.call("sf.tray", "name_search", [code], {
|
||||
name: barcode,
|
||||
args: this.getDomain(),
|
||||
operator: "ilike",
|
||||
limit: 2, // If one result we set directly and if more than one we use normal flow so no need to search more
|
||||
context: this.context,
|
||||
});
|
||||
return results.map((result) => {
|
||||
const [id, displayName] = result;
|
||||
return {
|
||||
id,
|
||||
name: displayName,
|
||||
};
|
||||
});
|
||||
}
|
||||
async onBarcodeScanned(barcode) {
|
||||
const results = await this.search(barcode);
|
||||
const records = results.filter((r) => !!r.id);
|
||||
if (records.length === 1) {
|
||||
this.update([{ id: records[0].id, name: records[0].name }]);
|
||||
} else {
|
||||
const searchInput = this.autocompleteContainerRef.el.querySelector("input");
|
||||
searchInput.value = barcode;
|
||||
searchInput.dispatchEvent(new Event("input"));
|
||||
if (this.env.isSmall) {
|
||||
searchInput.click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CodeField.template = xml`
|
||||
<button
|
||||
t-on-click="onBarcodeBtnClick"
|
||||
type="button"
|
||||
class="btn ms-3 o_barcode"
|
||||
tabindex="-1"
|
||||
draggable="false"
|
||||
aria-label="Scan barcode"
|
||||
title="Scan barcode"
|
||||
data-tooltip="Scan barcode"
|
||||
/>
|
||||
`;
|
||||
// CodeField.template = 'sf_machine_connect.CodeField';
|
||||
CodeField.props = standardFieldProps;
|
||||
|
||||
// Add the field to the correct category
|
||||
registry.category("fields").add("code", CodeField);
|
||||
@@ -2,19 +2,29 @@
|
||||
<odoo>
|
||||
<record id="workcenter_form_vieww_scan_barcode_search" model="ir.ui.view">
|
||||
<field name="name">work.order.search</field>
|
||||
<!-- <field name="model">mrp.workcenter</field>-->
|
||||
<!-- <field name="model">mrp.workcenter</field>-->
|
||||
<field name="model">mrp.workorder</field>
|
||||
<field name="inherit_id" ref="mrp.view_mrp_production_work_order_search"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='production_id']" position="before">
|
||||
<!-- <field name="name" filter_domain="['|', '|', ('明确的字段内容', 'ilike', self), ('shortdesc', 'ilike', self), ('name', 'ilike', self)]" string="Theme"/>-->
|
||||
<!-- <field name="tray_code" filter_domain="[('production_id.tray_ids.code','=',self)]"/>-->
|
||||
<!-- <field name="production_id"/>-->
|
||||
</xpath>
|
||||
<!-- <xpath expr="//search//group//filter[@name='product']" position="before">-->
|
||||
<!-- <filter string="Tray code" name="traycode" domain="[]" context="{'group_by': 'tray_code'}"/>-->
|
||||
<!-- </xpath>-->
|
||||
<xpath expr="//group" position="before">
|
||||
<searchpanel>
|
||||
<field name="routing_type" select="multi" string="工序类型" icon="fa-building" enable_counters="1"/>
|
||||
<field name="state" select="multi" string="状态" icon="fa-building" enable_counters="1"/>
|
||||
<!-- <field name="manual_quotation" select="multi" string="" icon="fa-building" enable_counters="1"/>-->
|
||||
</searchpanel>
|
||||
|
||||
<!-- <field name="name" filter_domain="['|', '|', ('明确的字段内容', 'ilike', self), ('shortdesc', 'ilike', self), ('name', 'ilike', self)]" string="Theme"/>-->
|
||||
<!-- <field name="tray_code" filter_domain="[('production_id.tray_ids.code','=',self)]"/>-->
|
||||
<!-- <field name="production_id"/>-->
|
||||
</xpath>
|
||||
<!-- <xpath expr="//search//group//filter[@name='product']" position="before">-->
|
||||
<!-- <filter string="Tray code" name="traycode" domain="[]" context="{'group_by': 'tray_code'}"/>-->
|
||||
<!-- </xpath>-->
|
||||
<xpath expr="//filter[@name='date_start_filter']" position="after">
|
||||
<separator/>
|
||||
<filter string="人工编程" name="manual_quotation" domain="[('manual_quotation', '=', True)]"/>
|
||||
<filter string="自动编程" name="no_manual_quotation" domain="[('manual_quotation', '=', False)]"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
@@ -51,7 +51,7 @@ class SfEquipmentSaintenanceStandards(models.Model):
|
||||
domain="[('category_id', '=', maintenance_equipment_category_id)]"
|
||||
)
|
||||
maintenance_standards_ids = fields.One2many('maintenance.standards', 'equipment_maintenance_standards_id',
|
||||
string='维保项目', widget='one2many_list')
|
||||
string='维保项目')
|
||||
eq_maintenance_ids = fields.One2many('maintenance.equipment', 'eq_maintenance_id', string='保养设备')
|
||||
overhaul_ids = fields.One2many('maintenance.equipment', 'overhaul_id', string='检修设备')
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ class SfMaintenanceEquipmentCategory(models.Model):
|
||||
_description = '设备类别'
|
||||
|
||||
equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'),
|
||||
('检测设备', '检测设备')], string='类型', default='机床')
|
||||
('检测设备', '检测设备'), ('其他', '其他')], string='类型', default='机床')
|
||||
equipment_type_code = fields.Char('简写')
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ class SfMaintenanceEquipment(models.Model):
|
||||
default="", string="轴数")
|
||||
|
||||
# 1212新增字段
|
||||
a_axis = fields.Integer('a轴')
|
||||
|
||||
function_type = fields.Selection(
|
||||
[("ZXJGZX", "钻铣加工中心"), ("CXJGZX", "车削加工中心"), ("FHJGZX", "复合加工中心")],
|
||||
default="", string="功能类型")
|
||||
@@ -73,23 +73,23 @@ class SfMaintenanceEquipment(models.Model):
|
||||
straight_cutting_feed_rate = fields.Char('直线切削进给速度(mm/min)')
|
||||
rotary_cutting_feed_rate = fields.Char('回转切削进给速度(mm/min)')
|
||||
|
||||
X_precision = fields.Float('X轴定位精度(mm)', digits=(12, 3))
|
||||
X_precision_repeat = fields.Float('X轴重复定位精度(mm)', digits=(12, 3))
|
||||
Y_precision = fields.Float('Y轴定位精度(mm)', digits=(12, 3))
|
||||
Y_precision_repeat = fields.Float('Y轴重复定位精度(mm)', digits=(12, 3))
|
||||
Z_precision = fields.Float('Z轴定位精度(mm)', digits=(12, 3))
|
||||
Z_precision_repeat = fields.Float('Z轴重复定位精度(mm)', digits=(12, 3))
|
||||
a_precision = fields.Float('a轴定位精度(mm)', digits=(12, 3))
|
||||
a_precision_repeat = fields.Float('a轴重复定位精度(mm)', digits=(12, 3))
|
||||
b_precision = fields.Float('b轴定位精度(mm)', digits=(12, 3))
|
||||
b_precision_repeat = fields.Float('b轴重复定位精度(mm)', digits=(12, 3))
|
||||
c_precision = fields.Float('c轴定位精度(mm)', digits=(12, 3))
|
||||
c_precision_repeat = fields.Float('c轴重复定位精度(mm)', digits=(12, 3))
|
||||
X_precision = fields.Char('X轴定位精度(mm)')
|
||||
X_precision_repeat = fields.Char('X轴重复定位精度(mm)')
|
||||
Y_precision = fields.Char('Y轴定位精度(mm)')
|
||||
Y_precision_repeat = fields.Char('Y轴重复定位精度(mm)')
|
||||
Z_precision = fields.Char('Z轴定位精度(mm)')
|
||||
Z_precision_repeat = fields.Char('Z轴重复定位精度(mm)')
|
||||
a_precision = fields.Char('a轴定位精度(mm)')
|
||||
a_precision_repeat = fields.Char('a轴重复定位精度(mm)')
|
||||
b_precision = fields.Char('b轴定位精度(mm)')
|
||||
b_precision_repeat = fields.Char('b轴重复定位精度(mm)')
|
||||
c_precision = fields.Char('c轴定位精度(mm)')
|
||||
c_precision_repeat = fields.Char('c轴重复定位精度(mm)')
|
||||
|
||||
tool_full_diameter_max = fields.Float('刀具满刀最大直径(mm)')
|
||||
tool_perimeter_diameter_max = fields.Float('刀具邻空刀最大直径(mm)')
|
||||
T_tool_time = fields.Integer('T-T换刀时间(s)')
|
||||
C_tool_time = fields.Integer('C-C换刀时间(s)')
|
||||
T_tool_time = fields.Float('T-T换刀时间(s)', digits=(12, 1))
|
||||
C_tool_time = fields.Float('C-C换刀时间(s)', digits=(12, 1))
|
||||
|
||||
# 待删除字段
|
||||
precision_min = fields.Float('X轴定位精度min(mm)', digits=(12, 3))
|
||||
@@ -104,18 +104,18 @@ class SfMaintenanceEquipment(models.Model):
|
||||
tool_diameter_max = fields.Char('刀具刀径max(mm)')
|
||||
tool_diameter_min = fields.Char('刀具刀径min(mm)')
|
||||
|
||||
def get_no(self):
|
||||
partner = self.env['maintenance.equipment'].sudo().search(
|
||||
[('MTcode', '!=', '')],
|
||||
limit=1,
|
||||
order="id desc")
|
||||
if not partner:
|
||||
num = "%04d" % 1
|
||||
|
||||
else:
|
||||
m = int(partner.MTcode) + 1
|
||||
num = "%04d" % m
|
||||
return num
|
||||
# def get_no(self):
|
||||
# partner = self.env['maintenance.equipment'].sudo().search(
|
||||
# [('MTcode', '!=', '')],
|
||||
# limit=1,
|
||||
# order="id desc")
|
||||
# if not partner:
|
||||
# num = "%04d" % 1
|
||||
#
|
||||
# else:
|
||||
# m = int(partner.MTcode) + 1
|
||||
# num = "%04d" % m
|
||||
# return num
|
||||
|
||||
|
||||
equipment_maintenance_standards_ids = fields.Many2many('equipment.maintenance.standards',
|
||||
@@ -145,10 +145,10 @@ class SfMaintenanceEquipment(models.Model):
|
||||
else:
|
||||
record.equipment_maintenance_standards_ids = False
|
||||
|
||||
MTcode = fields.Char("机台编码", default=get_no)
|
||||
MTcode = fields.Char("机台编码")
|
||||
created_user = fields.Many2one('res.users', string='创建人', default=lambda self: self.env.user)
|
||||
equipment_type = fields.Selection([('机床', '机床'), ('机器人', '机器人'), ('AGV小车', 'AGV小车'),
|
||||
('检测设备', '检测设备')], compute='_compute_category_id')
|
||||
('检测设备', '检测设备'), ('其他', '其他')], compute='_compute_category_id')
|
||||
|
||||
@api.depends('category_id')
|
||||
def _compute_category_id(self):
|
||||
@@ -164,11 +164,12 @@ class SfMaintenanceEquipment(models.Model):
|
||||
number_of_knife_library = fields.Integer('刀库数量(把)')
|
||||
rotate_speed = fields.Integer('转速')
|
||||
# 加工进程
|
||||
a_axis = fields.Char('a轴')
|
||||
x_axis = fields.Integer('X轴')
|
||||
y_axis = fields.Integer('Y轴')
|
||||
z_axis = fields.Integer('Z轴')
|
||||
b_axis = fields.Integer('B轴')
|
||||
c_axis = fields.Integer('C轴')
|
||||
b_axis = fields.Char('B轴')
|
||||
c_axis = fields.Char('C轴')
|
||||
remark = fields.Char('备注')
|
||||
is_binding = fields.Boolean('是否绑定机床', default=False)
|
||||
control_system_id = fields.Many2one('sf.machine.control_system',
|
||||
@@ -178,7 +179,7 @@ class SfMaintenanceEquipment(models.Model):
|
||||
type_id = fields.Many2one('sf.machine_tool.type', '型号')
|
||||
|
||||
state = fields.Selection(
|
||||
[("正常", "正常"), ("故障停机", "故障停机"), ("计划维保", "计划维保"),("空闲", "空闲"),("封存(报废)", "封存(报废)")],
|
||||
[("正常", "正常"), ("故障停机", "故障停机"), ("计划维保", "计划维保"), ("空闲", "空闲"), ("封存(报废)", "封存(报废)")],
|
||||
default='正常', string="机床状态")
|
||||
run_time = fields.Char('总运行时长')
|
||||
# 0606新增字段
|
||||
@@ -191,6 +192,7 @@ class SfMaintenanceEquipment(models.Model):
|
||||
workpiece_load = fields.Char('工件最大负载(kg)')
|
||||
workbench_L = fields.Char('工作台长度(mm)')
|
||||
workbench_W = fields.Char('工作台宽度(mm)')
|
||||
workbench_H = fields.Char('工作台高度(mm)')
|
||||
machine_tool_L = fields.Char('机床长度(mm)')
|
||||
machine_tool_W = fields.Char('机床宽度(mm)')
|
||||
machine_tool_H = fields.Char('机床高度(mm)')
|
||||
@@ -230,7 +232,15 @@ class SfMaintenanceEquipment(models.Model):
|
||||
|
||||
equipment = super(SfMaintenanceEquipment, self).create(vals)
|
||||
if equipment.category_id:
|
||||
equipment.name = equipment.MTcode + '#' + equipment.category_id.name
|
||||
equipment.name = "%s%s" % (equipment.MTcode, equipment.category_id.name)
|
||||
if equipment.category_id.equipment_type == '机床':
|
||||
equipment_id = self.env['maintenance.equipment.oee'].search([('equipment_id', '=', equipment.id)])
|
||||
if not equipment_id:
|
||||
self.env['maintenance.equipment.oee'].sudo().create({
|
||||
'equipment_id': equipment.id,
|
||||
'name': equipment.name,
|
||||
|
||||
})
|
||||
|
||||
# 在创建设备之后执行一些自定义逻辑
|
||||
# ...
|
||||
@@ -376,8 +386,8 @@ class SfMaintenanceEquipment(models.Model):
|
||||
AGV_turning_radius = fields.Char('最小转弯半径')
|
||||
AGV_gradeability_max = fields.Integer('最大爬坡度')
|
||||
AGV_parking_accuracy = fields.Char('停车精度')
|
||||
AGV_load_weight_max = fields.Char('最大负载重量')
|
||||
AGV_weight = fields.Char('本体总重量')
|
||||
AGV_load_weight_max = fields.Char('AGV最大负载重量')
|
||||
AGV_weight = fields.Char('AGV本体总重量')
|
||||
AGV_job_duration = fields.Char('连续作业时长')
|
||||
AGV_transfer_mode = fields.Char('移载方式')
|
||||
AGV_drive_motor_power = fields.Char('驱动电机功率')
|
||||
@@ -387,11 +397,11 @@ class SfMaintenanceEquipment(models.Model):
|
||||
AGV_veer_motor_speed_ratio = fields.Char('转向电机速比')
|
||||
AGV_move_motor_power = fields.Char('前移电机功率')
|
||||
AGV_move_motor_speed_ratio = fields.Char('前移电机速比')
|
||||
AGV_drive_mode = fields.Char('驱动方式')
|
||||
AGV_drive_mode = fields.Char('AGV驱动方式')
|
||||
AGV_navigation_mode = fields.Char('导航方式')
|
||||
AGV_communication_mode = fields.Char('通讯方式')
|
||||
AGV_direction_travel = fields.Char('行走方向')
|
||||
AGV_power_requirements = fields.Char('电源要求')
|
||||
AGV_power_requirements = fields.Char('AGV电源要求')
|
||||
AGV_charge_mode = fields.Selection([('手动', '手动'), ('自动', '自动')], string='充电方式')
|
||||
AGV_security = fields.Char('安全防护')
|
||||
AGV_operating_temperature = fields.Char('环境温度')
|
||||
@@ -408,8 +418,8 @@ class SfMaintenanceEquipment(models.Model):
|
||||
detect_measurement_mode = fields.Selection([('光栅尺', '光栅尺'), ('容栅', '容栅'), ('磁栅', '磁栅'),
|
||||
('激光干涉仪', '激光干涉仪')], string='测量方式')
|
||||
detect_resolution = fields.Char('分辨率')
|
||||
detect_load_weight_max = fields.Char('最大负载重量')
|
||||
detect_weight = fields.Char('本体总重量')
|
||||
detect_load_weight_max = fields.Char('检测设备最大负载重量')
|
||||
detect_weight = fields.Char('检测设备本体总重量')
|
||||
detect_measurement_length = fields.Char('深孔测量长度(max)')
|
||||
detect_control_mode = fields.Char('控制方式')
|
||||
detect_balance_mode_for_Z = fields.Char('Z轴平衡方式')
|
||||
@@ -429,11 +439,11 @@ class SfMaintenanceEquipment(models.Model):
|
||||
robot_gripping_of_workpieces_W = fields.Char('可抓取工件(宽)')
|
||||
robot_gripping_of_workpieces_H = fields.Char('可抓取工件(高)')
|
||||
robot_radius_of_the_boom = fields.Char('展臂半径')
|
||||
robot_load_weight_max = fields.Char('最大负载重量')
|
||||
robot_weight = fields.Char('本体总重量')
|
||||
robot_load_weight_max = fields.Char('机械臂最大负载重量')
|
||||
robot_weight = fields.Char('机械臂本体总重量')
|
||||
robot_repeatable_positioning_accuracy = fields.Char('重复定位精度')
|
||||
robot_axis_num = fields.Selection([('2轴', '2轴'), ('3轴', '3轴'), ('4轴', '4轴'), ('5轴', '5轴'), ('6轴', '6轴'),
|
||||
('7轴', '7轴'), ('8轴', '8轴')], string='轴数')
|
||||
('7轴', '7轴'), ('8轴', '8轴')], string='机械臂轴数')
|
||||
axis_ids = fields.One2many('sf.robot.axis.num', 'equipment_id', string='动作范围')
|
||||
robot_track_dimensions_L = fields.Char('轨道尺寸(长)')
|
||||
robot_track_dimensions_W = fields.Char('轨道尺寸(宽)')
|
||||
@@ -510,6 +520,7 @@ class SfMaintenanceEquipment(models.Model):
|
||||
'lead_screw': item.lead_screw,
|
||||
'workbench_L': item.workbench_L,
|
||||
'workbench_W': item.workbench_W,
|
||||
'workbench_H': item.workbench_H,
|
||||
'guide_rail': item.guide_rail,
|
||||
'machine_tool_L': item.machine_tool_L,
|
||||
'machine_tool_W': item.machine_tool_W,
|
||||
@@ -566,7 +577,7 @@ class SfMaintenanceEquipment(models.Model):
|
||||
'tool_perimeter_diameter_max': item.tool_perimeter_diameter_max,
|
||||
'T_tool_time': item.T_tool_time,
|
||||
'C_tool_time': item.C_tool_time,
|
||||
'jiancheng': item.category_id.equipment_type_code
|
||||
'jiancheng': item.category_id.equipment_type_code,
|
||||
}
|
||||
machine_tool_list.append(val)
|
||||
# kw = machine_tool_list
|
||||
|
||||
@@ -1,24 +1,23 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_equipment_maintenance_standards,equipment_maintenance_standards,model_equipment_maintenance_standards,sf_group_equipment_user,1,1,1,0
|
||||
access_sf_maintenance_logs,sf_maintenance_logs,model_sf_maintenance_logs,sf_group_equipment_user,1,0,0,0
|
||||
access_sf_maintenance_logs,sf_maintenance_logs,model_sf_maintenance_logs,sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment,maintenance_equipment,model_maintenance_equipment,sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_equipment,maintenance_equipment,model_maintenance_equipment,sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_oee,maintenance_equipment_oee,model_maintenance_equipment_oee,sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_equipment_oee,maintenance_equipment_oee,model_maintenance_equipment_oee,sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_oee,maintenance_equipment_oee,model_maintenance_equipment_oee,base.group_user,1,1,1,1
|
||||
access_maintenance_equipment_oee_logs,maintenance_equipment_oee_logs,model_maintenance_equipment_oee_logs,sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_equipment_oee_logs,maintenance_equipment_oee_logs,model_maintenance_equipment_oee_logs,sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_oee_logs,maintenance_equipment_oee_logs,model_maintenance_equipment_oee_logs,base.group_user,1,1,1,1
|
||||
access_maintenance_standards,maintenance_standards,model_maintenance_standards,sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_standards,maintenance_standards,model_maintenance_standards,sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_standard_image,maintenance_standard_image,model_maintenance_standard_image,sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_standard_image,maintenance_standard_image,model_maintenance_standard_image,sf_group_equipment_manager,1,1,1,0
|
||||
access_sf_robot_axis_num,sf_robot_axis_num,model_sf_robot_axis_num,sf_group_equipment_user,1,0,0,0
|
||||
access_sf_robot_axis_num,sf_robot_axis_num,model_sf_robot_axis_num,sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_maintenance_equipment_agv_log,sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_maintenance_equipment_agv_log,sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_maintenance_equipment_agv_log,base.group_user,1,1,1,1
|
||||
access_equipment_maintenance_standards_manager,equipment_maintenance_standards,model_equipment_maintenance_standards,sf_maintenance.sf_group_equipment_manager,1,1,1,1
|
||||
access_equipment_maintenance_standards,equipment_maintenance_standards,model_equipment_maintenance_standards,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_maintenance_logs_sf_group_equipment_user,sf_maintenance_logs,model_sf_maintenance_logs,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_maintenance_logs_sf_group_equipment_manager,sf_maintenance_logs,model_sf_maintenance_logs,sf_maintenance.sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_sf_group_equipment_user,maintenance_equipment,model_maintenance_equipment,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_equipment,maintenance_equipment,model_maintenance_equipment,sf_maintenance.sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_oee_sf_group_equipment_user,maintenance_equipment_oee,model_maintenance_equipment_oee,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_equipment_oee,maintenance_equipment_oee,model_maintenance_equipment_oee,sf_maintenance.sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_oee_logs_sf_group_equipment_user,maintenance_equipment_oee_logs,model_maintenance_equipment_oee_logs,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_equipment_oee_logs,maintenance_equipment_oee_logs,model_maintenance_equipment_oee_logs,sf_maintenance.sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_standards_sf_group_equipment_user,maintenance_standards,model_maintenance_standards,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_standards,maintenance_standards,model_maintenance_standards,sf_maintenance.sf_group_equipment_manager,1,1,1,1
|
||||
access_maintenance_standard_image_sf_group_equipment_user,maintenance_standard_image,model_maintenance_standard_image,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_standard_image,maintenance_standard_image,model_maintenance_standard_image,sf_maintenance.sf_group_equipment_manager,1,1,1,0
|
||||
access_sf_robot_axis_num_sf_group_equipment_user,sf_robot_axis_num,model_sf_robot_axis_num,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_robot_axis_num,sf_robot_axis_num,model_sf_robot_axis_num,sf_maintenance.sf_group_equipment_manager,1,1,1,0
|
||||
access_maintenance_equipment_agv_log_sf_group_equipment_user,maintenance_equipment_agv_log,model_maintenance_equipment_agv_log,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_maintenance_equipment_agv_log,maintenance_equipment_agv_log,model_maintenance_equipment_agv_log,sf_maintenance.sf_group_equipment_manager,1,1,1,0
|
||||
|
||||
|
||||
|
||||
access_maintenance_system_user,equipment.request system user,maintenance.model_maintenance_request,base.group_user,1,0,0,0
|
||||
@@ -29,5 +28,42 @@ access_sf_maintenance_logs_group_plan_dispatch,sf_maintenance_logs,model_sf_main
|
||||
access_maintenance_standard_image_group_plan_dispatch,maintenance_standard_image,model_maintenance_standard_image,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_equipment_maintenance_standards_group_plan_dispatch,equipment_maintenance_standards,model_equipment_maintenance_standards,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_maintenance_standards_group_plan_dispatch,maintenance_standards,model_maintenance_standards,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_maintenance_equipment_agv_log_group_plan_dispatch,maintenance.equipment.agv.log,model_maintenance_equipment_agv_log,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
access_sf_robot_axis_num_group_plan_dispatch,sf.robot.axis.num,model_sf_robot_axis_num,sf_base.group_plan_dispatch,1,0,0,0
|
||||
access_sf_robot_axis_num_group_plan_dispatch,sf.robot.axis.num,model_sf_robot_axis_num,sf_base.group_plan_dispatch,1,0,0,0
|
||||
|
||||
access_sf_machine_tool_sf_group_equipment_user,sf_machine_tool,sf_base.model_sf_machine_tool,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_tool_admin_sf_group_equipment_user,sf_machine_tool_admin,sf_base.model_sf_machine_tool,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_tool_type_sf_group_equipment_user,sf_machine_tool_type,sf_base.model_sf_machine_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_tool_type_admin_sf_group_equipment_user,sf_machine_tool_type_admin,sf_base.model_sf_machine_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_brand_sf_group_equipment_user,sf_machine_brand,sf_base.model_sf_machine_brand,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_brand_admin_sf_group_equipment_user,sf_machine_brand_admin,sf_base.model_sf_machine_brand,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_brand_tags_sf_group_equipment_user,sf_machine_brand_tags,sf_base.model_sf_machine_brand_tags,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_brand_tags_admin_sf_group_equipment_user,sf_machine_brand_tags_admin,sf_base.model_sf_machine_brand_tags,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_control_system_sf_group_equipment_user,sf_machine_control_system,sf_base.model_sf_machine_control_system,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_control_system_admin_sf_group_equipment_user,sf_machine_control_system_admin,sf_base.model_sf_machine_control_system,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_sf_group_equipment_user,sf_production_process,sf_base.model_sf_production_process,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_admin_sf_group_equipment_user,sf_production_process_admin,sf_base.model_sf_production_process,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_materials_sf_group_equipment_user,sf_production_materials,sf_base.model_sf_production_materials,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_materials_admin_sf_group_equipment_user,sf_production_materials_admin,sf_base.model_sf_production_materials,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_materials_model_sf_group_equipment_user,sf_materials_model,sf_base.model_sf_materials_model,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_materials_model_admin_sf_group_equipment_user,sf_materials_model_admin,sf_base.model_sf_materials_model,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
|
||||
access_sf_supplier_sort_sf_group_equipment_user,sf_supplier_sort,sf_base.model_sf_supplier_sort,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_supplier_sort_admin_sf_group_equipment_user,sf_supplier_sort_admin,sf_base.model_sf_supplier_sort,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_parameter_sf_group_equipment_user,sf_production_process_parameter,sf_base.model_sf_production_process_parameter,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_parameter_group_plan_director_sf_group_equipment_user,sf_production_process_parameter_group_plan_director,sf_base.model_sf_production_process_parameter,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_parameter_group_purchase_director_sf_group_equipment_user,sf_production_process_parameter_group_purchase_director,sf_base.model_sf_production_process_parameter,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_parameter_group_sale_director_sf_group_equipment_user,sf_production_process_parameter_group_sale_director,sf_base.model_sf_production_process_parameter,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_parameter_admin_sf_group_equipment_user,sf_production_process_parameter_admin,sf_base.model_sf_production_process_parameter,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_category_sf_group_equipment_user,sf_production_process_category,sf_base.model_sf_production_process_category,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_production_process_category_admin_sf_group_equipment_user,sf_production_process_category_admin,sf_base.model_sf_production_process_category,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_tool_category_sf_group_equipment_user,sf_machine_tool_category,sf_base.model_sf_machine_tool_category,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_machine_tool_category_admin_sf_group_equipment_user,sf_machine_tool_category_admin,sf_base.model_sf_machine_tool_category,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_cutting_tool_material_sf_group_equipment_user,sf_cutting_tool_material,sf_base.model_sf_cutting_tool_material,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_cutting_tool_material_admin_sf_group_equipment_user,sf_cutting_tool_material_admin,sf_base.model_sf_cutting_tool_material,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_cutting_tool_type_sf_group_equipment_user,sf_cutting_tool_type,sf_base.model_sf_cutting_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_cutting_tool_type_admin_sf_group_equipment_user,sf_cutting_tool_type_admin,sf_base.model_sf_cutting_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_cutting_tool_type_group_purchase_director_sf_group_equipment_user,sf_cutting_tool_type_group_purchase_director,sf_base.model_sf_cutting_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_cutting_tool_type_group_sale_director_sf_group_equipment_user,sf_cutting_tool_type_group_sale_director,sf_base.model_sf_cutting_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
access_sf_cutting_tool_type_group_plan_director_sf_group_equipment_user,sf_cutting_tool_type_group_plan_director,sf_base.model_sf_cutting_tool_type,sf_maintenance.sf_group_equipment_user,1,0,0,0
|
||||
|
||||
|
@@ -12,7 +12,7 @@
|
||||
<group>
|
||||
<field name="code" readonly="1" force_save="1"/>
|
||||
<field name="name" readonly="1" force_save="1"/>
|
||||
<field name="maintenance_equipment_category_id" required="1"/>
|
||||
<field name="maintenance_equipment_category_id" required="1" />
|
||||
<field name="eq_maintenance_ids" invisible='1'/>
|
||||
<field name="overhaul_ids" invisible='1'/>
|
||||
|
||||
@@ -31,12 +31,12 @@
|
||||
<notebook>
|
||||
<page string="维保项目">
|
||||
|
||||
<field name="maintenance_standards_ids">
|
||||
<tree editable="bottom">
|
||||
<field name="name"/>
|
||||
<field name="fault_type"/>
|
||||
<field name="maintenance_standards"/>
|
||||
<field name="Period"/>
|
||||
<field name="maintenance_standards_ids" delete="1">
|
||||
<tree editable="bottom" >
|
||||
<field name="name" />
|
||||
<field name="fault_type" />
|
||||
<field name="maintenance_standards" />
|
||||
<field name="Period" />
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
<field name="inherit_id" ref="maintenance.hr_equipment_category_view_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//field[@name='technician_user_id']" position="before">
|
||||
<field name="equipment_type"/>
|
||||
<field name="equipment_type_code" required='1'/>
|
||||
<field name="equipment_type" class="custom_required"/>
|
||||
<field name="equipment_type_code" required='1' class="custom_required"/>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
@@ -76,22 +76,30 @@
|
||||
<field name="equipment_maintenance_id"/>
|
||||
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='user_id']" position="replace">
|
||||
<field name="user_id" string="维保人"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='close_date']" position="replace">
|
||||
<field name="close_date" attrs="{'invisible': [('done', '!=', True)]}" readonly="True" string="维保日期"/>
|
||||
</xpath>
|
||||
|
||||
<sheet>
|
||||
|
||||
<notebook>
|
||||
<page string="维保标准" attrs="{'invisible': [('equipment_maintenance_id', '=', False)]}" context="{'default_standard_id': 'id'}">
|
||||
<field name="maintenance_standards" widget="one2many_list">
|
||||
<tree multi_edit="" editable="">
|
||||
<field name="name" />
|
||||
<field name="maintenance_standards"/>
|
||||
<field name="images" force_save="1" required="1">
|
||||
<field name="name" class="table_custom_required"/>
|
||||
<field name="maintenance_standards" class="table_custom_required"/>
|
||||
<field name="images" force_save="1" required="1" class="table_custom_required">
|
||||
</field>
|
||||
<field name="remark"/>
|
||||
<field name="remark" class="table_custom_required"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
|
||||
</sheet>
|
||||
|
||||
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
type="action"
|
||||
class="oe_stat_button"
|
||||
context="{'search_default_equipment_id': [active_id]}"
|
||||
icon="fa-exchange"
|
||||
attrs="{'invisible': [('state_zc', '!=', '已注册')]}">
|
||||
icon="fa-exchange">
|
||||
<field string="设备oee" name="equipment_oee_ids" widget="statinfo"/>
|
||||
</button>
|
||||
|
||||
@@ -56,12 +55,14 @@
|
||||
<field name="MTcode"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='category_id']" position="after">
|
||||
|
||||
<field name="state_zc" readonly="1"/>
|
||||
<field name="function_type"/>
|
||||
<field name="code" readonly="1"/>
|
||||
<field name="equipment_type" invisible="1"/>
|
||||
<field name="brand_id" force_save="1"/>
|
||||
<field name="brand_id" force_save="1" />
|
||||
<field name="type_id" attrs="{'required': [('equipment_type', '=', '机床')]}"
|
||||
domain="[('brand_id', '=', brand_id)]"/>
|
||||
domain="[('brand_id', '=', brand_id)]" />
|
||||
<field name="machine_tool_category" readonly="1" attrs="{'invisible': [('type_id', '=', False)]}"
|
||||
force_save="1"/>
|
||||
<field name="run_time" force_save="1"/>
|
||||
@@ -72,7 +73,7 @@
|
||||
<group>
|
||||
<group string="基础参数">
|
||||
<field name="control_system_id" attrs="{'required': [('equipment_type', '=', '机床')]}"
|
||||
options="{'no_create': True}"/>
|
||||
options="{'no_create': True}" />
|
||||
<label for="workbench_L" string="工作台尺寸(mm)"/>
|
||||
<div class="test_model">
|
||||
<label for="workbench_L" string="长"/>
|
||||
@@ -84,6 +85,11 @@
|
||||
<field name="workbench_W" class="o_address_zip"
|
||||
attrs="{'required': [('equipment_type', '=', '机床')]}"
|
||||
options="{'format': false}"/>
|
||||
<span>&nbsp;</span>
|
||||
<label for="workbench_H" string="高"/>
|
||||
<field name="workbench_H" class="o_address_zip"
|
||||
attrs="{'required': [('equipment_type', '=', '机床')]}"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
<field name="workpiece_load"/>
|
||||
<label for="machine_tool_L" string="机床尺寸(mm)"/>
|
||||
@@ -128,7 +134,7 @@
|
||||
<!-- <field name="guide_rail" required="1"/>-->
|
||||
<field name="number_of_axles" attrs="{'required': [('equipment_type', '=', '机床')]}"
|
||||
widget="radio"
|
||||
options="{'horizontal': true}"/>
|
||||
options="{'horizontal': true}" />
|
||||
<label for="x_axis" string="加工行程(mm)"
|
||||
attrs="{'invisible': [('number_of_axles', '=', False)]}"/>
|
||||
<div class="test_model"
|
||||
@@ -154,21 +160,44 @@
|
||||
attrs="{'invisible': [('number_of_axles', '=', '三轴')]}"
|
||||
options="{'format': false}"/>
|
||||
<span>&nbsp;</span>
|
||||
<label for="b_axis" string="b"
|
||||
<label for="c_axis" string="c"
|
||||
attrs="{'invisible': [('number_of_axles', 'in', ['三轴','四轴'])]}"/>
|
||||
<field name="b_axis" class="o_address_zip"
|
||||
<field name="c_axis" class="o_address_zip"
|
||||
attrs="{'invisible': [('number_of_axles', 'in', ['三轴','四轴'])]}"
|
||||
options="{'format': false}"/>
|
||||
<span>&nbsp;</span>
|
||||
<label for="c_axis" string="c"
|
||||
<label for="b_axis" string="b"
|
||||
attrs="{'invisible': [('number_of_axles', 'in', ['三轴','四轴','五轴'])]}"/>
|
||||
<field name="c_axis" class="o_address_zip"
|
||||
<field name="b_axis" class="o_address_zip"
|
||||
attrs="{'invisible': [('number_of_axles', 'in', ['三轴','四轴','五轴'])]}"
|
||||
options="{'format': false}"/>
|
||||
</div>
|
||||
</group>
|
||||
<group string="主轴">
|
||||
<field name="taper_type_id" attrs="{'required': [('equipment_type', '=', '机床')]}"/>
|
||||
|
||||
<group string="刀具">
|
||||
<!-- <field name="knife_type" required="1"/>-->
|
||||
<field name="number_of_knife_library"
|
||||
attrs="{'required': [('equipment_type', '=', '机床')]}"/>
|
||||
<!-- <field name="tool_speed" required="1"/>-->
|
||||
<field name="tool_full_diameter_max"/>
|
||||
<field name="tool_perimeter_diameter_max"/>
|
||||
<field name="tool_long_max"/>
|
||||
<!-- <label for="tool_diameter_min" string="刀具刀径(mm)"/>-->
|
||||
<!-- <div class="test_model">-->
|
||||
<!-- <label for="tool_diameter_min" string="最小(min)"/>-->
|
||||
<!-- <field name="tool_diameter_min" class="o_address_zip" required="1"-->
|
||||
<!-- options="{'format': false}"/>-->
|
||||
<!-- <span>&nbsp;</span>-->
|
||||
<!-- <label for="tool_diameter_max" string="最大(max)"/>-->
|
||||
<!-- <field name="tool_diameter_max" class="o_address_zip" required="1"-->
|
||||
<!-- options="{'format': false}"/>-->
|
||||
<!-- </div>-->
|
||||
<field name="tool_quality_max"/>
|
||||
<field name="T_tool_time"/>
|
||||
<field name="C_tool_time"/>
|
||||
</group>
|
||||
<group string="主轴">
|
||||
<field name="taper_type_id" attrs="{'required': [('equipment_type', '=', '机床')]}" />
|
||||
<label for="distance_min" string="主轴端面-工作台距离(mm)"/>
|
||||
<div class="test_model">
|
||||
<label for="distance_min" string="最小(min)"/>
|
||||
@@ -192,40 +221,8 @@
|
||||
|
||||
<!-- <field name="distance" required="1"/>-->
|
||||
</group>
|
||||
<group string="刀具">
|
||||
<!-- <field name="knife_type" required="1"/>-->
|
||||
<field name="number_of_knife_library"
|
||||
attrs="{'required': [('equipment_type', '=', '机床')]}"
|
||||
options="{'format': false}"/>
|
||||
<!-- <field name="tool_speed" required="1"/>-->
|
||||
<field name="tool_full_diameter_max"/>
|
||||
<field name="tool_perimeter_diameter_max"/>
|
||||
<field name="tool_long_max"/>
|
||||
<!-- <label for="tool_diameter_min" string="刀具刀径(mm)"/>-->
|
||||
<!-- <div class="test_model">-->
|
||||
<!-- <label for="tool_diameter_min" string="最小(min)"/>-->
|
||||
<!-- <field name="tool_diameter_min" class="o_address_zip" required="1"-->
|
||||
<!-- options="{'format': false}"/>-->
|
||||
<!-- <span>&nbsp;</span>-->
|
||||
<!-- <label for="tool_diameter_max" string="最大(max)"/>-->
|
||||
<!-- <field name="tool_diameter_max" class="o_address_zip" required="1"-->
|
||||
<!-- options="{'format': false}"/>-->
|
||||
<!-- </div>-->
|
||||
<field name="tool_quality_max"/>
|
||||
<field name="T_tool_time"/>
|
||||
<field name="C_tool_time"/>
|
||||
</group>
|
||||
|
||||
<group string="进给参数">
|
||||
<field name="X_axis_rapid_traverse_speed"/>
|
||||
<field name="Y_axis_rapid_traverse_speed"/>
|
||||
<field name="Z_axis_rapid_traverse_speed"/>
|
||||
<field name="a_axis_rapid_traverse_speed"/>
|
||||
<field name="b_axis_rapid_traverse_speed"/>
|
||||
<field name="c_axis_rapid_traverse_speed"/>
|
||||
<field name="straight_cutting_feed_rate"/>
|
||||
<field name="rotary_cutting_feed_rate"/>
|
||||
</group>
|
||||
|
||||
<group string="精度参数">
|
||||
<field name="X_precision"/>
|
||||
<field name="X_precision_repeat"/>
|
||||
@@ -240,6 +237,16 @@
|
||||
<field name="c_precision"/>
|
||||
<field name="c_precision_repeat"/>
|
||||
</group>
|
||||
<group string="进给参数">
|
||||
<field name="X_axis_rapid_traverse_speed"/>
|
||||
<field name="Y_axis_rapid_traverse_speed"/>
|
||||
<field name="Z_axis_rapid_traverse_speed"/>
|
||||
<field name="a_axis_rapid_traverse_speed"/>
|
||||
<field name="b_axis_rapid_traverse_speed"/>
|
||||
<field name="c_axis_rapid_traverse_speed"/>
|
||||
<field name="straight_cutting_feed_rate"/>
|
||||
<field name="rotary_cutting_feed_rate"/>
|
||||
</group>
|
||||
|
||||
</group>
|
||||
|
||||
@@ -981,7 +988,7 @@
|
||||
<xpath expr="//div[hasclass('o_row')][field[@name='maintenance_duration']]" position="after">
|
||||
|
||||
|
||||
<field name='overhaul_id'/>
|
||||
<field name='overhaul_id' options="{'no_create':True}"/>
|
||||
<field name="overhaul_date" string="下次预防检修"/>
|
||||
<label for="overhaul_period" string="预防检修频次"/>
|
||||
<div class="o_row">
|
||||
@@ -1180,7 +1187,7 @@
|
||||
<field name="name" readonly="1"/>
|
||||
<field name="type" readonly="1"/>
|
||||
<field name="image" widget="image" readonly="1"/>
|
||||
<field name="equipment_id"/>
|
||||
<!-- <field name="equipment_id"/>-->
|
||||
<field name="active" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
'depends': ['sf_base', 'sf_maintenance', 'web_widget_model_viewer', 'sf_warehouse'],
|
||||
'data': [
|
||||
'data/stock_data.xml',
|
||||
'data/empty_racks_data.xml',
|
||||
'security/group_security.xml',
|
||||
'security/ir.model.access.csv',
|
||||
'wizard/workpiece_delivery_views.xml',
|
||||
@@ -24,6 +25,7 @@
|
||||
'views/mrp_workcenter_views.xml',
|
||||
'views/mrp_workorder_view.xml',
|
||||
'views/model_type_view.xml',
|
||||
'views/agv_setting_views.xml',
|
||||
'views/sf_maintenance_equipment.xml',
|
||||
|
||||
],
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
from . import controllers
|
||||
from . import workpiece
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import json
|
||||
from datetime import datetime
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class Manufacturing_Connect(http.Controller):
|
||||
|
||||
@http.route('/AutoDeviceApi/GetWoInfo', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/GetWoInfo', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def get_Work_Info(self, **kw):
|
||||
"""
|
||||
@@ -20,22 +21,29 @@ class Manufacturing_Connect(http.Controller):
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/GetWoInfo'})
|
||||
logging.info('RfidCode:%s' % ret['RfidCode'])
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('rfid_code', '=', ret['RfidCode']), ('routing_type', '=', '装夹预调')])
|
||||
if workorder:
|
||||
for item in workorder:
|
||||
res['Datas'].append({
|
||||
'BillId': item.production_id.name,
|
||||
'ProductionLine': item.production_line,
|
||||
'CraftName': item.name,
|
||||
'Quantity': 1,
|
||||
'MaterialId': item.product_id.default_code,
|
||||
'MaterialName': item.product_id.name,
|
||||
'Spec': '%s×%s×%s' % (item.move_raw_ids.materiel_length, item.move_raw_ids.materiel_width,
|
||||
item.move_raw_ids.materiel_height),
|
||||
'Material': item.product_id.materials_type_id.name
|
||||
})
|
||||
if 'RfidCode' in ret:
|
||||
workorder = request.env['mrp.workorder'].sudo().search([('rfid_code', '=', ret['RfidCode'])])
|
||||
if workorder:
|
||||
for item in workorder:
|
||||
res['Datas'].append({
|
||||
'BillId': item.production_id.name,
|
||||
'ProductionLine': item.production_id.production_line_id.id,
|
||||
'SortId': item.sequence,
|
||||
'CraftName': item.name,
|
||||
'Quantity': 1,
|
||||
'MaterialId': item.product_id.default_code,
|
||||
'MaterialName': item.product_id.name,
|
||||
'Spec': '%s×%s×%s' % (item.move_raw_ids.materiel_length, item.move_raw_ids.materiel_width,
|
||||
item.move_raw_ids.materiel_height),
|
||||
'Material': item.product_id.materials_type_id.name
|
||||
})
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '该rfid暂未有对应的工单'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传RfidCode字段'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_Work_Info error:%s' % e)
|
||||
@@ -54,22 +62,32 @@ class Manufacturing_Connect(http.Controller):
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
ret = json.loads(ret['result'])
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/GetShiftPlan'})
|
||||
if 'ProductionLine' in ret:
|
||||
workorder_ids = request.env['mrp.workorder'].sudo().get_plan_workorder(ret['ProductionLine'])
|
||||
else:
|
||||
ProductionLine = False
|
||||
workorder_ids = request.env['mrp.workorder'].sudo().get_plan_workorder(ProductionLine)
|
||||
# todo 需要筛选出CNC工单
|
||||
logging.info('RfidCode:%s' % ret)
|
||||
workorder = request.env['mrp.workorder'].sudo().search([('name', '=', ret['ProductionLine'])])
|
||||
logging.info('workorder_ids:%s' % workorder_ids)
|
||||
workorder = request.env['mrp.workorder'].sudo().search(workorder_ids)
|
||||
if workorder:
|
||||
for item in workorder:
|
||||
date_planned_start = ''
|
||||
date_planned_finished = ''
|
||||
if item.date_planned_start is not False:
|
||||
logging.info('date_planned_start:%s' % item.date_planned_start)
|
||||
planned_start = item.date_planned_start.strftime("%Y-%m-%d %H:%M:%S")
|
||||
date_planned_start = request.env['sf.sync.common'].sudo().get_add_time(planned_start)
|
||||
if item.date_planned_finished is not False:
|
||||
logging.info('date_planned_finished:%s' % item.date_planned_finished)
|
||||
planned_finished = item.date_planned_finished.strftime("%Y-%m-%d %H:%M:%S")
|
||||
date_planned_finished = request.env['sf.sync.common'].sudo().get_add_time(planned_finished)
|
||||
res['Datas'].append({
|
||||
'BillId': item.production_id.name,
|
||||
'RfidCode': item.RfidCode,
|
||||
'RfidCode': item.rfid_code,
|
||||
'CraftName': item.name,
|
||||
'Quantity': 1,
|
||||
'WortkStart': date_planned_start,
|
||||
@@ -77,7 +95,7 @@ class Manufacturing_Connect(http.Controller):
|
||||
'MaterialId': item.product_id.default_code,
|
||||
'MaterialName': item.product_id.name,
|
||||
# 'Spec':item.mat,
|
||||
'Material': item.materials_type_id.name
|
||||
'Material': item.product_id.materials_type_id.name
|
||||
})
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
@@ -99,23 +117,33 @@ class Manufacturing_Connect(http.Controller):
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
ret = json.loads(ret['result'])
|
||||
logging.info('RfidCode:%s' % ret)
|
||||
workorder = request.env['mrp.workorder'].sudo().search([('routing_type', '=', '前置三元定位检测')])
|
||||
if workorder:
|
||||
for item in workorder:
|
||||
res['Datas'].append({
|
||||
'XOffset': item.production_id.name,
|
||||
'YOffset': item.RfidCode,
|
||||
'ZOffet': item.name,
|
||||
'COffset': 1
|
||||
})
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/QcCheck'})
|
||||
logging.info('RfidCode:%s' % ret['RfidCode'])
|
||||
if 'RfidCode' in ret:
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('routing_type', '=', '装夹预调'), ('rfid_code', '=', ret['RfidCode'])], limit=1, order='id asc')
|
||||
if workorder:
|
||||
for item in workorder:
|
||||
if item.material_center_point:
|
||||
offset = item.material_center_point[1:-1].split(",")
|
||||
res['Datas'].append({
|
||||
'XOffset': 0 if not item.material_center_point else offset[0],
|
||||
'YOffset': 0 if not item.material_center_point else offset[1],
|
||||
'ZOffset': 0 if not item.material_center_point else offset[2],
|
||||
'COffset': 0,
|
||||
'Coordinate': 'G54'
|
||||
})
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '该rfid暂未有对应的工件预调(前置三元检测)工单'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传RfidCode字段'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('get_qcCheck error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/FeedBackStart', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def button_Work_START(self, **kw):
|
||||
"""
|
||||
@@ -125,29 +153,42 @@ class Manufacturing_Connect(http.Controller):
|
||||
"""
|
||||
logging.info('button_Work_START:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
res = {'Succeed': True, 'Datas': ['工单已开始']}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
if not ret['BillId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传制造订单号'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if not ret['CraftId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传工序名称'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if not ret['DeviceId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传设备号'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/FeedBackStart'})
|
||||
production_id = ret['BillId']
|
||||
routing_type = ret['CraftId']
|
||||
equipment_id = ret["DeviceId"]
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
if not workorder:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '该工单不存在'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if workorder.state != 'ready':
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '工单未就绪'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
work_equipment_id = request.env['maintenance.equipment'].sudo().search([('name', '=', equipment_id)],
|
||||
limit=1)
|
||||
if not work_equipment_id:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '没有找到该加工设备'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
workorder.equipment_id = work_equipment_id
|
||||
workorder.button_start()
|
||||
|
||||
# 根据工单的实际开始时间修改排程单的开始时间、状态
|
||||
if workorder.date_start:
|
||||
request.env['sf.production.plan'].sudo().search([('production_id', '=', production_id)]).write(
|
||||
{'actual_start_time': workorder.date_start,
|
||||
'state': 'processing'})
|
||||
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('button_Work_START error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/FeedBackEnd', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def button_Work_End(self, **kw):
|
||||
"""
|
||||
@@ -157,61 +198,384 @@ class Manufacturing_Connect(http.Controller):
|
||||
"""
|
||||
logging.info('button_Work_End:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
res = {'Succeed': True, 'Datas': ['工单已结束']}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
if not ret['BillId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传制造订单号'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if not ret['CraftId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传工序名称'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if not ret['DeviceId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传设备号'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/FeedBackEnd'})
|
||||
production_id = ret['BillId']
|
||||
routing_type = ret['CraftId']
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
if not workorder:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '该工单不存在'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if workorder.state != 'progress':
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '该工单未开始'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
workorder.button_finish()
|
||||
# workorder.process_state = '待解除装夹'
|
||||
# workorder.sudo().production_id.process_state = '待解除装夹'
|
||||
|
||||
# 根据工单的实际结束时间修改排程单的结束时间、状态,同时修改销售订单的状态
|
||||
if workorder.date_finished:
|
||||
request.env['sf.production.plan'].sudo().search([('production_id', '=', production_id)]).write(
|
||||
{'actual_end_time': workorder.date_finished,
|
||||
'state': 'finished'})
|
||||
production_obj = request.env['mrp.production'].sudo().search([('name', '=', production_id)])
|
||||
if production_obj:
|
||||
production_obj.sudo().work_order_state = '已完成'
|
||||
production_obj.write({'state': 'completed'})
|
||||
# request.env['sale.order'].sudo().search(
|
||||
# [('name', '=', production_obj.origin)]).write({'schedule_status': 'to deliver'})
|
||||
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('button_Work_End error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/QcCheck', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
@http.route('/AutoDeviceApi/PartQualityInspect', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def Workorder_QcCheck(self, **kw):
|
||||
def PartQualityInspect(self, **kw):
|
||||
"""
|
||||
零件质检
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('Workorder_QcCheck:%s' % kw)
|
||||
logging.info('PartQualityInspect:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/PartQualityInspect'})
|
||||
production_id = ret['BillId']
|
||||
routing_type = ret['CraftId']
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
if workorder:
|
||||
# workorder.test_results = ret['Quality']
|
||||
logging.info('制造订单:%s' % workorder.production_id.name)
|
||||
if 'ReportPaht' in ret:
|
||||
download_state = request.env['mrp.workorder'].with_user(
|
||||
request.env.ref("base.user_admin")).download_reportfile_tmp(workorder,
|
||||
ret['ReportPaht'])
|
||||
if download_state == 1:
|
||||
detection_ret = request.env['mrp.workorder'].with_user(
|
||||
request.env.ref("base.user_admin")).get_detection_file(workorder, ret['ReportPaht'])
|
||||
if detection_ret is True:
|
||||
stock_picking_type = request.env['stock.picking.type'].sudo().search(
|
||||
[('sequence_code', '=', 'SFP')])
|
||||
if stock_picking_type:
|
||||
stock_picking = request.env['stock.picking'].sudo().search(
|
||||
[('product_id', '=', workorder.product_id.id),
|
||||
('origin', '=', workorder.production_id.origin),
|
||||
('picking_type_id', '=', stock_picking_type.id)])
|
||||
if stock_picking:
|
||||
quality_check = request.env['quality.check'].sudo().search(
|
||||
[('product_id', '=', workorder.product_id.id),
|
||||
('picking_id', '=', stock_picking.id)])
|
||||
if quality_check:
|
||||
logging.info('质检单:%s' % quality_check.name)
|
||||
quality_check.write({'report_pdf': workorder.detection_report})
|
||||
elif download_state == 2:
|
||||
res = {'Succeed': False, 'ErrorCode': 205,
|
||||
'Error': 'ReportPaht中的工件号与制造订单%s不匹配,请检查ReportPaht是否正确' % workorder.production_id.name}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 204, 'Error': '检测报告文件从FTP拉取失败'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '未传ReportPaht字段'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 206, 'Error': '未查询到工单'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('PartQualityInspect error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/CMMProgDolod', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def CMMProgDolod(self, **kw):
|
||||
"""
|
||||
中控系统传递RFID编号给MES,获取测量程序文件。Ftp下载文件
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('CMMProgDolod:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
if not ret['BillId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传制造订单号'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if not ret['CraftId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传工序名称'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if not ret['DeviceId']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传设备号'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if not ret['Quality']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传检测结果'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if not ret['ReportPaht']:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未传检查报告文件(地址)'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
production_id = ret['BillId']
|
||||
routing_type = ret['CraftId']
|
||||
request.env['mrp.workorder'].sudo().search(
|
||||
[('production_id', '=', production_id), ('routing_type', '=', routing_type)], limit=1)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/CMMProgDolod'})
|
||||
if 'RfidCode' in ret:
|
||||
logging.info('RfidCode:%s' % ret['RfidCode'])
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('rfid_code', '=', ret['RfidCode']), ('routing_type', '=', 'CNC加工')])
|
||||
if workorder:
|
||||
for item in workorder.cmm_ids:
|
||||
if item.program_date is not False:
|
||||
program_date = item.program_date.strftime("%Y-%m-%d %H:%M:%S")
|
||||
program_date_str = request.env['sf.sync.common'].sudo().get_add_time(program_date)
|
||||
res['Datas'].append({
|
||||
'CraftId': workorder.id,
|
||||
'CraftKey': workorder.name,
|
||||
'ProgramDate': '' if not item.program_date else program_date_str,
|
||||
'ProgramPath': item.program_path,
|
||||
'PostProcessing': item.post_processing_name,
|
||||
})
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '暂无工单及对应的CNC程序数据'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传RfidCode字段'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('Workorder_QcCheck error:%s' % e)
|
||||
logging.info('CMMProgDolod error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/NCProgDolod', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def NCProgDolod(self, **kw):
|
||||
"""
|
||||
中控系统传递RFID编号给MES,获取程序单及程序文件。Ftp下载文件
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('NCProgDolod:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/NCProgDolod'})
|
||||
if 'RfidCode' in ret:
|
||||
logging.info('RfidCode:%s' % ret['RfidCode'])
|
||||
workorder = request.env['mrp.workorder'].sudo().search(
|
||||
[('rfid_code', '=', ret['RfidCode']), ('routing_type', '=', 'CNC加工')])
|
||||
if workorder:
|
||||
for item in workorder.cnc_ids:
|
||||
res['Datas'].append({
|
||||
'CraftId': workorder.id,
|
||||
'CraftName': workorder.name,
|
||||
'SortId': item.sequence_number,
|
||||
'ProgramName': item.program_name,
|
||||
'ToolId': item.cutting_tool_no,
|
||||
'ToolName': item.cutting_tool_name,
|
||||
'Depth': item.depth_of_processing_z,
|
||||
'ProgramPath': item.program_path,
|
||||
'ProgramTime': item.estimated_processing_time,
|
||||
})
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '暂无工单及对应的CNC程序数据'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传RfidCode字段'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('NCProgDolod error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/LocationChange', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def LocationChange(self, **kw):
|
||||
"""
|
||||
库位变更
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('LocationChange:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True, 'Datas': []}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/LocationChange'})
|
||||
logging.info('LocationChange_ret===========:%s' % ret)
|
||||
RfidCode = ret['RfidCode']
|
||||
ChangeType = ret['ChangeType']
|
||||
OldDeciveId = ret['OldDeciveId']
|
||||
OldPosition = ret['OldPosition']
|
||||
NewDeciveId = ret['NewDeciveId']
|
||||
NewPosition = ret['NewPosition']
|
||||
OldDeciveStart = ret['OldDeciveStart']
|
||||
OldDeciveEnd = ret['OldDeciveEnd']
|
||||
|
||||
temp_val_sn_id = None
|
||||
old_localtion = None
|
||||
# if ChangeType == 'Part' or ChangeType == 'Tool':
|
||||
stock_lot_obj = request.env['stock.lot'].sudo().search(
|
||||
[('rfid', '=', RfidCode)], limit=1)
|
||||
logging.info('stock_lot_obj===========:%s' % stock_lot_obj)
|
||||
if not stock_lot_obj:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '未根据RfidCode找到该产品'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if OldPosition:
|
||||
old_localtion = request.env['sf.shelf.location'].sudo().search(
|
||||
[('barcode', '=', OldPosition)], limit=1)
|
||||
logging.info('old_localtion===========:%s' % old_localtion)
|
||||
new_localtion = request.env['sf.shelf.location'].sudo().search(
|
||||
[('barcode', '=', NewPosition)], limit=1)
|
||||
logging.info('new_localtion===========:%s' % new_localtion)
|
||||
if not new_localtion:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': '没有该目标位置'}
|
||||
return json.JSONEncoder().encode(res)
|
||||
if old_localtion:
|
||||
temp_val_sn_id = old_localtion.product_sn_id
|
||||
logging.info('temp_val_sn_id===========:%s' % temp_val_sn_id)
|
||||
old_localtion.product_sn_id = None
|
||||
new_localtion.product_sn_id = temp_val_sn_id
|
||||
logging.info('====1======')
|
||||
else:
|
||||
new_localtion.product_sn_id = stock_lot_obj.id
|
||||
logging.info('=====2======')
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('LocationChange error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/AGVToProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def AGVToProduct(self, **kw):
|
||||
"""
|
||||
AGV运送上产线(完成)
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('AGVToProduct:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/AGVToProduct'})
|
||||
logging.info('ret:%s' % ret)
|
||||
if 'DeviceId' in ret:
|
||||
logging.info('DeviceId:%s' % ret['DeviceId'])
|
||||
if 'IsComplete' in ret:
|
||||
if ret['IsComplete'] is True or ret['IsComplete'] is False:
|
||||
for i in range(1, 5):
|
||||
logging.info('F-RfidCode:%s' % i)
|
||||
if f'RfidCode{i}' in ret:
|
||||
rfid_code = ret[f'RfidCode{i}']
|
||||
logging.info('RfidCode:%s' % rfid_code)
|
||||
domain = [
|
||||
('feeder_station_destination_id.name', '=', ret['DeviceId']),
|
||||
('workorder_id.rfid_code', '=', rfid_code),
|
||||
('status', '=', '已配送'),
|
||||
('type', '=', '上产线')
|
||||
]
|
||||
workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(domain,
|
||||
order='id asc')
|
||||
if workpiece_delivery:
|
||||
for wd in workpiece_delivery:
|
||||
logging.info('wd.production_id:%s' % wd.production_id.name)
|
||||
if wd.workorder_id.state == 'done' and wd.production_id.production_line_state == '待上产线':
|
||||
logging.info(
|
||||
'wd.production_line_state:%s' % wd.production_id.production_line_state)
|
||||
wd.production_id.write({'production_line_state': '已上产线'})
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 204,
|
||||
'Error': 'DeviceId为%s没有对应的已配送工件数据' % ret['DeviceId']}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '未传IsComplete字段'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传DeviceId字段'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('AGVToProduct error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/AGVDownProduct', type='json', auth='sf_token', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def AGVDownProduct(self, **kw):
|
||||
"""
|
||||
MES调度AGV,搬运零件AGV托盘到产线接驳站。
|
||||
生产线接受到零件AGV托盘到位信号后,把生产合格或特采的零件,机器人搬运零件到AGV接驳站中,触发AGV运送下产线接口。
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('AGVDownProduct:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/AGVDownProduct'})
|
||||
logging.info('ret:%s' % ret)
|
||||
if 'DeviceId' in ret:
|
||||
logging.info('DeviceId:%s' % ret['DeviceId'])
|
||||
delivery_Arr = []
|
||||
if 'IsComplete' in ret:
|
||||
if ret['IsComplete'] is True or ret['IsComplete'] is False:
|
||||
for i in range(1, 5):
|
||||
logging.info('F-RfidCode:%s' % i)
|
||||
if f'RfidCode{i}' in ret:
|
||||
rfid_code = ret[f'RfidCode{i}']
|
||||
logging.info('RfidCode:%s' % rfid_code)
|
||||
domain = [
|
||||
('workorder_id.rfid_code', '=', rfid_code),
|
||||
('status', '=', '待下发'),
|
||||
('type', '=', '下产线')
|
||||
]
|
||||
workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(domain,
|
||||
order='id asc')
|
||||
if workpiece_delivery:
|
||||
for wd in workpiece_delivery:
|
||||
logging.info('wd.production_id:%s' % wd.production_id.name)
|
||||
if wd.workorder_id.state == 'done' and wd.production_id.production_line_state == '已上产线':
|
||||
logging.info(
|
||||
'wd.production_line_state:%s' % wd.production_id.production_line_state)
|
||||
wd.production_id.write({'production_line_state': '已下产线'})
|
||||
delivery_Arr.append(wd.id)
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 204,
|
||||
'Error': 'DeviceId为%s没有对应的已配送工件数据' % ret['DeviceId']}
|
||||
if delivery_Arr:
|
||||
logging.info('delivery_Arr:%s' % delivery_Arr)
|
||||
delivery_workpiece = request.env['sf.workpiece.delivery'].sudo().search(
|
||||
[('id', 'in', delivery_Arr)])
|
||||
if delivery_workpiece:
|
||||
logging.info('开始向agv下发下产线任务')
|
||||
is_free = delivery_workpiece._check_avgsite_state()
|
||||
if is_free is True:
|
||||
delivery_workpiece._delivery_avg()
|
||||
logging.info('agv下发下产线任务下发完成')
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': '未传IsComplete字段'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('AGVDownProduct error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
@http.route('/AutoDeviceApi/EquipmentBaseCoordinate', type='json', auth='sf_token', methods=['GET', 'POST'],
|
||||
csrf=False,
|
||||
cors="*")
|
||||
def PutEquipmentBaseCoordinate(self, **kw):
|
||||
"""
|
||||
获取机床基坐标
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('PutEquipmentBaseCoordinate:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
request.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/EquipmentBaseCoordinate'})
|
||||
if 'DeviceId' in ret:
|
||||
equipment = request.env['maintenance.equipment'].sudo().search('name', '=', ret['DeviceId'])
|
||||
if equipment:
|
||||
equipment.sudo().write({
|
||||
'base_coordinate_fixture_model_id': ret['base_coordinate_fixture_model_id'],
|
||||
'base_coordinate_g_coordinate': ret['base_coordinate_g_coordinate'],
|
||||
'base_coordinate_x': ret['base_coordinate_x'],
|
||||
'base_coordinate_y': ret['base_coordinate_y'],
|
||||
'base_coordinate_z': ret['base_coordinate_z'],
|
||||
})
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203, 'Error': 'DeviceId为%s的设备不存在!' % ret['DeviceId']}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传DeviceId字段'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('AGVDownProduct error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
|
||||
44
sf_manufacturing/controllers/workpiece.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import json
|
||||
from datetime import datetime
|
||||
from odoo import http
|
||||
from odoo.http import request
|
||||
|
||||
|
||||
class Workpiece(http.Controller):
|
||||
|
||||
@http.route('/agvApi/backfeed', type='json', auth='none', methods=['GET', 'POST'], csrf=False,
|
||||
cors="*")
|
||||
def backfeed(self, **kw):
|
||||
"""
|
||||
agv小车反馈工单(工件)结果
|
||||
:param kw:
|
||||
:return:
|
||||
"""
|
||||
logging.info('backfeed:%s' % kw)
|
||||
try:
|
||||
res = {'Succeed': True}
|
||||
datas = request.httprequest.data
|
||||
ret = json.loads(datas)
|
||||
logging.info('backfeed-ret:%s' % ret)
|
||||
if 'reqCode' in ret:
|
||||
if 'method' in ret:
|
||||
if ret['method'] == 'end':
|
||||
req_codes = ret['reqCode'].split(',')
|
||||
for req_code in req_codes:
|
||||
workpiece_delivery = request.env['sf.workpiece.delivery'].sudo().search(
|
||||
[('name', '=', req_code.strip()), ('task_completion_time', '=', False)])
|
||||
if workpiece_delivery:
|
||||
workpiece_delivery.write({'status': '已配送', 'task_completion_time': datetime.now()})
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 203,
|
||||
'Error': '该reqCode暂未查到对应的工件配送记录'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 204, 'Error': '未传method字段'}
|
||||
else:
|
||||
res = {'Succeed': False, 'ErrorCode': 201, 'Error': '未传reqCode字段'}
|
||||
except Exception as e:
|
||||
res = {'Succeed': False, 'ErrorCode': 202, 'Error': e}
|
||||
logging.info('backfeed error:%s' % e)
|
||||
return json.JSONEncoder().encode(res)
|
||||
48
sf_manufacturing/data/empty_racks_data.xml
Normal file
@@ -0,0 +1,48 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="sequence_workpiece_delivery" model="ir.sequence">
|
||||
<field name="name">工件配送</field>
|
||||
<field name="code">sf.workpiece.delivery</field>
|
||||
<field name="prefix">WDO%(year)s%(month)s%(day)s</field>
|
||||
<field name="padding">4</field>
|
||||
<field name="company_id" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="workpiece_delivery_empty_racks_1" model="sf.workpiece.delivery">
|
||||
<field name="name">运送空料架路线:C01-A01</field>
|
||||
<field name="type">运送空料架</field>
|
||||
<field name="route_id"
|
||||
search="[('start_site_id.name','=','C01'),('end_site_id.name','=','A01')]"/>
|
||||
<field name="feeder_station_start_id" search="[('name','=','C01')]"/>
|
||||
<field name="feeder_station_destination_id" search="[('name','=','A01')]"/>
|
||||
</record>
|
||||
|
||||
<record id="workpiece_delivery_empty_racks_2" model="sf.workpiece.delivery">
|
||||
<field name="name">运送空料架路线:B01-B02</field>
|
||||
<field name="type">运送空料架</field>
|
||||
<field name="route_id"
|
||||
search="[('start_site_id.name','=','B01'),('end_site_id.name','=','B02')]"/>
|
||||
<field name="feeder_station_start_id" search="[('name','=','B01')]"/>
|
||||
<field name="feeder_station_destination_id" search="[('name','=','B02')]"/>
|
||||
</record>
|
||||
|
||||
<record id="workpiece_delivery_empty_racks_3" model="sf.workpiece.delivery">
|
||||
<field name="name">运送空料架路线:B01-A01</field>
|
||||
<field name="type">运送空料架</field>
|
||||
<field name="route_id"
|
||||
search="[('start_site_id.name','=','B01'),('end_site_id.name','=','A01')]"/>
|
||||
<field name="feeder_station_start_id" search="[('name','=','B01')]"/>
|
||||
<field name="feeder_station_destination_id" search="[('name','=','A01')]"/>
|
||||
</record>
|
||||
|
||||
<record id="workpiece_delivery_empty_racks_4" model="sf.workpiece.delivery">
|
||||
<field name="name">运送空料架路线:C01-B02</field>
|
||||
<field name="type">运送空料架</field>
|
||||
<field name="route_id"
|
||||
search="[('start_site_id.name','=','C01'),('end_site_id.name','=','B02')]"/>
|
||||
<field name="feeder_station_start_id" search="[('name','=','C01')]"/>
|
||||
<field name="feeder_station_destination_id" search="[('name','=','B02')]"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="1">
|
||||
<record id="sequence_routing_workcenter" model="ir.sequence">
|
||||
<record id="sequence_routing_workcenter" model="ir.sequence">
|
||||
<field name="name">工序编码规则</field>
|
||||
<field name="code">mrp.routing.workcenter</field>
|
||||
<field name="padding">4</field>
|
||||
@@ -67,5 +67,32 @@
|
||||
search="[('barcode','=','WH-PREPRODUCTION')]"/>
|
||||
<field name="default_location_dest_id" ref="stock_location_locations_virtual_outcontract"/>
|
||||
</record>
|
||||
|
||||
<record id="route_surface_technology_outsourcing" model="stock.route">
|
||||
<field name="name">表面工艺外协</field>
|
||||
<!-- <field name="company_id"></field>-->
|
||||
<field name="active">True</field>
|
||||
<field name="sequence">11</field>
|
||||
</record>
|
||||
<!-- <record id="rule_surface_technology_in" model="stock.rule">-->
|
||||
<!-- <field name="name">外协出库单</field>-->
|
||||
<!-- <field name="route_id" ref="route_surface_technology_outsourcing"/>-->
|
||||
<!--<!– <field name="action">push</field>–>-->
|
||||
<!-- <field name="pick_type_id" ref="outcontract_picking_in"/>-->
|
||||
<!-- <!– <field name="location_src_id" search="[('barcode','=','WH-PREPRODUCTION')]"/>–>-->
|
||||
<!-- <!– <field name="location_dest_id" ref="stock_location_locations_virtual_outcontract"/>–>-->
|
||||
<!-- <!– <field name="active">True</field>–>-->
|
||||
<!-- <!– <field name="sequence">11</field>–>-->
|
||||
<!-- </record>-->
|
||||
<!-- <record id="rule_surface_technology_in" model="stock.rule">-->
|
||||
<!-- <field name="name">外协入库单</field>-->
|
||||
<!-- <field name="route_id" ref="route_surface_technology_outsourcing"/>-->
|
||||
<!-- <field name="action">pull</field>-->
|
||||
<!-- <field name="pick_type_id" ref="outcontract_picking_out"/>-->
|
||||
<!-- <field name="location_src_id" ref="stock_location_locations_virtual_outcontract"/>-->
|
||||
<!-- <field name="location_dest_id" search="[('barcode','=','WH-PREPRODUCTION')]"/>-->
|
||||
<!-- <field name="active">True</field>-->
|
||||
<!-- <field name="sequence">11</field>-->
|
||||
<!-- </record>-->
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -8,3 +8,4 @@ from . import mrp_routing_workcenter
|
||||
from . import stock
|
||||
from . import res_user
|
||||
from . import production_line_base
|
||||
from . import agv_setting
|
||||
|
||||
68
sf_manufacturing/models/agv_setting.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import requests
|
||||
import logging
|
||||
import time
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class AgvSetting(models.Model):
|
||||
_name = 'sf.agv.site'
|
||||
_description = 'agv站点'
|
||||
|
||||
name = fields.Char('位置编号')
|
||||
owning_region = fields.Char('所属区域')
|
||||
state = fields.Selection([
|
||||
('占用', '占用'),
|
||||
('空闲', '空闲')], string='状态')
|
||||
divide_the_work = fields.Char('主要分工')
|
||||
active = fields.Boolean('有效', default=True)
|
||||
|
||||
def update_site_state(self):
|
||||
# 调取中控的接驳站接口并修改对应站点的状态
|
||||
config = self.env['res.config.settings'].get_values()
|
||||
# token = sf_sync_config['token'Ba F2CF5DCC-1A00-4234-9E95-65603F70CC8A]
|
||||
headers = {'Authorization': config['center_control_Authorization']}
|
||||
center_control_url = config['center_control_url'] + "/AutoDeviceApi/GetAgvStationState?date="
|
||||
timestamp = int(time.time())
|
||||
center_control_url += str(timestamp)
|
||||
logging.info('工件配送-请求中控地址:%s' % center_control_url)
|
||||
center_control_r = requests.get(center_control_url, params={}, headers=headers)
|
||||
ret = center_control_r.json()
|
||||
logging.info('工件配送-请求中控站点信息:%s' % ret)
|
||||
self.env['center_control.interface.log'].sudo().create(
|
||||
{'content': ret, 'name': 'AutoDeviceApi/GetAgvStationState?date=%s' % str(timestamp)})
|
||||
if ret['Succeed'] is True:
|
||||
datas = ret['Datas']
|
||||
for item in self:
|
||||
for da in datas:
|
||||
if da['DeviceId'] == item.name:
|
||||
if da['AtHome'] is True:
|
||||
item.state = '占用'
|
||||
else:
|
||||
item.state = '空闲'
|
||||
|
||||
|
||||
class AgvTaskRoute(models.Model):
|
||||
_name = 'sf.agv.task.route'
|
||||
_description = 'agv任务路线'
|
||||
|
||||
name = fields.Char('名称')
|
||||
type = fields.Selection([
|
||||
('F01', '搬运'), ], string='任务类型', default="F01")
|
||||
route_type = fields.Selection([
|
||||
('上产线', '上产线'), ('下产线', '下产线'), ('运送空料架', '运送空料架')], string='类型')
|
||||
start_site_id = fields.Many2one('sf.agv.site', '起点接驳站位置编号')
|
||||
end_site_id = fields.Many2one('sf.agv.site', '终点接驳站位置编号')
|
||||
destination_production_line_id = fields.Many2one('sf.production.line', '目的生产线')
|
||||
active = fields.Boolean('有效', default=True)
|
||||
|
||||
|
||||
class Center_controlInterfaceLog(models.Model):
|
||||
_name = 'center_control.interface.log'
|
||||
_description = '中控接口调用日志'
|
||||
_order = 'id desc'
|
||||
|
||||
name = fields.Char('接口名称')
|
||||
content = fields.Char('接口内容')
|
||||
interface_call_date = fields.Datetime("调用时间", default=fields.Datetime.now, readonly=True)
|
||||
active = fields.Boolean('有效', default=True)
|
||||
@@ -21,7 +21,8 @@ class ProductModelTypeRoutingSort(models.Model):
|
||||
_description = '成品工序排序'
|
||||
|
||||
sequence = fields.Integer('Sequence')
|
||||
route_workcenter_id = fields.Many2one('mrp.routing.workcenter')
|
||||
route_workcenter_id = fields.Many2one('mrp.routing.workcenter',
|
||||
domain=[('routing_type', 'in', ['装夹预调', 'CNC加工', '解除装夹'])])
|
||||
is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat')
|
||||
|
||||
# routing_type = fields.Selection([
|
||||
@@ -54,7 +55,7 @@ class EmbryoModelTypeRoutingSort(models.Model):
|
||||
_description = '坯料工序排序'
|
||||
|
||||
sequence = fields.Integer('Sequence')
|
||||
route_workcenter_id = fields.Many2one('mrp.routing.workcenter')
|
||||
route_workcenter_id = fields.Many2one('mrp.routing.workcenter', domain=[('routing_type', 'in', ['切割'])])
|
||||
is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat')
|
||||
|
||||
# routing_type = fields.Selection([
|
||||
@@ -87,7 +88,7 @@ class SurfaceTechnicsModelTypeRoutingSort(models.Model):
|
||||
_description = '表面工艺工序排序'
|
||||
|
||||
sequence = fields.Integer('Sequence')
|
||||
route_workcenter_id = fields.Many2one('mrp.routing.workcenter')
|
||||
route_workcenter_id = fields.Many2one('mrp.routing.workcenter', domain=[('routing_type', 'in', ['表面工艺'])])
|
||||
is_repeat = fields.Boolean('重复', related='route_workcenter_id.is_repeat')
|
||||
|
||||
# routing_type = fields.Selection([
|
||||
|
||||
@@ -3,6 +3,7 @@ import base64
|
||||
import logging
|
||||
import re
|
||||
import requests
|
||||
from itertools import groupby
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.addons.sf_base.commons.common import Common
|
||||
@@ -20,6 +21,8 @@ class MrpProduction(models.Model):
|
||||
model_file = fields.Binary('模型文件', related='product_id.model_file')
|
||||
schedule_state = fields.Selection([('未排', '未排'), ('已排', '已排'), ('已完成', '已完成')],
|
||||
string='排程状态', default='未排')
|
||||
work_order_state = fields.Selection([('未排', '未排'), ('已排', '已排'), ('已完成', '已完成')],
|
||||
string='工单状态', default='未排')
|
||||
|
||||
# state = fields.Selection(selection_add=[
|
||||
# ('pending_scheduling', '待排程'),
|
||||
@@ -30,7 +33,9 @@ class MrpProduction(models.Model):
|
||||
('draft', 'Draft'),
|
||||
('confirmed', 'Confirmed'),
|
||||
('progress', '待排程'),
|
||||
('pending_cam', '待装夹'),
|
||||
('pending_processing', '待加工'),
|
||||
('pending_era_cam', '待解除装夹'),
|
||||
('completed', '已完工'),
|
||||
('to_close', 'To Close'),
|
||||
('done', 'Done'),
|
||||
@@ -52,11 +57,30 @@ class MrpProduction(models.Model):
|
||||
glb_file = fields.Binary("glb模型文件")
|
||||
production_line_id = fields.Many2one('sf.production.line', string='生产线')
|
||||
plan_start_processing_time = fields.Datetime('计划开始加工时间')
|
||||
production_line_state = fields.Selection(
|
||||
[('待上产线', '待上产线'), ('已上产线', '已上产线'), ('已下产线', '已下产线')],
|
||||
string='上/下产线', default='待上产线')
|
||||
# 工序状态
|
||||
# Todo 研究下用法
|
||||
process_state = fields.Selection([
|
||||
('待装夹', '待装夹'),
|
||||
('待检测', '待检测'),
|
||||
('待加工', '待加工'),
|
||||
('待解除装夹', '待解除装夹'),
|
||||
('已完工', '已完工'),
|
||||
], string='工序状态', default='待装夹')
|
||||
|
||||
# 零件图号
|
||||
part_number = fields.Char('零件图号')
|
||||
|
||||
# 上传零件图纸
|
||||
part_drawing = fields.Binary('零件图纸')
|
||||
|
||||
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
|
||||
|
||||
@api.depends(
|
||||
'move_raw_ids.state', 'move_raw_ids.quantity_done', 'move_finished_ids.state',
|
||||
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state')
|
||||
'workorder_ids.state', 'product_qty', 'qty_producing', 'schedule_state', 'process_state')
|
||||
def _compute_state(self):
|
||||
for production in self:
|
||||
if not production.state or not production.product_uom_id:
|
||||
@@ -88,9 +112,17 @@ class MrpProduction(models.Model):
|
||||
production.state = 'progress'
|
||||
|
||||
# 新添加的状态逻辑
|
||||
if production.state == 'progress' and production.schedule_state == '已排':
|
||||
if production.state == 'progress' and production.schedule_state == '已排' and production.process_state == '待装夹':
|
||||
# production.state = 'pending_processing'
|
||||
production.state = 'pending_cam'
|
||||
if production.state == 'progress' and production.schedule_state == '已排' and production.process_state == '待加工':
|
||||
# if production.state == 'pending_cam' and production.process_state == '待加工':
|
||||
production.state = 'pending_processing'
|
||||
elif production.state == 'progress' and production.schedule_state == '已完成':
|
||||
elif production.state == 'progress' and production.process_state == '待解除装夹':
|
||||
production.state = 'pending_era_cam'
|
||||
elif production.state == 'progress' and production.process_state == '已完工':
|
||||
production.state = 'completed'
|
||||
elif production.state == 'progress' and production.work_order_state == '已完成':
|
||||
production.state = 'completed'
|
||||
|
||||
def action_check(self):
|
||||
@@ -123,28 +155,43 @@ class MrpProduction(models.Model):
|
||||
production.maintenance_count = len(production.request_ids)
|
||||
|
||||
# cnc程序获取
|
||||
def fetchCNC(self):
|
||||
def fetchCNC(self, production_names):
|
||||
cnc = self.env['mrp.production'].search([('id', '=', self.id)])
|
||||
quick_order = self.env['quick.easy.order'].search(
|
||||
[('name', '=', cnc.product_id.default_code.rsplit('-', 1)[0])])
|
||||
programme_way = False
|
||||
if cnc.manual_quotation is True:
|
||||
programme_way = 'manual operation'
|
||||
else:
|
||||
programme_way = 'auto'
|
||||
if quick_order:
|
||||
programme_way = 'manual operation'
|
||||
try:
|
||||
res = {'model_code': '' if not cnc.product_id.model_code else cnc.product_id.model_code,
|
||||
'production_no': cnc.name,
|
||||
'machine_tool_code': "",
|
||||
'material_code': self.env['sf.production.materials'].search(
|
||||
[('id', '=', cnc.product_id.materials_id.id)]).materials_no,
|
||||
'material_type_code': self.env['sf.materials.model'].search(
|
||||
[('id', '=', cnc.product_id.materials_type_id.id)]).materials_no,
|
||||
'machining_processing_panel': cnc.product_id.model_processing_panel,
|
||||
'machining_precision': cnc.product_id.model_machining_precision,
|
||||
'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length,
|
||||
'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height,
|
||||
'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width,
|
||||
'order_no': cnc.origin,
|
||||
'model_order_no': cnc.product_id.default_code.rsplit(' -', 1)[0],
|
||||
'user': cnc.env.user.name,
|
||||
'model_file': '' if not cnc.product_id.model_file else base64.b64encode(
|
||||
cnc.product_id.model_file).decode('utf-8')
|
||||
}
|
||||
logging.info('res:%s' % res)
|
||||
res = {
|
||||
'production_no': production_names,
|
||||
'machine_tool_code': '',
|
||||
'product_name': cnc.product_id.name,
|
||||
'model_code': cnc.product_id.model_code,
|
||||
'material_code': self.env['sf.production.materials'].search(
|
||||
[('id', '=', cnc.product_id.materials_id.id)]).materials_no,
|
||||
'material_type_code': self.env['sf.materials.model'].search(
|
||||
[('id', '=', cnc.product_id.materials_type_id.id)]).materials_no,
|
||||
'machining_processing_panel': cnc.product_id.model_processing_panel,
|
||||
'machining_precision': cnc.product_id.model_machining_precision,
|
||||
'embryo_long': cnc.product_id.bom_ids.bom_line_ids.product_id.length,
|
||||
'embryo_height': cnc.product_id.bom_ids.bom_line_ids.product_id.height,
|
||||
'embryo_width': cnc.product_id.bom_ids.bom_line_ids.product_id.width,
|
||||
'order_no': cnc.origin,
|
||||
'model_order_no': cnc.product_id.default_code,
|
||||
'user': cnc.env.user.name,
|
||||
'programme_way': programme_way,
|
||||
'model_file': '' if not cnc.product_id.model_file else base64.b64encode(
|
||||
cnc.product_id.model_file).decode('utf-8')
|
||||
}
|
||||
# 打印出除了 model_file 之外的所有键值对
|
||||
for key, value in res.items():
|
||||
if key != 'model_file':
|
||||
logging.info('%s: %s' % (key, value))
|
||||
configsettings = self.env['res.config.settings'].get_values()
|
||||
config_header = Common.get_headers(self, configsettings['token'], configsettings['sf_secret_key'])
|
||||
url = '/api/intelligent_programming/create'
|
||||
@@ -222,11 +269,18 @@ class MrpProduction(models.Model):
|
||||
# 其他规则限制: 默认只分配给工作中心状态为非故障的工作中心;
|
||||
|
||||
def _create_workorder3(self):
|
||||
# 根据product_id对self进行分组
|
||||
grouped_product_ids = {k: list(g) for k, g in groupby(self, key=lambda x: x.product_id.id)}
|
||||
# 初始化一个字典来存储每个product_id对应的生产订单名称列表
|
||||
product_id_to_production_names = {}
|
||||
# 对于每个product_id,获取其所有生产订单的名称
|
||||
for product_id, productions in grouped_product_ids.items():
|
||||
# 为同一个product_id创建一个生产订单名称列表
|
||||
product_id_to_production_names[product_id] = [production.name for production in productions]
|
||||
for production in self:
|
||||
if not production.bom_id or not production.product_id:
|
||||
continue
|
||||
workorders_values = []
|
||||
|
||||
product_qty = production.product_uom_id._compute_quantity(production.product_qty,
|
||||
production.bom_id.product_uom_id)
|
||||
exploded_boms, dummy = production.bom_id.explode(production.product_id,
|
||||
@@ -250,8 +304,19 @@ class MrpProduction(models.Model):
|
||||
'state': 'pending',
|
||||
}]
|
||||
if production.product_id.categ_id.type == '成品':
|
||||
production.fetchCNC()
|
||||
# 根据加工面板的面数及对应的工序模板生成工单
|
||||
if production.product_id.id in product_id_to_production_names:
|
||||
# # 同一个产品多个制造订单对应一个编程单和模型库
|
||||
# # 只调用一次fetchCNC,并将所有生产订单的名称作为字符串传递
|
||||
if not production.programming_no:
|
||||
production_programming = self.search(
|
||||
[('product_id.id', '=', production.product_id.id), ('origin', '=', production.origin)],
|
||||
limit=1, order='id asc')
|
||||
if not production_programming.programming_no:
|
||||
production.fetchCNC(', '.join(product_id_to_production_names[production.product_id.id]))
|
||||
else:
|
||||
production.write({'programming_no': production_programming.programming_no,
|
||||
'programming_state': '编程中'})
|
||||
# # 根据加工面板的面数及对应的工序模板生成工单
|
||||
i = 0
|
||||
processing_panel_len = len(production.product_id.model_processing_panel.split(','))
|
||||
for k in (production.product_id.model_processing_panel.split(',')):
|
||||
@@ -314,48 +379,6 @@ class MrpProduction(models.Model):
|
||||
workorders_values.append(
|
||||
self.env['mrp.workorder'].json_workorder_str('', production, route))
|
||||
production.workorder_ids = workorders_values
|
||||
process_parameter_workorder = self.env['mrp.workorder'].search(
|
||||
[('surface_technics_parameters_id', '!=', False), ('production_id', '=', production.id),
|
||||
('is_subcontract', '=', True)])
|
||||
if process_parameter_workorder:
|
||||
is_pick = False
|
||||
consecutive_workorders = []
|
||||
m = 0
|
||||
sorted_workorders = sorted(process_parameter_workorder, key=lambda w: w.id)
|
||||
for i in range(len(sorted_workorders) - 1):
|
||||
if m == 0:
|
||||
is_pick = False
|
||||
if sorted_workorders[i].supplier_id.id == sorted_workorders[i + 1].supplier_id.id and \
|
||||
sorted_workorders[i].is_subcontract == sorted_workorders[i + 1].is_subcontract and \
|
||||
sorted_workorders[i].id == sorted_workorders[i + 1].id - 1:
|
||||
if sorted_workorders[i] not in consecutive_workorders:
|
||||
consecutive_workorders.append(sorted_workorders[i])
|
||||
consecutive_workorders.append(sorted_workorders[i + 1])
|
||||
m += 1
|
||||
continue
|
||||
else:
|
||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
|
||||
if sorted_workorders[i] in consecutive_workorders:
|
||||
is_pick = True
|
||||
consecutive_workorders = []
|
||||
m = 0
|
||||
# 当前面的连续工序生成对应的外协出入库单再生成当前工序的外协出入库单
|
||||
if is_pick is False:
|
||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production)
|
||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
|
||||
if sorted_workorders[i] in consecutive_workorders:
|
||||
is_pick = True
|
||||
consecutive_workorders = []
|
||||
m = 0
|
||||
if m == len(consecutive_workorders) - 1 and m != 0:
|
||||
self.env['stock.picking'].create_outcontract_picking(consecutive_workorders, production)
|
||||
if is_pick is False and m == 0:
|
||||
if len(sorted_workorders) == 1:
|
||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders, production)
|
||||
else:
|
||||
self.env['stock.picking'].create_outcontract_picking(sorted_workorders[i], production)
|
||||
for workorder in production.workorder_ids:
|
||||
workorder.duration_expected = workorder._get_duration_expected()
|
||||
|
||||
@@ -381,20 +404,6 @@ class MrpProduction(models.Model):
|
||||
'user_id': production.user_id.id}
|
||||
return production_values_str
|
||||
|
||||
def _get_stock_move_values_Res(self, item, location_src_id, location_dest_id, picking_type_id):
|
||||
move_values = {
|
||||
'name': item.name if item.name else '/',
|
||||
'company_id': item.company_id.id,
|
||||
'product_id': item.bom_id.bom_line_ids.product_id.id,
|
||||
'product_uom': item.bom_id.bom_line_ids.product_uom_id.id,
|
||||
'product_uom_qty': 1.0,
|
||||
'location_id': location_src_id,
|
||||
'location_dest_id': location_dest_id,
|
||||
'origin': item.origin,
|
||||
'picking_type_id': picking_type_id,
|
||||
}
|
||||
return move_values
|
||||
|
||||
# 工单排序
|
||||
def _reset_work_order_sequence1(self, k):
|
||||
sequen = 0
|
||||
@@ -491,7 +500,8 @@ class MrpProduction(models.Model):
|
||||
|
||||
# 修改标记已完成方法
|
||||
def button_mark_done1(self):
|
||||
self._button_mark_done_sanity_checks()
|
||||
if not self.workorder_ids.filtered(lambda w: w.routing_type not in ['表面工艺']):
|
||||
self._button_mark_done_sanity_checks()
|
||||
|
||||
if not self.env.context.get('button_mark_done_production_ids'):
|
||||
self = self.with_context(button_mark_done_production_ids=self.ids)
|
||||
|
||||
@@ -22,10 +22,19 @@ class ResMrpRoutingWorkcenter(models.Model):
|
||||
bom_id = fields.Many2one('mrp.bom', required=False)
|
||||
surface_technics_id = fields.Many2one('sf.production.process', string="表面工艺")
|
||||
|
||||
def generate_code(self):
|
||||
return self.env['ir.sequence'].next_by_code('mrp.routing.workcenter')
|
||||
def get_no(self):
|
||||
international_standards = self.search(
|
||||
[('code', '!=', ''), ('active', 'in', [True, False])],
|
||||
limit=1,
|
||||
order="id desc")
|
||||
if not international_standards:
|
||||
num = "%03d" % 1
|
||||
else:
|
||||
m = int(international_standards.code) + 1
|
||||
num = "%03d" % m
|
||||
return num
|
||||
|
||||
code = fields.Char('编码', default=generate_code)
|
||||
code = fields.Char('编码', default=get_no)
|
||||
|
||||
# 获得当前登陆者公司
|
||||
def get_company_id(self):
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
import requests
|
||||
import base64
|
||||
import hashlib
|
||||
import os
|
||||
from odoo import models, fields, api, _
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.modules import get_resource_path
|
||||
# from OCC.Extend.DataExchange import read_step_file
|
||||
# from OCC.Extend.DataExchange import write_stl_file
|
||||
from OCC.Extend.DataExchange import read_step_file
|
||||
from OCC.Extend.DataExchange import write_stl_file
|
||||
|
||||
|
||||
class ResProductMo(models.Model):
|
||||
@@ -39,7 +40,8 @@ class ResProductMo(models.Model):
|
||||
product_model_type_id = fields.Many2one('sf.model.type', string='产品模型类型')
|
||||
embryo_model_type_id = fields.Many2one('sf.model.type', string='坯料模型类型')
|
||||
materials_id = fields.Many2one('sf.production.materials', string='材料')
|
||||
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号')
|
||||
materials_type_id = fields.Many2one('sf.materials.model', string='材料型号',
|
||||
domain="[('materials_id', '=', materials_id)]")
|
||||
server_product_process_parameters_id = fields.Many2one('sf.production.process.parameter',
|
||||
string='表面工艺参数(服务产品)')
|
||||
model_process_parameters_ids = fields.Many2many('sf.production.process.parameter', 'process_parameter_rel',
|
||||
@@ -68,7 +70,8 @@ class ResProductMo(models.Model):
|
||||
cutting_tool_shank_length = fields.Float('柄部长度(mm)', digits=(6, 1))
|
||||
cutting_tool_blade_length = fields.Float('刃部长度(mm)')
|
||||
cutting_tool_blade_number = fields.Selection(
|
||||
[('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8')], '刃数(个)')
|
||||
[('0', '0'), ('2', '2'), ('3', '3'), ('4', '4'), ('5', '5'), ('6', '6'), ('7', '7'), ('8', '8')],
|
||||
string='刃数(个)', default='0')
|
||||
# 整体式刀具新增字段
|
||||
cutting_tool_neck_length = fields.Float('颈部长度(mm)', digits=(6, 1))
|
||||
cutting_tool_neck_diameter = fields.Float('颈部直径(mm)', digits=(6, 1))
|
||||
@@ -101,6 +104,13 @@ class ResProductMo(models.Model):
|
||||
compaction_way_id = fields.Many2one('maintenance.equipment.image',
|
||||
'压紧方式', domain=[('type', '=', '压紧方式')])
|
||||
|
||||
@api.onchange('cutting_tool_model_id')
|
||||
def _onchange_cutting_tool_model_id(self):
|
||||
for item in self:
|
||||
if item:
|
||||
item.specification_id = False
|
||||
item.cutting_tool_chuck_id = item.cutting_tool_model_id.chuck_id
|
||||
|
||||
@api.onchange('cutting_tool_material_id')
|
||||
def _onchange_cutting_tool_material_id(self):
|
||||
for item in self:
|
||||
@@ -169,6 +179,12 @@ class ResProductMo(models.Model):
|
||||
# ('standard_library_id', '=', self.cutting_tool_model_id.id)],
|
||||
# }
|
||||
|
||||
# def name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
|
||||
# # if self._context.get('is_sale_order_line'):
|
||||
# # domain = [('sale_ok', '=', True), ('categ_type', '=', '成品')]
|
||||
# # return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)
|
||||
# return super(product.template, self)._name_search(name, args, operator, limit, name_get_uid)
|
||||
|
||||
@api.onchange('specification_id')
|
||||
def _onchange_specification(self):
|
||||
if self.specification_id:
|
||||
@@ -190,20 +206,24 @@ class ResProductMo(models.Model):
|
||||
self.cutting_tool_blade_number = self.specification_id.blade_number
|
||||
self.cutting_tool_blade_type = self.cutting_tool_model_id.blade_type
|
||||
self.cutting_tool_shank_diameter = self.specification_id.handle_diameter
|
||||
self.cutting_tool_shank_length = self.specification_id.handle_length
|
||||
self.cutting_tool_neck_length = self.specification_id.neck_length
|
||||
self.cutting_tool_neck_diameter = self.specification_id.neck_diameter
|
||||
self.cutting_tool_blade_tip_diameter = self.specification_id.blade_tip_diameter
|
||||
self.cutting_tool_blade_tip_taper = self.specification_id.blade_tip_taper
|
||||
self.cutting_tool_blade_helix_angle = self.specification_id.blade_helix_angle
|
||||
self.cutting_tool_blade_tip_working_size = self.specification_id.blade_tip_working_size
|
||||
self.cutting_tool_pitch = self.specification_id.pitch
|
||||
self.cutting_tool_blade_width = self.specification_id.blade_width
|
||||
self.cutting_tool_blade_depth = self.specification_id.blade_depth
|
||||
self.cutting_tool_cut_depth = self.specification_id.cutting_depth
|
||||
self.cutting_tool_cut_depth_max = self.specification_id.cut_depth_max
|
||||
self.cutting_speed_ids = self.cutting_tool_model_id.cutting_speed_ids
|
||||
self.feed_per_tooth_ids = self.cutting_tool_model_id.feed_per_tooth_ids.filtered(
|
||||
lambda r: int(r.blade_diameter) == int(self.specification_id.blade_diameter))
|
||||
elif self.cutting_tool_type == '夹头':
|
||||
self.cutting_tool_clamping_diameter_min = self.specification_id.min_clamping_diameter
|
||||
self.cutting_tool_clamping_diameter_min = self.specification_id.max_clamping_diameter
|
||||
self.cutting_tool_clamping_way = self.specification_id.clamping_mode
|
||||
self.cutting_tool_clamping_diameter_max = self.specification_id.max_clamping_diameter
|
||||
self.cutting_tool_taper = self.specification_id.taper
|
||||
self.cutting_tool_top_diameter = self.specification_id.top_diameter
|
||||
self.cutting_tool_outer_diameter = self.specification_id.outer_diameter
|
||||
self.cutting_tool_inner_diameter = self.specification_id.inner_diameter
|
||||
@@ -241,6 +261,7 @@ class ResProductMo(models.Model):
|
||||
self.cutting_speed_ids = self.cutting_tool_model_id.cutting_speed_ids
|
||||
self.feed_per_tooth_ids = self.cutting_tool_model_id.feed_per_tooth_ids
|
||||
elif self.cutting_tool_type in ('刀盘', '刀杆'):
|
||||
self.cutting_tool_blade_diameter = self.specification_id.blade_diameter
|
||||
self.cutting_tool_total_length = self.specification_id.total_length
|
||||
self.tool_length = self.specification_id.length
|
||||
self.tool_thickness = self.specification_id.thickness
|
||||
@@ -271,14 +292,19 @@ class ResProductMo(models.Model):
|
||||
self.cutting_tool_cutter_head_diameter = self.specification_id.cutter_head_diameter
|
||||
self.cutting_tool_interface_diameter = self.specification_id.interface_diameter
|
||||
else:
|
||||
self.cutting_tool_cutter_arbor_diameter = self.specification_id.cutter_arbor_diameter
|
||||
self.cutting_tool_knife_head_height = self.specification_id.knife_head_height
|
||||
self.cutting_tool_knife_head_width = self.specification_id.knife_head_width
|
||||
self.cutting_tool_knife_head_length = self.specification_id.knife_head_length
|
||||
self.cutting_tool_tool_shim = self.specification_id.tool_shim
|
||||
self.cutting_tool_cotter_pin = self.specification_id.cotter_pin
|
||||
self.cutting_tool_pressing_plate = self.specification_id.pressing_plate
|
||||
self.cutting_tool_min_machining_aperture = self.specification_id.min_machining_aperture
|
||||
self.cutting_tool_rear_angle = self.specification_id.relief_angle
|
||||
elif self.cutting_tool_type == '刀柄':
|
||||
self.cutting_tool_total_length = self.specification_id.total_length
|
||||
self.cutting_tool_shank_diameter = self.specification_id.shank_diameter
|
||||
self.cutting_tool_shank_length = self.specification_id.shank_length
|
||||
self.cutting_tool_speed_max = self.specification_id.max_rotate_speed
|
||||
self.cutting_tool_change_time = self.specification_id.tool_changing_time
|
||||
self.cutting_tool_total_length = self.specification_id.total_length
|
||||
@@ -292,9 +318,10 @@ class ResProductMo(models.Model):
|
||||
self.cutting_tool_is_safety_lock = self.specification_id.is_safe_lock
|
||||
self.cutting_tool_fit_nut_model = self.specification_id.nut
|
||||
self.cutting_tool_wrench = self.specification_id.spanner
|
||||
self.cutting_tool_chuck_id = self.specification_id.chuck_id.id
|
||||
self.cutting_tool_jump_accuracy = self.specification_id.diameter_slip_accuracy
|
||||
self.cutting_tool_taper_shank_model = self.specification_id.taper_shank_model
|
||||
self.cutting_tool_cooling_type = self.specification_id.cooling_model
|
||||
self.cutting_tool_clamping_way = self.specification_id.clamping_mode
|
||||
self.suitable_machining_method_ids = [(6, 0, [])] if not \
|
||||
self.cutting_tool_model_id.suitable_machining_method_ids \
|
||||
else [(6, 0, self.cutting_tool_model_id.suitable_machining_method_ids.ids)]
|
||||
@@ -311,6 +338,7 @@ class ResProductMo(models.Model):
|
||||
(6, 0, self.cutting_tool_model_id.suitable_coolant_ids.ids)]
|
||||
self.compaction_way_id = self.cutting_tool_model_id.compaction_way_id.id
|
||||
self.fit_blade_shape_id = self.cutting_tool_model_id.fit_blade_shape_id.id
|
||||
self.image_1920 = self.cutting_tool_model_id.image
|
||||
else:
|
||||
self.cutting_tool_type_id = False
|
||||
self.brand_id = False
|
||||
@@ -350,34 +378,34 @@ class ResProductMo(models.Model):
|
||||
self.cutting_speed_ids = False
|
||||
self.feed_per_tooth_ids = False
|
||||
|
||||
@api.constrains('fit_blade_shape_id', 'suitable_machining_method_ids', 'blade_tip_characteristics_id',
|
||||
'handle_type_id', 'cutting_direction_ids', 'suitable_coolant_ids', 'compaction_way_id')
|
||||
def _check_cutting_tool_ability(self):
|
||||
if self.cutting_tool_type in ['整体式刀具', '刀片', '刀杆', '刀盘']:
|
||||
if self.cutting_tool_type in ['刀片', '刀杆', '刀盘']:
|
||||
if not self.fit_blade_shape_id:
|
||||
raise ValidationError("请选择适配刀片形状")
|
||||
if self.cutting_tool_type in ['刀杆', '刀盘']:
|
||||
if not self.compaction_way_id:
|
||||
raise ValidationError("请选择压紧方式")
|
||||
if self.cutting_tool_type == '刀片':
|
||||
if not self.suitable_coolant_ids:
|
||||
raise ValidationError("请选择适合冷却方式")
|
||||
elif self.cutting_tool_type == '整体式刀具':
|
||||
if not self.handle_type_id:
|
||||
raise ValidationError("请选择柄部类型")
|
||||
if not self.suitable_coolant_ids:
|
||||
raise ValidationError("请选择适合冷却方式")
|
||||
if not self.suitable_machining_method_ids:
|
||||
raise ValidationError("请选择适合加工方式")
|
||||
if not self.blade_tip_characteristics_id:
|
||||
raise ValidationError("请选择刀尖特征")
|
||||
if not self.cutting_direction_ids:
|
||||
raise ValidationError("请选择走刀方向")
|
||||
# @api.constrains('fit_blade_shape_id', 'suitable_machining_method_ids', 'blade_tip_characteristics_id',
|
||||
# 'handle_type_id', 'cutting_direction_ids', 'suitable_coolant_ids', 'compaction_way_id')
|
||||
# def _check_cutting_tool_ability(self):
|
||||
# if self.cutting_tool_type in ['整体式刀具', '刀片', '刀杆', '刀盘']:
|
||||
# if self.cutting_tool_type in ['刀片', '刀杆', '刀盘']:
|
||||
# if not self.fit_blade_shape_id:
|
||||
# raise ValidationError("请选择适配刀片形状")
|
||||
# if self.cutting_tool_type in ['刀杆', '刀盘']:
|
||||
# if not self.compaction_way_id:
|
||||
# raise ValidationError("请选择压紧方式")
|
||||
# if self.cutting_tool_type == '刀片':
|
||||
# if not self.suitable_coolant_ids:
|
||||
# raise ValidationError("请选择适合冷却方式")
|
||||
# elif self.cutting_tool_type == '整体式刀具':
|
||||
# if not self.handle_type_id:
|
||||
# raise ValidationError("请选择柄部类型")
|
||||
# if not self.suitable_coolant_ids:
|
||||
# raise ValidationError("请选择适合冷却方式")
|
||||
# if not self.suitable_machining_method_ids:
|
||||
# raise ValidationError("请选择适合加工方式")
|
||||
# if not self.blade_tip_characteristics_id:
|
||||
# raise ValidationError("请选择刀尖特征")
|
||||
# if not self.cutting_direction_ids:
|
||||
# raise ValidationError("请选择走刀方向")
|
||||
|
||||
cutting_speed_ids = fields.One2many('sf.cutting.speed', 'product_template_id', string='切削速度Vc')
|
||||
feed_per_tooth_ids = fields.One2many('sf.feed.per.tooth', 'product_template_id', string='每齿走刀量fz')
|
||||
cutting_tool_diameter = fields.Float('直径(mm)')
|
||||
cutting_tool_diameter = fields.Float('刀具直径(mm)')
|
||||
cutting_tool_rear_angle = fields.Integer('后角(°)')
|
||||
cutting_tool_main_included_angle = fields.Integer('主偏角(°)')
|
||||
# 适用夹头型号可以多选
|
||||
@@ -500,6 +528,9 @@ class ResProductMo(models.Model):
|
||||
string='注册状态', default='未注册')
|
||||
industry_code = fields.Char('行业编码', readonly=True)
|
||||
|
||||
# bfm下单
|
||||
manual_quotation = fields.Boolean('人工编程', default=False, readonly=True)
|
||||
|
||||
@api.constrains('tool_length')
|
||||
def _check_tool_length_size(self):
|
||||
if self.tool_length > 1000000:
|
||||
@@ -594,6 +625,7 @@ class ResProductMo(models.Model):
|
||||
'process_parameters_code') else self.get_process_parameters_id(item['process_parameters_code']),
|
||||
'model_remark': item['remark'],
|
||||
'default_code': '%s-%s' % (order_number, i),
|
||||
'manual_quotation': item['manual_quotation'] or False,
|
||||
'active': True,
|
||||
}
|
||||
copy_product_id.sudo().write(vals)
|
||||
@@ -626,8 +658,12 @@ class ResProductMo(models.Model):
|
||||
return attachment
|
||||
|
||||
# 创建坯料
|
||||
def no_bom_product_create(self, product_id, item, order_id, route_type, i):
|
||||
def no_bom_product_create(self, product_id, item, order_id, route_type, i, finish_product):
|
||||
no_bom_copy_product_id = product_id.with_user(self.env.ref("base.user_admin")).copy()
|
||||
# if finish_product.model_process_parameters_ids:
|
||||
# surface_technology = self.env['stock.route'].sudo().search([('name', '=', '表面工艺外协')])
|
||||
# if surface_technology:
|
||||
# no_bom_copy_product_id.route_ids |= surface_technology
|
||||
no_bom_copy_product_id.product_tmpl_id.active = True
|
||||
materials_id = self.env['sf.production.materials'].search(
|
||||
[('materials_no', '=', item['texture_code'])])
|
||||
@@ -658,11 +694,14 @@ class ResProductMo(models.Model):
|
||||
# 外协和采购生成的坯料需要根据材料型号绑定供应商
|
||||
if route_type == 'subcontract' or route_type == 'purchase':
|
||||
no_bom_copy_product_id.purchase_ok = True
|
||||
no_bom_copy_product_id.seller_ids = [
|
||||
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})]
|
||||
if route_type == 'subcontract':
|
||||
partner = self.env['res.partner'].search([('id', '=', supplier.partner_id.id)])
|
||||
partner.is_subcontractor = True
|
||||
if supplier:
|
||||
no_bom_copy_product_id.seller_ids = [
|
||||
(0, 0, {'partner_id': supplier.partner_id.id, 'delay': 1.0})]
|
||||
if route_type == 'subcontract':
|
||||
partner = self.env['res.partner'].search([('id', '=', supplier.partner_id.id)])
|
||||
partner.is_subcontractor = True
|
||||
else:
|
||||
return -3
|
||||
no_bom_copy_product_id.write(vals)
|
||||
return no_bom_copy_product_id
|
||||
|
||||
@@ -859,11 +898,38 @@ class SfMaintenanceEquipmentAndProductTemplate(models.Model):
|
||||
for i in range(1, number + 1):
|
||||
self.env['maintenance.equipment.tool'].create({
|
||||
'equipment_id': res.id,
|
||||
'code': 'T' + str(i)
|
||||
'code': "T%02d" % i
|
||||
})
|
||||
vals.append(res)
|
||||
return vals[0]
|
||||
|
||||
base_coordinate_fixture_model_id = fields.Many2one('sf.fixture.model', '基坐标卡盘型号',
|
||||
domain=[('fixture_material_id', '=', '零点卡盘')])
|
||||
base_coordinate_g_coordinate = fields.Char('G坐标')
|
||||
base_coordinate_x = fields.Float('x轴', digits=(12, 3))
|
||||
base_coordinate_y = fields.Float('y轴', digits=(12, 3))
|
||||
base_coordinate_z = fields.Float('z轴', digits=(12, 3))
|
||||
|
||||
# ==========获取机床基坐标接口==========
|
||||
def get_equipment_base_coordinate(self):
|
||||
headers = {'Authorization': 'Ba F2CF5DCC-1A00-4234-9E95-65603F70CC8A'}
|
||||
crea_url = "https://x24467i973.zicp.fun/AutoDeviceApi/EquipmentBaseCoordinate"
|
||||
params = {"DeviceId": self.name}
|
||||
r = requests.get(crea_url, params=params, headers=headers)
|
||||
ret = r.json()
|
||||
logging.info('register_equipment_tool:%s' % ret)
|
||||
self.write({
|
||||
'base_coordinate_fixture_model_id': ret['base_coordinate_fixture_model_id'],
|
||||
'base_coordinate_g_coordinate': ret['base_coordinate_g_coordinate'],
|
||||
'base_coordinate_x': ret['base_coordinate_x'],
|
||||
'base_coordinate_y': ret['base_coordinate_y'],
|
||||
'base_coordinate_z': ret['base_coordinate_z'],
|
||||
})
|
||||
if ret['Succeed']:
|
||||
return "机床基坐标获取成功"
|
||||
else:
|
||||
raise ValidationError("机床基坐标获取失败")
|
||||
|
||||
|
||||
class SfMaintenanceEquipmentTool(models.Model):
|
||||
_name = 'maintenance.equipment.tool'
|
||||
|
||||