forked from Wavyzz/dolibarr
Compare commits
1291 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
870c2a8f50 | ||
|
|
01aa901f93 | ||
|
|
96a74c4976 | ||
|
|
a69ba88857 | ||
|
|
b05be5e1df | ||
|
|
247c38923f | ||
|
|
2d55195982 | ||
|
|
5788438864 | ||
|
|
4f684df12f | ||
|
|
adbbf9e3b2 | ||
|
|
1f29c7758c | ||
|
|
07512d1dad | ||
|
|
3362a6b06d | ||
|
|
9666a96d8c | ||
|
|
1b59bcfadb | ||
|
|
347bf3e4d6 | ||
|
|
b3a2257638 | ||
|
|
24652ec722 | ||
|
|
b226894e36 | ||
|
|
3b0a4c9fa9 | ||
|
|
0928191fdd | ||
|
|
154a25f8cb | ||
|
|
6a88d31675 | ||
|
|
437a07ba3c | ||
|
|
f4555c4413 | ||
|
|
ed4006b51b | ||
|
|
bc33f7e1a7 | ||
|
|
3c1b5846c9 | ||
|
|
fe96d826ef | ||
|
|
df60ce695c | ||
|
|
3b5e07dca9 | ||
|
|
8927d1260a | ||
|
|
ee294917e1 | ||
|
|
53cf9f0bf1 | ||
|
|
f4efa58022 | ||
|
|
737dc7726e | ||
|
|
af095c0e11 | ||
|
|
453b289346 | ||
|
|
2bef534e60 | ||
|
|
c0161ccead | ||
|
|
1be67fee52 | ||
|
|
4a88509cdf | ||
|
|
a4b1700bae | ||
|
|
f5cb64afaa | ||
|
|
4841a8d2ce | ||
|
|
52a5d4ca0a | ||
|
|
cb0d39ff6e | ||
|
|
a5c51589d3 | ||
|
|
b4501511c8 | ||
|
|
e18c5b9d68 | ||
|
|
b940f2eae3 | ||
|
|
e6ff31abf1 | ||
|
|
d31bad82a1 | ||
|
|
bc0b0bebd3 | ||
|
|
031acacdab | ||
|
|
18725aec6b | ||
|
|
75c3456743 | ||
|
|
c0db33caf2 | ||
|
|
8159249209 | ||
|
|
9f76298e58 | ||
|
|
f1ecb023ff | ||
|
|
ce1243140f | ||
|
|
52c827c2bb | ||
|
|
c263fccb5f | ||
|
|
719de0aef3 | ||
|
|
4cc3be24d3 | ||
|
|
b1109f6803 | ||
|
|
fda1499eee | ||
|
|
4bb42de5d6 | ||
|
|
f31270df2a | ||
|
|
d50a938d12 | ||
|
|
478a8a4d52 | ||
|
|
fa135a216b | ||
|
|
79779b1d2f | ||
|
|
456adc1e95 | ||
|
|
06dc4f5426 | ||
|
|
467c772504 | ||
|
|
1bd6757e62 | ||
|
|
1c52426b90 | ||
|
|
bc18656fd5 | ||
|
|
c77c4efcb8 | ||
|
|
cada04442b | ||
|
|
4bd11f64d7 | ||
|
|
9c45f42e4f | ||
|
|
c9f743983a | ||
|
|
1497541129 | ||
|
|
878474f1d1 | ||
|
|
0afd5cc7e3 | ||
|
|
1aaa29ad9e | ||
|
|
4096b00bd5 | ||
|
|
dcc4334768 | ||
|
|
f137074a98 | ||
|
|
f8f31daa16 | ||
|
|
35528a5885 | ||
|
|
8853bfd51a | ||
|
|
ce0f46a483 | ||
|
|
9a8a07e85a | ||
|
|
26bcc944cf | ||
|
|
d2d9590019 | ||
|
|
fe4b1ff34d | ||
|
|
4e95aab6b5 | ||
|
|
4fb79ba8a1 | ||
|
|
a42593db0d | ||
|
|
cfc766ebbe | ||
|
|
51e4ce05c9 | ||
|
|
819c3fd08a | ||
|
|
4c6955017f | ||
|
|
de40214a09 | ||
|
|
491ecaccfe | ||
|
|
3b3f3fa29b | ||
|
|
efb9327896 | ||
|
|
223f0c2763 | ||
|
|
b85bfc40f4 | ||
|
|
cc78023a44 | ||
|
|
9b74628e29 | ||
|
|
0ef0d339b5 | ||
|
|
5bf5d23495 | ||
|
|
02588036c2 | ||
|
|
8e0d3911e6 | ||
|
|
3929ef0bfa | ||
|
|
c3b35d4da5 | ||
|
|
5e887e8850 | ||
|
|
61df34acd6 | ||
|
|
f5b11b78da | ||
|
|
d7758f9ae6 | ||
|
|
8434e6567f | ||
|
|
2c38bea2b0 | ||
|
|
096b59913d | ||
|
|
d38b9e6248 | ||
|
|
f256deb54b | ||
|
|
7fa3474ecd | ||
|
|
363b05d314 | ||
|
|
3fe6132c94 | ||
|
|
238f684576 | ||
|
|
e6ebf315ed | ||
|
|
70e4d1ccd0 | ||
|
|
a8a95cba75 | ||
|
|
1a015cd91e | ||
|
|
9b36b6e965 | ||
|
|
cbb9f5aa0c | ||
|
|
ef159f919e | ||
|
|
3e8c5651cd | ||
|
|
0a4f1ffc06 | ||
|
|
42a1cde41a | ||
|
|
324f9631d7 | ||
|
|
8073c0e1be | ||
|
|
b256c9aaba | ||
|
|
4897c9de7f | ||
|
|
2058d572d9 | ||
|
|
089fab828b | ||
|
|
fa05dc44ce | ||
|
|
5b9453e302 | ||
|
|
d81a2d060e | ||
|
|
8d9dc8c87d | ||
|
|
97aaff7395 | ||
|
|
7a1fa20959 | ||
|
|
2f36edef3b | ||
|
|
f7fe6c4f1a | ||
|
|
b9f4ddb021 | ||
|
|
6f4b2a8905 | ||
|
|
0e95f70b8d | ||
|
|
dd7189b1d0 | ||
|
|
cd21d385d6 | ||
|
|
86442aa7f0 | ||
|
|
39cd4fcb9e | ||
|
|
4272cfa7e4 | ||
|
|
db56e5c8ea | ||
|
|
0c573812e9 | ||
|
|
4cf6394f01 | ||
|
|
00ccb45bc4 | ||
|
|
8aa1d1165f | ||
|
|
5911d7d0c0 | ||
|
|
41e54529b0 | ||
|
|
f89aff96f7 | ||
|
|
54df3c2991 | ||
|
|
85bce8b71f | ||
|
|
9d9d890c97 | ||
|
|
f511e2e523 | ||
|
|
bd9bf8b5a8 | ||
|
|
5fd5eae3b1 | ||
|
|
6aa4d6a940 | ||
|
|
7997e927a0 | ||
|
|
9516f9bbd2 | ||
|
|
f7bd03fb75 | ||
|
|
ea60024712 | ||
|
|
edea44bccb | ||
|
|
09df62600e | ||
|
|
94eaf5d089 | ||
|
|
d04ac67ecd | ||
|
|
81b9286ea4 | ||
|
|
c648bd8c90 | ||
|
|
99a291f878 | ||
|
|
47f10cdc29 | ||
|
|
7eba8832e6 | ||
|
|
03340d6016 | ||
|
|
d288fe74a2 | ||
|
|
28d588fd40 | ||
|
|
9fc78cd1b6 | ||
|
|
34298f6c8c | ||
|
|
bbbba45fc1 | ||
|
|
bfb97edccf | ||
|
|
989c9b9548 | ||
|
|
82b7326c99 | ||
|
|
d2e6335e95 | ||
|
|
711f21e8a0 | ||
|
|
e1c343cedd | ||
|
|
51def8d31d | ||
|
|
bbb8b0f01f | ||
|
|
c115a76d4e | ||
|
|
63ab8d9f75 | ||
|
|
7848d77830 | ||
|
|
737a807456 | ||
|
|
e6a6426b5b | ||
|
|
f3dc94d334 | ||
|
|
e4f0c1a42b | ||
|
|
44d6803d12 | ||
|
|
f80e83b846 | ||
|
|
bdcd7b5ef3 | ||
|
|
17d1c279ab | ||
|
|
dd40aea380 | ||
|
|
f9ec70f1db | ||
|
|
83bc7b70a0 | ||
|
|
2cbede2ef8 | ||
|
|
729e6c4aba | ||
|
|
a2e865587f | ||
|
|
c6ab6cd57e | ||
|
|
837b2ff060 | ||
|
|
c7ee83b3b9 | ||
|
|
a404b80988 | ||
|
|
cbe15c7c71 | ||
|
|
278b07099c | ||
|
|
576e70c3ce | ||
|
|
5433aa8d2e | ||
|
|
b67fdb3e51 | ||
|
|
7f2a253625 | ||
|
|
ad60a50d4d | ||
|
|
08a976fd85 | ||
|
|
426f4305b0 | ||
|
|
db47ce3bb1 | ||
|
|
1b42078d1e | ||
|
|
736890b244 | ||
|
|
2664518bd3 | ||
|
|
c6f90d8361 | ||
|
|
cc732621ab | ||
|
|
04fed9526a | ||
|
|
9f4692e1c9 | ||
|
|
1fa3b63fdc | ||
|
|
af2889e982 | ||
|
|
4d925db3cd | ||
|
|
36d91f1c07 | ||
|
|
bcc260dc08 | ||
|
|
9507b89fec | ||
|
|
a52a218ae4 | ||
|
|
0409b8b9c5 | ||
|
|
f68cf0034a | ||
|
|
ba4e97f07b | ||
|
|
c2c3879032 | ||
|
|
c4529ed986 | ||
|
|
8b7eaf360e | ||
|
|
2f317f0f52 | ||
|
|
bd35af1360 | ||
|
|
351a7bd6bb | ||
|
|
fe6d59c090 | ||
|
|
d4e66426e7 | ||
|
|
88d81aa943 | ||
|
|
f24f4e012d | ||
|
|
60ea952b78 | ||
|
|
5354b54ec0 | ||
|
|
49feeee85e | ||
|
|
42d8591758 | ||
|
|
cf156e024d | ||
|
|
6b0c8f39d5 | ||
|
|
2c2e01d14c | ||
|
|
abc1d1dcb3 | ||
|
|
628189f57f | ||
|
|
748dcd0881 | ||
|
|
2d1d6f13c9 | ||
|
|
4f98ca37e2 | ||
|
|
a34eaa07ed | ||
|
|
20f2293c01 | ||
|
|
7869e45954 | ||
|
|
9af7eaf08c | ||
|
|
79ed9c7e37 | ||
|
|
eb8167bc57 | ||
|
|
df992477be | ||
|
|
79c55149b2 | ||
|
|
ac1077bfe3 | ||
|
|
a46c47c134 | ||
|
|
762e4ec8d1 | ||
|
|
77f982d1a8 | ||
|
|
7a7146c03d | ||
|
|
a34d760a88 | ||
|
|
e9eb22f8f0 | ||
|
|
e1a47ed0fb | ||
|
|
6388f6e62a | ||
|
|
e2605fbf64 | ||
|
|
90c24b3d95 | ||
|
|
0912b3b04f | ||
|
|
7e82f70c77 | ||
|
|
2dd81deb13 | ||
|
|
273ec857a3 | ||
|
|
ef564caf28 | ||
|
|
3ef6299c83 | ||
|
|
ec58ee940a | ||
|
|
2519278269 | ||
|
|
74881ae251 | ||
|
|
c218eaa6ed | ||
|
|
b7cb799af0 | ||
|
|
78bf506790 | ||
|
|
61b03b0c05 | ||
|
|
b31962f7e2 | ||
|
|
112220da86 | ||
|
|
1fafc1b6ad | ||
|
|
eb4e059683 | ||
|
|
b5ff688841 | ||
|
|
8805b8cac4 | ||
|
|
d01a99cd79 | ||
|
|
1866713082 | ||
|
|
9ecc88230f | ||
|
|
8ddd050a34 | ||
|
|
4c4b773de5 | ||
|
|
37a815af53 | ||
|
|
f60f34cdf8 | ||
|
|
4267f5f010 | ||
|
|
f08c9605db | ||
|
|
e41dfcbbb3 | ||
|
|
a0b6aa28a7 | ||
|
|
c273495261 | ||
|
|
220090813d | ||
|
|
e65ee097a5 | ||
|
|
92963af09f | ||
|
|
8ccdbf374b | ||
|
|
0300209b3d | ||
|
|
a5f51dc969 | ||
|
|
04b7fdd4c4 | ||
|
|
e3c44568a0 | ||
|
|
37f3fccc35 | ||
|
|
fedcec58a6 | ||
|
|
be95c92c45 | ||
|
|
810fd7e744 | ||
|
|
c6afa1a6cb | ||
|
|
29eedd2ac4 | ||
|
|
ead519811c | ||
|
|
5203652796 | ||
|
|
750ed5e91c | ||
|
|
425c23d28c | ||
|
|
900a91a0a2 | ||
|
|
ce06c12da6 | ||
|
|
b73bcd68a9 | ||
|
|
86833633ef | ||
|
|
21ac3b28ef | ||
|
|
6aee2db1d4 | ||
|
|
a6da3b189a | ||
|
|
65d6403fa3 | ||
|
|
62c1d500e8 | ||
|
|
ef090aa895 | ||
|
|
d9be3efa90 | ||
|
|
a4785adb3d | ||
|
|
3c22179183 | ||
|
|
a96d13d5aa | ||
|
|
f1868ee162 | ||
|
|
cfd4919829 | ||
|
|
30893bf676 | ||
|
|
28213b3129 | ||
|
|
c3ede4413d | ||
|
|
21eca275e9 | ||
|
|
127b9701ff | ||
|
|
ee7201fc61 | ||
|
|
c075e078e9 | ||
|
|
f9eb6b69f5 | ||
|
|
3d9b7ed7d3 | ||
|
|
6920b72cf4 | ||
|
|
9a9602f418 | ||
|
|
0960fcba2a | ||
|
|
9b46ed9c2d | ||
|
|
d055b1fb29 | ||
|
|
9411ac2144 | ||
|
|
eb2b35e3b1 | ||
|
|
ab5f9a0884 | ||
|
|
b4ece8d154 | ||
|
|
75e504ffbc | ||
|
|
3877f257b4 | ||
|
|
6f2d8b23b4 | ||
|
|
80326acb71 | ||
|
|
d9035eecda | ||
|
|
da6f1fbc9a | ||
|
|
4bb2b9f971 | ||
|
|
a0864dfb3f | ||
|
|
d3d534efee | ||
|
|
2e94f7dbd4 | ||
|
|
2c4b3bf6ad | ||
|
|
e8aaa51edc | ||
|
|
e48e1e27d5 | ||
|
|
c86b50e3fc | ||
|
|
42368b37e9 | ||
|
|
addefdf0cf | ||
|
|
59642d8d93 | ||
|
|
a26eecf0fd | ||
|
|
69449668a8 | ||
|
|
084d99f670 | ||
|
|
15c19b99c9 | ||
|
|
c418a6ff57 | ||
|
|
3aad5fd283 | ||
|
|
d04b1e57d2 | ||
|
|
f5c715c6a7 | ||
|
|
d8fecc1522 | ||
|
|
30a9da8fbf | ||
|
|
e6712300d5 | ||
|
|
c547362ae9 | ||
|
|
9ec4575c43 | ||
|
|
4962dd1a81 | ||
|
|
6337a987d8 | ||
|
|
7a500976d2 | ||
|
|
0e1744a6ec | ||
|
|
29a7a410c8 | ||
|
|
e9009ede87 | ||
|
|
7b16039084 | ||
|
|
acdab170a7 | ||
|
|
32b18d6bfd | ||
|
|
9cd7d381a6 | ||
|
|
e35b534ee2 | ||
|
|
682544ad45 | ||
|
|
53ffe42f92 | ||
|
|
c2a037842d | ||
|
|
552bebf564 | ||
|
|
ec93f50863 | ||
|
|
240c5bb311 | ||
|
|
c12a7e144a | ||
|
|
991f53db9e | ||
|
|
877fd00353 | ||
|
|
d420d035de | ||
|
|
115323dec8 | ||
|
|
ac6c57e90e | ||
|
|
9c4bb84460 | ||
|
|
5a58b8e721 | ||
|
|
b068fdc9b3 | ||
|
|
b8533e1853 | ||
|
|
753e5e535d | ||
|
|
99774022a5 | ||
|
|
c5ebc9b7bd | ||
|
|
f2f3e478d1 | ||
|
|
f10d9464a1 | ||
|
|
580d789a00 | ||
|
|
98d106e6b5 | ||
|
|
bca77bddb8 | ||
|
|
7ca9f0022a | ||
|
|
a602309e04 | ||
|
|
f51935a258 | ||
|
|
976399c2d9 | ||
|
|
cd6ed63768 | ||
|
|
348981a419 | ||
|
|
adf59f2599 | ||
|
|
d0323fa27d | ||
|
|
038f8d5dff | ||
|
|
bab49d66c5 | ||
|
|
230eee4ead | ||
|
|
ce9a1b3661 | ||
|
|
4feb9def4e | ||
|
|
dccde49388 | ||
|
|
a039a00277 | ||
|
|
d30a0ea066 | ||
|
|
ab6c74ae88 | ||
|
|
fbca98ec2a | ||
|
|
93f23fe452 | ||
|
|
67c2a48fc9 | ||
|
|
792ff4044e | ||
|
|
29ef86a245 | ||
|
|
d5add8aa49 | ||
|
|
d3b9a83055 | ||
|
|
f4b2269e2e | ||
|
|
0eee1ad18b | ||
|
|
d5e2f89edc | ||
|
|
67bcc242db | ||
|
|
8a55e2f6a4 | ||
|
|
5eb5033aba | ||
|
|
723c8278ce | ||
|
|
bbf83c7053 | ||
|
|
b8286ab8f3 | ||
|
|
7133c6529b | ||
|
|
e0a3756c6e | ||
|
|
c396a08cb2 | ||
|
|
0981c69515 | ||
|
|
1987ea2eb7 | ||
|
|
6a4ee18380 | ||
|
|
b3a2908b48 | ||
|
|
910f7e8564 | ||
|
|
7cf1a97673 | ||
|
|
cf57e7e88b | ||
|
|
8b4dcb1194 | ||
|
|
a186e16568 | ||
|
|
eaa31ed4a3 | ||
|
|
0e62008db6 | ||
|
|
aa096448be | ||
|
|
d9d0618eec | ||
|
|
39afafc585 | ||
|
|
b37b2ba76f | ||
|
|
c48b035a15 | ||
|
|
1d197e42bb | ||
|
|
b0c7b8750a | ||
|
|
a0b791a4a6 | ||
|
|
abefce7ae2 | ||
|
|
352bdaf9c4 | ||
|
|
87c16498ca | ||
|
|
35f3a4f441 | ||
|
|
111e3fcd32 | ||
|
|
d819d88718 | ||
|
|
278eea6fae | ||
|
|
fa22ebd893 | ||
|
|
793e77bc5f | ||
|
|
70a453a5c2 | ||
|
|
33c6d95b1c | ||
|
|
1e64870a9e | ||
|
|
94ed718782 | ||
|
|
40965b63b5 | ||
|
|
3391d3db05 | ||
|
|
9509929f5d | ||
|
|
63d4b5e3d8 | ||
|
|
f287d100a3 | ||
|
|
336d3ad8e5 | ||
|
|
9af212a542 | ||
|
|
e71631abe0 | ||
|
|
5d58a33f37 | ||
|
|
25ea797aed | ||
|
|
97eacefa6b | ||
|
|
f5fbbcfcb8 | ||
|
|
2c67c8b6ff | ||
|
|
d0fb08adf4 | ||
|
|
624493fb26 | ||
|
|
6eddee9a78 | ||
|
|
52138372ce | ||
|
|
a27538f582 | ||
|
|
385927fe06 | ||
|
|
a621032643 | ||
|
|
32646cb7f4 | ||
|
|
74b67eb6c6 | ||
|
|
231fc6ce70 | ||
|
|
1dfc091c9b | ||
|
|
df7fffcab3 | ||
|
|
b517e068ed | ||
|
|
8a330ecaa9 | ||
|
|
eef0d0bddb | ||
|
|
c1889afd7b | ||
|
|
644f365455 | ||
|
|
667890247c | ||
|
|
c727bbb530 | ||
|
|
79edf0fb15 | ||
|
|
c0f5e314e1 | ||
|
|
e125ab4783 | ||
|
|
a8cb076bbd | ||
|
|
691f76d1e0 | ||
|
|
4ea503f366 | ||
|
|
65c9bd7dcf | ||
|
|
16a0d1d7d5 | ||
|
|
bb40a43c5f | ||
|
|
e4a93da82e | ||
|
|
6de574bf5c | ||
|
|
2f773e9326 | ||
|
|
1594afdef7 | ||
|
|
ad154a368f | ||
|
|
171494ddfc | ||
|
|
21d8c40fc0 | ||
|
|
fd0338cb1c | ||
|
|
61c5a61623 | ||
|
|
bad8ee865d | ||
|
|
dcba3347d8 | ||
|
|
126dc77ef3 | ||
|
|
f64a07861d | ||
|
|
1ee3c5e5a0 | ||
|
|
1a81d7fc16 | ||
|
|
4cd82df73c | ||
|
|
1b24270a46 | ||
|
|
65e5899442 | ||
|
|
d17890f05b | ||
|
|
0be0c1a1c1 | ||
|
|
d29ebee2ac | ||
|
|
21ec7ce98f | ||
|
|
9f5ef68123 | ||
|
|
70660d778f | ||
|
|
e7e96f650a | ||
|
|
bd98d3e9ff | ||
|
|
892d9cc865 | ||
|
|
0295c43885 | ||
|
|
163e623964 | ||
|
|
7cde5adec8 | ||
|
|
650fa5ef1d | ||
|
|
27435508a3 | ||
|
|
a5cba3235e | ||
|
|
2c92e57fe7 | ||
|
|
dc58a90a48 | ||
|
|
966ac2cdbc | ||
|
|
385d98b3e0 | ||
|
|
c1b8197b8b | ||
|
|
d5004258db | ||
|
|
207a290edd | ||
|
|
54e087f8e5 | ||
|
|
7c9e6b1fb9 | ||
|
|
517e5e732c | ||
|
|
bc69a62af0 | ||
|
|
1495c9d3ce | ||
|
|
0982220397 | ||
|
|
89b558a1b1 | ||
|
|
30f1d4f18b | ||
|
|
8857aebb70 | ||
|
|
f14833f856 | ||
|
|
6c7bc18ae1 | ||
|
|
193faf6813 | ||
|
|
f8da618789 | ||
|
|
4479b1e662 | ||
|
|
50646e70a0 | ||
|
|
8d6d17c18d | ||
|
|
75d40e6b72 | ||
|
|
609b842e65 | ||
|
|
f7936d4378 | ||
|
|
9487a4f918 | ||
|
|
eca8735e22 | ||
|
|
09fdb887bb | ||
|
|
2335ea3067 | ||
|
|
05cfd3dc52 | ||
|
|
32aaab75b5 | ||
|
|
9ddc8dd93c | ||
|
|
0a88dc95a5 | ||
|
|
86362599c1 | ||
|
|
ca39809658 | ||
|
|
29dd8ade01 | ||
|
|
a7dcd9cccb | ||
|
|
e79f18a636 | ||
|
|
96a5479e9e | ||
|
|
75f853f2db | ||
|
|
7cee801622 | ||
|
|
6031f8437b | ||
|
|
d6da8fafc2 | ||
|
|
d4b49fac4a | ||
|
|
00b58c94c3 | ||
|
|
300fd7c1c4 | ||
|
|
70799e392f | ||
|
|
6cd3d7943d | ||
|
|
2e6af87823 | ||
|
|
42d9b384d4 | ||
|
|
9c6a1eac94 | ||
|
|
cbba014355 | ||
|
|
c5bb1856c2 | ||
|
|
956d1b025a | ||
|
|
b0e825c123 | ||
|
|
5989ee9cf0 | ||
|
|
040e9083da | ||
|
|
72a2a96063 | ||
|
|
ee75ffe823 | ||
|
|
a3e7151633 | ||
|
|
bd23133543 | ||
|
|
7249e3a4d1 | ||
|
|
26e09f85d2 | ||
|
|
5a2bcc47b6 | ||
|
|
382f279783 | ||
|
|
f0bf49f942 | ||
|
|
5821a87ac3 | ||
|
|
fb1e5b9dd5 | ||
|
|
5b35b2be30 | ||
|
|
659830b68a | ||
|
|
a9cb586f30 | ||
|
|
f3460eae48 | ||
|
|
b6561116a0 | ||
|
|
03ce503bd2 | ||
|
|
22dddb8e87 | ||
|
|
133bf3ffb8 | ||
|
|
1406715ce5 | ||
|
|
ba4f7323fe | ||
|
|
66d4960a79 | ||
|
|
8a57ac3caf | ||
|
|
cfc162a31d | ||
|
|
c4ad5e06f2 | ||
|
|
b44e35e8ef | ||
|
|
98fc9ffe14 | ||
|
|
4fef808efa | ||
|
|
1c81155a9a | ||
|
|
3258b00e16 | ||
|
|
cf6cbafa8c | ||
|
|
8474360271 | ||
|
|
6b812ccad3 | ||
|
|
594280e1df | ||
|
|
36873b9fe7 | ||
|
|
93fc018cd4 | ||
|
|
750c1c16db | ||
|
|
fdb63a6540 | ||
|
|
03c4f7219f | ||
|
|
37fcbc34b8 | ||
|
|
82806b00ab | ||
|
|
a174922733 | ||
|
|
94e93aea05 | ||
|
|
ff54b1cb5a | ||
|
|
3df149045d | ||
|
|
768846191b | ||
|
|
4ed77028e9 | ||
|
|
73a07ed669 | ||
|
|
c29a27d79d | ||
|
|
90a89d3468 | ||
|
|
fdc1cdd94c | ||
|
|
56e1412627 | ||
|
|
50e9b4c9da | ||
|
|
35aa10a28f | ||
|
|
7317e16737 | ||
|
|
5129454883 | ||
|
|
078c1dd489 | ||
|
|
3a887ab2fa | ||
|
|
00e61f875a | ||
|
|
f46ec55e0b | ||
|
|
0693fa9149 | ||
|
|
bc29102c18 | ||
|
|
07dedd3d2c | ||
|
|
8d5dd565a6 | ||
|
|
7259195caf | ||
|
|
3723ae025f | ||
|
|
2d971f3a05 | ||
|
|
c8ef530d52 | ||
|
|
0a2699f6cd | ||
|
|
ce8c70450c | ||
|
|
c454729f90 | ||
|
|
79353a6cbb | ||
|
|
98fc0033f5 | ||
|
|
8e0369440f | ||
|
|
54caae51e0 | ||
|
|
370785d515 | ||
|
|
483c137535 | ||
|
|
be14db7b73 | ||
|
|
c24fda189f | ||
|
|
bb5e4685cd | ||
|
|
8e23600ee0 | ||
|
|
31ce8f826b | ||
|
|
26a750ee0a | ||
|
|
2768d80b9b | ||
|
|
459ff72732 | ||
|
|
2a93168d48 | ||
|
|
1adda9817a | ||
|
|
095679845b | ||
|
|
7ad3a0601f | ||
|
|
dc988f7e37 | ||
|
|
3002fa120b | ||
|
|
137de338d2 | ||
|
|
ed6247b640 | ||
|
|
5c3caa3f31 | ||
|
|
22244a9d84 | ||
|
|
b133d9386e | ||
|
|
7213455fd3 | ||
|
|
ec45ca8abe | ||
|
|
477c81ae99 | ||
|
|
d10d5aed72 | ||
|
|
e407588231 | ||
|
|
65f2425902 | ||
|
|
28075f7cf8 | ||
|
|
5a6c6b0509 | ||
|
|
87bee3fb8c | ||
|
|
b0055c502e | ||
|
|
87e336eb79 | ||
|
|
cb9a93d97e | ||
|
|
9e638ccc12 | ||
|
|
285080fc74 | ||
|
|
8156fbfea3 | ||
|
|
cdf46276ac | ||
|
|
a15cb44096 | ||
|
|
191ed21a91 | ||
|
|
52b51b79ff | ||
|
|
214eac46ab | ||
|
|
c583102364 | ||
|
|
81adb15eb0 | ||
|
|
6ff1bbf2a5 | ||
|
|
c664ed7565 | ||
|
|
d7bd31c0ce | ||
|
|
85a08a9288 | ||
|
|
2ed6ae0799 | ||
|
|
601989f924 | ||
|
|
cbf1014ab9 | ||
|
|
bdcf1a3a62 | ||
|
|
ef4a1bef3b | ||
|
|
48bcc07bc6 | ||
|
|
c78b62112a | ||
|
|
e1d80df488 | ||
|
|
c5391bd8f4 | ||
|
|
96711686da | ||
|
|
97a81455b8 | ||
|
|
5bd834b7ac | ||
|
|
dd42f45d1a | ||
|
|
14f286053a | ||
|
|
1d13e51a5c | ||
|
|
2ae4f94eed | ||
|
|
f16b08fbdb | ||
|
|
d8e102a24c | ||
|
|
38156a84fc | ||
|
|
48e85e6690 | ||
|
|
3b9be97792 | ||
|
|
e1fc40d694 | ||
|
|
a8771d03bd | ||
|
|
049beb9bf8 | ||
|
|
522a012053 | ||
|
|
70471186ed | ||
|
|
5378c85c5d | ||
|
|
9c604536ca | ||
|
|
5f1796b39a | ||
|
|
fa45588c49 | ||
|
|
10444e588a | ||
|
|
d8b87ff6eb | ||
|
|
5ffdc44952 | ||
|
|
ab10f29db7 | ||
|
|
01a058b208 | ||
|
|
ad36de82a2 | ||
|
|
976686262d | ||
|
|
5bae4ffe4d | ||
|
|
fe4d567a82 | ||
|
|
9e7aeca447 | ||
|
|
2e8080b0e5 | ||
|
|
5b2cb4b063 | ||
|
|
a7223719a5 | ||
|
|
2f0ad0bf36 | ||
|
|
ce3171a722 | ||
|
|
b705dd8094 | ||
|
|
2b76ba7b4f | ||
|
|
3cf8c162bd | ||
|
|
6f85a989f0 | ||
|
|
426e18ea33 | ||
|
|
07c84df3dc | ||
|
|
2077c23c5e | ||
|
|
9ee6e6c170 | ||
|
|
715ce8b745 | ||
|
|
f7f64651c9 | ||
|
|
9320ea03ee | ||
|
|
ac1ae64ef8 | ||
|
|
97e11f7f5f | ||
|
|
0fdca9b183 | ||
|
|
34a554e64d | ||
|
|
ea12c39cba | ||
|
|
57fa0671e5 | ||
|
|
2bef2c6b87 | ||
|
|
52d9b7d6c4 | ||
|
|
15ba3757ab | ||
|
|
15207665d8 | ||
|
|
78d49e6713 | ||
|
|
8e3a567c03 | ||
|
|
b65b184405 | ||
|
|
c8545ff59d | ||
|
|
bb57fb3a93 | ||
|
|
efc96c8cf4 | ||
|
|
4d72f22b8a | ||
|
|
aa56a170c7 | ||
|
|
d96fa756c6 | ||
|
|
91c6940818 | ||
|
|
7ecf1ac082 | ||
|
|
f61c837b41 | ||
|
|
1c9129497f | ||
|
|
0903b4da87 | ||
|
|
aa10a32d4f | ||
|
|
a0b26ae7cd | ||
|
|
71442efa03 | ||
|
|
94dbde9cfd | ||
|
|
d1ec646b5f | ||
|
|
33de57bd6c | ||
|
|
8367e909c9 | ||
|
|
c19efebc76 | ||
|
|
6122ba335f | ||
|
|
c92be21524 | ||
|
|
a437398993 | ||
|
|
2cc95fda85 | ||
|
|
77afadcc1f | ||
|
|
3ede8e2937 | ||
|
|
330abe14fe | ||
|
|
05b949ed98 | ||
|
|
e0cf910f49 | ||
|
|
07ecee2429 | ||
|
|
f40ad6e90a | ||
|
|
5daa7d6a08 | ||
|
|
2df1ea2097 | ||
|
|
ab760df389 | ||
|
|
2db58f09bc | ||
|
|
4065a59024 | ||
|
|
23723289c2 | ||
|
|
bcf6d7a2aa | ||
|
|
9f1904e8d2 | ||
|
|
57e5599d82 | ||
|
|
7f10566d5e | ||
|
|
4dcf98b9f7 | ||
|
|
91b994b89c | ||
|
|
2d9801ffe3 | ||
|
|
75f1de8f8f | ||
|
|
55c0efae3f | ||
|
|
f166f15f7d | ||
|
|
db7a62f644 | ||
|
|
0c86f64565 | ||
|
|
17ff0972ab | ||
|
|
717297ef29 | ||
|
|
cb6c65183d | ||
|
|
7964f831e9 | ||
|
|
aaae1aad67 | ||
|
|
ce4dc610ed | ||
|
|
615a80835a | ||
|
|
9ab1f56f83 | ||
|
|
3c28480fda | ||
|
|
af8e086aac | ||
|
|
cb302fbb63 | ||
|
|
b6a056799c | ||
|
|
15a578e6ac | ||
|
|
c3ad0bc9e7 | ||
|
|
a0fc77cd76 | ||
|
|
284fb49f60 | ||
|
|
4c116e1577 | ||
|
|
700c0e3e73 | ||
|
|
042ef30a9f | ||
|
|
d59e3e5bc8 | ||
|
|
a2fb7884f9 | ||
|
|
c34dbebcc5 | ||
|
|
737407c953 | ||
|
|
d40081b0a8 | ||
|
|
bc10246974 | ||
|
|
02a7c27ec6 | ||
|
|
e34e8ddb9a | ||
|
|
aec7cdefde | ||
|
|
6996974376 | ||
|
|
9d24025496 | ||
|
|
5ec5369289 | ||
|
|
bb12b0c8b9 | ||
|
|
0140f5057d | ||
|
|
459101cb4f | ||
|
|
26a3ca0413 | ||
|
|
692e10ec94 | ||
|
|
d84a886e87 | ||
|
|
80f3bc6c1b | ||
|
|
2acfea2f0c | ||
|
|
38095cf8b8 | ||
|
|
af062aa5f6 | ||
|
|
9874d008aa | ||
|
|
1f129feed8 | ||
|
|
88da45d9dd | ||
|
|
a76eafa0d4 | ||
|
|
8c2a910a94 | ||
|
|
f7e8725406 | ||
|
|
52646ee9f5 | ||
|
|
e363e53516 | ||
|
|
6defdcd018 | ||
|
|
75ad2e82fd | ||
|
|
c2980f34c7 | ||
|
|
7117ec5a7c | ||
|
|
ab5d5a3e79 | ||
|
|
ffafad5d4a | ||
|
|
46afde019b | ||
|
|
6f5ed78d0a | ||
|
|
2b71c260d8 | ||
|
|
832284e710 | ||
|
|
aa068bd0a0 | ||
|
|
926462e218 | ||
|
|
ebe68c9075 | ||
|
|
b3720deda4 | ||
|
|
1a14c19cd2 | ||
|
|
f9426f30a9 | ||
|
|
05cf98fae8 | ||
|
|
6e5fd5eb58 | ||
|
|
8edebd56be | ||
|
|
a417b4eda9 | ||
|
|
acf09b805f | ||
|
|
1ef91d3a21 | ||
|
|
3867d1619e | ||
|
|
549f10c150 | ||
|
|
280ceef46b | ||
|
|
7e652b9f9f | ||
|
|
1527dfc7c1 | ||
|
|
36d9022c7d | ||
|
|
67272dddd3 | ||
|
|
52ab3dbba4 | ||
|
|
2e620c9a43 | ||
|
|
65533360a2 | ||
|
|
60f15baef2 | ||
|
|
6ef86d2f85 | ||
|
|
dbc6027d9b | ||
|
|
92afb654db | ||
|
|
31816168da | ||
|
|
d07b7dc72e | ||
|
|
2f1eecd709 | ||
|
|
027e0334a2 | ||
|
|
e22dabe59a | ||
|
|
48c3dfb9eb | ||
|
|
f5df332d3e | ||
|
|
62632893ad | ||
|
|
e3ad92df44 | ||
|
|
2c07bd764d | ||
|
|
6a8be838be | ||
|
|
fb69347ea7 | ||
|
|
b92b8c443d | ||
|
|
b2fad54f1f | ||
|
|
897475f186 | ||
|
|
4b60b3d991 | ||
|
|
e6b165003f | ||
|
|
4a0519c674 | ||
|
|
792606925f | ||
|
|
a2f58f1d3d | ||
|
|
5a756ffc4c | ||
|
|
cdad15bae3 | ||
|
|
015546b07c | ||
|
|
72305a9218 | ||
|
|
b42fd50a7c | ||
|
|
b0f999fc5a | ||
|
|
e5d27ead40 | ||
|
|
5dbecd73a0 | ||
|
|
ed3bfb152a | ||
|
|
05b824b4d6 | ||
|
|
1e412c7a13 | ||
|
|
13801c6b99 | ||
|
|
9dd1646818 | ||
|
|
a237f5dc54 | ||
|
|
7b178844e8 | ||
|
|
5f24f79b4d | ||
|
|
07d0093fbc | ||
|
|
efa977bd21 | ||
|
|
ab585b6efc | ||
|
|
662ab45037 | ||
|
|
2e620ba35a | ||
|
|
b99efb24df | ||
|
|
da3775ee7c | ||
|
|
afbb6b6659 | ||
|
|
c67b34ed35 | ||
|
|
0d545313cd | ||
|
|
318aed668d | ||
|
|
39f3fe4606 | ||
|
|
570fcd9174 | ||
|
|
356bb80676 | ||
|
|
1f21e1a945 | ||
|
|
8d9ddf4a51 | ||
|
|
4c5ac44621 | ||
|
|
fa104b6613 | ||
|
|
9e89499fba | ||
|
|
101c5a2dca | ||
|
|
dedd0ef20d | ||
|
|
6b5aba1960 | ||
|
|
beaee43eef | ||
|
|
d34f9ffece | ||
|
|
bbf765c535 | ||
|
|
2420794b94 | ||
|
|
6d9065ebbe | ||
|
|
fd39b3270c | ||
|
|
284b556019 | ||
|
|
2f18dc1b9c | ||
|
|
9c638968ff | ||
|
|
8dce4e7114 | ||
|
|
f31b43e1dc | ||
|
|
dacea0db8a | ||
|
|
eb3a6e2297 | ||
|
|
36f8d66af2 | ||
|
|
8ad7097614 | ||
|
|
3d1ff876ad | ||
|
|
fe71403046 | ||
|
|
4d971a9c33 | ||
|
|
088c1606df | ||
|
|
49b5c081d6 | ||
|
|
bb2f13aed4 | ||
|
|
505841b194 | ||
|
|
da625fc847 | ||
|
|
2886c688f0 | ||
|
|
ea7e7456a5 | ||
|
|
c6d13d98e9 | ||
|
|
b05d1c5f6e | ||
|
|
0592e639c0 | ||
|
|
43b37ead7c | ||
|
|
9778e4ad08 | ||
|
|
3fb8528f41 | ||
|
|
28521540c1 | ||
|
|
f5b6b8ece9 | ||
|
|
41da70f494 | ||
|
|
e644782b53 | ||
|
|
2f76d2f800 | ||
|
|
18b896f034 | ||
|
|
fcf024ef4f | ||
|
|
5e9b4d8074 | ||
|
|
8ab8f57594 | ||
|
|
90404da0a7 | ||
|
|
e773aebb6a | ||
|
|
ae67e6fcbd | ||
|
|
a5422d2fc4 | ||
|
|
0aae72b694 | ||
|
|
951535a3d5 | ||
|
|
66a175e48d | ||
|
|
a1709b8deb | ||
|
|
6f0a91856f | ||
|
|
9e23700a50 | ||
|
|
42b90a4537 | ||
|
|
e5ea3d7f4a | ||
|
|
7bc28e3003 | ||
|
|
fd3f0036fe | ||
|
|
90ddcaab8b | ||
|
|
03a4123c6c | ||
|
|
0ce2d0179b | ||
|
|
986bdc09c5 | ||
|
|
62e3f56223 | ||
|
|
d585b22a93 | ||
|
|
26a05d3046 | ||
|
|
fba1aea273 | ||
|
|
e222842864 | ||
|
|
5eecee1102 | ||
|
|
26bb72d12f | ||
|
|
d04cfa89ce | ||
|
|
afda242968 | ||
|
|
d9858d9bb7 | ||
|
|
ecb171905e | ||
|
|
a2cdfa5492 | ||
|
|
387a06fdc5 | ||
|
|
7c0ccba344 | ||
|
|
369d0eb676 | ||
|
|
0412374568 | ||
|
|
bc14550ded | ||
|
|
4c5d9f2742 | ||
|
|
dee8e74e00 | ||
|
|
d10ee5a76e | ||
|
|
16c30d5ef9 | ||
|
|
83dc527389 | ||
|
|
4f4c427259 | ||
|
|
e24da32424 | ||
|
|
a13b720598 | ||
|
|
d26086324d | ||
|
|
85c055e997 | ||
|
|
212a0b2fe7 | ||
|
|
82bc2e2d71 | ||
|
|
4c4cf7cc94 | ||
|
|
f3f6515c72 | ||
|
|
5a04b2393d | ||
|
|
320f04b4a4 | ||
|
|
e6c3c5993d | ||
|
|
d4fd234b75 | ||
|
|
0cc66bbed6 | ||
|
|
38fdbdaae1 | ||
|
|
6a2d7d1523 | ||
|
|
5453f0c628 | ||
|
|
790df062c7 | ||
|
|
13b9a65a9e | ||
|
|
2de0c09e8e | ||
|
|
b053b55e2f | ||
|
|
13ddcb9552 | ||
|
|
f46512c626 | ||
|
|
5df2850dca | ||
|
|
f03eb1f505 | ||
|
|
4374aa1a20 | ||
|
|
3e7cf0a463 | ||
|
|
a3a62570a9 | ||
|
|
64fb9d0db7 | ||
|
|
893538d851 | ||
|
|
72210dc19b | ||
|
|
6bc40a5e26 | ||
|
|
3f697b11ac | ||
|
|
fc70f82734 | ||
|
|
20db435325 | ||
|
|
5c434e273e | ||
|
|
f3911bccc8 | ||
|
|
59412cd38a | ||
|
|
39c5d64536 | ||
|
|
2f46ffec3a | ||
|
|
c2f3ce1491 | ||
|
|
8f7a4800ee | ||
|
|
6d88670eee | ||
|
|
efce6c5aab | ||
|
|
08891edd04 | ||
|
|
834a7a078a | ||
|
|
1628a48bde | ||
|
|
1f2d1a2df2 | ||
|
|
ffd309e24e | ||
|
|
b90d18e1fb | ||
|
|
ca05d75644 | ||
|
|
7d3c348c68 | ||
|
|
1ead118722 | ||
|
|
dbb7af4f2e | ||
|
|
bd77c11d41 | ||
|
|
6098674956 | ||
|
|
a9b9f915d2 | ||
|
|
053e0981ad | ||
|
|
43fceaf468 | ||
|
|
f710b3c2b7 | ||
|
|
06c7e015bb | ||
|
|
cbadfc061b | ||
|
|
b2603fddd2 | ||
|
|
336a50774d | ||
|
|
6830fb0405 | ||
|
|
d55ed1cb5d | ||
|
|
b08d6b5019 | ||
|
|
b9591bb314 | ||
|
|
06cac9333f | ||
|
|
3fae1cc099 | ||
|
|
41cb100160 | ||
|
|
52508fbac7 | ||
|
|
0dffaa53dd | ||
|
|
5f8651fe87 | ||
|
|
f5a123212b | ||
|
|
29667900f6 | ||
|
|
0329bbc0cb | ||
|
|
086da9f73f | ||
|
|
feff28a171 | ||
|
|
1d36146768 | ||
|
|
b221ff35b2 | ||
|
|
a008f04cf7 | ||
|
|
49c163d1ee | ||
|
|
8da8db215a | ||
|
|
a04b714d28 | ||
|
|
14cc6c0332 | ||
|
|
ed3ef01e37 | ||
|
|
1d38a3b7b8 | ||
|
|
d2b3920684 | ||
|
|
c5b5b51aa4 | ||
|
|
74a92e117c | ||
|
|
48f4e52a22 | ||
|
|
6e73a25775 | ||
|
|
9a7c1caff0 | ||
|
|
72ac76d4cf | ||
|
|
46511ae315 | ||
|
|
041f36b67d | ||
|
|
66d89cc480 | ||
|
|
16feb2fe6e | ||
|
|
272b2b588a | ||
|
|
39d986ae59 | ||
|
|
3d23322556 | ||
|
|
00a8ad9207 | ||
|
|
30c11306f9 | ||
|
|
adf9fcb290 | ||
|
|
46dc264654 | ||
|
|
ea7e0686df | ||
|
|
4adc8516b5 | ||
|
|
5d7005320f | ||
|
|
0b9673f651 | ||
|
|
012e0440e0 | ||
|
|
28769a13eb | ||
|
|
0181267b3c | ||
|
|
a49eff45da | ||
|
|
23e39cb8b3 | ||
|
|
47e6c1f354 | ||
|
|
b38b4e12a0 | ||
|
|
86971c7b86 | ||
|
|
daccab5a07 | ||
|
|
cd69c59e6c | ||
|
|
65e9a31f22 | ||
|
|
9a6ae3c454 | ||
|
|
40329db2b2 | ||
|
|
377ec64229 | ||
|
|
b6e8e518d1 | ||
|
|
c8c1125efd | ||
|
|
450cbbb76d | ||
|
|
f9f3d3a6e1 | ||
|
|
08803c3f30 | ||
|
|
121f376f7a | ||
|
|
2ad52d9fc9 | ||
|
|
9892abdbb2 | ||
|
|
b5d2fde37d | ||
|
|
292cf02d0c | ||
|
|
4d6c39ed6e | ||
|
|
ceecf89892 | ||
|
|
87695c931e | ||
|
|
30465fdac8 | ||
|
|
37cad9b4fc | ||
|
|
774af5c371 | ||
|
|
ca667c7ed6 | ||
|
|
53c1244ad2 | ||
|
|
0fb8238e9d | ||
|
|
11780b0f12 | ||
|
|
a571ed8dda | ||
|
|
fca6541c83 | ||
|
|
5b2012dba2 | ||
|
|
aa1abf2b69 | ||
|
|
4dcd7955ef | ||
|
|
4d32d93ee2 | ||
|
|
abc9eb7bdc | ||
|
|
ec19dcc8f8 | ||
|
|
9051e411d0 | ||
|
|
70e01178a9 | ||
|
|
0f456f7126 | ||
|
|
4979b43ebc | ||
|
|
bb65d9520d | ||
|
|
22c93cb029 | ||
|
|
f7772ecb2b | ||
|
|
191b8f5205 | ||
|
|
1661534d5a | ||
|
|
0c5769f329 | ||
|
|
64b9414271 | ||
|
|
8cb9bdd852 | ||
|
|
438e922a75 | ||
|
|
21b7d68f49 | ||
|
|
9160d49625 | ||
|
|
97491b5446 | ||
|
|
338f363fce | ||
|
|
2245ea09d4 | ||
|
|
4eddee5b4d | ||
|
|
a5b95b7be3 | ||
|
|
5c074a2bed | ||
|
|
734de118f0 | ||
|
|
8be0970a0c | ||
|
|
06037295c4 | ||
|
|
67ad440381 | ||
|
|
6bb952bf9a | ||
|
|
82c49e62d1 | ||
|
|
c5ccf54572 | ||
|
|
382f9ce95d | ||
|
|
9bbd285c3a | ||
|
|
786ea1029e | ||
|
|
a3fa8b82fa |
3
.github/changed-lines-count-labeler.yml
vendored
Normal file
3
.github/changed-lines-count-labeler.yml
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# Add this tag for any changes for more than 1 line
|
||||
"Pending analysis of PR (maintenance team)":
|
||||
min: 1
|
||||
86
.github/scripts/get_changed_php.sh
vendored
Executable file
86
.github/scripts/get_changed_php.sh
vendored
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2025 MDW <mdeweerd@users.noreply.github.com>
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# This script retrieves the list of changed PHP files for a pull request
|
||||
# using the GitHub API and sets two outputs:
|
||||
# - any_changed: "true" if at least one PHP file changed, "false" otherwise
|
||||
# - all_changed_files: space-separated list of changed PHP file paths
|
||||
#
|
||||
# Required environment variables:
|
||||
# GITHUB_TOKEN - GitHub token with repo access
|
||||
# GITHUB_REPOSITORY - "owner/repo"
|
||||
# GITHUB_EVENT_PATH - Path to the event JSON payload
|
||||
|
||||
# Verify required environment variables are set
|
||||
if [[ -z "${GITHUB_TOKEN:-}" ]]; then
|
||||
echo "GITHUB_TOKEN is not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
|
||||
echo "GITHUB_REPOSITORY is not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z "${GITHUB_EVENT_PATH:-}" ]]; then
|
||||
echo "GITHUB_EVENT_PATH is not set" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract the pull request number from the event payload
|
||||
pr_number=$(jq --raw-output '.pull_request.number' "$GITHUB_EVENT_PATH")
|
||||
if [[ "$pr_number" == "null" ]]; then
|
||||
echo "Not a pull request event"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Split repository into owner and repo name
|
||||
# Split repository into owner and repo name using Bash parameter expansion
|
||||
owner="${GITHUB_REPOSITORY%%/*}" # Extract text before the first '/'
|
||||
repo="${GITHUB_REPOSITORY##*/}" # Extract text after the last '/'
|
||||
|
||||
page=1
|
||||
per_page=100
|
||||
changed_php_files=()
|
||||
|
||||
# Loop through all pages to gather changed files
|
||||
while true; do
|
||||
response=$(curl -s -H "Authorization: token ${GITHUB_TOKEN}" \
|
||||
"https://api.github.com/repos/${owner}/${repo}/pulls/${pr_number}/files?per_page=${per_page}&page=${page}")
|
||||
|
||||
# Filter for files ending with .php and add them to the list
|
||||
mapfile -t files < <(echo "$response" | jq -r '.[] | select(.filename | test("\\.php$")) | .filename')
|
||||
changed_php_files+=("${files[@]}")
|
||||
|
||||
# Check if we have reached the last page (less than per_page results)
|
||||
count=$(echo "$response" | jq 'length')
|
||||
if (( count < per_page )); then
|
||||
break
|
||||
fi
|
||||
((page++))
|
||||
done
|
||||
|
||||
|
||||
# Build a space-separated string of changed PHP files
|
||||
# This does not cope with files that have spaces.
|
||||
# But such files do not exist in the project (at least not for the
|
||||
# files we are filtering).
|
||||
all_changed_files=$(IFS=" " ; echo "${changed_php_files[*]}")
|
||||
|
||||
|
||||
# Determine changed files flag
|
||||
if [ -z "$all_changed_files" ]; then
|
||||
any_changed="false"
|
||||
else
|
||||
any_changed="true"
|
||||
fi
|
||||
|
||||
# Set outputs for GitHub Actions if GITHUB_OUTPUT is available
|
||||
if [ -n "${GITHUB_OUTPUT:-}" ]; then
|
||||
echo "any_changed=${any_changed}" >> "$GITHUB_OUTPUT"
|
||||
echo "all_changed_files=${all_changed_files}" >> "$GITHUB_OUTPUT"
|
||||
else
|
||||
# Otherwise, print the outputs
|
||||
echo "any_changed=${any_changed}"
|
||||
echo "all_changed_files=${all_changed_files}"
|
||||
fi
|
||||
21
.github/workflows/pr-18-autolabel.yaml.disabled
vendored
Normal file
21
.github/workflows/pr-18-autolabel.yaml.disabled
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
name: "Set label for v18"
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- "18.0"
|
||||
push:
|
||||
branches:
|
||||
- "18.0"
|
||||
|
||||
jobs:
|
||||
changed-lines-count-labeler:
|
||||
runs-on: ubuntu-latest
|
||||
name: An action for automatically labelling pull requests based on the changed lines count
|
||||
steps:
|
||||
- name: Set a label
|
||||
uses: vkirilichev/changed-lines-count-labeler@v0.2
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
configuration-path: .github/changed-lines-count-labeler.yml
|
||||
continue-on-error: true
|
||||
45
.github/workflows/pr-18.yaml.disabled
vendored
Normal file
45
.github/workflows/pr-18.yaml.disabled
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
# Action to prepare the github action
|
||||
# Go on Dolibarr - Settings - Developer settings - Enter a name + webhook to disable + Permissions (see app test) + Can install by any account
|
||||
# Click on generate the private keys
|
||||
# Click on Install application - choose user of the Organization
|
||||
# Go on Organisation - Secret and variables and create a secret PR18_SECRET_KEY and copy the content of received private key. Choose the repository access to "Repository Dolibarr".
|
||||
# Go on Organisation - Secret and variables and create a variable PR18_APP_ID and copy the ID of the previously create ID. Choose the repository access to "Repository Dolibarr".
|
||||
#
|
||||
|
||||
name: Set reviewer for v18
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- "18.0"
|
||||
push:
|
||||
branches:
|
||||
- "18.0"
|
||||
|
||||
jobs:
|
||||
pr18:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
#env:
|
||||
# GH_TOKEN: ${{ github.token }}
|
||||
# GH_TOKENS: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
steps:
|
||||
- name: Generate a token
|
||||
id: generate-token
|
||||
uses: actions/create-github-app-token@v2
|
||||
with:
|
||||
app-id: ${{ vars.PR18_APP_ID }}
|
||||
private-key: ${{ secrets.PR18_SECRET_KEY }}
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Assign reviewer
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.generate-token.outputs.token }}
|
||||
url: ${{ github.event.pull_request.html_url }}
|
||||
run: |
|
||||
gh pr edit "$url" --add-reviewer rycks
|
||||
gh pr edit "$url" --add-reviewer lvessiller-opendsi
|
||||
|
||||
122
.github/workflows/pre-commit.yml
vendored
Normal file
122
.github/workflows/pre-commit.yml
vendored
Normal file
@@ -0,0 +1,122 @@
|
||||
---
|
||||
name: pre-commit
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
RAW_LOG: pre-commit.log
|
||||
CS_XML: pre-commit.xml
|
||||
steps:
|
||||
- name: Install required tools
|
||||
run: sudo apt-get update && sudo apt-get install cppcheck
|
||||
if: false
|
||||
|
||||
# Checkout git sources to analyze
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
# The next uses the git API because there is no clone yet.
|
||||
# This is faster for a big repo.
|
||||
- name: Get all changed php files (if PR)
|
||||
id: changed-php
|
||||
if: env.gh_event == 'pull_request'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./.github/scripts/get_changed_php.sh
|
||||
|
||||
# Action setup-python needs a requirements.txt or pyproject.toml
|
||||
# This ensures one of them exists.
|
||||
- name: Create requirements.txt if no requirements.txt or pyproject.toml
|
||||
run: |-
|
||||
[ -r requirements.txt ] || [ -r pyproject.toml ] || touch requirements.txt
|
||||
# Install python and pre-commit tool
|
||||
- uses: actions/setup-python@v5
|
||||
with:
|
||||
cache: pip
|
||||
python-version: "3.11"
|
||||
- run: python -m pip install pre-commit
|
||||
# Restore previous cache of precommit
|
||||
- uses: actions/cache/restore@v4
|
||||
with:
|
||||
path: ~/.cache/pre-commit/
|
||||
key: pre-commit-4|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
|
||||
- name: Extract PHP version
|
||||
id: extract-php-version
|
||||
run: |
|
||||
PHP_VERSION=$(sed -n 's/.*\$arrayphpmaxversionwarning\s*=\s*array\s*(\s*\([0-9]\+\)\s*,\s*\([0-9]\+\).*/\1.\2/p' htdocs/install/check.php)
|
||||
echo "PHP_VERSION=$PHP_VERSION" >> $GITHUB_ENV
|
||||
|
||||
- name: Setup PHPCS
|
||||
uses: shivammathur/setup-php@v2
|
||||
# Install proper php version, and also install phpcs which may be needed
|
||||
with:
|
||||
php-version: ${{ env.PHP_VERSION }} # Version from check.php
|
||||
coverage: none # disable xdebug, pcov
|
||||
tools: phpcs
|
||||
|
||||
# Run all the precommit tools (defined into pre-commit-config.yaml).
|
||||
# We can force exclusion of some of them here.
|
||||
- name: Run pre-commit hooks
|
||||
env:
|
||||
# SKIP is used by pre-commit to not execute certain hooks
|
||||
SKIP: no-commit-to-branch,php-cs,php-cbf,trailing-whitespace,end-of-file-fixer,check-json,check-executables-have-shebangs,check-shebang-scripts-are-executable,beautysh,yamllint,shellcheck
|
||||
run: |
|
||||
set -o pipefail
|
||||
pre-commit gc
|
||||
pre-commit run --show-diff-on-failure --color=always --all-files | tee ${RAW_LOG}
|
||||
|
||||
# The next uses git, which is slow for a bit repo.
|
||||
# - name: Get all changed php files (if PR)
|
||||
# id: changed-php
|
||||
# uses: tj-actions/changed-files@v42
|
||||
# if: github.event_name == 'pull_request'
|
||||
# with:
|
||||
# files: |
|
||||
# **.php
|
||||
|
||||
- name: Run some pre-commit hooks on selected changed files only
|
||||
if: steps.changed-php.outputs.any_changed == 'true'
|
||||
env:
|
||||
ALL_CHANGED_FILES: ${{ steps.changed-php.outputs.all_changed_files }}
|
||||
run: |
|
||||
set -o pipefail
|
||||
pre-commit run php-cs --files ${ALL_CHANGED_FILES} | tee -a ${RAW_LOG}
|
||||
|
||||
- name: Run some pre-commit hooks on all files on push to "main" branches
|
||||
if: |
|
||||
github.event_name == 'push'
|
||||
&& (
|
||||
github.event.ref == 'refs/heads/develop'
|
||||
|| endsWith(github.event.ref, '.0')
|
||||
)
|
||||
run: |
|
||||
set -o pipefail
|
||||
ln -sf ~/.cache .cache # Absolute path in .pre-commit-config.yaml
|
||||
pre-commit run --hook-stage manual -a php-cs-with-cache | tee -a ${RAW_LOG}
|
||||
ls -l ~/.cache/pre-commit/
|
||||
|
||||
- name: Convert Raw Log to Annotations
|
||||
uses: mdeweerd/logToCheckStyle@v2024.2.9
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
in: ${{ env.RAW_LOG }}
|
||||
|
||||
# Save the precommit cache
|
||||
- uses: actions/cache/save@v4
|
||||
if: ${{ ! cancelled() }}
|
||||
with:
|
||||
path: ~/.cache/pre-commit/
|
||||
key: pre-commit-4|${{ env.pythonLocation }}|${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
# Upload result log files of precommit into the Artifact shared store
|
||||
- name: Provide log as artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
if: ${{ ! cancelled() }}
|
||||
with:
|
||||
name: precommit-logs
|
||||
path: |
|
||||
${{ env.RAW_LOG }}
|
||||
${{ env.CS_XML }}
|
||||
retention-days: 2
|
||||
2
.github/workflows/stale-issues-safe.yml
vendored
2
.github/workflows/stale-issues-safe.yml
vendored
@@ -8,7 +8,7 @@ on:
|
||||
types: [created]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {} # none
|
||||
permissions: {} # no restriction by default
|
||||
|
||||
jobs:
|
||||
stale:
|
||||
|
||||
28
.github/workflows/test.yaml
vendored
Normal file
28
.github/workflows/test.yaml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Test github actions
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
types: [opened, reopened, synchronize]
|
||||
push:
|
||||
|
||||
env:
|
||||
ENVGHT: ${{ secrets.GITHUB_TOKEN }}
|
||||
ENVGHU: ${{ github.token }}
|
||||
TEST_ACCESS_KEY: ${{ secrets.TEST_ACCESS_KEY }}
|
||||
TEST_VAR_REPO: ${{ vars.TEST_VAR_REPO }}
|
||||
ENVLOCAL: "varenvlocal"
|
||||
|
||||
jobs:
|
||||
testjob:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Log
|
||||
run: |
|
||||
echo "Run action by ${{ github.actor }}"
|
||||
echo "github.token=${{ github.token }}"
|
||||
echo "secrets.GITHUB_TOKEN=${{ secrets.GITHUB_TOKEN }}"
|
||||
echo "GITHUB_EVENT_PATH=$GITHUB_EVENT_PATH"
|
||||
echo "repo-token: ${{secrets.GITHUB_TOKEN}}"
|
||||
echo "secret repository TEST_ACCESS_KEY: ${{secrets.TEST_ACCESS_KEY}}"
|
||||
echo "variable repository : ${{vars.TEST_VAR_REPO}}"
|
||||
echo "ENVLOCAL: ${{env.ENVLOCAL}}"
|
||||
19
.idea/php.xml
generated
19
.idea/php.xml
generated
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="MessDetectorOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCSFixerOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PHPCodeSnifferOptionsConfiguration">
|
||||
<option name="highlightLevel" value="WARNING" />
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PhpStanOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
<component name="PsalmOptionsConfiguration">
|
||||
<option name="transferred" value="true" />
|
||||
</component>
|
||||
</project>
|
||||
173
.pre-commit-config.yaml
Normal file
173
.pre-commit-config.yaml
Normal file
@@ -0,0 +1,173 @@
|
||||
---
|
||||
exclude: (?x)^( htdocs/includes/ckeditor/.* )
|
||||
repos:
|
||||
# Several miscellaneous checks and fix (on yaml files, end of files fix)
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.5.0
|
||||
hooks:
|
||||
- id: no-commit-to-branch
|
||||
args: [--branch, develop, --pattern, \d+.0$]
|
||||
- id: check-yaml
|
||||
args: [--unsafe]
|
||||
- id: check-json
|
||||
- id: mixed-line-ending
|
||||
exclude: (?x)^(htdocs/includes/tecnickcom/tcpdf/fonts/.*)$
|
||||
- id: trailing-whitespace
|
||||
exclude_types: [markdown]
|
||||
- id: end-of-file-fixer
|
||||
- id: check-merge-conflict
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-shebang-scripts-are-executable
|
||||
exclude:
|
||||
(?x)^( dev/tools/dolibarr-postgres2mysql.php |test/other/test_serialize.php
|
||||
|test/phpunit/textutf8.txt |test/phpunit/textiso.txt |htdocs/includes/.*
|
||||
|htdocs/modulebuilder/template/.* |build/debian/dolibarr.postrm |build/debian/dolibarr.postinst
|
||||
|build/debian/dolibarr.config )$
|
||||
- id: fix-byte-order-marker
|
||||
- id: check-case-conflict
|
||||
|
||||
# Beautify shell scripts
|
||||
- repo: https://github.com/lovesegfault/beautysh.git
|
||||
rev: v6.2.1
|
||||
hooks:
|
||||
- id: beautysh
|
||||
exclude: (?x)^(dev/setup/git/hooks/pre-commit)$
|
||||
args: [--tab]
|
||||
|
||||
# Run local script
|
||||
#
|
||||
# For instance to update the license in edited files, you could add to local.sh:
|
||||
#
|
||||
# ```shell
|
||||
# #!/bin/bash
|
||||
# MYDIR=$(dirname "$0")
|
||||
# CHANGED_INTERNALS=$(git diff --name-only | grep -v includes)
|
||||
# "$MYDIR/dev/tools/updatelicense.php" $CHANGED_INTERNALS
|
||||
# ```
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: local-precommit-script
|
||||
name: Run local script before commit if it exists
|
||||
language: system
|
||||
entry: bash -c '[ ! -x local.sh ] || ./local.sh'
|
||||
pass_filenames: false
|
||||
|
||||
# Check PHP syntax
|
||||
- repo: https://github.com/mdeweerd/pre-commit-php
|
||||
rev: v1.6.5
|
||||
hooks:
|
||||
- id: php-cbf
|
||||
files: \.(php)$
|
||||
args: [--standard=dev/setup/codesniffer/ruleset.xml]
|
||||
- id: php-cs
|
||||
files: \.(php)$
|
||||
args:
|
||||
[
|
||||
--standard=dev/setup/codesniffer/ruleset.xml,
|
||||
--report=emacs,
|
||||
--severity=5,
|
||||
]
|
||||
- alias: php-cs-with-cache
|
||||
id: php-cs
|
||||
# Configuration for ci - run on all files with cache
|
||||
stages: [manual]
|
||||
args:
|
||||
[
|
||||
--standard=dev/setup/codesniffer/ruleset.xml,
|
||||
--report=emacs,
|
||||
--severity=5,
|
||||
--cache=.cache/pre-commit/dolibarr-php-cs.cache,
|
||||
.,
|
||||
]
|
||||
pass_filenames: false # Run on all files
|
||||
- id: php-lint
|
||||
exclude:
|
||||
(?x)^(htdocs/includes/symfony/var-dumper/Tests/.*)$
|
||||
- id: php-stan
|
||||
stages: [manual]
|
||||
files: \.(php)$
|
||||
|
||||
# Prettier (format code, only for non common files)
|
||||
- repo: https://github.com/pre-commit/mirrors-prettier
|
||||
rev: v3.0.3
|
||||
hooks:
|
||||
- id: prettier
|
||||
stages: [manual]
|
||||
exclude:
|
||||
(?x)^( .*\.(phar |min\.css |lock) |htdocs/(includes|theme/common)/.*
|
||||
)$
|
||||
exclude_types:
|
||||
- php
|
||||
- executable
|
||||
- binary
|
||||
- shell
|
||||
- javascript
|
||||
- markdown
|
||||
- html
|
||||
- less
|
||||
- plain-text
|
||||
- scss
|
||||
- css
|
||||
- yaml
|
||||
|
||||
# Check format of yaml files
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.33.0
|
||||
hooks:
|
||||
- id: yamllint
|
||||
args:
|
||||
- --no-warnings
|
||||
- -d
|
||||
- "{extends: relaxed, rules: {line-length: {max: 120}}}"
|
||||
|
||||
# Execute codespell to fix typo errors (setup of codespell into dev/tools/codespell/)
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.2.6
|
||||
hooks:
|
||||
- id: codespell
|
||||
# Due to a current limitation of configuration files,
|
||||
# we can specify two dicts only on the CLI.
|
||||
# You can update the contents of the exclude-file codespell-lines-ignore with the script
|
||||
# dev/tools/codespell/addCodespellIgnores.sh
|
||||
args:
|
||||
- -D
|
||||
- "-"
|
||||
- -D
|
||||
- dev/tools/codespell/codespell-dict.txt
|
||||
- -I
|
||||
- dev/tools/codespell/codespell-ignore.txt
|
||||
- -x
|
||||
- dev/tools/codespell/codespell-lines-ignore.txt
|
||||
- --uri-ignore-words-list
|
||||
- ned
|
||||
exclude_types: [image]
|
||||
exclude: (?x)^(.phan/stubs/.*)$
|
||||
additional_dependencies: [tomli]
|
||||
- alias: codespell-lang-en_US
|
||||
# Only for translations with specialised exceptions
|
||||
# -D contains predefined conversion dictionaries
|
||||
# -L is to ignore some words
|
||||
id: codespell
|
||||
files: ^htdocs/langs/en_US/.*$
|
||||
args:
|
||||
- -D
|
||||
- "-"
|
||||
- -D
|
||||
- dev/tools/codespell/codespell-dict.txt
|
||||
- -L
|
||||
- informations,medias,uptodate,reenable,crypted,developpers
|
||||
- -L
|
||||
- creat,unitl,alltime,datas,referers
|
||||
- -I
|
||||
- dev/tools/codespell/codespell-ignore.txt
|
||||
- -x
|
||||
- dev/tools/codespell/codespell-lines-ignore.txt
|
||||
- --uri-ignore-words-list
|
||||
- ned
|
||||
|
||||
# Check some shell scripts
|
||||
- repo: https://github.com/shellcheck-py/shellcheck-py
|
||||
rev: v0.9.0.6
|
||||
hooks:
|
||||
- id: shellcheck
|
||||
args: [-W, "100"]
|
||||
16
.travis.yml
16
.travis.yml
@@ -2,9 +2,9 @@
|
||||
# from Dolibarr GitHub repository.
|
||||
# For syntax, see https://docs.travis-ci.com/user/languages/php/
|
||||
|
||||
# We use dist: bionic = 18.04, focal = 20.04
|
||||
# We use dist: focal = 20.04, jammy = 22.04
|
||||
os: linux
|
||||
dist: focal
|
||||
dist: jammy
|
||||
|
||||
language: generic
|
||||
|
||||
@@ -21,7 +21,7 @@ services:
|
||||
|
||||
|
||||
addons:
|
||||
mariadb: '10.5'
|
||||
mariadb: '10.6'
|
||||
|
||||
|
||||
env:
|
||||
@@ -106,6 +106,9 @@ before_install:
|
||||
|
||||
install:
|
||||
- |
|
||||
if [ "$TRAVIS_PHP_VERSION" = '7.0' ]; then
|
||||
sudo update-alternatives --set php /usr/bin/php7.0
|
||||
fi
|
||||
if [ "$TRAVIS_PHP_VERSION" = '7.1' ]; then
|
||||
sudo update-alternatives --set php /usr/bin/php7.1
|
||||
fi
|
||||
@@ -123,7 +126,8 @@ install:
|
||||
sudo php /tmp/composer-setup.php --install-dir=/usr/local/bin --filename=composer
|
||||
sudo chmod -R a+rwx /usr/local/bin/composer
|
||||
composer -V
|
||||
composer -n config -g vendor-dir htdocs/includes
|
||||
sudo composer -n config -g vendor-dir htdocs/includes
|
||||
sudo chmod -R a+rwx /home/travis/.config/composer
|
||||
echo
|
||||
|
||||
- |
|
||||
@@ -193,8 +197,8 @@ before_script:
|
||||
phpcs -i | head -
|
||||
# Check PHP Vardump check version
|
||||
echo "PHP Vardump check version"
|
||||
which var_dump_check
|
||||
var_dump_check --version
|
||||
which var-dump-check
|
||||
var-dump-check --version
|
||||
# Check PHPUnit version
|
||||
echo "PHPUnit version"
|
||||
which phpunit
|
||||
|
||||
430
ChangeLog
430
ChangeLog
@@ -2,6 +2,301 @@
|
||||
English Dolibarr ChangeLog
|
||||
--------------------------------------------------------------
|
||||
|
||||
***** ChangeLog for 18.0.8 compared to 18.0.7 *****
|
||||
35 files changed, 647 insertions(+), 298 deletions(-)
|
||||
|
||||
FIX: #34746 - More complete fix for CVE-2024-40137
|
||||
FIX: Correct the calculation of the amount of the current period between the period provided (#35083)
|
||||
FIX: Add security test for show terminal selection if no terminal selected when invoice.php is call (#34717)
|
||||
FIX: Add security test for show terminal selection if no terminal selected when invoice.php is call
|
||||
FIX: missing quick edit for extrafields (baclport commit 4fc66c6) (#35160)
|
||||
FIX: Missing sentence part (#35144)
|
||||
FIX: set global mysoc and load langs in API access (#35041)
|
||||
FIX: set global mysoc and load langs in API access
|
||||
FIX: reset mysoc and langs only if entity of API has changed
|
||||
FIX: accountancy general ledger: bad handling of hook return (#34029)
|
||||
FIX: accountancy general ledger: bad handling of hook return
|
||||
FIX: accountancy balance: bad handling of hook return
|
||||
FIX: - Fix missing token for disable custom group category for compta report (page /htdocs/accountancy/admin/categories_list.php) (#35084)
|
||||
FIX: The combo of custom groups has disappeared (backport v19) (#35016)
|
||||
FIX: #34893 (#34897)
|
||||
FIX: #34893
|
||||
FIX: change error code to USERNOTALLOWEDTOCHANGEPASS
|
||||
FIX: asset: could not select invoice in disposal pop-in (#34725)
|
||||
FIX: 17.0 SQL syntax error and/or constraint error when calling Facture::update() after a clone (e.g. in a trigger) (#34778)
|
||||
FIX: 17.0: when you clone an invoice that was created from a template invoice, the clone should not be linked to the template invoice (#34777)
|
||||
FIX: pre-send mail mass action: keep __EMAIL__ substitution (#34522)
|
||||
FIX: pre-send mail mass action: keep __EMAIL__ substitution
|
||||
FIX: comment
|
||||
FIX: massaction email tpl: keep preset
|
||||
FIX: loop interrupt if an error occurs in sendEmailsRemindersOnInvoiceDueDate (#34657)
|
||||
FIX: #34654
|
||||
|
||||
***** ChangeLog for 18.0.7 compared to 18.0.6 *****
|
||||
138 files changed, 1622 insertions(+), 530 deletions(-)
|
||||
|
||||
FIX: 17.0 API endpoints "PUT": prevent overwriting all extrafields if only some are supplied in the request cf. PR #29237
|
||||
FIX: 17.0 - collisions in cache for dol_getIdFromCode
|
||||
FIX: 17.0 - missing error handling for FactureRec::fetch in card-rec.php
|
||||
FIX: 17.0: warnings due to uninitialized variables + delete code that doesn't apply to recurring invoices (AFAIK, there is no recurring credit note feature)
|
||||
FIX: #21294 Stock import sql query
|
||||
FIX: #26250 fatal error on kit
|
||||
FIX: #32339 Delete a loan settlement is partial
|
||||
FIX: #33038 drag and drop files are not prefixed with object reference
|
||||
FIX: #33117 accountancy export Quadratus when doc ref is less than 10 char
|
||||
FIX: #33145 wrong label status buy on product tooltip
|
||||
FIX: accountancy export Quadratus when doc ref is less than 10 char
|
||||
FIX: bad dispatched quantities for batches on shipment card
|
||||
FIX: bank payment rejection on SEPA (backport commit 100a657) (#33838)
|
||||
FIX: calculate start date of cloned task from cloned project (#31799)
|
||||
FIX: can not delete files in task card
|
||||
FIX: close all services on contract will close all lines (#33466)
|
||||
FIX: compatibility with multicompany
|
||||
FIX: constant PAYMENTBYBANKTRANSFER_ADDDAYS was never saved (#33799)
|
||||
FIX: Count on supplier invoice list does not match count in DB (#33351)
|
||||
FIX: #CVE-2024-34051
|
||||
FIX: delete supplier order line when linked to customer order line
|
||||
FIX: delete supplier order when at least one line linked to customer order line
|
||||
FIX: display error when loan can't be deleted
|
||||
FIX: display full tree on shipment card when a kit contains a same component in other sub-kit
|
||||
FIX: Fix case when the value of a extrafields of the type 'boolean', 'select' or other have an option with a value equal to '0'.
|
||||
FIX: Fix return value of hook sendMail when hook return -1 who must be return false in sendfile() function
|
||||
FIX: GETPOST('private_message')
|
||||
FIX: in projet/element.php total_time is always back to 0
|
||||
FIX: invoice creation : use dol_include_once instead of require_once to allow external modules
|
||||
FIX: invoice creation : use dol_include_once instead of require_once to allow external modules.
|
||||
FIX: issue #28222 Edit date extrafield displayed on all on lines (#31914)
|
||||
FIX: Many status on invoice linked object block
|
||||
FIX: Multilangs : PDF lines description
|
||||
FIX: ODT substitution when many HTML tags in string
|
||||
FIX: old copy not needed in supplier order create method (#31733)
|
||||
FIX: PAIEMENT Wrong field displayed for DateChequeReceived (#33390)
|
||||
FIX: phpcs
|
||||
FIX: product variants copy: also copy multiprice variations
|
||||
FIX: qual
|
||||
FIX: removes traces of <<<HEAD conflicts following the postponement of branch 13 modifications (#32014)
|
||||
FIX: Replace compromised tj-actions/changed-files (#33481)
|
||||
FIX: selectcontact is loading all contacts if socid is empty and MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT is not set
|
||||
FIX: selectcontact is loading all contacts when update event
|
||||
FIX: select group and severity search fields on ticket list
|
||||
FIX: send email to assigned user on ticket create
|
||||
FIX: send mail to BCC when email formatted as Fullname <email> (#31983)
|
||||
FIX: Show true error when send notify email at validate expense report
|
||||
FIX: status ticket update for new message
|
||||
FIX: swiftmailer: correctly set errors-to header (#31826)
|
||||
FIX: TakePos barcode rule (#31857)
|
||||
FIX: There were many status indicator in the invoice linked object block (propal card)
|
||||
FIX(ticket): Notification email without public interface
|
||||
FIX: Update on a sold line of bank entries set the type to empty, now it's fixed #22539 (#31888)
|
||||
FIX: update status on create supplier order for trigger (#31642)
|
||||
FIX: use tax with code on supplier order line give tax code missing in supplier invoice (#32018)
|
||||
FIX: use vat with code on supplier order result code missing in supplier invoice
|
||||
FIX: warehouse list: broken status filter (#33667)
|
||||
FIX: warnings (#33423)
|
||||
FIX: wrong left margin (v18 to develop ?)
|
||||
FIX: wrong message on update shipment
|
||||
FIX: wrong update function parameter
|
||||
|
||||
|
||||
***** ChangeLog for 18.0.6 compared to 18.0.5 *****
|
||||
FIX: 16.0 - parent company gets emptied when updating a third party from the card in edit mode (#28269)
|
||||
FIX: 16.0 - the e-mail templates configured in the notification module are not used if the recipient is a fixed e-mail address (#29407)
|
||||
FIX: 17.0: $num doesn't take trigger-modified newref into account, leading to inconsistencies if BILL_SUPPLIER_VALIDATE changes the invoice's ref (#28684)
|
||||
FIX: 17.0: fatal when updating recurring supplier invoice line with php8 ($remise_percent is '' instead of 0) (#31713)
|
||||
FIX: 17.0: supplier invoice template card: buyer and seller swapped in VAT-related function calls (probably a copy-paste from customer invoice templates) (#31446)
|
||||
FIX: #24265 regression cannot see all product on takepos (#28753)
|
||||
FIX: #25853 Thirdparty Massaction (#25868)
|
||||
FIX: #28205
|
||||
FIX: #28251 Fixing subpermission name on api_multicurrencies.class.php (#28252)
|
||||
FIX: #28369
|
||||
FIX: #28518 (#28520)
|
||||
FIX: #28978 FIX: #28976
|
||||
FIX: #29029 Impossible to delete an order line
|
||||
FIX: #29114 Missing contact term in intervention
|
||||
FIX: #29114 Translate contact term in intervention
|
||||
FIX: #29439 incomplete API return (#29796)
|
||||
FIX: #29496 filtering a record should not hide its child not filtered
|
||||
FIX: #30010 Use conf TICKET_MESSAGE_MAIL_INTRO instead of translation key (#30081)
|
||||
FIX: #30274 Add the include before executing dolibarr_set_const (#30320)
|
||||
FIX: #30467
|
||||
FIX: #30768 allocate the correct invoice_line_id to the element timespent (#30769)
|
||||
FIX: Accountancy export with file or not
|
||||
FIX: Accountancy - Generate entries of expense report with localtax (#30411)
|
||||
FIX: Accountancy - Not trunc id_import
|
||||
FIX: accounting FEC import (Issue #28306) (#29414)
|
||||
FIX: Add new hidden conf "DISABLE_QTY_OVERWRITTEN" (#28523)
|
||||
FIX: Add same security test when uploading files from API than from GUI (#31114)
|
||||
FIX: Amount of localtaxes in foreign currency was wrong on screen and PDF
|
||||
FIX: an error in a complex else condition
|
||||
FIX: ASSET: annual depreciation starting year (Again ;-)) #26084 (#30040)
|
||||
FIX: avoid error "Column 'entity' in where clause is ambiguous" (#28270)
|
||||
FIX: avoid from re-initializing array result on nested hook getEntity (#30626)
|
||||
FIX: avoid php warnings (#29247)
|
||||
FIX: avoid to delete "lock" and "unlock" files
|
||||
FIX: avoid Unknown column 'pfp.ref_fourn' (#28145)
|
||||
FIX: background color for enabled modules (#29378)
|
||||
FIX: Backport fix fatal error on price with some truncating setup
|
||||
FIX: Backport page inventory.php from v18 to fix pagination bugs causing data loss (#29688)
|
||||
FIX: back to page on error in contact card (#29627)
|
||||
FIX: Bad calculation of $nbtotalofrecord (#30183)
|
||||
FIX: box_actions.php still uses fk_user_done which no longer exists (#31190)
|
||||
FIX: can validate shipment without stock movement (#31780)
|
||||
FIX: Condition on newDateLimReglement
|
||||
FIX: Conflict with autoload (#30399)
|
||||
FIX: const WORKFLOW_RECEPTION_CLASSIFY_NEWD_INVOICE (#31601)
|
||||
FIX: contact/address title is always "New Contact/Address" even if the contact/address already exists (#29581)
|
||||
FIX: Display the date according to user language on substitutions (#29510)
|
||||
FIX: Display the real_PMP on inventory when its value is equal to 0 (#22291)
|
||||
FIX: Don't display column when it's out of date (#28271)
|
||||
FIX: email templates for expense report not visible
|
||||
FIX: Error mesg show untranslated extrafield name (#30227)
|
||||
FIX: Error message overwrote when a error occurs during update of product multilangs (#30841)
|
||||
FIX: Error When cloning fourn price no default value for tva_tx (#28368)
|
||||
FIX: executeHooks $object default value (#29647)
|
||||
FIX: expedition PDF models using units labels (#30358)
|
||||
FIX: Extrafield following between rec invoice and classic invoice (#31445)
|
||||
FIX: fatal error on loading pictures in attached documents of an event (#30553)
|
||||
FIX: fatal error Unsupported operand types when recording load payment
|
||||
FIX: Fix bug select columns and access to the public ticket list from the public ticket card (case when we have connected to another client before, the track id stocked in session overwrite the new track id from the public ticket card) (#31000)
|
||||
FIX: Fix create shipping with product who have negative stocks on warehouse but the negative stock transfer is allowed (#26217)
|
||||
FIX: Fix save directory for invoice ODT and multientities
|
||||
FIX: group by qty in product margin tab (#29853)
|
||||
FIX: Hierarchy Employee view do not filter on employee = 1 (#29496)
|
||||
FIX: if you call fetchLines several times, your $object->lines contains duplicates (#31167)
|
||||
FIX: If you have no stock of your product, an error is displayed when you delete the reception. (#31504)
|
||||
FIX: incorrect page numbering in PDF #29458 (#29476)
|
||||
FIX: inventoryDeletePermission id define twice
|
||||
FIX: issue on action set condition in particular when you set a deposi… (#31518)
|
||||
FIX: issue to get the right files exported in Quadratrus export.php (#30004)
|
||||
FIX: lang output for sales representative on PDF (#30469)
|
||||
FIX: late order search option (#30692) and propal (#30687)
|
||||
FIX: lettering (auto) for invoice deposit with company discount (#29633)
|
||||
FIX: made invalid code shape error more user friendly (#29498)
|
||||
FIX: Merge of thirdparties must also move uploaded files
|
||||
FIX: missing entity parameter for ajax_constantonoff
|
||||
FIX: missing hide "new" button where "product" or "service" module are disable
|
||||
FIX: mo cloning (#29686)
|
||||
FIX: modification date from label in accounting bookkeeping list (#30038)
|
||||
FIX: Move the trigger for delete order line before the SQL request
|
||||
FIX: multiple problems with multicompany
|
||||
FIX: mysql error during dump for enable sandbox M999999 (#31116)
|
||||
FIX: notification: error 500 in fixed emails due to a bad copy/paste (#29580)
|
||||
FIX: notification module: for supplier orders (any of the 3 triggers), user can choose an e-mail template in conf, but the conf is not used when sending the notification (#28216)
|
||||
FIX: Not qualified lines for reception (#29473)
|
||||
FIX: not redirect when error occurs on updating card (#29388)
|
||||
FIX: Not trancate the multicurrency rate shown on cards (even if the global MAIN_MAX_DECIMALS_SHOWN is set to 0) (#28211)
|
||||
FIX: on change ref for bank account attachment are lost (#30529)
|
||||
FIX: Option MAIN_DOC_USE_TIMING can be a string with date format
|
||||
FIX: orders to bill menu (#30179)
|
||||
FIX: Payment on customer invoice - Remove accountid in url if empty for apply default value (#28156)
|
||||
FIX: PDF Fatal error : Backport fix from #23972
|
||||
FIX: PDF Translations Extrafields
|
||||
FIX: permission on payment file of a tax
|
||||
FIX: php8: Fatal when empty $tmpvat is an empty string (no silent conversion to '0' when used in arithmetic operations) (#29451)
|
||||
FIX: PHP 8 warning on output of successful cronjob (#29922)
|
||||
FIX: PHP exception on getSpecialCode (#29646)
|
||||
FIX: php warning global conf (#29478)
|
||||
FIX: pos: invoice date incorrectly set because of timezome mismatches (reverts #36e91da) (#30184)
|
||||
FIX: public project form return an error if SOCIETE_EMAIL_UNIQUE (#29942)
|
||||
FIX: purge files cron: php warnings when rest module enabled (#30919)
|
||||
FIX: PUT /thirdparties/{id} and PUT /contacts/{id} should throw exception if update returns < 0 (#29596)
|
||||
FIX: Regression #29340
|
||||
FIX: Repair the replenishment list (#29336)
|
||||
FIX: REPLENISH MANY FOURN WHEN ORDER ALREADY CREATE (#29710)
|
||||
FIX: round capital societe (#29211)
|
||||
FIX: search and add extrafields to tasks when conf disabled (#29542)
|
||||
FIX: show preview pdf list expensereport (#31694)
|
||||
FIX: sometimes a string type instead integer is return, why ?
|
||||
FIX: Special code is now transmitted by args only in order supplier (#28546) (#28619)
|
||||
FIX: SQL syntax error in DDLUpdateField
|
||||
FIX: subscription must be editable when accounting isn't reconciled (#28469)
|
||||
FIX: substitutions THIRDPARTY_XXX are not available for actioncomm reminders (#31385)
|
||||
FIX: Supplier Order search on date valid (#30448)
|
||||
FIX: supplier price duplicate entry on update supplier product ref (#29290)
|
||||
FIX: syntax error
|
||||
FIX: TakePOS | Add product / Delete line of existing invoice
|
||||
FIX: Ticket new message notification sent twice
|
||||
FIX: transfer in accountancy for expense reports.
|
||||
FIX: Unsigned propal having signing date (#29825)
|
||||
FIX: Update asset.class.php
|
||||
FIX: update date_echeance of supplier invoices when we update invoice date in the past (#29886)
|
||||
FIX: use $conf->browser->os instead
|
||||
FIX: use price() to display qty on a product's stats tab to avoid showing too many decimals when rounding errors are possible (#31165)
|
||||
FIX: User List - Function is show in wrong column when module HRM enabled (#30186)
|
||||
fix: when invoice is created by WORKFLOW_ORDER_AUTOCREATE_INVOICE on ORDER_NEW, the invoice must have the default bank account of the thirdparty is it's empty on order (#29462)
|
||||
FIX: when qty is not an integer, apply price() (#31138)
|
||||
FIX: Wrong currency shown in TakePOS payment page
|
||||
FIX: wrong shortcut key for macintosh
|
||||
FIX: wrong sql request with product category filter
|
||||
FIX: wrong stock permission number
|
||||
|
||||
|
||||
***** ChangeLog for 18.0.5 compared to 18.0.4 *****
|
||||
FIX: 17.0: deprecated field should only be a fallback
|
||||
FIX: 17.0 - php8 warnings: test for $field existence before checking if it is null or empty
|
||||
FIX: #24185: v18: display of the merged pdf lists
|
||||
FIX: #26416 BOM_SUB_BOM blank page
|
||||
FIX: #27166
|
||||
FIX: #27262 Recurrent invoice - user to string conversion
|
||||
FIX: #27970 #26283 #27970
|
||||
FIX: Accountancy - Level 3 of binding not working on supplier side (#27462)
|
||||
FIX: Accounting files export - Use th instead of td on all title columns (#28003)
|
||||
FIX: add action update_extras to don card
|
||||
FIX: Adding hooks init
|
||||
FIX: Adding the $encode parameter to recursive _replaceHtmlWithOdtTag() utilisation
|
||||
FIX: add new hook context for mo production card (#28037)
|
||||
FIX: avoid from re-initializing result on nested hook getEntity (#27799)
|
||||
FIX: avoid sql error (issue #26342)
|
||||
FIX: bad accountancy code autoselection for supplier ventilation
|
||||
FIX: Bad visible status of proposal after reopen
|
||||
FIX: Barcode header cell not well displayed
|
||||
FIX: BarCode Header not well displayed
|
||||
FIX: Bar code verification should be done by entity because generation does (#28087)
|
||||
FIX: can edit reminders on past events
|
||||
FIX: check parameter socid before cloning a customer proposal (#28085)
|
||||
FIX: crabe PDF is generating in conf->entity instead of object->entity
|
||||
FIX: CVE-2024-23817 (#28089)
|
||||
FIX: disable pointer events on jQuery-UI tooltips to prevent a glitch (fast-blinking tooltip)
|
||||
FIX: Error on emailreminder not reported
|
||||
FIX: Fatal error converting object of class User to string (php8)
|
||||
FIX: filter by entity on contact is missing
|
||||
FIX: Fix supplier invoice security check
|
||||
FIX: format of color in manifest is wrong when using a custom color
|
||||
FIX: #GHSA-7947-48q7-cp5m
|
||||
FIX: HTML injection vulnerability in Dolibarr Application Home Page
|
||||
FIX: invoice add line save devise
|
||||
FIX: Keep a link to enable a 'always_enabled' module to solve pb.
|
||||
FIX: label
|
||||
FIX: line special_code never saved (#28051)
|
||||
FIX: link to print when there is a search on multiselect fields
|
||||
FIX: Menu Create of project no working on smartphone with no top menu.
|
||||
FIX: missing $search_sale var (backport from v19)
|
||||
FIX: Missing begin transaction when updating supplier recurring invoice
|
||||
FIX: missing entity filter for check if period exists
|
||||
FIX: more correctly parse the select part to be replaced in sql queries
|
||||
FIX: MouvementStock::origin is not an object
|
||||
FIX: notification information on intervention validated confirmation message (v17+)
|
||||
FIX: not load all contacts by default when creating an event
|
||||
FIX: port in Docker MailDev
|
||||
FIX: propal use devise changes
|
||||
FIX: public user photo not visible if $dolibarr_main_instance_unique_id
|
||||
FIX: remove DISTINCT (backport from v19)
|
||||
FIX: remove specific name from v19
|
||||
FIX: Retours PR
|
||||
FIX: Return a better error message when token is not valid
|
||||
FIX: search by ref & rowid in don list
|
||||
FIX: search by thirdparty in don list
|
||||
FIX: several names for one const THIRDPARTY_CAN_HAVE_CUSTOMER_CATEGORY_EVEN_IF_NOT_CUSTOMER_PROSPECT
|
||||
FIX: SQL concatenation error
|
||||
FIX: [TAKEPOS] display prices with or without taxes depending on setup (TAKEPOS_CHANGE_PRICE_HT)
|
||||
FIX: Ternary operator condition is always true/false
|
||||
FIX: too long output
|
||||
FIX: Undefined property: Task::$fk_parent
|
||||
FIX: uniformization to use "intervention"
|
||||
FIX: Update loan.class.php (#27971)
|
||||
FIX: update price extrafield on propal card
|
||||
FIX: user filter in per user view of event list (#28049)
|
||||
FIX: use the currency for propal signature page
|
||||
|
||||
***** ChangeLog for 18.0.4 compared to 18.0.3 *****
|
||||
FIX: $this->newref already exists and could have been modified by trigger but we still use a local variable for the filesystem-based renaming
|
||||
@@ -207,7 +502,7 @@ NEW: Accountancy - Manage intra-community VAT on supplier invoices - FPC22
|
||||
NEW: Accountancy - iSuiteExpert export model
|
||||
NEW: Accountancy - Quadratus export with attachments in accountancy export
|
||||
NEW: Accountancy - Can filter on a custom group of accounts. Perf or ledger list.
|
||||
NEW: Can upload a file with drag and drop on purchase invoice, vats, salaries and social contributions
|
||||
NEW: Can upload a file with drag and drop on purchase invoice, vats, salaries and social contributions
|
||||
NEW: Authentication: #22740 add OpenID Connect impl
|
||||
NEW: Authentication: add experimental support for Google OAuth2 connexion
|
||||
NEW: Authentication: can now edit service name for OAuth token
|
||||
@@ -300,7 +595,7 @@ NEW: No overwrite of optionals during put() contact
|
||||
NEW: Notifications: add Customer Order delivered (ORDER_NEW) in module Notification
|
||||
NEW: Notifications: for Sign or Refused Propal from Online Page
|
||||
NEW: Now we can edit amount on VAT and salaries clone action
|
||||
NEW: only get openned contact from liste_contact function, to not have acces to closed contact as mail receiver
|
||||
NEW: only get open contact from liste_contact function, to not have access to closed contact as mail receiver
|
||||
NEW: Option to manage deposit slips for more payment modes (not only
|
||||
NEW: Option to show column for field and line selection on the left
|
||||
NEW: Orders: add sub total in order list det
|
||||
@@ -396,13 +691,13 @@ WARNING:
|
||||
|
||||
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
|
||||
* Minimal PHP version is now PHP 7.1 instead of PHP 7.0
|
||||
* Sensitive datas like keys in setup pages, that need encyption (for example the API keys of users, the CRON security key, the keys into the Stripe module, or
|
||||
* Sensitive datas like keys in setup pages, that need encyption (for example the API keys of users, the CRON security key, the keys into the Stripe module, or
|
||||
external modules setup pages that store sensitive keys or password), are using the $dolibarr_main_instance_unique_id as part of the key for encryption. So,
|
||||
if you restore or duplicate the data from another instance dump, you must also update this parameter in ther conf.php file to allow decryption in the new instance, or
|
||||
if you restore or duplicate the data from another instance dump, you must also update this parameter in ther conf.php file to allow decryption in the new instance, or
|
||||
better, you must reenter the sensitive data into the setup pages of the new instance to resave them correctly.
|
||||
Note that to find all the parameters that are encrypted into the setup database, you can do a "SELECT * FROM llx_const WHERE value LIKE '%dolcrypt%';"
|
||||
Note that to find all the parameters that are encrypted into the setup database, you can do a "SELECT * FROM llx_const WHERE value LIKE '%dolcrypt%';"
|
||||
* The deprecated method "escapeunderscore()" of database handlers has been removed. You must use "escapeforlike()" instead.
|
||||
* The method "nb_expedition()" has been renamed into "countNbOfShipments()"
|
||||
* The method "nb_expedition()" has been renamed into "countNbOfShipments()"
|
||||
* Revert default type of hooks. Default is now 'addreplace' hooks (and exception become 'output' hooks, that become deprecated).
|
||||
* Deprecated property libelle removed from entrepot class.
|
||||
* The type 'text' in ->fields property does not accept html content anymore. Use the type 'html' for that.
|
||||
@@ -411,6 +706,117 @@ Note that to find all the parameters that are encrypted into the setup database,
|
||||
* The method getCheckOption() and deleteCPUser() of class Holiday has been removed (it was not used)
|
||||
|
||||
|
||||
***** ChangeLog for 17.0.4 compared to 17.0.3 *****
|
||||
FIX: $this->newref already exists and could have been modified by a trigger but we still use a local variable for the filesystem-based renaming
|
||||
FIX: 16.0 only, backport fix for SQL error on global search product
|
||||
FIX: 17.0: deprecated field should only be a fallback
|
||||
FIX: 17.0 PHP8: supplier invoice class:
|
||||
FIX: 17.0 - php8 warnings: test for $field existence before checking is_null
|
||||
FIX: #25399 (#26694)
|
||||
FIX: #25458 intervention localizations (backport v17) (#26757)
|
||||
FIX: #25580 install/step1.php - wrong command line argument used for $main_dir (#25581)
|
||||
FIX: #25919
|
||||
FIX: #25934 #25929
|
||||
FIX: #26100 - Ticket - On edit, list of closed project must be excluded (#26223)
|
||||
FIX: #26195 - Various payment - List of project excluded those assigned to third parties (#26222)
|
||||
FIX: #26735 FIX: #26994
|
||||
FIX: #27262 Recurrent invoice - user to string conversion
|
||||
FIX: Accountancy - Possibility to write in bookkeeping expense report operation with some line not bound (#26545)
|
||||
FIX: Accountancy - Update Quadra export format
|
||||
FIX: add action update_extras to don card
|
||||
FIX: add_customer_ref_on_linked_shipment (#26349)
|
||||
FIX: add display of an error when attempting to delete a committed transaction (#26573)
|
||||
FIX: Adding the $encode parameter to recursive _replaceHtmlWithOdtTag() utilisation
|
||||
FIX: add warning in the changelog
|
||||
FIX: avoid php8 warnings (#25596)
|
||||
FIX: avoid warning : Cannot use a scalar value as an array (#26437)
|
||||
FIX: Backport memory fix for fatal error when +100000 products
|
||||
FIX: backport SQL error on global search product
|
||||
FIX: bad accountancy code autoselection for supplier ventilation
|
||||
FIX: Bad calculation of localtax when price_base_type not defined.
|
||||
FIX: bad check return for sendfile
|
||||
FIX: bad from and to
|
||||
FIX: Bad value of accounting account shown in list. Edit fails.
|
||||
FIX: Barcode header cell not well displayed
|
||||
FIX: Bar code verification should be done by entity because generation does (#28087)
|
||||
FIX: # Bug Estimated Stock at date value in V14 (#26479)
|
||||
FIX: Can't access to rec supplier invoice card
|
||||
FIX: Can't delete a fourn commande row if a commande ligne is linked
|
||||
FIX: check tva_tx before comparing price_min_ttc (#25220)
|
||||
FIX: commande context (#26497)
|
||||
FIX: compare the result of the send mail file function
|
||||
FIX: could not delete a fourn commande row if a commande ligne is linked
|
||||
FIX: count cronjob list differs of lines shown nb
|
||||
FIX: crabe PDF is generating in conf->entity instead of object->entity
|
||||
FIX: creation of invoice from contract with discount lines
|
||||
FIX: CVE-2024-23817 (#28089)
|
||||
FIX: dir output path for ODT models on reception card
|
||||
FIX: disable pointer events on jQuery-UI tooltips to prevent a glitch (fast-blinking tooltip)
|
||||
FIX: Error handling for computed values on import (#24897)
|
||||
FIX: escape HTML tags in return value of getFullName() (#26735)
|
||||
FIX: export FEC
|
||||
FIX: Fatal error converting object of class User to string (php8)
|
||||
FIX: fatal error with bad definition of dictionaries
|
||||
FIX: filter by entity on contact is missing
|
||||
FIX: Fix supplier invoice security check
|
||||
FIX: HTML in ODT templates (#26181)
|
||||
FIX: include
|
||||
FIX: label
|
||||
FIX: line special_code never saved (#28051)
|
||||
FIX: link to create purchase order from sale order
|
||||
FIX: menu auguria
|
||||
FIX: message order in ticket public view is not coherent with tickets events tab
|
||||
FIX: Missing begin transaction when updating supplier recurring invoice
|
||||
FIX: missing contact_id for the trigger
|
||||
FIX: Missing error message on CommandeFourn creation
|
||||
FIX: missing fk_account situation invoice
|
||||
FIX: missing project entity filter (Issue #26243) (#26247)
|
||||
FIX: modification of complementary attributes in commercial proposals
|
||||
FIX: modification of complementary attributes in invoices (#26180)
|
||||
FIX: more correctly parse the select part to be replaced in sql queries
|
||||
FIX: not create/update extrafields for visibility 0,2 and 5
|
||||
FIX: notification information on intervention validated confirmation message (v17+)
|
||||
FIX: payment card: misleading message when delete button disabled
|
||||
FIX: payment : language is not propagated to following pages
|
||||
FIX: pdf cornas page head multicell width (backport v17)
|
||||
FIX: possible inconsistency between llx_ecm_files and file system when BILL_SUPPLIER_VALIDATES changes ref
|
||||
FIX: Prices visible on TakePOS KO with multiprices support
|
||||
FIX: product list accounting length
|
||||
FIX: propal list : warning if product module is not enabled (#25583)
|
||||
FIX: Propal's negative quantities
|
||||
FIX: Quick search Intervention redirect to wrong page
|
||||
FIX: reception odt dir output path
|
||||
FIX: regression on rounding stocks fields on product list
|
||||
FIX_reload_linked_objects_on_propal_closeas
|
||||
FIX: Return right content type
|
||||
FIX: right access on salary card and tabs
|
||||
FIX: rights paymentsc paiementcharge
|
||||
FIX: same broken feature as v18 (Multicompany)
|
||||
FIX: Save user modif id when changing a contact status
|
||||
FIX: search by ref & rowid in don list
|
||||
FIX: search by thirdparty in don list
|
||||
FIX: special_code update line keep old value. (#26819)
|
||||
FIX: SQL concatenation error
|
||||
FIX: SQL request parenthesis
|
||||
FIX: substitute project variables in invoice documents (#26445)
|
||||
FIX: Suppliers addlines never have VAT if buyprice for this supplier
|
||||
FIX: [TAKEPOS] display prices with or without taxes depending on setup (TAKEPOS_CHANGE_PRICE_HT)
|
||||
FIX: TakePOS receipt preview in admin #25648
|
||||
FIX: template invoice list extrafield filters (backport v17) (#26227)
|
||||
FIX: thirdparty object in proposal card is not loaded
|
||||
FIX: too long output
|
||||
FIX: translation button
|
||||
FIX: use event.key instead event.which to avoid keyboard difference
|
||||
FIX: Use of line->insert instead of line->create
|
||||
FIX: user creation when LDAP is configured (#26332)
|
||||
FIX: Use the wrong logo size on PDF
|
||||
FIX: v17: Param $notrigger in $societe->create() causes method to return true regardless of actual result of database functions (#26499)
|
||||
FIX: warning param $lineID getSpecialCode is negatif (#26826)
|
||||
FIX: warning php8.2 undefined_array_key (#26830)
|
||||
FIX: warning when Workboard Responses display non numeric strings
|
||||
FIX: Wrong backtopage given for the stocktransfer button from the stocktransfer list (#26271)
|
||||
FIX: wrong place of trigger delete
|
||||
|
||||
***** ChangeLog for 17.0.3 compared to 17.0.2 *****
|
||||
FIX: #20304 propaldates update
|
||||
FIX: #24508 Label not reported when creating a supplier invoice template (#25340)
|
||||
@@ -804,7 +1210,7 @@ WARNING:
|
||||
Following changes may create regressions for some external modules, but were necessary to make Dolibarr better:
|
||||
* Minimal PHP version is now PHP 7.0 instead of PHP 5.6
|
||||
* Core has introduced a Universal Filter Syntax for seach criteria. Example: ((((field1:=:value1) OR (field2:in:1,2,3)) AND ...). In rare case, some filters
|
||||
could be provided by URL parameters. For such cases (societe/ajax/company.php), use of Universal Filter Syntax become mandatory.
|
||||
could be provided by URL parameters. For such cases (societe/ajax/company.php), use of Universal Filter Syntax become mandatory.
|
||||
* The signature of method getNomUrl() of class ProductFournisseur has been modified to match the signature of method Product->getNomUrl()
|
||||
* Trigger ORDER_SUPPLIER_DISPATCH is removed, use ORDER_SUPPLIER_RECEIVE and/or LINEORDER_SUPPLIER_DISPATCH instead.
|
||||
* All functions fetch_all() have been set to deprecated for naming consitency, use fetchAll() instead.
|
||||
@@ -882,7 +1288,7 @@ FIX: #23019 Impossible to add task times to an existing draft invoice
|
||||
FIX: #23072
|
||||
FIX: #23075
|
||||
FIX: #23087
|
||||
FIX: #23115
|
||||
FIX: #23115
|
||||
FIX: #23116
|
||||
FIX: #23117
|
||||
FIX: #23281
|
||||
@@ -2434,7 +2840,7 @@ NEW: add quick dropdown menu in top right menu (experimental with MAIN_USE_TOP_M
|
||||
NEW: add region in export companies and contacts
|
||||
NEW: add rights on margin info on invoice list
|
||||
NEW: add search param for close date on order list
|
||||
NEW: add show preview for mail attachement on form mail
|
||||
NEW: add show preview for mail attachment on form mail
|
||||
NEW: add State/Province origin for products
|
||||
NEW: add the workflow interaction close intervention on closing ticket
|
||||
NEW: add tracking number in list and search_all items
|
||||
@@ -3819,7 +4225,7 @@ FIX: access to public interface when origin email has an alias.
|
||||
FIX: Alias name is not into the email recipient label.
|
||||
FIX: allow standalone credit note even if no invoice
|
||||
FIX: an admin can not access his own permissions after enabling advanced permissions
|
||||
FIX: Attachement of linked files on ticket when sending a message
|
||||
FIX: Attachment of linked files on ticket when sending a message
|
||||
FIX: avoid non numeric warning
|
||||
FIX: Bad currency var used in stripe for connect
|
||||
FIX: Bad list of ticket on public interface for ticket emailcollector
|
||||
@@ -4615,7 +5021,7 @@ NEW: hidden option to define an invoice template for each invoice type
|
||||
NEW: Highlight lines on lists when they are checked
|
||||
NEW: Notification module support expense report+holiday validation and approval
|
||||
NEW: On customer/supplier card, add simple tooltip to amount boxes
|
||||
NEW: Page to check if the operations/items created between two dates have attached item(s) and possibility to download all attachements
|
||||
NEW: Page to check if the operations/items created between two dates have attached item(s) and possibility to download all attachments
|
||||
NEW: possibility to add all rights of all modules in one time
|
||||
NEW: redirect if only one result on global search on card
|
||||
NEW: Permission to ignore price min
|
||||
@@ -6059,7 +6465,7 @@ NEW: No external check of version without explicit click in about page.
|
||||
NEW: ODT docs for USER USERGROUP CONTRACT and PRODUCT class
|
||||
NEW: odt usergroup
|
||||
NEW: On invoices generated by template, we save if invoice come from a source template.
|
||||
NEW: option to copy into attachement files of events, files send by mail (with auto event creation)
|
||||
NEW: option to copy into attachment files of events, files send by mail (with auto event creation)
|
||||
NEW: PDF with numbertoword
|
||||
NEW: Permit multiple file upload in linked documents
|
||||
NEW: PHP 7.1 compatibility
|
||||
|
||||
@@ -50,7 +50,7 @@ RUN echo 'xdebug.idekey="netbeans-xdebug"' >> ${PHP_INI_DIR}/php.ini
|
||||
# set up sendmail config, to use maildev
|
||||
RUN echo "account default" > /etc/msmtprc
|
||||
RUN echo "auth off" >> /etc/msmtprc
|
||||
RUN echo "port 25" >> /etc/msmtprc
|
||||
RUN echo "port 1025" >> /etc/msmtprc
|
||||
RUN echo "host mail" >> /etc/msmtprc
|
||||
RUN echo "from local@localdomain.com" >> /etc/msmtprc
|
||||
RUN echo "domain localhost.localdomain" >> /etc/msmtprc
|
||||
|
||||
@@ -55,8 +55,8 @@ services:
|
||||
mail:
|
||||
image: maildev/maildev
|
||||
ports:
|
||||
- "8081:80"
|
||||
- "25:25"
|
||||
- "8081:1080"
|
||||
- "25:1025"
|
||||
networks:
|
||||
- internal-pod
|
||||
- external-pod
|
||||
|
||||
@@ -304,22 +304,15 @@ if (isset($_GET['img']))
|
||||
|
||||
|
||||
|
||||
// Definition de la langue et des textes
|
||||
// Definition of language and texts
|
||||
|
||||
if (isset ($_GET['lang']))
|
||||
{
|
||||
$langue = $_GET['lang'];
|
||||
}
|
||||
elseif (preg_match("/^fr/", $_SERVER['HTTP_ACCEPT_LANGUAGE']))
|
||||
{
|
||||
if (isset ($_GET['lang'])) {
|
||||
$langue = preg_replace('/[^a-z_]/i', '', $_GET['lang']);
|
||||
} elseif (preg_match("/^fr/", $_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||
$langue = 'fr';
|
||||
}
|
||||
elseif (preg_match("/^es/", $_SERVER['HTTP_ACCEPT_LANGUAGE']))
|
||||
{
|
||||
} elseif (preg_match("/^es/", $_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
|
||||
$langue = 'es';
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
$langue = 'en';
|
||||
}
|
||||
|
||||
@@ -327,29 +320,25 @@ else
|
||||
// Read PHP extensions
|
||||
$loaded_extensions = get_loaded_extensions();
|
||||
$phpExtContents='';
|
||||
foreach ($loaded_extensions as $extension)
|
||||
foreach ($loaded_extensions as $extension) {
|
||||
$phpExtContents .= "<li>${extension}</li>";
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Read alias directory
|
||||
$listoffile=array();
|
||||
$aliasarray=array();
|
||||
$aliasContents='';
|
||||
if (is_dir($aliasDir))
|
||||
{
|
||||
if (is_dir($aliasDir)) {
|
||||
$handle=opendir($aliasDir);
|
||||
if (is_resource($handle))
|
||||
{
|
||||
while ($file = readdir($handle))
|
||||
{
|
||||
if (is_resource($handle)) {
|
||||
while ($file = readdir($handle)) {
|
||||
$listoffiles[]=$file;
|
||||
}
|
||||
}
|
||||
sort($listoffiles);
|
||||
|
||||
foreach($listoffiles as $file)
|
||||
{
|
||||
foreach($listoffiles as $file) {
|
||||
if (is_file($aliasDir.$file) && preg_match('/\.conf/',$file))
|
||||
{
|
||||
$msg = '';
|
||||
@@ -374,8 +363,7 @@ if (!isset($aliasContents))
|
||||
// Read projects in www dir
|
||||
$listoffiles=array();
|
||||
$handle=opendir(".");
|
||||
if (is_resource($handle))
|
||||
{
|
||||
if (is_resource($handle)) {
|
||||
while ($file = readdir($handle))
|
||||
{
|
||||
$listoffiles[]=$file;
|
||||
@@ -383,8 +371,7 @@ if (is_resource($handle))
|
||||
closedir($handle);
|
||||
}
|
||||
|
||||
foreach($listoffiles as $file)
|
||||
{
|
||||
foreach($listoffiles as $file) {
|
||||
if (is_dir($file) && !in_array($file,$projectsListIgnore) && !in_array($file,$aliasarray))
|
||||
{
|
||||
$projectContents .= '<tr><td><ul class="projects">';
|
||||
@@ -397,9 +384,9 @@ foreach($listoffiles as $file)
|
||||
}
|
||||
}
|
||||
|
||||
if (!isset($projectContents))
|
||||
if (!isset($projectContents)) {
|
||||
$projectContents = '<tr><td colspan="3">'.$langues[$langue]['txtNoProjet'].'</td></tr>';
|
||||
|
||||
}
|
||||
|
||||
|
||||
$nameServer=getenv("COMPUTERNAME");
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# \brief Dolibarr package builder (tgz, zip, rpm, deb, exe, aps)
|
||||
# \author (c)2004-2020 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
#
|
||||
# This is list of constant you can set to have generated packages moved into a specific dir:
|
||||
# This is list of constant you can set to have generated packages moved into a specific dir:
|
||||
#DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild'
|
||||
#DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable'
|
||||
#DESTIMODULES='/media/HDDATA1_LD/Mes Sites/Web/Admin1/wwwroot/files/modules'
|
||||
@@ -18,10 +18,12 @@ use Term::ANSIColor;
|
||||
|
||||
# Change this to defined target for option 98 and 99
|
||||
$PROJECT="dolibarr";
|
||||
$PUBLISHSTABLE="eldy,dolibarr\@frs.sourceforge.net:/home/frs/project/dolibarr";
|
||||
$PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/dolibarr_documents/website/www.dolibarr.org/files";
|
||||
|
||||
$PUBLISHBETARC="$ENV{'DESTIASSOLOGIN'}\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/dolibarr_documents/website/www.dolibarr.org/files";
|
||||
$PUBLISHSTABLE="$ENV{'DESTISFLOGIN'}\@frs.sourceforge.net:/home/frs/project/dolibarr";
|
||||
|
||||
# due to implicit origin on git commands, example
|
||||
# implicit origin, lionel upstream, eric dolibarr
|
||||
$GITREMOTENAME="$ENV{'GITREMOTENAME'}";
|
||||
#@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT"); # Possible packages
|
||||
@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT"); # Possible packages
|
||||
%REQUIREMENTPUBLISH=(
|
||||
@@ -36,7 +38,7 @@ $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/asso.dolibarr.org/
|
||||
"RPM_FEDORA"=>"rpmbuild",
|
||||
"RPM_MANDRIVA"=>"rpmbuild",
|
||||
"RPM_OPENSUSE"=>"rpmbuild",
|
||||
"DEB"=>"dpkg dpatch",
|
||||
"DEB"=>"dpkg",
|
||||
"FLATPACK"=>"flatpack",
|
||||
"EXEDOLIWAMP"=>"ISCC.exe",
|
||||
"SNAPSHOT"=>"tar"
|
||||
@@ -98,6 +100,13 @@ if (! -d $ENV{"DESTIBETARC"} || ! -d $ENV{"DESTISTABLE"})
|
||||
exit 1;
|
||||
}
|
||||
|
||||
if (! $ENV{"GITREMOTENAME"})
|
||||
{
|
||||
print "Error: environment variable GITREMOTENAME does not exist. You can set it to 'origin' or any other git remote name.\n";
|
||||
print "$PROG.$Extension aborted.\n";
|
||||
sleep 2;
|
||||
exit 1;
|
||||
}
|
||||
# Detect OS type
|
||||
# --------------
|
||||
if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; }
|
||||
@@ -129,7 +138,7 @@ if (! $TEMP || ! -d $TEMP) {
|
||||
print "$PROG.$Extension aborted.\n";
|
||||
sleep 2;
|
||||
exit 2;
|
||||
}
|
||||
}
|
||||
$BUILDROOT="$TEMP/buildroot";
|
||||
|
||||
|
||||
@@ -172,7 +181,7 @@ $newbuild = $BUILD;
|
||||
$newbuild =~ s/(dev|alpha)/1/gi; # dev
|
||||
$newbuild =~ s/beta(.?)/2/gi; # beta (we want beta1, beta2, betax to be same package name)
|
||||
$newbuild =~ s/rc(.?)/3/gi; # rc (we want rc1, rc2, rcx to be same package name)
|
||||
if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc.
|
||||
if ($newbuild !~ /-/) { $newbuild.='-4'; } # finale is same than rc.
|
||||
# now newbuild is 0-1 or 0-4 for example. Note that for native package (see debian/source/format), we should not use a dash part but to get a better version management
|
||||
$build = $newbuild;
|
||||
$build =~ s/-.*$//g;
|
||||
@@ -190,8 +199,8 @@ for (0..@ARGV-1) {
|
||||
if ($ARGV[$_] =~ /^-*target=(\w+)/i) { $target=$1; $batch=1; }
|
||||
if ($ARGV[$_] =~ /^-*desti=(.+)/i) { $DESTI=$1; }
|
||||
if ($ARGV[$_] =~ /^-*prefix=(.+)/i) {
|
||||
$PREFIX=$1;
|
||||
$FILENAMESNAPSHOT.="-".$PREFIX;
|
||||
$PREFIX=$1;
|
||||
$FILENAMESNAPSHOT.="-".$PREFIX;
|
||||
}
|
||||
}
|
||||
if ($ENV{"DESTIBETARC"} && $BUILD =~ /[a-z]/i) { $DESTI = $ENV{"DESTIBETARC"}; } # Force output dir if env DESTIBETARC is defined
|
||||
@@ -210,7 +219,7 @@ print "Target directory (DESTI) : $DESTI\n";
|
||||
# Choose package targets
|
||||
#-----------------------
|
||||
if ($target) {
|
||||
if ($target eq "ALL") {
|
||||
if ($target eq "ALL") {
|
||||
foreach my $key (@LISTETARGET) {
|
||||
if ($key ne 'SNAPSHOT' && $key ne 'SF' && $key ne 'ASSO') { $CHOOSEDTARGET{$key}=1; }
|
||||
}
|
||||
@@ -236,10 +245,10 @@ else {
|
||||
printf(" %2d - %-14s (%s)\n",$cpt,"ASSO (publish)","Need ".$REQUIREMENTPUBLISH{"ASSO"});
|
||||
$cpt=99;
|
||||
printf(" %2d - %-14s (%s)\n",$cpt,"SF (publish)","Need ".$REQUIREMENTPUBLISH{"SF"});
|
||||
|
||||
|
||||
# Ask which target to build
|
||||
print "Choose one target number or several separated with space (0 - ".$cpt."): ";
|
||||
$NUM_SCRIPT=<STDIN>;
|
||||
$NUM_SCRIPT=<STDIN>;
|
||||
chomp($NUM_SCRIPT);
|
||||
if ($NUM_SCRIPT !~ /^[0-9\s]+$/)
|
||||
{
|
||||
@@ -286,11 +295,11 @@ foreach my $target (sort keys %CHOOSEDTARGET) {
|
||||
print "Error: You asked creation of several rpms. Because all rpm have same name, you must defined an environment variable DESTI to tell packager where it can create subdirs for each generated package.\n";
|
||||
exit;
|
||||
}
|
||||
$atleastonerpm=1;
|
||||
}
|
||||
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target}))
|
||||
$atleastonerpm=1;
|
||||
}
|
||||
foreach my $req (split(/[,\s]/,$REQUIREMENTTARGET{$target}))
|
||||
{
|
||||
# Test
|
||||
# Test
|
||||
print "Test requirement for target $target: Search '$req'... ";
|
||||
$newreq=$req; $newparam='';
|
||||
if ($newreq eq 'zip') { $newparam.='-h'; }
|
||||
@@ -299,12 +308,12 @@ foreach my $target (sort keys %CHOOSEDTARGET) {
|
||||
print "Test command ".$cmd."... ";
|
||||
$ret=`$cmd`;
|
||||
$coderetour=$?; $coderetour2=$coderetour>>8;
|
||||
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
|
||||
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/)) && $PROGPATH) {
|
||||
# Not found error, we try in PROGPATH
|
||||
$ret=`"$PROGPATH/$ALTERNATEPATH{$req}/$req\" 2>&1`;
|
||||
$coderetour=$?; $coderetour2=$coderetour>>8;
|
||||
$REQUIREMENTTARGET{$target}="$PROGPATH/$ALTERNATEPATH{$req}/$req";
|
||||
}
|
||||
}
|
||||
|
||||
if ($coderetour != 0 && (($coderetour2 == 1 && $OS =~ /windows/ && $ret !~ /Usage/i) || ($coderetour2 == 127 && $OS !~ /windows/))) {
|
||||
# Not found error
|
||||
@@ -333,7 +342,7 @@ $nbofpublishneedchangelog=0;
|
||||
foreach my $target (sort keys %CHOOSEDTARGET) {
|
||||
if ($target eq '-CHKSUM') { $nbofpublishneedchangelog++; }
|
||||
if ($CHOOSEDTARGET{$target} < 0) { next; }
|
||||
if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM')
|
||||
if ($target ne 'EXE' && $target ne 'EXEDOLIWAMP' && $target ne '-CHKSUM')
|
||||
{
|
||||
$nboftargetneedbuildroot++;
|
||||
}
|
||||
@@ -397,10 +406,10 @@ if ($nboftargetok) {
|
||||
print "Go to directory $SOURCE\n";
|
||||
$olddir=getcwd();
|
||||
chdir("$SOURCE");
|
||||
|
||||
|
||||
print "Clean $SOURCE/htdocs/includes/autoload.php\n";
|
||||
$ret=`rm -f $SOURCE/htdocs/includes/autoload.php`;
|
||||
|
||||
|
||||
$ret=`git ls-files . --exclude-standard --others`;
|
||||
if ($ret)
|
||||
{
|
||||
@@ -409,12 +418,16 @@ if ($nboftargetok) {
|
||||
print "Canceled.\n";
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
print 'Create xml check file with md5 checksum with command php '.$SOURCE.'/build/generate_filelist_xml.php release='.$MAJOR.'.'.$MINOR.'.'.$BUILD."\n";
|
||||
$ret=`php $SOURCE/build/generate_filelist_xml.php release=$MAJOR.$MINOR.$BUILD`;
|
||||
print $ret."\n";
|
||||
# Copy to final dir
|
||||
$NEWDESTI=$DESTI;
|
||||
if ( !-d "$NEWDESTI/signatures" ) {
|
||||
use File::Path qw( make_path );
|
||||
make_path "$NEWDESTI/signatures" or die "Failed to create path: $NEWDESTI/signatures";
|
||||
}
|
||||
print "Copy \"$SOURCE/htdocs/install/filelist-$MAJOR.$MINOR.$BUILD.xml\" to $NEWDESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml\n";
|
||||
use File::Copy qw(copy);
|
||||
copy "$SOURCE/htdocs/install/filelist-$MAJOR.$MINOR.$BUILD.xml", "$NEWDESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml";
|
||||
@@ -427,32 +440,32 @@ if ($nboftargetok) {
|
||||
print "Go to directory $SOURCE\n";
|
||||
$olddir=getcwd();
|
||||
chdir("$SOURCE");
|
||||
|
||||
|
||||
print 'Run git tag -a -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n";
|
||||
$ret=`git tag -a -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD" 2>&1`;
|
||||
if ($ret =~ /(already exists|existe déjà)/)
|
||||
{
|
||||
print "WARNING: Tag ".$MAJOR.'.'.$MINOR.'.'.$BUILD." already exists. Overwrite (y/N) ? ";
|
||||
$QUESTIONOVERWRITETAG=<STDIN>;
|
||||
$QUESTIONOVERWRITETAG=<STDIN>;
|
||||
chomp($QUESTIONOVERWRITETAG);
|
||||
if ($QUESTIONOVERWRITETAG =~ /(o|y)/)
|
||||
{
|
||||
print 'Run git tag -a -f -m "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'" "'.$MAJOR.'.'.$MINOR.'.'.$BUILD.'"'."\n";
|
||||
$ret=`git tag -a -f -m "$MAJOR.$MINOR.$BUILD" "$MAJOR.$MINOR.$BUILD"`;
|
||||
print 'Run git push -f --tags'."\n";
|
||||
$ret=`git push -f --tags`;
|
||||
print 'Run git push $GITREMOTENAME -f --tags'."\n";
|
||||
$ret=`git push $GITREMOTENAME -f --tags`;
|
||||
#$ret=`git push -f origin "$MAJOR.$MINOR.$BUILD"`;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
print 'Run git push --tags'."\n";
|
||||
$ret=`git push --tags`;
|
||||
print 'Run git push $GITREMOTENAME --tags'."\n";
|
||||
$ret=`git push $GITREMOTENAME --tags`;
|
||||
#$ret=`git push origin "$MAJOR.$MINOR.$BUILD"`;
|
||||
}
|
||||
chdir("$olddir");
|
||||
}
|
||||
|
||||
|
||||
# Update buildroot if required
|
||||
#-----------------------------
|
||||
if ($nboftargetneedbuildroot)
|
||||
@@ -462,7 +475,7 @@ if ($nboftargetok) {
|
||||
|
||||
print "Delete directory $BUILDROOT\n";
|
||||
$ret=`rm -fr "$BUILDROOT"`;
|
||||
|
||||
|
||||
mkdir "$BUILDROOT";
|
||||
mkdir "$BUILDROOT/$PROJECT";
|
||||
print "Copy $SOURCE into $BUILDROOT/$PROJECT\n";
|
||||
@@ -488,7 +501,7 @@ if ($nboftargetok) {
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/phpstan.neon`;
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/pom.xml`;
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/README-*.md`;
|
||||
|
||||
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/build/html`;
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/build/Doli*-*`;
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/build/dolibarr_*.deb`;
|
||||
@@ -555,20 +568,20 @@ if ($nboftargetok) {
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot11.png`;
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/doc/images/dolibarr_screenshot12.png`;
|
||||
|
||||
# Security to avoid to package data files
|
||||
# Security to avoid to package data files
|
||||
print "Remove documents dir\n";
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/document`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/documents`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/document`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/documents`;
|
||||
|
||||
|
||||
print "Remove subdir of custom dir\n";
|
||||
print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\;\n";
|
||||
$ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type d -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs but not files
|
||||
print "find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\;\n";
|
||||
$ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs, even symbolic links, but not files
|
||||
|
||||
# Removed known external modules to avoid any error when packaging from env where external modules are tested
|
||||
# Removed known external modules to avoid any error when packaging from env where external modules are tested
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/abricot*`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/accountingexport*`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/allscreens*`;
|
||||
@@ -593,15 +606,15 @@ if ($nboftargetok) {
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/webmail*`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/theme/common/fontawesome-5/svgs`;
|
||||
|
||||
|
||||
# Removed other test files
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/public/test`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/test`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/Thumbs.db $BUILDROOT/$PROJECT/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/Thumbs.db $BUILDROOT/$PROJECT/*/*/*/*/Thumbs.db`;
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/.cvsignore $BUILDROOT/$PROJECT/*/.cvsignore $BUILDROOT/$PROJECT/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.cvsignore`;
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/.gitignore $BUILDROOT/$PROJECT/*/.gitignore $BUILDROOT/$PROJECT/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.gitignore`;
|
||||
|
||||
# Removed files installed by the awful composer
|
||||
|
||||
# Removed files installed by the awful composer
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/geoip/sample*.*`;
|
||||
$ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/bin`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/ckeditor/ckeditor/adapters`; # Keep this removal in case we embed libraries
|
||||
@@ -640,14 +653,14 @@ if ($nboftargetok) {
|
||||
|
||||
# Build package for each target
|
||||
#------------------------------
|
||||
foreach my $target (sort keys %CHOOSEDTARGET)
|
||||
foreach my $target (sort keys %CHOOSEDTARGET)
|
||||
{
|
||||
if ($CHOOSEDTARGET{$target} < 0) { next; }
|
||||
if ($target eq '-CHKSUM') { next; }
|
||||
|
||||
|
||||
print "\nBuild package for target $target\n";
|
||||
|
||||
if ($target eq 'SNAPSHOT')
|
||||
if ($target eq 'SNAPSHOT')
|
||||
{
|
||||
$NEWDESTI=$DESTI;
|
||||
|
||||
@@ -671,13 +684,13 @@ if ($nboftargetok) {
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target eq 'TGZ')
|
||||
if ($target eq 'TGZ')
|
||||
{
|
||||
$NEWDESTI=$DESTI;
|
||||
if ($NEWDESTI =~ /stable/)
|
||||
{
|
||||
mkdir($DESTI.'/standard');
|
||||
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
|
||||
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
|
||||
}
|
||||
|
||||
print "Remove target $FILENAMETGZ.tgz...\n";
|
||||
@@ -691,7 +704,7 @@ if ($nboftargetok) {
|
||||
|
||||
$ret=`rm -fr $BUILDROOT/$FILENAMETGZ/build/exe`;
|
||||
$ret=`rm -fr $BUILDROOT/$FILENAMETGZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages
|
||||
|
||||
|
||||
print "Compress $FILENAMETGZ into $FILENAMETGZ.tgz...\n";
|
||||
$cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMETGZ.tgz\" $FILENAMETGZ";
|
||||
print "$cmd\n";
|
||||
@@ -703,14 +716,14 @@ if ($nboftargetok) {
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target eq 'XZ')
|
||||
if ($target eq 'XZ')
|
||||
{
|
||||
$NEWDESTI=$DESTI;
|
||||
if ($NEWDESTI =~ /stable/)
|
||||
{
|
||||
mkdir($DESTI.'/standard');
|
||||
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
|
||||
}
|
||||
}
|
||||
|
||||
print "Remove target $FILENAMEXZ.xz...\n";
|
||||
unlink("$NEWDESTI/$FILENAMEXZ.xz");
|
||||
@@ -723,7 +736,7 @@ if ($nboftargetok) {
|
||||
|
||||
$ret=`rm -fr $BUILDROOT/$FILENAMEXZ/build/exe`;
|
||||
$ret=`rm -fr $BUILDROOT/$FILENAMEXZ/htdocs/includes/ckeditor/_source`; # We can't remove it with exclude file, we need it for some tarball packages
|
||||
|
||||
|
||||
print "Compress $FILENAMEXZ into $FILENAMEXZ.xz...\n";
|
||||
|
||||
print "Go to directory $BUILDROOT\n";
|
||||
@@ -739,15 +752,15 @@ if ($nboftargetok) {
|
||||
$ret=`mv "$BUILDROOT/$FILENAMEXZ.xz" "$NEWDESTI/$FILENAMEXZ.xz"`;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target eq 'ZIP')
|
||||
|
||||
if ($target eq 'ZIP')
|
||||
{
|
||||
$NEWDESTI=$DESTI;
|
||||
if ($NEWDESTI =~ /stable/)
|
||||
{
|
||||
mkdir($DESTI.'/standard');
|
||||
if (-d $DESTI.'/standard') { $NEWDESTI=$DESTI.'/standard'; }
|
||||
}
|
||||
}
|
||||
|
||||
print "Remove target $FILENAMEZIP.zip...\n";
|
||||
unlink("$NEWDESTI/$FILENAMEZIP.zip");
|
||||
@@ -770,14 +783,14 @@ if ($nboftargetok) {
|
||||
print $cmd."\n";
|
||||
$ret= `$cmd`;
|
||||
chdir("$olddir");
|
||||
|
||||
|
||||
# Move to final dir
|
||||
print "Move $FILENAMEZIP.zip to $NEWDESTI/$FILENAMEZIP.zip\n";
|
||||
$ret=`mv "$BUILDROOT/$FILENAMEZIP.zip" "$NEWDESTI/$FILENAMEZIP.zip"`;
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target =~ /RPM/) # Linux only
|
||||
|
||||
if ($target =~ /RPM/) # Linux only
|
||||
{
|
||||
$NEWDESTI=$DESTI;
|
||||
$subdir="package_rpm_generic";
|
||||
@@ -788,7 +801,7 @@ if ($nboftargetok) {
|
||||
{
|
||||
mkdir($DESTI.'/'.$subdir);
|
||||
if (-d $DESTI.'/'.$subdir) { $NEWDESTI=$DESTI.'/'.$subdir; }
|
||||
}
|
||||
}
|
||||
|
||||
if ($RPMDIR eq "") { $RPMDIR=$ENV{'HOME'}."/rpmbuild"; }
|
||||
|
||||
@@ -801,7 +814,7 @@ if ($nboftargetok) {
|
||||
|
||||
print "Create directory $BUILDROOT/$FILENAMETGZ2\n";
|
||||
$ret=`rm -fr $BUILDROOT/$FILENAMETGZ2`;
|
||||
|
||||
|
||||
print "Copy $BUILDROOT/$PROJECT to $BUILDROOT/$FILENAMETGZ2\n";
|
||||
$cmd="cp -pr '$BUILDROOT/$PROJECT' '$BUILDROOT/$FILENAMETGZ2'";
|
||||
$ret=`$cmd`;
|
||||
@@ -818,6 +831,7 @@ if ($nboftargetok) {
|
||||
print "Compress $FILENAMETGZ2 into $FILENAMETGZ2.tgz...\n";
|
||||
$ret=`tar --exclude-from "$SOURCE/build/tgz/tar_exclude.txt" --directory "$BUILDROOT" -czvf "$BUILDROOT/$FILENAMETGZ2.tgz" $FILENAMETGZ2`;
|
||||
|
||||
if (! -d $RPMDIR . '/SOURCES') { mkdir($RPMDIR . '/SOURCES'); }
|
||||
print "Move $BUILDROOT/$FILENAMETGZ2.tgz to $RPMDIR/SOURCES/$FILENAMETGZ2.tgz\n";
|
||||
$cmd="mv $BUILDROOT/$FILENAMETGZ2.tgz $RPMDIR/SOURCES/$FILENAMETGZ2.tgz";
|
||||
$ret=`$cmd`;
|
||||
@@ -827,7 +841,7 @@ if ($nboftargetok) {
|
||||
if ($target =~ /FEDO/i) { $BUILDFICSRC="${FILENAME}_fedora.spec"; }
|
||||
if ($target =~ /MAND/i) { $BUILDFICSRC="${FILENAME}_mandriva.spec"; }
|
||||
if ($target =~ /OPEN/i) { $BUILDFICSRC="${FILENAME}_opensuse.spec"; }
|
||||
|
||||
|
||||
use Date::Language;
|
||||
$lang=Date::Language->new('English');
|
||||
$datestring = $lang->time2str("%a %b %e %Y", time);
|
||||
@@ -845,7 +859,7 @@ if ($nboftargetok) {
|
||||
}
|
||||
close SPECFROM;
|
||||
close SPECTO;
|
||||
|
||||
|
||||
print "Copy patch file to $RPMDIR/SOURCES\n";
|
||||
$ret=`cp "$SOURCE/build/rpm/dolibarr-forrpm.patch" "$RPMDIR/SOURCES"`;
|
||||
$ret=`chmod 644 $RPMDIR/SOURCES/dolibarr-forrpm.patch`;
|
||||
@@ -867,14 +881,14 @@ if ($nboftargetok) {
|
||||
next;
|
||||
}
|
||||
|
||||
if ($target eq 'DEB')
|
||||
if ($target eq 'DEB')
|
||||
{
|
||||
$NEWDESTI=$DESTI;
|
||||
if ($NEWDESTI =~ /stable/)
|
||||
{
|
||||
mkdir($DESTI.'/package_debian-ubuntu');
|
||||
if (-d $DESTI.'/package_debian-ubuntu') { $NEWDESTI=$DESTI.'/package_debian-ubuntu'; }
|
||||
}
|
||||
}
|
||||
|
||||
$olddir=getcwd();
|
||||
|
||||
@@ -955,13 +969,18 @@ if ($nboftargetok) {
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/jquery/plugins/select2/LICENSE`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mike42/escpos-php/LICENSE.md`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/mobiledetect/mobiledetectlib/LICENSE.txt`;
|
||||
|
||||
|
||||
# Removed files we don't need (already removed)
|
||||
#$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/htdocs/includes/ckeditor/ckeditor/_source`;
|
||||
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/.codeclimate.yml`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/.pre-commit-config.yaml`;
|
||||
$ret=`rm -fr $BUILDROOT/$PROJECT.tmp/.vscode`;
|
||||
$ret=`find $BUILDROOT/$PROJECT.tmp/ -type f -name '.editorconfig' -exec rm {} \\;`;
|
||||
$ret=`find $BUILDROOT/$PROJECT.tmp/ -type f -name '.travis.yml' -exec rm {} \\;`;
|
||||
|
||||
# Rename upstream changelog to match debian rules
|
||||
$ret=`mv $BUILDROOT/$PROJECT.tmp/ChangeLog $BUILDROOT/$PROJECT.tmp/changelog`;
|
||||
|
||||
|
||||
# Prepare source package (init debian dir)
|
||||
print "Create directory $BUILDROOT/$PROJECT.tmp/debian\n";
|
||||
$ret=`mkdir "$BUILDROOT/$PROJECT.tmp/debian"`;
|
||||
@@ -999,7 +1018,7 @@ if ($nboftargetok) {
|
||||
$ret=`cp -f "$SOURCE/build/debian/dolibarr.postrm" "$BUILDROOT/$PROJECT.tmp/debian"`;
|
||||
$ret=`cp -f "$SOURCE/build/debian/dolibarr.templates" "$BUILDROOT/$PROJECT.tmp/debian"`;
|
||||
$ret=`cp -f "$SOURCE/build/debian/install.forced.php.install" "$BUILDROOT/$PROJECT.tmp/debian"`;
|
||||
|
||||
|
||||
# Set owners and permissions
|
||||
#print "Set owners on files/dir\n";
|
||||
#$ret=`chown -R root.root $BUILDROOT/$PROJECT.tmp`;
|
||||
@@ -1030,8 +1049,8 @@ if ($nboftargetok) {
|
||||
$ret=`$cmd`;
|
||||
$cmd="find $BUILDROOT/$PROJECT.tmp/scripts -name '*.sh' -type f -exec chmod 755 {} \\; ";
|
||||
$ret=`$cmd`;
|
||||
|
||||
|
||||
|
||||
|
||||
print "Rename directory $BUILDROOT/$PROJECT.tmp into $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n";
|
||||
$cmd="mv $BUILDROOT/$PROJECT.tmp $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build";
|
||||
$ret=`$cmd`;
|
||||
@@ -1039,14 +1058,14 @@ if ($nboftargetok) {
|
||||
|
||||
print "Go into directory $BUILDROOT\n";
|
||||
chdir("$BUILDROOT");
|
||||
|
||||
|
||||
# We need a tarball to be able to build "quilt" debian package (not required for native but we need patch so it is not a native)
|
||||
print "Compress $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build into $BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz...\n";
|
||||
$cmd="tar --exclude-vcs --exclude-from \"$BUILDROOT/$PROJECT/build/tgz/tar_exclude.txt\" --directory \"$BUILDROOT\" --mode=go-w --group=500 --owner=500 -czvf \"$BUILDROOT/$FILENAMEDEBNATIVE.orig.tar.gz\" $PROJECT-$MAJOR.$MINOR.$build";
|
||||
print $cmd."\n";
|
||||
$ret=`$cmd`;
|
||||
|
||||
# Creation of source package
|
||||
# Creation of source package
|
||||
print "Go into directory $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build\n";
|
||||
chdir("$BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build");
|
||||
#$cmd="dpkg-source -b $BUILDROOT/$PROJECT-$MAJOR.$MINOR.$build";
|
||||
@@ -1065,12 +1084,12 @@ if ($nboftargetok) {
|
||||
$ret=`mv $BUILDROOT/*_all.deb "$NEWDESTI/"`;
|
||||
$ret=`mv $BUILDROOT/*.dsc "$NEWDESTI/"`;
|
||||
$ret=`mv $BUILDROOT/*.orig.tar.gz "$NEWDESTI/"`;
|
||||
#$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option
|
||||
#$ret=`mv $BUILDROOT/*.debian.tar.xz "$NEWDESTI/"`; # xz file is generated when build/debian/sources/option
|
||||
$ret=`mv $BUILDROOT/*.debian.tar.gz "$NEWDESTI/"`;
|
||||
$ret=`mv $BUILDROOT/*.changes "$NEWDESTI/"`;
|
||||
next;
|
||||
}
|
||||
|
||||
|
||||
if ($target eq 'EXEDOLIWAMP')
|
||||
{
|
||||
$NEWDESTI=$DESTI;
|
||||
@@ -1078,22 +1097,22 @@ if ($nboftargetok) {
|
||||
{
|
||||
mkdir($DESTI.'/package_windows');
|
||||
if (-d $DESTI.'/package_windows') { $NEWDESTI=$DESTI.'/package_windows'; }
|
||||
}
|
||||
}
|
||||
|
||||
print "Remove target $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe...\n";
|
||||
unlink "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe";
|
||||
|
||||
|
||||
if ($OS eq 'windows') {
|
||||
print "Check that ISCC.exe is in your PATH.\n";
|
||||
} else {
|
||||
print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n";
|
||||
}
|
||||
|
||||
|
||||
$SOURCEBACK=$SOURCE;
|
||||
$SOURCEBACK =~ s/\//\\/g;
|
||||
|
||||
print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n";
|
||||
|
||||
|
||||
#$ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`;
|
||||
open(IN, '<' . $SOURCE."/build/exe/doliwamp/doliwamp.iss") or die $!;
|
||||
open(OUT, '>' . "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss") or die $!;
|
||||
@@ -1106,7 +1125,7 @@ if ($nboftargetok) {
|
||||
close(OUT);
|
||||
|
||||
print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" on OS $OS\n";
|
||||
|
||||
|
||||
if ($OS eq 'windows') {
|
||||
$cmd= "ISCC.exe \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\"";
|
||||
} else {
|
||||
@@ -1120,26 +1139,26 @@ if ($nboftargetok) {
|
||||
print "Move \"$SOURCE\\build\\$FILENAMEEXEDOLIWAMP.exe\" to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n";
|
||||
rename("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe","$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe");
|
||||
print "Move $SOURCE/build/$FILENAMEEXEDOLIWAMP.exe to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n";
|
||||
|
||||
|
||||
use File::Copy;
|
||||
|
||||
#$ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`;
|
||||
$ret=move("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe", "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe");
|
||||
|
||||
|
||||
print "Remove tmp file $SOURCE/build/exe/doliwamp/doliwamp.tmp.iss\n";
|
||||
#$ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`;
|
||||
$ret=unlink("$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss");
|
||||
|
||||
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
# Publish package for each target
|
||||
#--------------------------------
|
||||
foreach my $target (sort keys %CHOOSEDPUBLISH)
|
||||
foreach my $target (sort keys %CHOOSEDPUBLISH)
|
||||
{
|
||||
if ($CHOOSEDPUBLISH{$target} < 0) { next; }
|
||||
|
||||
|
||||
print "\nList of files to publish (BUILD=$BUILD)\n";
|
||||
%filestoscansf=(
|
||||
"$DESTI/signatures/filelist-$MAJOR.$MINOR.$BUILD.xml"=>'none', # none means it won't be published on SF
|
||||
@@ -1162,7 +1181,8 @@ if ($nboftargetok) {
|
||||
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}_all.deb"=>'package_debian-ubuntu',
|
||||
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}_amd64.changes"=>'package_debian-ubuntu',
|
||||
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.dsc"=>'package_debian-ubuntu',
|
||||
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.xz"=>'package_debian-ubuntu',
|
||||
#"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.xz"=>'package_debian-ubuntu',
|
||||
"$DESTI/package_debian-ubuntu/${FILENAMEDEB}.debian.tar.gz"=>'package_debian-ubuntu',
|
||||
"$DESTI/package_debian-ubuntu/${FILENAMEDEBSHORT}.orig.tar.gz"=>'package_debian-ubuntu',
|
||||
"$DESTI/package_windows/$FILENAMEEXEDOLIWAMP.exe"=>'package_windows',
|
||||
"$DESTI/standard/$FILENAMETGZ.tgz"=>'standard',
|
||||
@@ -1197,26 +1217,26 @@ if ($nboftargetok) {
|
||||
print "\n";
|
||||
}
|
||||
|
||||
if ($target eq 'SF' || $target eq 'ASSO')
|
||||
if ($target eq 'SF' || $target eq 'ASSO')
|
||||
{
|
||||
print "\n";
|
||||
|
||||
|
||||
if ($target eq 'SF') { $PUBLISH = $PUBLISHSTABLE; }
|
||||
if ($target eq 'ASSO' && $BUILD =~ /[a-z]/i) { $PUBLISH = $PUBLISHBETARC.'/lastbuild'; }
|
||||
if ($target eq 'ASSO' && $BUILD =~ /^[0-9]+$/) { $PUBLISH = $PUBLISHBETARC.'/stable'; }
|
||||
|
||||
|
||||
$NEWPUBLISH=$PUBLISH;
|
||||
print "Publish to target $NEWPUBLISH. Click enter or CTRL+C...\n";
|
||||
|
||||
# Ask which target to build
|
||||
$NUM_SCRIPT=<STDIN>;
|
||||
$NUM_SCRIPT=<STDIN>;
|
||||
chomp($NUM_SCRIPT);
|
||||
|
||||
print "Create empty dir /tmp/emptydir. We need it to create target dir using rsync.\n";
|
||||
$ret=`mkdir -p "/tmp/emptydir/"`;
|
||||
|
||||
|
||||
%filestoscan=%filestoscansf;
|
||||
|
||||
|
||||
foreach my $file (sort keys %filestoscan)
|
||||
{
|
||||
$found=0;
|
||||
@@ -1226,30 +1246,30 @@ if ($nboftargetok) {
|
||||
if ($target eq 'SF') {
|
||||
if ($filestoscan{$file} eq 'none') {
|
||||
next;
|
||||
}
|
||||
}
|
||||
$destFolder="$NEWPUBLISH/$filestoscan{$file}/".$MAJOR.'.'.$MINOR.'.'.$BUILD;
|
||||
}
|
||||
elsif ($target eq 'ASSO' and $NEWPUBLISH =~ /stable/) {
|
||||
$destFolder="$NEWPUBLISH/$filestoscanstableasso{$file}";
|
||||
}
|
||||
}
|
||||
elsif ($target eq 'ASSO' and $NEWPUBLISH !~ /stable/) {
|
||||
$destFolder="$NEWPUBLISH";
|
||||
}
|
||||
}
|
||||
else # No more used
|
||||
{
|
||||
$dirnameonly=$file;
|
||||
$dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/;
|
||||
$dirnameonly =~ s/.*\/([^\/]+)\/[^\/]+$/$1/;
|
||||
$filenameonly=$file;
|
||||
$filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/;
|
||||
$filenameonly =~ s/.*\/[^\/]+\/([^\/])+$/$1/;
|
||||
$destFolder="$NEWPUBLISH/$dirnameonly";
|
||||
}
|
||||
|
||||
print "\n";
|
||||
print "Publish file ".$file." to ".$destFolder."\n";
|
||||
|
||||
# mkdir
|
||||
# mkdir
|
||||
#my $ssh = Net::SSH::Perl->new("frs.sourceforge.net");
|
||||
#$ssh->login("$user","$pass");
|
||||
#$ssh->login("$user","$pass");
|
||||
#use String::ShellQuote qw( shell_quote );
|
||||
#$ssh->cmd('mkdir '.shell_quote($destFolder).' && exit');
|
||||
|
||||
@@ -1258,20 +1278,20 @@ if ($nboftargetok) {
|
||||
#$sftp->mkdir($destFolder)
|
||||
|
||||
#$command="ssh eldy,dolibarr\@frs.sourceforge.net mkdir -p \"$destFolder\"";
|
||||
#print "$command\n";
|
||||
#print "$command\n";
|
||||
#my $ret=`$command 2>&1`;
|
||||
|
||||
$command="rsync -s -e 'ssh' --recursive /tmp/emptydir/ \"".$destFolder."\"";
|
||||
print "$command\n";
|
||||
print "$command\n";
|
||||
my $ret=`$command 2>&1`;
|
||||
|
||||
$command="rsync -s -e 'ssh' \"$file\" \"".$destFolder."\"";
|
||||
print "$command\n";
|
||||
print "$command\n";
|
||||
my $ret2=`$command 2>&1`;
|
||||
print "$ret2\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "\n----- Summary -----\n";
|
||||
|
||||
@@ -6,7 +6,7 @@ of Dolibarr. There is a chapter for BETA version and a chapter for RELEASE versi
|
||||
***** Prerequisites For Linux *****
|
||||
|
||||
Prerequisites to build tgz, debian and rpm packages:
|
||||
> apt-get install perl tar dpkg dpatch p7zip-full rpm zip php-cli
|
||||
> apt-get install perl tar dpkg p7zip-full rpm zip php-cli debhelper po-debconf
|
||||
|
||||
Prerequisites to build autoexe DoliWamp package from Linux (solution seems broken since Ubuntu 20.04):
|
||||
> apt-get install wine q4wine
|
||||
@@ -14,11 +14,11 @@ Prerequisites to build autoexe DoliWamp package from Linux (solution seems broke
|
||||
> Install InnoSetup
|
||||
For example by running isetup-5.5.8.exe (https://www.jrsoftware.org) https://files.jrsoftware.org/is/5/
|
||||
> Install WampServer into "C:\wamp64" to have Apache, PHP and MariaDB
|
||||
For example by running wampserver3.2.6_x64.exe (https://www.wampserver.com).
|
||||
For example by running wampserver3.2.6_x64.exe (https://www.wampserver.com).
|
||||
See file build/exe/doliwamp.iss to know the doliwamp version currently setup.
|
||||
> Add path to ISCC into PATH windows var:
|
||||
Launch wine cmd, then regedit and add entry int HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment\PATH
|
||||
> To build manually the .exe from Windows (running from makepack-dolibarr.pl script is however recommanded),
|
||||
> To build manually the .exe from Windows (running from makepack-dolibarr.pl script is however recommanded),
|
||||
open file build/exe/doliwamp.iss and click on button "Compile".
|
||||
The .exe file will be build into directory build.
|
||||
|
||||
@@ -31,8 +31,8 @@ Prerequisites to build autoexe DoliWamp package from Windows:
|
||||
> Install isetup-5.5.8.exe (https://www.jrsoftware.org)
|
||||
> Install WampServer-3.2.*-64.exe (Apache 2.4.51, PHP 7.3.33, MariaDB 10.6.5 for example. Version must match the values found into doliwamp.iss)
|
||||
> Install GIT for Windows (https://git-scm.com/ => You must choose option "Add Git bash profile", "Git commit as-is")
|
||||
> Install Dolibarr current version:
|
||||
git clone https://github.com/dolibarr/dolibarr or git clone --branch X.Y https://github.com/dolibarr/dolibarr
|
||||
> Install Dolibarr current version:
|
||||
git clone https://github.com/dolibarr/dolibarr or git clone --branch X.Y https://github.com/dolibarr/dolibarr
|
||||
|
||||
> Add the path of PHP (C:\wamp64\bin\php\php7.3.33) and InnoSetup (C:\Program Files (x86)\Inno Setup 5) into the %PATH% of Windows.
|
||||
|
||||
@@ -43,11 +43,11 @@ Prerequisites to build autoexe DoliWamp package from Windows:
|
||||
|
||||
|
||||
***** Actions to do a BETA *****
|
||||
This files describe steps made by Dolibarr packaging team to make a
|
||||
This files describe steps made by Dolibarr packaging team to make a
|
||||
beta version of Dolibarr, step by step.
|
||||
|
||||
- Check all files are commited.
|
||||
- Update version/info in ChangeLog, for this you can:
|
||||
- Update version/info in ChangeLog, for this you can:
|
||||
To generate a changelog of a major new version x.y.0 (from a repo on branch develop), you can do "cd ~/git/dolibarr; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent develop) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
|
||||
To generate a changelog of a major new version x.y.0 (from a repo on branch x.y repo), you can do "cd ~/git/dolibarr_x.y; git log `diff -u <(git rev-list --first-parent x.(y-1).0) <(git rev-list --first-parent x.y.0) | sed -ne 's/^ //p' | head -1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
|
||||
To generate a changelog of a maintenance version x.y.z, you can do "cd ~/git/dolibarr_x.y; git log x.y.z-1.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e '^FIX\|NEW' | sort -u | sed 's/FIXED:/FIX:/g' | sed 's/FIXED :/FIX:/g' | sed 's/FIX :/FIX:/g' | sed 's/FIX /FIX: /g' | sed 's/NEW :/NEW:/g' | sed 's/NEW /NEW: /g' > /tmp/aaa"
|
||||
@@ -67,7 +67,7 @@ Recopy the content of the output file into the file ChangeLog.
|
||||
|
||||
|
||||
***** Actions to do a RELEASE *****
|
||||
This files describe steps made by Dolibarr packaging team to make a
|
||||
This files describe steps made by Dolibarr packaging team to make a
|
||||
complete release of Dolibarr, step by step.
|
||||
|
||||
- Check all files are commited.
|
||||
@@ -84,9 +84,9 @@ Recopy the content of the output file into the file ChangeLog.
|
||||
|
||||
- Check content of built packages.
|
||||
|
||||
- Run makepack-dolibarr.pl again with option to publish files on
|
||||
- Run makepack-dolibarr.pl again with option to publish files on
|
||||
dolibarr foundation server (Dir /home/dolibarr/wwwroot/files/stable on www.dolibarr.org).
|
||||
- Run makepack-dolibarr.pl again with option to publish files on
|
||||
- Run makepack-dolibarr.pl again with option to publish files on
|
||||
sourceforge. This will also add official tag.
|
||||
- Edit symbolic links in directory "/home/dolibarr/wwwroot/files/stable/xxx"
|
||||
on server to point to new files (used by some web sites).
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
.git
|
||||
.gitignore
|
||||
.scrutinizer.yml
|
||||
.travis.yml
|
||||
.vscode
|
||||
.idea
|
||||
.editorconfig
|
||||
.codeclimate.yml
|
||||
.pre-commit-config.yaml
|
||||
.mailmap
|
||||
Thumbs.db
|
||||
build/exe
|
||||
build/html
|
||||
|
||||
@@ -22,3 +22,9 @@ dolibarr*.deb
|
||||
dolibarr*.zip
|
||||
cvschangelogbuilder_dolibarr*
|
||||
dolibarr_install.log
|
||||
.travis.yml
|
||||
.vscode
|
||||
.idea
|
||||
.editorconfig
|
||||
.codeclimate.yml
|
||||
.pre-commit-config.yaml
|
||||
|
||||
@@ -102,7 +102,7 @@ with
|
||||
* Replace in tcpdf.php
|
||||
|
||||
if (!@TCPDF_STATIC::file_exists($file)) {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
|
||||
with
|
||||
@@ -116,7 +116,7 @@ with
|
||||
$file = $tfile;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
* Replace in tcpdf.php
|
||||
|
||||
if (($imgsrc[0] === '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
|
||||
@@ -138,7 +138,6 @@ with
|
||||
}
|
||||
elseif (($imgsrc[0] === '/') AND !empty($_SERVER['DOCUMENT_ROOT']) AND ($_SERVER['DOCUMENT_ROOT'] != '/')) {
|
||||
|
||||
|
||||
* In tecnickcom/tcpdf/include/tcpdf_static.php, in function fopenLocal, replace
|
||||
|
||||
if (strpos($filename, '://') === false) {
|
||||
@@ -154,16 +153,16 @@ with
|
||||
elseif (strpos($filename, '://') === false)
|
||||
|
||||
* To avoid to have QRcode changed because generated with a random mask, replace
|
||||
define('QR_FIND_FROM_RANDOM', 2);
|
||||
with
|
||||
define('QR_FIND_FROM_RANDOM', false);
|
||||
define('QR_FIND_FROM_RANDOM', 2);
|
||||
with:
|
||||
define('QR_FIND_FROM_RANDOM', false);
|
||||
|
||||
* Removed useless directories ("examples", "tools")
|
||||
|
||||
* Optionnaly, removed all fonts except
|
||||
dejavusans* (used by greek, arab, persan, romanian, turkish),
|
||||
freemono* (russian),
|
||||
cid*+msungstdlight+stsongstdlight+uni2cid* (chinese),
|
||||
* Optionnaly, removed all fonts except
|
||||
dejavusans* (used by greek, arab, persan, romanian, turkish),
|
||||
freemono* (russian),
|
||||
cid*+msungstdlight+stsongstdlight+uni2cid* (chinese),
|
||||
helvetica* (all other languages),
|
||||
zapfdingbats.php (for special chars like form checkboxes)
|
||||
|
||||
@@ -175,15 +174,15 @@ In htdocs/includes/tecnickcom/tcpdf/tcpdf.php
|
||||
* In tecnickcom/tcpdf/include/tcpdf_static, in function intToRoman, right at the beginning
|
||||
of the function, replace:
|
||||
|
||||
$roman = '';
|
||||
$roman = '';
|
||||
|
||||
with:
|
||||
with:
|
||||
|
||||
$roman = '';
|
||||
if ($number >= 4000) {
|
||||
// do not represent numbers above 4000 in Roman numerals
|
||||
return strval($number);
|
||||
}
|
||||
$roman = '';
|
||||
if ($number >= 4000) {
|
||||
// do not represent numbers above 4000 in Roman numerals
|
||||
return strval($number);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -201,7 +200,7 @@ with:
|
||||
|
||||
* Fix syntax error by replacing
|
||||
} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1] >= 2))) {
|
||||
with
|
||||
with
|
||||
} elseif (($key == '/Index') AND ($v[0] == PDF_TYPE_ARRAY AND count($v[1]) >= 2)) {
|
||||
|
||||
* Fix php fatal error on php 8.0 on tcpdi.php
|
||||
@@ -292,6 +291,24 @@ RESTLER:
|
||||
empty($value[0]) ? null :
|
||||
empty($value[1]) ? null :
|
||||
|
||||
* Add a test into AutoLoader.php to complete function loadThisLoader and test if property exists before calling it. For this replace code
|
||||
|
||||
if (false !== $file = $b::$loader[1]($className) && $this->exists($className, $b::$loader[1])) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
with:
|
||||
|
||||
//avoid PHP Fatal error: Uncaught Error: Access to undeclared static property: Composer\\Autoload\\ClassLoader::$loader
|
||||
//in case of multiple autoloader systems
|
||||
if(property_exists($b, $loader[1])) {
|
||||
if (false !== $file = $b::$loader[1]($className)
|
||||
&& $this->exists($className, $b::$loader[1])) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+With swagger 2 provided into /explorer:
|
||||
----------------------------------------
|
||||
|
||||
@@ -305,16 +322,15 @@ PARSEDOWN
|
||||
* Add support of css by adding in Parsedown.php:
|
||||
|
||||
// @CHANGE LDR
|
||||
'class' => $Link['element']['attributes']['class']
|
||||
'class' => $Link['element']['attributes']['class']
|
||||
|
||||
...
|
||||
|
||||
|
||||
// @CHANGE LDR
|
||||
if (preg_match('/{([^}]+)}/', $remainder, $matches2))
|
||||
{
|
||||
$Element['attributes']['class'] = $matches2[1];
|
||||
$remainder = preg_replace('/{'.preg_quote($matches2[1],'/').'}/', '', $remainder);
|
||||
}
|
||||
if (preg_match('/{([^}]+)}/', $remainder, $matches2)) {
|
||||
$Element['attributes']['class'] = $matches2[1];
|
||||
$remainder = preg_replace('/{'.preg_quote($matches2[1],'/').'}/', '', $remainder);
|
||||
}
|
||||
|
||||
|
||||
// @CHANGE LDR
|
||||
@@ -347,7 +363,7 @@ Add into Class Google of file OAuth2/Service/Google:
|
||||
}
|
||||
$this->approvalPrompt = $prompt;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
JEDITABLE.JS
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"npm": ">=5.6.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"zapier-platform-core": "11.3.1"
|
||||
"zapier-platform-core": "15.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"mocha": "^5.2.0",
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
<ruleset name="Dolibarr">
|
||||
<description>Dolibarr coding standard.</description>
|
||||
<arg name="tab-width" value="4"/>
|
||||
<arg name="extensions" value="php" />
|
||||
|
||||
<exclude-pattern type="relative">build/html</exclude-pattern>
|
||||
<exclude-pattern type="relative">build/aps</exclude-pattern>
|
||||
<exclude-pattern type="relative">dev/tools/test/namespacemig</exclude-pattern>
|
||||
<!-- <exclude-pattern type="relative">dev/initdata/dbf/includes</exclude-pattern> -->
|
||||
<exclude-pattern type="relative">documents</exclude-pattern>
|
||||
<exclude-pattern type="relative">htdocs/core/class/lessc.class.php</exclude-pattern>
|
||||
<exclude-pattern type="relative">htdocs/custom</exclude-pattern>
|
||||
<exclude-pattern type="relative">htdocs/includes</exclude-pattern>
|
||||
<exclude-pattern type="relative">htdocs/install/doctemplates/websites</exclude-pattern>
|
||||
<exclude-pattern type="relative">htdocs/conf.php</exclude-pattern>
|
||||
<exclude-pattern type="relative">*/nltechno*</exclude-pattern>
|
||||
<exclude-pattern type="relative">source</exclude-pattern>
|
||||
<exclude-pattern type="relative">.git</exclude-pattern>
|
||||
<exclude-pattern>htdocs/includes</exclude-pattern>
|
||||
<exclude-pattern>htdocs/install/doctemplates/websites</exclude-pattern>
|
||||
<!-- info: '*' is replaced with '.*', so better use '+' in some cases -->
|
||||
<!-- info: 'relative' paths are relative to the examined file, so not ok. -->
|
||||
<exclude-pattern>/build/(html|aps)/</exclude-pattern>
|
||||
<exclude-pattern>/dev/tools/test/namespacemig/</exclude-pattern>
|
||||
<!-- <exclude-pattern>dev/initdata/dbf/includes</exclude-pattern> -->
|
||||
<exclude-pattern>/documents/</exclude-pattern>
|
||||
<exclude-pattern>/htdocs/core/class/lessc\.class\.php</exclude-pattern>
|
||||
<exclude-pattern>/htdocs/(custom|includes)/</exclude-pattern>
|
||||
<exclude-pattern>/htdocs/install/doctemplates/websites</exclude-pattern>
|
||||
<exclude-pattern>/htdocs/([^/]+/)?conf\.php</exclude-pattern>
|
||||
<exclude-pattern>*/nltechno*</exclude-pattern>
|
||||
<exclude-pattern>/source/</exclude-pattern>
|
||||
<exclude-pattern>/\.git/</exclude-pattern>
|
||||
<exclude-pattern>/\.cache/</exclude-pattern>
|
||||
|
||||
<!-- List of all tests -->
|
||||
|
||||
@@ -32,51 +32,62 @@
|
||||
|
||||
<!-- We want to allow empty statement: It allows to put some code comments into the else for examples -->
|
||||
<rule ref="Generic.CodeAnalysis.EmptyStatement">
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedIf"/>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedElse"/>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedElseif"/>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedCatch"/>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedForeach"/>
|
||||
</rule>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedIf"/>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedElse"/>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedElseif"/>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedCatch"/>
|
||||
<exclude name="Generic.CodeAnalysis.EmptyStatement.DetectedForeach"/>
|
||||
</rule>
|
||||
|
||||
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop" />
|
||||
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall" />
|
||||
<rule ref="Generic.CodeAnalysis.ForLoopShouldBeWhileLoop" />
|
||||
<rule ref="Generic.CodeAnalysis.ForLoopWithTestFunctionCall" />
|
||||
|
||||
<rule ref="Generic.CodeAnalysis.JumbledIncrementer" />
|
||||
<rule ref="Generic.CodeAnalysis.JumbledIncrementer" />
|
||||
|
||||
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement" />
|
||||
<rule ref="Generic.CodeAnalysis.UnconditionalIfStatement" />
|
||||
|
||||
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier" />
|
||||
<rule ref="Generic.CodeAnalysis.UnnecessaryFinalModifier" />
|
||||
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter" />
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.Found">
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter" />
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.Found">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed">
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundBeforeLastUsed">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed">
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundAfterLastUsed">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass">
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClass">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed">
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassAfterLastUsed">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed">
|
||||
</rule>
|
||||
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter.FoundInExtendedClassBeforeLastUsed">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- Lower severity on warnings we do not want to show in the pre-commit reports -->
|
||||
<rule ref="Generic.Files.LineLength.TooLong">
|
||||
<severity>4</severity>
|
||||
</rule>
|
||||
<rule ref="Generic.Metrics.CyclomaticComplexity.TooHigh">
|
||||
<severity>4</severity>
|
||||
</rule>
|
||||
<rule ref="Generic.Metrics.NestingLevel.TooHigh">
|
||||
<severity>4</severity>
|
||||
</rule>
|
||||
|
||||
|
||||
<!-- Warnings on TODO -->
|
||||
<!-- Disabled: We want to keep TODO as normal
|
||||
<rule ref="Generic.Commenting.Todo" />
|
||||
-->
|
||||
<!-- Warnings on TODO -->
|
||||
<!-- Disabled: We want to keep TODO as normal
|
||||
<rule ref="Generic.Commenting.Todo" />
|
||||
-->
|
||||
|
||||
|
||||
<!-- PHP code MUST use only UTF-8 without BOM. -->
|
||||
<rule ref="Generic.Files.ByteOrderMark"/>
|
||||
<!-- PHP code MUST use only UTF-8 without BOM. -->
|
||||
<rule ref="Generic.Files.ByteOrderMark"/>
|
||||
|
||||
<!-- Lines can be 85 chars long, but never show errors -->
|
||||
<rule ref="Generic.Files.LineLength">
|
||||
@@ -94,57 +105,57 @@
|
||||
</rule>
|
||||
|
||||
|
||||
<!-- Disallow several statements on same line -->
|
||||
<!-- Disallow several statements on same line -->
|
||||
|
||||
<!-- Warning if action on same line than if -->
|
||||
<!-- Disabled: We want to allow this for better code compacity and readability
|
||||
<rule ref="Generic.ControlStructures.InlineControlStructure">
|
||||
<!-- Disabled: We want to allow this for better code compactness and readability
|
||||
<rule ref="Generic.ControlStructures.InlineControlStructure">
|
||||
<properties>
|
||||
<property name="error" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
</rule>
|
||||
-->
|
||||
<!-- We want to allow 'if () { ...small code... }' on same line for better code compacity and readability -->
|
||||
<!-- We want to allow 'if () { ...small code... }' on a single line for better code compactness and readability -->
|
||||
<!-- <rule ref="Generic.Formatting.DisallowMultipleStatements">
|
||||
<severity>0</severity>
|
||||
</rule> -->
|
||||
|
||||
|
||||
<!-- Check assignement have the = align on each line. Have 20 chars padding maximum and always show as errors -->
|
||||
<!-- Check that assignments have the = aligned on each line. Have 20 chars padding maximum and always show as errors -->
|
||||
<!-- Disabled: Report some false warning
|
||||
<rule ref="Generic.Formatting.MultipleStatementAlignment">
|
||||
<rule ref="Generic.Formatting.MultipleStatementAlignment">
|
||||
<properties>
|
||||
<property name="maxPadding" value="20"/>
|
||||
<property name="ignoreMultiLine" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<property name="maxPadding" value="20"/>
|
||||
<property name="ignoreMultiLine" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
-->
|
||||
|
||||
<rule ref="Generic.Formatting.SpaceAfterCast" />
|
||||
|
||||
<rule ref="Generic.Functions.CallTimePassByReference" />
|
||||
<rule ref="Generic.Functions.CallTimePassByReference" />
|
||||
|
||||
<rule ref="Generic.Functions.FunctionCallArgumentSpacing" />
|
||||
|
||||
<!-- Disallow several spaces after comma -->
|
||||
<!-- Disallow several spaces after comma -->
|
||||
<!-- We want to allow this because we want to be able to align params on several similare functions on different lines -->
|
||||
<rule ref="Generic.Functions.FunctionCallArgumentSpacing.TooMuchSpaceAfterComma">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- Tweaks to metrics -->
|
||||
<rule ref="Generic.Metrics.CyclomaticComplexity">
|
||||
<properties>
|
||||
<property name="complexity" value="250" />
|
||||
<property name="absoluteComplexity" value="400" />
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Generic.Metrics.NestingLevel">
|
||||
<properties>
|
||||
<property name="nestingLevel" value="12" />
|
||||
<property name="absoluteNestingLevel" value="50" />
|
||||
</properties>
|
||||
</rule>
|
||||
<!-- Tweaks to metrics -->
|
||||
<rule ref="Generic.Metrics.CyclomaticComplexity">
|
||||
<properties>
|
||||
<property name="complexity" value="250" />
|
||||
<property name="absoluteComplexity" value="500" />
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Generic.Metrics.NestingLevel">
|
||||
<properties>
|
||||
<property name="nestingLevel" value="12" />
|
||||
<property name="absoluteNestingLevel" value="50" />
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<rule ref="Generic.NamingConventions.ConstructorName" />
|
||||
<!-- Check if we use PHP4 constructor instead of __construct() -->
|
||||
@@ -152,20 +163,20 @@
|
||||
|
||||
<rule ref="Generic.NamingConventions.UpperCaseConstantName" />
|
||||
|
||||
<rule ref="Generic.PHP.DeprecatedFunctions" />
|
||||
<rule ref="Generic.PHP.DeprecatedFunctions.Deprecated">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="Generic.PHP.DeprecatedFunctions" />
|
||||
<rule ref="Generic.PHP.DeprecatedFunctions.Deprecated">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="Generic.PHP.DisallowShortOpenTag" />
|
||||
|
||||
<rule ref="Generic.PHP.ForbiddenFunctions" />
|
||||
<rule ref="Generic.PHP.ForbiddenFunctions" />
|
||||
|
||||
<!-- Warning when using @ before functions -->
|
||||
<!-- We want this. Some features need this -->
|
||||
<rule ref="Generic.PHP.NoSilencedErrors">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<!-- Disable warning when using @ before functions -->
|
||||
<!-- We want the '@' symbols. Some features need this. -->
|
||||
<rule ref="Generic.PHP.NoSilencedErrors">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- Say if null, true, false must be uppercase (Rule 2.5 of PSR2 https://www.php-fig.org/psr/psr-2/) -->
|
||||
<rule ref="Generic.PHP.LowerCaseConstant" />
|
||||
@@ -183,123 +194,122 @@
|
||||
<!-- <rule ref="Generic.WhiteSpace.ScopeIndent" /> -->
|
||||
|
||||
<rule ref="Generic.WhiteSpace.ScopeIndent">
|
||||
<properties>
|
||||
<property name="indent" value="4"/>
|
||||
<property name="tabIndent" value="true"/>
|
||||
</properties>
|
||||
<properties>
|
||||
<property name="indent" value="4"/>
|
||||
<property name="tabIndent" value="true"/>
|
||||
</properties>
|
||||
</rule>
|
||||
|
||||
<!-- Check for duplicate class names -->
|
||||
<!-- Disabled: We need this for dependency injection.
|
||||
<rule ref="Generic.Classes.DuplicateClassName" />
|
||||
-->
|
||||
<!-- Check for duplicate class names -->
|
||||
<!-- Disabled: We need this for dependency injection.
|
||||
<rule ref="Generic.Classes.DuplicateClassName" />
|
||||
-->
|
||||
|
||||
|
||||
<!-- Rules from Squiz Standard -->
|
||||
<!-- Rules from Squiz Standard -->
|
||||
|
||||
<rule ref="Squiz.WhiteSpace.ScopeClosingBrace.Indent" />
|
||||
<rule ref="Squiz.WhiteSpace.ScopeClosingBrace.Indent" />
|
||||
|
||||
<!-- There MUST NOT be trailing whitespace at the end of non-blank lines. -->
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
|
||||
<properties>
|
||||
<property name="ignoreBlankLines" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile" />
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile" />
|
||||
<!-- Disabled: We want to have 2 empty line as separator sometimes -->
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines" >
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="Squiz.WhiteSpace.ControlStructureSpacing.SpacingAfterOpen" />
|
||||
<rule ref="Squiz.WhiteSpace.ControlStructureSpacing.SpacingBeforeClose" />
|
||||
|
||||
<rule ref="Squiz.ControlStructures.ControlSignature.SpaceAfterCloseParenthesis" />
|
||||
<rule ref="Squiz.ControlStructures.ControlSignature.SpaceAfterCloseBrace" />
|
||||
<rule ref="Squiz.ControlStructures.ControlSignature.SpaceAfterKeyword" />
|
||||
|
||||
<rule ref="Squiz.ControlStructures.ForEachLoopDeclaration.SpaceAfterOpen" />
|
||||
<rule ref="Squiz.ControlStructures.ForEachLoopDeclaration.SpaceBeforeClose" />
|
||||
|
||||
<rule ref="Squiz.Functions.MultiLineFunctionDeclaration" />
|
||||
<rule ref="Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction">
|
||||
<!-- There MUST NOT be trailing whitespace at the end of non-blank lines. -->
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace">
|
||||
<properties>
|
||||
<property name="ignoreBlankLines" value="false"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing">
|
||||
<properties>
|
||||
<property name="equalsSpacing" value="1"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="Squiz.Scope.MethodScope.Missing" />
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.StartFile" />
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EndFile" />
|
||||
<!-- Disabled: We want to have 2 empty line as separator sometimes -->
|
||||
<rule ref="Squiz.WhiteSpace.SuperfluousWhitespace.EmptyLines" >
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="Squiz.WhiteSpace.ControlStructureSpacing.SpacingAfterOpen" />
|
||||
<rule ref="Squiz.WhiteSpace.ControlStructureSpacing.SpacingBeforeClose" />
|
||||
|
||||
<rule ref="Squiz.ControlStructures.ControlSignature.SpaceAfterCloseParenthesis" />
|
||||
<rule ref="Squiz.ControlStructures.ControlSignature.SpaceAfterCloseBrace" />
|
||||
<rule ref="Squiz.ControlStructures.ControlSignature.SpaceAfterKeyword" />
|
||||
|
||||
<rule ref="Squiz.ControlStructures.ForEachLoopDeclaration.SpaceAfterOpen" />
|
||||
<rule ref="Squiz.ControlStructures.ForEachLoopDeclaration.SpaceBeforeClose" />
|
||||
|
||||
<rule ref="Squiz.Functions.MultiLineFunctionDeclaration" />
|
||||
<rule ref="Squiz.Functions.MultiLineFunctionDeclaration.SpaceAfterFunction" />
|
||||
<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing">
|
||||
<properties>
|
||||
<property name="equalsSpacing" value="1"/>
|
||||
</properties>
|
||||
</rule>
|
||||
<rule ref="Squiz.Functions.FunctionDeclarationArgumentSpacing.SpacingAfterHint">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="Squiz.Scope.MethodScope.Missing" />
|
||||
|
||||
|
||||
<!-- Rules from PEAR Standard -->
|
||||
<!-- Rules from PEAR Standard -->
|
||||
|
||||
<rule ref="PEAR.Classes.ClassDeclaration" />
|
||||
<rule ref="PEAR.Classes.ClassDeclaration" />
|
||||
|
||||
<rule ref="PEAR.Commenting.ClassComment" />
|
||||
<rule ref="PEAR.Commenting.ClassComment" />
|
||||
|
||||
<rule ref="PEAR.Commenting.ClassComment.Missing" />
|
||||
<rule ref="PEAR.Commenting.ClassComment.Missing" />
|
||||
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingTag" />
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingTag" />
|
||||
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingAuthorTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingAuthorTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingCategoryTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingLicenseTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingLinkTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingPackageTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingCategoryTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingLicenseTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingLinkTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.ClassComment.MissingPackageTag">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.Commenting.FunctionComment" />
|
||||
<rule ref="PEAR.Commenting.FunctionComment" />
|
||||
|
||||
<rule ref="PEAR.Commenting.FunctionComment.Empty" />
|
||||
<rule ref="PEAR.Commenting.FunctionComment.Empty" />
|
||||
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParamType" />
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParamType" />
|
||||
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParamName">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParamType">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParamName">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParamType">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.Commenting.FunctionComment.ReturnNotRequired" />
|
||||
<rule ref="PEAR.Commenting.FunctionComment.ReturnNotRequired" />
|
||||
|
||||
<rule ref="PEAR.Commenting.FunctionComment.WrongStyle" />
|
||||
<rule ref="PEAR.Commenting.FunctionComment.WrongStyle" />
|
||||
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingBeforeParamType">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterLongType">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterLongName">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParams">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.ParameterCommentsNotAligned">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.ParameterNamesNotAligned">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingBeforeParamType">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterLongType">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterLongName">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.SpacingAfterParams">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.ParameterCommentsNotAligned">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Commenting.FunctionComment.ParameterNamesNotAligned">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.Commenting.InlineComment" />
|
||||
<rule ref="PEAR.Commenting.InlineComment" />
|
||||
|
||||
<!-- Check position of { after a control structure like if (), while (), etc... -->
|
||||
<!--
|
||||
@@ -312,37 +322,37 @@
|
||||
<rule ref="PEAR.Files.IncludingFile" />
|
||||
|
||||
<!-- We disable this: We must be able to make require inside if -->
|
||||
<rule ref="PEAR.Files.IncludingFile.UseInclude">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Files.IncludingFile.UseInclude">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- We disable this. We must be allowed to use strict require instead of non strict include anywhere -->
|
||||
<rule ref="PEAR.Files.IncludingFile.UseIncludeOnce">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<!-- We disable this. We must be allowed to use strict require instead of non strict include anywhere -->
|
||||
<rule ref="PEAR.Files.IncludingFile.UseIncludeOnce">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.Files.IncludingFile.UseRequire">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.Files.IncludingFile.UseRequire">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- We disable this: We want to allow include_once -->
|
||||
<rule ref="PEAR.Files.IncludingFile.UseRequireOnce">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<!-- We disable this: We want to allow include_once -->
|
||||
<rule ref="PEAR.Files.IncludingFile.UseRequireOnce">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.Formatting.MultiLineAssignment" />
|
||||
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature" />
|
||||
|
||||
<!-- We disable this: It returns a lot of false positive -->
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.CloseBracketLine">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<!-- We disable this: It returns a lot of false positive -->
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.CloseBracketLine">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- We disable this: We want to allow small function on 1 line -->
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<!-- We disable this: We want to allow small function on 1 line -->
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.ContentAfterOpenBracket">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.EmptyLine" />
|
||||
|
||||
@@ -351,14 +361,14 @@
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.SpaceBeforeOpenBracket" />
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.SpaceAfterCloseBracket" />
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.SpaceBeforeOpenBracket" />
|
||||
<rule ref="PEAR.Functions.FunctionCallSignature.SpaceAfterCloseBracket" />
|
||||
|
||||
<rule ref="PEAR.Functions.ValidDefaultValue" />
|
||||
|
||||
<rule ref="PEAR.NamingConventions.ValidClassName" />
|
||||
<rule ref="PEAR.NamingConventions.ValidClassName.Invalid">
|
||||
<severity>0</severity>
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!-- We disable this: there is a lot of existing method not starting with a capital letter (class modXxxx, ...) -->
|
||||
@@ -367,7 +377,7 @@
|
||||
</rule>
|
||||
<!-- some phpcs have a typo error in rule, so we add it this rule too with term "Captial" instead of "Capital" -->
|
||||
<rule ref="PEAR.NamingConventions.ValidClassName.StartWithCaptial">
|
||||
<severity>0</severity>
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.NamingConventions.ValidFunctionName" />
|
||||
@@ -375,26 +385,26 @@
|
||||
|
||||
<!-- We disable this: there is a lot of existing function not starting with a capital letter (class modXxxx, ...) -->
|
||||
<rule ref="PEAR.NamingConventions.ValidFunctionName.FunctionNameInvalid">
|
||||
<severity>0</severity>
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.NamingConventions.ValidFunctionName.FunctionNoCapital">
|
||||
<severity>0</severity>
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<!-- some phpcs have a typo error in rule, so we add it this rule too with term "Captial" instead of "Capital" -->
|
||||
<rule ref="PEAR.NamingConventions.ValidFunctionName.FunctionNoCaptial">
|
||||
<severity>0</severity>
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<!--<rule ref="PEAR.NamingConventions.ValidFunctionName.NotCamelCaps">
|
||||
<severity>0</severity>
|
||||
</rule>-->
|
||||
<!--<rule ref="PEAR.NamingConventions.ValidFunctionName.NotCamelCaps">
|
||||
<severity>0</severity>
|
||||
</rule>-->
|
||||
<!--<rule ref="PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps">
|
||||
<severity>0</severity>
|
||||
<severity>0</severity>
|
||||
</rule>-->
|
||||
|
||||
<!-- We disable this: We don't want to have private methods prefixed with an underscore -->
|
||||
<rule ref="PEAR.NamingConventions.ValidFunctionName.PrivateNoUnderscore">
|
||||
<severity>0</severity>
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.NamingConventions.ValidVariableName" />
|
||||
@@ -402,35 +412,35 @@
|
||||
<!-- This is not in PSR2 -->
|
||||
<!-- We disable this: We don't want to have private methods prefixed with an underscore -->
|
||||
<rule ref="PEAR.NamingConventions.ValidVariableName.PrivateNoUnderscore">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
|
||||
<rule ref="PEAR.WhiteSpace.ObjectOperatorIndent" />
|
||||
|
||||
<!-- Need to be commented to be disabled
|
||||
<rule ref="PEAR.WhiteSpace.ScopeClosingBrace">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.WhiteSpace.ScopeClosingBrace.Line">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
<rule ref="PEAR.WhiteSpace.ScopeClosingBrace.Line">
|
||||
<severity>0</severity>
|
||||
</rule>
|
||||
-->
|
||||
|
||||
<!-- Already found as a Generic rule -->
|
||||
<!-- Already found as a Generic rule -->
|
||||
<!-- <rule ref="PEAR.WhiteSpace.ScopeIndent" /> -->
|
||||
|
||||
|
||||
<!-- Rules PSR 2 -->
|
||||
<rule ref="PSR2.Classes.ClassDeclaration" />
|
||||
<rule ref="PSR2.Methods.FunctionClosingBrace" />
|
||||
<rule ref="PSR2.ControlStructures.ElseIfDeclaration.NotAllowed" />
|
||||
<rule ref="PSR2.Classes.ClassDeclaration" />
|
||||
<rule ref="PSR2.Methods.FunctionClosingBrace" />
|
||||
<rule ref="PSR2.Files.EndFileNewline.TooMany" />
|
||||
<rule ref="PSR2.Classes.ClassDeclaration" />
|
||||
<rule ref="PSR2.Methods.FunctionClosingBrace" />
|
||||
<rule ref="PSR2.ControlStructures.ElseIfDeclaration.NotAllowed" />
|
||||
<rule ref="PSR2.Classes.ClassDeclaration" />
|
||||
<rule ref="PSR2.Methods.FunctionClosingBrace" />
|
||||
<rule ref="PSR2.Files.EndFileNewline.TooMany" />
|
||||
<rule ref="PSR2.Files.EndFileNewline.NoneFound" />
|
||||
<rule ref="PSR2.Methods.FunctionCallSignature.SpaceBeforeOpenBracket" />
|
||||
<rule ref="PSR2.Classes.PropertyDeclaration.VarUsed" />
|
||||
<!-- The closing ?> tag MUST be omitted from files containing only PHP. -->
|
||||
<rule ref="PSR2.Files.ClosingTag"/>
|
||||
<!-- The closing ?> tag MUST be omitted from files containing only PHP. -->
|
||||
<rule ref="PSR2.Files.ClosingTag"/>
|
||||
|
||||
</ruleset>
|
||||
|
||||
68
dev/tools/codespell/addCodespellIgnores.sh
Executable file
68
dev/tools/codespell/addCodespellIgnores.sh
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/bin/bash
|
||||
# Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
|
||||
|
||||
#
|
||||
# Script to add codespell exceptions to the ignores lines file.
|
||||
#
|
||||
# The file is named '...-lines-ignore' to make TAB expansion on the cli easier.
|
||||
#
|
||||
# The line in the ignore file must match the line in the source
|
||||
# exactly.
|
||||
#
|
||||
# To clean up or create the ignored lines file, just do
|
||||
# ```shell
|
||||
# echo > dev/tools/codespell/codespell-lines-ignore.txt
|
||||
# ```
|
||||
# and then execute this script.
|
||||
#
|
||||
# author: https://github.com/mdeweerd
|
||||
|
||||
#
|
||||
# :warning:
|
||||
#
|
||||
# This script only works properly if codespell is installed for your CLI.
|
||||
# As the configuration is in pyproject.toml, you also need tomli.
|
||||
#
|
||||
# ```shell
|
||||
# python -m pip install codespell tomli
|
||||
# # or
|
||||
# pip install codespell tomli
|
||||
# ```
|
||||
|
||||
codespell_ignore_file=dev/tools/codespell/codespell-lines-ignore.txt
|
||||
if [ -z "${0##*.sh}" ] ; then
|
||||
# Suppose running from inside script
|
||||
# Get real path
|
||||
script=$(realpath "$(test -L "$0" && readlink "$0" || echo "$0")")
|
||||
PROJECT_ROOT=$(realpath "${script}")
|
||||
|
||||
while [ "${PROJECT_ROOT}" != "/" ] ; do
|
||||
[ -r "${PROJECT_ROOT}/${codespell_ignore_file}" ] && break
|
||||
PROJECT_ROOT=$(dirname "${PROJECT_ROOT}")
|
||||
done
|
||||
if [ "${PROJECT_ROOT}" == "/" ] ; then
|
||||
echo "Project root not found from '${script}'"
|
||||
exit 1
|
||||
fi
|
||||
codespell_ignore_file=${PROJECT_ROOT}/${codespell_ignore_file}
|
||||
fi
|
||||
|
||||
|
||||
# Make sure we are at the root of the project
|
||||
[ -r "${codespell_ignore_file}" ] || { echo "${codespell_ignore_file} not found" ; exit 1 ; }
|
||||
# Then:
|
||||
# - Run codespell;
|
||||
# - Identify files that have fixes;
|
||||
# - Limit to files under git control;
|
||||
# - Run codespell on selected files;
|
||||
# - For each line, create a grep command to find the lines;
|
||||
# - Execute that command by evaluation
|
||||
codespell . \
|
||||
| sed -n -E 's@^([^:]+):.*@\1@p' \
|
||||
| xargs -r git ls-files -- \
|
||||
| xargs -r codespell -- \
|
||||
| sed -n -E 's@^([^:]+):[[:digit:]]+:[[:space:]](\S+)[[:space:]].*@grep -P '\''\\b\2\\b'\'' -- "\1" >> '"${codespell_ignore_file}"'@p' \
|
||||
| while read -r line ; do eval "$line" ; done
|
||||
|
||||
# Finally, sort and remove duplicates to make merges easier.
|
||||
sort -u -o "${codespell_ignore_file}"{,}
|
||||
21
dev/tools/codespell/codespell-dict.txt
Normal file
21
dev/tools/codespell/codespell-dict.txt
Normal file
@@ -0,0 +1,21 @@
|
||||
# Please add in alphabetical order->(`sort -u` like).
|
||||
EPR->ERP
|
||||
alpah->alpha
|
||||
alphanothtml->alphanohtml
|
||||
alpahnothtml->alphanohtml
|
||||
aplha->alpha
|
||||
aplhanothtml->alphanohtml
|
||||
aploha->alpha
|
||||
aplohanothtml->alphanohtml
|
||||
aplphanothtml->alphanohtml
|
||||
choosed->chosen
|
||||
dolibar->dolibarr
|
||||
dollibar->dolibarr
|
||||
dollibarr->dolibarr
|
||||
# fiche->card
|
||||
mot de passe->password
|
||||
not de passe->password
|
||||
nothtml->nohtml
|
||||
tableau de bord->state board
|
||||
tagret->target
|
||||
thridparty->thirdparty
|
||||
91
dev/tools/codespell/codespell-ignore.txt
Normal file
91
dev/tools/codespell/codespell-ignore.txt
Normal file
@@ -0,0 +1,91 @@
|
||||
# List of words codespell will ignore
|
||||
# one per line, case-sensitive (when not lowercase)
|
||||
# PROVid
|
||||
provid
|
||||
# PostgreSQL
|
||||
postgresql
|
||||
|
||||
alltime
|
||||
ba
|
||||
blacklist
|
||||
whitelist
|
||||
bu
|
||||
captial
|
||||
categorie
|
||||
categories
|
||||
crypted
|
||||
clos
|
||||
contaxt
|
||||
courant
|
||||
datea
|
||||
datee
|
||||
errorstring
|
||||
exten
|
||||
falsy
|
||||
master
|
||||
medias
|
||||
noe
|
||||
NOO
|
||||
noo
|
||||
od
|
||||
nd
|
||||
udate
|
||||
periode
|
||||
projet
|
||||
referer
|
||||
referers
|
||||
scrit
|
||||
ser
|
||||
slave
|
||||
savvy
|
||||
# Inside email
|
||||
suport
|
||||
te
|
||||
technic
|
||||
thead
|
||||
udo
|
||||
ue
|
||||
ro
|
||||
ws
|
||||
# Code string
|
||||
ect
|
||||
tempdate
|
||||
# checkES
|
||||
checkes
|
||||
sav
|
||||
files'
|
||||
# Used as array ke
|
||||
seeked
|
||||
# Used as translation key
|
||||
developpers
|
||||
# Used as var
|
||||
pice
|
||||
# Used as key
|
||||
marge
|
||||
# htdocs/projet/activity/permonth.php
|
||||
tweek
|
||||
# moral (var name)
|
||||
mor
|
||||
# reyear, remonth, reday
|
||||
reday
|
||||
# Strings used as keys for translation
|
||||
uptodate
|
||||
reenable
|
||||
# Function - rename to devalidate ?
|
||||
unvalidate
|
||||
# Some french strings
|
||||
somme
|
||||
caracteres
|
||||
cas
|
||||
sur
|
||||
Datas
|
||||
datas
|
||||
valide
|
||||
raison
|
||||
que
|
||||
dur
|
||||
fonction
|
||||
espace
|
||||
methode
|
||||
# Proper names
|
||||
tim
|
||||
2464
dev/tools/codespell/codespell-lines-ignore.txt
Normal file
2464
dev/tools/codespell/codespell-lines-ignore.txt
Normal file
File diff suppressed because it is too large
Load Diff
@@ -135,6 +135,7 @@ $s = $formaccounting->select_accounting_category($cat_id, 'account_category', 1,
|
||||
if ($formaccounting->nbaccounts_category <= 0) {
|
||||
print '<span class="opacitymedium">'.$s.'</span>';
|
||||
} else {
|
||||
print $s;
|
||||
print '<input type="submit" class="button small" value="'.$langs->trans("Select").'">';
|
||||
}
|
||||
print '</td></tr>';
|
||||
|
||||
@@ -87,7 +87,7 @@ $tablib[32] = "DictionaryAccountancyCategory";
|
||||
|
||||
// Requests to extract data
|
||||
$tabsql = array();
|
||||
$tabsql[32] = "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.category_type, a.formula, a.position as position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid and c.active=1";
|
||||
$tabsql[32] = "SELECT a.rowid as rowid, a.code as code, a.label, a.range_account, a.category_type, a.formula, a.position as position, a.fk_country as country_id, c.code as country_code, c.label as country, a.active FROM ".MAIN_DB_PREFIX."c_accounting_category as a, ".MAIN_DB_PREFIX."c_country as c WHERE a.fk_country=c.rowid AND c.active=1 AND a.entity IN (".getEntity('c_accounting_category').")";
|
||||
|
||||
// Criteria to sort dictionaries
|
||||
$tabsqlsort = array();
|
||||
@@ -99,11 +99,11 @@ $tabfield[32] = "code,label,range_account,category_type,formula,position,country
|
||||
|
||||
// Name of editing fields for record modification
|
||||
$tabfieldvalue = array();
|
||||
$tabfieldvalue[32] = "code,label,range_account,category_type,formula,position,country_id";
|
||||
$tabfieldvalue[32] = "code,label,range_account,category_type,formula,position,country_id,entity";
|
||||
|
||||
// Name of the fields in the table for inserting a record
|
||||
$tabfieldinsert = array();
|
||||
$tabfieldinsert[32] = "code,label,range_account,category_type,formula,position,fk_country";
|
||||
$tabfieldinsert[32] = "code,label,range_account,category_type,formula,position,fk_country,entity";
|
||||
|
||||
// Name of the rowid if the field is not of type autoincrement
|
||||
// Example: "" if id field is "rowid" and has autoincrement on
|
||||
@@ -896,7 +896,7 @@ if ($resql) {
|
||||
// Active
|
||||
print '<td class="center" class="nowrap">';
|
||||
if ($canbedisabled) {
|
||||
print '<a href="'.$url.'action='.$acts[$obj->active].'">'.$actl[$obj->active].'</a>';
|
||||
print '<a href="'.$url.'action='.$acts[$obj->active].'&token='.newToken().'">'.$actl[$obj->active].'</a>';
|
||||
} else {
|
||||
print $langs->trans("AlwaysActive");
|
||||
}
|
||||
|
||||
@@ -197,6 +197,9 @@ if (empty($reshook)) {
|
||||
$filter['t.reconciled_option'] = $search_not_reconciled;
|
||||
$param .= '&search_not_reconciled='.urlencode($search_not_reconciled);
|
||||
}
|
||||
if (!empty($show_subgroup)) {
|
||||
$param .= '&show_subgroup='.urlencode($show_subgroup);
|
||||
}
|
||||
|
||||
// param with type of list
|
||||
$url_param = substr($param, 1); // remove first "&"
|
||||
@@ -300,7 +303,7 @@ if ($action != 'export_csv') {
|
||||
$newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint;
|
||||
|
||||
if (empty($reshook)) {
|
||||
$newcardbutton = '<input type="button" id="exportcsvbutton" name="exportcsvbutton" class="butAction" value="'.$langs->trans("Export").' ('.$conf->global->ACCOUNTING_EXPORT_FORMAT.')" />';
|
||||
$newcardbutton .= '<input type="button" id="exportcsvbutton" name="exportcsvbutton" class="butAction" value="'.$langs->trans("Export").' ('.$conf->global->ACCOUNTING_EXPORT_FORMAT.')" />';
|
||||
|
||||
print '<script type="text/javascript">
|
||||
jQuery(document).ready(function() {
|
||||
@@ -538,7 +541,7 @@ if ($action != 'export_csv') {
|
||||
|
||||
// Show first line of a break
|
||||
print '<tr class="trforbreak">';
|
||||
print '<td colspan="'.($colspan+1).'" style="font-weight:bold; border-bottom: 1pt solid black;">'.$line->numero_compte.($root_account_description ? ' - '.$root_account_description : '').'</td>';
|
||||
print '<td colspan="'.($colspan+1).'" class="tdforbreak">'.$root_account_number.($root_account_description ? ' - '.$root_account_description : '').'</td>';
|
||||
print '</tr>';
|
||||
|
||||
$displayed_account = $root_account_number;
|
||||
|
||||
@@ -330,7 +330,7 @@ if ($action == 'valid') {
|
||||
* View
|
||||
*/
|
||||
|
||||
$html = new Form($db);
|
||||
$form = new Form($db);
|
||||
$formaccounting = new FormAccounting($db);
|
||||
|
||||
$title = $langs->trans("CreateMvts");
|
||||
@@ -339,7 +339,7 @@ llxHeader('', $title);
|
||||
|
||||
// Confirmation to delete the command
|
||||
if ($action == 'delete') {
|
||||
$formconfirm = $html->formconfirm($_SERVER["PHP_SELF"].'?id='.$id.'&mode='.$mode, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'confirm_delete', '', 0, 1);
|
||||
$formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$id.'&mode='.$mode, $langs->trans('DeleteMvt'), $langs->trans('ConfirmDeleteMvt', $langs->transnoentitiesnoconv("RegistrationInAccounting")), 'confirm_delete', '', 0, 1);
|
||||
print $formconfirm;
|
||||
}
|
||||
|
||||
@@ -374,7 +374,7 @@ if ($action == 'create') {
|
||||
print '<tr>';
|
||||
print '<td class="titlefieldcreate fieldrequired">'.$langs->trans("Docdate").'</td>';
|
||||
print '<td>';
|
||||
print $html->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1);
|
||||
print $form->selectDate('', 'doc_date', '', '', '', "create_mvt", 1, 1);
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
|
||||
@@ -348,7 +348,7 @@ if (empty($reshook)) {
|
||||
$listofaccountsforgroup2 = array();
|
||||
if (is_array($listofaccountsforgroup)) {
|
||||
foreach ($listofaccountsforgroup as $tmpval) {
|
||||
$listofaccountsforgroup2[] = "'".$db->escape($tmpval['id'])."'";
|
||||
$listofaccountsforgroup2[] = "'".$db->escape($tmpval['account_number'])."'";
|
||||
}
|
||||
}
|
||||
$filter['t.search_accounting_code_in'] = join(',', $listofaccountsforgroup2);
|
||||
@@ -1190,7 +1190,6 @@ while ($i < min($num, $limit)) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
|
||||
$objectstatic = new Facture($db);
|
||||
$objectstatic->fetch($line->fk_doc);
|
||||
//$modulepart = 'facture';
|
||||
|
||||
$filename = dol_sanitizeFileName($line->doc_ref);
|
||||
$filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($line->doc_ref);
|
||||
@@ -1202,11 +1201,10 @@ while ($i < min($num, $limit)) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
|
||||
$objectstatic = new FactureFournisseur($db);
|
||||
$objectstatic->fetch($line->fk_doc);
|
||||
//$modulepart = 'invoice_supplier';
|
||||
|
||||
$filename = dol_sanitizeFileName($line->doc_ref);
|
||||
$filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($line->fk_doc, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref);
|
||||
$subdir = get_exdir($objectstatic->id, 2, 0, 0, $objectstatic, $modulepart).dol_sanitizeFileName($line->doc_ref);
|
||||
$filedir = $conf->fournisseur->facture->dir_output.'/'.get_exdir($line->fk_doc, 2, 0, 0, $objectstatic, $objectstatic->element).dol_sanitizeFileName($line->doc_ref);
|
||||
$subdir = get_exdir($objectstatic->id, 2, 0, 0, $objectstatic, $objectstatic->element).dol_sanitizeFileName($line->doc_ref);
|
||||
$documentlink = $formfile->getDocumentsLink($objectstatic->element, $subdir, $filedir);
|
||||
} elseif ($line->doc_type == 'expense_report') {
|
||||
$langs->loadLangs(array('trips'));
|
||||
@@ -1214,7 +1212,6 @@ while ($i < min($num, $limit)) {
|
||||
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
|
||||
$objectstatic = new ExpenseReport($db);
|
||||
$objectstatic->fetch($line->fk_doc);
|
||||
//$modulepart = 'expensereport';
|
||||
|
||||
$filename = dol_sanitizeFileName($line->doc_ref);
|
||||
$filedir = $conf->expensereport->dir_output.'/'.dol_sanitizeFileName($line->doc_ref);
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<?php
|
||||
/* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
|
||||
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013-2023 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2022 Lionel Vessiller <lvessiller@open-dsi.fr>
|
||||
* Copyright (C) 2013-2024 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2022 Lionel Vessiller <lvessiller@open-dsi.fr>
|
||||
* Copyright (C) 2016-2017 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2018-2021 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2022 Progiseize <a.bisotti@progiseize.fr>
|
||||
@@ -332,7 +332,7 @@ if (empty($reshook)) {
|
||||
$listofaccountsforgroup2 = array();
|
||||
if (is_array($listofaccountsforgroup)) {
|
||||
foreach ($listofaccountsforgroup as $tmpval) {
|
||||
$listofaccountsforgroup2[] = "'".$db->escape($tmpval['id'])."'";
|
||||
$listofaccountsforgroup2[] = "'".$db->escape($tmpval['account_number'])."'";
|
||||
}
|
||||
}
|
||||
$filter['t.search_accounting_code_in'] = join(',', $listofaccountsforgroup2);
|
||||
@@ -479,7 +479,7 @@ if (empty($reshook)) {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
$error++;
|
||||
break;
|
||||
} elseif (isset($object->date_validation) || $object->date_validation != '') {
|
||||
} elseif (isset($object->date_validation) && $object->date_validation != '') {
|
||||
setEventMessages($langs->trans("ValidatedRecordWhereFound"), null, 'errors');
|
||||
$error++;
|
||||
break;
|
||||
@@ -932,7 +932,7 @@ if (!empty($arrayfields['t.tms']['checked'])) {
|
||||
print $form->selectDate($search_date_modification_start, 'search_date_modification_start', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
|
||||
print '</div>';
|
||||
print '<div class="nowrap">';
|
||||
print $form->selectDate($search_date_modification_end, 'search_date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("From"));
|
||||
print $form->selectDate($search_date_modification_end, 'search_date_modification_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("to"));
|
||||
print '</div>';
|
||||
print '</td>';
|
||||
}
|
||||
@@ -1293,7 +1293,7 @@ while ($i < min($num, $limit)) {
|
||||
}
|
||||
|
||||
if (!empty($arrayfields['t.import_key']['checked'])) {
|
||||
print '<td class="tdoverflowmax100">'.$obj->import_key."</td>\n";
|
||||
print '<td class="center">'.$obj->import_key."</td>\n";
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
/* Copyright (C) 2016 Neil Orley <neil.orley@oeris.fr>
|
||||
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
|
||||
* Copyright (C) 2013-2020 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013-2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2013-2024 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -291,7 +291,7 @@ if (empty($reshook)) {
|
||||
$listofaccountsforgroup2 = array();
|
||||
if (is_array($listofaccountsforgroup)) {
|
||||
foreach ($listofaccountsforgroup as $tmpval) {
|
||||
$listofaccountsforgroup2[] = "'".$db->escape($tmpval['id'])."'";
|
||||
$listofaccountsforgroup2[] = "'".$db->escape($tmpval['account_number'])."'";
|
||||
}
|
||||
}
|
||||
$filter['t.search_accounting_code_in'] = join(',', $listofaccountsforgroup2);
|
||||
@@ -446,7 +446,7 @@ if (empty($reshook)) {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
$error++;
|
||||
break;
|
||||
} elseif (isset($object->date_validation) || $object->date_validation != '') {
|
||||
} elseif (isset($object->date_validation) && $object->date_validation != '') {
|
||||
setEventMessages($langs->trans("ValidatedRecordWhereFound"), null, 'errors');
|
||||
$error++;
|
||||
break;
|
||||
@@ -675,7 +675,7 @@ if ($reshook < 0) {
|
||||
$newcardbutton = empty($hookmanager->resPrint) ? '' : $hookmanager->resPrint;
|
||||
|
||||
if (empty($reshook)) {
|
||||
$newcardbutton = dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param);
|
||||
$newcardbutton .= dolGetButtonTitle($langs->trans('ViewFlatList'), '', 'fa fa-list paddingleft imgforviewmode', DOL_URL_ROOT.'/accountancy/bookkeeping/list.php?'.$param);
|
||||
if ($type == 'sub') {
|
||||
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupByAccountAccounting'), '', 'fa fa-stream paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?' . $url_param, '', 1, array('morecss' => 'marginleftonly'));
|
||||
$newcardbutton .= dolGetButtonTitle($langs->trans('GroupBySubAccountAccounting'), '', 'fa fa-align-left vmirror paddingleft imgforviewmode', DOL_URL_ROOT . '/accountancy/bookkeeping/listbyaccount.php?type=sub&' . $url_param, '', 1, array('morecss' => 'marginleftonly btnTitleSelected'));
|
||||
@@ -932,6 +932,21 @@ $sous_total_credit = 0;
|
||||
$totalarray['val']['totaldebit'] = 0;
|
||||
$totalarray['val']['totalcredit'] = 0;
|
||||
|
||||
$colspan = 0; // colspan before field 'label of operation'
|
||||
$colspanend = 3; // colspan after debit/credit
|
||||
if (!empty($arrayfields['t.piece_num']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.code_journal']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.doc_date']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.doc_ref']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.label_operation']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; }
|
||||
if (!empty($arrayfields['t.date_validated']['checked'])) { $colspanend++; }
|
||||
if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; }
|
||||
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
||||
$colspan++;
|
||||
$colspanend--;
|
||||
}
|
||||
|
||||
while ($i < min($num, $limit)) {
|
||||
$line = $object->lines[$i];
|
||||
|
||||
@@ -945,21 +960,6 @@ while ($i < min($num, $limit)) {
|
||||
}
|
||||
//if (empty($accountg)) $accountg = '-';
|
||||
|
||||
$colspan = 0; // colspan before field 'label of operation'
|
||||
$colspanend = 3; // colspan after debit/credit
|
||||
if (!empty($arrayfields['t.piece_num']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.code_journal']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.doc_date']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.doc_ref']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.label_operation']['checked'])) { $colspan++; }
|
||||
if (!empty($arrayfields['t.date_export']['checked'])) { $colspanend++; }
|
||||
if (!empty($arrayfields['t.date_validated']['checked'])) { $colspanend++; }
|
||||
if (!empty($arrayfields['t.lettering_code']['checked'])) { $colspanend++; }
|
||||
if (getDolGlobalString('MAIN_CHECKBOX_LEFT_COLUMN')) {
|
||||
$colspan++;
|
||||
$colspanend--;
|
||||
}
|
||||
|
||||
// Is it a break ?
|
||||
if ($accountg != $displayed_account_number || !isset($displayed_account_number)) {
|
||||
// Show a subtotal by accounting account
|
||||
@@ -1027,8 +1027,6 @@ while ($i < min($num, $limit)) {
|
||||
//if (empty($displayed_account_number)) $displayed_account_number='-';
|
||||
$sous_total_debit = 0;
|
||||
$sous_total_credit = 0;
|
||||
|
||||
$colspan = 0;
|
||||
}
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
@@ -1207,7 +1205,7 @@ while ($i < min($num, $limit)) {
|
||||
}
|
||||
|
||||
if (!empty($arrayfields['t.import_key']['checked'])) {
|
||||
print '<td class="tdoverflowmax100">'.$line->import_key."</td>\n";
|
||||
print '<td class="center">'.$line->import_key."</td>\n";
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
* Copyright (C) 2015 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
|
||||
* Copyright (C) 2016 Pierre-Henry Favre <phf@atm-consulting.fr>
|
||||
* Copyright (C) 2016-2023 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2016-2024 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2022 Lionel Vessiller <lvessiller@open-dsi.fr>
|
||||
* Copyright (C) 2013-2017 Olivier Geffroy <jeff@jeffinfo.com>
|
||||
* Copyright (C) 2017 Elarifr. Ari Elbaz <github@accedinfo.com>
|
||||
@@ -385,11 +385,12 @@ class AccountancyExport
|
||||
// directory already created when module is enabled
|
||||
$outputDir .= '/export';
|
||||
$outputDir .= '/'.dol_sanitizePathName($formatexportset);
|
||||
if (!dol_is_dir($outputDir)) {
|
||||
if (dol_mkdir($outputDir) < 0) {
|
||||
$this->errors[] = $langs->trans('ErrorCanNotCreateDir', $outputDir);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (!dol_is_dir($outputDir)) {
|
||||
if (dol_mkdir($outputDir) < 0) {
|
||||
$this->errors[] = $langs->trans('ErrorCanNotCreateDir', $outputDir);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -965,7 +966,7 @@ class AccountancyExport
|
||||
|
||||
// We need to keep the 10 lastest number of invoice doc_ref not the beginning part that is the unusefull almost same part
|
||||
// $tab['num_piece3'] = str_pad(self::trunc($line->piece_num, 10), 10);
|
||||
$tab['num_piece3'] = substr(self::trunc($line->doc_ref, 20), -10);
|
||||
$tab['num_piece3'] = str_pad(substr(self::trunc($line->doc_ref, 20), -10), 10);
|
||||
$tab['reserved'] = str_repeat(' ', 10); // position 159
|
||||
$tab['currency_amount'] = str_repeat(' ', 13); // position 169
|
||||
// get document file
|
||||
|
||||
@@ -93,10 +93,9 @@ class AccountancyImport
|
||||
public function computeAmount(&$arrayrecord, $listfields, $record_key)
|
||||
{
|
||||
// get fields indexes
|
||||
$field_index_list = array_flip($listfields);
|
||||
if (isset($field_index_list['debit']) && isset($field_index_list['credit'])) {
|
||||
$debit_index = $field_index_list['debit'];
|
||||
$credit_index = $field_index_list['credit'];
|
||||
if (isset($listfields['b.debit']) && isset($listfields['b.credit'])) {
|
||||
$debit_index = $listfields['b.debit'];
|
||||
$credit_index = $listfields['b.credit'];
|
||||
|
||||
$debit = floatval($arrayrecord[$debit_index]['val']);
|
||||
$credit = floatval($arrayrecord[$credit_index]['val']);
|
||||
@@ -123,9 +122,8 @@ class AccountancyImport
|
||||
*/
|
||||
public function computeDirection(&$arrayrecord, $listfields, $record_key)
|
||||
{
|
||||
$field_index_list = array_flip($listfields);
|
||||
if (isset($field_index_list['debit'])) {
|
||||
$debit_index = $field_index_list['debit'];
|
||||
if (isset($listfields['b.debit'])) {
|
||||
$debit_index = $listfields['b.debit'];
|
||||
|
||||
$debit = floatval($arrayrecord[$debit_index]['val']);
|
||||
if (!empty($debit)) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/* Copyright (C) 2013-2014 Olivier Geffroy <jeff@jeffinfo.com>
|
||||
* Copyright (C) 2013-2021 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2013-2024 Alexandre Spangaro <aspangaro@easya.solutions>
|
||||
* Copyright (C) 2013-2021 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2015 Ari Elbaz (elarifr) <github@accedinfo.com>
|
||||
@@ -842,7 +842,7 @@ class AccountingAccount extends CommonObject
|
||||
}
|
||||
$suggestedid = $accountingAccount['dom']; // There is a doubt for this case. Is it an error on vat or we just forgot to fill vat number ?
|
||||
$suggestedaccountingaccountfor = 'eecwithoutvatnumber';
|
||||
} elseif ($isSellerInEEC && $isBuyerInEEC && !empty($product->accountancy_code_sell_intra)) {
|
||||
} elseif ($isSellerInEEC && $isBuyerInEEC) {
|
||||
// European intravat sale
|
||||
if ($type == 'customer' && !empty($product->accountancy_code_sell_intra)) {
|
||||
$code_p = $product->accountancy_code_sell_intra;
|
||||
@@ -865,10 +865,14 @@ class AccountingAccount extends CommonObject
|
||||
|
||||
// Level 3 (define $code_t): Search suggested account for this thirdparty (similar code exists in page index.php to make automatic binding)
|
||||
if (!empty($conf->global->ACCOUNTANCY_USE_PRODUCT_ACCOUNT_ON_THIRDPARTY)) {
|
||||
if (!empty($buyer->code_compta_product)) {
|
||||
if ($type == 'customer' && !empty($buyer->code_compta_product)) {
|
||||
$code_t = $buyer->code_compta_product;
|
||||
$suggestedid = $accountingAccount['thirdparty'];
|
||||
$suggestedaccountingaccountfor = 'thirdparty';
|
||||
} elseif ($type == 'supplier' && !empty($seller->code_compta_product)) {
|
||||
$code_t = $seller->code_compta_product;
|
||||
$suggestedid = $accountingAccount['thirdparty'];
|
||||
$suggestedaccountingaccountfor = 'thirdparty';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -967,7 +967,7 @@ class BookKeeping extends CommonObject
|
||||
$line->multicurrency_amount = $obj->multicurrency_amount;
|
||||
$line->multicurrency_code = $obj->multicurrency_code;
|
||||
$line->lettering_code = $obj->lettering_code;
|
||||
$line->date_lettering = $obj->date_lettering;
|
||||
$line->date_lettering = $this->db->jdate($obj->date_lettering);
|
||||
$line->fk_user_author = $obj->fk_user_author;
|
||||
$line->import_key = $obj->import_key;
|
||||
$line->code_journal = $obj->code_journal;
|
||||
@@ -1068,7 +1068,7 @@ class BookKeeping extends CommonObject
|
||||
$sqlwhere[] = natural_search($key, $value, 1, 1);
|
||||
} elseif ($key == 't.code_journal' && !empty($value)) {
|
||||
if (is_array($value)) {
|
||||
$sqlwhere[] = natural_search("t.code_journal", join(',', $value), 3, 1);
|
||||
$sqlwhere[] = natural_search("t.code_journal", (string) join(',', $value), 3, 1);
|
||||
} else {
|
||||
$sqlwhere[] = natural_search("t.code_journal", $value, 3, 1);
|
||||
}
|
||||
@@ -1119,7 +1119,7 @@ class BookKeeping extends CommonObject
|
||||
$line->amount = $obj->amount;
|
||||
$line->sens = $obj->sens;
|
||||
$line->lettering_code = $obj->lettering_code;
|
||||
$line->date_lettering = $obj->date_lettering;
|
||||
$line->date_lettering = $this->db->jdate($obj->date_lettering);
|
||||
$line->fk_user_author = $obj->fk_user_author;
|
||||
$line->import_key = $obj->import_key;
|
||||
$line->code_journal = $obj->code_journal;
|
||||
@@ -1399,6 +1399,7 @@ class BookKeeping extends CommonObject
|
||||
*/
|
||||
public function updateByMvt($piece_num = '', $field = '', $value = '', $mode = '')
|
||||
{
|
||||
global $conf;
|
||||
$error = 0;
|
||||
|
||||
$this->db->begin();
|
||||
@@ -1406,6 +1407,7 @@ class BookKeeping extends CommonObject
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element.$mode;
|
||||
$sql .= " SET ".$field." = ".(is_numeric($value) ? ((float) $value) : "'".$this->db->escape($value)."'");
|
||||
$sql .= " WHERE piece_num = ".((int) $piece_num);
|
||||
$sql .= " AND entity = " . ((int) $conf->entity);
|
||||
|
||||
$resql = $this->db->query($sql);
|
||||
|
||||
@@ -2147,7 +2149,7 @@ class BookKeeping extends CommonObject
|
||||
dol_syslog(get_class($this)."::select_account", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
$obj = '';
|
||||
$obj = (object) array('label' => '');
|
||||
if ($this->db->num_rows($resql)) {
|
||||
$obj = $this->db->fetch_object($resql);
|
||||
}
|
||||
|
||||
@@ -51,6 +51,10 @@ class Lettering extends BookKeeping
|
||||
'table' => 'societe_remise_except',
|
||||
'fk_doc' => 'fk_facture_source',
|
||||
'fk_link' => 'fk_facture',
|
||||
'fk_line_link' => 'fk_facture_line',
|
||||
'table_link_line' => 'facturedet',
|
||||
'fk_table_link_line' => 'rowid',
|
||||
'fk_table_link_line_parent' => 'fk_facture',
|
||||
'prefix' => 'a',
|
||||
'is_fk_link_is_also_fk_doc' => true,
|
||||
),
|
||||
@@ -73,6 +77,10 @@ class Lettering extends BookKeeping
|
||||
'table' => 'societe_remise_except',
|
||||
'fk_doc' => 'fk_invoice_supplier_source',
|
||||
'fk_link' => 'fk_invoice_supplier',
|
||||
'fk_line_link' => 'fk_invoice_supplier_line',
|
||||
'table_link_line' => 'facture_fourn_det',
|
||||
'fk_table_link_line' => 'rowid',
|
||||
'fk_table_link_line_parent' => 'fk_facture_fourn',
|
||||
'prefix' => 'a',
|
||||
'is_fk_link_is_also_fk_doc' => true,
|
||||
),
|
||||
@@ -566,7 +574,7 @@ class Lettering extends BookKeeping
|
||||
|
||||
$grouped_lines = array();
|
||||
foreach (self::$doc_type_infos as $doc_type => $doc_type_info) {
|
||||
if (!is_array($bookkeeping_lines_by_type[$doc_type])) {
|
||||
if (empty($bookkeeping_lines_by_type[$doc_type]) || !is_array($bookkeeping_lines_by_type[$doc_type])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -765,10 +773,26 @@ class Lettering extends BookKeeping
|
||||
$link_by_element = array();
|
||||
$element_by_link = array();
|
||||
foreach ($doc_type_info['linked_info'] as $linked_info) {
|
||||
$sql = "SELECT DISTINCT tl2." . $linked_info['fk_link'] . " AS fk_link, tl2." . $linked_info['fk_doc'] . " AS fk_doc";
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . $linked_info['table'] . " AS tl";
|
||||
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . $linked_info['table'] . " AS tl2 ON tl2." . $linked_info['fk_link'] . " = tl." . $linked_info['fk_link'];
|
||||
$sql .= " WHERE tl." . $linked_info['fk_doc'] . " IN (" . $this->db->sanitize(implode(',', $document_ids)) . ")";
|
||||
if (empty($linked_info['fk_line_link'])) {
|
||||
$sql = "SELECT DISTINCT tl2.".$linked_info['fk_link']." AS fk_link, tl2.".$linked_info['fk_doc']." AS fk_doc";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX.$linked_info['table']." AS tl";
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX.$linked_info['table']." AS tl2 ON tl2.".$linked_info['fk_link']." = tl.".$linked_info['fk_link'];
|
||||
$sql .= " WHERE tl.".$linked_info['fk_doc']." IN (".$this->db->sanitize(implode(',', $document_ids)).")";
|
||||
} else {
|
||||
$sql = "SELECT DISTINCT tl2.fk_link, tl2.fk_doc";
|
||||
$sql .= " FROM (";
|
||||
$sql .= " SELECT DISTINCT " . $this->db->ifsql("tll." . $linked_info['fk_table_link_line_parent'], "tll." . $linked_info['fk_table_link_line_parent'], "tl." . $linked_info['fk_link']) . " AS fk_link, tl." . $linked_info['fk_doc'] . " AS fk_doc";
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . $linked_info['table'] . " AS tl";
|
||||
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . $linked_info['table_link_line'] . " AS tll ON tll." . $linked_info['fk_table_link_line'] . " = tl." . $linked_info['fk_line_link'];
|
||||
$sql .= ") AS tl";
|
||||
$sql .= " LEFT JOIN (";
|
||||
$sql .= " SELECT DISTINCT " . $this->db->ifsql("tll." . $linked_info['fk_table_link_line_parent'], "tll." . $linked_info['fk_table_link_line_parent'], "tl." . $linked_info['fk_link']) . " AS fk_link, tl." . $linked_info['fk_doc'] . " AS fk_doc";
|
||||
$sql .= " FROM " . MAIN_DB_PREFIX . $linked_info['table'] . " AS tl";
|
||||
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . $linked_info['table_link_line'] . " AS tll ON tll." . $linked_info['fk_table_link_line'] . " = tl." . $linked_info['fk_line_link'];
|
||||
$sql .= ") AS tl2 ON tl2.fk_link = tl.fk_link";
|
||||
$sql .= " WHERE tl.fk_doc IN (" . $this->db->sanitize(implode(',', $document_ids)) . ")";
|
||||
$sql .= " AND tl2.fk_doc IS NOT NULL";
|
||||
}
|
||||
|
||||
dol_syslog(__METHOD__ . " - Get document lines", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
|
||||
@@ -212,10 +212,11 @@ if ($result) {
|
||||
$tabtype = array();
|
||||
$tabmoreinfo = array();
|
||||
|
||||
// Loop on each line into llx_bank table. For each line, we should get:
|
||||
// Loop on each line into the llx_bank table. For each line, we should get:
|
||||
// one line tabpay = line into bank
|
||||
// one line for bank record = tabbq
|
||||
// one line for thirdparty record = tabtp
|
||||
// Note: tabcompany is used to store the subledger account
|
||||
$i = 0;
|
||||
while ($i < $num) {
|
||||
$obj = $db->fetch_object($result);
|
||||
@@ -263,7 +264,8 @@ if ($result) {
|
||||
);
|
||||
|
||||
// Set accountancy code for user
|
||||
// $obj->accountancy_code is the accountancy_code of table u=user but it is defined only if a link with type 'user' exists)
|
||||
// $obj->accountancy_code is the accountancy_code of table u=user (but it is defined only if
|
||||
// a link with type 'user' exists and user as a subledger account)
|
||||
$compta_user = (!empty($obj->accountancy_code) ? $obj->accountancy_code : '');
|
||||
|
||||
$tabuser[$obj->rowid] = array(
|
||||
@@ -307,15 +309,25 @@ if ($result) {
|
||||
// get_url may return -1 which is not traversable
|
||||
if (is_array($links) && count($links) > 0) {
|
||||
$is_sc = false;
|
||||
$is_expensereport = false;
|
||||
foreach ($links as $v) {
|
||||
if ($v['type'] == 'sc') {
|
||||
$is_sc = true;
|
||||
break;
|
||||
}
|
||||
if ($v['type'] == 'payment_expensereport') {
|
||||
$is_expensereport = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Now loop on each link of record in bank (code similar to bankentries_list.php)
|
||||
foreach ($links as $key => $val) {
|
||||
if ($links[$key]['type'] == 'user' && !$is_sc) continue;
|
||||
if ($links[$key]['type'] == 'user' && !$is_sc && !$is_expensereport) {
|
||||
// We must avoid as much as possible this "continue". If we want to jump to next loop, it means we don't want to process
|
||||
// the case the link is user (often because managed by hard coded code into another link), and we must avoid this.
|
||||
continue;
|
||||
}
|
||||
if (in_array($links[$key]['type'], array('sc', 'payment_sc', 'payment', 'payment_supplier', 'payment_vat', 'payment_expensereport', 'banktransfert', 'payment_donation', 'member', 'payment_loan', 'payment_salary', 'payment_various'))) {
|
||||
// So we excluded 'company' and 'user' here. We want only payment lines
|
||||
|
||||
@@ -364,13 +376,25 @@ if ($result) {
|
||||
$userstatic->lastname = $tabuser[$obj->rowid]['lastname'];
|
||||
$userstatic->statut = $tabuser[$obj->rowid]['status'];
|
||||
$userstatic->accountancy_code = $tabuser[$obj->rowid]['accountancy_code'];
|
||||
// For a payment of social contribution, we have a link sc + user.
|
||||
// but we already fill the $tabpay[$obj->rowid]["soclib"] in the line 'sc'.
|
||||
// If we fill it here to, we must concat
|
||||
if ($userstatic->id > 0) {
|
||||
$tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0);
|
||||
if ($is_sc) {
|
||||
$tabpay[$obj->rowid]["soclib"] .= ' '.$userstatic->getNomUrl(1, 'accountancy', 0);
|
||||
} else {
|
||||
$tabpay[$obj->rowid]["soclib"] = $userstatic->getNomUrl(1, 'accountancy', 0);
|
||||
}
|
||||
} else {
|
||||
$tabpay[$obj->rowid]["soclib"] = '???'; // Should not happen, but happens with old data when id of user was not saved on expense report payment.
|
||||
}
|
||||
|
||||
if ($compta_user) {
|
||||
$tabtp[$obj->rowid][$compta_user] += $amounttouse;
|
||||
if ($is_sc) {
|
||||
//$tabcompany[$obj->rowid][$compta_user] += $amounttouse;
|
||||
} else {
|
||||
$tabtp[$obj->rowid][$compta_user] += $amounttouse;
|
||||
}
|
||||
}
|
||||
} elseif ($links[$key]['type'] == 'sc') {
|
||||
$chargestatic->id = $links[$key]['url_id'];
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<?php
|
||||
/* Copyright (C) 2007-2010 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2010 Jean Heimburger <jean@tiaris.info>
|
||||
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2013-2023 Alexandre Spangaro <aspangaro@easya.solutions>
|
||||
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
|
||||
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2018 Eric Seigne <eric.seigne@cap-rel.fr>
|
||||
/* Copyright (C) 2007-2010 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2007-2010 Jean Heimburger <jean@tiaris.info>
|
||||
* Copyright (C) 2011 Juanjo Menent <jmenent@2byte.es>
|
||||
* Copyright (C) 2012 Regis Houssin <regis.houssin@inodbox.com>
|
||||
* Copyright (C) 2013-2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
|
||||
* Copyright (C) 2013-2016 Olivier Geffroy <jeff@jeffinfo.com>
|
||||
* Copyright (C) 2013-2016 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2018 Frédéric France <frederic.france@free.fr>
|
||||
* Copyright (C) 2018 Eric Seigne <eric.seigne@cap-rel.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -155,8 +155,8 @@ if ($result) {
|
||||
|
||||
$vatdata = getTaxesFromId($obj->tva_tx.($obj->vat_src_code ? ' ('.$obj->vat_src_code.')' : ''), $mysoc, $mysoc, 0);
|
||||
$compta_tva = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $account_vat);
|
||||
$compta_localtax1 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
|
||||
$compta_localtax2 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva);
|
||||
$compta_localtax1 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $account_vat);
|
||||
$compta_localtax2 = (!empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $account_vat);
|
||||
|
||||
// Define array to display all VAT rates that use this accounting account $compta_tva
|
||||
if (price2num($obj->tva_tx) || !empty($obj->vat_src_code)) {
|
||||
@@ -238,7 +238,7 @@ if ($action == 'writebookkeeping' && !$error) {
|
||||
$db->begin();
|
||||
|
||||
// Error if some lines are not binded/ready to be journalized
|
||||
if ($errorforinvoice[$key] == 'somelinesarenotbound') {
|
||||
if (!empty($errorforinvoice[$key]) && $errorforinvoice[$key] == 'somelinesarenotbound') {
|
||||
$error++;
|
||||
$errorforline++;
|
||||
setEventMessages($langs->trans('ErrorInvoiceContainsLinesNotYetBounded', $val['ref']), null, 'errors');
|
||||
|
||||
@@ -408,7 +408,7 @@ if ($action == 'writebookkeeping') {
|
||||
}
|
||||
|
||||
// Warranty
|
||||
if (!$errorforline) {
|
||||
if (!$errorforline && getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY') && isset($tabwarranty[$key])) {
|
||||
foreach ($tabwarranty[$key] as $k => $mt) {
|
||||
$bookkeeping = new BookKeeping($db);
|
||||
$bookkeeping->doc_date = $val["date"];
|
||||
@@ -649,52 +649,54 @@ if ($action == 'writebookkeeping') {
|
||||
|
||||
// Revenue stamp
|
||||
if (!$errorforline) {
|
||||
foreach ($tabrevenuestamp[$key] as $k => $mt) {
|
||||
if ($mt) {
|
||||
$accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
|
||||
$label_account = $accountingaccount->label;
|
||||
if (isset($tabrevenuestamp[$key])) {
|
||||
foreach ($tabrevenuestamp[$key] as $k => $mt) {
|
||||
if ($mt) {
|
||||
$accountingaccount->fetch(null, $k, true); // TODO Use a cache for label
|
||||
$label_account = $accountingaccount->label;
|
||||
|
||||
$bookkeeping = new BookKeeping($db);
|
||||
$bookkeeping->doc_date = $val["date"];
|
||||
$bookkeeping->date_lim_reglement = $val["datereg"];
|
||||
$bookkeeping->doc_ref = $val["ref"];
|
||||
$bookkeeping->date_creation = $now;
|
||||
$bookkeeping->doc_type = 'customer_invoice';
|
||||
$bookkeeping->fk_doc = $key;
|
||||
$bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
|
||||
$bookkeeping->thirdparty_code = $companystatic->code_client;
|
||||
$bookkeeping = new BookKeeping($db);
|
||||
$bookkeeping->doc_date = $val["date"];
|
||||
$bookkeeping->date_lim_reglement = $val["datereg"];
|
||||
$bookkeeping->doc_ref = $val["ref"];
|
||||
$bookkeeping->date_creation = $now;
|
||||
$bookkeeping->doc_type = 'customer_invoice';
|
||||
$bookkeeping->fk_doc = $key;
|
||||
$bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add
|
||||
$bookkeeping->thirdparty_code = $companystatic->code_client;
|
||||
|
||||
$bookkeeping->subledger_account = '';
|
||||
$bookkeeping->subledger_label = '';
|
||||
$bookkeeping->subledger_account = '';
|
||||
$bookkeeping->subledger_label = '';
|
||||
|
||||
$bookkeeping->numero_compte = $k;
|
||||
$bookkeeping->label_compte = $label_account;
|
||||
$bookkeeping->numero_compte = $k;
|
||||
$bookkeeping->label_compte = $label_account;
|
||||
|
||||
$bookkeeping->label_operation = dol_trunc($companystatic->name, 16).' - '.$invoicestatic->ref.' - '.$langs->trans("RevenueStamp");
|
||||
$bookkeeping->montant = $mt;
|
||||
$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
|
||||
$bookkeeping->debit = ($mt < 0) ? -$mt : 0;
|
||||
$bookkeeping->credit = ($mt >= 0) ? $mt : 0;
|
||||
$bookkeeping->code_journal = $journal;
|
||||
$bookkeeping->journal_label = $langs->transnoentities($journal_label);
|
||||
$bookkeeping->fk_user_author = $user->id;
|
||||
$bookkeeping->entity = $conf->entity;
|
||||
$bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("RevenueStamp");
|
||||
$bookkeeping->montant = $mt;
|
||||
$bookkeeping->sens = ($mt < 0) ? 'D' : 'C';
|
||||
$bookkeeping->debit = ($mt < 0) ? -$mt : 0;
|
||||
$bookkeeping->credit = ($mt >= 0) ? $mt : 0;
|
||||
$bookkeeping->code_journal = $journal;
|
||||
$bookkeeping->journal_label = $langs->transnoentities($journal_label);
|
||||
$bookkeeping->fk_user_author = $user->id;
|
||||
$bookkeeping->entity = $conf->entity;
|
||||
|
||||
$totaldebit += $bookkeeping->debit;
|
||||
$totalcredit += $bookkeeping->credit;
|
||||
$totaldebit += $bookkeeping->debit;
|
||||
$totalcredit += $bookkeeping->credit;
|
||||
|
||||
$result = $bookkeeping->create($user);
|
||||
if ($result < 0) {
|
||||
if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
|
||||
$error++;
|
||||
$errorforline++;
|
||||
$errorforinvoice[$key] = 'alreadyjournalized';
|
||||
//setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
|
||||
} else {
|
||||
$error++;
|
||||
$errorforline++;
|
||||
$errorforinvoice[$key] = 'other';
|
||||
setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
|
||||
$result = $bookkeeping->create($user);
|
||||
if ($result < 0) {
|
||||
if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') { // Already exists
|
||||
$error++;
|
||||
$errorforline++;
|
||||
$errorforinvoice[$key] = 'alreadyjournalized';
|
||||
//setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings');
|
||||
} else {
|
||||
$error++;
|
||||
$errorforline++;
|
||||
$errorforinvoice[$key] = 'other';
|
||||
setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -799,22 +801,24 @@ if ($action == 'exportcsv') { // ISO and not UTF8 !
|
||||
}
|
||||
|
||||
// Warranty
|
||||
foreach ($tabwarranty[$key] as $k => $mt) {
|
||||
//if ($mt) {
|
||||
print '"'.$key.'"'.$sep;
|
||||
print '"'.$date.'"'.$sep;
|
||||
print '"'.$val["ref"].'"'.$sep;
|
||||
print '"'.utf8_decode(dol_trunc($companystatic->name, 32)).'"'.$sep;
|
||||
print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
|
||||
print '"'.length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY')).'"'.$sep;
|
||||
print '"'.length_accounta(html_entity_decode($k)).'"'.$sep;
|
||||
print '"'.$langs->trans("Thirdparty").'"'.$sep;
|
||||
print '"'.utf8_decode(dol_trunc($companystatic->name, 16)).' - '.$invoicestatic->ref.' - '.$langs->trans("Retainedwarranty").'"'.$sep;
|
||||
print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
|
||||
print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
|
||||
print '"'.$journal.'"';
|
||||
print "\n";
|
||||
//}
|
||||
if (getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY') && isset($tabwarranty[$key])) {
|
||||
foreach ($tabwarranty[$key] as $k => $mt) {
|
||||
//if ($mt) {
|
||||
print '"' . $key . '"' . $sep;
|
||||
print '"' . $date . '"' . $sep;
|
||||
print '"' . $val["ref"] . '"' . $sep;
|
||||
print '"' . utf8_decode(dol_trunc($companystatic->name, 32)) . '"' . $sep;
|
||||
print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep;
|
||||
print '"' . length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY')) . '"' . $sep;
|
||||
print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep;
|
||||
print '"' . $langs->trans("Thirdparty") . '"' . $sep;
|
||||
print '"' . utf8_decode(dol_trunc($companystatic->name, 16)) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("Retainedwarranty") . '"' . $sep;
|
||||
print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep;
|
||||
print '"' . ($mt < 0 ? price(-$mt) : '') . '"' . $sep;
|
||||
print '"' . $journal . '"';
|
||||
print "\n";
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
// Third party
|
||||
@@ -888,22 +892,24 @@ if ($action == 'exportcsv') { // ISO and not UTF8 !
|
||||
}
|
||||
|
||||
// Revenue stamp
|
||||
foreach ($tabrevenuestamp[$key] as $k => $mt) {
|
||||
//if ($mt) {
|
||||
print '"'.$key.'"'.$sep;
|
||||
print '"'.$date.'"'.$sep;
|
||||
print '"'.$val["ref"].'"'.$sep;
|
||||
print '"'.utf8_decode(dol_trunc($companystatic->name, 32)).'"'.$sep;
|
||||
print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
|
||||
print '"'.length_accountg(html_entity_decode($k)).'"'.$sep;
|
||||
print '""'.$sep;
|
||||
print '"'.$langs->trans("RevenueStamp").'"'.$sep;
|
||||
print '"'.utf8_decode(dol_trunc($companystatic->name, 16)).' - '.$invoicestatic->ref.' - '.$langs->trans("RevenueStamp").'"'.$sep;
|
||||
print '"'.($mt < 0 ? price(-$mt) : '').'"'.$sep;
|
||||
print '"'.($mt >= 0 ? price($mt) : '').'"'.$sep;
|
||||
print '"'.$journal.'"';
|
||||
print "\n";
|
||||
//}
|
||||
if (isset($tabrevenuestamp[$key])) {
|
||||
foreach ($tabrevenuestamp[$key] as $k => $mt) {
|
||||
//if ($mt) {
|
||||
print '"' . $key . '"' . $sep;
|
||||
print '"' . $date . '"' . $sep;
|
||||
print '"' . $val["ref"] . '"' . $sep;
|
||||
print '"' . utf8_decode(dol_trunc($companystatic->name, 32)) . '"' . $sep;
|
||||
print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep;
|
||||
print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep;
|
||||
print '""' . $sep;
|
||||
print '"' . $langs->trans("RevenueStamp") . '"' . $sep;
|
||||
print '"' . utf8_decode(dol_trunc($companystatic->name, 16)) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("RevenueStamp") . '"' . $sep;
|
||||
print '"' . ($mt < 0 ? price(-$mt) : '') . '"' . $sep;
|
||||
print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep;
|
||||
print '"' . $journal . '"';
|
||||
print "\n";
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1066,33 +1072,35 @@ if (empty($action) || $action == 'view') {
|
||||
}
|
||||
|
||||
// Warranty
|
||||
foreach ($tabwarranty[$key] as $k => $mt) {
|
||||
print '<tr class="oddeven">';
|
||||
print "<!-- Thirdparty warranty -->";
|
||||
print "<td>".$date."</td>";
|
||||
print "<td>".$invoicestatic->getNomUrl(1)."</td>";
|
||||
// Account
|
||||
print "<td>";
|
||||
$accountoshow = length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY'));
|
||||
if (($accountoshow == "") || $accountoshow == 'NotDefined') {
|
||||
print '<span class="error">'.$langs->trans("MainAccountForRetainedWarrantyNotDefined").'</span>';
|
||||
} else {
|
||||
print $accountoshow;
|
||||
if (getDolGlobalString('INVOICE_USE_RETAINED_WARRANTY') && isset($tabwarranty[$key])) {
|
||||
foreach ($tabwarranty[$key] as $k => $mt) {
|
||||
print '<tr class="oddeven">';
|
||||
print "<!-- Thirdparty warranty -->";
|
||||
print "<td>" . $date . "</td>";
|
||||
print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
|
||||
// Account
|
||||
print "<td>";
|
||||
$accountoshow = length_accountg(getDolGlobalString('ACCOUNTING_ACCOUNT_CUSTOMER_RETAINED_WARRANTY'));
|
||||
if (($accountoshow == "") || $accountoshow == 'NotDefined') {
|
||||
print '<span class="error">' . $langs->trans("MainAccountForRetainedWarrantyNotDefined") . '</span>';
|
||||
} else {
|
||||
print $accountoshow;
|
||||
}
|
||||
print '</td>';
|
||||
// Subledger account
|
||||
print "<td>";
|
||||
$accountoshow = length_accounta($k);
|
||||
if (($accountoshow == "") || $accountoshow == 'NotDefined') {
|
||||
print '<span class="error">' . $langs->trans("ThirdpartyAccountNotDefined") . '</span>';
|
||||
} else {
|
||||
print $accountoshow;
|
||||
}
|
||||
print '</td>';
|
||||
print "<td>" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("Retainedwarranty") . "</td>";
|
||||
print '<td class="right nowraponall amount">' . ($mt >= 0 ? price($mt) : '') . "</td>";
|
||||
print '<td class="right nowraponall amount">' . ($mt < 0 ? price(-$mt) : '') . "</td>";
|
||||
print "</tr>";
|
||||
}
|
||||
print '</td>';
|
||||
// Subledger account
|
||||
print "<td>";
|
||||
$accountoshow = length_accounta($k);
|
||||
if (($accountoshow == "") || $accountoshow == 'NotDefined') {
|
||||
print '<span class="error">'.$langs->trans("ThirdpartyAccountNotDefined").'</span>';
|
||||
} else {
|
||||
print $accountoshow;
|
||||
}
|
||||
print '</td>';
|
||||
print "<td>".$companystatic->getNomUrl(0, 'customer', 16).' - '.$invoicestatic->ref.' - '.$langs->trans("Retainedwarranty")."</td>";
|
||||
print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
|
||||
print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
|
||||
print "</tr>";
|
||||
}
|
||||
|
||||
// Third party
|
||||
@@ -1212,27 +1220,29 @@ if (empty($action) || $action == 'view') {
|
||||
}
|
||||
|
||||
// Warranty
|
||||
foreach ($tabrevenuestamp[$key] as $k => $mt) {
|
||||
print '<tr class="oddeven">';
|
||||
print "<!-- Thirdparty revenuestamp -->";
|
||||
print "<td>".$date."</td>";
|
||||
print "<td>".$invoicestatic->getNomUrl(1)."</td>";
|
||||
// Account
|
||||
print "<td>";
|
||||
$accountoshow = length_accountg($k);
|
||||
if (($accountoshow == "") || $accountoshow == 'NotDefined') {
|
||||
print '<span class="error">'.$langs->trans("MainAccountForRevenueStampSaleNotDefined").'</span>';
|
||||
} else {
|
||||
print $accountoshow;
|
||||
if (isset($tabrevenuestamp[$key])) {
|
||||
foreach ($tabrevenuestamp[$key] as $k => $mt) {
|
||||
print '<tr class="oddeven">';
|
||||
print "<!-- Thirdparty revenuestamp -->";
|
||||
print "<td>" . $date . "</td>";
|
||||
print "<td>" . $invoicestatic->getNomUrl(1) . "</td>";
|
||||
// Account
|
||||
print "<td>";
|
||||
$accountoshow = length_accountg($k);
|
||||
if (($accountoshow == "") || $accountoshow == 'NotDefined') {
|
||||
print '<span class="error">' . $langs->trans("MainAccountForRevenueStampSaleNotDefined") . '</span>';
|
||||
} else {
|
||||
print $accountoshow;
|
||||
}
|
||||
print '</td>';
|
||||
// Subledger account
|
||||
print "<td>";
|
||||
print '</td>';
|
||||
print "<td>" . $companystatic->getNomUrl(0, 'customer', 16) . ' - ' . $invoicestatic->ref . ' - ' . $langs->trans("RevenueStamp") . "</td>";
|
||||
print '<td class="right nowraponall amount">' . ($mt < 0 ? price(-$mt) : '') . "</td>";
|
||||
print '<td class="right nowraponall amount">' . ($mt >= 0 ? price($mt) : '') . "</td>";
|
||||
print "</tr>";
|
||||
}
|
||||
print '</td>';
|
||||
// Subledger account
|
||||
print "<td>";
|
||||
print '</td>';
|
||||
print "<td>".$companystatic->getNomUrl(0, 'customer', 16).' - '.$invoicestatic->ref.' - '.$langs->trans("RevenueStamp")."</td>";
|
||||
print '<td class="right nowraponall amount">'.($mt < 0 ? price(-$mt) : '')."</td>";
|
||||
print '<td class="right nowraponall amount">'.($mt >= 0 ? price($mt) : '')."</td>";
|
||||
print "</tr>";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1016,7 +1016,7 @@ if (is_object($objcanvas) && $objcanvas->displayCanvasExists($action)) {
|
||||
$listetype = $adht->liste_array(1);
|
||||
print img_picto('', $adht->picto, 'class="pictofixedwidth"');
|
||||
if (count($listetype)) {
|
||||
print $form->selectarray("typeid", $listetype, (GETPOST('typeid', 'int') ? GETPOST('typeid', 'int') : $typeid), (count($listetype) > 1 ? 1 : 0), 0, 0, '', 0, 0, 0, '', '', 1);
|
||||
print $form->selectarray("typeid", $listetype, (GETPOST('typeid', 'int') ? GETPOST('typeid', 'int') : $typeid), (count($listetype) > 1 ? 1 : 0), 0, 0, '', 0, 0, 0, '', 'minwidth150', 1);
|
||||
} else {
|
||||
print '<span class="error">'.$langs->trans("NoTypeDefinedGoToSetup").'</span>';
|
||||
}
|
||||
|
||||
@@ -3102,6 +3102,7 @@ class Adherent extends CommonObject
|
||||
|
||||
$sql = 'SELECT rowid FROM '.MAIN_DB_PREFIX.'adherent';
|
||||
$sql .= " WHERE entity = ".((int) $conf->entity); // Do not use getEntity('adherent').")" here, we want the batch to be on its entity only;
|
||||
$sql .= " AND statut = 1";
|
||||
$sql .= " AND datefin = '".$this->db->idate($datetosearchfor)."'";
|
||||
//$sql .= " LIMIT 10000";
|
||||
|
||||
|
||||
@@ -348,6 +348,12 @@ class Members extends DolibarrApi
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$member->array_options[$index] = $this->_checkValForAPI($field, $val, $member);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$member->$field = $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,6 +193,12 @@ class MembersTypes extends DolibarrApi
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$membertype->array_options[$index] = $this->_checkValForAPI($field, $val, $membertype);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// Process the status separately because it must be updated using
|
||||
// the validate(), resiliate() and exclude() methods of the class AdherentType.
|
||||
$membertype->$field = $value;
|
||||
|
||||
@@ -186,6 +186,12 @@ class Subscriptions extends DolibarrApi
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$subscription->array_options[$index] = $this->_checkValForAPI($field, $val, $subscription);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$subscription->$field = $value;
|
||||
}
|
||||
|
||||
|
||||
@@ -1431,7 +1431,7 @@ print '</div>'."\n";
|
||||
|
||||
print '</form>'."\n";
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -358,7 +358,7 @@ if ($rowid && $action != 'edit') {
|
||||
print '<div class="tabsAction">';
|
||||
|
||||
if ($user->hasRight('adherent', 'cotisation', 'creer')) {
|
||||
if (!empty($bankline->rappro) || empty($bankline)) {
|
||||
if (empty($bankline->rappro) || empty($bankline)) {
|
||||
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"]."?rowid=".$object->id.'&action=edit&token='.newToken().'">'.$langs->trans("Modify")."</a></div>";
|
||||
} else {
|
||||
print '<div class="inline-block divButAction"><a class="butActionRefused classfortooltip" title="'.$langs->trans("BankLineConciliated").'" href="#">'.$langs->trans("Modify")."</a></div>";
|
||||
|
||||
@@ -66,8 +66,13 @@ if ($reshook < 0) {
|
||||
|
||||
if (($action == 'update' && !GETPOST("cancel", 'alpha'))
|
||||
|| ($action == 'updateedit')) {
|
||||
$tmparray = getCountry(GETPOST('country_id', 'int'), 'all', $db, $langs, 0);
|
||||
$tmparray = getCountry(GETPOSTINT('country_id'), 'all', $db, $langs, 0);
|
||||
if (!empty($tmparray['id'])) {
|
||||
if ($tmparray['code'] == 'FR' && $tmparray['id'] != $mysoc->country_id) {
|
||||
// For FR, default value of option to show profid SIREN is on by default
|
||||
$res = dolibarr_set_const($db, "MAIN_PROFID1_IN_ADDRESS", 1, 'chaine', 0, '', $conf->entity);
|
||||
}
|
||||
|
||||
$mysoc->country_id = $tmparray['id'];
|
||||
$mysoc->country_code = $tmparray['code'];
|
||||
$mysoc->country_label = $tmparray['label'];
|
||||
|
||||
@@ -157,7 +157,7 @@ if ($action == 'updateMask') {
|
||||
setEventMessages($langs->trans("Error"), null, 'errors');
|
||||
}
|
||||
} elseif ($action == "allowonlinesign") {
|
||||
if (!dolibarr_set_const($db, "CONTRACT_ALLOW_ONLINESIGN", $value, 0, 'int', $conf->entity)) {
|
||||
if (!dolibarr_set_const($db, "CONTRACT_ALLOW_ONLINESIGN", $value, 'int', 0, '', $conf->entity)) {
|
||||
$error++;
|
||||
}
|
||||
} elseif (preg_match('/set_(.*)/', $action, $reg)) {
|
||||
|
||||
@@ -2004,6 +2004,11 @@ if ($id > 0) {
|
||||
$canbemodified = 1;
|
||||
}
|
||||
|
||||
if ($tabname[$id] == "c_product_nature" && in_array($obj->code, array(0, 1))) {
|
||||
$canbedisabled = 0;
|
||||
$canbemodified = 0;
|
||||
$iserasable = 0;
|
||||
}
|
||||
// Build Url. The table is id=, the id of line is rowid=
|
||||
$rowidcol = $tabrowid[$id];
|
||||
// If rowidcol not defined
|
||||
|
||||
@@ -728,7 +728,7 @@ print '<br>';
|
||||
|
||||
print '</form>'."\n";
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -43,7 +43,7 @@ if (!$user->admin) {
|
||||
|
||||
$usersignature = $user->signature;
|
||||
// For action = test or send, we ensure that content is not html, even for signature, because for this we want a test with NO html.
|
||||
if ($action == 'test' || ($action == 'send' && $trackid = 'test')) {
|
||||
if ($action == 'test' || ($action == 'send' && $trackid == 'test')) {
|
||||
$usersignature = dol_string_nohtmltag($usersignature, 2);
|
||||
}
|
||||
|
||||
|
||||
@@ -685,7 +685,7 @@ print '</div>'."\n";
|
||||
|
||||
print '</form>'."\n";
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -121,6 +121,13 @@ if ($max_time && $max_time < $max_execution_time_for_deploy) {
|
||||
@ini_set("max_execution_time", $max_execution_time_for_deploy); // This work only if safe mode is off. also web servers has timeout of 300
|
||||
}
|
||||
|
||||
$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
|
||||
$allowonlineinstall = true;
|
||||
$allowfromweb = 1;
|
||||
if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
|
||||
$allowonlineinstall = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Actions
|
||||
@@ -141,7 +148,7 @@ if (GETPOST('buttonreset', 'alpha')) {
|
||||
$search_version = '';
|
||||
}
|
||||
|
||||
if ($action == 'install') {
|
||||
if ($action == 'install' && $allowonlineinstall) {
|
||||
$error = 0;
|
||||
|
||||
// $original_file should match format module_modulename-x.y[.z].zip
|
||||
@@ -262,6 +269,8 @@ if ($action == 'install') {
|
||||
if (!$error) {
|
||||
setEventMessages($langs->trans("SetupIsReadyForUse", DOL_URL_ROOT.'/admin/modules.php?mainmenu=home', $langs->transnoentitiesnoconv("Home").' - '.$langs->transnoentitiesnoconv("Setup").' - '.$langs->transnoentitiesnoconv("Modules")), null, 'warnings');
|
||||
}
|
||||
} elseif ($action == 'install' && !$allowonlineinstall) {
|
||||
httponly_accessforbidden("You try to bypass the protection to disallow deployment of an external module. Hack attempt ?");
|
||||
}
|
||||
|
||||
if ($action == 'set' && $user->admin) {
|
||||
@@ -933,7 +942,12 @@ if ($mode == 'common' || $mode == 'commonkanban') {
|
||||
} else { // Module not yet activated
|
||||
// Set $codeenabledisable
|
||||
if (!empty($objMod->always_enabled)) {
|
||||
// Should never happened
|
||||
// A 'always_enabled' module should not never be disabled. If this happen, we keep a link to reenable it.
|
||||
$codeenabledisable .= '<!-- Message to show: an always_enabled module has been disabled -->'."\n";
|
||||
$codeenabledisable .= '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$objMod->numero.'&token='.newToken().'&module_position='.$module_position.'&action=set&token='.newToken().'&value='.$modName.'&mode='.$mode.$param.'"';
|
||||
$codeenabledisable .= '>';
|
||||
$codeenabledisable .= img_picto($langs->trans("Disabled"), 'switch_off');
|
||||
$codeenabledisable .= "</a>\n";
|
||||
} elseif (!empty($objMod->disabled)) {
|
||||
$codeenabledisable .= $langs->trans("Disabled");
|
||||
} else {
|
||||
@@ -1170,13 +1184,6 @@ if ($mode == 'deploy') {
|
||||
|
||||
print $deschelp;
|
||||
|
||||
$dolibarrdataroot = preg_replace('/([\\/]+)$/i', '', DOL_DATA_ROOT);
|
||||
$allowonlineinstall = true;
|
||||
$allowfromweb = 1;
|
||||
if (dol_is_file($dolibarrdataroot.'/installmodules.lock')) {
|
||||
$allowonlineinstall = false;
|
||||
}
|
||||
|
||||
$fullurl = '<a href="'.$urldolibarrmodules.'" target="_blank" rel="noopener noreferrer">'.$urldolibarrmodules.'</a>';
|
||||
$message = '';
|
||||
if ($allowonlineinstall) {
|
||||
|
||||
@@ -156,253 +156,255 @@ if ($mode == 'setup' && $user->admin) {
|
||||
$oauthstateanticsrf = bin2hex(random_bytes(128/8));
|
||||
|
||||
// $list is defined into oauth.lib.php to the list of supporter OAuth providers.
|
||||
foreach ($listinsetup as $key) {
|
||||
$supported = 0;
|
||||
$keyforsupportedoauth2array = $key[0]; // May be OAUTH_GOOGLE_NAME or OAUTH_GOOGLE_xxx_NAME
|
||||
$keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
|
||||
$keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
|
||||
if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
|
||||
$keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||
$keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
|
||||
} else {
|
||||
$keybeforeprovider = $keyforsupportedoauth2array;
|
||||
$keyforprovider = '';
|
||||
}
|
||||
$keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||
$keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
|
||||
if (!empty($listinsetup)) {
|
||||
foreach ($listinsetup as $key) {
|
||||
$supported = 0;
|
||||
$keyforsupportedoauth2array = $key[0]; // May be OAUTH_GOOGLE_NAME or OAUTH_GOOGLE_xxx_NAME
|
||||
$keyforsupportedoauth2array = preg_replace('/^OAUTH_/', '', $keyforsupportedoauth2array);
|
||||
$keyforsupportedoauth2array = preg_replace('/_NAME$/', '', $keyforsupportedoauth2array);
|
||||
if (preg_match('/^.*-/', $keyforsupportedoauth2array)) {
|
||||
$keybeforeprovider = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||
$keyforprovider = preg_replace('/^.*-/', '', $keyforsupportedoauth2array);
|
||||
} else {
|
||||
$keybeforeprovider = $keyforsupportedoauth2array;
|
||||
$keyforprovider = '';
|
||||
}
|
||||
$keyforsupportedoauth2array = preg_replace('/-.*$/', '', $keyforsupportedoauth2array);
|
||||
$keyforsupportedoauth2array = 'OAUTH_'.$keyforsupportedoauth2array.'_NAME';
|
||||
|
||||
|
||||
$OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
|
||||
$OAUTH_SERVICENAME = (empty($supportedoauth2array[$keyforsupportedoauth2array]['name']) ? 'Unknown' : $supportedoauth2array[$keyforsupportedoauth2array]['name'].($keyforprovider ? '-'.$keyforprovider : ''));
|
||||
|
||||
$shortscope = '';
|
||||
if (getDolGlobalString($key[4])) {
|
||||
$shortscope = getDolGlobalString($key[4]);
|
||||
}
|
||||
$state = $shortscope; // TODO USe a better state
|
||||
$shortscope = '';
|
||||
if (getDolGlobalString($key[4])) {
|
||||
$shortscope = getDolGlobalString($key[4]);
|
||||
}
|
||||
$state = $shortscope; // TODO USe a better state
|
||||
|
||||
// Define $urltorenew, $urltodelete, $urltocheckperms
|
||||
if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
|
||||
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
|
||||
// We pass this param list in to 'state' because we need it before and after the redirect.
|
||||
// Define $urltorenew, $urltodelete, $urltocheckperms
|
||||
if ($keyforsupportedoauth2array == 'OAUTH_GITHUB_NAME') {
|
||||
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
|
||||
// We pass this param list in to 'state' because we need it before and after the redirect.
|
||||
|
||||
// Note: github does not accept csrf key inside the state parameter (only known values)
|
||||
$urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($shortscope).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltocheckperms = 'https://github.com/settings/applications/';
|
||||
} elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
|
||||
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
|
||||
// List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes
|
||||
// We pass this key list into the param 'state' because we need it before and after the redirect.
|
||||
$urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltocheckperms = 'https://security.google.com/settings/security/permissions';
|
||||
} elseif (!empty($supportedoauth2array[$keyforsupportedoauth2array]['returnurl'])) {
|
||||
$urltorenew = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltodelete = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltocheckperms = '';
|
||||
} else {
|
||||
$urltorenew = '';
|
||||
$urltodelete = '';
|
||||
$urltocheckperms = '';
|
||||
}
|
||||
// Note: github does not accept csrf key inside the state parameter (only known values)
|
||||
$urltorenew = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($shortscope).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltodelete = $urlwithroot.'/core/modules/oauth/github_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltocheckperms = 'https://github.com/settings/applications/';
|
||||
} elseif ($keyforsupportedoauth2array == 'OAUTH_GOOGLE_NAME') {
|
||||
// List of keys that will be converted into scopes (from constants 'SCOPE_state_in_uppercase' in file of service).
|
||||
// List of scopes for Google are here: https://developers.google.com/identity/protocols/oauth2/scopes
|
||||
// We pass this key list into the param 'state' because we need it before and after the redirect.
|
||||
$urltorenew = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'-'.$oauthstateanticsrf.'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltodelete = $urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltocheckperms = 'https://security.google.com/settings/security/permissions';
|
||||
} elseif (!empty($supportedoauth2array[$keyforsupportedoauth2array]['returnurl'])) {
|
||||
$urltorenew = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?shortscope='.urlencode($shortscope).'&state='.urlencode($state).'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltodelete = $urlwithroot.$supportedoauth2array[$keyforsupportedoauth2array]['returnurl'].'?action=delete&token='.newToken().'&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php');
|
||||
$urltocheckperms = '';
|
||||
} else {
|
||||
$urltorenew = '';
|
||||
$urltodelete = '';
|
||||
$urltocheckperms = '';
|
||||
}
|
||||
|
||||
if ($urltorenew) {
|
||||
$urltorenew .= '&keyforprovider='.urlencode($keyforprovider);
|
||||
}
|
||||
if ($urltodelete) {
|
||||
$urltodelete .= '&keyforprovider='.urlencode($keyforprovider);
|
||||
}
|
||||
if ($urltorenew) {
|
||||
$urltorenew .= '&keyforprovider='.urlencode($keyforprovider);
|
||||
}
|
||||
if ($urltodelete) {
|
||||
$urltodelete .= '&keyforprovider='.urlencode($keyforprovider);
|
||||
}
|
||||
|
||||
// Show value of token
|
||||
$tokenobj = null;
|
||||
// Token
|
||||
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
||||
// Dolibarr storage
|
||||
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||
try {
|
||||
// $OAUTH_SERVICENAME is for example 'Google-keyforprovider'
|
||||
print '<!-- '.$OAUTH_SERVICENAME.' -->'."\n";
|
||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
||||
//print $storage->token.'<br>';
|
||||
//print $tokenobj->getExtraParams()['id_token'].'<br>';
|
||||
//print $tokenobj->getAccessToken().'<br>';
|
||||
} catch (Exception $e) {
|
||||
// Return an error if token not found
|
||||
//print $e->getMessage();
|
||||
}
|
||||
// Show value of token
|
||||
$tokenobj = null;
|
||||
// Token
|
||||
require_once DOL_DOCUMENT_ROOT.'/includes/OAuth/bootstrap.php';
|
||||
// Dolibarr storage
|
||||
$storage = new DoliStorage($db, $conf, $keyforprovider);
|
||||
try {
|
||||
// $OAUTH_SERVICENAME is for example 'Google-keyforprovider'
|
||||
print '<!-- '.$OAUTH_SERVICENAME.' -->'."\n";
|
||||
$tokenobj = $storage->retrieveAccessToken($OAUTH_SERVICENAME);
|
||||
//print $storage->token.'<br>';
|
||||
//print $tokenobj->getExtraParams()['id_token'].'<br>';
|
||||
//print $tokenobj->getAccessToken().'<br>';
|
||||
} catch (Exception $e) {
|
||||
// Return an error if token not found
|
||||
//print $e->getMessage();
|
||||
}
|
||||
|
||||
// Set other properties
|
||||
$refreshtoken = false;
|
||||
$expiredat = '';
|
||||
// Set other properties
|
||||
$refreshtoken = false;
|
||||
$expiredat = '';
|
||||
|
||||
$expire = false;
|
||||
// Is token expired or will token expire in the next 30 seconds
|
||||
if (is_object($tokenobj)) {
|
||||
$expire = ($tokenobj->getEndOfLife() !== $tokenobj::EOL_NEVER_EXPIRES && $tokenobj->getEndOfLife() !== $tokenobj::EOL_UNKNOWN && time() > ($tokenobj->getEndOfLife() - 30));
|
||||
}
|
||||
if ($key[1] != '' && $key[2] != '') {
|
||||
$expire = false;
|
||||
// Is token expired or will token expire in the next 30 seconds
|
||||
if (is_object($tokenobj)) {
|
||||
$refreshtoken = $tokenobj->getRefreshToken();
|
||||
$expire = ($tokenobj->getEndOfLife() !== $tokenobj::EOL_NEVER_EXPIRES && $tokenobj->getEndOfLife() !== $tokenobj::EOL_UNKNOWN && time() > ($tokenobj->getEndOfLife() - 30));
|
||||
}
|
||||
if ($key[1] != '' && $key[2] != '') {
|
||||
if (is_object($tokenobj)) {
|
||||
$refreshtoken = $tokenobj->getRefreshToken();
|
||||
|
||||
$endoflife = $tokenobj->getEndOfLife();
|
||||
if ($endoflife == $tokenobj::EOL_NEVER_EXPIRES) {
|
||||
$expiredat = $langs->trans("Never");
|
||||
} elseif ($endoflife == $tokenobj::EOL_UNKNOWN) {
|
||||
$expiredat = $langs->trans("Unknown");
|
||||
} else {
|
||||
$expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel');
|
||||
$endoflife = $tokenobj->getEndOfLife();
|
||||
if ($endoflife == $tokenobj::EOL_NEVER_EXPIRES) {
|
||||
$expiredat = $langs->trans("Never");
|
||||
} elseif ($endoflife == $tokenobj::EOL_UNKNOWN) {
|
||||
$expiredat = $langs->trans("Unknown");
|
||||
} else {
|
||||
$expiredat = dol_print_date($endoflife, "dayhour", 'tzuserrel');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$submit_enabled = 0;
|
||||
$submit_enabled = 0;
|
||||
|
||||
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&driver='.$driver.'" autocomplete="off">';
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="action" value="setconst">';
|
||||
print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?mode=setup&driver='.$driver.'" autocomplete="off">';
|
||||
print '<input type="hidden" name="token" value="'.newToken().'">';
|
||||
print '<input type="hidden" name="action" value="setconst">';
|
||||
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">'."\n";
|
||||
print '<div class="div-table-responsive-no-min">';
|
||||
print '<table class="noborder centpercent">'."\n";
|
||||
|
||||
// Api Name
|
||||
$label = $langs->trans($keyforsupportedoauth2array);
|
||||
print '<tr class="liste_titre">';
|
||||
print '<th class="titlefieldcreate">';
|
||||
print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
|
||||
if ($label == $keyforsupportedoauth2array) {
|
||||
print $supportedoauth2array[$keyforsupportedoauth2array]['name'];
|
||||
} else {
|
||||
print $label;
|
||||
}
|
||||
if ($keyforprovider) {
|
||||
print ' (<b>'.$keyforprovider.'</b>)';
|
||||
} else {
|
||||
print ' (<b>'.$langs->trans("NoName").'</b>)';
|
||||
}
|
||||
print '</th>';
|
||||
print '<th></th>';
|
||||
print '<th></th>';
|
||||
print "</tr>\n";
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("OAuthIDSecret").'</td>';
|
||||
print '<td>';
|
||||
print '<span class="opacitymedium">'.$langs->trans("SeePreviousTab").'</span>';
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print '</td>';
|
||||
print '</tr>'."\n";
|
||||
|
||||
// Scopes
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.$langs->trans("Scopes").'</td>';
|
||||
print '<td colspan="2">';
|
||||
$currentscopes = getDolGlobalString($key[4]);
|
||||
print $currentscopes;
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("IsTokenGenerated");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
if (is_object($tokenobj)) {
|
||||
print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : '.dol_print_date($storage->date_modification, 'dayhour').' state='.dol_escape_htmltag($storage->state));
|
||||
} else {
|
||||
print '<span class="opacitymedium">'.$langs->trans("NoAccessToken").'</span>';
|
||||
}
|
||||
print '</td>';
|
||||
print '<td width="50%">';
|
||||
// Links to delete/checks token
|
||||
if (is_object($tokenobj)) {
|
||||
//test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
|
||||
if ($urltodelete) {
|
||||
print '<a class="button smallpaddingimp" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a><br>';
|
||||
// Api Name
|
||||
$label = $langs->trans($keyforsupportedoauth2array);
|
||||
print '<tr class="liste_titre">';
|
||||
print '<th class="titlefieldcreate">';
|
||||
print img_picto('', $supportedoauth2array[$keyforsupportedoauth2array]['picto'], 'class="pictofixedwidth"');
|
||||
if ($label == $keyforsupportedoauth2array) {
|
||||
print $supportedoauth2array[$keyforsupportedoauth2array]['name'];
|
||||
} else {
|
||||
print '<span class="opacitymedium">'.$langs->trans('GoOnTokenProviderToDeleteToken').'</span><br>';
|
||||
print $label;
|
||||
}
|
||||
}
|
||||
// Request remote token
|
||||
if ($urltorenew) {
|
||||
print '<a class="button smallpaddingimp" href="'.$urltorenew.'">'.$langs->trans('GetAccess').'</a>';
|
||||
print $form->textwithpicto('', $langs->trans('RequestAccess'));
|
||||
if ($keyforprovider) {
|
||||
print ' (<b>'.$keyforprovider.'</b>)';
|
||||
} else {
|
||||
print ' (<b>'.$langs->trans("NoName").'</b>)';
|
||||
}
|
||||
print '</th>';
|
||||
print '<th></th>';
|
||||
print '<th></th>';
|
||||
print "</tr>\n";
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("OAuthIDSecret").'</td>';
|
||||
print '<td>';
|
||||
print '<span class="opacitymedium">'.$langs->trans("SeePreviousTab").'</span>';
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
print '</td>';
|
||||
print '</tr>'."\n";
|
||||
|
||||
// Scopes
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.$langs->trans("Scopes").'</td>';
|
||||
print '<td colspan="2">';
|
||||
$currentscopes = getDolGlobalString($key[4]);
|
||||
print $currentscopes;
|
||||
print '</td></tr>';
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("IsTokenGenerated");
|
||||
print '</td>';
|
||||
print '<td>';
|
||||
if (is_object($tokenobj)) {
|
||||
print $form->textwithpicto(yn(1), $langs->trans("HasAccessToken").' : '.dol_print_date($storage->date_modification, 'dayhour').' state='.dol_escape_htmltag($storage->state));
|
||||
} else {
|
||||
print '<span class="opacitymedium">'.$langs->trans("NoAccessToken").'</span>';
|
||||
}
|
||||
print '</td>';
|
||||
print '<td width="50%">';
|
||||
// Links to delete/checks token
|
||||
if (is_object($tokenobj)) {
|
||||
//test on $storage->hasAccessToken($OAUTH_SERVICENAME) ?
|
||||
if ($urltodelete) {
|
||||
print '<a class="button smallpaddingimp" href="'.$urltodelete.'">'.$langs->trans('DeleteAccess').'</a><br>';
|
||||
} else {
|
||||
print '<span class="opacitymedium">'.$langs->trans('GoOnTokenProviderToDeleteToken').'</span><br>';
|
||||
}
|
||||
}
|
||||
// Request remote token
|
||||
if ($urltorenew) {
|
||||
print '<a class="button smallpaddingimp" href="'.$urltorenew.'">'.$langs->trans('GetAccess').'</a>';
|
||||
print $form->textwithpicto('', $langs->trans('RequestAccess'));
|
||||
print '<br>';
|
||||
}
|
||||
// Check remote access
|
||||
if ($urltocheckperms) {
|
||||
print '<br>'.$langs->trans("ToCheckDeleteTokenOnProvider", $OAUTH_SERVICENAME).': <a href="'.$urltocheckperms.'" target="_'.strtolower($OAUTH_SERVICENAME).'">'.$urltocheckperms.'</a>';
|
||||
}
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("Token").'</td>';
|
||||
print '<td colspan="2">';
|
||||
|
||||
if (is_object($tokenobj)) {
|
||||
$tokentoshow = $tokenobj->getAccessToken();
|
||||
print '<span class="" title="'.dol_escape_htmltag($tokentoshow).'">'.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'</span><br>';
|
||||
//print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
|
||||
//print 'EndOfLife: '.$tokenobj->getEndOfLife().'<br>';
|
||||
//var_dump($tokenobj->getExtraParams());
|
||||
/*print '<br>Extra: <br><textarea class="quatrevingtpercent">';
|
||||
print ''.join(',',$tokenobj->getExtraParams());
|
||||
print '</textarea>';*/
|
||||
}
|
||||
print '</td>';
|
||||
print '</tr>'."\n";
|
||||
|
||||
if (is_object($tokenobj)) {
|
||||
// Token refresh
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("TOKEN_REFRESH");
|
||||
print '</td>';
|
||||
print '<td colspan="2">';
|
||||
print '<span class="" title="'.dol_escape_htmltag($refreshtoken).'">'.showValueWithClipboardCPButton($refreshtoken, 1, dol_trunc($refreshtoken, 32)).'</span>';
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Token expired
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("TOKEN_EXPIRED");
|
||||
print '</td>';
|
||||
print '<td colspan="2">';
|
||||
print yn($expire);
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Token expired at
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("TOKEN_EXPIRE_AT");
|
||||
print '</td>';
|
||||
print '<td colspan="2">';
|
||||
print $expiredat;
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
if (!empty($driver)) {
|
||||
if ($submit_enabled) {
|
||||
print $form->buttonsSaveCancel("Modify", '');
|
||||
}
|
||||
}
|
||||
|
||||
print '</form>';
|
||||
print '<br>';
|
||||
}
|
||||
// Check remote access
|
||||
if ($urltocheckperms) {
|
||||
print '<br>'.$langs->trans("ToCheckDeleteTokenOnProvider", $OAUTH_SERVICENAME).': <a href="'.$urltocheckperms.'" target="_'.strtolower($OAUTH_SERVICENAME).'">'.$urltocheckperms.'</a>';
|
||||
}
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("Token").'</td>';
|
||||
print '<td colspan="2">';
|
||||
|
||||
if (is_object($tokenobj)) {
|
||||
$tokentoshow = $tokenobj->getAccessToken();
|
||||
print '<span class="" title="'.dol_escape_htmltag($tokentoshow).'">'.showValueWithClipboardCPButton($tokentoshow, 1, dol_trunc($tokentoshow, 32)).'</span><br>';
|
||||
//print 'Refresh: '.$tokenobj->getRefreshToken().'<br>';
|
||||
//print 'EndOfLife: '.$tokenobj->getEndOfLife().'<br>';
|
||||
//var_dump($tokenobj->getExtraParams());
|
||||
/*print '<br>Extra: <br><textarea class="quatrevingtpercent">';
|
||||
print ''.join(',',$tokenobj->getExtraParams());
|
||||
print '</textarea>';*/
|
||||
}
|
||||
print '</td>';
|
||||
print '</tr>'."\n";
|
||||
|
||||
if (is_object($tokenobj)) {
|
||||
// Token refresh
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("TOKEN_REFRESH");
|
||||
print '</td>';
|
||||
print '<td colspan="2">';
|
||||
print '<span class="" title="'.dol_escape_htmltag($refreshtoken).'">'.showValueWithClipboardCPButton($refreshtoken, 1, dol_trunc($refreshtoken, 32)).'</span>';
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Token expired
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("TOKEN_EXPIRED");
|
||||
print '</td>';
|
||||
print '<td colspan="2">';
|
||||
print yn($expire);
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
|
||||
// Token expired at
|
||||
print '<tr class="oddeven">';
|
||||
print '<td'.(empty($key['required']) ? '' : ' class="required"').'>';
|
||||
//var_dump($key);
|
||||
print $langs->trans("TOKEN_EXPIRE_AT");
|
||||
print '</td>';
|
||||
print '<td colspan="2">';
|
||||
print $expiredat;
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
print '</table>';
|
||||
print '</div>';
|
||||
|
||||
if (!empty($driver)) {
|
||||
if ($submit_enabled) {
|
||||
print $form->buttonsSaveCancel("Modify", '');
|
||||
}
|
||||
}
|
||||
|
||||
print '</form>';
|
||||
print '<br>';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -104,7 +104,9 @@ if ($action == "set") {
|
||||
if (!($res > 0)) {
|
||||
$error++;
|
||||
}
|
||||
} elseif (!$error) {
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$db->commit();
|
||||
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
|
||||
} else {
|
||||
|
||||
@@ -161,7 +161,7 @@ $workflowcodes = array(
|
||||
),
|
||||
|
||||
// Automatic classification reception
|
||||
'WORKFLOW_EXPEDITION_CLASSIFY_CLOSED_INVOICE'=>array(
|
||||
'WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE'=>array(
|
||||
'family'=>'classify_reception',
|
||||
'position'=>95,
|
||||
'enabled'=>(isModEnabled("reception") && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))),
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
/* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
|
||||
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2020 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2025 William Mead <william@m34d.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -174,14 +175,6 @@ class DolibarrApi
|
||||
unset($object->stats_mrptoconsume);
|
||||
unset($object->stats_mrptoproduce);
|
||||
|
||||
unset($object->element);
|
||||
unset($object->element_for_permission);
|
||||
unset($object->fk_element);
|
||||
unset($object->table_element);
|
||||
unset($object->table_element_line);
|
||||
unset($object->class_element_line);
|
||||
unset($object->picto);
|
||||
|
||||
unset($object->fieldsforcombobox);
|
||||
unset($object->regeximgext);
|
||||
|
||||
@@ -202,10 +195,18 @@ class DolibarrApi
|
||||
|
||||
unset($object->prefix_comm);
|
||||
|
||||
if (!isset($object->table_element) || $object->table_element != 'ticket') {
|
||||
if (!isset($object->table_element) || ! in_array($object->table_element, array('expensereport_det', 'ticket'))) {
|
||||
unset($object->comments);
|
||||
}
|
||||
|
||||
unset($object->element);
|
||||
unset($object->element_for_permission);
|
||||
unset($object->fk_element);
|
||||
unset($object->table_element);
|
||||
unset($object->table_element_line);
|
||||
unset($object->class_element_line);
|
||||
unset($object->picto);
|
||||
|
||||
// Remove the $oldcopy property because it is not supported by the JSON
|
||||
// encoder. The following error is generated when trying to serialize
|
||||
// it: "Error encoding/decoding JSON: Type is not supported"
|
||||
|
||||
@@ -81,7 +81,7 @@ class DolibarrApiAccess implements iAuthenticate
|
||||
public function __isAllowed()
|
||||
{
|
||||
// phpcs:enable
|
||||
global $conf, $db, $user;
|
||||
global $conf, $db, $langs, $mysoc, $user;
|
||||
|
||||
$login = '';
|
||||
$stored_key = '';
|
||||
@@ -132,6 +132,56 @@ class DolibarrApiAccess implements iAuthenticate
|
||||
// We must also reload global conf to get params from the entity
|
||||
dol_syslog("Entity was not set on http header with HTTP_DOLAPIENTITY (recommanded for performance purpose), so we switch now on entity of user (".$conf->entity.") and we have to reload configuration.", LOG_WARNING);
|
||||
$conf->setValues($this->db);
|
||||
|
||||
// set global mysoc after setting conf entity (the entity can be changed with the user logged)
|
||||
// see master.inc.php
|
||||
require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
|
||||
|
||||
$fmysoc = new Societe($db);
|
||||
$fmysoc->setMysoc($conf);
|
||||
|
||||
// We set some specific default values according to country
|
||||
if ($fmysoc->country_code == 'DE' && !isset($conf->global->MAIN_INVERT_SENDER_RECIPIENT)) {
|
||||
// For DE, we need to invert our address with customer address
|
||||
$conf->global->MAIN_INVERT_SENDER_RECIPIENT = 1;
|
||||
}
|
||||
if ($fmysoc->country_code == 'FR' && !isset($conf->global->INVOICE_CATEGORY_OF_OPERATION)) {
|
||||
// For FR, default value of option to show category of operations is on by default. Decret n°2099-1299 2022-10-07
|
||||
$conf->global->INVOICE_CATEGORY_OF_OPERATION = 1;
|
||||
}
|
||||
if ($fmysoc->country_code == 'FR' && !isset($conf->global->INVOICE_DISABLE_REPLACEMENT)) {
|
||||
// For FR, the replacement invoice type is not allowed.
|
||||
// From an accounting point of view, this creates holes in the numbering of the invoice.
|
||||
// This is very problematic during a fiscal control.
|
||||
$conf->global->INVOICE_DISABLE_REPLACEMENT = 1;
|
||||
}
|
||||
if ($fmysoc->country_code == 'GR' && !isset($conf->global->INVOICE_DISABLE_REPLACEMENT)) {
|
||||
// The replacement invoice type is not allowed in Greece.
|
||||
$conf->global->INVOICE_DISABLE_REPLACEMENT = 1;
|
||||
}
|
||||
if ($fmysoc->country_code == 'GR' && !isset($conf->global->INVOICE_DISABLE_DEPOSIT)) {
|
||||
// The deposit invoice type is not allowed in Greece.
|
||||
$conf->global->INVOICE_DISABLE_DEPOSIT = 1;
|
||||
}
|
||||
|
||||
if (($fmysoc->localtax1_assuj || $fmysoc->localtax2_assuj) && !isset($conf->global->MAIN_NO_INPUT_PRICE_WITH_TAX)) {
|
||||
// For countries using the 2nd or 3rd tax, we disable input/edit of lines using the price including tax (because 2nb and 3rd tax not yet taken into account).
|
||||
// Work In Progress to support all taxes into unit price entry when MAIN_UNIT_PRICE_WITH_TAX_IS_FOR_ALL_TAXES is set.
|
||||
$conf->global->MAIN_NO_INPUT_PRICE_WITH_TAX = 1;
|
||||
}
|
||||
// Set also the global variable $mysoc
|
||||
$mysoc = $fmysoc;
|
||||
|
||||
// Reload langs
|
||||
$langcode = (empty($conf->global->MAIN_LANG_DEFAULT) ? 'auto' : $conf->global->MAIN_LANG_DEFAULT);
|
||||
if (!empty($user->conf->MAIN_LANG_DEFAULT)) {
|
||||
$langcode = $user->conf->MAIN_LANG_DEFAULT;
|
||||
}
|
||||
if ($langs->getDefaultLang() != $langcode) {
|
||||
$langs->setDefaultLang($langcode);
|
||||
$langs->tab_translate = array();
|
||||
$langs->loadLangs(array('main'));
|
||||
}
|
||||
}
|
||||
} elseif ($nbrows > 1) {
|
||||
throw new RestException(503, 'Error when fetching user api_key : More than 1 user with this apikey');
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
|
||||
* Copyright (C) 2016 Jean-François Ferry <jfefe@aternatik.fr>
|
||||
* Copyright (C) 2023 Romain Neil <contact@romain-neil.fr>
|
||||
* Copyright (C) 2025 William Mead <william@m34d.com>
|
||||
*
|
||||
* This program is free software you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -481,7 +482,7 @@ class Documents extends DolibarrApi
|
||||
} elseif ($modulepart == 'expensereport') {
|
||||
require_once DOL_DOCUMENT_ROOT.'/expensereport/class/expensereport.class.php';
|
||||
|
||||
if (!DolibarrApiAccess::$user->rights->expensereport->read && !DolibarrApiAccess::$user->rights->expensereport->read) {
|
||||
if (!DolibarrApiAccess::$user->rights->expensereport->lire) {
|
||||
throw new RestException(401);
|
||||
}
|
||||
|
||||
@@ -580,8 +581,10 @@ class Documents extends DolibarrApi
|
||||
} elseif (is_array($ecmfile->lines) && count($ecmfile->lines) > 0) {
|
||||
$count = count($filearray);
|
||||
for ($i = 0 ; $i < $count ; $i++) {
|
||||
if ($filearray[$i]['name'] == $ecmfile->lines[$i]->filename) {
|
||||
$filearray[$i] = array_merge($filearray[$i], (array) $ecmfile->lines[0]);
|
||||
foreach ($ecmfile->lines as $line) {
|
||||
if ($filearray[$i]['name'] == $line->filename) {
|
||||
$filearray[$i] = array_merge($filearray[$i], (array) $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -888,7 +891,7 @@ class Documents extends DolibarrApi
|
||||
// Move the temporary file at its final emplacement
|
||||
$result = dol_move($destfiletmp, $dest_file, 0, $overwriteifexists, 1, 1, $moreinfo);
|
||||
if (!$result) {
|
||||
throw new RestException(500, "Failed to move file into '".$destfile."'");
|
||||
throw new RestException(500, "Failed to move file into '".$dest_file."'");
|
||||
}
|
||||
|
||||
return dol_basename($destfile);
|
||||
|
||||
@@ -165,6 +165,10 @@ class Login
|
||||
$token = $tmpuser->api_key;
|
||||
}
|
||||
|
||||
if (!ascii_check($token)) {
|
||||
throw new RestException(500, 'Error the token for this user has not an hexa format. Try first to reset it.');
|
||||
}
|
||||
|
||||
//return token
|
||||
return array(
|
||||
'success' => array(
|
||||
|
||||
@@ -271,9 +271,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea
|
||||
$disposal_type_form = $object->showInputField(null, 'fk_disposal_type', $fk_disposal_type, '', '', '', 0);
|
||||
$object->fields['fk_disposal_type']['visible'] = -2;
|
||||
|
||||
$object->fields['disposal_invoice_id'] = array('type' => 'integer:Facture:compta/facture/class/facture.class.php::entity IN (__SHARED_ENTITIES__)', 'enabled' => '1', 'notnull' => 1, 'visible' => 1, 'index' => 1, 'validate' => '1',);
|
||||
$disposal_invoice_form = $object->showInputField(null, 'disposal_invoice_id', $disposal_invoice_id, '', '', '', 0);
|
||||
unset($object->fields['disposal_invoice_id']);
|
||||
$disposal_invoice_form = $form->selectForForms('Facture:compta/facture/class/facture.class.php::(entity:IN:__SHARED_ENTITIES__)', 'disposal_invoice_id', $disposal_invoice_id);
|
||||
|
||||
// Create an array for form
|
||||
$formquestion = array(
|
||||
|
||||
@@ -863,7 +863,7 @@ class Asset extends CommonObject
|
||||
// Get fiscal period
|
||||
require_once DOL_DOCUMENT_ROOT . '/core/lib/date.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT . '/core/lib/accounting.lib.php';
|
||||
$dates = getDefaultDatesForTransfer();
|
||||
$dates = getCurrentPeriodOfFiscalYear($this->db, $conf, $this->date_start > $this->date_acquisition ? $this->date_start : $this->date_acquisition);
|
||||
$init_fiscal_period_start = $dates['date_start'];
|
||||
$init_fiscal_period_end = $dates['date_end'];
|
||||
if (empty($init_fiscal_period_start) || empty($init_fiscal_period_end)) {
|
||||
@@ -999,7 +999,7 @@ class Asset extends CommonObject
|
||||
//-----------------------------------------------------
|
||||
$nb_days_in_year = !empty($conf->global->ASSET_DEPRECIATION_DURATION_PER_YEAR) ? $conf->global->ASSET_DEPRECIATION_DURATION_PER_YEAR : 365;
|
||||
$nb_days_in_month = !empty($conf->global->ASSET_DEPRECIATION_DURATION_PER_MONTH) ? $conf->global->ASSET_DEPRECIATION_DURATION_PER_MONTH : 30;
|
||||
$period_amount = (double) price2num($depreciation_period_amount / $fields['duration'], 'MT');
|
||||
$period_amount = (float) ($fields['duration'] > 0 ? price2num($depreciation_period_amount / $fields['duration'], 'MT') : 0);
|
||||
$first_period_found = false;
|
||||
$first_period_date = isset($begin_period) && $begin_period > $fiscal_period_start ? $begin_period : $fiscal_period_start;
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ class AssetDepreciationOptions extends CommonObject
|
||||
// Unset required option (notnull) if field disabled
|
||||
if (!empty($field_info['enabled_field'])) {
|
||||
$info = explode(':', $field_info['enabled_field']);
|
||||
if ($this->deprecation_options[$info[0]][$info[1]] != $info[2] && isset($this->fields[$field_key]['notnull'])) {
|
||||
if (!empty($this->deprecation_options[$info[0]][$info[1]]) && $this->deprecation_options[$info[0]][$info[1]] != $info[2] && isset($this->fields[$field_key]['notnull'])) {
|
||||
unset($this->fields[$field_key]['notnull']);
|
||||
}
|
||||
}
|
||||
@@ -285,7 +285,7 @@ class AssetDepreciationOptions extends CommonObject
|
||||
foreach ($this->deprecation_options_fields as $mode_key => $mode_info) {
|
||||
if (!empty($mode_info['enabled_field'])) {
|
||||
$info = explode(':', $mode_info['enabled_field']);
|
||||
if ($deprecation_options[$info[0]][$info[1]] != $info[2]) {
|
||||
if (!empty($this->deprecation_options[$info[0]][$info[1]]) && $deprecation_options[$info[0]][$info[1]] != $info[2]) {
|
||||
unset($deprecation_options[$info[0]][$info[1]]);
|
||||
}
|
||||
}
|
||||
@@ -356,7 +356,7 @@ class AssetDepreciationOptions extends CommonObject
|
||||
foreach ($this->deprecation_options_fields as $mode_key => $mode_info) {
|
||||
if (!empty($mode_info['enabled_field'])) {
|
||||
$info = explode(':', $mode_info['enabled_field']);
|
||||
if ($deprecation_options[$info[0]][$info[1]] != $info[2]) {
|
||||
if (!empty($this->deprecation_options[$info[0]][$info[1]]) && $deprecation_options[$info[0]][$info[1]] != $info[2]) {
|
||||
unset($deprecation_options[$info[0]][$info[1]]);
|
||||
}
|
||||
}
|
||||
@@ -469,7 +469,7 @@ class AssetDepreciationOptions extends CommonObject
|
||||
if (!$error && !empty($this->deprecation_options[$mode_key])) {
|
||||
if (!empty($mode_info['enabled_field'])) {
|
||||
$info = explode(':', $mode_info['enabled_field']);
|
||||
if ($this->deprecation_options[$info[0]][$info[1]] != $info[2]) {
|
||||
if (!empty($this->deprecation_options[$info[0]][$info[1]]) && $this->deprecation_options[$info[0]][$info[1]] != $info[2]) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -654,7 +654,7 @@ print '</div>'."\n";
|
||||
|
||||
print '</form>'."\n";
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -660,7 +660,7 @@ print '</div>'."\n";
|
||||
|
||||
print '</form>'."\n";
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -108,6 +108,7 @@ if ($action == 'initbarcodethirdparties') {
|
||||
$nbok = 0;
|
||||
if (!empty($eraseallthirdpartybarcode)) {
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."societe";
|
||||
$sql .= " AND entity IN (".getEntity('societe').")";
|
||||
$sql .= " SET barcode = NULL";
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
@@ -120,6 +121,7 @@ if ($action == 'initbarcodethirdparties') {
|
||||
$sql = "SELECT rowid";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."societe";
|
||||
$sql .= " WHERE barcode IS NULL or barcode = ''";
|
||||
$sql .= " AND entity IN (".getEntity('societe').")";
|
||||
$sql .= $db->order("datec", "ASC");
|
||||
$sql .= $db->plimit($maxperinit);
|
||||
|
||||
@@ -211,6 +213,7 @@ if ($action == 'initbarcodeproducts') {
|
||||
if (!empty($eraseallproductbarcode)) {
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."product";
|
||||
$sql .= " SET barcode = NULL";
|
||||
$sql .= " WHERE entity IN (".getEntity('product').")";
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
setEventMessages($langs->trans("AllBarcodeReset"), null, 'mesgs');
|
||||
@@ -222,6 +225,7 @@ if ($action == 'initbarcodeproducts') {
|
||||
$sql = "SELECT rowid, ref, fk_product_type";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."product";
|
||||
$sql .= " WHERE barcode IS NULL or barcode = ''";
|
||||
$sql .= " AND entity IN (".getEntity('product').")";
|
||||
$sql .= $db->order("datec", "ASC");
|
||||
$sql .= $db->plimit($maxperinit);
|
||||
|
||||
@@ -322,6 +326,7 @@ if (isModEnabled('societe')) {
|
||||
}
|
||||
|
||||
$sql = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."societe";
|
||||
$sql .= " WHERE entity IN (".getEntity('societe').")";
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
$obj = $db->fetch_object($resql);
|
||||
@@ -376,6 +381,7 @@ if (isModEnabled('product') || isModEnabled('service')) {
|
||||
$sql = "SELECT count(rowid) as nb, fk_product_type, datec";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."product";
|
||||
$sql .= " WHERE barcode IS NULL OR barcode = ''";
|
||||
$sql .= " AND entity IN (".getEntity('product').")";
|
||||
$sql .= " GROUP BY fk_product_type, datec";
|
||||
$sql .= " ORDER BY datec";
|
||||
$resql = $db->query($sql);
|
||||
@@ -394,6 +400,7 @@ if (isModEnabled('product') || isModEnabled('service')) {
|
||||
}
|
||||
|
||||
$sql = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."product";
|
||||
$sql .= " WHERE entity IN (".getEntity('product').")";
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
$obj = $db->fetch_object($resql);
|
||||
|
||||
@@ -255,10 +255,18 @@ if ($action == 'builddoc') {
|
||||
|
||||
if (!$mesg) {
|
||||
$outputlangs = $langs;
|
||||
$previousConf = getDolGlobalInt('TCPDF_THROW_ERRORS_INSTEAD_OF_DIE');
|
||||
$conf->global->TCPDF_THROW_ERRORS_INSTEAD_OF_DIE = 1;
|
||||
|
||||
|
||||
// This generates and send PDF to output
|
||||
// TODO Move
|
||||
$result = doc_label_pdf_create($db, $arrayofrecords, $modellabel, $outputlangs, $diroutput, $template, dol_sanitizeFileName($outfile));
|
||||
try {
|
||||
$result = doc_label_pdf_create($db, $arrayofrecords, $modellabel, $outputlangs, $diroutput, $template, dol_sanitizeFileName($outfile));
|
||||
} catch (Exception $e) {
|
||||
$mesg = $langs->trans('ErrorGeneratingBarcode');
|
||||
}
|
||||
$conf->global->TCPDF_THROW_ERRORS_INSTEAD_OF_DIE = $previousConf;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,7 +321,7 @@ foreach (array_keys($_Avery_Labels) as $codecards) {
|
||||
$arrayoflabels[$codecards] = $labeltoshow;
|
||||
}
|
||||
asort($arrayoflabels);
|
||||
print $form->selectarray('modellabel', $arrayoflabels, (GETPOST('modellabel') ?GETPOST('modellabel') : $conf->global->ADHERENT_ETIQUETTE_TYPE), 1, 0, 0, '', 0, 0, 0, '', '', 1);
|
||||
print $form->selectarray('modellabel', $arrayoflabels, (GETPOST('modellabel') ? GETPOST('modellabel') : getDolGlobalString('ADHERENT_ETIQUETTE_TYPE')), 1, 0, 0, '', 0, 0, 0, '', '', 1);
|
||||
print '</div></div>';
|
||||
|
||||
// Number of stickers to print
|
||||
|
||||
@@ -814,7 +814,7 @@ print '</div>'."\n";
|
||||
print '</form>'."\n";
|
||||
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -240,6 +240,12 @@ class Boms extends DolibarrApi
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$this->bom->array_options[$index] = $this->_checkValForAPI($field, $val, $this->bom);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$this->bom->$field = $value;
|
||||
}
|
||||
|
||||
@@ -350,7 +356,8 @@ class Boms extends DolibarrApi
|
||||
$request_data->efficiency,
|
||||
$request_data->position,
|
||||
$request_data->fk_bom_child,
|
||||
$request_data->import_key
|
||||
$request_data->import_key,
|
||||
$request_data->fk_unit
|
||||
);
|
||||
|
||||
if ($updateRes > 0) {
|
||||
@@ -395,7 +402,8 @@ class Boms extends DolibarrApi
|
||||
$request_data->disable_stock_change,
|
||||
$request_data->efficiency,
|
||||
$request_data->position,
|
||||
$request_data->import_key
|
||||
$request_data->import_key,
|
||||
$request_data->fk_unit
|
||||
);
|
||||
|
||||
if ($updateRes > 0) {
|
||||
|
||||
@@ -1739,13 +1739,25 @@ class BOMLine extends CommonObjectLine
|
||||
* @var string description
|
||||
*/
|
||||
public $description;
|
||||
|
||||
/**
|
||||
* @var double qty
|
||||
*/
|
||||
public $qty;
|
||||
|
||||
/**
|
||||
* @var int qty frozen
|
||||
*/
|
||||
public $qty_frozen;
|
||||
|
||||
/**
|
||||
* @var int disable stock change
|
||||
*/
|
||||
public $disable_stock_change;
|
||||
|
||||
/**
|
||||
* @var double efficiency
|
||||
*/
|
||||
public $efficiency;
|
||||
|
||||
/**
|
||||
@@ -1769,12 +1781,16 @@ class BOMLine extends CommonObjectLine
|
||||
*/
|
||||
public $unit_cost = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @var Bom array of Bom in line
|
||||
*/
|
||||
public $childBom = array();
|
||||
|
||||
/**
|
||||
* @var int Service unit
|
||||
*/
|
||||
public $fk_unit;
|
||||
|
||||
/**
|
||||
* @var int Service Workstation
|
||||
*/
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
/* Copyright (C) 2019 Maxime Kohlhaas <maxime@atm-consulting.fr>
|
||||
* Copyright (C) 2019-2021 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2019-2023 Frédéric France <frederic.france@netlogic.fr>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -113,7 +113,7 @@ function bomPrepareHead($object)
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/link.class.php';
|
||||
$upload_dir = $conf->bom->dir_output."/bom/".dol_sanitizeFileName($object->ref);
|
||||
$upload_dir = $conf->bom->dir_output."/".dol_sanitizeFileName($object->ref);
|
||||
$nbFiles = count(dol_dir_list($upload_dir, 'files', 0, '', '(\.meta|_preview.*\.png)$'));
|
||||
$nbLinks = Link::count($db, $object->element, $object->id);
|
||||
$head[$h][0] = DOL_URL_ROOT.'/bom/bom_document.php?id='.$object->id;
|
||||
|
||||
@@ -769,7 +769,7 @@ print '</div>'."\n";
|
||||
|
||||
print '</form>'."\n";
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -769,7 +769,7 @@ print '</div>'."\n";
|
||||
|
||||
print '</form>'."\n";
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -237,6 +237,12 @@ class Categories extends DolibarrApi
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$this->category->array_options[$index] = $this->_checkValForAPI($field, $val, $this->category);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$this->category->$field = $value;
|
||||
}
|
||||
|
||||
@@ -267,8 +273,8 @@ class Categories extends DolibarrApi
|
||||
throw new RestException(401, 'Access not allowed for login '.DolibarrApiAccess::$user->login);
|
||||
}
|
||||
|
||||
if (!$this->category->delete(DolibarrApiAccess::$user)) {
|
||||
throw new RestException(401, 'error when delete category');
|
||||
if ($this->category->delete(DolibarrApiAccess::$user) <= 0) {
|
||||
throw new RestException(500, 'Error when delete category : ' . $this->category->error);
|
||||
}
|
||||
|
||||
return array(
|
||||
|
||||
@@ -131,7 +131,7 @@ $cancel != $langs->trans("Cancel") &&
|
||||
|
||||
foreach ($object->multilangs as $key => $value) { // recording of new values in the object
|
||||
$libelle = GETPOST('libelle-'.$key, 'alpha');
|
||||
$desc = GETPOST('desc-'.$key);
|
||||
$desc = GETPOST('desc-'.$key, 'restricthtml');
|
||||
|
||||
if (empty($libelle)) {
|
||||
$error++;
|
||||
|
||||
@@ -270,11 +270,11 @@ if (empty($reshook) && $action == 'add') {
|
||||
if ($fulldayevent) {
|
||||
$tzforfullday = getDolGlobalString('MAIN_STORE_FULL_EVENT_IN_GMT');
|
||||
// For "full day" events, we must store date in GMT (It must be viewed as same moment everywhere)
|
||||
$datep = dol_mktime($fulldayevent ? '00' : GETPOST("aphour", 'int'), $fulldayevent ? '00' : GETPOST("apmin", 'int'), $fulldayevent ? '00' : GETPOST("apsec", 'int'), GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int'), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
||||
$datef = dol_mktime($fulldayevent ? '23' : GETPOST("p2hour", 'int'), $fulldayevent ? '59' : GETPOST("p2min", 'int'), $fulldayevent ? '59' : GETPOST("apsec", 'int'), GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int'), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
||||
$datep = dol_mktime('00', '00', '00', GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int'), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
||||
$datef = dol_mktime('23', '59', '59', GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int'), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
||||
} else {
|
||||
$datep = dol_mktime($fulldayevent ? '00' : GETPOST("aphour", 'int'), $fulldayevent ? '00' : GETPOST("apmin", 'int'), $fulldayevent ? '00' : GETPOST("apsec", 'int'), GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int'), 'tzuserrel');
|
||||
$datef = dol_mktime($fulldayevent ? '23' : GETPOST("p2hour", 'int'), $fulldayevent ? '59' : GETPOST("p2min", 'int'), $fulldayevent ? '59' : GETPOST("apsec", 'int'), GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int'), 'tzuserrel');
|
||||
$datep = dol_mktime(GETPOST("aphour", 'int'), GETPOST("apmin", 'int'), GETPOST("apsec", 'int'), GETPOST("apmonth", 'int'), GETPOST("apday", 'int'), GETPOST("apyear", 'int'), 'tzuserrel');
|
||||
$datef = dol_mktime(GETPOST("p2hour", 'int'), GETPOST("p2min", 'int'), GETPOST("apsec", 'int'), GETPOST("p2month", 'int'), GETPOST("p2day", 'int'), GETPOST("p2year", 'int'), 'tzuserrel');
|
||||
}
|
||||
|
||||
// Check parameters
|
||||
@@ -769,7 +769,8 @@ if (empty($reshook) && $action == 'update') {
|
||||
}
|
||||
|
||||
if (!$datef && $percentage == 100) {
|
||||
$error++; $donotclearsession = 1;
|
||||
$error++;
|
||||
$donotclearsession = 1;
|
||||
setEventMessages($langs->transnoentitiesnoconv("ErrorFieldRequired", $langs->transnoentitiesnoconv("DateEnd")), $object->errors, 'errors');
|
||||
$action = 'edit';
|
||||
}
|
||||
@@ -901,15 +902,19 @@ if (empty($reshook) && $action == 'update') {
|
||||
$object->setCategories($categories);
|
||||
|
||||
$object->loadReminders($remindertype, 0, false);
|
||||
if (!empty($object->reminders) && $object->datep > dol_now()) {
|
||||
|
||||
// If there is reminders, we remove them
|
||||
if (!empty($object->reminders)) {
|
||||
foreach ($object->reminders as $reminder) {
|
||||
$reminder->delete($user);
|
||||
if ($reminder->status < 1) { // If already sent, we never remove it
|
||||
$reminder->delete($user);
|
||||
}
|
||||
}
|
||||
$object->reminders = array();
|
||||
}
|
||||
|
||||
//Create reminders
|
||||
if ($addreminder == 'on' && $object->datep > dol_now()) {
|
||||
// Create reminders for every assigned user if reminder is on
|
||||
if ($addreminder == 'on') {
|
||||
$actionCommReminder = new ActionCommReminder($db);
|
||||
|
||||
$dateremind = dol_time_plus_duree($datep, -$offsetvalue, $offsetunit);
|
||||
@@ -995,7 +1000,7 @@ if (empty($reshook) && GETPOST('actionmove', 'alpha') == 'mupdate') {
|
||||
|
||||
$newdate = GETPOST('newdate', 'alpha');
|
||||
if (empty($newdate) || strpos($newdate, 'dayevent_') != 0) {
|
||||
header("Location: ".$backtopage);
|
||||
header("Location: ".$backtopage, true, 307);
|
||||
exit;
|
||||
}
|
||||
|
||||
@@ -1080,7 +1085,7 @@ if (empty($reshook) && GETPOST('actionmove', 'alpha') == 'mupdate') {
|
||||
}
|
||||
}
|
||||
if (!empty($backtopage)) {
|
||||
header("Location: ".$backtopage);
|
||||
header("Location: ".$backtopage, true, 307);
|
||||
exit;
|
||||
} else {
|
||||
$action = '';
|
||||
@@ -1441,8 +1446,14 @@ if ($action == 'create') {
|
||||
$preselectedids[GETPOST('contactid', 'int')] = GETPOST('contactid', 'int');
|
||||
}
|
||||
if ($origin=='contact') $preselectedids[GETPOST('originid', 'int')] = GETPOST('originid', 'int');
|
||||
// select "all" or "none" contact by default
|
||||
if (getDolGlobalInt('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT')) {
|
||||
$select_contact_default = 0; // select "all" contacts by default : avoid to use it if there is a lot of contacts
|
||||
} else {
|
||||
$select_contact_default = -1; // select "none" by default
|
||||
}
|
||||
print img_picto('', 'contact', 'class="paddingrightonly"');
|
||||
print $form->selectcontacts(empty($conf->global->MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT) ? GETPOST('socid', 'int') : 0, $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'minwidth300 quatrevingtpercent', false, 0, array(), false, 'multiple', 'contactid');
|
||||
print $form->selectcontacts(GETPOSTISSET('socid') ? GETPOSTINT('socid') : $select_contact_default, $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'minwidth300 quatrevingtpercent', false, 0, array(), false, 'multiple', 'contactid');
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
@@ -1949,7 +1960,12 @@ if ($id > 0) {
|
||||
// related contact
|
||||
print '<tr><td>'.$langs->trans("ActionOnContact").'</td><td>';
|
||||
print '<div class="maxwidth200onsmartphone">';
|
||||
print img_picto('', 'contact', 'class="paddingrightonly"').$form->selectcontacts(empty($conf->global->MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT) ? $object->socid : 0, array_keys($object->socpeopleassigned), 'socpeopleassigned[]', 1, '', '', 1, 'quatrevingtpercent', false, 0, 0, array(), 'multiple', 'contactid');
|
||||
if (getDolGlobalInt('MAIN_ACTIONCOM_CAN_ADD_ANY_CONTACT')) {
|
||||
$select_contact_default = 0; // select "all" contacts by default : avoid to use it if there is a lot of contacts
|
||||
} else {
|
||||
$select_contact_default = -1; // select "none" by default
|
||||
}
|
||||
print img_picto('', 'contact', 'class="paddingrightonly"').$form->selectcontacts(!empty($object->socid) ? $object->socid : $select_contact_default, array_keys($object->socpeopleassigned), 'socpeopleassigned[]', 1, '', '', 1, 'quatrevingtpercent', false, 0, 0, array(), 'multiple', 'contactid');
|
||||
print '</div>';
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
@@ -2056,8 +2072,12 @@ if ($id > 0) {
|
||||
$actionCommReminder->offsetunit = 'i';
|
||||
$actionCommReminder->typeremind = 'email';
|
||||
}
|
||||
$disabled = '';
|
||||
if ($object->datep < dol_now()) {
|
||||
//$disabled = 'disabled title="'.dol_escape_htmltag($langs->trans("EventExpired")).'"';
|
||||
}
|
||||
|
||||
print '<label for="addreminder">'.img_picto('', 'bell', 'class="pictofixedwidth"').$langs->trans("AddReminder").'</label> <input type="checkbox" id="addreminder" name="addreminder" '.$checked.'><br>';
|
||||
print '<label for="addreminder">'.img_picto('', 'bell', 'class="pictofixedwidth"').$langs->trans("AddReminder").'</label> <input type="checkbox" id="addreminder" name="addreminder"'.($checked ? ' '.$checked : '').($disabled ? ' '.$disabled : '').'><br>';
|
||||
|
||||
print '<div class="reminderparameters" '.(empty($checked) ? 'style="display: none;"' : '').'>';
|
||||
|
||||
@@ -2447,6 +2467,7 @@ if ($id > 0) {
|
||||
print ' ('.$tmpuserstatic->getNomUrl(0, '', 0, 0, 16).')';
|
||||
}
|
||||
print ' - '.$actioncommreminder->offsetvalue.' '.$TDurationTypes[$actioncommreminder->offsetunit];
|
||||
|
||||
if ($actioncommreminder->status == $actioncommreminder::STATUS_TODO) {
|
||||
print ' - <span class="opacitymedium">';
|
||||
print $langs->trans("NotSent");
|
||||
@@ -2455,6 +2476,10 @@ if ($id > 0) {
|
||||
print ' - <span class="opacitymedium">';
|
||||
print $langs->trans("Done");
|
||||
print ' </span>';
|
||||
} elseif ($actioncommreminder->status == $actioncommreminder::STATUS_ERROR) {
|
||||
print ' - <span class="opacitymedium">';
|
||||
print $form->textwithpicto($langs->trans("Error"), $actioncommreminder->lasterror);
|
||||
print ' </span>';
|
||||
}
|
||||
print '<br>';
|
||||
}
|
||||
|
||||
@@ -619,7 +619,7 @@ class ActionComm extends CommonObject
|
||||
foreach ($this->userassigned as $key => $val) {
|
||||
// Common value with new behavior is to have $val = array('id'=>iduser, 'transparency'=>0|1) and $this->userassigned is an array of iduser => $val.
|
||||
if (!is_array($val)) { // For backward compatibility when $val='id'.
|
||||
$val = array('id'=>$val);
|
||||
$val = array('id' => $val);
|
||||
}
|
||||
|
||||
if ($val['id'] > 0) {
|
||||
@@ -841,9 +841,6 @@ class ActionComm extends CommonObject
|
||||
$this->type_color = $obj->type_color;
|
||||
$this->type_picto = $obj->type_picto;
|
||||
$this->type = $obj->type_type;
|
||||
/*$transcode = $langs->trans("Action".$obj->type_code);
|
||||
$this->type = (($transcode != "Action".$obj->type_code) ? $transcode : $obj->type_label); */
|
||||
$transcode = $langs->trans("Action".$obj->type_code.'Short');
|
||||
|
||||
$this->code = $obj->code;
|
||||
$this->label = $obj->label;
|
||||
@@ -1261,9 +1258,11 @@ class ActionComm extends CommonObject
|
||||
$already_inserted = array();
|
||||
foreach (array_keys($this->socpeopleassigned) as $key => $val) {
|
||||
if (!is_array($val)) { // For backward compatibility when val=id
|
||||
$val = array('id'=>$val);
|
||||
$val = array('id' => $val);
|
||||
}
|
||||
if (!empty($already_inserted[$val['id']])) {
|
||||
continue;
|
||||
}
|
||||
if (!empty($already_inserted[$val['id']])) continue;
|
||||
|
||||
$sql = "INSERT INTO ".MAIN_DB_PREFIX."actioncomm_resources(fk_actioncomm, element_type, fk_element, mandatory, transparency, answer_status)";
|
||||
$sql .= " VALUES(".((int) $this->id).", 'socpeople', ".((int) $val['id']).", 0, 0, 0)";
|
||||
@@ -2414,23 +2413,23 @@ class ActionComm extends CommonObject
|
||||
$this->reminders = array();
|
||||
|
||||
//Select all action comm reminders for event
|
||||
$sql = "SELECT rowid as id, typeremind, dateremind, status, offsetvalue, offsetunit, fk_user";
|
||||
$sql = "SELECT rowid as id, typeremind, dateremind, status, offsetvalue, offsetunit, fk_user, fk_email_template, lasterror";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
|
||||
$sql .= " WHERE fk_actioncomm = ".((int) $this->id);
|
||||
if ($onlypast) {
|
||||
$sql .= " AND dateremind <= '".$this->db->idate(dol_now())."'";
|
||||
}
|
||||
if ($type) {
|
||||
$sql .= " AND typeremind ='".$this->db->escape($type)."'";
|
||||
$sql .= " AND typeremind = '".$this->db->escape($type)."'";
|
||||
}
|
||||
if ($fk_user > 0) {
|
||||
$sql .= " AND fk_user = ".((int) $fk_user);
|
||||
}
|
||||
if (empty($conf->global->AGENDA_REMINDER_EMAIL)) {
|
||||
$sql .= " AND typeremind != 'email'";
|
||||
$sql .= " AND typeremind <> 'email'";
|
||||
}
|
||||
if (empty($conf->global->AGENDA_REMINDER_BROWSER)) {
|
||||
$sql .= " AND typeremind != 'browser'";
|
||||
$sql .= " AND typeremind <> 'browser'";
|
||||
}
|
||||
|
||||
$sql .= $this->db->order("dateremind", "ASC");
|
||||
@@ -2446,6 +2445,8 @@ class ActionComm extends CommonObject
|
||||
$tmpactioncommreminder->offsetunit = $obj->offsetunit;
|
||||
$tmpactioncommreminder->status = $obj->status;
|
||||
$tmpactioncommreminder->fk_user = $obj->fk_user;
|
||||
$tmpactioncommreminder->fk_email_template = $obj->fk_email_template;
|
||||
$tmpactioncommreminder->lasterror = $obj->lasterror;
|
||||
|
||||
$this->reminders[$obj->id] = $tmpactioncommreminder;
|
||||
}
|
||||
@@ -2494,7 +2495,8 @@ class ActionComm extends CommonObject
|
||||
|
||||
//Select all action comm reminders
|
||||
$sql = "SELECT rowid as id FROM ".MAIN_DB_PREFIX."actioncomm_reminder";
|
||||
$sql .= " WHERE typeremind = 'email' AND status = 0";
|
||||
$sql .= " WHERE typeremind = 'email'";
|
||||
$sql .= " AND status = 0"; // 0=No yet sent, -1=Error. TODO Include reminder in error once we can count number of error, so we can try 5 times and not more on errors.
|
||||
$sql .= " AND dateremind <= '".$this->db->idate($now)."'";
|
||||
$sql .= " AND entity IN (".getEntity('actioncomm').")";
|
||||
$sql .= $this->db->order("dateremind", "ASC");
|
||||
@@ -2518,80 +2520,86 @@ class ActionComm extends CommonObject
|
||||
// Load event
|
||||
$res = $this->fetch($actionCommReminder->fk_actioncomm);
|
||||
if ($res > 0) {
|
||||
// PREPARE EMAIL
|
||||
$errormesg = '';
|
||||
$res2 = $this->fetch_thirdparty();
|
||||
if ($res2 >= 0) {
|
||||
// PREPARE EMAIL
|
||||
$errormesg = '';
|
||||
|
||||
// Make substitution in email content
|
||||
$substitutionarray = getCommonSubstitutionArray($langs, 0, '', $this);
|
||||
// Make substitution in email content
|
||||
$substitutionarray = getCommonSubstitutionArray($langs, 0, null, $this);
|
||||
|
||||
complete_substitutions_array($substitutionarray, $langs, $this);
|
||||
complete_substitutions_array($substitutionarray, $langs, $this);
|
||||
|
||||
// Content
|
||||
$sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray);
|
||||
// Content
|
||||
$sendContent = make_substitutions($langs->trans($arraymessage->content), $substitutionarray);
|
||||
|
||||
//Topic
|
||||
$sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder'));
|
||||
//Topic
|
||||
$sendTopic = (!empty($arraymessage->topic)) ? $arraymessage->topic : html_entity_decode($langs->transnoentities('EventReminder'));
|
||||
|
||||
// Recipient
|
||||
$recipient = new User($this->db);
|
||||
$res = $recipient->fetch($actionCommReminder->fk_user);
|
||||
if ($res > 0) {
|
||||
if (!empty($recipient->email)) {
|
||||
$to = $recipient->email;
|
||||
// Recipient
|
||||
$recipient = new User($this->db);
|
||||
$res = $recipient->fetch($actionCommReminder->fk_user);
|
||||
if ($res > 0) {
|
||||
if (!empty($recipient->email)) {
|
||||
$to = $recipient->email;
|
||||
} else {
|
||||
$errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user.";
|
||||
$error++;
|
||||
}
|
||||
} else {
|
||||
$errormesg = "Failed to send remind to user id=".$actionCommReminder->fk_user.". No email defined for user.";
|
||||
$errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user;
|
||||
$error++;
|
||||
}
|
||||
|
||||
// Sender
|
||||
$from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
|
||||
if (empty($from)) {
|
||||
$errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
|
||||
$error++;
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
// Errors Recipient
|
||||
$errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO');
|
||||
|
||||
// Mail Creation
|
||||
$cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', '');
|
||||
|
||||
// Sending Mail
|
||||
if ($cMailFile->sendfile()) {
|
||||
$nbMailSend++;
|
||||
} else {
|
||||
$errormesg = 'Failed to send email to: '.$to.' '.$cMailFile->error.implode(',', $cMailFile->errors);
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$actionCommReminder->status = $actionCommReminder::STATUS_DONE;
|
||||
|
||||
$res = $actionCommReminder->update($user);
|
||||
if ($res < 0) {
|
||||
$errorsMsg[] = "Failed to update status to done of ActionComm Reminder";
|
||||
$error++;
|
||||
break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first.
|
||||
}
|
||||
} else {
|
||||
$actionCommReminder->status = $actionCommReminder::STATUS_ERROR;
|
||||
$actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1);
|
||||
|
||||
$res = $actionCommReminder->update($user);
|
||||
if ($res < 0) {
|
||||
$errorsMsg[] = "Failed to update status to error of ActionComm Reminder";
|
||||
$error++;
|
||||
break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first.
|
||||
} else {
|
||||
$errorsMsg[] = $errormesg;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$errormesg = "Failed to load recipient with user id=".$actionCommReminder->fk_user;
|
||||
$errorsMsg[] = 'Failed to fetch record thirdparty on actioncomm with ID = '.$actionCommReminder->fk_actioncomm;
|
||||
$error++;
|
||||
}
|
||||
|
||||
// Sender
|
||||
$from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
|
||||
if (empty($from)) {
|
||||
$errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
|
||||
$error++;
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
// Errors Recipient
|
||||
$errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO');
|
||||
|
||||
// Mail Creation
|
||||
$cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, array(), array(), array(), '', "", 0, 1, $errors_to, '', '', '', '', '');
|
||||
|
||||
// Sending Mail
|
||||
if ($cMailFile->sendfile()) {
|
||||
$nbMailSend++;
|
||||
} else {
|
||||
$errormesg = $cMailFile->error.' : '.$to;
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$actionCommReminder->status = $actionCommReminder::STATUS_DONE;
|
||||
|
||||
$res = $actionCommReminder->update($user);
|
||||
if ($res < 0) {
|
||||
$errorsMsg[] = "Failed to update status to done of ActionComm Reminder";
|
||||
$error++;
|
||||
break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first.
|
||||
}
|
||||
} else {
|
||||
$actionCommReminder->status = $actionCommReminder::STATUS_ERROR;
|
||||
$actionCommReminder->lasterror = dol_trunc($errormesg, 128, 'right', 'UTF-8', 1);
|
||||
|
||||
$res = $actionCommReminder->update($user);
|
||||
if ($res < 0) {
|
||||
$errorsMsg[] = "Failed to update status to error of ActionComm Reminder";
|
||||
$error++;
|
||||
break; // This is to avoid to have this error on all the selected email. If we fails here for one record, it may fails for others. We must solve first.
|
||||
} else {
|
||||
$errorsMsg[] = $errormesg;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$errorsMsg[] = 'Failed to fetch record actioncomm with ID = '.$actionCommReminder->fk_actioncomm;
|
||||
$error++;
|
||||
|
||||
@@ -270,6 +270,12 @@ class AgendaEvents extends DolibarrApi
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$this->actioncomm->array_options[$index] = $this->_checkValForAPI($field, $val, $this->actioncomm);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$this->actioncomm->$field = $this->_checkValForAPI($field, $value, $this->actioncomm);
|
||||
}
|
||||
|
||||
|
||||
@@ -53,6 +53,9 @@ if ($user->socid && $socid) {
|
||||
$result = restrictedArea($user, 'societe', $socid);
|
||||
}
|
||||
|
||||
$object = new ActionComm($db);
|
||||
$object->fetch($id);
|
||||
|
||||
$usercancreate = $user->hasRight('agenda', 'allactions', 'create') || (($object->authorid == $user->id || $object->userownerid == $user->id) && $user->hasRight('agenda', 'myactions', 'create'));
|
||||
|
||||
|
||||
@@ -65,8 +68,6 @@ $form = new Form($db);
|
||||
$help_url = 'EN:Module_Agenda_En|FR:Module_Agenda|ES:M&omodulodulo_Agenda|DE:Modul_Terminplanung';
|
||||
llxHeader('', $langs->trans("Agenda"), $help_url);
|
||||
|
||||
$object = new ActionComm($db);
|
||||
$object->fetch($id);
|
||||
$object->info($object->id);
|
||||
|
||||
$head = actions_prepare_head($object);
|
||||
|
||||
@@ -348,41 +348,41 @@ if ($search_title != '') {
|
||||
if ($search_note != '') {
|
||||
$param .= '&search_note='.urlencode($search_note);
|
||||
}
|
||||
if (GETPOST('datestartday_dtstart', 'int')) {
|
||||
$param .= '&datestartday_dtstart='.GETPOST('datestartday_dtstart', 'int');
|
||||
if (GETPOST('datestart_dtstartday', 'int')) {
|
||||
$param .= '&datestart_dtstartday='.GETPOST('datestart_dtstartday', 'int');
|
||||
}
|
||||
if (GETPOST('datestartmonth_dtstart', 'int')) {
|
||||
$param .= '&datestartmonth_dtstart='.GETPOST('datestartmonth_dtstart', 'int');
|
||||
if (GETPOST('datestart_dtstartmonth', 'int')) {
|
||||
$param .= '&datestart_dtstartmonth='.GETPOST('datestart_dtstartmonth', 'int');
|
||||
}
|
||||
if (GETPOST('datestartyear_dtstart', 'int')) {
|
||||
$param .= '&datestartyear_dtstart='.GETPOST('datestartyear_dtstart', 'int');
|
||||
if (GETPOST('datestart_dtstartyear', 'int')) {
|
||||
$param .= '&datestart_dtstartyear='.GETPOST('datestart_dtstartyear', 'int');
|
||||
}
|
||||
if (GETPOST('datestartday_dtend', 'int')) {
|
||||
$param .= '&datestartday_dtend='.GETPOST('datestartday_dtend', 'int');
|
||||
if (GETPOST('datestart_dtendday', 'int')) {
|
||||
$param .= '&datestart_dtendday='.GETPOST('datestart_dtendday', 'int');
|
||||
}
|
||||
if (GETPOST('datestartmonth_dtend', 'int')) {
|
||||
$param .= '&datestartmonth_dtend='.GETPOST('datestartmonth_dtend', 'int');
|
||||
if (GETPOST('datestart_dtendmonth', 'int')) {
|
||||
$param .= '&datestart_dtendmonth='.GETPOST('datestart_dtendmonth', 'int');
|
||||
}
|
||||
if (GETPOST('datestartyear_dtend', 'int')) {
|
||||
$param .= '&datestartyear_dtend='.GETPOST('datestartyear_dtend', 'int');
|
||||
if (GETPOST('datestart_dtendyear', 'int')) {
|
||||
$param .= '&datestart_dtendyear='.GETPOST('datestart_dtendyear', 'int');
|
||||
}
|
||||
if (GETPOST('dateendday_dtstart', 'int')) {
|
||||
$param .= '&dateendday_dtstart='.GETPOST('dateendday_dtstart', 'int');
|
||||
if (GETPOST('dateend_dtstartday', 'int')) {
|
||||
$param .= '&dateend_dtstartday='.GETPOST('dateend_dtstartday', 'int');
|
||||
}
|
||||
if (GETPOST('dateendmonth_dtstart', 'int')) {
|
||||
$param .= '&dateendmonth_dtstart='.GETPOST('dateendmonth_dtstart', 'int');
|
||||
if (GETPOST('dateend_dtstartmonth', 'int')) {
|
||||
$param .= '&dateend_dtstartmonth='.GETPOST('dateend_dtstartmonth', 'int');
|
||||
}
|
||||
if (GETPOST('dateendyear_dtstart', 'int')) {
|
||||
$param .= '&dateendyear_dtstart='.GETPOST('dateendyear_dtstart', 'int');
|
||||
if (GETPOST('dateend_dtstartyear', 'int')) {
|
||||
$param .= '&dateend_dtstartyear='.GETPOST('dateend_dtstartyear', 'int');
|
||||
}
|
||||
if (GETPOST('dateendday_dtend', 'int')) {
|
||||
$param .= '&dateendday_dtend='.GETPOST('dateendday_dtend', 'int');
|
||||
if (GETPOST('dateend_dtendday', 'int')) {
|
||||
$param .= '&dateend_dtendday='.GETPOST('dateend_dtendday', 'int');
|
||||
}
|
||||
if (GETPOST('dateendmonth_dtend', 'int')) {
|
||||
$param .= '&dateendmonth_dtend='.GETPOST('dateendmonth_dtend', 'int');
|
||||
if (GETPOST('dateend_dtendmonth', 'int')) {
|
||||
$param .= '&dateend_dtendmonth='.GETPOST('dateend_dtendmonth', 'int');
|
||||
}
|
||||
if (GETPOST('dateendyear_dtend', 'int')) {
|
||||
$param .= '&dateendyear_dtend='.GETPOST('dateendyear_dtend', 'int');
|
||||
if (GETPOST('dateend_dtendyear', 'int')) {
|
||||
$param .= '&dateend_dtendyear='.GETPOST('dateend_dtendyear', 'int');
|
||||
}
|
||||
if ($optioncss != '') {
|
||||
$param .= '&optioncss='.urlencode($optioncss);
|
||||
@@ -442,20 +442,25 @@ if (empty($user->rights->societe->client->voir) && !$socid) {
|
||||
}
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON a.fk_soc = s.rowid";
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid";
|
||||
$sql .= " ,".MAIN_DB_PREFIX."c_actioncomm as c";
|
||||
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON c.id = a.fk_action";
|
||||
// We must filter on resource table
|
||||
if ($resourceid > 0) {
|
||||
$sql .= ", ".MAIN_DB_PREFIX."element_resources as r";
|
||||
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."element_resources as r ON r.element_type = 'action' AND r.element_id = a.id";
|
||||
}
|
||||
// We must filter on assignement table
|
||||
if ($filtert > 0 || $usergroup > 0) {
|
||||
$sql .= ", ".MAIN_DB_PREFIX."actioncomm_resources as ar";
|
||||
$sql .= " INNER JOIN ".MAIN_DB_PREFIX."actioncomm_resources as ar ON ar.fk_actioncomm = a.id AND ar.element_type='user'";
|
||||
}
|
||||
if ($usergroup > 0) {
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."usergroup_user as ugu ON ugu.fk_user = ar.fk_element";
|
||||
}
|
||||
$sql .= " WHERE c.id = a.fk_action";
|
||||
$sql .= ' AND a.entity IN ('.getEntity('agenda').')';
|
||||
|
||||
// Add table from hooks
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldListFrom', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
||||
$sql .= $hookmanager->resPrint;
|
||||
|
||||
$sql .= " WHERE a.entity IN (".getEntity('agenda').")";
|
||||
// Condition on actioncode
|
||||
if (!empty($actioncode)) {
|
||||
if (empty($conf->global->AGENDA_USE_EVENT_TYPE)) {
|
||||
@@ -486,7 +491,7 @@ if (!empty($actioncode)) {
|
||||
}
|
||||
}
|
||||
if ($resourceid > 0) {
|
||||
$sql .= " AND r.element_type = 'action' AND r.element_id = a.id AND r.resource_id = ".((int) $resourceid);
|
||||
$sql .= " AND r.resource_id = ".((int) $resourceid);
|
||||
}
|
||||
if ($pid) {
|
||||
$sql .= " AND a.fk_project=".((int) $pid);
|
||||
@@ -497,10 +502,6 @@ if (empty($user->rights->societe->client->voir) && !$socid) {
|
||||
if ($socid > 0) {
|
||||
$sql .= " AND s.rowid = ".((int) $socid);
|
||||
}
|
||||
// We must filter on assignement table
|
||||
if ($filtert > 0 || $usergroup > 0) {
|
||||
$sql .= " AND ar.fk_actioncomm = a.id AND ar.element_type='user'";
|
||||
}
|
||||
if ($type) {
|
||||
$sql .= " AND c.id = ".((int) $type);
|
||||
}
|
||||
@@ -574,6 +575,7 @@ if (!getDolGlobalInt('MAIN_DISABLE_FULL_SCANLIST')) {
|
||||
/* The fast and low memory method to get and count full list converts the sql into a sql count */
|
||||
$sqlforcount = preg_replace('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(*) as nbtotalofrecords', $sql);
|
||||
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
|
||||
|
||||
$resql = $db->query($sqlforcount);
|
||||
if ($resql) {
|
||||
$objforcount = $db->fetch_object($resql);
|
||||
|
||||
@@ -921,6 +921,9 @@ while ($currentdaytoshow < $lastdaytoshow) {
|
||||
$sql .= " WHERE u.entity IN (".getEntity('user').")";
|
||||
}
|
||||
$sql .= " AND u.statut = 1";
|
||||
if ($filtert > 0) {
|
||||
$sql .= " AND u.rowid = ".((int) $filtert);
|
||||
}
|
||||
if ($usergroup > 0) {
|
||||
$sql .= " AND ug.fk_usergroup = ".((int) $usergroup);
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ if (isModEnabled('ficheinter')) {
|
||||
}
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array('companies', 'banks'));
|
||||
$langs->loadLangs(array('companies', 'banks', 'commercial'));
|
||||
|
||||
if (isModEnabled('contrat')) {
|
||||
$langs->load("contracts");
|
||||
@@ -868,9 +868,9 @@ if ($object->id > 0) {
|
||||
$filedir = $conf->propal->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
|
||||
$file_list = null;
|
||||
if (!empty($filedir)) {
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
}
|
||||
if (is_array($file_list)) {
|
||||
if (is_array($file_list) && !empty($file_list)) {
|
||||
// Defined relative dir to DOL_DATA_ROOT
|
||||
$relativedir = '';
|
||||
if ($filedir) {
|
||||
@@ -980,9 +980,9 @@ if ($object->id > 0) {
|
||||
$filedir = $conf->commande->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
|
||||
$file_list = null;
|
||||
if (!empty($filedir)) {
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
}
|
||||
if (is_array($file_list)) {
|
||||
if (is_array($file_list) && !empty($file_list)) {
|
||||
// Defined relative dir to DOL_DATA_ROOT
|
||||
$relativedir = '';
|
||||
if ($filedir) {
|
||||
@@ -1074,9 +1074,9 @@ if ($object->id > 0) {
|
||||
$filedir = $conf->expedition->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
|
||||
$file_list = null;
|
||||
if (!empty($filedir)) {
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
}
|
||||
if (is_array($file_list)) {
|
||||
if (is_array($file_list) && !empty($file_list)) {
|
||||
// Defined relative dir to DOL_DATA_ROOT
|
||||
$relativedir = '';
|
||||
if ($filedir) {
|
||||
@@ -1180,9 +1180,9 @@ if ($object->id > 0) {
|
||||
$filedir = $conf->contrat->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
|
||||
$file_list = null;
|
||||
if (!empty($filedir)) {
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
}
|
||||
if (is_array($file_list)) {
|
||||
if (is_array($file_list) && !empty($file_list)) {
|
||||
// Defined relative dir to DOL_DATA_ROOT
|
||||
$relativedir = '';
|
||||
if ($filedir) {
|
||||
@@ -1271,9 +1271,9 @@ if ($object->id > 0) {
|
||||
$filedir = $conf->ficheinter->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
|
||||
$file_list = null;
|
||||
if (!empty($filedir)) {
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
}
|
||||
if (is_array($file_list)) {
|
||||
if (is_array($file_list) && !empty($file_list)) {
|
||||
// Defined relative dir to DOL_DATA_ROOT
|
||||
$relativedir = '';
|
||||
if ($filedir) {
|
||||
@@ -1471,9 +1471,9 @@ if ($object->id > 0) {
|
||||
$filedir = $conf->facture->multidir_output[$objp->entity].'/'.dol_sanitizeFileName($objp->ref);
|
||||
$file_list = null;
|
||||
if (!empty($filedir)) {
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, '', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
$file_list = dol_dir_list($filedir, 'files', 0, dol_sanitizeFileName($objp->ref).'.pdf', '(\.meta|_preview.*.*\.png)$', 'date', SORT_DESC);
|
||||
}
|
||||
if (is_array($file_list)) {
|
||||
if (is_array($file_list) && !empty($file_list)) {
|
||||
// Defined relative dir to DOL_DATA_ROOT
|
||||
$relativedir = '';
|
||||
if ($filedir) {
|
||||
|
||||
@@ -37,7 +37,7 @@ if (!$sortorder) {
|
||||
$sortorder = "ASC";
|
||||
}
|
||||
if (!$sortfield) {
|
||||
$sortfield = "p.name";
|
||||
$sortfield = "p.lastname";
|
||||
}
|
||||
if ($page < 0) {
|
||||
$page = 0;
|
||||
@@ -81,7 +81,7 @@ if ($type == "f") {
|
||||
*/
|
||||
|
||||
$sql = "SELECT s.rowid, s.nom as name, st.libelle as stcomm";
|
||||
$sql .= ", p.rowid as cidp, p.name, p.firstname, p.email, p.phone";
|
||||
$sql .= ", p.rowid as cidp, p.lastname, p.firstname, p.email, p.phone";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."c_stcomm as st,";
|
||||
if (empty($user->rights->societe->client->voir) && !$socid) {
|
||||
$sql .= " ".MAIN_DB_PREFIX."societe_commerciaux as sc,";
|
||||
@@ -106,7 +106,7 @@ if ($socid) {
|
||||
$sql .= " AND s.rowid = ".((int) $socid);
|
||||
}
|
||||
if (!empty($search_lastname)) {
|
||||
$sql .= " AND p.name LIKE '%".$db->escape($search_lastname)."%'";
|
||||
$sql .= " AND p.lastname LIKE '%".$db->escape($search_lastname)."%'";
|
||||
}
|
||||
if (!empty($search_firstname)) {
|
||||
$sql .= " AND p.firstname LIKE '%".$db->escape($search_firstname)."%'";
|
||||
@@ -115,8 +115,8 @@ if (!empty($search_company)) {
|
||||
$sql .= " AND s.nom LIKE '%".$db->escape($search_company)."%'";
|
||||
}
|
||||
if (!empty($contactname)) { // acces a partir du module de recherche
|
||||
$sql .= " AND (p.name LIKE '%".$db->escape($contactname)."%' OR lower(p.firstname) LIKE '%".$db->escape($contactname)."%') ";
|
||||
$sortfield = "p.name";
|
||||
$sql .= " AND (p.lastname LIKE '%".$db->escape($contactname)."%' OR lower(p.firstname) LIKE '%".$db->escape($contactname)."%') ";
|
||||
$sortfield = "p.lastname";
|
||||
$sortorder = "ASC";
|
||||
}
|
||||
|
||||
@@ -136,7 +136,7 @@ if ($resql) {
|
||||
|
||||
print '<table class="liste centpercent">';
|
||||
print '<tr class="liste_titre">';
|
||||
print_liste_field_titre("Lastname", $_SERVER["PHP_SELF"], "p.name", $begin, $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("Lastname", $_SERVER["PHP_SELF"], "p.lastname", $begin, $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("Firstname", $_SERVER["PHP_SELF"], "p.firstname", $begin, $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("Company", $_SERVER["PHP_SELF"], "s.nom", $begin, $param, "", $sortfield, $sortorder);
|
||||
print_liste_field_titre("Email");
|
||||
|
||||
@@ -901,14 +901,14 @@ if ($action == 'create') {
|
||||
|
||||
$text = '';
|
||||
|
||||
if (isset($conf->global->MAILING_LIMIT_SENDBYDAY) && $conf->global->MAILING_LIMIT_SENDBYDAY >= 0) {
|
||||
$text .= $langs->trans('WarningLimitSendByDay', $conf->global->MAILING_LIMIT_SENDBYDAY);
|
||||
if (getDolGlobalInt('MAILING_LIMIT_SENDBYDAY') > 0) {
|
||||
$text .= $langs->trans('WarningLimitSendByDay', getDolGlobalInt('MAILING_LIMIT_SENDBYDAY'));
|
||||
$text .= '<br><br>';
|
||||
}
|
||||
$text .= $langs->trans('ConfirmSendingEmailing').'<br>';
|
||||
$text .= $langs->trans('LimitSendingEmailing', $conf->global->MAILING_LIMIT_SENDBYWEB);
|
||||
|
||||
if (!isset($conf->global->MAILING_LIMIT_SENDBYCLI) || $conf->global->MAILING_LIMIT_SENDBYCLI >= 0) {
|
||||
if (!isset($conf->global->MAILING_LIMIT_SENDBYCLI) || getDolGlobalInt('MAILING_LIMIT_SENDBYCLI') >= 0) {
|
||||
$text .= '<br><br>';
|
||||
$text .= $langs->trans("MailingNeedCommand");
|
||||
$text .= '<br><textarea class="quatrevingtpercent" rows="'.ROWS_2.'" wrap="soft" disabled>php ./scripts/emailings/mailing-send.php '.$object->id.' '.$user->login.'</textarea>';
|
||||
|
||||
@@ -146,7 +146,6 @@ $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action
|
||||
if ($reshook < 0) {
|
||||
setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
|
||||
}
|
||||
|
||||
if (empty($reshook)) {
|
||||
$backurlforlist = DOL_URL_ROOT.'/comm/propal/list.php';
|
||||
|
||||
@@ -179,8 +178,8 @@ if (empty($reshook)) {
|
||||
|
||||
// Action clone object
|
||||
if ($action == 'confirm_clone' && $confirm == 'yes' && $usercancreate) {
|
||||
if (!GETPOST('socid', 3)) {
|
||||
setEventMessages($langs->trans("NoCloneOptionsSpecified"), null, 'errors');
|
||||
if (!($socid > 0)) {
|
||||
setEventMessages($langs->trans('ErrorFieldRequired', $langs->transnoentitiesnoconv('IdThirdParty')), null, 'errors');
|
||||
} else {
|
||||
if ($object->id > 0) {
|
||||
if (!empty($conf->global->PROPAL_CLONE_DATE_DELIVERY)) {
|
||||
@@ -780,10 +779,14 @@ if (empty($reshook)) {
|
||||
if ($object->statut == Propal::STATUS_SIGNED || $object->statut == Propal::STATUS_NOTSIGNED || $object->statut == Propal::STATUS_BILLED) {
|
||||
$db->begin();
|
||||
|
||||
$result = $object->reopen($user, empty($conf->global->PROPAL_SKIP_ACCEPT_REFUSE));
|
||||
$newstatus = (getDolGlobalInt('PROPAL_SKIP_ACCEPT_REFUSE') ? Propal::STATUS_DRAFT : Propal::STATUS_VALIDATED);
|
||||
$result = $object->reopen($user, $newstatus);
|
||||
if ($result < 0) {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
$error++;
|
||||
} else {
|
||||
$object->statut = $newstatus;
|
||||
$object->status = $newstatus;
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
@@ -1167,6 +1170,10 @@ if (empty($reshook)) {
|
||||
if (!empty($price_ht) || (string) $price_ht === '0') {
|
||||
$pu_ht = price2num($price_ht, 'MU');
|
||||
$pu_ttc = price2num($pu_ht * (1 + ((float) $tmpvat / 100)), 'MU');
|
||||
} elseif (!empty($price_ht_devise) || (string) $price_ht_devise === '0') {
|
||||
$pu_ht_devise = price2num($price_ht_devise, 'MU');
|
||||
$pu_ht = '';
|
||||
$pu_ttc = '';
|
||||
} elseif (!empty($price_ttc) || (string) $price_ttc === '0') {
|
||||
$pu_ttc = price2num($price_ttc, 'MU');
|
||||
$pu_ht = price2num($pu_ttc / (1 + ((float) $tmpvat / 100)), 'MU');
|
||||
@@ -1606,7 +1613,20 @@ if (empty($reshook)) {
|
||||
$result = $object->set_demand_reason($user, GETPOST('demand_reason_id', 'int'));
|
||||
} elseif ($action == 'setconditions' && $usercancreate) {
|
||||
// Terms of payment
|
||||
$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha'));
|
||||
$sql = "SELECT code ";
|
||||
$sql .= "FROM " . $db->prefix() . "c_payment_term";
|
||||
$sql .= " WHERE rowid = " . ((int) GETPOST('cond_reglement_id', 'int'));
|
||||
$result = $db->query($sql);
|
||||
if ($result) {
|
||||
$obj = $db->fetch_object($result);
|
||||
if ($obj->code == 'DEP30PCTDEL') {
|
||||
$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), GETPOST('cond_reglement_id_deposit_percent', 'alpha'));
|
||||
} else {
|
||||
$object->deposit_percent = 0;
|
||||
$object->update($user);
|
||||
$result = $object->setPaymentTerms(GETPOST('cond_reglement_id', 'int'), $object->deposit_percent);
|
||||
}
|
||||
}
|
||||
} elseif ($action == 'setremisepercent' && $usercancreate) {
|
||||
$result = $object->set_remise_percent($user, price2num(GETPOST('remise_percent'), '', 2));
|
||||
} elseif ($action == 'setremiseabsolue' && $usercancreate) {
|
||||
@@ -1631,14 +1651,15 @@ if (empty($reshook)) {
|
||||
$result = $object->setWarehouse(GETPOST('warehouse_id', 'int'));
|
||||
} elseif ($action == 'update_extras') {
|
||||
$object->oldcopy = dol_clone($object, 2);
|
||||
$attribute_name = GETPOST('attribute', 'restricthtml');
|
||||
|
||||
// Fill array 'array_options' with data from update form
|
||||
$ret = $extrafields->setOptionalsFromPost(null, $object, GETPOST('attribute', 'restricthtml'));
|
||||
$ret = $extrafields->setOptionalsFromPost(null, $object, $attribute_name);
|
||||
if ($ret < 0) {
|
||||
$error++;
|
||||
}
|
||||
if (!$error) {
|
||||
$result = $object->insertExtraFields('PROPAL_MODIFY');
|
||||
$result = $object->updateExtraField($attribute_name, 'PROPAL_MODIFY');
|
||||
if ($result < 0) {
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
$error++;
|
||||
@@ -2848,7 +2869,9 @@ if ($action == 'create') {
|
||||
print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
|
||||
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, '', $langs, 0, -1, -1, $conf->currency) . '</td>';
|
||||
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
||||
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
$object->multicurrency_total_localtax1 = price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
|
||||
|
||||
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax1, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
}
|
||||
print '</tr>';
|
||||
|
||||
@@ -2857,7 +2880,9 @@ if ($action == 'create') {
|
||||
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
|
||||
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, '', $langs, 0, -1, -1, $conf->currency) . '</td>';
|
||||
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
||||
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
$object->multicurrency_total_localtax2 = price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
|
||||
|
||||
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax2, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
}
|
||||
print '</tr>';
|
||||
}
|
||||
@@ -3112,7 +3137,7 @@ if ($action == 'create') {
|
||||
if ($object->statut != Propal::STATUS_DRAFT && $useonlinesignature) {
|
||||
print '<br><!-- Link to sign -->';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php';
|
||||
print showOnlineSignatureUrl('proposal', $object->ref).'<br>';
|
||||
print showOnlineSignatureUrl('proposal', $object->ref, $object).'<br>';
|
||||
}
|
||||
|
||||
print '</div><div class="fichehalfright">';
|
||||
|
||||
@@ -278,7 +278,7 @@ class Proposals extends DolibarrApi
|
||||
throw new RestException(500, "Error creating order", array_merge(array($this->propal->error), $this->propal->errors));
|
||||
}
|
||||
|
||||
return $this->propal->id;
|
||||
return ((int) $this->propal->id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -695,6 +695,12 @@ class Proposals extends DolibarrApi
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$this->propal->array_options[$index] = $this->_checkValForAPI($field, $val, $this->propal);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$this->propal->$field = $value;
|
||||
}
|
||||
|
||||
|
||||
@@ -272,6 +272,8 @@ class Propal extends CommonObject
|
||||
public $multicurrency_total_ht;
|
||||
public $multicurrency_total_tva;
|
||||
public $multicurrency_total_ttc;
|
||||
public $multicurrency_total_localtax1; // not in database
|
||||
public $multicurrency_total_localtax2; // not in database
|
||||
|
||||
|
||||
/**
|
||||
@@ -1413,7 +1415,9 @@ class Propal extends CommonObject
|
||||
}
|
||||
|
||||
// reset ref_client
|
||||
$object->ref_client = '';
|
||||
if (!getDolGlobalString('MAIN_KEEP_REF_CUSTOMER_ON_CLONING')) {
|
||||
$object->ref_client = '';
|
||||
}
|
||||
|
||||
// TODO Change product price if multi-prices
|
||||
} else {
|
||||
@@ -2695,7 +2699,10 @@ class Propal extends CommonObject
|
||||
}
|
||||
|
||||
$sql = "UPDATE ".MAIN_DB_PREFIX."propal";
|
||||
$sql .= " SET fk_statut = ".((int) $status).", note_private = '".$this->db->escape($newprivatenote)."', date_signature='".$this->db->idate($date_signature)."', fk_user_signature=".$fk_user_signature;
|
||||
$sql .= " SET fk_statut = ".((int) $status).", note_private = '".$this->db->escape($newprivatenote)."'";
|
||||
if ($status == self::STATUS_SIGNED) {
|
||||
$sql .= ", date_signature='".$this->db->idate($now)."', fk_user_signature = ".($fk_user_signature);
|
||||
}
|
||||
$sql .= " WHERE rowid = ".((int) $this->id);
|
||||
|
||||
$resql = $this->db->query($sql);
|
||||
@@ -3510,7 +3517,7 @@ class Propal extends CommonObject
|
||||
$response->label = $label;
|
||||
$response->labelShort = $labelShort;
|
||||
$response->url = DOL_URL_ROOT.'/comm/propal/list.php?search_status='.$status.'&mainmenu=commercial&leftmenu=propals';
|
||||
$response->url_late = DOL_URL_ROOT.'/comm/propal/list.php?search_status='.$status.'&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
|
||||
$response->url_late = DOL_URL_ROOT.'/comm/propal/list.php?search_option=late&mainmenu=commercial&leftmenu=propals&sortfield=p.datep&sortorder=asc';
|
||||
$response->img = img_object('', "propal");
|
||||
|
||||
// This assignment in condition is not a bug. It allows walking the results.
|
||||
@@ -4436,8 +4443,17 @@ class PropaleLigne extends CommonObjectLine
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
if (!$error) {
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
foreach ($this->errors as $errmsg) {
|
||||
dol_syslog(get_class($this)."::insert ".$errmsg, LOG_ERR);
|
||||
$this->error .= ($this->error ? ', '.$errmsg : $errmsg);
|
||||
}
|
||||
$this->db->rollback();
|
||||
return -1 * $error;
|
||||
} else {
|
||||
$this->error = $this->db->error()." sql=".$sql;
|
||||
$this->db->rollback();
|
||||
@@ -4643,8 +4659,17 @@ class PropaleLigne extends CommonObjectLine
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
if (!$error) {
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
foreach ($this->errors as $errmsg) {
|
||||
dol_syslog(get_class($this)."::update ".$errmsg, LOG_ERR);
|
||||
$this->error .= ($this->error ? ', '.$errmsg : $errmsg);
|
||||
}
|
||||
$this->db->rollback();
|
||||
return -1 * $error;
|
||||
} else {
|
||||
$this->error = $this->db->error();
|
||||
$this->db->rollback();
|
||||
|
||||
@@ -67,11 +67,11 @@ $socid = '';
|
||||
if (!empty($user->socid)) {
|
||||
$socid = $user->socid;
|
||||
}
|
||||
$hookmanager->initHooks(array('proposalcontactcard', 'globalcard'));
|
||||
restrictedArea($user, 'propal', $object->id);
|
||||
|
||||
$usercancreate = $user->hasRight("propal", "creer");
|
||||
|
||||
|
||||
/*
|
||||
* Add a new contact
|
||||
*/
|
||||
|
||||
@@ -81,6 +81,7 @@ $socid = '';
|
||||
if (!empty($user->socid)) {
|
||||
$socid = $user->socid;
|
||||
}
|
||||
$hookmanager->initHooks(array('propaldocument', 'globalcard'));
|
||||
restrictedArea($user, 'propal', $object->id);
|
||||
|
||||
$usercancreate = $user->hasRight("propal", "creer");
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
* Copyright (C) 2021 Anthony Berton <anthony.berton@bb2a.fr>
|
||||
* Copyright (C) 2021 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2022 Josep Lluís Amador <joseplluis@lliuretic.cat>
|
||||
* Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -146,6 +147,12 @@ $search_status = GETPOST('search_status', 'alpha');
|
||||
$optioncss = GETPOST('optioncss', 'alpha');
|
||||
$object_statut = GETPOST('search_statut', 'alpha');
|
||||
|
||||
$search_option = GETPOST('search_option', 'alpha');
|
||||
if ($search_option == 'late') {
|
||||
$search_status = '1';
|
||||
$object_statut = '1';
|
||||
}
|
||||
|
||||
$sall = trim((GETPOST('search_all', 'alphanohtml') != '') ?GETPOST('search_all', 'alphanohtml') : GETPOST('sall', 'alphanohtml'));
|
||||
$mesg = (GETPOST("msg") ? GETPOST("msg") : GETPOST("mesg"));
|
||||
|
||||
@@ -389,6 +396,7 @@ if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x'
|
||||
$search_date_signature_endyear = '';
|
||||
$search_date_signature_start = '';
|
||||
$search_date_signature_end = '';
|
||||
$search_option = '';
|
||||
}
|
||||
if ($object_statut != '') {
|
||||
$search_status = $object_statut;
|
||||
@@ -764,6 +772,9 @@ if ($search_date_signature_start) {
|
||||
if ($search_date_signature_end) {
|
||||
$sql .= " AND p.date_signature <= '".$db->idate($search_date_signature_end)."'";
|
||||
}
|
||||
if ($search_option == 'late') {
|
||||
$sql .= " AND p.fin_validite < '".$db->idate(dol_now() - $conf->propal->cloture->warning_delay)."'";
|
||||
}
|
||||
// Search for tag/category ($searchCategoryProductList is an array of ID)
|
||||
$searchCategoryProductOperator = -1;
|
||||
$searchCategoryProductList = array($search_product_category);
|
||||
@@ -1042,6 +1053,9 @@ if ($resql) {
|
||||
if ($search_date_signature_endyear) {
|
||||
$param .= '&search_date_signature_endyear='.urlencode($search_date_signature_endyear);
|
||||
}
|
||||
if ($search_option) {
|
||||
$param .= "&search_option=".urlencode($search_option);
|
||||
}
|
||||
|
||||
// Add $param from extra fields
|
||||
include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php';
|
||||
@@ -1166,6 +1180,7 @@ if ($resql) {
|
||||
$moreforfilter .= img_picto($tmptitle, 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', $tmptitle, 0, 0, $tmptitle);
|
||||
$moreforfilter .= '</div>';
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
||||
if (empty($reshook)) {
|
||||
|
||||
@@ -937,7 +937,7 @@ if ($socid > 0) {
|
||||
print '<td class="nowrap">'.$langs->trans("ConsumedBy").'</td>';
|
||||
print '<td class="right">'.$langs->trans("AmountHT").'</td>';
|
||||
if (isModEnabled('multicompany')) {
|
||||
print '<td class="right toverflowmax125" title="'.dol_escape_htmltag($langs->trans("MulticurrencyAmountHT")).'">'.$langs->trans("MulticurrencyAmountHT").'</td>';
|
||||
print '<td class="right tdoverflowmax125" title="'.dol_escape_htmltag($langs->trans("MulticurrencyAmountHT")).'">'.$langs->trans("MulticurrencyAmountHT").'</td>';
|
||||
}
|
||||
print '<td class="right">'.$langs->trans("VATRate").'</td>';
|
||||
print '<td class="right">'.$langs->trans("AmountTTC").'</td>';
|
||||
|
||||
@@ -866,22 +866,22 @@ if (empty($reshook)) {
|
||||
}
|
||||
}
|
||||
|
||||
$tmpvat = price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx));
|
||||
$tmpprodvat = price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx));
|
||||
$tmpvat = (float) price2num(preg_replace('/\s*\(.*\)/', '', $tva_tx));
|
||||
$tmpprodvat = (float) price2num(preg_replace('/\s*\(.*\)/', '', $prod->tva_tx));
|
||||
|
||||
// Set unit price to use
|
||||
if (!empty($price_ht) || $price_ht === '0') {
|
||||
$pu_ht = price2num($price_ht, 'MU');
|
||||
$pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
|
||||
$pu_ht = (float) price2num($price_ht, 'MU');
|
||||
$pu_ttc = (float) price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
|
||||
} elseif (!empty($price_ttc) || $price_ttc === '0') {
|
||||
$pu_ttc = price2num($price_ttc, 'MU');
|
||||
$pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
|
||||
$pu_ttc = (float) price2num($price_ttc, 'MU');
|
||||
$pu_ht = (float) price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
|
||||
} elseif ($tmpvat != $tmpprodvat) {
|
||||
// Is this still used ?
|
||||
if ($price_base_type != 'HT') {
|
||||
$pu_ht = price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
|
||||
$pu_ht = (float) price2num($pu_ttc / (1 + ($tmpvat / 100)), 'MU');
|
||||
} else {
|
||||
$pu_ttc = price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
|
||||
$pu_ttc = (float) price2num($pu_ht * (1 + ($tmpvat / 100)), 'MU');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2770,7 +2770,9 @@ if ($action == 'create' && $usercancreate) {
|
||||
print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
|
||||
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, '', $langs, 0, -1, -1, $conf->currency) . '</td>';
|
||||
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
||||
print '<td class="nowrap amountcard right">' . price($object->total_localtax1, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
$object->multicurrency_total_localtax1 = price2num($object->total_localtax1 * $object->multicurrency_tx, 'MT');
|
||||
|
||||
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax1, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
}
|
||||
print '</tr>';
|
||||
|
||||
@@ -2780,7 +2782,9 @@ if ($action == 'create' && $usercancreate) {
|
||||
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
|
||||
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, '', $langs, 0, -1, -1, $conf->currency) . '</td>';
|
||||
if (isModEnabled("multicurrency") && ($object->multicurrency_code && $object->multicurrency_code != $conf->currency)) {
|
||||
print '<td class="nowrap amountcard right">' . price($object->total_localtax2, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
$object->multicurrency_total_localtax2 = price2num($object->total_localtax2 * $object->multicurrency_tx, 'MT');
|
||||
|
||||
print '<td class="nowrap amountcard right">' . price($object->multicurrency_total_localtax2, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
}
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
@@ -297,7 +297,7 @@ class Orders extends DolibarrApi
|
||||
throw new RestException(500, "Error creating order", array_merge(array($this->commande->error), $this->commande->errors));
|
||||
}
|
||||
|
||||
return $this->commande->id;
|
||||
return ((int) $this->commande->id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -653,6 +653,12 @@ class Orders extends DolibarrApi
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$this->commande->array_options[$index] = $this->_checkValForAPI($field, $val, $this->commande);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$this->commande->$field = $value;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
* Copyright (C) 2016-2022 Ferran Marcet <fmarcet@2byte.es>
|
||||
* Copyright (C) 2021-2023 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
|
||||
* Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -275,6 +276,8 @@ class Commande extends CommonOrder
|
||||
public $multicurrency_total_ht;
|
||||
public $multicurrency_total_tva;
|
||||
public $multicurrency_total_ttc;
|
||||
public $multicurrency_total_localtax1; // not in database
|
||||
public $multicurrency_total_localtax2; // not in database
|
||||
|
||||
//! key of module source when order generated from a dedicated module ('cashdesk', 'takepos', ...)
|
||||
public $module_source;
|
||||
@@ -3278,7 +3281,7 @@ class Commande extends CommonOrder
|
||||
$this->line->localtax1_type = empty($localtaxes_type[0]) ? '' : $localtaxes_type[0];
|
||||
$this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2];
|
||||
$this->line->remise_percent = $remise_percent;
|
||||
$this->line->subprice = $subprice;
|
||||
$this->line->subprice = (float) $pu_ht;
|
||||
$this->line->info_bits = $info_bits;
|
||||
$this->line->special_code = $special_code;
|
||||
$this->line->total_ht = $total_ht;
|
||||
@@ -3612,6 +3615,7 @@ class Commande extends CommonOrder
|
||||
$response->label = $langs->trans("OrdersToProcess");
|
||||
$response->labelShort = $langs->trans("Opened");
|
||||
$response->url = DOL_URL_ROOT.'/commande/list.php?search_status=-3&mainmenu=commercial&leftmenu=orders';
|
||||
$response->url_late = DOL_URL_ROOT.'/commande/list.php?search_option=late&mainmenu=commercial&leftmenu=orders';
|
||||
$response->img = img_object('', "order");
|
||||
|
||||
$generic_commande = new Commande($this->db);
|
||||
@@ -4374,6 +4378,8 @@ class OrderLine extends CommonOrderLine
|
||||
$this->multicurrency_total_tva = $objp->multicurrency_total_tva;
|
||||
$this->multicurrency_total_ttc = $objp->multicurrency_total_ttc;
|
||||
|
||||
$this->fetch_optionals();
|
||||
|
||||
$this->db->free($result);
|
||||
|
||||
return 1;
|
||||
@@ -4396,20 +4402,20 @@ class OrderLine extends CommonOrderLine
|
||||
|
||||
$error = 0;
|
||||
|
||||
if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
|
||||
if (empty($this->id) && !empty($this->rowid)) { // For backward compatibility
|
||||
$this->id = $this->rowid;
|
||||
}
|
||||
|
||||
// check if order line is not in a shipment line before deleting
|
||||
$sqlCheckShipmentLine = "SELECT";
|
||||
$sqlCheckShipmentLine = "SELECT";
|
||||
$sqlCheckShipmentLine .= " ed.rowid";
|
||||
$sqlCheckShipmentLine .= " FROM ".MAIN_DB_PREFIX."expeditiondet ed";
|
||||
$sqlCheckShipmentLine .= " WHERE ed.fk_origin_line = ".((int) $this->id);
|
||||
$sqlCheckShipmentLine .= " FROM " . MAIN_DB_PREFIX . "expeditiondet ed";
|
||||
$sqlCheckShipmentLine .= " WHERE ed.fk_origin_line = " . ((int) $this->id);
|
||||
|
||||
$resqlCheckShipmentLine = $this->db->query($sqlCheckShipmentLine);
|
||||
if (!$resqlCheckShipmentLine) {
|
||||
$error++;
|
||||
$this->error = $this->db->lasterror();
|
||||
$this->error = $this->db->lasterror();
|
||||
$this->errors[] = $this->error;
|
||||
} else {
|
||||
$langs->load('errors');
|
||||
@@ -4417,56 +4423,58 @@ class OrderLine extends CommonOrderLine
|
||||
if ($num > 0) {
|
||||
$error++;
|
||||
$objCheckShipmentLine = $this->db->fetch_object($resqlCheckShipmentLine);
|
||||
$this->error = $langs->trans('ErrorRecordAlreadyExists').' : '.$langs->trans('ShipmentLine').' '.$objCheckShipmentLine->rowid;
|
||||
$this->error = $langs->trans('ErrorRecordAlreadyExists') . ' : ' . $langs->trans('ShipmentLine') . ' ' . $objCheckShipmentLine->rowid;
|
||||
$this->errors[] = $this->error;
|
||||
}
|
||||
$this->db->free($resqlCheckShipmentLine);
|
||||
}
|
||||
if ($error) {
|
||||
dol_syslog(__METHOD__.'Error ; '.$this->error, LOG_ERR);
|
||||
dol_syslog(__METHOD__ . 'Error ; ' . $this->error, LOG_ERR);
|
||||
return -1;
|
||||
}
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
$sql = 'DELETE FROM '.MAIN_DB_PREFIX."commandedet WHERE rowid = ".((int) $this->id);
|
||||
|
||||
dol_syslog("OrderLine::delete", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if ($resql) {
|
||||
if (!$error && !$notrigger) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('LINEORDER_DELETE', $user);
|
||||
if ($result < 0) {
|
||||
$error++;
|
||||
}
|
||||
// End call triggers
|
||||
if (!$notrigger) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('LINEORDER_DELETE', $user);
|
||||
if ($result < 0) {
|
||||
$error++;
|
||||
}
|
||||
|
||||
// Remove extrafields
|
||||
if (!$error) {
|
||||
$result = $this->deleteExtraFields();
|
||||
if ($result < 0) {
|
||||
$error++;
|
||||
dol_syslog(get_class($this)."::delete error -4 ".$this->error, LOG_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
foreach ($this->errors as $errmsg) {
|
||||
dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
|
||||
$this->error .= ($this->error ? ', '.$errmsg : $errmsg);
|
||||
}
|
||||
$this->db->rollback();
|
||||
return -1 * $error;
|
||||
} else {
|
||||
$this->error = $this->db->lasterror();
|
||||
return -1;
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$sql = 'DELETE FROM ' . MAIN_DB_PREFIX . "commandedet WHERE rowid = " . ((int) $this->id);
|
||||
|
||||
dol_syslog("OrderLine::delete", LOG_DEBUG);
|
||||
$resql = $this->db->query($sql);
|
||||
if (!$resql) {
|
||||
$this->error = $this->db->lasterror();
|
||||
$error++;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove extrafields
|
||||
if (!$error) {
|
||||
$result = $this->deleteExtraFields();
|
||||
if ($result < 0) {
|
||||
$error++;
|
||||
dol_syslog(get_class($this) . "::delete error -4 " . $this->error, LOG_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error) {
|
||||
$this->db->commit();
|
||||
return 1;
|
||||
}
|
||||
|
||||
foreach ($this->errors as $errmsg) {
|
||||
dol_syslog(get_class($this) . "::delete " . $errmsg, LOG_ERR);
|
||||
$this->error .= ($this->error ? ', ' . $errmsg : $errmsg);
|
||||
}
|
||||
$this->db->rollback();
|
||||
return -1 * $error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,6 +45,9 @@ $action = GETPOST('action', 'aZ09');
|
||||
if ($user->socid) {
|
||||
$socid = $user->socid;
|
||||
}
|
||||
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
|
||||
$hookmanager->initHooks(array('ordercontact', 'globalcard'));
|
||||
|
||||
$result = restrictedArea($user, 'commande', $id, '');
|
||||
|
||||
$usercancreate = $user->hasRight("commande", "creer");
|
||||
|
||||
@@ -80,6 +80,10 @@ $permissiontoadd = $usercancreate;
|
||||
if ($user->socid) {
|
||||
$socid = $user->socid;
|
||||
}
|
||||
|
||||
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
|
||||
$hookmanager->initHooks(array('orderdocument', 'globalcard'));
|
||||
|
||||
$result = restrictedArea($user, 'commande', $id, '');
|
||||
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
* Copyright (C) 2016-2023 Ferran Marcet <fmarcet@2byte.es>
|
||||
* Copyright (C) 2018 Charlene Benke <charlie@patas-monkey.com>
|
||||
* Copyright (C) 2021 Anthony Berton <anthony.berton@bb2a.fr>
|
||||
* Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -118,6 +119,10 @@ $search_fk_cond_reglement = GETPOST('search_fk_cond_reglement', 'int');
|
||||
$search_fk_shipping_method = GETPOST('search_fk_shipping_method', 'int');
|
||||
$search_fk_mode_reglement = GETPOST('search_fk_mode_reglement', 'int');
|
||||
$search_fk_input_reason = GETPOST('search_fk_input_reason', 'int');
|
||||
$search_option = GETPOST('search_option', 'alpha');
|
||||
if ($search_option == 'late') {
|
||||
$search_status = '-2';
|
||||
}
|
||||
|
||||
$diroutputmassaction = $conf->commande->multidir_output[$conf->entity].'/temp/massgeneration/'.$user->id;
|
||||
|
||||
@@ -293,6 +298,7 @@ if (empty($reshook)) {
|
||||
$search_fk_shipping_method = '';
|
||||
$search_fk_mode_reglement = '';
|
||||
$search_fk_input_reason = '';
|
||||
$search_option = '';
|
||||
}
|
||||
if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')
|
||||
|| GETPOST('button_search_x', 'alpha') || GETPOST('button_search.x', 'alpha') || GETPOST('button_search', 'alpha')) {
|
||||
@@ -601,6 +607,9 @@ if (empty($reshook)) {
|
||||
if ($search_status != '') {
|
||||
$param .= '&search_status='.urlencode($search_status);
|
||||
}
|
||||
if ($search_option) {
|
||||
$param .= "&search_option=".urlencode($search_option);
|
||||
}
|
||||
if ($search_orderday) {
|
||||
$param .= '&search_orderday='.urlencode($search_orderday);
|
||||
}
|
||||
@@ -915,7 +924,9 @@ if ($search_status <> '') {
|
||||
$sql .= ' AND (c.fk_statut IN (1,2))'; // validated, in process
|
||||
}
|
||||
}
|
||||
|
||||
if ($search_option == 'late') {
|
||||
$sql .= " AND c.date_commande < '".$db->idate(dol_now() - $conf->commande->client->warning_delay)."'";
|
||||
}
|
||||
if ($search_datecloture_start) {
|
||||
$sql .= " AND c.date_cloture >= '".$db->idate($search_datecloture_start)."'";
|
||||
}
|
||||
@@ -1169,6 +1180,9 @@ if ($socid > 0) {
|
||||
if ($search_status != '') {
|
||||
$param .= '&search_status='.urlencode($search_status);
|
||||
}
|
||||
if ($search_option) {
|
||||
$param .= "&search_option=".urlencode($search_option);
|
||||
}
|
||||
if ($search_datecloture_start) {
|
||||
$param .= '&search_datecloture_startday='.dol_print_date($search_datecloture_start, '%d').'&search_datecloture_startmonth='.dol_print_date($search_datecloture_start, '%m').'&search_datecloture_startyear='.dol_print_date($search_datecloture_start, '%Y');
|
||||
}
|
||||
@@ -1466,6 +1480,7 @@ if (isModEnabled('stock') && !empty($conf->global->WAREHOUSE_ASK_WAREHOUSE_DURIN
|
||||
$moreforfilter .= img_picto($tmptitle, 'stock', 'class="pictofixedwidth"').$formproduct->selectWarehouses($search_warehouse, 'search_warehouse', '', 1, 0, 0, $tmptitle, 0, 0, array(), 'maxwidth250 widthcentpercentminusx');
|
||||
$moreforfilter .= '</div>';
|
||||
}
|
||||
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
||||
if (empty($reshook)) {
|
||||
@@ -1477,9 +1492,6 @@ if (empty($reshook)) {
|
||||
if (!empty($moreforfilter)) {
|
||||
print '<div class="liste_titre liste_titre_bydiv centpercent">';
|
||||
print $moreforfilter;
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldPreListTitle', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
|
||||
print $hookmanager->resPrint;
|
||||
print '</div>';
|
||||
}
|
||||
|
||||
@@ -2620,7 +2632,7 @@ while ($i < $imaxinloop) {
|
||||
$productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
|
||||
} else {
|
||||
$generic_product->stock_reel = $productstat_cache[$generic_commande->lines[$lig]->fk_product]['stock_reel'];
|
||||
$generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'] = $generic_product->stock_theorique;
|
||||
$generic_product->stock_theorique = $productstat_cachevirtual[$generic_commande->lines[$lig]->fk_product]['stock_reel'];
|
||||
}
|
||||
|
||||
if ($reliquat > $generic_product->stock_reel) {
|
||||
@@ -2773,7 +2785,7 @@ print '</div>'."\n";
|
||||
|
||||
print '</form>'."\n";
|
||||
|
||||
if (in_array('builddoc', $arrayofmassactions) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
if (in_array('builddoc', array_keys($arrayofmassactions)) && ($nbtotalofrecords === '' || $nbtotalofrecords)) {
|
||||
$hidegeneratedfilelistifempty = 1;
|
||||
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files) {
|
||||
$hidegeneratedfilelistifempty = 0;
|
||||
|
||||
@@ -2016,7 +2016,7 @@ if ($resql) {
|
||||
$productstat_cachevirtual[$obj->fk_product]['stock_reel'] = $generic_product->stock_theorique;
|
||||
} else {
|
||||
$generic_product->stock_reel = $productstat_cache[$obj->fk_product]['stock_reel'];
|
||||
$generic_product->stock_theorique = $productstat_cachevirtual[$obj->fk_product]['stock_reel'] = $generic_product->stock_theorique;
|
||||
$generic_product->stock_theorique = $productstat_cachevirtual[$obj->fk_product]['stock_reel'];
|
||||
}
|
||||
|
||||
if ($reliquat > $generic_product->stock_reel) {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Copyright (C) 2017 Pierre-Henry Favre <support@atm-consulting.fr>
|
||||
* Copyright (C) 2020 Maxime DEMAREST <maxime@indelog.fr>
|
||||
* Copyright (C) 2021 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
|
||||
* Copyright (C) 2022 Alexandre Spangaro <aspangaro@open-dsi.fr>
|
||||
* Copyright (C) 2022-2024 Alexandre Spangaro <aspangaro@easya.solutions>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
@@ -724,18 +724,18 @@ if (!empty($date_start) && !empty($date_stop)) {
|
||||
print_liste_field_titre($arrayfields['date']['label'], $_SERVER["PHP_SELF"], "date", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
|
||||
print_liste_field_titre($arrayfields['date_due']['label'], $_SERVER["PHP_SELF"], "date_due", "", $param, '', $sortfield, $sortorder, 'center nowrap ');
|
||||
print_liste_field_titre($arrayfields['ref']['label'], $_SERVER["PHP_SELF"], "", "", $param, '', $sortfield, $sortorder, 'nowraponall ');
|
||||
print '<td>'.$langs->trans("Document").'</td>';
|
||||
print '<td>'.$langs->trans("Paid").'</td>';
|
||||
print '<td align="right">'.$langs->trans("TotalHT").(isModEnabled('multicurrency') ? ' ('.$langs->getCurrencySymbol($conf->currency).')' : '').'</td>';
|
||||
print '<td align="right">'.$langs->trans("TotalTTC").(isModEnabled('multicurrency') ? ' ('.$langs->getCurrencySymbol($conf->currency).')' : '').'</td>';
|
||||
print '<td align="right">'.$langs->trans("TotalVAT").(isModEnabled('multicurrency') ? ' ('.$langs->getCurrencySymbol($conf->currency).')' : '').'</td>';
|
||||
print '<th>'.$langs->trans("Document").'</th>';
|
||||
print '<th>'.$langs->trans("Paid").'</th>';
|
||||
print '<th class="right">'.$langs->trans("TotalHT").(isModEnabled('multicurrency') ? ' ('.$langs->getCurrencySymbol($conf->currency).')' : '').'</th>';
|
||||
print '<th class="right">'.$langs->trans("TotalTTC").(isModEnabled('multicurrency') ? ' ('.$langs->getCurrencySymbol($conf->currency).')' : '').'</th>';
|
||||
print '<th class="right">'.$langs->trans("TotalVAT").(isModEnabled('multicurrency') ? ' ('.$langs->getCurrencySymbol($conf->currency).')' : '').'</th>';
|
||||
|
||||
print '<td>'.$langs->trans("ThirdParty").'</td>';
|
||||
print '<td class="center">'.$langs->trans("Code").'</td>';
|
||||
print '<td class="center">'.$langs->trans("Country").'</td>';
|
||||
print '<td class="center">'.$langs->trans("VATIntra").'</td>';
|
||||
print '<th>'.$langs->trans("ThirdParty").'</th>';
|
||||
print '<th class="center">'.$langs->trans("Code").'</th>';
|
||||
print '<th class="center">'.$langs->trans("Country").'</th>';
|
||||
print '<th class="center">'.$langs->trans("VATIntra").'</th>';
|
||||
if (isModEnabled('multicurrency')) {
|
||||
print '<td class="center">'.$langs->trans("Currency").'</td>';
|
||||
print '<th class="center">'.$langs->trans("Currency").'</th>';
|
||||
}
|
||||
print '</tr>';
|
||||
|
||||
@@ -852,9 +852,9 @@ if (!empty($date_start) && !empty($date_stop)) {
|
||||
print '<td class="center">'.($data['paid'] ? yn($data['paid']) : '').'</td>';
|
||||
|
||||
// Total WOT
|
||||
print '<td align="right"><span class="amount">'.price(price2num($data['sens'] ? $data['amount_ht'] : -$data['amount_ht'], 'MT'))."</span></td>\n";
|
||||
print '<td class="right"><span class="amount">'.price(price2num($data['sens'] ? $data['amount_ht'] : -$data['amount_ht'], 'MT'))."</span></td>\n";
|
||||
// Total INCT
|
||||
print '<td align="right"><span class="amount">';
|
||||
print '<td class="right"><span class="amount">';
|
||||
$tooltip = $langs->trans("TotalVAT").' : '.price(price2num($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'], 'MT'));
|
||||
if (!empty($data['amount_localtax1'])) {
|
||||
$tooltip .= '<br>'.$langs->transcountrynoentities("TotalLT1", $mysoc->country_code).' : '.price(price2num($data['sens'] ? $data['amount_localtax1'] : -$data['amount_localtax1'], 'MT'));
|
||||
@@ -868,7 +868,7 @@ if (!empty($date_start) && !empty($date_stop)) {
|
||||
print '<span class="classfortooltip" title="'.dol_escape_htmltag($tooltip).'">'.price(price2num($data['sens'] ? $data['amount_ttc'] : -$data['amount_ttc'], 'MT')).'</span>';
|
||||
print "</span></td>\n";
|
||||
// Total VAT
|
||||
print '<td align="right"><span class="amount">'.price(price2num($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'], 'MT'))."</span></td>\n";
|
||||
print '<td class="right"><span class="amount">'.price(price2num($data['sens'] ? $data['amount_vat'] : -$data['amount_vat'], 'MT'))."</span></td>\n";
|
||||
|
||||
print '<td class="tdoverflowmax150" title="'.dol_escape_htmltag($data['thirdparty_name']).'">'.dol_escape_htmltag($data['thirdparty_name'])."</td>\n";
|
||||
|
||||
@@ -899,9 +899,9 @@ if (!empty($date_start) && !empty($date_stop)) {
|
||||
// Total credits
|
||||
print '<tr class="liste_total">';
|
||||
print '<td colspan="6" class="right">'.$langs->trans('Total').' '.$langs->trans('Income').'</td>';
|
||||
print '<td align="right">'.price(price2num($totalET_credit, 'MT')).'</td>';
|
||||
print '<td align="right">'.price(price2num($totalIT_credit, 'MT')).'</td>';
|
||||
print '<td align="right">'.price(price2num($totalVAT_credit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalET_credit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalIT_credit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalVAT_credit, 'MT')).'</td>';
|
||||
print '<td colspan="4"></td>';
|
||||
if (isModEnabled('multicurrency')) {
|
||||
print '<td></td>';
|
||||
@@ -910,9 +910,9 @@ if (!empty($date_start) && !empty($date_stop)) {
|
||||
// Total debits
|
||||
print '<tr class="liste_total">';
|
||||
print '<td colspan="6" class="right">'.$langs->trans('Total').' '.$langs->trans('Outcome').'</td>';
|
||||
print '<td align="right">'.price(price2num($totalET_debit, 'MT')).'</td>';
|
||||
print '<td align="right">'.price(price2num($totalIT_debit, 'MT')).'</td>';
|
||||
print '<td align="right">'.price(price2num($totalVAT_debit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalET_debit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalIT_debit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalVAT_debit, 'MT')).'</td>';
|
||||
print '<td colspan="4"></td>';
|
||||
if (isModEnabled('multicurrency')) {
|
||||
print '<td></td>';
|
||||
@@ -921,9 +921,9 @@ if (!empty($date_start) && !empty($date_stop)) {
|
||||
// Balance
|
||||
print '<tr class="liste_total">';
|
||||
print '<td colspan="6" class="right">'.$langs->trans('Total').'</td>';
|
||||
print '<td align="right">'.price(price2num($totalET_credit + $totalET_debit, 'MT')).'</td>';
|
||||
print '<td align="right">'.price(price2num($totalIT_credit + $totalIT_debit, 'MT')).'</td>';
|
||||
print '<td align="right">'.price(price2num($totalVAT_credit + $totalVAT_debit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalET_credit + $totalET_debit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalIT_credit + $totalIT_debit, 'MT')).'</td>';
|
||||
print '<td class="right">'.price(price2num($totalVAT_credit + $totalVAT_debit, 'MT')).'</td>';
|
||||
print '<td colspan="4"></td>';
|
||||
if (isModEnabled('multicurrency')) {
|
||||
print '<td></td>';
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user