forked from Wavyzz/dolibarr
Compare commits
1024 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1d57a6bd1 | ||
|
|
16904d12f8 | ||
|
|
1525b9c85e | ||
|
|
ffe07999cf | ||
|
|
24146d89c5 | ||
|
|
477d755bbc | ||
|
|
f85b53a4ca | ||
|
|
a6e01fe7b7 | ||
|
|
43c2336683 | ||
|
|
e1b919366e | ||
|
|
40e4a6959f | ||
|
|
52ae202aff | ||
|
|
2ca2fe7f28 | ||
|
|
140310c508 | ||
|
|
64cf2513bd | ||
|
|
a3969c1d2c | ||
|
|
d9563ac0ed | ||
|
|
bea2f674f0 | ||
|
|
80494870c0 | ||
|
|
d25847602b | ||
|
|
283efbbffe | ||
|
|
2e430a71a3 | ||
|
|
faf2971ff7 | ||
|
|
acf5e30b30 | ||
|
|
76b5540124 | ||
|
|
8bb63c5963 | ||
|
|
f532f85d8c | ||
|
|
a63eae7903 | ||
|
|
79210c0120 | ||
|
|
d87ebbf926 | ||
|
|
08b105502e | ||
|
|
bd2aba1a2f | ||
|
|
a4601686a6 | ||
|
|
bcf6d6a7a2 | ||
|
|
db5f33442a | ||
|
|
84ba1852aa | ||
|
|
65a3b0893d | ||
|
|
669c939bcd | ||
|
|
92454d671f | ||
|
|
f33fe1036f | ||
|
|
f43f2909ff | ||
|
|
fc8b0a80c0 | ||
|
|
4adc4a31e2 | ||
|
|
7920cf8596 | ||
|
|
c5451242e7 | ||
|
|
60f089c015 | ||
|
|
8e689c1479 | ||
|
|
8efe6d477e | ||
|
|
870c2a8f50 | ||
|
|
7d898184b5 | ||
|
|
bba84133e7 | ||
|
|
01aa901f93 | ||
|
|
96a74c4976 | ||
|
|
a69ba88857 | ||
|
|
b05be5e1df | ||
|
|
247c38923f | ||
|
|
e818bf732d | ||
|
|
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 | ||
|
|
52ab3dbba4 | ||
|
|
66a175e48d | ||
|
|
e24da32424 | ||
|
|
a13b720598 | ||
|
|
28769a13eb | ||
|
|
86971c7b86 | ||
|
|
daccab5a07 | ||
|
|
4d32d93ee2 | ||
|
|
abc9eb7bdc | ||
|
|
ec19dcc8f8 | ||
|
|
9051e411d0 | ||
|
|
382f9ce95d |
588
.github/logToCs.py
vendored
588
.github/logToCs.py
vendored
@@ -1,588 +0,0 @@
|
||||
#!/usr/bin/env python3
|
||||
# pylint: disable=invalid-name
|
||||
"""
|
||||
Convert a log to CheckStyle format.
|
||||
|
||||
Url: https://github.com/mdeweerd/LogToCheckStyle
|
||||
|
||||
The log can then be used for generating annotations in a github action.
|
||||
|
||||
Note: this script is very young and "quick and dirty".
|
||||
Patterns can be added to "PATTERNS" to match more messages.
|
||||
|
||||
# Examples
|
||||
|
||||
Assumes that logToCs.py is available as .github/logToCs.py.
|
||||
|
||||
## Example 1:
|
||||
|
||||
|
||||
```yaml
|
||||
- run: |
|
||||
pre-commit run -all-files | tee pre-commit.log
|
||||
.github/logToCs.py pre-commit.log pre-commit.xml
|
||||
- uses: staabm/annotate-pull-request-from-checkstyle-action@v1
|
||||
with:
|
||||
files: pre-commit.xml
|
||||
notices-as-warnings: true # optional
|
||||
```
|
||||
|
||||
## Example 2:
|
||||
|
||||
|
||||
```yaml
|
||||
- run: |
|
||||
pre-commit run --all-files | tee pre-commit.log
|
||||
- name: Add results to PR
|
||||
if: ${{ always() }}
|
||||
run: |
|
||||
.github/logToCs.py pre-commit.log | cs2pr
|
||||
```
|
||||
|
||||
Author(s):
|
||||
- https://github.com/mdeweerd
|
||||
|
||||
License: MIT License
|
||||
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import datetime as dt
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import xml.etree.ElementTree as ET # nosec
|
||||
|
||||
|
||||
def remove_prefix(string, prefix):
|
||||
"""
|
||||
Remove prefix from string
|
||||
|
||||
Provided for backward compatibility.
|
||||
"""
|
||||
if prefix and string.startswith(prefix):
|
||||
return string[len(prefix) :]
|
||||
return string
|
||||
|
||||
|
||||
def convert_notices_to_checkstyle(notices, root_path=None):
|
||||
"""
|
||||
Convert annotation list to CheckStyle xml string
|
||||
"""
|
||||
root = ET.Element("checkstyle")
|
||||
for fields in notices:
|
||||
add_error_entry(root, **fields, root_path=root_path)
|
||||
return ET.tostring(root, encoding="utf_8").decode("utf_8")
|
||||
|
||||
|
||||
def convert_lines_to_notices(lines):
|
||||
"""
|
||||
Convert provided message to CheckStyle format.
|
||||
"""
|
||||
notices = []
|
||||
for line in lines:
|
||||
fields = parse_message(line)
|
||||
if fields:
|
||||
notices.append(fields)
|
||||
return notices
|
||||
|
||||
|
||||
def convert_text_to_notices(text):
|
||||
"""
|
||||
Convert provided message to CheckStyle format.
|
||||
"""
|
||||
return parse_file(text)
|
||||
|
||||
|
||||
# Initial version for Checkrun from:
|
||||
# https://github.com/tayfun/flake8-your-pr/blob/50a175cde4dd26a656734c5b64ba1e5bb27151cb/src/main.py#L7C1-L123C36
|
||||
# MIT Licence
|
||||
class CheckRun:
|
||||
"""
|
||||
Represents the check run
|
||||
"""
|
||||
|
||||
GITHUB_TOKEN = os.environ.get("GITHUB_TOKEN", None)
|
||||
GITHUB_EVENT_PATH = os.environ.get("GITHUB_EVENT_PATH", None)
|
||||
|
||||
URI = "https://api.github.com"
|
||||
API_VERSION = "2022-11-28"
|
||||
ACCEPT_HEADER_VALUE = "application/vnd.github+json"
|
||||
AUTH_HEADER_VALUE = f"Bearer {GITHUB_TOKEN}"
|
||||
# This is the max annotations Github API accepts in one go.
|
||||
MAX_ANNOTATIONS = 50
|
||||
|
||||
def __init__(self):
|
||||
"""
|
||||
Initialise Check Run object with information from checkrun
|
||||
"""
|
||||
self.read_event_file()
|
||||
self.read_meta_data()
|
||||
|
||||
def read_event_file(self):
|
||||
"""
|
||||
Read the event file to get the event information later.
|
||||
"""
|
||||
if self.GITHUB_EVENT_PATH is None:
|
||||
raise ValueError("Not running in github workflow")
|
||||
with open(self.GITHUB_EVENT_PATH, encoding="utf_8") as event_file:
|
||||
self.event = json.loads(event_file.read())
|
||||
|
||||
def read_meta_data(self):
|
||||
"""
|
||||
Get meta data from event information
|
||||
"""
|
||||
self.repo_full_name = self.event["repository"]["full_name"]
|
||||
pull_request = self.event.get("pull_request")
|
||||
print("%r", self.event)
|
||||
if pull_request:
|
||||
self.head_sha = pull_request["head"]["sha"]
|
||||
else:
|
||||
print("%r", self.event)
|
||||
check_suite = self.event.get("check_suite", None)
|
||||
if check_suite is not None:
|
||||
self.head_sha = check_suite["pull_requests"][0]["base"]["sha"]
|
||||
else:
|
||||
self.head_sha = None # Can't annotate?
|
||||
|
||||
def submit( # pylint: disable=too-many-arguments
|
||||
self,
|
||||
notices,
|
||||
title=None,
|
||||
summary=None,
|
||||
text=None,
|
||||
conclusion=None,
|
||||
):
|
||||
"""
|
||||
Submit annotations to github
|
||||
|
||||
See:
|
||||
https://docs.github.com/en/rest/checks/runs?apiVersion=2022-11-28
|
||||
#update-a-check-run
|
||||
|
||||
:param conclusion: success, failure
|
||||
"""
|
||||
# pylint: disable=import-outside-toplevel
|
||||
import requests # Import here to not impose presence of module
|
||||
|
||||
if self.head_sha is None:
|
||||
return
|
||||
|
||||
output = {
|
||||
"annotations": notices[: CheckRun.MAX_ANNOTATIONS],
|
||||
}
|
||||
if title is not None:
|
||||
output["title"] = title
|
||||
if summary is not None:
|
||||
output["summary"] = summary
|
||||
if text is not None:
|
||||
output["text"] = text
|
||||
if conclusion is None:
|
||||
# action_required, cancelled, failure, neutral, success
|
||||
# skipped, stale, timed_out
|
||||
if bool(notices):
|
||||
conclusion = "failure"
|
||||
else:
|
||||
conclusion = "success"
|
||||
|
||||
payload = {
|
||||
"name": "log-to-pr-annotation",
|
||||
"head_sha": self.head_sha,
|
||||
"status": "completed", # queued, in_progress, completed
|
||||
"conclusion": conclusion,
|
||||
# "started_at": dt.datetime.now(dt.timezone.utc).isoformat(),
|
||||
"completed_at": dt.datetime.now(dt.timezone.utc).isoformat(),
|
||||
"output": output,
|
||||
}
|
||||
|
||||
# Create the check-run
|
||||
response = requests.post(
|
||||
f"{self.URI}/repos/{self.repo_full_name}/check-runs",
|
||||
headers={
|
||||
"Accept": self.ACCEPT_HEADER_VALUE,
|
||||
"Authorization": self.AUTH_HEADER_VALUE,
|
||||
"X-GitHub-Api-Version": self.API_VERSION,
|
||||
},
|
||||
json=payload,
|
||||
timeout=30,
|
||||
)
|
||||
print(response.content)
|
||||
response.raise_for_status()
|
||||
|
||||
|
||||
ANY_REGEX = r".*?"
|
||||
FILE_REGEX = r"\s*(?P<file_name>\S.*?)\s*?"
|
||||
FILEGROUP_REGEX = r"\s*(?P<file_group>\S.*?)\s*?"
|
||||
EOL_REGEX = r"[\r\n]"
|
||||
LINE_REGEX = r"\s*(?P<line>\d+?)\s*?"
|
||||
COLUMN_REGEX = r"\s*(?P<column>\d+?)\s*?"
|
||||
SEVERITY_REGEX = r"\s*(?P<severity>error|warning|notice|style|info)\s*?"
|
||||
MSG_REGEX = r"\s*(?P<message>.+?)\s*?"
|
||||
MULTILINE_MSG_REGEX = r"\s*(?P<message>(?:.|.[\r\n])+)"
|
||||
# cpplint confidence index
|
||||
CONFIDENCE_REGEX = r"\s*\[(?P<confidence>\d+)\]\s*?"
|
||||
|
||||
|
||||
# List of message patterns, add more specific patterns earlier in the list
|
||||
# Creating patterns by using constants makes them easier to define and read.
|
||||
PATTERNS = [
|
||||
# beautysh
|
||||
# File ftp.sh: error: "esac" before "case" in line 90.
|
||||
re.compile(
|
||||
f"^File {FILE_REGEX}:{SEVERITY_REGEX}:"
|
||||
f" {MSG_REGEX} in line {LINE_REGEX}.$"
|
||||
),
|
||||
# beautysh
|
||||
# File socks4echo.sh: error: indent/outdent mismatch: -2.
|
||||
re.compile(f"^File {FILE_REGEX}:{SEVERITY_REGEX}: {MSG_REGEX}$"),
|
||||
# yamllint
|
||||
# ##[group].pre-commit-config.yaml
|
||||
# ##[error]97:14 [trailing-spaces] trailing spaces
|
||||
# ##[endgroup]
|
||||
re.compile(rf"^##\[group\]{FILEGROUP_REGEX}$"), # Start file group
|
||||
re.compile(
|
||||
rf"^##\[{SEVERITY_REGEX}\]{LINE_REGEX}:{COLUMN_REGEX}{MSG_REGEX}$"
|
||||
), # Msg
|
||||
re.compile(r"^##(?P<file_endgroup>\[endgroup\])$"), # End file group
|
||||
# File socks4echo.sh: error: indent/outdent mismatch: -2.
|
||||
re.compile(f"^File {FILE_REGEX}:{SEVERITY_REGEX}: {MSG_REGEX}$"),
|
||||
# Emacs style
|
||||
# path/to/file:845:5: error - Expected 1 space after closing brace
|
||||
re.compile(
|
||||
rf"^{FILE_REGEX}:{LINE_REGEX}:{COLUMN_REGEX}:{SEVERITY_REGEX}"
|
||||
rf"-?\s{MSG_REGEX}$"
|
||||
),
|
||||
# ESLint (JavaScript Linter), RoboCop, shellcheck
|
||||
# path/to/file.js:10:2: Some linting issue
|
||||
# path/to/file.rb:10:5: Style/Indentation: Incorrect indentation detected
|
||||
# path/to/script.sh:10:1: SC2034: Some shell script issue
|
||||
re.compile(f"^{FILE_REGEX}:{LINE_REGEX}:{COLUMN_REGEX}: {MSG_REGEX}$"),
|
||||
# Cpplint default output:
|
||||
# '%s:%s: %s [%s] [%d]\n'
|
||||
# % (filename, linenum, message, category, confidence)
|
||||
re.compile(f"^{FILE_REGEX}:{LINE_REGEX}:{MSG_REGEX}{CONFIDENCE_REGEX}$"),
|
||||
# MSVC
|
||||
# file.cpp(10): error C1234: Some error message
|
||||
re.compile(
|
||||
f"^{FILE_REGEX}\\({LINE_REGEX}\\):{SEVERITY_REGEX}{MSG_REGEX}$"
|
||||
),
|
||||
# Java compiler
|
||||
# File.java:10: error: Some error message
|
||||
re.compile(f"^{FILE_REGEX}:{LINE_REGEX}:{SEVERITY_REGEX}:{MSG_REGEX}$"),
|
||||
# Python
|
||||
# File ".../logToCs.py", line 90 (note: code line follows)
|
||||
re.compile(f'^File "{FILE_REGEX}", line {LINE_REGEX}$'),
|
||||
# Pylint, others
|
||||
# path/to/file.py:10: [C0111] Missing docstring
|
||||
# others
|
||||
re.compile(f"^{FILE_REGEX}:{LINE_REGEX}: {MSG_REGEX}$"),
|
||||
# Shellcheck:
|
||||
# In script.sh line 76:
|
||||
re.compile(
|
||||
f"^In {FILE_REGEX} line {LINE_REGEX}:{EOL_REGEX}?"
|
||||
f"({MULTILINE_MSG_REGEX})?{EOL_REGEX}{EOL_REGEX}"
|
||||
),
|
||||
# eslint:
|
||||
# /path/to/filename
|
||||
# 14:5 error Unexpected trailing comma comma-dangle
|
||||
re.compile(
|
||||
f"^{FILE_REGEX}{EOL_REGEX}"
|
||||
rf"\s+{LINE_REGEX}:{COLUMN_REGEX}\s+{SEVERITY_REGEX}\s+{MSG_REGEX}$"
|
||||
),
|
||||
]
|
||||
|
||||
# Exceptionnaly some regexes match messages that are not error.
|
||||
# This pattern matches those exceptions
|
||||
EXCLUDE_MSG_PATTERN = re.compile(
|
||||
r"^("
|
||||
r"Placeholder pattern" # To remove on first message pattern
|
||||
r")"
|
||||
)
|
||||
|
||||
# Exceptionnaly some regexes match messages that are not error.
|
||||
# This pattern matches those exceptions
|
||||
EXCLUDE_FILE_PATTERN = re.compile(
|
||||
r"^("
|
||||
# Codespell: (appears as a file name):
|
||||
r"Used config files\b"
|
||||
r")"
|
||||
)
|
||||
|
||||
# Severities available in CodeSniffer report format
|
||||
SEVERITY_NOTICE = "notice"
|
||||
SEVERITY_WARNING = "warning"
|
||||
SEVERITY_ERROR = "error"
|
||||
|
||||
|
||||
def strip_ansi(text: str):
|
||||
"""
|
||||
Strip ANSI escape sequences from string (colors, etc)
|
||||
"""
|
||||
return re.sub(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])", "", text)
|
||||
|
||||
|
||||
def parse_file(text):
|
||||
"""
|
||||
Parse all messages in a file
|
||||
|
||||
Returns the fields in a dict.
|
||||
"""
|
||||
# pylint: disable=too-many-branches,too-many-statements
|
||||
# regex required to allow same group names
|
||||
try:
|
||||
import regex # pylint: disable=import-outside-toplevel
|
||||
except ImportError as exc:
|
||||
raise ImportError(
|
||||
"The 'parsefile' method requires 'python -m pip install regex'"
|
||||
) from exc
|
||||
|
||||
patterns = [pattern.pattern for pattern in PATTERNS]
|
||||
# patterns = [PATTERNS[0].pattern]
|
||||
|
||||
file_group = None # The file name for the group (if any)
|
||||
full_regex = "(?:(?:" + (")|(?:".join(patterns)) + "))"
|
||||
results = []
|
||||
|
||||
for fields in regex.finditer(
|
||||
full_regex, strip_ansi(text), regex.MULTILINE | regex.IGNORECASE
|
||||
):
|
||||
if not fields:
|
||||
continue
|
||||
result = fields.groupdict()
|
||||
|
||||
if len(result) == 0:
|
||||
continue
|
||||
|
||||
severity = result.get("severity", None)
|
||||
file_name = result.get("file_name", None)
|
||||
confidence = result.pop("confidence", None)
|
||||
new_file_group = result.pop("file_group", None)
|
||||
file_endgroup = result.pop("file_endgroup", None)
|
||||
message = result.get("message", None)
|
||||
|
||||
if new_file_group is not None:
|
||||
# Start of file_group, just store file
|
||||
file_group = new_file_group
|
||||
continue
|
||||
|
||||
if file_endgroup is not None:
|
||||
file_group = None
|
||||
continue
|
||||
|
||||
if file_name is None:
|
||||
if file_group is not None:
|
||||
file_name = file_group
|
||||
result["file_name"] = file_name
|
||||
else:
|
||||
# No filename, skip
|
||||
continue
|
||||
else:
|
||||
if EXCLUDE_FILE_PATTERN.search(file_name):
|
||||
# This file_name is excluded
|
||||
continue
|
||||
|
||||
if message is not None:
|
||||
if EXCLUDE_MSG_PATTERN.search(message):
|
||||
# This message is excluded
|
||||
continue
|
||||
|
||||
if confidence is not None:
|
||||
# Convert confidence level of cpplint
|
||||
# to warning, etc.
|
||||
confidence = int(confidence)
|
||||
|
||||
if confidence <= 1:
|
||||
severity = SEVERITY_NOTICE
|
||||
elif confidence >= 5:
|
||||
severity = SEVERITY_ERROR
|
||||
else:
|
||||
severity = SEVERITY_WARNING
|
||||
|
||||
if severity is None:
|
||||
severity = SEVERITY_ERROR
|
||||
else:
|
||||
severity = severity.lower()
|
||||
|
||||
if severity in ["info", "style"]:
|
||||
severity = SEVERITY_NOTICE
|
||||
|
||||
result["severity"] = severity
|
||||
|
||||
results.append(result)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
def parse_message(message):
|
||||
"""
|
||||
Parse message until it matches a pattern.
|
||||
|
||||
Returns the fields in a dict.
|
||||
"""
|
||||
for pattern in PATTERNS:
|
||||
fields = pattern.match(message, re.IGNORECASE)
|
||||
if not fields:
|
||||
continue
|
||||
result = fields.groupdict()
|
||||
if len(result) == 0:
|
||||
continue
|
||||
|
||||
if "confidence" in result:
|
||||
# Convert confidence level of cpplint
|
||||
# to warning, etc.
|
||||
confidence = int(result["confidence"])
|
||||
del result["confidence"]
|
||||
|
||||
if confidence <= 1:
|
||||
severity = SEVERITY_NOTICE
|
||||
elif confidence >= 5:
|
||||
severity = SEVERITY_ERROR
|
||||
else:
|
||||
severity = SEVERITY_WARNING
|
||||
result["severity"] = severity
|
||||
|
||||
if "severity" not in result:
|
||||
result["severity"] = SEVERITY_ERROR
|
||||
else:
|
||||
result["severity"] = result["severity"].lower()
|
||||
|
||||
if result["severity"] in ["info", "style"]:
|
||||
result["severity"] = SEVERITY_NOTICE
|
||||
|
||||
return result
|
||||
|
||||
# Nothing matched
|
||||
return None
|
||||
|
||||
|
||||
def add_error_entry( # pylint: disable=too-many-arguments
|
||||
root,
|
||||
severity,
|
||||
file_name,
|
||||
line=None,
|
||||
column=None,
|
||||
message=None,
|
||||
source=None,
|
||||
root_path=None,
|
||||
):
|
||||
"""
|
||||
Add error information to the CheckStyle output being created.
|
||||
"""
|
||||
file_element = find_or_create_file_element(
|
||||
root, file_name, root_path=root_path
|
||||
)
|
||||
error_element = ET.SubElement(file_element, "error")
|
||||
error_element.set("severity", severity)
|
||||
if line:
|
||||
error_element.set("line", line)
|
||||
if column:
|
||||
error_element.set("column", column)
|
||||
if message:
|
||||
error_element.set("message", message)
|
||||
if source:
|
||||
# To verify if this is a valid attribute
|
||||
error_element.set("source", source)
|
||||
|
||||
|
||||
def find_or_create_file_element(root, file_name: str, root_path=None):
|
||||
"""
|
||||
Find/create file element in XML document tree.
|
||||
"""
|
||||
|
||||
if root_path is not None:
|
||||
file_name = remove_prefix(file_name, root_path)
|
||||
for file_element in root.findall("file"):
|
||||
if file_element.get("name") == file_name:
|
||||
return file_element
|
||||
file_element = ET.SubElement(root, "file")
|
||||
file_element.set("name", file_name)
|
||||
return file_element
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Parse the script arguments and get the conversion done.
|
||||
"""
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Convert messages to Checkstyle XML format."
|
||||
)
|
||||
parser.add_argument(
|
||||
"input", help="Input file. Use '-' for stdin.", nargs="?", default="-"
|
||||
)
|
||||
parser.add_argument(
|
||||
"output",
|
||||
help="Output file. Use '-' for stdout.",
|
||||
nargs="?",
|
||||
default="-",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-i",
|
||||
"--in",
|
||||
dest="input_named",
|
||||
help="Input filename. Overrides positional input.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o",
|
||||
"--out",
|
||||
dest="output_named",
|
||||
help="Output filename. Overrides positional output.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--root",
|
||||
metavar="ROOT_PATH",
|
||||
help="Root directory to remove from file paths."
|
||||
" Defaults to working directory.",
|
||||
default=os.getcwd(),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--github-annotate",
|
||||
action=argparse.BooleanOptionalAction,
|
||||
help="Annotate when in Github workflow.",
|
||||
# Currently disabled,
|
||||
# Future: (os.environ.get("GITHUB_EVENT_PATH", None) is not None),
|
||||
default=False,
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.input == "-" and args.input_named:
|
||||
with open(
|
||||
args.input_named, encoding="utf_8", errors="surrogateescape"
|
||||
) as input_file:
|
||||
text = input_file.read()
|
||||
elif args.input != "-":
|
||||
with open(
|
||||
args.input, encoding="utf_8", errors="surrogateescape"
|
||||
) as input_file:
|
||||
text = input_file.read()
|
||||
else:
|
||||
text = sys.stdin.read()
|
||||
|
||||
root_path = os.path.join(args.root, "")
|
||||
|
||||
try:
|
||||
notices = convert_text_to_notices(text)
|
||||
except ImportError:
|
||||
notices = convert_lines_to_notices(re.split(r"[\r\n]+", text))
|
||||
|
||||
checkstyle_xml = convert_notices_to_checkstyle(
|
||||
notices, root_path=root_path
|
||||
)
|
||||
|
||||
if args.output == "-" and args.output_named:
|
||||
with open(args.output_named, "w", encoding="utf_8") as output_file:
|
||||
output_file.write(checkstyle_xml)
|
||||
elif args.output != "-":
|
||||
with open(args.output, "w", encoding="utf_8") as output_file:
|
||||
output_file.write(checkstyle_xml)
|
||||
else:
|
||||
print(checkstyle_xml)
|
||||
|
||||
if args.github_annotate:
|
||||
checkrun = CheckRun()
|
||||
checkrun.submit(notices)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
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
|
||||
@@ -3,8 +3,6 @@ on:
|
||||
schedule:
|
||||
- cron: "0 20 * * 1,3,5"
|
||||
workflow_dispatch:
|
||||
branches:
|
||||
- develop
|
||||
# push:
|
||||
# branches:
|
||||
# - develop
|
||||
51
.github/workflows/pr-18.yaml
vendored
Normal file
51
.github/workflows/pr-18.yaml
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
# 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 and label for v18
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize, reopened]
|
||||
branches:
|
||||
- "18.0"
|
||||
push:
|
||||
branches:
|
||||
- "18.0"
|
||||
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
assign-and-label-v18:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
#- name: Install GitHub CLI
|
||||
# run: sudo apt-get install gh
|
||||
|
||||
- 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: |
|
||||
echo "env.url=${{env.url}}"
|
||||
gh pr edit "${{env.url}}" --add-reviewer rycks
|
||||
gh pr edit "${{env.url}}" --add-reviewer lvessiller-opendsi
|
||||
#gh pr edit "${{env.url}}" --add-reviewer eldy
|
||||
gh pr edit "${{env.url}}" --add-label "Issue for v18 maintenance Team"
|
||||
65
.github/workflows/pre-commit.yml
vendored
65
.github/workflows/pre-commit.yml
vendored
@@ -7,7 +7,6 @@ jobs:
|
||||
pre-commit:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
LOG_TO_CS: .github/logToCs.py
|
||||
RAW_LOG: pre-commit.log
|
||||
CS_XML: pre-commit.xml
|
||||
steps:
|
||||
@@ -15,18 +14,18 @@ jobs:
|
||||
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
|
||||
uses: tj-actions/changed-files@v42
|
||||
if: github.event_name == 'pull_request'
|
||||
with:
|
||||
files: |
|
||||
**.php
|
||||
if: env.gh_event == 'pull_request'
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: ./.github/scripts/get_changed_php.sh
|
||||
|
||||
# Checkout git sources to analyze
|
||||
- uses: actions/checkout@v4
|
||||
# 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
|
||||
@@ -37,12 +36,27 @@ jobs:
|
||||
with:
|
||||
cache: pip
|
||||
python-version: "3.11"
|
||||
- run: python -m pip install pre-commit regex
|
||||
- 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
|
||||
@@ -63,24 +77,6 @@ jobs:
|
||||
# files: |
|
||||
# **.php
|
||||
|
||||
- name: Setup PHPCS
|
||||
uses: shivammathur/setup-php@v2
|
||||
# Install when we're going to run phpcs
|
||||
if: |
|
||||
steps.changed-php.outputs.any_changed == 'true'
|
||||
||
|
||||
(
|
||||
github.event_name == 'push'
|
||||
&& (
|
||||
github.event.ref == 'refs/heads/develop'
|
||||
|| endsWith(github.event.ref, '.0')
|
||||
)
|
||||
)
|
||||
with:
|
||||
php-version: 8.1
|
||||
coverage: none # disable xdebug, pcov
|
||||
tools: phpcs
|
||||
|
||||
- name: Run some pre-commit hooks on selected changed files only
|
||||
if: steps.changed-php.outputs.any_changed == 'true'
|
||||
env:
|
||||
@@ -102,19 +98,12 @@ jobs:
|
||||
pre-commit run --hook-stage manual -a php-cs-with-cache | tee -a ${RAW_LOG}
|
||||
ls -l ~/.cache/pre-commit/
|
||||
|
||||
# If error, we convert log in the checkstyle format
|
||||
- name: Convert Raw Log to CheckStyle format
|
||||
if: ${{ failure() }}
|
||||
run: |
|
||||
python ${LOG_TO_CS} ${RAW_LOG} ${CS_XML}
|
||||
# Annotate the git sources with the log messages
|
||||
- name: Annotate Source Code with Messages
|
||||
uses: staabm/annotate-pull-request-from-checkstyle-action@v1
|
||||
- name: Convert Raw Log to Annotations
|
||||
uses: mdeweerd/logToCheckStyle@v2024.2.9
|
||||
if: ${{ failure() }}
|
||||
with:
|
||||
files: ${{ env.CS_XML }}
|
||||
notices-as-warnings: true # optional
|
||||
prepend-filename: true # optional
|
||||
in: ${{ env.RAW_LOG }}
|
||||
|
||||
# Save the precommit cache
|
||||
- uses: actions/cache/save@v4
|
||||
if: ${{ ! cancelled() }}
|
||||
|
||||
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:
|
||||
|
||||
@@ -6,7 +6,7 @@ repos:
|
||||
rev: v4.5.0
|
||||
hooks:
|
||||
- id: no-commit-to-branch
|
||||
args: [--branch, develop, --pattern, \d+.0]
|
||||
args: [--branch, develop, --pattern, \d+.0$]
|
||||
- id: check-yaml
|
||||
args: [--unsafe]
|
||||
- id: check-json
|
||||
@@ -81,6 +81,8 @@ repos:
|
||||
]
|
||||
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)$
|
||||
|
||||
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
|
||||
|
||||
366
ChangeLog
366
ChangeLog
@@ -2,6 +2,235 @@
|
||||
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
|
||||
@@ -14,7 +243,7 @@ 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 parrameter to recursive _replaceHtmlWithOdtTag() utilisation
|
||||
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)
|
||||
@@ -273,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
|
||||
@@ -366,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
|
||||
@@ -462,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.
|
||||
@@ -477,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)
|
||||
@@ -870,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.
|
||||
@@ -948,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
|
||||
@@ -2500,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
|
||||
@@ -3885,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
|
||||
@@ -4681,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
|
||||
@@ -6125,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
|
||||
|
||||
@@ -172,7 +172,7 @@ $files = new RegexIterator($iterator1, '#^(?:[A-Z]:)?(?:/(?!(?:'.($includecustom
|
||||
*/
|
||||
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
|
||||
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
|
||||
$regextoexclude = '('.($includecustom?'':'custom|').'documents|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
|
||||
$regextoexclude = '('.($includecustom?'':'custom|').'documents|escpos-php\/doc|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
|
||||
$files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname');
|
||||
|
||||
$dir='';
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -5,20 +5,20 @@
|
||||
<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 type="relative">.cache</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 -->
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
|
||||
<rule ref="Generic.Formatting.SpaceAfterCast" />
|
||||
|
||||
<rule ref="Generic.Functions.CallTimePassByReference" />
|
||||
<!-- <rule ref="Generic.Functions.CallTimePassByReference" /> -->
|
||||
|
||||
<rule ref="Generic.Functions.FunctionCallArgumentSpacing" />
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
@@ -1175,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);
|
||||
|
||||
@@ -2127,7 +2127,7 @@ class Setup extends DolibarrApi
|
||||
|
||||
// Define qualified files (must be same than into generate_filelist_xml.php and in api_setup.class.php)
|
||||
$regextoinclude = '\.(php|php3|php4|php5|phtml|phps|phar|inc|css|scss|html|xml|js|json|tpl|jpg|jpeg|png|gif|ico|sql|lang|txt|yml|bak|md|mp3|mp4|wav|mkv|z|gz|zip|rar|tar|less|svg|eot|woff|woff2|ttf|manifest)$';
|
||||
$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
|
||||
$regextoexclude = '('.($includecustom ? '' : 'custom|').'documents|escpos-php\/doc|conf|install|dejavu-fonts-ttf-.*|public\/test|sabre\/sabre\/.*\/tests|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs
|
||||
$scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude);
|
||||
|
||||
// Fill file_list with files in signature, new files, modified files
|
||||
|
||||
@@ -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)) {
|
||||
@@ -928,12 +928,13 @@ class Asset extends CommonObject
|
||||
}
|
||||
|
||||
// Delete old lines
|
||||
$sql = "DELETE " . MAIN_DB_PREFIX . "asset_depreciation FROM " . MAIN_DB_PREFIX . "asset_depreciation";
|
||||
$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab ON ab.doc_type = 'asset' AND ab.fk_docdet = " . MAIN_DB_PREFIX . "asset_depreciation.rowid";
|
||||
$sql .= " WHERE " . MAIN_DB_PREFIX . "asset_depreciation.fk_asset = " . (int) $this->id;
|
||||
$sql .= " AND " . MAIN_DB_PREFIX . "asset_depreciation.depreciation_mode = '" . $this->db->escape($mode_key) . "'";
|
||||
$sql .= " AND ab.fk_docdet IS NULL";
|
||||
if ($last_depreciation_date !== "") $sql .= " AND " . MAIN_DB_PREFIX . "asset_depreciation.ref != ''";
|
||||
$sql = "DELETE FROM " . MAIN_DB_PREFIX . "asset_depreciation";
|
||||
$sql .= " WHERE fk_asset = " . (int) $this->id;
|
||||
$sql .= " AND depreciation_mode = '" . $this->db->escape($mode_key) . "'";
|
||||
$sql .= " AND NOT EXISTS (SELECT fk_docdet FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping WHERE doc_type = 'asset' AND fk_docdet = " . MAIN_DB_PREFIX . "asset_depreciation.rowid)";
|
||||
if ($last_depreciation_date !== "") {
|
||||
$sql .= " AND ref != ''";
|
||||
}
|
||||
$resql = $this->db->query($sql);
|
||||
if (!$resql) {
|
||||
$this->errors[] = $langs->trans('AssetErrorClearDepreciationLines') . ': ' . $this->db->lasterror();
|
||||
@@ -999,7 +1000,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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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++;
|
||||
|
||||
@@ -1000,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;
|
||||
}
|
||||
|
||||
@@ -1085,7 +1085,7 @@ if (empty($reshook) && GETPOST('actionmove', 'alpha') == 'mupdate') {
|
||||
}
|
||||
}
|
||||
if (!empty($backtopage)) {
|
||||
header("Location: ".$backtopage);
|
||||
header("Location: ".$backtopage, true, 307);
|
||||
exit;
|
||||
} else {
|
||||
$action = '';
|
||||
@@ -1960,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>';
|
||||
|
||||
@@ -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)";
|
||||
@@ -2521,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 = 'Failed to send email to: '.$to.' '.$cMailFile->error.join(',', $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 {
|
||||
$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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -1614,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) {
|
||||
@@ -2857,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>';
|
||||
|
||||
@@ -2866,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>';
|
||||
}
|
||||
@@ -3121,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)) {
|
||||
|
||||
@@ -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;
|
||||
@@ -1202,7 +1205,7 @@ class Commande extends CommonOrder
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
dol_print_error($this->db);
|
||||
$this->error = $this->db->lasterror();
|
||||
$this->db->rollback();
|
||||
return -1;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -82,7 +82,6 @@ if (GETPOST("id", 'int') || GETPOST("ref")) {
|
||||
|
||||
$result = restrictedArea($user, 'banque', $id, 'bank_account&bank_account', '', '', $fieldid);
|
||||
|
||||
|
||||
/*
|
||||
* Actions
|
||||
*/
|
||||
@@ -236,6 +235,7 @@ if (empty($reshook)) {
|
||||
$object = new Account($db);
|
||||
$object->fetch(GETPOST("id", 'int'));
|
||||
|
||||
$object->oldref = $object->ref;
|
||||
$object->ref = dol_string_nospecial(trim(GETPOST('ref', 'alpha')));
|
||||
$object->label = trim(GETPOST("label", 'alphanohtml'));
|
||||
$object->courant = GETPOST("type");
|
||||
|
||||
@@ -277,6 +277,11 @@ class Account extends CommonObject
|
||||
*/
|
||||
public $ics_transfer;
|
||||
|
||||
/**
|
||||
* @var string The previous ref in case of rename on update to rename attachment folders
|
||||
*/
|
||||
public $oldref;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
@@ -920,6 +925,28 @@ class Account extends CommonObject
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error && !empty($this->oldref) && $this->oldref !== $this->ref) {
|
||||
$sql = 'UPDATE '.MAIN_DB_PREFIX."ecm_files set filepath = 'bank/".$this->db->escape($this->ref)."'";
|
||||
$sql .= " WHERE filepath = 'bank/".$this->db->escape($this->oldref)."' and src_object_type='bank_account' and entity = ".((int) $conf->entity);
|
||||
$resql = $this->db->query($sql);
|
||||
if (!$resql) {
|
||||
$error++;
|
||||
$this->error = $this->db->lasterror();
|
||||
}
|
||||
|
||||
// We rename directory in order not to lose the attachments
|
||||
$oldref = dol_sanitizeFileName($this->oldref);
|
||||
$newref = dol_sanitizeFileName($this->ref);
|
||||
$dirsource = $conf->bank->dir_output.'/'.$oldref;
|
||||
$dirdest = $conf->bank->dir_output.'/'.$newref;
|
||||
if (file_exists($dirsource)) {
|
||||
dol_syslog(get_class($this)."::update rename dir ".$dirsource." into ".$dirdest, LOG_DEBUG);
|
||||
if (@rename($dirsource, $dirdest)) {
|
||||
dol_syslog("Rename ok", LOG_DEBUG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!$error && !$notrigger) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('BANKACCOUNT_MODIFY', $user);
|
||||
@@ -2570,12 +2597,15 @@ class AccountLine extends CommonObjectLine
|
||||
*/
|
||||
public function getNomUrl($withpicto = 0, $maxlen = 0, $option = '', $notooltip = 0)
|
||||
{
|
||||
global $langs;
|
||||
global $conf, $langs;
|
||||
|
||||
$result = '';
|
||||
|
||||
$label = img_picto('', $this->picto).' <u>'.$langs->trans("BankTransactionLine").'</u>:<br>';
|
||||
$label .= '<b>'.$langs->trans("Ref").':</b> '.$this->ref;
|
||||
if ($this->amount) {
|
||||
$label .= '<br><strong>'.$langs->trans("Amount").':</strong> '.price($this->amount, 0, $langs, 1, -1, -1, $conf->currency);
|
||||
}
|
||||
|
||||
$linkstart = '<a href="'.DOL_URL_ROOT.'/compta/bank/line.php?rowid='.((int) $this->id).'&save_lastsearch_values=1" title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">';
|
||||
$linkend = '</a>';
|
||||
@@ -2587,6 +2617,7 @@ class AccountLine extends CommonObjectLine
|
||||
if ($withpicto != 2) {
|
||||
$result .= ($this->ref ? $this->ref : $this->id);
|
||||
}
|
||||
|
||||
$result .= $linkend;
|
||||
|
||||
if ($option == 'showall' || $option == 'showconciliated' || $option == 'showconciliatedandaccounted') {
|
||||
|
||||
@@ -332,6 +332,12 @@ class BankAccounts extends DolibarrApi
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$account->array_options[$index] = $this->_checkValForAPI($field, $val, $account);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$account->$field = $this->_checkValForAPI($field, $value, $account);
|
||||
}
|
||||
|
||||
|
||||
@@ -163,7 +163,8 @@ if ($user->rights->banque->modifier && $action == "update") {
|
||||
$sql .= " SET ";
|
||||
// Always opened
|
||||
if (GETPOSTISSET('value')) {
|
||||
$sql .= " fk_type='".$db->escape(GETPOST('value'))."',";
|
||||
$type = GETPOST('value');
|
||||
$sql .= " fk_type='".$db->escape(empty($type) && $object->fk_type == 'SOLD' ? 'SOLD' : $type)."',";
|
||||
}
|
||||
if (GETPOSTISSET('num_chq')) {
|
||||
$sql .= " num_chq='".$db->escape(GETPOST("num_chq"))."',";
|
||||
|
||||
@@ -125,6 +125,7 @@ $foundnext = '';
|
||||
$sql = "SELECT b.num_releve as num";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."bank as b";
|
||||
$sql .= " WHERE b.num_releve < '".$db->escape($numref)."'";
|
||||
$sql .= " AND b.num_releve <> ''";
|
||||
$sql .= " AND b.fk_account = ".((int) $object->id);
|
||||
$sql .= " ORDER BY b.num_releve DESC";
|
||||
$sql .= $db->plimit(1);
|
||||
@@ -380,6 +381,7 @@ if (empty($numref)) {
|
||||
$sql = "SELECT sum(b.amount) as amount";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."bank as b";
|
||||
$sql .= " WHERE b.num_releve < '".$db->escape($objp->numr)."'";
|
||||
$sql .= " AND b.num_releve <> ''";
|
||||
$sql .= " AND b.fk_account = ".((int) $object->id);
|
||||
$resql = $db->query($sql);
|
||||
if ($resql) {
|
||||
@@ -464,6 +466,7 @@ if (empty($numref)) {
|
||||
$sql = "SELECT sum(b.amount) as amount";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."bank as b";
|
||||
$sql .= " WHERE b.num_releve < '".$db->escape($numref)."'";
|
||||
$sql .= " AND b.num_releve <> ''";
|
||||
$sql .= " AND b.fk_account = ".((int) $object->id);
|
||||
|
||||
$resql = $db->query($sql);
|
||||
|
||||
@@ -196,6 +196,7 @@ class CashControl extends CommonObject
|
||||
$sql .= ", cash";
|
||||
$sql .= ", cheque";
|
||||
$sql .= ", card";
|
||||
$sql .= ", fk_user_creat";
|
||||
$sql .= ") VALUES (";
|
||||
//$sql .= "'(PROV)', ";
|
||||
$sql .= ((int) $conf->entity);
|
||||
@@ -210,6 +211,7 @@ class CashControl extends CommonObject
|
||||
$sql .= ", ".price2num($this->cash, 'MT');
|
||||
$sql .= ", ".price2num($this->cheque, 'MT');
|
||||
$sql .= ", ".price2num($this->card, 'MT');
|
||||
$sql .= ", ".((int) $user->id);
|
||||
$sql .= ")";
|
||||
|
||||
$this->db->begin();
|
||||
|
||||
@@ -253,7 +253,7 @@ if ($resql) {
|
||||
|
||||
// Date ope
|
||||
print '<td class="nowrap left">';
|
||||
print '<span id="dateoperation_'.$objp->rowid.'">'.dol_print_date($db->jdate($objp->do), "day")."</span>";
|
||||
print '<span id="dateoperation_'.$objp->facid.'">'.dol_print_date($db->jdate($objp->do), "day")."</span>";
|
||||
print "</td>\n";
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
|
||||
@@ -91,7 +91,10 @@ $pagenext = $page + 1;
|
||||
$object = new FactureRec($db);
|
||||
if (($id > 0 || $ref) && $action != 'create' && $action != 'add') {
|
||||
$ret = $object->fetch($id, $ref);
|
||||
if (!$ret) {
|
||||
if ($ret < 0) {
|
||||
dol_print_error($db, $object->error, $object->errors);
|
||||
exit;
|
||||
} elseif (! $ret) {
|
||||
setEventMessages($langs->trans("ErrorRecordNotFound"), null, 'errors');
|
||||
}
|
||||
}
|
||||
@@ -1304,14 +1307,10 @@ if ($action == 'create') {
|
||||
}
|
||||
print '</tr></table>';
|
||||
print '</td><td>';
|
||||
if ($object->type != Facture::TYPE_CREDIT_NOTE) {
|
||||
if ($action == 'editconditions') {
|
||||
$form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
|
||||
} else {
|
||||
$form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'none');
|
||||
}
|
||||
if ($action == 'editconditions') {
|
||||
$form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'cond_reglement_id');
|
||||
} else {
|
||||
print ' ';
|
||||
$form->form_conditions_reglement($_SERVER['PHP_SELF'].'?facid='.$object->id, $object->cond_reglement_id, 'none');
|
||||
}
|
||||
print '</td></tr>';
|
||||
|
||||
@@ -1735,6 +1734,7 @@ if ($action == 'create') {
|
||||
// List of actions on element
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
|
||||
$formactions = new FormActions($db);
|
||||
$morehtmlcenter = '';
|
||||
$somethingshown = $formactions->showactions($object, $object->element, (is_object($object->thirdparty) ? $object->thirdparty->id : 0), 1, '', $MAXEVENT, '', $morehtmlcenter);
|
||||
|
||||
print '</div>';
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
* Copyright (C) 2013 Jean-Francois FERRY <jfefe@aternatik.fr>
|
||||
* Copyright (C) 2013-2014 Florian Henry <florian.henry@open-concept.pro>
|
||||
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
|
||||
* Copyright (C) 2014-2019 Ferran Marcet <fmarcet@2byte.es>
|
||||
* Copyright (C) 2014-2024 Ferran Marcet <fmarcet@2byte.es>
|
||||
* Copyright (C) 2015-2016 Marcos García <marcosgdf@gmail.com>
|
||||
* Copyright (C) 2018-2023 Frédéric France <frederic.france@netlogic.fr>
|
||||
* Copyright (C) 2022 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
|
||||
@@ -98,7 +98,7 @@ $origin = GETPOST('origin', 'alpha');
|
||||
$originid = (GETPOST('originid', 'int') ? GETPOST('originid', 'int') : GETPOST('origin_id', 'int')); // For backward compatibility
|
||||
$fac_rec = GETPOST('fac_rec', 'int');
|
||||
$facid = GETPOST('facid', 'int');
|
||||
$ref_client = GETPOST('ref_client', 'int');
|
||||
$ref_client = GETPOST('ref_client', 'alpha');
|
||||
$rank = (GETPOST('rank', 'int') > 0) ? GETPOST('rank', 'int') : -1;
|
||||
$projectid = (GETPOST('projectid', 'int') ? GETPOST('projectid', 'int') : 0);
|
||||
|
||||
@@ -321,7 +321,7 @@ if (empty($reshook)) {
|
||||
$object->date = dol_now();
|
||||
}
|
||||
|
||||
if (!empty($conf->global-> INVOICE_CHECK_POSTERIOR_DATE)) {
|
||||
if (!empty($conf->global->INVOICE_CHECK_POSTERIOR_DATE)) {
|
||||
$last_of_type = $object->willBeLastOfSameType(true);
|
||||
if (empty($object->date_validation) && !$last_of_type[0]) {
|
||||
setEventMessages($langs->transnoentities("ErrorInvoiceIsNotLastOfSameType", $object->ref, dol_print_date($object->date, 'day'), dol_print_date($last_of_type[1], 'day')), null, 'errors');
|
||||
@@ -456,7 +456,7 @@ if (empty($reshook)) {
|
||||
|
||||
$object->date = $newdate;
|
||||
$new_date_lim_reglement = $object->calculate_date_lim_reglement();
|
||||
if ($new_date_lim_reglement > $old_date_lim_reglement) {
|
||||
if ($new_date_lim_reglement) {
|
||||
$object->date_lim_reglement = $new_date_lim_reglement;
|
||||
}
|
||||
if ($object->date_lim_reglement < $object->date) {
|
||||
@@ -496,7 +496,7 @@ if (empty($reshook)) {
|
||||
if (!$error) {
|
||||
$old_date_lim_reglement = $object->date_lim_reglement;
|
||||
$new_date_lim_reglement = $object->calculate_date_lim_reglement();
|
||||
if ($new_date_lim_reglement > $old_date_lim_reglement) {
|
||||
if ($new_date_lim_reglement) {
|
||||
$object->date_lim_reglement = $new_date_lim_reglement;
|
||||
}
|
||||
if ($object->date_lim_reglement < $object->date) {
|
||||
@@ -643,7 +643,7 @@ if (empty($reshook)) {
|
||||
$object->setValueFrom('ref', GETPOST('ref'), '', null, '', '', $user, 'BILL_MODIFY');
|
||||
} elseif ($action == 'setref_client' && $usercancreate) {
|
||||
$object->fetch($id);
|
||||
$object->set_ref_client(GETPOST('ref_client'));
|
||||
$object->set_ref_client(GETPOST('ref_client', 'alpha'));
|
||||
} elseif ($action == 'confirm_valid' && $confirm == 'yes' && $usercanvalidate) {
|
||||
// Classify to validated
|
||||
$idwarehouse = GETPOST('idwarehouse', 'int');
|
||||
@@ -1515,6 +1515,9 @@ if (empty($reshook)) {
|
||||
}
|
||||
|
||||
foreach ($TTotalByTva as $tva => &$total) {
|
||||
if (empty($amountdeposit[$tva])) {
|
||||
$amountdeposit[$tva] = 0;
|
||||
}
|
||||
$coef = $total / $srcobject->total_ttc; // Calc coef
|
||||
$am = $amount * $coef;
|
||||
$amount_ttc_diff += $am;
|
||||
@@ -1539,6 +1542,9 @@ if (empty($reshook)) {
|
||||
if ($qualified) {
|
||||
$totalamount += $lines[$i]->total_ht; // Fixme : is it not for the customer ? Shouldn't we take total_ttc ?
|
||||
$tva_tx = $lines[$i]->tva_tx;
|
||||
if (empty($amountdeposit[$tva_tx])) {
|
||||
$amountdeposit[$tva_tx] = 0;
|
||||
}
|
||||
$amountdeposit[$tva_tx] += ($lines[$i]->total_ht * $valuedeposit) / 100;
|
||||
}
|
||||
}
|
||||
@@ -1604,7 +1610,7 @@ if (empty($reshook)) {
|
||||
null,
|
||||
0,
|
||||
'',
|
||||
1
|
||||
(!empty($conf->global->MAIN_DEPOSIT_MULTI_TVA)?0:1)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -4487,6 +4493,9 @@ if ($action == 'create') {
|
||||
$morehtmlref .= '</div>';
|
||||
|
||||
$object->totalpaid = $totalpaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status
|
||||
$object->totalcreditnotes = $totalcreditnotes;
|
||||
$object->totaldeposits = $totaldeposits;
|
||||
$object->remaintopay = price2num($object->total_ttc - $object->totalpaid - $object->totalcreditnotes - $object->totaldeposits, 'MT');
|
||||
|
||||
dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref, '', 0, '', '');
|
||||
|
||||
@@ -4904,7 +4913,9 @@ if ($action == 'create') {
|
||||
print '<td class="titlefieldmiddle">' . $langs->transcountry("AmountLT1", $mysoc->country_code) . '</td>';
|
||||
print '<td class="nowrap amountcard right">' . price($sign * $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($sign * $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($sign * $object->multicurrency_total_localtax1, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
}
|
||||
print '</tr>';
|
||||
|
||||
@@ -4913,7 +4924,9 @@ if ($action == 'create') {
|
||||
print '<td>' . $langs->transcountry("AmountLT2", $mysoc->country_code) . '</td>';
|
||||
print '<td class="nowrap amountcard right">' . price($sign * $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($sign * $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($sign * $object->multicurrency_total_localtax2, '', $langs, 0, -1, -1, $object->multicurrency_code) . '</td>';
|
||||
}
|
||||
print '</tr>';
|
||||
}
|
||||
@@ -5035,7 +5048,9 @@ if ($action == 'create') {
|
||||
|
||||
$current_situation_counter = array();
|
||||
foreach ($object->tab_previous_situation_invoice as $prev_invoice) {
|
||||
$tmptotalpaidforthisinvoice = $prev_invoice->getSommePaiement();
|
||||
$tmptotalallpayments = $prev_invoice->getSommePaiement(0);
|
||||
$tmptotalallpayments += $prev_invoice->getSumDepositsUsed(0);
|
||||
$tmptotalallpayments += $prev_invoice->getSumCreditNotesUsed(0);
|
||||
$total_prev_ht += $prev_invoice->total_ht;
|
||||
$total_prev_ttc += $prev_invoice->total_ttc;
|
||||
$current_situation_counter[] = (($prev_invoice->type == Facture::TYPE_CREDIT_NOTE) ?-1 : 1) * $prev_invoice->situation_counter;
|
||||
@@ -5048,11 +5063,14 @@ if ($action == 'create') {
|
||||
}
|
||||
print '<td class="right"><span class="amount">'.price($prev_invoice->total_ht).'</span></td>';
|
||||
print '<td class="right"><span class="amount">'.price($prev_invoice->total_ttc).'</span></td>';
|
||||
print '<td class="right">'.$prev_invoice->getLibStatut(3, $tmptotalpaidforthisinvoice).'</td>';
|
||||
print '<td class="right">'.$prev_invoice->getLibStatut(3, $tmptotalallpayments).'</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
}
|
||||
|
||||
$totalallpayments = $object->getSommePaiement(0);
|
||||
$totalallpayments += $object->getSumCreditNotesUsed(0);
|
||||
$totalallpayments += $object->getSumDepositsUsed(0);
|
||||
|
||||
$total_global_ht += $total_prev_ht;
|
||||
$total_global_ttc += $total_prev_ttc;
|
||||
@@ -5068,7 +5086,7 @@ if ($action == 'create') {
|
||||
}
|
||||
print '<td class="right"><span class="amount">'.price($object->total_ht).'</span></td>';
|
||||
print '<td class="right"><span class="amount">'.price($object->total_ttc).'</span></td>';
|
||||
print '<td class="right">'.$object->getLibStatut(3, $object->getSommePaiement()).'</td>';
|
||||
print '<td class="right">'.$object->getLibStatut(3, $totalallpayments).'</td>';
|
||||
print '</tr>';
|
||||
|
||||
|
||||
@@ -5110,7 +5128,9 @@ if ($action == 'create') {
|
||||
$total_next_ht = $total_next_ttc = 0;
|
||||
|
||||
foreach ($object->tab_next_situation_invoice as $next_invoice) {
|
||||
$totalpaid = $next_invoice->getSommePaiement();
|
||||
$totalpaid = $next_invoice->getSommePaiement(0);
|
||||
$totalcreditnotes = $next_invoice->getSumCreditNotesUsed(0);
|
||||
$totaldeposits = $next_invoice->getSumDepositsUsed(0);
|
||||
$total_next_ht += $next_invoice->total_ht;
|
||||
$total_next_ttc += $next_invoice->total_ttc;
|
||||
|
||||
@@ -5123,7 +5143,7 @@ if ($action == 'create') {
|
||||
}
|
||||
print '<td class="right"><span class="amount">'.price($next_invoice->total_ht).'</span></td>';
|
||||
print '<td class="right"><span class="amount">'.price($next_invoice->total_ttc).'</span></td>';
|
||||
print '<td class="right">'.$next_invoice->getLibStatut(3, $totalpaid).'</td>';
|
||||
print '<td class="right">'.$next_invoice->getLibStatut(3, $totalpaid + $totalcreditnotes + $totaldeposits).'</td>';
|
||||
print '</tr>';
|
||||
}
|
||||
|
||||
@@ -5696,7 +5716,7 @@ if ($action == 'create') {
|
||||
// Sometimes we can receive more, so we accept to enter more and will offer a button to convert into discount (but it is not a credit note, just a prepayment done)
|
||||
//print '<a class="butAction" href="'.DOL_URL_ROOT.'/compta/paiement.php?facid='.$object->id.'&action=create&accountid='.$object->fk_account.'">'.$langs->trans('DoPayment').'</a>';
|
||||
$params['attr']['title'] = '';
|
||||
print dolGetButtonAction($langs->trans('DoPayment'), '', 'default', DOL_URL_ROOT.'/compta/paiement.php?facid='.$object->id.'&action=create&accountid='.$object->fk_account, '', true, $params);
|
||||
print dolGetButtonAction($langs->trans('DoPayment'), '', 'default', DOL_URL_ROOT.'/compta/paiement.php?facid='.$object->id.'&action=create'.($object->fk_account > 0 ? '&accountid='.$object->fk_account : ''), '', true, $params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,7 +318,7 @@ class Invoices extends DolibarrApi
|
||||
if ($this->invoice->create(DolibarrApiAccess::$user, 0, (empty($request_data["date_lim_reglement"]) ? 0 : $request_data["date_lim_reglement"])) < 0) {
|
||||
throw new RestException(500, "Error creating invoice", array_merge(array($this->invoice->error), $this->invoice->errors));
|
||||
}
|
||||
return $this->invoice->id;
|
||||
return ((int) $this->invoice->id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -622,6 +622,12 @@ class Invoices extends DolibarrApi
|
||||
if ($field == 'id') {
|
||||
continue;
|
||||
}
|
||||
if ($field == 'array_options' && is_array($value)) {
|
||||
foreach ($value as $index => $val) {
|
||||
$this->invoice->array_options[$index] = $this->_checkValForAPI($field, $val, $this->invoice);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
$this->invoice->$field = $value;
|
||||
}
|
||||
|
||||
@@ -632,11 +638,11 @@ class Invoices extends DolibarrApi
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->invoice->update(DolibarrApiAccess::$user)) {
|
||||
if ($this->invoice->update(DolibarrApiAccess::$user) > 0) {
|
||||
return $this->get($id);
|
||||
} else {
|
||||
throw new RestException(500, $this->invoice->error);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1562,13 +1568,13 @@ class Invoices extends DolibarrApi
|
||||
$amount = price2num($amountarray["multicurrency_amount"], 'MT');
|
||||
}
|
||||
|
||||
if ($amount > $remainstopay && !$accepthigherpayment) {
|
||||
if (abs($amount) > abs($remainstopay) && !$accepthigherpayment) {
|
||||
$this->db->rollback();
|
||||
throw new RestException(400, 'Payment amount on invoice ID '.$id.' ('.$amount.') is higher than remain to pay ('.$remainstopay.')');
|
||||
}
|
||||
|
||||
if ($this->invoice->type == Facture::TYPE_CREDIT_NOTE) {
|
||||
$amount = -$amount;
|
||||
$amount = - abs($amount);
|
||||
}
|
||||
|
||||
if ($is_multicurrency) {
|
||||
|
||||
@@ -131,6 +131,13 @@ class FactureRec extends CommonInvoice
|
||||
public $cond_reglement_code; // Code in llx_c_paiement
|
||||
public $mode_reglement_code; // Code in llx_c_paiement
|
||||
|
||||
public $fk_multicurrency;
|
||||
public $multicurrency_code;
|
||||
public $multicurrency_tx;
|
||||
public $multicurrency_total_ht;
|
||||
public $multicurrency_total_tva;
|
||||
public $multicurrency_total_ttc;
|
||||
|
||||
public $suspended; // status
|
||||
|
||||
public $auto_validate; // 0 to create in draft, 1 to create and validate the new invoice
|
||||
@@ -1340,6 +1347,14 @@ class FactureRec extends CommonInvoice
|
||||
$facture->multicurrency_tx = $facturerec->multicurrency_tx;
|
||||
}
|
||||
|
||||
if (isset($facture->array_options) && isset($facturerec->array_options)) {
|
||||
foreach ($facturerec->array_options as $key => $value) {
|
||||
if (isset($facture->array_options[$key])) {
|
||||
$facture->array_options[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$invoiceidgenerated = $facture->create($user);
|
||||
if ($invoiceidgenerated <= 0) {
|
||||
$this->errors = $facture->errors;
|
||||
@@ -1389,6 +1404,7 @@ class FactureRec extends CommonInvoice
|
||||
$nb_create++;
|
||||
$this->output .= $langs->trans("InvoiceGeneratedFromTemplate", $facture->ref, $facturerec->ref)."\n";
|
||||
} else {
|
||||
$this->output .= $langs->trans("InvoiceGeneratedFromTemplateError", $facture->ref, $facturerec->ref, $this->error)."\n";
|
||||
$this->db->rollback("createRecurringInvoices Process invoice template id=".$facturerec->id.", ref=".$facturerec->ref);
|
||||
}
|
||||
|
||||
|
||||
@@ -262,6 +262,8 @@ class Facture extends CommonInvoice
|
||||
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
|
||||
|
||||
/**
|
||||
* @var int Situation cycle reference number
|
||||
@@ -501,8 +503,8 @@ class Facture extends CommonInvoice
|
||||
$this->ref_client = trim($this->ref_client);
|
||||
|
||||
$this->note = (isset($this->note) ? trim($this->note) : trim($this->note_private)); // deprecated
|
||||
$this->note_private = (isset($this->note_private) ? trim($this->note_private) : trim($this->note_private));
|
||||
$this->note_public = trim($this->note_public);
|
||||
$this->note_private = (isset($this->note_private) ? trim($this->note_private) : '');
|
||||
$this->note_public = (isset($this->note_public) ? trim($this->note_public) : '');
|
||||
if (!$this->cond_reglement_id) {
|
||||
$this->cond_reglement_id = 0;
|
||||
}
|
||||
@@ -1011,13 +1013,13 @@ class Facture extends CommonInvoice
|
||||
*/
|
||||
if (!$error && $this->fac_rec > 0) {
|
||||
foreach ($_facrec->lines as $i => $val) {
|
||||
// For line from template invoice, we use data from template invoice
|
||||
/*
|
||||
if ($_facrec->lines[$i]->fk_product) {
|
||||
$prod = new Product($this->db);
|
||||
$res = $prod->fetch($_facrec->lines[$i]->fk_product);
|
||||
}
|
||||
|
||||
// For line from template invoice, we use data from template invoice
|
||||
/*
|
||||
$tva_tx = get_default_tva($mysoc,$soc,$prod->id);
|
||||
$tva_npr = get_default_npr($mysoc,$soc,$prod->id);
|
||||
if (empty($tva_tx)) $tva_npr=0;
|
||||
@@ -1270,7 +1272,7 @@ class Facture extends CommonInvoice
|
||||
$object->socid = $objsoc->id;
|
||||
$object->cond_reglement_id = (!empty($objsoc->cond_reglement_id) ? $objsoc->cond_reglement_id : 0);
|
||||
$object->mode_reglement_id = (!empty($objsoc->mode_reglement_id) ? $objsoc->mode_reglement_id : 0);
|
||||
$object->fk_project = '';
|
||||
$object->fk_project = null;
|
||||
$object->fk_delivery_address = '';
|
||||
}
|
||||
|
||||
@@ -1288,10 +1290,12 @@ class Facture extends CommonInvoice
|
||||
$object->fk_user_author = $user->id;
|
||||
$object->fk_user_valid = null;
|
||||
$object->fk_facture_source = 0;
|
||||
$object->fk_fac_rec_source = null;
|
||||
$object->date_creation = '';
|
||||
$object->date_modification = '';
|
||||
$object->date_validation = '';
|
||||
$object->ref_client = '';
|
||||
$object->ref_customer = '';
|
||||
$object->close_code = '';
|
||||
$object->close_note = '';
|
||||
if (getDolGlobalInt('MAIN_DONT_KEEP_NOTE_ON_CLONING') == 1) {
|
||||
@@ -2520,6 +2524,9 @@ class Facture extends CommonInvoice
|
||||
if (isset($this->retained_warranty)) {
|
||||
$this->retained_warranty = floatval($this->retained_warranty);
|
||||
}
|
||||
if (!isset($this->fk_user_author) && isset($this->user_author) ) {
|
||||
$this->fk_user_author = $this->user_author;
|
||||
}
|
||||
|
||||
|
||||
// Check parameters
|
||||
@@ -2549,7 +2556,7 @@ class Facture extends CommonInvoice
|
||||
$sql .= " total_ttc=".(isset($this->total_ttc) ? $this->total_ttc : "null").",";
|
||||
$sql .= " revenuestamp=".((isset($this->revenuestamp) && $this->revenuestamp != '') ? $this->db->escape($this->revenuestamp) : "null").",";
|
||||
$sql .= " fk_statut=".(isset($this->statut) ? $this->db->escape($this->statut) : "null").",";
|
||||
$sql .= " fk_user_author=".(isset($this->user_author) ? $this->db->escape($this->user_author) : "null").",";
|
||||
$sql .= " fk_user_author=".(isset($this->fk_user_author) ? $this->db->escape($this->fk_user_author) : "null").",";
|
||||
$sql .= " fk_user_valid=".(isset($this->fk_user_valid) ? $this->db->escape($this->fk_user_valid) : "null").",";
|
||||
$sql .= " fk_facture_source=".(isset($this->fk_facture_source) ? $this->db->escape($this->fk_facture_source) : "null").",";
|
||||
$sql .= " fk_projet=".(isset($this->fk_project) ? $this->db->escape($this->fk_project) : "null").",";
|
||||
@@ -3233,7 +3240,7 @@ class Facture extends CommonInvoice
|
||||
$this->date = dol_now();
|
||||
$this->date_lim_reglement = $this->calculate_date_lim_reglement();
|
||||
}
|
||||
if (!empty($conf->global-> INVOICE_CHECK_POSTERIOR_DATE)) {
|
||||
if (!empty($conf->global->INVOICE_CHECK_POSTERIOR_DATE)) {
|
||||
$last_of_type = $this->willBeLastOfSameType(true);
|
||||
if (!$last_of_type[0]) {
|
||||
$this->error = $langs->transnoentities("ErrorInvoiceIsNotLastOfSameType", $this->ref, dol_print_date($this->date, 'day'), dol_print_date($last_of_type[1], 'day'));
|
||||
@@ -4229,6 +4236,11 @@ class Facture extends CommonInvoice
|
||||
$rangmax = $this->line_max($fk_parent_line);
|
||||
$this->line->rang = $rangmax + 1;
|
||||
}
|
||||
$apply_abs_price_on_credit_note=false;
|
||||
if ($this->type == self::TYPE_CREDIT_NOTE && !getDolGlobalInt('FACTURE_ENABLE_NEGATIVE_LINES') && !getDolGlobalInt('INVOICE_KEEP_DISCOUNT_LINES_AS_IN_ORIGIN')) {
|
||||
$apply_abs_price_on_credit_note = true;
|
||||
}
|
||||
|
||||
|
||||
$this->line->id = $rowid;
|
||||
$this->line->rowid = $rowid;
|
||||
@@ -4245,14 +4257,14 @@ class Facture extends CommonInvoice
|
||||
$this->line->localtax2_type = empty($localtaxes_type[2]) ? '' : $localtaxes_type[2];
|
||||
|
||||
$this->line->remise_percent = $remise_percent;
|
||||
$this->line->subprice = ($this->type == self::TYPE_CREDIT_NOTE ?-abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise
|
||||
$this->line->subprice = ($apply_abs_price_on_credit_note?-abs($pu_ht) : $pu_ht); // For credit note, unit price always negative, always positive otherwise
|
||||
$this->line->date_start = $date_start;
|
||||
$this->line->date_end = $date_end;
|
||||
$this->line->total_ht = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative
|
||||
$this->line->total_tva = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_tva) : $total_tva);
|
||||
$this->line->total_ht = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_ht) : $total_ht); // For credit note and if qty is negative, total is negative
|
||||
$this->line->total_tva = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_tva) : $total_tva);
|
||||
$this->line->total_localtax1 = $total_localtax1;
|
||||
$this->line->total_localtax2 = $total_localtax2;
|
||||
$this->line->total_ttc = (($this->type == self::TYPE_CREDIT_NOTE || $qty < 0) ?-abs($total_ttc) : $total_ttc);
|
||||
$this->line->total_ttc = (($apply_abs_price_on_credit_note || $qty < 0) ?-abs($total_ttc) : $total_ttc);
|
||||
$this->line->info_bits = $info_bits;
|
||||
$this->line->special_code = $special_code;
|
||||
$this->line->product_type = $type;
|
||||
@@ -5736,209 +5748,212 @@ class Facture extends CommonInvoice
|
||||
|
||||
if ($resql) {
|
||||
while ($obj = $this->db->fetch_object($resql)) {
|
||||
if (!$error) {
|
||||
// Load event
|
||||
$res = $tmpinvoice->fetch($obj->id);
|
||||
if ($res > 0) {
|
||||
$tmpinvoice->fetch_thirdparty();
|
||||
// Create a loopError that is reset at each loop, this counter is added to the global counter at the end of loop
|
||||
$loopError = 0;
|
||||
|
||||
$outputlangs = new Translate('', $conf);
|
||||
if ($tmpinvoice->thirdparty->default_lang) {
|
||||
$outputlangs->setDefaultLang($tmpinvoice->thirdparty->default_lang);
|
||||
$outputlangs->loadLangs(array("main", "bills"));
|
||||
} else {
|
||||
$outputlangs = $langs;
|
||||
}
|
||||
// Load event
|
||||
$res = $tmpinvoice->fetch($obj->id);
|
||||
if ($res > 0) {
|
||||
$tmpinvoice->fetch_thirdparty();
|
||||
|
||||
// Select email template according to language of recipient
|
||||
$arraymessage = $formmail->getEMailTemplate($this->db, 'facture_send', $user, $outputlangs, (is_numeric($template) ? $template : 0), 1, (is_numeric($template) ? '' : $template));
|
||||
if (is_numeric($arraymessage) && $arraymessage <= 0) {
|
||||
$langs->load("errors");
|
||||
$this->output .= $langs->trans('ErrorFailedToFindEmailTemplate', $template);
|
||||
return 0;
|
||||
}
|
||||
$outputlangs = new Translate('', $conf);
|
||||
if ($tmpinvoice->thirdparty->default_lang) {
|
||||
$outputlangs->setDefaultLang($tmpinvoice->thirdparty->default_lang);
|
||||
$outputlangs->loadLangs(array("main", "bills"));
|
||||
} else {
|
||||
$outputlangs = $langs;
|
||||
}
|
||||
|
||||
// PREPARE EMAIL
|
||||
$errormesg = '';
|
||||
// Select email template according to language of recipient
|
||||
$arraymessage = $formmail->getEMailTemplate($this->db, 'facture_send', $user, $outputlangs, (is_numeric($template) ? $template : 0), 1, (is_numeric($template) ? '' : $template));
|
||||
if (is_numeric($arraymessage) && $arraymessage <= 0) {
|
||||
$langs->load("errors");
|
||||
$this->output .= $langs->trans('ErrorFailedToFindEmailTemplate', $template);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make substitution in email content
|
||||
$substitutionarray = getCommonSubstitutionArray($outputlangs, 0, '', $tmpinvoice);
|
||||
// PREPARE EMAIL
|
||||
$errormesg = '';
|
||||
|
||||
complete_substitutions_array($substitutionarray, $outputlangs, $tmpinvoice);
|
||||
// Make substitution in email content
|
||||
$substitutionarray = getCommonSubstitutionArray($outputlangs, 0, '', $tmpinvoice);
|
||||
|
||||
// Topic
|
||||
$sendTopic = make_substitutions(empty($arraymessage->topic) ? $outputlangs->transnoentitiesnoconv('InformationMessage') : $arraymessage->topic, $substitutionarray, $outputlangs, 1);
|
||||
complete_substitutions_array($substitutionarray, $outputlangs, $tmpinvoice);
|
||||
|
||||
// Content
|
||||
$content = $outputlangs->transnoentitiesnoconv($arraymessage->content);
|
||||
// Topic
|
||||
$sendTopic = make_substitutions(empty($arraymessage->topic) ? $outputlangs->transnoentitiesnoconv('InformationMessage') : $arraymessage->topic, $substitutionarray, $outputlangs, 1);
|
||||
|
||||
$sendContent = make_substitutions($content, $substitutionarray, $outputlangs, 1);
|
||||
// Content
|
||||
$content = $outputlangs->transnoentitiesnoconv($arraymessage->content);
|
||||
|
||||
// Recipient
|
||||
$to = array();
|
||||
if ($forcerecipient) { // If a recipient was forced
|
||||
$to = array($forcerecipient);
|
||||
} else {
|
||||
$res = $tmpinvoice->fetch_thirdparty();
|
||||
$recipient = $tmpinvoice->thirdparty;
|
||||
if ($res > 0) {
|
||||
$tmparraycontact = $tmpinvoice->liste_contact(-1, 'external', 0, 'BILLING');
|
||||
if (is_array($tmparraycontact) && count($tmparraycontact) > 0) {
|
||||
foreach ($tmparraycontact as $data_email) {
|
||||
if (!empty($data_email['email'])) {
|
||||
$to[] = $tmpinvoice->thirdparty->contact_get_property($data_email['id'], 'email');
|
||||
}
|
||||
$sendContent = make_substitutions($content, $substitutionarray, $outputlangs, 1);
|
||||
|
||||
// Recipient
|
||||
$to = array();
|
||||
if ($forcerecipient) { // If a recipient was forced
|
||||
$to = array($forcerecipient);
|
||||
} else {
|
||||
$res = $tmpinvoice->fetch_thirdparty();
|
||||
$recipient = $tmpinvoice->thirdparty;
|
||||
if ($res > 0) {
|
||||
$tmparraycontact = $tmpinvoice->liste_contact(-1, 'external', 0, 'BILLING');
|
||||
if (is_array($tmparraycontact) && count($tmparraycontact) > 0) {
|
||||
foreach ($tmparraycontact as $data_email) {
|
||||
if (!empty($data_email['email'])) {
|
||||
$to[] = $tmpinvoice->thirdparty->contact_get_property($data_email['id'], 'email');
|
||||
}
|
||||
}
|
||||
if (empty($to) && !empty($recipient->email)) {
|
||||
$to[] = $recipient->email;
|
||||
}
|
||||
if (empty($to)) {
|
||||
$errormesg = "Failed to send remind to thirdparty id=".$tmpinvoice->socid.". No email defined for invoice or customer.";
|
||||
$error++;
|
||||
}
|
||||
} else {
|
||||
$errormesg = "Failed to load recipient with thirdparty id=".$tmpinvoice->socid;
|
||||
$error++;
|
||||
}
|
||||
if (empty($to) && !empty($recipient->email)) {
|
||||
$to[] = $recipient->email;
|
||||
}
|
||||
if (empty($to)) {
|
||||
$errormesg = "Failed to send remind to thirdparty id=".$tmpinvoice->socid.". No email defined for invoice or customer.";
|
||||
$loopError++;
|
||||
}
|
||||
} else {
|
||||
$errormesg = "Failed to load recipient with thirdparty id=".$tmpinvoice->socid;
|
||||
$loopError++;
|
||||
}
|
||||
|
||||
// Sender
|
||||
$from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
|
||||
if (!empty($arraymessage->email_from)) { // If a sender is defined into template, we use it in priority
|
||||
$from = $arraymessage->email_from;
|
||||
}
|
||||
if (empty($from)) {
|
||||
$errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
|
||||
$error++;
|
||||
}
|
||||
|
||||
if (!$error && !empty($to)) {
|
||||
$this->db->begin();
|
||||
|
||||
$to = implode(',', $to);
|
||||
if (!empty($arraymessage->email_to)) { // If a recipient is defined into template, we add it
|
||||
$to = $to.','.$arraymessage->email_to;
|
||||
}
|
||||
|
||||
// Errors Recipient
|
||||
$errors_to = $conf->global->MAIN_MAIL_ERRORS_TO;
|
||||
|
||||
$trackid = 'inv'.$tmpinvoice->id;
|
||||
$sendcontext = 'standard';
|
||||
|
||||
$email_tocc = '';
|
||||
if (!empty($arraymessage->email_tocc)) { // If a CC is defined into template, we use it
|
||||
$email_tocc = $arraymessage->email_tocc;
|
||||
}
|
||||
|
||||
$email_tobcc = '';
|
||||
if (!empty($arraymessage->email_tobcc)) { // If a BCC is defined into template, we use it
|
||||
$email_tobcc = $arraymessage->email_tobcc;
|
||||
}
|
||||
|
||||
//join file is asked
|
||||
$joinFile = [];
|
||||
$joinFileName = [];
|
||||
$joinFileMime = [];
|
||||
if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) {
|
||||
$joinFile[] = DOL_DATA_ROOT.$tmpinvoice->last_main_doc;
|
||||
$joinFileName[] = basename($tmpinvoice->last_main_doc);
|
||||
$joinFileMime[] = dol_mimetype(DOL_DATA_ROOT.$tmpinvoice->last_main_doc);
|
||||
}
|
||||
|
||||
// Mail Creation
|
||||
$cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, $joinFile, $joinFileMime, $joinFileName, $email_tocc, $email_tobcc, 0, 1, $errors_to, '', $trackid, '', $sendcontext, '');
|
||||
|
||||
// Sending Mail
|
||||
if ($cMailFile->sendfile()) {
|
||||
$nbMailSend++;
|
||||
|
||||
// Add a line into event table
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
||||
|
||||
// Insert record of emails sent
|
||||
$actioncomm = new ActionComm($this->db);
|
||||
|
||||
$actioncomm->type_code = 'AC_OTH_AUTO'; // Event insert into agenda automatically
|
||||
$actioncomm->socid = $tmpinvoice->thirdparty->id; // To link to a company
|
||||
$actioncomm->contact_id = 0;
|
||||
|
||||
$actioncomm->code = 'AC_EMAIL';
|
||||
$actioncomm->label = 'sendEmailsRemindersOnInvoiceDueDateOK (nbdays='.$nbdays.' paymentmode='.$paymentmode.' template='.$template.' datetouse='.$datetouse.' forcerecipient='.$forcerecipient.')';
|
||||
$actioncomm->note_private = $sendContent;
|
||||
$actioncomm->fk_project = $tmpinvoice->fk_project;
|
||||
$actioncomm->datep = dol_now();
|
||||
$actioncomm->datef = $actioncomm->datep;
|
||||
$actioncomm->percentage = -1; // Not applicable
|
||||
$actioncomm->authorid = $user->id; // User saving action
|
||||
$actioncomm->userownerid = $user->id; // Owner of action
|
||||
// Fields when action is an email (content should be added into note)
|
||||
$actioncomm->email_msgid = $cMailFile->msgid;
|
||||
$actioncomm->email_subject = $sendTopic;
|
||||
$actioncomm->email_from = $from;
|
||||
$actioncomm->email_sender = '';
|
||||
$actioncomm->email_to = $to;
|
||||
//$actioncomm->email_tocc = $sendtocc;
|
||||
//$actioncomm->email_tobcc = $sendtobcc;
|
||||
//$actioncomm->email_subject = $subject;
|
||||
$actioncomm->errors_to = $errors_to;
|
||||
|
||||
$actioncomm->elementtype = 'invoice';
|
||||
$actioncomm->fk_element = $tmpinvoice->id;
|
||||
|
||||
//$actioncomm->extraparams = $extraparams;
|
||||
|
||||
$actioncomm->create($user);
|
||||
} else {
|
||||
$errormesg = $cMailFile->error.' : '.$to;
|
||||
$error++;
|
||||
|
||||
// Add a line into event table
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
||||
|
||||
// Insert record of emails sent
|
||||
$actioncomm = new ActionComm($this->db);
|
||||
|
||||
$actioncomm->type_code = 'AC_OTH_AUTO'; // Event insert into agenda automatically
|
||||
$actioncomm->socid = $tmpinvoice->thirdparty->id; // To link to a company
|
||||
$actioncomm->contact_id = 0;
|
||||
|
||||
$actioncomm->code = 'AC_EMAIL';
|
||||
$actioncomm->label = 'sendEmailsRemindersOnInvoiceDueDateKO';
|
||||
$actioncomm->note_private = $errormesg;
|
||||
$actioncomm->fk_project = $tmpinvoice->fk_project;
|
||||
$actioncomm->datep = dol_now();
|
||||
$actioncomm->datef = $actioncomm->datep;
|
||||
$actioncomm->percentage = -1; // Not applicable
|
||||
$actioncomm->authorid = $user->id; // User saving action
|
||||
$actioncomm->userownerid = $user->id; // Owner of action
|
||||
// Fields when action is an email (content should be added into note)
|
||||
$actioncomm->email_msgid = $cMailFile->msgid;
|
||||
$actioncomm->email_from = $from;
|
||||
$actioncomm->email_sender = '';
|
||||
$actioncomm->email_to = $to;
|
||||
//$actioncomm->email_tocc = $sendtocc;
|
||||
//$actioncomm->email_tobcc = $sendtobcc;
|
||||
//$actioncomm->email_subject = $subject;
|
||||
$actioncomm->errors_to = $errors_to;
|
||||
|
||||
//$actioncomm->extraparams = $extraparams;
|
||||
|
||||
$actioncomm->create($user);
|
||||
}
|
||||
|
||||
$this->db->commit(); // We always commit
|
||||
}
|
||||
|
||||
if ($errormesg) {
|
||||
$errorsMsg[] = $errormesg;
|
||||
}
|
||||
} else {
|
||||
$errorsMsg[] = 'Failed to fetch record invoice with ID = '.$obj->id;
|
||||
$error++;
|
||||
}
|
||||
|
||||
// Sender
|
||||
$from = getDolGlobalString('MAIN_MAIL_EMAIL_FROM');
|
||||
if (!empty($arraymessage->email_from)) { // If a sender is defined into template, we use it in priority
|
||||
$from = $arraymessage->email_from;
|
||||
}
|
||||
if (empty($from)) {
|
||||
$errormesg = "Failed to get sender into global setup MAIN_MAIL_EMAIL_FROM";
|
||||
$loopError++;
|
||||
}
|
||||
|
||||
if (!$loopError && !empty($to)) {
|
||||
$this->db->begin();
|
||||
|
||||
$to = implode(',', $to);
|
||||
if (!empty($arraymessage->email_to)) { // If a recipient is defined into template, we add it
|
||||
$to = $to.','.$arraymessage->email_to;
|
||||
}
|
||||
|
||||
// Errors Recipient
|
||||
$errors_to = getDolGlobalString('MAIN_MAIL_ERRORS_TO');;
|
||||
|
||||
$trackid = 'inv'.$tmpinvoice->id;
|
||||
$sendcontext = 'standard';
|
||||
|
||||
$email_tocc = '';
|
||||
if (!empty($arraymessage->email_tocc)) { // If a CC is defined into template, we use it
|
||||
$email_tocc = $arraymessage->email_tocc;
|
||||
}
|
||||
|
||||
$email_tobcc = '';
|
||||
if (!empty($arraymessage->email_tobcc)) { // If a BCC is defined into template, we use it
|
||||
$email_tobcc = $arraymessage->email_tobcc;
|
||||
}
|
||||
|
||||
//join file is asked
|
||||
$joinFile = [];
|
||||
$joinFileName = [];
|
||||
$joinFileMime = [];
|
||||
if ($arraymessage->joinfiles == 1 && !empty($tmpinvoice->last_main_doc)) {
|
||||
$joinFile[] = DOL_DATA_ROOT.'/'.$tmpinvoice->last_main_doc;
|
||||
$joinFileName[] = basename($tmpinvoice->last_main_doc);
|
||||
$joinFileMime[] = dol_mimetype(DOL_DATA_ROOT.'/'.$tmpinvoice->last_main_doc);
|
||||
}
|
||||
|
||||
// Mail Creation
|
||||
$cMailFile = new CMailFile($sendTopic, $to, $from, $sendContent, $joinFile, $joinFileMime, $joinFileName, $email_tocc, $email_tobcc, 0, 1, $errors_to, '', $trackid, '', $sendcontext, '');
|
||||
|
||||
// Sending Mail
|
||||
if ($cMailFile->sendfile()) {
|
||||
$nbMailSend++;
|
||||
|
||||
// Add a line into event table
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
||||
|
||||
// Insert record of emails sent
|
||||
$actioncomm = new ActionComm($this->db);
|
||||
|
||||
$actioncomm->type_code = 'AC_OTH_AUTO'; // Event insert into agenda automatically
|
||||
$actioncomm->socid = $tmpinvoice->thirdparty->id; // To link to a company
|
||||
$actioncomm->contact_id = 0;
|
||||
|
||||
$actioncomm->code = 'AC_EMAIL';
|
||||
$actioncomm->label = 'sendEmailsRemindersOnInvoiceDueDateOK (nbdays='.$nbdays.' paymentmode='.$paymentmode.' template='.$template.' datetouse='.$datetouse.' forcerecipient='.$forcerecipient.')';
|
||||
$actioncomm->note_private = $sendContent;
|
||||
$actioncomm->fk_project = $tmpinvoice->fk_project;
|
||||
$actioncomm->datep = dol_now();
|
||||
$actioncomm->datef = $actioncomm->datep;
|
||||
$actioncomm->percentage = -1; // Not applicable
|
||||
$actioncomm->authorid = $user->id; // User saving action
|
||||
$actioncomm->userownerid = $user->id; // Owner of action
|
||||
// Fields when action is an email (content should be added into note)
|
||||
$actioncomm->email_msgid = $cMailFile->msgid;
|
||||
$actioncomm->email_subject = $sendTopic;
|
||||
$actioncomm->email_from = $from;
|
||||
$actioncomm->email_sender = '';
|
||||
$actioncomm->email_to = $to;
|
||||
//$actioncomm->email_tocc = $sendtocc;
|
||||
//$actioncomm->email_tobcc = $sendtobcc;
|
||||
//$actioncomm->email_subject = $subject;
|
||||
$actioncomm->errors_to = $errors_to;
|
||||
|
||||
$actioncomm->elementtype = 'invoice';
|
||||
$actioncomm->fk_element = $tmpinvoice->id;
|
||||
|
||||
//$actioncomm->extraparams = $extraparams;
|
||||
|
||||
$actioncomm->create($user);
|
||||
} else {
|
||||
$errormesg = $cMailFile->error.' : '.$to;
|
||||
$loopError++;
|
||||
|
||||
// Add a line into event table
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
||||
|
||||
// Insert record of emails sent
|
||||
$actioncomm = new ActionComm($this->db);
|
||||
|
||||
$actioncomm->type_code = 'AC_OTH_AUTO'; // Event insert into agenda automatically
|
||||
$actioncomm->socid = $tmpinvoice->thirdparty->id; // To link to a company
|
||||
$actioncomm->contact_id = 0;
|
||||
|
||||
$actioncomm->code = 'AC_EMAIL';
|
||||
$actioncomm->label = 'sendEmailsRemindersOnInvoiceDueDateKO';
|
||||
$actioncomm->note_private = $errormesg;
|
||||
$actioncomm->fk_project = $tmpinvoice->fk_project;
|
||||
$actioncomm->datep = dol_now();
|
||||
$actioncomm->datef = $actioncomm->datep;
|
||||
$actioncomm->percentage = -1; // Not applicable
|
||||
$actioncomm->authorid = $user->id; // User saving action
|
||||
$actioncomm->userownerid = $user->id; // Owner of action
|
||||
// Fields when action is an email (content should be added into note)
|
||||
$actioncomm->email_msgid = $cMailFile->msgid;
|
||||
$actioncomm->email_from = $from;
|
||||
$actioncomm->email_sender = '';
|
||||
$actioncomm->email_to = $to;
|
||||
//$actioncomm->email_tocc = $sendtocc;
|
||||
//$actioncomm->email_tobcc = $sendtobcc;
|
||||
//$actioncomm->email_subject = $subject;
|
||||
$actioncomm->errors_to = $errors_to;
|
||||
|
||||
//$actioncomm->extraparams = $extraparams;
|
||||
|
||||
$actioncomm->create($user);
|
||||
}
|
||||
|
||||
$this->db->commit(); // We always commit
|
||||
}
|
||||
|
||||
if ($errormesg) {
|
||||
$errorsMsg[] = $errormesg;
|
||||
}
|
||||
} else {
|
||||
$errorsMsg[] = 'Failed to fetch record invoice with ID = '.$obj->id;
|
||||
$loopError++;
|
||||
}
|
||||
|
||||
$error += $loopError;
|
||||
}
|
||||
} else {
|
||||
$error++;
|
||||
@@ -6399,7 +6414,7 @@ class FactureLigne extends CommonInvoiceLine
|
||||
|
||||
// If fk_remise_except is defined, the discount is linked to the invoice
|
||||
// which flags it as "consumed".
|
||||
if ($this->fk_remise_except) {
|
||||
if ($this->fk_remise_except && empty($error)) {
|
||||
$discount = new DiscountAbsolute($this->db);
|
||||
$result = $discount->fetch($this->fk_remise_except);
|
||||
if ($result >= 0) {
|
||||
@@ -6436,7 +6451,7 @@ class FactureLigne extends CommonInvoiceLine
|
||||
}
|
||||
}
|
||||
|
||||
if (!$notrigger) {
|
||||
if (!$notrigger && empty($error)) {
|
||||
// Call trigger
|
||||
$result = $this->call_trigger('LINEBILL_INSERT', $user);
|
||||
if ($result < 0) {
|
||||
@@ -6446,8 +6461,17 @@ class FactureLigne extends CommonInvoiceLine
|
||||
// End call triggers
|
||||
}
|
||||
|
||||
$this->db->commit();
|
||||
return $this->id;
|
||||
if (!$error) {
|
||||
$this->db->commit();
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
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->lasterror();
|
||||
$this->db->rollback();
|
||||
@@ -6618,8 +6642,18 @@ class FactureLigne extends CommonInvoiceLine
|
||||
}
|
||||
// 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();
|
||||
|
||||
@@ -55,12 +55,11 @@ $object = new Facture($db);
|
||||
if ($id > 0 || !empty($ref)) {
|
||||
$ret = $object->fetch($id, $ref, '', '', (!empty($conf->global->INVOICE_USE_SITUATION) ? $conf->global->INVOICE_USE_SITUATION : 0));
|
||||
}
|
||||
|
||||
$hookmanager->initHooks(array('invoicecontactcard', 'globalcard'));
|
||||
$result = restrictedArea($user, 'facture', $object->id);
|
||||
|
||||
$usercancreate = $user->hasRight("facture", "creer");
|
||||
|
||||
|
||||
/*
|
||||
* Add a new contact
|
||||
*/
|
||||
|
||||
@@ -79,6 +79,7 @@ $permissiontoadd = $user->hasRight('facture', 'creer');
|
||||
if ($user->socid) {
|
||||
$socid = $user->socid;
|
||||
}
|
||||
$hookmanager->initHooks(array('invoicedocument', 'globalcard'));
|
||||
$result = restrictedArea($user, 'facture', $object->id, '');
|
||||
|
||||
$usercancreate = $user->hasRight("facture", "creer");
|
||||
|
||||
@@ -422,8 +422,8 @@ if ($action == 'makepayment_confirm' && $user->hasRight('facture', 'paiement'))
|
||||
$paiementAmount = $facture->getSommePaiement();
|
||||
$totalcreditnotes = $facture->getSumCreditNotesUsed();
|
||||
$totaldeposits = $facture->getSumDepositsUsed();
|
||||
$totalpay = $paiementAmount + $totalcreditnotes + $totaldeposits;
|
||||
$remaintopay = price2num($facture->total_ttc - $totalpay);
|
||||
$totalallpayments = $paiementAmount + $totalcreditnotes + $totaldeposits;
|
||||
$remaintopay = price2num($facture->total_ttc - $totalallpayments);
|
||||
if ($remaintopay != 0) {
|
||||
$resultBank = $facture->setBankAccount($bankid);
|
||||
if ($resultBank < 0) {
|
||||
@@ -1821,6 +1821,9 @@ if ($resql) {
|
||||
$totalarray['val']['f.total_tva'] = 0;
|
||||
$totalarray['val']['f.total_ht'] = 0;
|
||||
$totalarray['val']['f.total_ttc'] = 0;
|
||||
$totalarray['val']['dynamount_payed'] = 0;
|
||||
$totalarray['val']['rtp'] = 0;
|
||||
|
||||
|
||||
$with_margin_info = false;
|
||||
if (isModEnabled('margin') && (
|
||||
@@ -1907,8 +1910,8 @@ if ($resql) {
|
||||
$multicurrency_totalcreditnotes = $facturestatic->getSumCreditNotesUsed(1);
|
||||
$multicurrency_totaldeposits = $facturestatic->getSumDepositsUsed(1);
|
||||
|
||||
$totalpay = $paiement + $totalcreditnotes + $totaldeposits;
|
||||
$remaintopay = price2num($facturestatic->total_ttc - $totalpay);
|
||||
$totalallpayments = $paiement + $totalcreditnotes + $totaldeposits;
|
||||
$remaintopay = $obj->total_ttc - $totalallpayments;
|
||||
|
||||
$multicurrency_totalpay = $multicurrency_paiement + $multicurrency_totalcreditnotes + $multicurrency_totaldeposits;
|
||||
$multicurrency_remaintopay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_totalpay);
|
||||
@@ -1920,13 +1923,16 @@ if ($resql) {
|
||||
if ($facturestatic->type == Facture::TYPE_CREDIT_NOTE && $obj->paye == 1) { // If credit note closed, we take into account the amount not yet consumed
|
||||
$remaincreditnote = $discount->getAvailableDiscounts($companystatic, '', 'rc.fk_facture_source='.$facturestatic->id);
|
||||
$remaintopay = -$remaincreditnote;
|
||||
$totalpay = price2num($facturestatic->total_ttc - $remaintopay);
|
||||
$totalallpayments = price2num($facturestatic->total_ttc - $remaintopay);
|
||||
$multicurrency_remaincreditnote = $discount->getAvailableDiscounts($companystatic, '', 'rc.fk_facture_source='.$facturestatic->id, 0, 0, 1);
|
||||
$multicurrency_remaintopay = -$multicurrency_remaincreditnote;
|
||||
$multicurrency_totalpay = price2num($facturestatic->multicurrency_total_ttc - $multicurrency_remaintopay);
|
||||
}
|
||||
|
||||
$facturestatic->alreadypaid = $paiement;
|
||||
$facturestatic->totalpaid = $paiement;
|
||||
$facturestatic->totalcreditnotes = $totalcreditnotes;
|
||||
$facturestatic->totaldeposits = $totaldeposits;
|
||||
|
||||
$marginInfo = array();
|
||||
if ($with_margin_info === true) {
|
||||
@@ -1999,6 +2005,8 @@ if ($resql) {
|
||||
|
||||
$filename = dol_sanitizeFileName($obj->ref);
|
||||
$filedir = $conf->facture->dir_output.'/'.dol_sanitizeFileName($obj->ref);
|
||||
$filepath = $conf->invoice->multidir_output[$obj->entity] ?? $conf->invoice->dir_output;
|
||||
$filedir = $filepath . '/' . $filename;
|
||||
$urlsource = $_SERVER['PHP_SELF'].'?id='.$obj->id;
|
||||
print $formfile->getDocumentsLink($facturestatic->element, $filename, $filedir);
|
||||
print '</td>';
|
||||
@@ -2379,14 +2387,14 @@ if ($resql) {
|
||||
}
|
||||
|
||||
if (!empty($arrayfields['dynamount_payed']['checked'])) {
|
||||
print '<td class="right nowraponall amount">'.(!empty($totalpay) ? price($totalpay, 0, $langs) : ' ').'</td>'; // TODO Use a denormalized field
|
||||
print '<td class="right nowraponall amount">'.(!empty($totalallpayments) ? price($totalallpayments, 0, $langs) : ' ').'</td>'; // TODO Use a denormalized field
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
if (!$i) {
|
||||
$totalarray['pos'][$totalarray['nbfield']] = 'totalam';
|
||||
$totalarray['pos'][$totalarray['nbfield']] = 'dynamount_payed';
|
||||
}
|
||||
$totalarray['val']['totalam'] += $totalpay;
|
||||
$totalarray['val']['dynamount_payed'] += $totalallpayments;
|
||||
}
|
||||
|
||||
// Pending amount
|
||||
@@ -2577,7 +2585,7 @@ if ($resql) {
|
||||
// Status
|
||||
if (!empty($arrayfields['f.fk_statut']['checked'])) {
|
||||
print '<td class="nowrap right">';
|
||||
print $facturestatic->getLibStatut(5, $paiement);
|
||||
print $facturestatic->getLibStatut(5, $totalallpayments);
|
||||
print "</td>";
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
|
||||
@@ -86,11 +86,21 @@ foreach ($linkedObjectBlock as $key => $objectlink) {
|
||||
|
||||
print '</td>';
|
||||
print '<td class="linkedcol-statut right">';
|
||||
$totalallpayments = 0;
|
||||
$totalcalculated = false;
|
||||
if (method_exists($objectlink, 'getSommePaiement')) {
|
||||
print $objectlink->getLibStatut(3, $objectlink->getSommePaiement());
|
||||
} else {
|
||||
print $objectlink->getLibStatut(3);
|
||||
$totalcalculated = true;
|
||||
$totalallpayments += $objectlink->getSommePaiement();
|
||||
}
|
||||
if (method_exists($objectlink, 'getSumDepositsUsed')) {
|
||||
$totalcalculated = true;
|
||||
$totalallpayments += $objectlink->getSumDepositsUsed();
|
||||
}
|
||||
if (method_exists($objectlink, 'getSumCreditNotesUsed')) {
|
||||
$totalcalculated = true;
|
||||
$totalallpayments += $objectlink->getSumCreditNotesUsed();
|
||||
}
|
||||
print $objectlink->getLibStatut(3, ($totalcalculated ? $totalallpayments : -1));
|
||||
print '</td>';
|
||||
print '<td class="linkedcol-action right"><a class="reposition" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=dellink&token='.newToken().'&dellinkid='.$key.'">'.img_picto($langs->transnoentitiesnoconv("RemoveLink"), 'unlink').'</a></td>';
|
||||
print "</tr>\n";
|
||||
|
||||
@@ -215,6 +215,9 @@ if (isModEnabled('facture') && $user->hasRight('facture', 'lire')) {
|
||||
$thirdpartystatic->code_compta = $obj->code_compta;
|
||||
//$thirdpartystatic->code_compta_fournisseur = $obj->code_compta_fournisseur;
|
||||
|
||||
$totalallpayments = $tmpinvoice->getSommePaiement(0);
|
||||
$totalallpayments += $tmpinvoice->getSumCreditNotesUsed(0);
|
||||
$totalallpayments += $tmpinvoice->getSumDepositsUsed(0);
|
||||
print '<tr class="oddeven">';
|
||||
print '<td class="nowrap">';
|
||||
|
||||
@@ -247,7 +250,7 @@ if (isModEnabled('facture') && $user->hasRight('facture', 'lire')) {
|
||||
|
||||
print '<td class="right" title="'.dol_escape_htmltag($langs->trans("DateModificationShort").' : '.dol_print_date($db->jdate($obj->tms), 'dayhour', 'tzuserrel')).'">'.dol_print_date($db->jdate($obj->tms), 'day', 'tzuserrel').'</td>';
|
||||
|
||||
print '<td>'.$tmpinvoice->getLibStatut(3, $obj->am).'</td>';
|
||||
print '<td>'.$tmpinvoice->getLibStatut(3, $totalallpayments).'</td>';
|
||||
|
||||
print '</tr>';
|
||||
|
||||
@@ -377,6 +380,8 @@ if ((isModEnabled('fournisseur') && empty($conf->global->MAIN_USE_NEW_SUPPLIERMO
|
||||
print '<td class="nowrap right"><span class="amount">'.price($obj->total_ttc).'</span></td>';
|
||||
print '<td class="right" title="'.dol_escape_htmltag($langs->trans("DateModificationShort").' : '.dol_print_date($db->jdate($obj->tms), 'dayhour', 'tzuserrel')).'">'.dol_print_date($db->jdate($obj->tms), 'day', 'tzuserrel').'</td>';
|
||||
$alreadypaid = $facstatic->getSommePaiement();
|
||||
$alreadypaid += $facstatic->getSumCreditNotesUsed();
|
||||
$alreadypaid += $facstatic->getSumDepositsUsed();
|
||||
print '<td>'.$facstatic->getLibStatut(3, $alreadypaid).'</td>';
|
||||
print '</tr>';
|
||||
$total_ht += $obj->total_ht;
|
||||
|
||||
@@ -888,10 +888,10 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
|
||||
|
||||
print '<br>';
|
||||
if (!empty($totalpayment)) {
|
||||
$text = $langs->trans('ConfirmCustomerPayment', $totalpayment, $langs->trans("Currency".$conf->currency));
|
||||
$text = $langs->trans('ConfirmCustomerPayment', $totalpayment, $langs->transnoentitiesnoconv("Currency".$conf->currency));
|
||||
}
|
||||
if (!empty($multicurrency_totalpayment)) {
|
||||
$text .= '<br>'.$langs->trans('ConfirmCustomerPayment', $multicurrency_totalpayment, $langs->trans("paymentInInvoiceCurrency"));
|
||||
$text .= '<br>'.$langs->trans('ConfirmCustomerPayment', $multicurrency_totalpayment, $langs->transnoentitiesnoconv("paymentInInvoiceCurrency"));
|
||||
}
|
||||
if (GETPOST('closepaidinvoices')) {
|
||||
$text .= '<br>'.$langs->trans("AllCompletelyPayedInvoiceWillBeClosed");
|
||||
|
||||
@@ -544,7 +544,7 @@ if ($action == 'new') {
|
||||
if (count($lines[$bid])) {
|
||||
foreach ($lines[$bid] as $lid => $value) {
|
||||
print '<tr class="oddeven">';
|
||||
print '<td>'.dol_print_date($value["date"], 'day').'</td>';
|
||||
print '<td>'.dol_print_date($value["paymentdate"], 'day').'</td>';
|
||||
print '<td>'.$value["numero"]."</td>\n";
|
||||
print '<td>'.$value["emetteur"]."</td>\n";
|
||||
print '<td>'.$value["banque"]."</td>\n";
|
||||
|
||||
@@ -1269,7 +1269,7 @@ class Paiement extends CommonObject
|
||||
$facturestatic = new Facture($this->db);
|
||||
foreach ($arraybill as $billid) {
|
||||
$facturestatic->fetch($billid);
|
||||
$label .= '<br> '.$facturestatic->getNomUrl(1, '', 0, 0, '', 1).' '.$facturestatic->getLibStatut(2, 1);
|
||||
$label .= '<br> '.$facturestatic->getNomUrl(1, '', 0, 0, '', 1).' '.$facturestatic->getLibStatut(2, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,6 +183,8 @@ if (GETPOST("orphelins", "alpha")) {
|
||||
$sql = "SELECT p.rowid, p.ref, p.datep, p.amount, p.statut, p.num_paiement";
|
||||
$sql .= ", c.code as paiement_code";
|
||||
|
||||
$sqlfields = $sql; // $sql fields to remove for count total
|
||||
|
||||
// Add fields from hooks
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldListSelect', $parameters); // Note that $action and $object may have been modified by hook
|
||||
@@ -197,10 +199,13 @@ if (GETPOST("orphelins", "alpha")) {
|
||||
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
|
||||
$sql .= $hookmanager->resPrint;
|
||||
} else {
|
||||
$sql = "SELECT p.rowid, p.ref, p.datep, p.fk_bank, p.amount, p.statut, p.num_paiement";
|
||||
$sql = "SELECT p.rowid, p.ref, p.datep, p.fk_bank, p.statut, p.num_paiement, p.amount";
|
||||
$sql .= ", c.code as paiement_code";
|
||||
$sql .= ", ba.rowid as bid, ba.ref as bref, ba.label as blabel, ba.number, ba.account_number as account_number, ba.fk_accountancy_journal as accountancy_journal";
|
||||
$sql .= ", s.rowid as socid, s.nom as name, s.email";
|
||||
// We need an aggregate because we added a left join to get the thirdparty. In real world, it should be the same thirdparty if payment is same (but not in database structure)
|
||||
// so SUM(pf.amount) should be equal to p.amount but if we filter on $socid, it may differ
|
||||
$sql .= ", SUM(pf.amount) as totalamount, COUNT(f.rowid) as nbinvoices";
|
||||
|
||||
// Add fields from hooks
|
||||
$parameters = array();
|
||||
@@ -213,18 +218,21 @@ if (GETPOST("orphelins", "alpha")) {
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_paiement = c.id";
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank as b ON p.fk_bank = b.rowid";
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."bank_account as ba ON b.fk_account = ba.rowid";
|
||||
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON p.rowid = pf.fk_paiement";
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON pf.fk_facture = f.rowid";
|
||||
$sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON f.fk_soc = s.rowid";
|
||||
|
||||
$sql .= " WHERE p.entity IN (".getEntity('invoice').")";
|
||||
if ($socid > 0) {
|
||||
$sql .= " AND f.fk_soc = ".((int) $socid);
|
||||
$sql .= " AND EXISTS (SELECT f.fk_soc FROM ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."paiement_facture as pf";
|
||||
$sql .= " WHERE p.rowid = pf.fk_paiement AND pf.fk_facture = f.rowid AND f.fk_soc = ".((int) $socid).")";
|
||||
}
|
||||
if ($userid) {
|
||||
if ($userid == -1) {
|
||||
$sql .= " AND f.fk_user_author IS NULL";
|
||||
$sql .= " AND p.fk_user_creat IS NULL";
|
||||
} else {
|
||||
$sql .= " AND f.fk_user_author = ".((int) $userid);
|
||||
$sql .= " AND p.fk_user_creat = ".((int) $userid);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -248,7 +256,10 @@ if (GETPOST("orphelins", "alpha")) {
|
||||
$sql .= natural_search('p.num_paiement', $search_payment_num);
|
||||
}
|
||||
if ($search_amount) {
|
||||
$sql .= natural_search('p.amount', $search_amount, 1);
|
||||
$sql .= " AND (".natural_search('p.amount', $search_amount, 1, 1);
|
||||
$sql .= " OR ";
|
||||
$sql .= natural_search('pf.amount', $search_amount, 1, 1);
|
||||
$sql .= ")";
|
||||
}
|
||||
if ($search_company) {
|
||||
$sql .= natural_search('s.nom', $search_company);
|
||||
@@ -270,13 +281,18 @@ if (GETPOST("orphelins", "alpha")) {
|
||||
$parameters = array();
|
||||
$reshook = $hookmanager->executeHooks('printFieldListWhere', $parameters); // Note that $action and $object may have been modified by hook
|
||||
$sql .= $hookmanager->resPrint;
|
||||
|
||||
$sql .= " GROUP BY p.rowid, p.ref, p.datep, p.fk_bank, p.statut, p.num_paiement, p.amount";
|
||||
$sql .= ", c.code";
|
||||
$sql .= ", ba.rowid, ba.ref, ba.label, ba.number, ba.account_number, ba.fk_accountancy_journal";
|
||||
$sql .= ", s.rowid, s.nom, s.email";
|
||||
}
|
||||
|
||||
// Count total nb of records
|
||||
$nbtotalofrecords = '';
|
||||
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('/^'.preg_quote($sqlfields, '/').'/', 'SELECT COUNT(DISTINCT p.rowid) as nbtotalofrecords', $sql);
|
||||
$sqlforcount = preg_replace('/GROUP BY .*$/', '', $sqlforcount);
|
||||
$resql = $db->query($sqlforcount);
|
||||
if ($resql) {
|
||||
@@ -298,6 +314,7 @@ $sql .= $db->order($sortfield, $sortorder);
|
||||
if ($limit) {
|
||||
$sql .= $db->plimit($limit + 1, $offset);
|
||||
}
|
||||
//print $sql;
|
||||
|
||||
$resql = $db->query($sql);
|
||||
if (!$resql) {
|
||||
@@ -532,6 +549,8 @@ while ($i < min($num, $limit)) {
|
||||
|
||||
$object->id = $objp->rowid;
|
||||
$object->ref = ($objp->ref ? $objp->ref : $objp->rowid);
|
||||
$object->date = $db->jdate($objp->datep);
|
||||
$object->amount = $objp->amount;
|
||||
|
||||
$companystatic->id = $objp->socid;
|
||||
$companystatic->name = $objp->name;
|
||||
@@ -629,7 +648,12 @@ while ($i < min($num, $limit)) {
|
||||
|
||||
// Amount
|
||||
if (!empty($arrayfields['p.amount']['checked'])) {
|
||||
print '<td class="right"><span class="amount">'.price($objp->amount).'</span></td>';
|
||||
print '<td class="right">';
|
||||
if ($objp->nbinvoices > 1 || ($objp->totalamount && $objp->amount != $objp->totalamount)) {
|
||||
print $form->textwithpicto('', $langs->trans("PaymentMadeForSeveralInvoices"));
|
||||
}
|
||||
print '<span class="amount">'.price($objp->amount).'</span>';
|
||||
print '</td>';
|
||||
if (!$i) {
|
||||
$totalarray['nbfield']++;
|
||||
}
|
||||
|
||||
@@ -51,7 +51,7 @@ $charge = new ChargeSociales($db);
|
||||
* Actions
|
||||
*/
|
||||
|
||||
if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm == 'yes')) {
|
||||
if ($action == 'add_payment') {
|
||||
$error = 0;
|
||||
|
||||
if ($cancel) {
|
||||
@@ -89,7 +89,7 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm == 'y
|
||||
}
|
||||
}
|
||||
|
||||
if (count($amounts) <= 0) {
|
||||
if (empty($amounts)) {
|
||||
$error++;
|
||||
setEventMessages($langs->trans("ErrorNoPaymentDefined"), null, 'errors');
|
||||
$action = 'create';
|
||||
@@ -119,9 +119,9 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm == 'y
|
||||
|
||||
if (!$error) {
|
||||
$result = $paiement->addPaymentToBank($user, 'payment_sc', '(SocialContributionPayment)', GETPOST('accountid', 'int'), '', '');
|
||||
if (!($result > 0)) {
|
||||
if ($result <= 0) {
|
||||
$error++;
|
||||
setEventMessages($paiement->error, null, 'errors');
|
||||
setEventMessages($paiement->error, $paiement->errors, 'errors');
|
||||
$action = 'create';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,27 +76,28 @@ class RejetPrelevement
|
||||
}
|
||||
|
||||
/**
|
||||
* Create
|
||||
* Create a reject
|
||||
*
|
||||
* @param User $user User object
|
||||
* @param int $id Id
|
||||
* @param string $motif Motif
|
||||
* @param int $date_rejet Date rejet
|
||||
* @param int $date_rejet Date reject
|
||||
* @param int $bonid Bon id
|
||||
* @param int $facturation Facturation
|
||||
* @return void
|
||||
* @param int $facturation 1=Bill the reject
|
||||
* @return int Return >=0 if OK, <0 if KO
|
||||
*/
|
||||
public function create($user, $id, $motif, $date_rejet, $bonid, $facturation = 0)
|
||||
{
|
||||
global $langs, $conf;
|
||||
global $langs;
|
||||
|
||||
$error = 0;
|
||||
$this->id = $id;
|
||||
$this->bon_id = $bonid;
|
||||
$now = dol_now();
|
||||
|
||||
dol_syslog("RejetPrelevement::Create id $id");
|
||||
$bankaccount = ($this->type == 'bank-transfer' ? $conf->global->PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT : $conf->global->PRELEVEMENT_ID_BANKACCOUNT);
|
||||
dol_syslog("RejetPrelevement::Create id ".$id);
|
||||
|
||||
$bankaccount = ($this->type == 'bank-transfer' ? getDolGlobalString('PAYMENTBYBANKTRANSFER_ID_BANKACCOUNT') : getDolGlobalString('PRELEVEMENT_ID_BANKACCOUNT'));
|
||||
$facs = $this->getListInvoices(1);
|
||||
|
||||
require_once DOL_DOCUMENT_ROOT.'/compta/prelevement/class/ligneprelevement.class.php';
|
||||
@@ -152,17 +153,16 @@ class RejetPrelevement
|
||||
|
||||
$fac->fetch($facs[$i][0]);
|
||||
|
||||
// Make a negative payment
|
||||
//$pai = new Paiement($this->db);
|
||||
$amountrejected = $facs[$i][1];
|
||||
|
||||
// Make a negative payment
|
||||
// Amount must be an array (id of invoice -> amount)
|
||||
$pai->amounts = array();
|
||||
|
||||
/*
|
||||
* We replace the comma with a point otherwise some
|
||||
* PHP installs sends only the part integer negative
|
||||
*/
|
||||
//var_dump($this->type);exit;
|
||||
|
||||
$pai->amounts[$facs[$i][0]] = price2num($amountrejected * -1); // The payment must be negative because it is a refund
|
||||
|
||||
$pai->amounts[$facs[$i][0]] = price2num($facs[$i][1] * ($this->type == 'bank-transfer' ? 1 : -1));
|
||||
$pai->datepaye = $date_rejet;
|
||||
$pai->paiementid = 3; // type of payment: withdrawal
|
||||
$pai->num_paiement = $fac->ref;
|
||||
@@ -175,7 +175,13 @@ class RejetPrelevement
|
||||
$error++;
|
||||
dol_syslog("RejetPrelevement::Create Error creation payment invoice ".$facs[$i][0]);
|
||||
} else {
|
||||
$result = $pai->addPaymentToBank($user, 'payment', '(InvoiceRefused)', $bankaccount, '', '');
|
||||
// We record entry into bank
|
||||
$mode = 'payment';
|
||||
if ($this->type == 'bank-transfer') {
|
||||
$mode = 'payment_supplier';
|
||||
}
|
||||
|
||||
$result = $pai->addPaymentToBank($user, $mode, '(InvoiceRefused)', $bankaccount, '', '');
|
||||
if ($result < 0) {
|
||||
dol_syslog("RejetPrelevement::Create AddPaymentToBan Error");
|
||||
$error++;
|
||||
@@ -200,9 +206,13 @@ class RejetPrelevement
|
||||
if ($error == 0) {
|
||||
dol_syslog("RejetPrelevement::Create Commit");
|
||||
$this->db->commit();
|
||||
|
||||
return 1;
|
||||
} else {
|
||||
dol_syslog("RejetPrelevement::Create Rollback");
|
||||
$this->db->rollback();
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ print '</span></td></tr></table></div><br>';
|
||||
/*
|
||||
* Invoices waiting for withdraw
|
||||
*/
|
||||
$sql = "SELECT f.ref, f.rowid, f.total_ttc, f.fk_statut, f.paye, f.type,";
|
||||
$sql = "SELECT f.ref, f.rowid, f.total_ttc, f.fk_statut as status, f.paye, f.type,";
|
||||
$sql .= " pfd.date_demande, pfd.amount,";
|
||||
$sql .= " s.nom as name, s.email, s.rowid as socid, s.tva_intra, s.siren as idprof1, s.siret as idprof2, s.ape as idprof3, s.idprof4, s.idprof5, s.idprof6";
|
||||
$sql .= " FROM ".MAIN_DB_PREFIX."facture as f,";
|
||||
@@ -141,10 +141,13 @@ if ($resql) {
|
||||
|
||||
$invoicestatic->id = $obj->rowid;
|
||||
$invoicestatic->ref = $obj->ref;
|
||||
$invoicestatic->statut = $obj->fk_statut;
|
||||
$invoicestatic->statut = $obj->status;
|
||||
$invoicestatic->status = $obj->status;
|
||||
$invoicestatic->paye = $obj->paye;
|
||||
$invoicestatic->type = $obj->type;
|
||||
$alreadypayed = $invoicestatic->getSommePaiement();
|
||||
$totalallpayments = $invoicestatic->getSommePaiement(0);
|
||||
$totalallpayments += $invoicestatic->getSumCreditNotesUsed(0);
|
||||
$totalallpayments += $invoicestatic->getSumDepositsUsed(0);
|
||||
|
||||
$thirdpartystatic->id = $obj->socid;
|
||||
$thirdpartystatic->name = $obj->name;
|
||||
@@ -177,7 +180,7 @@ if ($resql) {
|
||||
print '</td>';
|
||||
|
||||
print '<td class="right">';
|
||||
print $invoicestatic->getLibStatut(3, $alreadypayed);
|
||||
print $invoicestatic->getLibStatut(3, $totalallpayments);
|
||||
print '</td>';
|
||||
print '</tr>';
|
||||
$i++;
|
||||
|
||||
@@ -85,7 +85,7 @@ $error = 0;
|
||||
if ($action == 'confirm_rejet' && $permissiontoadd) {
|
||||
if (GETPOST("confirm") == 'yes') {
|
||||
if (GETPOST('remonth', 'int')) {
|
||||
$daterej = mktime(2, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
|
||||
$daterej = dol_mktime(0, 0, 0, GETPOST('remonth', 'int'), GETPOST('reday', 'int'), GETPOST('reyear', 'int'));
|
||||
}
|
||||
|
||||
if (empty($daterej)) {
|
||||
@@ -166,7 +166,12 @@ if ($id) {
|
||||
print '<tr><td class="titlefield">'.$langs->trans("Ref").'</td><td>';
|
||||
print $id.'</td></tr>';
|
||||
|
||||
print '<tr><td class="titlefield">'.$langs->trans("WithdrawalsReceipts").'</td><td>';
|
||||
if ($type == 'bank-transfer') {
|
||||
print '<tr><td class="titlefield">'.$langs->trans("BankTransfers").'</td><td>';
|
||||
} else {
|
||||
print '<tr><td class="titlefield">'.$langs->trans("WithdrawalsReceipts").'</td><td>';
|
||||
}
|
||||
|
||||
print $bon->getNomUrl(1).'</td></tr>';
|
||||
|
||||
print '<tr><td>'.$langs->trans("Date").'</td><td>'.dol_print_date($bon->datec, 'day').'</td></tr>';
|
||||
|
||||
@@ -417,7 +417,7 @@ while ($i < $imaxinloop) {
|
||||
print '<td>';
|
||||
print $line->LibStatut($obj->statut_ligne, 2);
|
||||
print " ";
|
||||
print '<a href="'.DOL_URL_ROOT.'/compta/prelevement/line.php?id='.$obj->rowid_ligne.'">';
|
||||
print '<a href="'.DOL_URL_ROOT.'/compta/prelevement/line.php?id='.$obj->rowid_ligne.($type == 'bank-transfer' ? '&type=bank-transfer' : '').'">';
|
||||
print substr('000000'.$obj->rowid_ligne, -6);
|
||||
print '</a></td>';
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@ if ($result) {
|
||||
|
||||
print '<td>';
|
||||
print $line->LibStatut($obj->statut, 2).' ';
|
||||
print '<a href="'.DOL_URL_ROOT.'/compta/prelevement/line.php?id='.$obj->rowid.'">';
|
||||
print '<a href="'.DOL_URL_ROOT.'/compta/prelevement/line.php?id='.$obj->rowid.($type == 'bank-transfer' ? '&type=bank-transfer' : '').'">';
|
||||
print substr('000000'.$obj->rowid, -6)."</a></td>";
|
||||
|
||||
print '<td><a href="'.DOL_URL_ROOT.'/comm/card.php?socid='.$obj->socid.'">'.$obj->nom."</a></td>\n";
|
||||
|
||||
@@ -159,7 +159,9 @@ if ($id > 0) {
|
||||
print $fac->error."<br>";
|
||||
continue;
|
||||
}
|
||||
$totalpaid = $fac->getSommePaiement();
|
||||
$alreadypaid = $fac->getSommePaiement();
|
||||
$alreadypaid += $fac->getSumDepositsUsed();
|
||||
$alreadypaid += $fac->getSumCreditNotesUsed();
|
||||
|
||||
$userstatic->id = $objf->userid;
|
||||
$userstatic->login = $objf->login;
|
||||
@@ -169,7 +171,7 @@ if ($id > 0) {
|
||||
'date' => $fac->date,
|
||||
'datefieldforsort' => $fac->date.'-'.$fac->ref,
|
||||
'link' => $fac->getNomUrl(1),
|
||||
'status' => $fac->getLibStatut(2, $totalpaid),
|
||||
'status' => $fac->getLibStatut(2, $alreadypaid),
|
||||
'amount' => $fac->total_ttc,
|
||||
'author' => $userstatic->getLoginUrl(1)
|
||||
);
|
||||
|
||||
@@ -259,7 +259,7 @@ print '<th class="liste_titre"></th>';
|
||||
print '<th class="liste_titre right">'.$langs->trans("PreviousPeriod").'</th>';
|
||||
print '<th class="liste_titre right">'.$langs->trans("SelectedPeriod").'</th>';
|
||||
foreach ($months as $k => $v) {
|
||||
if (($k + 1) >= $date_startmonth) {
|
||||
if (($k + 1) >= $date_startmonth && $k < $date_endmonth) {
|
||||
print '<th class="liste_titre right width50">'.$langs->trans('MonthShort'.sprintf("%02s", ($k + 1))).'</th>';
|
||||
}
|
||||
}
|
||||
@@ -392,7 +392,7 @@ if ($modecompta == 'CREANCES-DETTES') {
|
||||
|
||||
// Detail by month
|
||||
foreach ($months as $k => $v) {
|
||||
if (($k + 1) >= $date_startmonth) {
|
||||
if (($k + 1) >= $date_startmonth && $k < $date_endmonth) {
|
||||
foreach ($sommes as $code => $det) {
|
||||
$vars[$code] = empty($det['M'][$k]) ? 0 : $det['M'][$k];
|
||||
}
|
||||
@@ -505,33 +505,37 @@ if ($modecompta == 'CREANCES-DETTES') {
|
||||
$yeartoprocess++;
|
||||
}
|
||||
|
||||
//var_dump($monthtoprocess.'_'.$yeartoprocess);
|
||||
if (isset($cpt['account_number'])) {
|
||||
$return = $AccCat->getSumDebitCredit($cpt['account_number'], $date_start, $date_end, empty($cat['dc']) ? 0 : $cat['dc'], 'nofilter', $monthtoprocess, $yeartoprocess);
|
||||
if ($return < 0) {
|
||||
setEventMessages(null, $AccCat->errors, 'errors');
|
||||
$resultM = 0;
|
||||
if (($yeartoprocess == $start_year && ($k + 1) >= $date_startmonth && $k < $date_endmonth) ||
|
||||
($yeartoprocess == $start_year + 1 && ($k + 1) < $date_startmonth)
|
||||
) {
|
||||
//var_dump($monthtoprocess.'_'.$yeartoprocess);
|
||||
if (isset($cpt['account_number'])) {
|
||||
$return = $AccCat->getSumDebitCredit($cpt['account_number'], $date_start, $date_end, empty($cat['dc']) ? 0 : $cat['dc'], 'nofilter', $monthtoprocess, $yeartoprocess);
|
||||
if ($return < 0) {
|
||||
setEventMessages(null, $AccCat->errors, 'errors');
|
||||
$resultM = 0;
|
||||
} else {
|
||||
$resultM = $AccCat->sdc;
|
||||
}
|
||||
} else {
|
||||
$resultM = $AccCat->sdc;
|
||||
$resultM = 0;
|
||||
}
|
||||
if (empty($totCat['M'][$k])) {
|
||||
$totCat['M'][$k] = $resultM;
|
||||
} else {
|
||||
$totCat['M'][$k] += $resultM;
|
||||
}
|
||||
if (empty($sommes[$code]['M'][$k])) {
|
||||
$sommes[$code]['M'][$k] = $resultM;
|
||||
} else {
|
||||
$sommes[$code]['M'][$k] += $resultM;
|
||||
}
|
||||
if (isset($cpt['account_number'])) {
|
||||
$totPerAccount[$cpt['account_number']]['M'][$k] = $resultM;
|
||||
}
|
||||
} else {
|
||||
$resultM = 0;
|
||||
}
|
||||
if (empty($totCat['M'][$k])) {
|
||||
$totCat['M'][$k] = $resultM;
|
||||
} else {
|
||||
$totCat['M'][$k] += $resultM;
|
||||
}
|
||||
if (empty($sommes[$code]['M'][$k])) {
|
||||
$sommes[$code]['M'][$k] = $resultM;
|
||||
} else {
|
||||
$sommes[$code]['M'][$k] += $resultM;
|
||||
}
|
||||
if (isset($cpt['account_number'])) {
|
||||
$totPerAccount[$cpt['account_number']]['M'][$k] = $resultM;
|
||||
}
|
||||
|
||||
$resultN += $resultM;
|
||||
$resultN += $resultM;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($totCat)) {
|
||||
@@ -591,7 +595,7 @@ if ($modecompta == 'CREANCES-DETTES') {
|
||||
|
||||
// Each month
|
||||
foreach ($totCat['M'] as $k => $v) {
|
||||
if (($k + 1) >= $date_startmonth) {
|
||||
if (($k + 1) >= $date_startmonth && $k < $date_endmonth) {
|
||||
print '<td class="right nowraponall"><span class="amount">'.price($v).'</span></td>';
|
||||
}
|
||||
}
|
||||
@@ -632,7 +636,7 @@ if ($modecompta == 'CREANCES-DETTES') {
|
||||
|
||||
// Make one call for each month
|
||||
foreach ($months as $k => $v) {
|
||||
if (($k + 1) >= $date_startmonth) {
|
||||
if (($k + 1) >= $date_startmonth && $k < $date_endmonth) {
|
||||
if (isset($cpt['account_number'])) {
|
||||
$resultM = $totPerAccount[$cpt['account_number']]['M'][$k];
|
||||
} else {
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user