mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-17 20:19:20 +00:00
Compare commits
828 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
92e09c0b7b | ||
|
|
819c50c042 | ||
|
|
6887cedaea | ||
|
|
aa7896f1e1 | ||
|
|
52909b73bb | ||
|
|
5235aa833c | ||
|
|
d0131762cc | ||
|
|
97b98b6c01 | ||
|
|
92a6155bb0 | ||
|
|
d6e67ce123 | ||
|
|
6a4e230cde | ||
|
|
c65f1d7745 | ||
|
|
e02ee898e9 | ||
|
|
2e6f6d6749 | ||
|
|
014b138074 | ||
|
|
fb734976eb | ||
|
|
8e7ba95b78 | ||
|
|
e146143bd1 | ||
|
|
4d22b6db30 | ||
|
|
bdfc074a7d | ||
|
|
c7bd77111e | ||
|
|
4a60554b91 | ||
|
|
3dc21b099d | ||
|
|
40a02769c5 | ||
|
|
e6712c129c | ||
|
|
464289b726 | ||
|
|
1c1237537b | ||
|
|
b7483f6dfd | ||
|
|
cba7a11d75 | ||
|
|
2672c331af | ||
|
|
f4283a3ebf | ||
|
|
8a0943ead7 | ||
|
|
82c9352d53 | ||
|
|
311823aca1 | ||
|
|
6c06e700d6 | ||
|
|
f76bc27db5 | ||
|
|
b88b7eaf5b | ||
|
|
7533101d4b | ||
|
|
e7eda65968 | ||
|
|
5fdd26f1e7 | ||
|
|
c44290955e | ||
|
|
4825eccad5 | ||
|
|
5a4d5bfaf2 | ||
|
|
b4f5f14438 | ||
|
|
bb60a59b96 | ||
|
|
5fa2adcca9 | ||
|
|
12e817bad6 | ||
|
|
47e405516b | ||
|
|
4272483f2d | ||
|
|
3173be9b17 | ||
|
|
9cb817874d | ||
|
|
8227422124 | ||
|
|
a7d5f94d4a | ||
|
|
7624e7bf85 | ||
|
|
dd7c1b87c5 | ||
|
|
3e4ca4219f | ||
|
|
7ec7a45f05 | ||
|
|
3e02d80636 | ||
|
|
5ab6ff2470 | ||
|
|
11e964d442 | ||
|
|
a516856c32 | ||
|
|
84f7ba8699 | ||
|
|
a3fe5b8528 | ||
|
|
bad5e90e46 | ||
|
|
a9feddbb79 | ||
|
|
44734049f5 | ||
|
|
bc4e2cd9c1 | ||
|
|
bfb108d722 | ||
|
|
45a640df08 | ||
|
|
53659cf0bd | ||
|
|
80f333950b | ||
|
|
cd4202c2f7 | ||
|
|
d3214fed57 | ||
|
|
bbbce58884 | ||
|
|
8bf7230fcc | ||
|
|
496174bbdf | ||
|
|
4072d71769 | ||
|
|
5ffed60916 | ||
|
|
8854438830 | ||
|
|
15411fcf70 | ||
|
|
76a9cefc9c | ||
|
|
4f7873b9df | ||
|
|
ad9afe68f3 | ||
|
|
41e2b98b63 | ||
|
|
4eb5286c4b | ||
|
|
3f309e1c20 | ||
|
|
9bb81ee1cb | ||
|
|
4cdb9dee09 | ||
|
|
ee9da67173 | ||
|
|
9893a2d608 | ||
|
|
e78601b040 | ||
|
|
47b2a5f7d1 | ||
|
|
5ba4c4c49c | ||
|
|
172f28fa06 | ||
|
|
d635a2646b | ||
|
|
f347e23556 | ||
|
|
966b3c156a | ||
|
|
fbbb8695f3 | ||
|
|
f9577652a0 | ||
|
|
d270748eea | ||
|
|
5ba39f3f83 | ||
|
|
2622d370c6 | ||
|
|
e181dd4c24 | ||
|
|
7f9d75521e | ||
|
|
eaf0abedd4 | ||
|
|
f91ad75b5a | ||
|
|
5cb6c38a34 | ||
|
|
6f5853b97a | ||
|
|
62ce218fc2 | ||
|
|
1b0f3ec666 | ||
|
|
beeba8b37a | ||
|
|
d7636b2b19 | ||
|
|
b870d0081b | ||
|
|
7eaeec951d | ||
|
|
5a834209d0 | ||
|
|
e3a5899980 | ||
|
|
455c3ebb27 | ||
|
|
58b587834e | ||
|
|
e31757b001 | ||
|
|
e0dfd1608e | ||
|
|
bf3b54f658 | ||
|
|
395cf4689b | ||
|
|
925e9776e8 | ||
|
|
9c0d30a087 | ||
|
|
4cb4d2f155 | ||
|
|
975d28307a | ||
|
|
607b5d4985 | ||
|
|
ea390effa5 | ||
|
|
31e6f75dbf | ||
|
|
34ad2e6a60 | ||
|
|
f8ad0cbe70 | ||
|
|
0518001bdc | ||
|
|
25db832be1 | ||
|
|
f23788bb7d | ||
|
|
74ce391303 | ||
|
|
671c6610de | ||
|
|
8c3d19e2ab | ||
|
|
4a5ac7cea6 | ||
|
|
f7a856b913 | ||
|
|
26507d7867 | ||
|
|
d6d99e0d59 | ||
|
|
729aa2025a | ||
|
|
7d4fd35aa3 | ||
|
|
e87a076f1d | ||
|
|
fd345f8e90 | ||
|
|
ff689a658f | ||
|
|
b290e3a4e7 | ||
|
|
77f0822abe | ||
|
|
f83bc51e81 | ||
|
|
fc712aea32 | ||
|
|
7105c4b76c | ||
|
|
54c725dcd1 | ||
|
|
1e2c554e61 | ||
|
|
65dfd09947 | ||
|
|
61287e3c53 | ||
|
|
1b67d71139 | ||
|
|
32456b0f14 | ||
|
|
3d0d4b2157 | ||
|
|
7e5a9f5c0e | ||
|
|
d3e21fff66 | ||
|
|
5171956646 | ||
|
|
0cc93538ed | ||
|
|
b779644493 | ||
|
|
c83e793ce8 | ||
|
|
4d68e03a97 | ||
|
|
eaec4695f7 | ||
|
|
5049edb494 | ||
|
|
d17bea0a31 | ||
|
|
444bfff1ff | ||
|
|
ee4a2dd26f | ||
|
|
f6580268e6 | ||
|
|
e3a468ed1b | ||
|
|
9e6f2a49e8 | ||
|
|
445e8a2e57 | ||
|
|
7b6eaee05b | ||
|
|
c26e3f1569 | ||
|
|
c4e52e5f95 | ||
|
|
7eba1a35d3 | ||
|
|
1f10d693e9 | ||
|
|
53e8989699 | ||
|
|
8919669ac2 | ||
|
|
d977333a99 | ||
|
|
3a2834c7ad | ||
|
|
88491715e0 | ||
|
|
0bdf1e5ef1 | ||
|
|
f059e7be35 | ||
|
|
00a48ad4e5 | ||
|
|
def308a433 | ||
|
|
cb38e599e5 | ||
|
|
9b98d7fa14 | ||
|
|
b1bf502119 | ||
|
|
cb48404bd2 | ||
|
|
5b58e489a8 | ||
|
|
38647ed832 | ||
|
|
42c74a6365 | ||
|
|
c6f25ba996 | ||
|
|
b387b3cca0 | ||
|
|
a456901e9f | ||
|
|
0f2b21f88b | ||
|
|
73f4eef40f | ||
|
|
9ded8a7290 | ||
|
|
c2befc59d1 | ||
|
|
34a8fb4100 | ||
|
|
47eac28f0a | ||
|
|
869b878286 | ||
|
|
f2e2e23b6b | ||
|
|
3a22fd1535 | ||
|
|
f07e53b7a8 | ||
|
|
bd121486a8 | ||
|
|
122981d465 | ||
|
|
962cef470a | ||
|
|
0f73f90fa2 | ||
|
|
69e88ffa39 | ||
|
|
f29969a5cc | ||
|
|
e3ed8b7cb3 | ||
|
|
9626ed79fa | ||
|
|
c429a6e688 | ||
|
|
2315a79b5f | ||
|
|
9da25f568d | ||
|
|
9d497a984b | ||
|
|
bb03ec103b | ||
|
|
4c58588d25 | ||
|
|
4b99fe15cc | ||
|
|
b9fe14631d | ||
|
|
01b96a0e31 | ||
|
|
79a1d2a3b0 | ||
|
|
6488645d42 | ||
|
|
b46900a4cb | ||
|
|
912ae24ca2 | ||
|
|
e292c83114 | ||
|
|
e1a4b3e4bc | ||
|
|
d3a48a83fd | ||
|
|
80d24f83f8 | ||
|
|
5d8fd477bd | ||
|
|
bf37995745 | ||
|
|
5510d0751d | ||
|
|
b79c4a9ff6 | ||
|
|
1b61dfd9ea | ||
|
|
3f7d96ecba | ||
|
|
367b90e3ae | ||
|
|
945f502748 | ||
|
|
9c339145b2 | ||
|
|
3c14c5a16c | ||
|
|
bdb4c542e7 | ||
|
|
6d61a45f42 | ||
|
|
c314485d55 | ||
|
|
3b04cfc812 | ||
|
|
79ba422273 | ||
|
|
0dc3c1b114 | ||
|
|
0f6fff6f0c | ||
|
|
2b87d100fa | ||
|
|
c4ee77a3cc | ||
|
|
3ec6960478 | ||
|
|
33670bba47 | ||
|
|
73f1c93cd2 | ||
|
|
bf68611567 | ||
|
|
0d91d3f572 | ||
|
|
892ec599d4 | ||
|
|
65cd9f2284 | ||
|
|
799d69baba | ||
|
|
71866e06f3 | ||
|
|
284ceb7abe | ||
|
|
65c7a6947a | ||
|
|
f7a8277d12 | ||
|
|
12cb07ce3c | ||
|
|
23a4b09d43 | ||
|
|
c9f9e5235b | ||
|
|
edd4fd4692 | ||
|
|
ca916a73de | ||
|
|
53e19075d1 | ||
|
|
a0ba5594f9 | ||
|
|
16645803f9 | ||
|
|
94799a8b93 | ||
|
|
fce14fdcf0 | ||
|
|
7baacb7f74 | ||
|
|
76615c8001 | ||
|
|
283922daa2 | ||
|
|
da8de2f0c7 | ||
|
|
0060993eab | ||
|
|
566a0a05c8 | ||
|
|
f702d72c35 | ||
|
|
76e1ca35ad | ||
|
|
e0a845c356 | ||
|
|
eb686f8b1a | ||
|
|
d3fa19143d | ||
|
|
70eaf2da95 | ||
|
|
103b239a31 | ||
|
|
87e994e0a2 | ||
|
|
45d45f4247 | ||
|
|
946e182564 | ||
|
|
9aff73d156 | ||
|
|
df8fbd7d72 | ||
|
|
51a07d19c8 | ||
|
|
8ff0a64ac2 | ||
|
|
c0b4f0e81b | ||
|
|
b0ba55e52f | ||
|
|
d4c2d77bba | ||
|
|
ada8ba96b3 | ||
|
|
773e686fb1 | ||
|
|
afe9eabd3c | ||
|
|
360c1efd18 | ||
|
|
a0b85cd1ec | ||
|
|
9ef023b10f | ||
|
|
0d0811ca14 | ||
|
|
39c2f75e6d | ||
|
|
cb5e1e550f | ||
|
|
3ab938ea34 | ||
|
|
7da3c46ef2 | ||
|
|
3b61552836 | ||
|
|
4ebac3380d | ||
|
|
e4be3f8dc9 | ||
|
|
cdd6ded790 | ||
|
|
3d5d858933 | ||
|
|
fb142f5283 | ||
|
|
6d78f7b862 | ||
|
|
5478a7fa67 | ||
|
|
2851dfad99 | ||
|
|
5b05335e89 | ||
|
|
0e28fccb34 | ||
|
|
ab5b03011d | ||
|
|
12fd8a6047 | ||
|
|
24ec3c7dcb | ||
|
|
c4c2c56af2 | ||
|
|
705d885b64 | ||
|
|
1c1dd08a34 | ||
|
|
b2dca79d89 | ||
|
|
6960a76adc | ||
|
|
0664d6ed8b | ||
|
|
1bcc6c661a | ||
|
|
9b44c16a32 | ||
|
|
1299d56e85 | ||
|
|
8c88af23ef | ||
|
|
d1d2633658 | ||
|
|
152ba1eccb | ||
|
|
49c52f7639 | ||
|
|
4e0559bc79 | ||
|
|
2b39d5d6d5 | ||
|
|
e4acf763a5 | ||
|
|
f073814635 | ||
|
|
2e4de83df6 | ||
|
|
f551b43a94 | ||
|
|
c15a3bd379 | ||
|
|
caf9891075 | ||
|
|
bd4b80e3d8 | ||
|
|
9930eb0a7a | ||
|
|
703e837125 | ||
|
|
4f0f144142 | ||
|
|
cf36534eed | ||
|
|
cb6774e373 | ||
|
|
1276893550 | ||
|
|
d02744b436 | ||
|
|
850eaa73b0 | ||
|
|
e859671eb3 | ||
|
|
d258372f9e | ||
|
|
f6d738b3c5 | ||
|
|
b98359f4a7 | ||
|
|
5c1d15f015 | ||
|
|
a22c94c246 | ||
|
|
aebcb17daf | ||
|
|
6cea73b834 | ||
|
|
bd0beb6c02 | ||
|
|
e78d5a240a | ||
|
|
de3429280b | ||
|
|
8c9f2a1be6 | ||
|
|
9b4f3cf9de | ||
|
|
0396674d0d | ||
|
|
9c334c34a6 | ||
|
|
e716da04ec | ||
|
|
590d401e5f | ||
|
|
9bc197cfd5 | ||
|
|
d7e1869a70 | ||
|
|
3f15bf9828 | ||
|
|
9744aa21af | ||
|
|
91eda6dad4 | ||
|
|
8f957ef6e6 | ||
|
|
11bd5fc3b1 | ||
|
|
2222f10720 | ||
|
|
bc9006ff30 | ||
|
|
70ef09aa8f | ||
|
|
2cb2064c6f | ||
|
|
21617da619 | ||
|
|
628ca2a2ec | ||
|
|
46941e8b35 | ||
|
|
d1ce7bfff4 | ||
|
|
dd092e30fb | ||
|
|
5ac01a2bf7 | ||
|
|
27bbb561d2 | ||
|
|
2c1f44ecfa | ||
|
|
c73383c34c | ||
|
|
43268bd350 | ||
|
|
2f64f0f5fa | ||
|
|
427172c941 | ||
|
|
41146657de | ||
|
|
092f6d3739 | ||
|
|
f41cff27e6 | ||
|
|
ea832b8157 | ||
|
|
fd39e6f3c8 | ||
|
|
8ea3bb0d90 | ||
|
|
45dce89cae | ||
|
|
bf8e331135 | ||
|
|
a6d78ef842 | ||
|
|
beb2f3c415 | ||
|
|
77b225e021 | ||
|
|
3f583b6dd2 | ||
|
|
d3e22ac09e | ||
|
|
f6b132f78e | ||
|
|
c7c141a5a0 | ||
|
|
f8458ed9e4 | ||
|
|
9a0db392de | ||
|
|
92309afea1 | ||
|
|
242218d2b7 | ||
|
|
c050c6945c | ||
|
|
52ac483368 | ||
|
|
c443c9f05d | ||
|
|
78baebfe0d | ||
|
|
f056974bc5 | ||
|
|
ff667695ad | ||
|
|
f849915c13 | ||
|
|
231c324589 | ||
|
|
f8f29677fd | ||
|
|
50312b54a0 | ||
|
|
e47bd4f477 | ||
|
|
ab64e323cd | ||
|
|
67dfd26639 | ||
|
|
54099e592e | ||
|
|
580f39a12c | ||
|
|
c9e96c15af | ||
|
|
de9eebe51c | ||
|
|
d54d6bc572 | ||
|
|
38830e54d8 | ||
|
|
1a77922e85 | ||
|
|
d0823adf42 | ||
|
|
80b902cea6 | ||
|
|
e5716e3b1e | ||
|
|
47605cae16 | ||
|
|
8a803a2310 | ||
|
|
e2149cb46f | ||
|
|
509bca36b1 | ||
|
|
cfb9310d13 | ||
|
|
4e006b0bc5 | ||
|
|
f5cbb9c7b9 | ||
|
|
336c9b23d6 | ||
|
|
dfeadf876e | ||
|
|
b9d158076e | ||
|
|
438088f69d | ||
|
|
80b2ba2b9a | ||
|
|
197901108e | ||
|
|
425f1df799 | ||
|
|
9bc2b66e14 | ||
|
|
d4e57a38a4 | ||
|
|
06b22e9ac1 | ||
|
|
07b713121b | ||
|
|
1b65575860 | ||
|
|
166b78f022 | ||
|
|
c79d14190f | ||
|
|
2e8e5354e9 | ||
|
|
290e066633 | ||
|
|
134d59949a | ||
|
|
2697e332f3 | ||
|
|
c72d08e8b9 | ||
|
|
ec46e51ed4 | ||
|
|
7419c4b577 | ||
|
|
914fd197fc | ||
|
|
8868ae22be | ||
|
|
ded8d11728 | ||
|
|
6c3618be37 | ||
|
|
6ef741554c | ||
|
|
668d04548a | ||
|
|
68a4146999 | ||
|
|
d4316f0264 | ||
|
|
4bcaeb312c | ||
|
|
e4434d3200 | ||
|
|
62b1dc777e | ||
|
|
799619b6b0 | ||
|
|
3ad045302b | ||
|
|
499fbe90dc | ||
|
|
c929e88b97 | ||
|
|
05885ca184 | ||
|
|
2967d7ed01 | ||
|
|
c872095d76 | ||
|
|
8054d962cf | ||
|
|
22cff25bf5 | ||
|
|
7faac85fff | ||
|
|
d32f08f6ec | ||
|
|
10fdf5a8c3 | ||
|
|
11cf44986b | ||
|
|
95d8fd38f5 | ||
|
|
cf9e986f82 | ||
|
|
fd39d6bd3c | ||
|
|
2e6db4d928 | ||
|
|
21833413b0 | ||
|
|
11355cd3c9 | ||
|
|
2b05e61d58 | ||
|
|
baacf51a00 | ||
|
|
85eeafdccc | ||
|
|
d6922b2de3 | ||
|
|
6ab630371d | ||
|
|
f1881065a8 | ||
|
|
fc1c00716c | ||
|
|
baabb07e00 | ||
|
|
7d868e41a6 | ||
|
|
a9c9b69c22 | ||
|
|
d112ee5244 | ||
|
|
3e43927767 | ||
|
|
60739847ab | ||
|
|
9012a9b414 | ||
|
|
4f939b82b6 | ||
|
|
2965f92be3 | ||
|
|
2a4328b4f5 | ||
|
|
d974bcd2fa | ||
|
|
d7ff9dca1d | ||
|
|
e7e29b7f10 | ||
|
|
84be137b4e | ||
|
|
1252c30edf | ||
|
|
1458d7fea6 | ||
|
|
7f8a259beb | ||
|
|
56e31d05e9 | ||
|
|
3c635e219e | ||
|
|
de278635a3 | ||
|
|
7e752c4ebf | ||
|
|
6163a397df | ||
|
|
1116f96aee | ||
|
|
491108a198 | ||
|
|
5096c45dec | ||
|
|
a896e52489 | ||
|
|
fd6b371dac | ||
|
|
c0f34f454b | ||
|
|
70aaff46be | ||
|
|
1a947dbf6a | ||
|
|
c70bbacd34 | ||
|
|
655f86d5e2 | ||
|
|
b9939a6449 | ||
|
|
6f50b3a5b2 | ||
|
|
ba3f0e6b70 | ||
|
|
6ccb6562f1 | ||
|
|
847f9f80c1 | ||
|
|
7ed4bfe7ee | ||
|
|
8fbc08f91f | ||
|
|
872bebbbf8 | ||
|
|
f8e6c44996 | ||
|
|
5d0c4361ab | ||
|
|
aaec42ebc2 | ||
|
|
95e13ea629 | ||
|
|
d44af40de8 | ||
|
|
2df0788c11 | ||
|
|
914b8463b7 | ||
|
|
7ba2a83182 | ||
|
|
554cf9be44 | ||
|
|
da2164373c | ||
|
|
c3a2204653 | ||
|
|
3ae9e91bcd | ||
|
|
d733b7d7d0 | ||
|
|
5e2d2059fe | ||
|
|
2558daf6b7 | ||
|
|
2f7cb82ca0 | ||
|
|
7dc113e977 | ||
|
|
579c8e68f9 | ||
|
|
e33a1e0515 | ||
|
|
bf4a974124 | ||
|
|
9a04da27b0 | ||
|
|
764bb30d2d | ||
|
|
6544a85f1e | ||
|
|
8de7c0245c | ||
|
|
17b2720f5b | ||
|
|
5d9196960e | ||
|
|
caab582943 | ||
|
|
1010a2a2a4 | ||
|
|
3da5574d79 | ||
|
|
6b651d734e | ||
|
|
e5f6b4d640 | ||
|
|
7e506af0b9 | ||
|
|
72fa958f2c | ||
|
|
641d88fd6b | ||
|
|
6d2f6c2e4d | ||
|
|
4a546e6c18 | ||
|
|
dc9744f353 | ||
|
|
dd8c0febd5 | ||
|
|
26df5b8c00 | ||
|
|
2d2b12c800 | ||
|
|
06f5ae0e78 | ||
|
|
918f029d98 | ||
|
|
cb40bd86f8 | ||
|
|
b73321c577 | ||
|
|
b903c86076 | ||
|
|
fcb2462902 | ||
|
|
1669404f06 | ||
|
|
b69ec059fe | ||
|
|
d46a9572af | ||
|
|
7379e4e5de | ||
|
|
bb326f2bbd | ||
|
|
34c218b2de | ||
|
|
382f5eb1b1 | ||
|
|
a6a93cbe06 | ||
|
|
a1637d8343 | ||
|
|
5cf3bdd593 | ||
|
|
081ff80882 | ||
|
|
4396a0e9a8 | ||
|
|
3b3ab4d574 | ||
|
|
974cfd2895 | ||
|
|
187cea3602 | ||
|
|
28d8557905 | ||
|
|
8f4e1712ba | ||
|
|
7716a08b5d | ||
|
|
7d9452f4e4 | ||
|
|
4cbd43cb40 | ||
|
|
11224eaf06 | ||
|
|
02bad86037 | ||
|
|
6c6e45157b | ||
|
|
52cc08dd2d | ||
|
|
adbf8adfb9 | ||
|
|
a591d1df5f | ||
|
|
33326fe90e | ||
|
|
78c81d9c6c | ||
|
|
c87c1dbbbf | ||
|
|
575ab3ab70 | ||
|
|
5088ad11ee | ||
|
|
62f0722325 | ||
|
|
9d6900bd3b | ||
|
|
ddb26d02e5 | ||
|
|
879e162cce | ||
|
|
196b491ac4 | ||
|
|
1f49f511aa | ||
|
|
0d9ab86496 | ||
|
|
6b1624cfee | ||
|
|
222e86bb13 | ||
|
|
80d06da978 | ||
|
|
dd351c585a | ||
|
|
8fd5b325e0 | ||
|
|
eba50c6860 | ||
|
|
592e8c2e77 | ||
|
|
5a27aead06 | ||
|
|
f03a73466c | ||
|
|
ca63cc6439 | ||
|
|
2890fa74a2 | ||
|
|
97c1bcf14f | ||
|
|
780f11ec16 | ||
|
|
fe43ecb5ee | ||
|
|
fff56530c4 | ||
|
|
5b266eff89 | ||
|
|
0f3d431476 | ||
|
|
b1daab4284 | ||
|
|
7bcb1cfc42 | ||
|
|
a0f8687945 | ||
|
|
03e7ec29e7 | ||
|
|
6e7db034f2 | ||
|
|
446c2b0e91 | ||
|
|
0650d8e155 | ||
|
|
ee9f9863ff | ||
|
|
9727a3fe50 | ||
|
|
df83191ea0 | ||
|
|
13218f7d76 | ||
|
|
bea7d9f919 | ||
|
|
1b43515160 | ||
|
|
48058a88e5 | ||
|
|
f7e42211b9 | ||
|
|
abd3419632 | ||
|
|
b5ed6823d6 | ||
|
|
f37eacdee5 | ||
|
|
64c32dcd59 | ||
|
|
9eb8680ec9 | ||
|
|
f35710db15 | ||
|
|
258faab761 | ||
|
|
5fc5b68a49 | ||
|
|
0371d5a326 | ||
|
|
44b088c6b3 | ||
|
|
289400d944 | ||
|
|
21fc26c2a2 | ||
|
|
f6544e95d4 | ||
|
|
4f366e9c38 | ||
|
|
683b015951 | ||
|
|
0973161ae5 | ||
|
|
40377e87de | ||
|
|
7b7a77a551 | ||
|
|
4ca3e8f70a | ||
|
|
e0cc7c64a1 | ||
|
|
e5ae4d3bd3 | ||
|
|
7186131d65 | ||
|
|
1132502e14 | ||
|
|
ea573e2421 | ||
|
|
1fe1a47658 | ||
|
|
6cb14cfc04 | ||
|
|
89505522d3 | ||
|
|
550b0fab84 | ||
|
|
35a4e587ee | ||
|
|
e92b4737e3 | ||
|
|
94c6b7409b | ||
|
|
e9dbafcc10 | ||
|
|
854d335ab1 | ||
|
|
a5cb9ae8bd | ||
|
|
f03afe0878 | ||
|
|
2fa8af3b02 | ||
|
|
41d77e8d86 | ||
|
|
b2f160eef0 | ||
|
|
67e2ef30c4 | ||
|
|
041b9c3c32 | ||
|
|
22baba2cff | ||
|
|
7273cb7f54 | ||
|
|
5a13087939 | ||
|
|
4157b64776 | ||
|
|
9e30969243 | ||
|
|
dbb5154f37 | ||
|
|
f7c7ff4aae | ||
|
|
65c4bd6db6 | ||
|
|
519cc09979 | ||
|
|
5ae39ae79a | ||
|
|
2e8232e7aa | ||
|
|
aac8349391 | ||
|
|
a854ea00a5 | ||
|
|
e97f587411 | ||
|
|
35438b6fc0 | ||
|
|
17e5f4132c | ||
|
|
08c3f4758e | ||
|
|
5039d6de6f | ||
|
|
14468e79a3 | ||
|
|
243f091b30 | ||
|
|
e05c2e5d95 | ||
|
|
5999ade43a | ||
|
|
bde05e96a6 | ||
|
|
da30a69ee7 | ||
|
|
353956a864 | ||
|
|
42251da131 | ||
|
|
3e29a28cee | ||
|
|
60fcf47f6a | ||
|
|
dfd8f9b0ce | ||
|
|
c957ce161f | ||
|
|
67884cb7cf | ||
|
|
17e35e6ac7 | ||
|
|
135560e170 | ||
|
|
468fb97c81 | ||
|
|
96e52be5f1 | ||
|
|
53f0f62f1c | ||
|
|
39ec7dc658 | ||
|
|
e77102ea47 | ||
|
|
7f476b4528 | ||
|
|
b985ad2a8e | ||
|
|
1ac6bcba23 | ||
|
|
32992d555d | ||
|
|
71088aa2bd | ||
|
|
1065679720 | ||
|
|
6b0b7912c4 | ||
|
|
35167be0d9 | ||
|
|
1846d0fa2f | ||
|
|
09d1eaa87b | ||
|
|
40343da1b0 | ||
|
|
3a4b6c2cba | ||
|
|
255c5f4407 | ||
|
|
9ef1d0f5a5 | ||
|
|
738d8c2e0f | ||
|
|
c0fb428075 | ||
|
|
632f7673d5 | ||
|
|
79005e83d7 | ||
|
|
19128134a8 | ||
|
|
80a9f37272 | ||
|
|
cbef770ed7 | ||
|
|
51b4167cdd | ||
|
|
82d2828be6 | ||
|
|
4ef1e2046b | ||
|
|
e770824568 | ||
|
|
cce79255fe | ||
|
|
f3be738b68 | ||
|
|
326acc3ecb | ||
|
|
592add9f0a | ||
|
|
4331067e57 | ||
|
|
329aae2458 | ||
|
|
33aaebac2b | ||
|
|
f7c1c2c812 | ||
|
|
1fd17a9a67 | ||
|
|
7663bbadb9 | ||
|
|
4a263c714d | ||
|
|
f5dee777dd | ||
|
|
2dd57acdef | ||
|
|
ee090a9a3c | ||
|
|
ed0b107a9f | ||
|
|
f9e4893d9d | ||
|
|
f1f1b60a62 | ||
|
|
78c6e34106 | ||
|
|
9641d5b1f4 | ||
|
|
edba79e8f0 | ||
|
|
38d4be8325 | ||
|
|
118ceda46f | ||
|
|
316477b422 | ||
|
|
564e8b74dc | ||
|
|
4ada637b17 | ||
|
|
1012bcdde5 | ||
|
|
d0c5b3eb07 | ||
|
|
cd95134267 | ||
|
|
1fb4abc322 | ||
|
|
95dfe27bf7 | ||
|
|
4920d73adb | ||
|
|
95349fe360 | ||
|
|
40d3ad2bb4 | ||
|
|
98b52a7245 | ||
|
|
8b6f7914b0 | ||
|
|
35d3190822 | ||
|
|
4e91f28ce5 | ||
|
|
e09b507b6c | ||
|
|
1fcd2b0676 | ||
|
|
482331b987 | ||
|
|
8990af458b | ||
|
|
569011fb21 | ||
|
|
4c7709efbd | ||
|
|
11a3d51774 | ||
|
|
3b27382013 | ||
|
|
be4fd1100d | ||
|
|
8af33a513b | ||
|
|
e16ec0c891 | ||
|
|
20f4d7f559 | ||
|
|
0fcf44e1a2 | ||
|
|
bab0c5a8a5 | ||
|
|
bead70b43a | ||
|
|
1c8d8a9720 | ||
|
|
d50da78f28 | ||
|
|
2653825d25 | ||
|
|
120b6c0b3c | ||
|
|
5296e3c321 | ||
|
|
8907f1d2c3 | ||
|
|
c54510660e | ||
|
|
7b764d03c2 | ||
|
|
b528411ed1 | ||
|
|
b8b01928d3 | ||
|
|
296603a861 | ||
|
|
84227a6c54 | ||
|
|
9281013d51 | ||
|
|
6848708377 | ||
|
|
c67bf5026e | ||
|
|
fbec103ae7 | ||
|
|
58c9934452 | ||
|
|
83535811ad |
21
.travis.yml
21
.travis.yml
@@ -15,6 +15,8 @@ services:
|
||||
- mysql
|
||||
|
||||
install:
|
||||
- pip install flake8==3.3.0
|
||||
- flake8 . --count --select=E901,E999,F821,F822,F823 --show-source --statistics
|
||||
- sudo rm /etc/apt/sources.list.d/docker.list
|
||||
- sudo apt-get purge -y mysql-common mysql-server mysql-client
|
||||
- nvm install v7.10.0
|
||||
@@ -49,8 +51,17 @@ before_script:
|
||||
- bench start &
|
||||
- sleep 10
|
||||
|
||||
script:
|
||||
- set -e
|
||||
- bench --verbose run-tests
|
||||
- sleep 5
|
||||
- bench --verbose run-ui-tests --app erpnext
|
||||
jobs:
|
||||
include:
|
||||
- stage: test
|
||||
script:
|
||||
- set -e
|
||||
- bench run-tests
|
||||
env: Server Side Test
|
||||
- # stage
|
||||
script:
|
||||
- bench --verbose run-setup-wizard-ui-test
|
||||
- bench execute erpnext.setup.utils.enable_all_roles_and_domains
|
||||
- bench run-ui-tests --app erpnext
|
||||
env: Client Side Test
|
||||
|
||||
|
||||
19
README.md
19
README.md
@@ -6,10 +6,9 @@
|
||||
|
||||
Includes: Accounting, Inventory, Manufacturing, CRM, Sales, Purchase, Project Management, HRMS. Requires MariaDB.
|
||||
|
||||
ERPNext is built on the [Frappe](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & JavaScript.
|
||||
ERPNext is built on the [Frappé](https://github.com/frappe/frappe) Framework, a full-stack web app framework in Python & JavaScript.
|
||||
|
||||
- [User Guide](https://frappe.github.io/erpnext/)
|
||||
- [Getting Help](http://erpnext.org/getting-help.html)
|
||||
- [User Guide](https://erpnext.org/docs/user)
|
||||
- [Discussion Forum](https://discuss.erpnext.com/)
|
||||
|
||||
---
|
||||
@@ -34,7 +33,7 @@ System and user credentials are listed on the download page.
|
||||
|
||||
GNU/General Public License (see LICENSE.txt)
|
||||
|
||||
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappe Technologies Pvt Ltd (Frappe) and Contributors.
|
||||
The ERPNext code is licensed as GNU General Public License (v3) and the Documentation is licensed as Creative Commons (CC-BY-SA-3.0) and the copyright is owned by Frappé Technologies Pvt Ltd (Frappé) and Contributors.
|
||||
|
||||
---
|
||||
|
||||
@@ -49,19 +48,19 @@ The ERPNext code is licensed as GNU General Public License (v3) and the Document
|
||||
|
||||
## Logo and Trademark
|
||||
|
||||
The brand name ERPNext and the logo are trademarks of Frappe Technologies Pvt. Ltd.
|
||||
The brand name ERPNext and the logo are trademarks of Frappé Technologies Pvt. Ltd.
|
||||
|
||||
### Introduction
|
||||
|
||||
Frappe Technologies Pvt. Ltd. (Frappe) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind:
|
||||
Frappé Technologies Pvt. Ltd. (Frappé) owns and oversees the trademarks for the ERPNext name and logos. We have developed this trademark usage policy with the following goals in mind:
|
||||
|
||||
- We’d like to make it easy for anyone to use the ERPNext name or logo for community-oriented efforts that help spread and improve ERPNext.
|
||||
- We’d like to make it clear how ERPNext-related businesses and projects can (and cannot) use the ERPNext name and logo.
|
||||
- We’d like to make it hard for anyone to use the ERPNext name and logo to unfairly profit from, trick or confuse people who are looking for official ERPNext resources.
|
||||
|
||||
### Frappe Trademark Usage Policy
|
||||
### Frappé Trademark Usage Policy
|
||||
|
||||
Permission from Frappe is required to use the ERPNext name or logo as part of any project, product, service, domain or company name.
|
||||
Permission from Frappé is required to use the ERPNext name or logo as part of any project, product, service, domain or company name.
|
||||
|
||||
We will grant permission to use the ERPNext name and logo for projects that meet the following criteria:
|
||||
|
||||
@@ -72,7 +71,7 @@ Your project neither promotes nor is associated with entities that currently fai
|
||||
|
||||
Use of the ERPNext name and logo is additionally allowed in the following situations:
|
||||
|
||||
All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappe Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.”
|
||||
All other ERPNext-related businesses or projects can use the ERPNext name and logo to refer to and explain their services, but they cannot use them as part of a product, project, service, domain, or company name and they cannot use them in any way that suggests an affiliation with or endorsement by ERPNext or Frappé Technologies or the ERPNext open source project. For example, a consulting company can describe its business as “123 Web Services, offering ERPNext consulting for small businesses,” but cannot call its business “The ERPNext Consulting Company.”
|
||||
|
||||
Similarly, it’s OK to use the ERPNext logo as part of a page that describes your products or services, but it is not OK to use it as part of your company or product logo or branding itself. Under no circumstances is it permitted to use ERPNext as part of a top-level domain name.
|
||||
|
||||
@@ -80,6 +79,6 @@ We do not allow the use of the trademark in advertising, including AdSense/AdWor
|
||||
|
||||
Please note that it is not the goal of this policy to limit commercial activity around ERPNext. We encourage ERPNext-based businesses, and we would love to see hundreds of them.
|
||||
|
||||
When in doubt about your use of the ERPNext name or logo, please contact Frappe Technologies for clarification.
|
||||
When in doubt about your use of the ERPNext name or logo, please contact Frappé Technologies for clarification.
|
||||
|
||||
(inspired by WordPress)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
## ERPNext includes these public works
|
||||
|
||||
For Frappe Framework, please see attributions.md at https://github.com/frappe/frappe/
|
||||
For Frappé Framework, please see attributions.md at https://github.com/frappe/frappe/
|
||||
|
||||
#### Images
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import inspect
|
||||
import frappe
|
||||
from erpnext.hooks import regional_overrides
|
||||
|
||||
__version__ = '8.7.2'
|
||||
__version__ = '9.2.2'
|
||||
|
||||
def get_default_company(user=None):
|
||||
'''Get default company for user'''
|
||||
@@ -28,6 +28,16 @@ def get_default_currency():
|
||||
if company:
|
||||
return frappe.db.get_value('Company', company, 'default_currency')
|
||||
|
||||
def get_default_cost_center(company):
|
||||
'''Returns the default cost center of the company'''
|
||||
if not company:
|
||||
return None
|
||||
|
||||
if not frappe.flags.company_cost_center:
|
||||
frappe.flags.company_cost_center = {}
|
||||
if not company in frappe.flags.company_cost_center:
|
||||
frappe.flags.company_cost_center[company] = frappe.db.get_value('Company', company, 'cost_center')
|
||||
return frappe.flags.company_cost_center[company]
|
||||
|
||||
def get_company_currency(company):
|
||||
'''Returns the default company currency'''
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -42,6 +43,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -70,6 +72,7 @@
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -100,6 +103,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -130,6 +134,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -161,6 +166,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -190,6 +196,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -219,6 +226,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -250,6 +258,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -278,6 +287,7 @@
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -309,6 +319,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -341,6 +352,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -372,6 +384,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -404,6 +417,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -433,6 +447,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -461,6 +476,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -489,6 +505,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -528,7 +545,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-04-21 17:22:41.150984",
|
||||
"modified": "2017-08-11 15:28:35.855809",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Account",
|
||||
@@ -641,6 +658,6 @@
|
||||
"search_fields": "",
|
||||
"show_name_in_global_search": 1,
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 0,
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -78,6 +78,7 @@ def get_chart(chart_template, existing_company=None):
|
||||
for folder in folders:
|
||||
path = os.path.join(os.path.dirname(__file__), folder)
|
||||
for fname in os.listdir(path):
|
||||
fname = frappe.as_unicode(fname)
|
||||
if fname.endswith(".json"):
|
||||
with open(os.path.join(path, fname), "r") as f:
|
||||
chart = f.read()
|
||||
@@ -105,6 +106,7 @@ def get_charts_for_country(country):
|
||||
path = os.path.join(os.path.dirname(__file__), folder)
|
||||
|
||||
for fname in os.listdir(path):
|
||||
fname = frappe.as_unicode(fname)
|
||||
if (fname.startswith(country_code) or fname.startswith(country)) and fname.endswith(".json"):
|
||||
with open(os.path.join(path, fname), "r") as f:
|
||||
_get_chart_name(f.read())
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"""
|
||||
Import chart of accounts from OpenERP sources
|
||||
"""
|
||||
from __future__ import unicode_literals
|
||||
from __future__ import print_function, unicode_literals
|
||||
|
||||
import os, json
|
||||
import ast
|
||||
@@ -84,7 +84,7 @@ def get_csv_contents(files_path):
|
||||
try:
|
||||
csv_content.setdefault(file_type, [])\
|
||||
.append(read_csv_content(csvfile.read()))
|
||||
except Exception, e:
|
||||
except Exception as e:
|
||||
continue
|
||||
return csv_content
|
||||
|
||||
@@ -229,7 +229,7 @@ def make_charts():
|
||||
|
||||
filename = src["id"][5:] + "_" + chart_id
|
||||
|
||||
print "building " + filename
|
||||
print("building " + filename)
|
||||
chart = {}
|
||||
chart["name"] = src["name"]
|
||||
chart["country_code"] = src["id"][5:]
|
||||
|
||||
@@ -0,0 +1,419 @@
|
||||
{
|
||||
"country_code": "ar",
|
||||
"name": "Argentina - Chart of Accounts",
|
||||
"tree": {
|
||||
"1.0.0.00.00 - ACTIVO": {
|
||||
"1.1.0.00.00 - ACTIVO CORRIENTE": {
|
||||
"1.1.1.00.00 - CAJA Y BANCOS": {
|
||||
"1.1.1.01.00 - CAJAS": {
|
||||
"1.1.1.01.01 - Caja": {},
|
||||
"1.1.1.01.02 - Caja chica": {},
|
||||
"1.1.1.01.03 - Caja en Moneda Extranjera": {},
|
||||
"1.1.1.01.04 - Valores a depositar": {},
|
||||
"1.1.1.01.05 - Tarjetas - Cupones": {},
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1.1.1.02.00 - BANCOS": {
|
||||
"1.1.1.02.01 - Banco de la Nacio\u0301n Argentina(ejemplo) c/c en": {},
|
||||
"1.1.1.02.03 - Banco del exterior": {},
|
||||
"account_type": "Bank"
|
||||
}
|
||||
},
|
||||
"1.1.2.00.00 - INVERSIONES TEMPORARIAS": {
|
||||
"1.1.2.01.00 - INVERSIONES EN ACCIONES": {
|
||||
"1.1.2.01.01 - Acciones": {
|
||||
"account_type": "Receivable"
|
||||
}
|
||||
},
|
||||
"1.1.2.02.00 - DEPO\u0301SITOS A PLAZO FIJO": {
|
||||
"1.1.2.02.01 - Depo\u0301sitos a Plazo Fijo en pesos": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1.1.2.02.02 - Depo\u0301sitos a Plazo Fijo en moneda": {
|
||||
"account_type": "Receivable"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1.1.3.00.00 - CRE\u0301DITOS POR VENTAS DE SERVICIOS": {
|
||||
"1.1.3.01.00 - DEUDORES EN CTA. CTE": {
|
||||
"1.1.3.01.01 - Deudores locales": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1.1.3.01.02 - Deudores del exterior": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1.1.3.01.03 - Deudores Morosos": {
|
||||
"account_type": "Chargeable"
|
||||
},
|
||||
"1.1.3.01.04 - Deudores en Gestio\u0301n Judicial": {}
|
||||
},
|
||||
"1.1.3.02.00 - Documentos a cobrar por Vas. de Servicios": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1.1.3.03.00 - Previsio\u0301n para deudores incobrables": {}
|
||||
},
|
||||
"1.1.4.00.00 - OTROS CRE\u0301DITOS CORRIENTES": {
|
||||
"1.1.4.01.00 - CRE\u0301DITOS IMPOSITIVOS CORRIENTES": {
|
||||
"1.1.4.01.01 - Anticipos Impuesto a las Ganancias": {},
|
||||
"1.1.4.01.02 - Anticipos Impuesto a los Ingresos Brutos": {},
|
||||
"1.1.4.01.03 - Percepciones y Retenciones Impto. a las Ganancias": {},
|
||||
"1.1.4.01.04 - Percepciones y Retenciones Impto. a los": {},
|
||||
"1.1.4.01.05 - IVA Cre\u0301dito Fiscal": {},
|
||||
"1.1.4.01.06 - IVA Cre\u0301dito Fiscal Exportacio\u0301n": {},
|
||||
"1.1.4.01.07 - IVA Saldo a Favor Te\u0301cnico": {},
|
||||
"1.1.4.01.08 - IVA Saldo a Favor Te\u0301cnico": {},
|
||||
"1.1.4.01.09 - IVA Saldo a Favor de Libre": {},
|
||||
"1.1.4.01.10 - Percepciones y Retenciones de IVA": {},
|
||||
"1.1.4.01.11 - Cre\u0301ditos por quebrantos impositivos no": {},
|
||||
"1.1.4.01.12 - Activos por Impuesto Diferido (Ctes.)": {}
|
||||
},
|
||||
"1.1.4.02.00 - CRE\u0301DITOS DIVERSOS CORRIENTES": {
|
||||
"1.1.4.02.01 - Cuentas Particulares Directores": {},
|
||||
"1.1.4.02.02 - Cuentas Particulares Socios/Accionistas": {},
|
||||
"1.1.4.02.03 - Anticipos a Proveedores (No cong.": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1.1.4.02.04 - Anticipos de Sueldos": {},
|
||||
"1.1.4.02.05 - Pre\u0301stamos al personal": {},
|
||||
"1.1.4.02.06 - Depo\u0301sitos pendientes de acreditacio\u0301n": {},
|
||||
"1.1.4.02.07 - Arrendamiento pagado por adelantado": {}
|
||||
}
|
||||
},
|
||||
"1.1.5.00.00 - OTROS ACTIVOS CORRIENTES": {
|
||||
"is_group": 1
|
||||
},
|
||||
"1.1.6.00.00 - INVENTARIOS": {
|
||||
"account_type": "Stock",
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"1.2.0.00.00 - ACTIVO NO CORRIENTE": {
|
||||
"1.2.1.00.00 - INVERSIONES PERMANENTES": {
|
||||
"1.2.1.01.00 - BONOS DE DEUDA": {
|
||||
"1.2.1.01.01 - Ti\u0301tulos Deuda Pu\u0301blica (Pesos)": {
|
||||
"is_group": 1
|
||||
},
|
||||
"1.2.1.01.02 - Bonex": {}
|
||||
},
|
||||
"1.2.1.02.00 - DEPO\u0301SITOS A PLAZO FIJO NO": {
|
||||
"1.2.1.02.01 - Depo\u0301sitos a plazo fijo en pesos (no cte.)": {},
|
||||
"1.2.1.02.02 - Depo\u0301sitos a plazo fijo en moneda": {}
|
||||
},
|
||||
"1.2.1.03.00 - INVERSIONES EN BIENES DEPRECIABLES": {
|
||||
"1.2.1.03.01 - Inversiones en Inmuebles Valores": {},
|
||||
"1.2.1.03.02 - Inversiones en Inmuebles": {},
|
||||
"1.2.1.03.03 - Amortizaciones Acumuladas Inversiones": {}
|
||||
}
|
||||
},
|
||||
"1.2.2.00.00 - BIENES DE USO": {
|
||||
"1.2.2.01.00 - INMUEBLES": {
|
||||
"1.2.2.01.01 - Inmuebles Valores originales": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1.2.2.01.02 - Inmuebles Actualizaciones": {},
|
||||
"1.2.2.01.03 - Amortizaciones Acumuladas Inmuebles": {
|
||||
"account_type": "Depreciation"
|
||||
}
|
||||
},
|
||||
"1.2.2.02.00 - MAQUINARIAS Y EQUIPOS": {
|
||||
"1.2.2.02.01 - Maquinarias y Equipos Valores de origen": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1.2.2.02.02 - Maquinarias y Equipos Actualizaciones": {},
|
||||
"1.2.2.02.03 - Amortizaciones Acumuladas Maquinarias": {
|
||||
"account_type": "Depreciation"
|
||||
}
|
||||
},
|
||||
"1.2.2.03.00 - MUEBLES Y U\u0301TILES": {
|
||||
"1.2.2.03.01 - Muebles y U\u0301tiles Valores de Origen": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1.2.2.03.02 - Muebles y U\u0301tiles Actualizaciones": {},
|
||||
"1.2.2.03.03 - Amortizaciones Acumuladas Muebles y": {
|
||||
"account_type": "Depreciation"
|
||||
}
|
||||
},
|
||||
"1.2.2.04.00 - RODADOS": {
|
||||
"1.2.2.04.01 - Rodados Valores Originales": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1.2.2.04.02 - Rodados Actualizaciones": {},
|
||||
"1.2.2.04.03 - Amortizaciones Acumuladas Rodados": {
|
||||
"account_type": "Depreciation"
|
||||
}
|
||||
},
|
||||
"1.2.2.07.00 - TERRENOS": {
|
||||
"1.2.2.07.01 - Terrenos Valores Originales": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1.2.2.07.02 - Terrenos Actualizaciones": {}
|
||||
},
|
||||
"1.2.2.08.00 - INSTALACIONES": {
|
||||
"1.2.2.08.01 - Instalaciones Valores Originales": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1.2.2.08.02 - Instalaciones Ajuste": {},
|
||||
"1.2.2.08.03 - Amortizaciones Acumuladas": {
|
||||
"account_type": "Depreciation"
|
||||
}
|
||||
},
|
||||
"1.2.2.09.00 - HERRAMIENTAS": {
|
||||
"1.2.2.09.01 - Herramientas Valores Originales": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1.2.2.09.02 - Herramientas Ajuste": {},
|
||||
"1.2.2.09.03 - Amortizaciones Acumuladas": {
|
||||
"account_type": "Depreciation"
|
||||
}
|
||||
}
|
||||
},
|
||||
"1.2.3.00.00 - ACTIVOS INTANGIBLES": {
|
||||
"1.2.3.01.00 - MARCAS Y PATENTES": {
|
||||
"1.2.3.01.01 - Marcas y Patentes Valores Originales": {},
|
||||
"1.2.3.01.02 - Marcas y Patentes Actualizaciones": {},
|
||||
"1.2.3.01.03 - Amortizaciones Acumuladas Marcas y": {}
|
||||
}
|
||||
},
|
||||
"1.2.4.00.00 - CRE\u0301DITOS POR VENTA DE SERVICIOS": {
|
||||
"1.2.4.01.00 - DEUDORES NO CORRIENTES": {
|
||||
"1.2.4.01.01 - Deudores Locales (No Ctes.)": {}
|
||||
},
|
||||
"1.2.4.02.00 - Documentos a cobrar por Vtas. de Servicios": {}
|
||||
},
|
||||
"1.2.5.00.00 - OTROS CRE\u0301DITOS NO CORRIENTES": {
|
||||
"1.2.5.01.00 - CRE\u0301DITOS IMPOSITIVOS NO CORRIENTES": {
|
||||
"1.2.5.01.01 - Activos por Impto. Diferido (No Ctes.)": {},
|
||||
"1.2.5.01.02 - Cre\u0301ditos por Quebrantos Impositivos no": {}
|
||||
},
|
||||
"1.2.5.02.00 - CRE\u0301DITOS DIVERSOS NO CORRIENTES": {
|
||||
"1.2.5.02.01 - Cuentas Particulares Directores (No": {},
|
||||
"1.2.5.02.02 - Cuentas Particulares Socios/Accionistas": {}
|
||||
}
|
||||
},
|
||||
"1.2.6.00.00 - OTROS ACTIVOS NO CORRIENTES": {
|
||||
"1.2.6.01.00 - Llave de Negocio": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"2.0.0.00.00 - PASIVO": {
|
||||
"2.1.0.00.00 - PASIVO CORRIENTE": {
|
||||
"2.1.1.00.00 - DEUDAS COMERCIALES CORRIENTES": {
|
||||
"2.1.1.02.00 - ACREEDORES": {
|
||||
"2.1.1.02.01 - Acreedores Locales (Ctes.)": {
|
||||
"account_type": "Payable"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2.1.2.00.00 - REMUNERACIONES Y CAGAS SOCIALES": {
|
||||
"2.1.2.02.00 - DEUDAS PREVISIONALES": {
|
||||
"2.1.2.02.01 - Jubilaciones a pagar": {},
|
||||
"2.1.2.02.02 - ART a pagar": {},
|
||||
"2.1.2.02.03 - Obra Social a pagar": {},
|
||||
"2.1.2.02.04 - SAC a pagar": {},
|
||||
"2.1.2.02.05 - Vacaciones a pagar": {}
|
||||
},
|
||||
"2.1.2.03.00 - Sueldos y Jornales a pagar": {
|
||||
"account_type": "Chargeable"
|
||||
}
|
||||
},
|
||||
"2.1.3.00.00 - CARGAS FISCALES": {
|
||||
"2.1.3.01.00 - IMPUESTO AL VALOR AGREGADO": {
|
||||
"2.1.3.01.01 - IVA De\u0301bito Fiscal": {},
|
||||
"2.1.3.01.02 - IVA De\u0301bito Fiscal Sobretasa": {},
|
||||
"2.1.3.01.03 - Percepciones y Retenciones efectuadas": {},
|
||||
"2.1.3.01.04 - IVA a Pagar": {}
|
||||
},
|
||||
"2.1.3.02.00 - INGRESOS BRUTOS": {
|
||||
"2.1.3.02.01 - Impuesto a los Ingresos Brutos a Pagar": {},
|
||||
"2.1.3.02.02 - Percepciones efectuadas Ingresos": {}
|
||||
},
|
||||
"2.1.3.03.00 - IMPUESTO A LAS GANANCIAS": {
|
||||
"2.1.3.03.01 - Impuesto Ganancia Mi\u0301nima Presunta a": {},
|
||||
"2.1.3.03.02 - Impuesto a las Ganancias a Pagar": {},
|
||||
"2.1.3.03.03 - Pasivo por Impuesto Diferido": {},
|
||||
"2.1.3.03.04 - Percepciones y Retenciones efectuadas": {}
|
||||
}
|
||||
},
|
||||
"2.1.4.00.00 - DEUDAS FINANCIERAS": {
|
||||
"2.1.4.01.00 - Pre\u0301stamo Banco de la Nacio\u0301n Argentina (Cte.)": {},
|
||||
"2.1.4.02.00 - Pre\u0301stamo Banco de la Provincia de Bs. As.": {}
|
||||
},
|
||||
"2.1.5.00.00 - OTRAS DEUDAS CORRIENTES": {
|
||||
"2.1.5.01.00 - Dividendos a pagar (Ctes.)": {},
|
||||
"2.1.5.02.00 - Honorarios Directores a Pagar (Ctes.)": {}
|
||||
},
|
||||
"2.1.6.00.00 - PROVISIONES": {
|
||||
"2.1.6.01.00 - Provisio\u0301n para despidos": {},
|
||||
"2.1.6.02.00 - Provisio\u0301n para SAC": {}
|
||||
},
|
||||
"2.1.7.00.00 - INVENTARIOS POR PAGAR": {
|
||||
"2.1.7.01.00 - Inventario entrante no facturado": {
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
}
|
||||
}
|
||||
},
|
||||
"2.2.0.00.00 - PASIVO NO CORRIENTE": {
|
||||
"2.2.1.00.00 - DEUDAS FINANCIERAS NO CORRIENTES": {
|
||||
"2.2.1.01.00 - Pre\u0301stamo Banco de la Nacio\u0301n Argentina(ejemplo) (No": {}
|
||||
},
|
||||
"2.2.2.00.00 - CARGAS FISCALES NO CORRIENTES": {
|
||||
"2.2.2.01.00 - Moratoria": {}
|
||||
},
|
||||
"2.2.3.00.00 - DEUDAS COMERCIALES": {
|
||||
"2.2.3.01.00 - ACREEDORES": {
|
||||
"2.2.3.01.01 - Acreedores Locales (No Ctes.)": {}
|
||||
}
|
||||
},
|
||||
"2.2.4.00.00 - OTRAS DEUDAS NO CORRIENTES": {
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"root_type": "Liability"
|
||||
},
|
||||
"3.0.0.00.00 - PATRIMONIO NETO": {
|
||||
"3.1.0.00.00 - APORTE DE LOS PROPIETARIOS": {
|
||||
"3.1.1.00.00 - CAPITAL SOCIAL": {
|
||||
"3.1.1.01.00 - Acciones en Circulacio\u0301n": {},
|
||||
"3.1.1.02.00 - Aportes Irrevocables": {},
|
||||
"3.1.1.03.00 - Acciones a distribuir": {},
|
||||
"3.1.1.04.00 - Capital": {},
|
||||
"3.1.1.05.00 - Ajuste del Capital": {}
|
||||
}
|
||||
},
|
||||
"3.3.0.00.00 - RESERVAS": {
|
||||
"3.3.1.00.00 - Reserva Legal": {},
|
||||
"3.3.2.00.00 - Reserva Facultativa": {},
|
||||
"3.3.3.00.00 - Reserva Estatutaria": {},
|
||||
"3.3.4.00.00 - Ajuste Reserva Legal": {}
|
||||
},
|
||||
"3.4.0.00.00 - RESULTADOS ACUMULADOS": {
|
||||
"3.4.1.00.00 - Resultado del Ejercicio": {},
|
||||
"3.4.2.00.00 - Resultado Ejercicios Anteriores": {},
|
||||
"3.4.3.00.00 - A.R.E.A (P)": {},
|
||||
"3.4.4.00.00 - A.R.E.A (G)": {}
|
||||
},
|
||||
"root_type": "Equity"
|
||||
},
|
||||
"4.1.0.00.00 - INGRESOS": {
|
||||
"4.1.0.00.00 - INGRESOS ORDINARIOS": {
|
||||
"4.1.1.00.00 - INGRESOS POR SERVICIOS PRESTADOS": {
|
||||
"4.1.1.01.00 - Ventas de Servicios": {},
|
||||
"4.1.1.02.00 - Ingresos de fuente extranjera": {}
|
||||
},
|
||||
"4.1.3.00.00 - RESULTADOS FINANCIEROS Y POR": {
|
||||
"4.1.3.01.00 - Intereses Ganados": {},
|
||||
"4.1.3.02.00 - Resultado por Tenencia de acciones": {},
|
||||
"4.1.3.03.00 - Diferencia tipo de cambio": {},
|
||||
"4.1.3.04.00 - Resultado por tenencia (positivo)": {}
|
||||
},
|
||||
"4.1.4.00.00 - OTROS INGRESOS ORDINARIOS": {
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"4.2.0.00.00 - INGRESOS EXTRAORDINARIOS": {
|
||||
"4.2.1.00.00 - Utilidad Venta Bienes de Uso": {},
|
||||
"4.2.2.00.00 - Reintegro de Seguros": {},
|
||||
"4.2.3.00.00 - Otros ingresos extraordinarios": {}
|
||||
},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"5.0.0.00.00 - EGRESOS": {
|
||||
"5.1.0.00.00 - EGRESOS ORDINARIOS": {
|
||||
"5.1.2.00.00 - GASTOS DE EXPLOTACIO\u0301N": {
|
||||
"5.1.2.01.00 - Sueldos y Jornales - Explotacio\u0301n": {},
|
||||
"5.1.2.02.00 - Cargas Sociales - Explotacio\u0301n": {},
|
||||
"5.1.2.03.00 - Energi\u0301a - Explotacio\u0301n": {},
|
||||
"5.1.2.04.00 - Honorarios Profesionales - Explotacio\u0301n": {},
|
||||
"5.1.2.05.00 - Ropa de trabajo - Explotacio\u0301n": {},
|
||||
"5.1.2.06.00 - Seguros - Explotacio\u0301n": {},
|
||||
"5.1.2.07.00 - Despidos - Explotacio\u0301n": {},
|
||||
"5.1.2.08.00 - Comida del personal - Explotacio\u0301n": {},
|
||||
"5.1.2.09.00 - Cuota me\u0301dica a cargo del empleador": {},
|
||||
"5.1.2.10.00 - Amortizaciones - Explotacio\u0301n": {},
|
||||
"5.1.2.11.00 - Repuestos y Reparaciones - Explotacio\u0301n": {},
|
||||
"5.1.2.12.00 - Gastos de limpieza - Explotacio\u0301n": {},
|
||||
"5.1.2.13.00 - Mantenimiento - Explotacio\u0301n": {},
|
||||
"5.1.2.14.00 - Combustibles y Lubricantes - Explotacio\u0301n": {},
|
||||
"5.1.2.15.00 - Insumos diversos - Explotacio\u0301n": {},
|
||||
"5.1.2.16.00 - Fletes - Explotacio\u0301n": {}
|
||||
},
|
||||
"5.1.3.00.00 - GASTOS DE ADMINISTRACIO\u0301N": {
|
||||
"5.1.3.01.00 - Sueldos - Administracio\u0301n": {},
|
||||
"5.1.3.02.00 - Cargas Sociales - Administracio\u0301n": {},
|
||||
"5.1.3.03.00 - Honorarios - Administracio\u0301n": {},
|
||||
"5.1.3.04.00 - Amortizaciones - Administracio\u0301n": {},
|
||||
"5.1.3.05.00 - Via\u0301ticos - Administracio\u0301n": {},
|
||||
"5.1.3.06.00 - Libreri\u0301a y Papeleri\u0301a - Administracio\u0301n": {},
|
||||
"5.1.3.07.00 - Certificaciones y Sellados": {},
|
||||
"5.1.3.08.00 - Gastos Bancarios - Administracio\u0301n": {},
|
||||
"5.1.3.09.00 - Gastos Varios - Administracio\u0301n": {},
|
||||
"5.1.3.10.00 - Insumos Computacio\u0301n - Administracio\u0301n": {},
|
||||
"5.1.3.11.00 - Correspondencia - Administracio\u0301n": {},
|
||||
"5.1.3.12.00 - Mantenimiento - Administracio\u0301n": {},
|
||||
"5.1.3.13.00 - Energi\u0301a - Administracio\u0301n": {},
|
||||
"5.1.3.14.00 - Seguros - Administracio\u0301n": {},
|
||||
"5.1.3.15.00 - Costo sobre ventas": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"5.1.3.16.00 - Gastos de Valoracion": {
|
||||
"account_type": "Expenses Included In Valuation"
|
||||
}
|
||||
},
|
||||
"5.1.4.00.00 - GASTOS DE COMERCIALIZACIO\u0301N": {
|
||||
"5.1.4.01.00 - Sueldos - Comercializacio\u0301n": {},
|
||||
"5.1.4.02.00 - Cargas Sociales - Comercializacio\u0301n": {},
|
||||
"5.1.4.03.00 - Publicidad - Comercializacio\u0301n": {},
|
||||
"5.1.4.04.00 - Amortizaciones - Comercializacio\u0301n": {},
|
||||
"5.1.4.05.00 - Seguros - Comercializacio\u0301n": {},
|
||||
"5.1.4.06.00 - Honorarios - Comercializacio\u0301n": {},
|
||||
"5.1.4.07.00 - Gastos Varios - Comercializacio\u0301n": {},
|
||||
"5.1.4.08.00 - Fletes - Comercializacio\u0301n": {},
|
||||
"5.1.4.09.00 - IVA no computable - Comercializacio\u0301n": {},
|
||||
"5.1.4.10.00 - Descuentos otorgados a clientes": {},
|
||||
"5.1.4.11.00 - Comisiones de terceros": {},
|
||||
"5.1.4.12.00 - Quebrantos por deudores": {},
|
||||
"5.1.4.13.00 - Via\u0301ticos - Comercializacio\u0301n": {}
|
||||
},
|
||||
"5.1.5.00.00 - GASTOS FINANCIEROS": {
|
||||
"5.1.5.01.00 - Intereses y Gastos bancarios": {},
|
||||
"5.1.5.02.00 - Intereses a Proveedores": {},
|
||||
"5.1.5.03.00 - Intereses y recargos impositivos": {},
|
||||
"5.1.5.04.00 - Diferencia de Cambio": {},
|
||||
"5.1.5.05.00 - Diferencia de Cambio Balance en": {},
|
||||
"5.1.5.06.00 - Resultado por tenencia (negativo)": {},
|
||||
"5.1.5.08.00 - Amortizaciones Inversiones en bienes": {},
|
||||
"5.1.5.09.00 - R.E.C.P.A.M": {},
|
||||
"5.1.5.10.00 - Resultado por tenencia negativo de": {}
|
||||
},
|
||||
"5.1.7.00.00 - IMPUESTOS": {
|
||||
"5.1.7.01.00 - Impuesto a las Ganancias": {},
|
||||
"5.1.7.02.00 - Impuesto a las Ganancia Mi\u0301nima": {},
|
||||
"5.1.7.03.00 - Impuesto a los Ingresos Brutos": {},
|
||||
"5.1.7.04.00 - Tasa municipal": {},
|
||||
"5.1.7.05.00 - Impuestos Territoriales": {},
|
||||
"5.1.7.06.00 - Impuesto s/ los De\u0301bitos y Cre\u0301ditos": {},
|
||||
"5.1.7.07.00 - Impuestos internos y varios": {}
|
||||
},
|
||||
"5.1.8.00.00 - GASTOS SOBRE EXISTENCIAS": {
|
||||
"5.1.8.01.00 - Costo sobre ventas": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"5.1.8.02.00 - Gastos de Valoracion": {
|
||||
"account_type": "Expenses Included In Valuation"
|
||||
},
|
||||
"5.1.8.03.00 - Ajuste de Existencia": {
|
||||
"account_type": "Stock Adjustment"
|
||||
}
|
||||
}
|
||||
},
|
||||
"5.2.0.00.00 - EGRESOS EXTRAORDINARIOS": {
|
||||
"5.2.1.00.00 - Pe\u0301rdida por venta bienes de uso": {},
|
||||
"5.2.2.00.00 - Amortizaciones extraordinarias": {},
|
||||
"5.2.3.00.00 - Ajuste del valor de los bienes": {},
|
||||
"5.2.4.00.00 - Ajuste de Amortizaciones acumuladas de": {}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -49,6 +49,10 @@
|
||||
"is_group": 1
|
||||
},
|
||||
"ESTOQUES": {
|
||||
"All Warehouses": {
|
||||
"account_type": "Stock",
|
||||
"is_group": 1
|
||||
},
|
||||
"Constru\u00e7\u00f5es em Andamento de Im\u00f3veis Destinados \u00e0 Venda": {},
|
||||
"Estoques Destinados \u00e0 Doa\u00e7\u00e3o": {},
|
||||
"Im\u00f3veis Destinados \u00e0 Venda": {},
|
||||
|
||||
@@ -1,100 +0,0 @@
|
||||
{
|
||||
"country_code": "fr",
|
||||
"name": "France - Chart of Accounts",
|
||||
"tree": {
|
||||
"Frais": {
|
||||
"601 achats stock\u00e9s, mat premi\u00e8res": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"6031 variation des stock\u00e9s mat premi\u00e8res": {
|
||||
"account_type": "Stock Adjustment"
|
||||
},
|
||||
"6081 frais accessoires d'achats mat premi\u00e8res": {
|
||||
"account_type": "Expenses Included In Valuation"
|
||||
},
|
||||
"Dotations aux amortissements, d\u00e9pr\u00e9ciations": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"le revenu": {
|
||||
"701 ventes de produits finis": {},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"les atouts": {
|
||||
"Amortissements des immobilisations corporelles ": {
|
||||
"Autres immobilisations corporelles (m\u00eame ventilation que celle du compte 218)": {
|
||||
"account_type": "Accumulated Depreciation"
|
||||
},
|
||||
"Constructions (m\u00eame ventilation que celle du compte 213) ": {
|
||||
"account_type": "Accumulated Depreciation"
|
||||
},
|
||||
"Installations mat\u00e9riel et outillage industriels (m\u00eame ventilation que celle du compte 215)": {
|
||||
"account_type": "Accumulated Depreciation"
|
||||
},
|
||||
"account_type": "Accumulated Depreciation"
|
||||
},
|
||||
"Banques": {
|
||||
"51201 Soci\u00e9t\u00e9 g\u00e9n\u00e9rale": {
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"Caisse": {
|
||||
"5301 Caisse si\u00e8ge social": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"Clients et comptes rattach\u00e9s": {
|
||||
"41119 Autres Clients": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"Immobilisations corporelles en cours": {
|
||||
"Autres immobilisations corporelles": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Constructions": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Installations techniques mat\u00e9riel et outillage industriels ": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"Stock": {
|
||||
"Stock in Hand": {
|
||||
"account_type": "Stock"
|
||||
}
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"passifs": {
|
||||
"Fournisseurs - Factures non parvenues ": {
|
||||
"4081 Fournisseurs - Factures non parvenues ": {
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
},
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
},
|
||||
"Fournisseurs et comptes rattach\u00e9s": {
|
||||
"4011 Fournisseurs - Achats de biens et prestations de services": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"root_type": "Liability",
|
||||
"\u00c9tat - Taxes sur le chiffre d'affaires": {
|
||||
"TVA collect\u00e9e (Taux Normal)": {
|
||||
"account_type": "Tax"
|
||||
},
|
||||
"account_type": "Tax"
|
||||
}
|
||||
},
|
||||
"\u00c9quit\u00e9": {
|
||||
"is_group": 1,
|
||||
"root_type": "Equity"
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,856 @@
|
||||
{
|
||||
"country_code": "hu",
|
||||
"name": "Hungary - Chart of Accounts",
|
||||
"tree": {
|
||||
"1. SZ\u00c1MLAOSZT\u00c1LY BEFEKTETETT ESZK\u00d6Z\u00d6K": {
|
||||
"11. IMMATERI\u00c1LIS JAVAK": {
|
||||
"111. Alap\u00edt\u00e1s-\u00e1tszervez\u00e9s aktiv\u00e1lt \u00e9rt\u00e9ke": {},
|
||||
"112. K\u00eds\u00e9rleti fejleszt\u00e9s aktiv\u00e1lt \u00e9rt\u00e9ke": {},
|
||||
"113. Vagyoni \u00e9rt\u00e9k\u0171 jogok": {},
|
||||
"114. Szellemi term\u00e9kek": {},
|
||||
"115. \u00dczleti vagy c\u00e9g\u00e9rt\u00e9k": {},
|
||||
"117. Immateri\u00e1lis javak \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {}
|
||||
},
|
||||
"12-16. T\u00c1RGYI ESZK\u00d6Z\u00d6K": {
|
||||
"12. INGATLANOK \u00c9S KAPCSOL\u00d3D\u00d3 VAGYONI \u00c9RT\u00c9K\u00db JOGOK": {
|
||||
"121. Telkek, f\u00f6ldter\u00fclet ": {
|
||||
"1211. Telkek, f\u00f6ldter\u00fcletek brutt\u00f3 \u00e9rt\u00e9ke": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1218. Telkek, f\u00f6ldter\u00fcletek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
|
||||
"1219. Telkek, f\u00f6ldter\u00fcletek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
|
||||
},
|
||||
"122. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok": {
|
||||
"1221. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok brutt\u00f3 \u00e9rt\u00e9ke": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1228. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
|
||||
"1229. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
|
||||
},
|
||||
"123. \u00c9p\u00fcletek, \u00e9p\u00fcletr\u00e9szek, tulajdoni h\u00e1nyadok ": {
|
||||
"account_type": "Fixed Asset",
|
||||
"is_group": 1
|
||||
},
|
||||
"124. Egy\u00e9b ingatlanok": {
|
||||
"is_group": 1
|
||||
},
|
||||
"125. \u00dczemk\u00f6r\u00f6n k\u00edv\u00fcli ingatlanok, \u00e9p\u00fcletek ": {
|
||||
"is_group": 1
|
||||
},
|
||||
"126. Ingatlanokhoz kapcsol\u00f3d\u00f3 vagyoni \u00e9rt\u00e9k\u0171 jogok": {
|
||||
"is_group": 1
|
||||
},
|
||||
"127. Ingatlanok \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {},
|
||||
"129. Kis \u00e9rt\u00e9k\u0171 ingatlanok": {}
|
||||
},
|
||||
"13. M\u00dbSZAKI BERENDEZ\u00c9SEK, G\u00c9PEK, J\u00c1RM\u00dbVEK": {
|
||||
"131. Termel\u0151 g\u00e9pek, berendez\u00e9sek, szersz\u00e1mok, gy\u00e1rt\u00f3eszk\u00f6z\u00f6k": {
|
||||
"1311. Termel\u0151 g\u00e9pek, berendez\u00e9sek brutt\u00f3 \u00e9rt\u00e9ke": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1318. Termel\u0151 g\u00e9pek, berendez\u00e9sek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
|
||||
"1319. Termel\u0151 g\u00e9pek, berendez\u00e9sek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
|
||||
},
|
||||
"132. M\u0171szaki j\u00e1rm\u0171vek": {},
|
||||
"133. Ki nem emelt m\u0171szaki berendez\u00e9sek, g\u00e9pek, j\u00e1rm\u0171vek": {},
|
||||
"139. Kis \u00e9rt\u00e9k\u0171 m\u0171szaki berendez\u00e9sek, g\u00e9pek, j\u00e1rm\u0171vek": {}
|
||||
},
|
||||
"14. EGY\u00c9B BERENDEZ\u00c9SEK, FELSZEREL\u00c9SEK, J\u00c1RM\u00dbVEK": {
|
||||
"141. Egy\u00e9b (\u00fczemi \u2013 \u00fczleti), berendez\u00e9sek, felszerel\u00e9sek": {
|
||||
"1411. Egy\u00e9b (\u00fczemi \u2013 \u00fczleti), berendez\u00e9sek, felszerel\u00e9sek brutt\u00f3 \u00e9rt\u00e9ke": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1418. Egy\u00e9b (\u00fczemi \u2013 \u00fczleti), berendez\u00e9sek, felszerel\u00e9sek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
|
||||
"1419. Egy\u00e9b (\u00fczemi \u2013 \u00fczleti), berendez\u00e9sek, felszerel\u00e9sek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
|
||||
},
|
||||
"142. Egy\u00e9b j\u00e1rm\u0171vek": {
|
||||
"1421. Egy\u00e9b j\u00e1rm\u0171vek brutt\u00f3 \u00e9rt\u00e9ke": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1428. Egy\u00e9b j\u00e1rm\u0171vek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
|
||||
"1429. Egy\u00e9b j\u00e1rm\u0171vek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
|
||||
},
|
||||
"143. Irodai, igazgat\u00e1si berendez\u00e9sek \u00e9s felszerel\u00e9sek": {
|
||||
"1431. Irodai, igazgat\u00e1si berendez\u00e9sek \u00e9s felszerel\u00e9sek brutt\u00f3 \u00e9rt\u00e9ke": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"1438. Irodai, igazgat\u00e1si berendez\u00e9sek \u00e9s felszerel\u00e9sek terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
|
||||
"1439. Irodai, igazgat\u00e1si berendez\u00e9sek \u00e9s felszerel\u00e9sek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
|
||||
},
|
||||
"144. Ki nem emelt egy\u00e9b berendez\u00e9sek, felszerel\u00e9sek": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"145. J\u00f3l\u00e9ti berendez\u00e9sek, felszerel\u00e9si t\u00e1rgyak \u00e9s k\u00e9pz\u0151m\u0171v\u00e9szeti alkot\u00e1sok": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"147. Egy\u00e9b berendez\u00e9sek, felszerel\u00e9sek, j\u00e1rm\u0171vek \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"149. Kis \u00e9rt\u00e9k\u0171 egy\u00e9b berendez\u00e9sek, felszerel\u00e9sek, j\u00e1rm\u0171vek": {
|
||||
"account_type": "Fixed Asset"
|
||||
}
|
||||
},
|
||||
"15. TENY\u00c9SZ\u00c1LLATOK": {
|
||||
"151. Teny\u00e9sz\u00e1llatok": {}
|
||||
},
|
||||
"16. BERUH\u00c1Z\u00c1SOK, FEL\u00daJ\u00cdT\u00c1SOK": {
|
||||
"161. Befejezetlen beruh\u00e1z\u00e1sok ": {},
|
||||
"162. Fel\u00faj\u00edt\u00e1sok": {},
|
||||
"168. Beruh\u00e1z\u00e1sok terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {}
|
||||
},
|
||||
"17-19. BEFEKTETETT P\u00c9NZ\u00dcGYI ESZK\u00d6Z\u00d6K": {
|
||||
"17. TULAJDONI R\u00c9SZESED\u00c9ST JELENT\u00d5 BEFEKTET\u00c9SEK (R\u00c9SZESED\u00c9SEK)": {
|
||||
"171. Tart\u00f3s r\u00e9szesed\u00e9s kapcsolt v\u00e1llalkoz\u00e1sban": {},
|
||||
"172. Egy\u00e9b tart\u00f3s r\u00e9szesed\u00e9s": {},
|
||||
"177. R\u00e9szesed\u00e9sek \u00e9rt\u00e9khelyesb\u00edt\u00e9se": {},
|
||||
"179. R\u00e9szesed\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"18. HITELVISZONYT MEGTESTES\u00cdT\u00d5 \u00c9RT\u00c9KPAP\u00cdROK": {
|
||||
"181. \u00c1llamk\u00f6tv\u00e9nyek": {},
|
||||
"182. Kapcsolt v\u00e1llalkoz\u00e1sok \u00e9rt\u00e9kpap\u00edrjai": {},
|
||||
"183. Egy\u00e9b v\u00e1llalkoz\u00e1sok \u00e9rt\u00e9kpap\u00edrjai": {},
|
||||
"184. Tart\u00f3s diszkont \u00e9rt\u00e9kpap\u00edrok": {},
|
||||
"189. \u00c9rt\u00e9kpap\u00edrok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"19. TART\u00d3SAN ADOTT K\u00d6LCS\u00d6N\u00d6K (tart\u00f3s bankbet\u00e9tek)": {
|
||||
"191. Tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6k kapcsolt v\u00e1llalkoz\u00e1sban": {},
|
||||
"192. Tart\u00f3s bankbet\u00e9tek": {},
|
||||
"193. Egy\u00e9b tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6k": {},
|
||||
"194. Tart\u00f3s bankbet\u00e9tek kapcsolt v\u00e1llalkoz\u00e1sban": {},
|
||||
"195. Tart\u00f3s bankbet\u00e9tek egy\u00e9b r\u00e9szesed\u00e9si viszonyban \u00e1ll\u00f3 v\u00e1llalkoz\u00e1sban": {},
|
||||
"196. Egy\u00e9b tart\u00f3s bankbet\u00e9tek": {},
|
||||
"197. P\u00e9nz\u00fcgyi l\u00edzing miatti tart\u00f3s k\u00f6vetel\u00e9s": {},
|
||||
"199. Tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6k (\u00e9s bankbet\u00e9tek) \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
}
|
||||
}
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"2. SZ\u00c1MLAOSZT\u00c1LY K\u00c9SZLETEK": {
|
||||
"21-22. ANYAGOK": {
|
||||
"211 - 219. Nyers- \u00e9s alapanyagok ": {},
|
||||
"221. Seg\u00e9danyagok": {},
|
||||
"222. \u00dczem- \u00e9s f\u0171t\u0151anyagok ": {},
|
||||
"223. Fenntart\u00e1si anyagok ": {},
|
||||
"224. \u00c9p\u00edt\u00e9si anyagok": {},
|
||||
"225. Egy \u00e9ven bel\u00fcl elhaszn\u00e1l\u00f3d\u00f3 anyagi eszk\u00f6z\u00f6k ": {},
|
||||
"226. T\u00e1rgyi eszk\u00f6z\u00f6k k\u00f6z\u00fcl \u00e1tsorolt anyagok": {},
|
||||
"227. Egy\u00e9b anyagok": {},
|
||||
"228. Anyagok \u00e1rk\u00fcl\u00f6nb\u00f6zete": {},
|
||||
"229. Anyagok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"23. BEFEJEZETLEN TERMEL\u00c9S \u00c9S F\u00c9LK\u00c9SZ TERM\u00c9KEK": {
|
||||
"231 - 234. Befejezetlen termel\u00e9s ": {
|
||||
"231. Befejezetlen termel\u00e9s": {},
|
||||
"232. F\u00e9lk\u00e9sz term\u00e9kek": {}
|
||||
},
|
||||
"238. F\u00e9lk\u00e9sz term\u00e9kek k\u00e9szlet\u00e9rt\u00e9k-k\u00fcl\u00f6nb\u00f6zete": {},
|
||||
"239. Befejezetlen termel\u00e9s \u00e9s f\u00e9lk\u00e9sz term\u00e9kek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"24. N\u00d6VEND\u00c9K-, H\u00cdZ\u00d3- \u00c9S EGY\u00c9B \u00c1LLATOK": {
|
||||
"is_group": 1
|
||||
},
|
||||
"25. K\u00c9SZTERM\u00c9KEK": {
|
||||
"251-257. K\u00e9szterm\u00e9kek": {},
|
||||
"258. K\u00e9szterm\u00e9kek k\u00e9szlet\u00e9rt\u00e9k-k\u00fcl\u00f6nb\u00f6zete": {},
|
||||
"259. K\u00e9szterm\u00e9kek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"26-28. \u00c1RUK ": {
|
||||
"261. Kereskedelmi \u00e1ruk": {
|
||||
"account_type": "Stock",
|
||||
"is_group": 0
|
||||
},
|
||||
"262. Idegen helyen t\u00e1rolt, bizom\u00e1nyba \u00e1tadott \u00e1ruk": {
|
||||
"account_type": "Stock",
|
||||
"is_group": 0
|
||||
},
|
||||
"263. T\u00e1rgyi eszk\u00f6z\u00f6k k\u00f6z\u00fcl \u00e1tsorolt \u00e1ruk": {
|
||||
"account_type": "Stock",
|
||||
"is_group": 0
|
||||
},
|
||||
"264. Bels\u0151 (egys\u00e9gek, tev\u00e9kenys\u00e9gek k\u00f6z\u00f6tti) \u00e1tad\u00e1s-\u00e1tv\u00e9tel \u00fctk\u00f6z\u0151sz\u00e1mla": {
|
||||
"account_type": "Stock",
|
||||
"is_group": 0
|
||||
},
|
||||
"269. Kereskedelmi \u00e1ruk \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {
|
||||
"account_type": "Stock",
|
||||
"is_group": 0
|
||||
},
|
||||
"account_type": "Stock"
|
||||
},
|
||||
"27. K\u00d6ZVET\u00cdTETT SZOLG\u00c1LTAT\u00c1SOK ": {
|
||||
"271. K\u00f6zvet\u00edtett szolg\u00e1ltat\u00e1sok": {},
|
||||
"279. K\u00f6zvet\u00edtett szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"28. BET\u00c9TD\u00cdJAS G\u00d6NGY\u00d6LEGEK": {
|
||||
"is_group": 1
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"3. SZ\u00c1MLAOSZT\u00c1LY K\u00d6VETEL\u00c9SEK, P\u00c9NZ\u00dcGYI ESZK\u00d6Z\u00d6K \u00c9S AKT\u00cdV ID\u00d5BELI ELHAT\u00c1ROL\u00c1SOK": {
|
||||
"31. K\u00d6VETEL\u00c9SEK \u00c1RUSZ\u00c1LL\u00cdT\u00c1SB\u00d3L \u00c9S SZOLG\u00c1LTAT\u00c1SB\u00d3L (VEV\u00d5K) ": {
|
||||
"311. Belf\u00f6ldi k\u00f6vetel\u00e9sek (forintban)": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"312. Belf\u00f6ldi k\u00f6vetel\u00e9sek (deviz\u00e1ban)": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"315. Belf\u00f6ldi k\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa ": {},
|
||||
"316. K\u00fclf\u00f6ldi k\u00f6vetel\u00e9sek (forintban)": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"317. K\u00fclf\u00f6ldi k\u00f6vetel\u00e9sek (deviz\u00e1ban)": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"319. K\u00fclf\u00f6ldi k\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"32. K\u00d6VETEL\u00c9SEK KAPCSOLT V\u00c1LLALKOZ\u00c1SSAL SZEMBEN": {
|
||||
"is_group": 1
|
||||
},
|
||||
"33. K\u00d6VETEL\u00c9SEK EGY\u00c9B R\u00c9SZESED\u00c9SI VISZONYBAN L\u00c9V\u00d5 V\u00c1LLALKOZ\u00c1SSAL SZEMBEN ": {
|
||||
"is_group": 1
|
||||
},
|
||||
"34. V\u00c1LT\u00d3K\u00d6VETEL\u00c9SEK": {
|
||||
"is_group": 1
|
||||
},
|
||||
"35. ADOTT EL\u00d5LEGEK": {
|
||||
"351. Immateri\u00e1lis javakra adott el\u0151legek": {},
|
||||
"352. Beruh\u00e1z\u00e1sokra adott el\u0151legek": {},
|
||||
"353. K\u00e9szletekre adott el\u0151legek": {},
|
||||
"358. Jegyzett, de m\u00e9g be nem fizetett t\u0151ke r\u00e9szesed\u00e9si viszonyban nem l\u00e9v\u0151 v\u00e1llalkoz\u00e1st\u00f3l": {},
|
||||
"359. Adott el\u0151legek \u00e9rt\u00e9kveszt\u00e9se \u00e9s vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"36. EGY\u00c9B K\u00d6VETEL\u00c9SEK": {
|
||||
"361. Munkav\u00e1llal\u00f3kkal szembeni k\u00f6vetel\u00e9sek": {
|
||||
"3611. Munkav\u00e1llal\u00f3knak foly\u00f3s\u00edtott el\u0151legek": {},
|
||||
"3612. El\u0151\u00edrt tartoz\u00e1sok": {},
|
||||
"3613. Egy\u00e9b elsz\u00e1mol\u00e1sok a munkav\u00e1llal\u00f3kkal": {}
|
||||
},
|
||||
"362. K\u00f6lts\u00e9gvet\u00e9ssel szembeni k\u00f6vetel\u00e9sek": {
|
||||
"is_group": 1
|
||||
},
|
||||
"363. R\u00f6vid lej\u00e1ratra k\u00f6lcs\u00f6nadott p\u00e9nzeszk\u00f6z\u00f6k": {
|
||||
"is_group": 1
|
||||
},
|
||||
"364. R\u00e9szesed\u00e9sekkel, \u00e9rt\u00e9kpap\u00edrokkal kapcsolatos k\u00f6vetel\u00e9sek": {
|
||||
"3641. R\u00f6vid lej\u00e1rat\u00fa k\u00f6lcs\u00f6n\u00f6k": {},
|
||||
"3642. Tart\u00f3san adott k\u00f6lcs\u00f6n\u00f6kb\u0151l \u00e1tsorolt k\u00f6vetel\u00e9sek": {}
|
||||
},
|
||||
"365. V\u00e1s\u00e1rolt \u00e9s kapott k\u00f6vetel\u00e9sek ": {
|
||||
"is_group": 1
|
||||
},
|
||||
"366. R\u00e9szesed\u00e9sekkel, \u00e9rt\u00e9kpap\u00edrokkal kapcsolatos k\u00f6vetel\u00e9sek": {},
|
||||
"367. Hat\u00e1rid\u0151s, opci\u00f3s \u00e9s swap \u00fcgyletekkel kapcsolatos k\u00f6vetel\u00e9sek": {},
|
||||
"368. K\u00fcl\u00f6nf\u00e9le egy\u00e9b k\u00f6vetel\u00e9sek ": {
|
||||
"3681. Bizom\u00e1nyosi \u00fcgylettel kapcsolatos elsz\u00e1mol\u00e1sok": {},
|
||||
"3682. \u00c9rt\u00e9kpap\u00edr-elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
"3683. Import beszerz\u00e9sek \u00e1f\u00e1ja": {},
|
||||
"3684. Ad\u00f3sok": {},
|
||||
"3685. Biztos\u00edt\u00f3int\u00e9zettel szembeni k\u00f6vetel\u00e9sek": {},
|
||||
"3686. Barter \u00fcgylet elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
"3687. \u00c1rfolyam k\u00fcl\u00f6nb\u00f6zetek elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
"3688. Ki nem emelt egy\u00e9b k\u00f6vetel\u00e9sek": {}
|
||||
},
|
||||
"369. Egy\u00e9b k\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"37. \u00c9RT\u00c9KPAP\u00cdROK": {
|
||||
"371. R\u00e9szesed\u00e9sek": {
|
||||
"3711. R\u00e9szesed\u00e9s anyav\u00e1llalatban": {},
|
||||
"3712. R\u00e9szesed\u00e9s le\u00e1nyv\u00e1llalatban": {},
|
||||
"3713. R\u00e9szesed\u00e9s k\u00f6z\u00f6s vezet\u00e9s\u0171 v\u00e1llalkoz\u00e1sban": {},
|
||||
"3714. R\u00e9szesed\u00e9s t\u00e1rsult v\u00e1llalkoz\u00e1sban": {},
|
||||
"3719. Kapcsolt v\u00e1llalkoz\u00e1sban l\u00e9v\u0151 r\u00e9szesed\u00e9sek \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"372. Saj\u00e1t r\u00e9szv\u00e9nyek, saj\u00e1t \u00fczletr\u00e9szek": {
|
||||
"3721. Elad\u00e1sra v\u00e1s\u00e1rolt egy\u00e9b r\u00e9szesed\u00e9sek": {}
|
||||
},
|
||||
"373. Forgat\u00e1si c\u00e9l\u00fa hitelviszonyt megtestes\u00edt\u0151 \u00e9rt\u00e9kpap\u00edrok ": {
|
||||
"3741. Elad\u00e1sra v\u00e1s\u00e1rolt hitelviszonyt megtestes\u00edt\u0151 \u00e9rt\u00e9kpap\u00edrok": {},
|
||||
"3742. Elad\u00e1sra v\u00e1s\u00e1rolt diszkont \u00e9rt\u00e9kpap\u00edrok": {},
|
||||
"3749. Forgat\u00e1si c\u00e9l\u00fa hitelviszonyt megtestes\u00edt\u0151 \u00e9rt\u00e9kpap\u00edrok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"378. \u00c9rt\u00e9kpap\u00edrok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {},
|
||||
"379. \u00c9rt\u00e9kpap\u00edr elsz\u00e1mol\u00e1si sz\u00e1mla": {}
|
||||
},
|
||||
"38. P\u00c9NZESZK\u00d6Z\u00d6K": {
|
||||
"381. P\u00e9nzt\u00e1r ": {
|
||||
"3811. P\u00e9nzt\u00e1r-sz\u00e1mla": {},
|
||||
"3812. Elektronikus p\u00e9nzeszk\u00f6z\u00f6k ": {},
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"382. Valutap\u00e9nzt\u00e1r ": {
|
||||
"3821. Valutap\u00e9nzt\u00e1r-sz\u00e1mla": {},
|
||||
"3829. Valuta \u00e1rfolyamk\u00fcl\u00f6nb\u00f6zeti sz\u00e1mla ": {}
|
||||
},
|
||||
"383. Csekkek": {},
|
||||
"384. Elsz\u00e1mol\u00e1si bet\u00e9tsz\u00e1mla ": {
|
||||
"account_type": "Bank",
|
||||
"is_group": 1
|
||||
},
|
||||
"385. Elk\u00fcl\u00f6n\u00edtett bet\u00e9tsz\u00e1ml\u00e1k ": {
|
||||
"3851. Kamatoz\u00f3 bet\u00e9tsz\u00e1ml\u00e1k": {},
|
||||
"3852. Elk\u00fcl\u00f6n\u00edtett p\u00e9nzeszk\u00f6z\u00f6k k\u00f6tv\u00e9nykibocs\u00e1t\u00e1sb\u00f3l ": {},
|
||||
"3853. Beruh\u00e1z\u00e1sra elk\u00fcl\u00f6n\u00edtett p\u00e9nzeszk\u00f6z\u00f6k": {},
|
||||
"3854. Fejleszt\u00e9si c\u00e9lra elk\u00fcl\u00f6n\u00edtett p\u00e9nzeszk\u00f6z\u00f6k ": {},
|
||||
"3855. Egy\u00e9b c\u00e9lra elk\u00fcl\u00f6n\u00edtett p\u00e9nzeszk\u00f6z\u00f6k": {},
|
||||
"3856. Lak\u00e1s\u00e9p\u00edt\u00e9si bet\u00e9tsz\u00e1mla": {},
|
||||
"3857. Elk\u00fcl\u00f6n\u00edtett lak\u00e1s\u00e9p\u00edt\u00e9si c\u00e9l\u00fa p\u00e9nzeszk\u00f6z\u00f6k ": {},
|
||||
"3858. Lak\u00e1s\u00e9p\u00edt\u00e9s \u00faton l\u00e9v\u0151 p\u00e9nzeszk\u00f6zei": {}
|
||||
},
|
||||
"386. Devizabet\u00e9t-sz\u00e1mla ": {
|
||||
"3861. Devizabet\u00e9t-sz\u00e1mla": {},
|
||||
"3862. K\u00fclf\u00f6ld\u00f6n vezetett devizabet\u00e9t-sz\u00e1mla ": {},
|
||||
"3863. Devizat\u00f6rzsbet\u00e9t-sz\u00e1mla": {},
|
||||
"3868. Egy\u00e9b devizabet\u00e9t-sz\u00e1mla": {},
|
||||
"3869. Devizabet\u00e9t \u00e1rfolyamk\u00fcl\u00f6nb\u00f6zeti sz\u00e1mla ": {}
|
||||
},
|
||||
"387. Elektronikus p\u00e9nz": {},
|
||||
"389. \u00c1tvezet\u00e9si sz\u00e1mla": {}
|
||||
},
|
||||
"39. AKT\u00cdV ID\u00d5BELI ELHAT\u00c1ROL\u00c1SOK": {
|
||||
"391. Bev\u00e9telek akt\u00edv id\u0151beli elhat\u00e1rol\u00e1sa ": {
|
||||
"3911. Diszkont \u00e9rt\u00e9kpap\u00edrok id\u0151ar\u00e1nyos kamat\u00e1nak elhat\u00e1rol\u00e1sa": {},
|
||||
"3912. \u00c9rt\u00e9kpap\u00edrok beszerz\u00e9s\u00e9hez kapcsol\u00f3d\u00f3 k\u00fcl\u00f6nb\u00f6zetb\u0151l az id\u0151ar\u00e1nyos \u00e1rfolyamnyeres\u00e9g elhat\u00e1rol\u00e1sa": {},
|
||||
"3913. \u00c1rbev\u00e9tel, egy\u00e9b kamatbev\u00e9tel, egy\u00e9b bev\u00e9tel elhat\u00e1rol\u00e1sa": {}
|
||||
},
|
||||
"392. K\u00f6lts\u00e9gek, r\u00e1ford\u00edt\u00e1sok akt\u00edv id\u0151beli elhat\u00e1rol\u00e1sa ": {
|
||||
"3921. \u00c9rt\u00e9kpap\u00edrok, r\u00e9szesed\u00e9sek beszerz\u00e9s\u00e9hez kapcsol\u00f3d\u00f3 bizom\u00e1nyi d\u00edj, v\u00e1s\u00e1rolt v\u00e9teli opci\u00f3 d\u00edj\u00e1nak elhat\u00e1rol\u00e1sa": {},
|
||||
"3922. T\u00f6bbletk\u00f6telezetts\u00e9gek elhat\u00e1rol\u00e1sa": {},
|
||||
"3923. K\u00f6lts\u00e9gek, egy\u00e9b fizetett kamatok, egy\u00e9b r\u00e1ford\u00edt\u00e1sok elhat\u00e1rol\u00e1sa": {}
|
||||
},
|
||||
"393. Halasztott r\u00e1ford\u00edt\u00e1sok ": {
|
||||
"3931. Tartoz\u00e1s\u00e1tv\u00e1llal\u00e1sok miatti r\u00e1ford\u00edt\u00e1sok elhat\u00e1rol\u00e1sa": {},
|
||||
"3932. Devizak\u00f6telezetts\u00e9gek \u00e1rfolyamvesztes\u00e9g\u00e9nek elhat\u00e1rol\u00e1sa ": {}
|
||||
},
|
||||
"399. A k\u00f6vetel\u00e9s-jelleg\u0171 akt\u00edv id\u0151beli elhat\u00e1rol\u00e1sok \u00e9rt\u00e9kveszt\u00e9se \u00e9s annak vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"4. SZ\u00c1MLAOSZT\u00c1LY FORR\u00c1SOK": {
|
||||
"41. SAJ\u00c1T T\u00d5KE": {
|
||||
"411. Jegyzett\u0151ke ": {},
|
||||
"412. T\u0151ketartal\u00e9k": {},
|
||||
"413. Eredm\u00e9nytartal\u00e9k": {},
|
||||
"414. Lek\u00f6t\u00f6tt tartal\u00e9k ": {
|
||||
"4141. Lek\u00f6t\u00f6tt tartal\u00e9k t\u0151ketartal\u00e9kb\u00f3l": {},
|
||||
"4142. Lek\u00f6t\u00f6tt tartal\u00e9k eredm\u00e9nytartal\u00e9kb\u00f3l": {},
|
||||
"4143. Lek\u00f6t\u00f6tt tartal\u00e9k p\u00f3tbefizet\u00e9sb\u0151l ": {}
|
||||
},
|
||||
"417. \u00c9rt\u00e9kel\u00e9si tartal\u00e9k": {},
|
||||
"418. El\u0151z\u0151 \u00e9vek helyesb\u00edt\u00e9s\u00e9b\u0151l sz\u00e1rmaz\u00f3 m\u00e9rleg szerinti eredm\u00e9ny": {},
|
||||
"419. Ad\u00f3zott eredm\u00e9ny": {}
|
||||
},
|
||||
"42. C\u00c9LTARTAL\u00c9KOK": {
|
||||
"421. C\u00e9ltartal\u00e9k a v\u00e1rhat\u00f3 k\u00f6telezetts\u00e9gekre ": {},
|
||||
"422. C\u00e9ltartal\u00e9k a j\u00f6v\u0151beni k\u00f6lts\u00e9gekre": {},
|
||||
"424. \u00c1rfolyamvesztes\u00e9g id\u0151beli elhat\u00e1rol\u00e1sa alapj\u00e1n k\u00e9pzett c\u00e9ltartal\u00e9k ": {},
|
||||
"429. Egy\u00e9b c\u00e9ltartal\u00e9k": {}
|
||||
},
|
||||
"43-47. K\u00d6TELEZETTS\u00c9GEK": {
|
||||
"43. H\u00c1TRASOROLT K\u00d6TELEZETTS\u00c9GEK": {
|
||||
"431. H\u00e1trasorolt k\u00f6telezetts\u00e9gek kapcsolt v\u00e1llalkoz\u00e1ssal szemben ": {
|
||||
"4311. H\u00e1trasorolt k\u00f6telezetts\u00e9gek anyav\u00e1llalattal szemben ": {},
|
||||
"4312. H\u00e1trasorolt k\u00f6telezetts\u00e9gek le\u00e1nyv\u00e1llalattal szemben": {},
|
||||
"4313. H\u00e1trasorolt k\u00f6telezetts\u00e9gek k\u00f6z\u00f6s vezet\u00e9s\u0171 v\u00e1llalkoz\u00e1ssal szemben ": {},
|
||||
"4314. H\u00e1trasorolt k\u00f6telezetts\u00e9gek t\u00e1rsult v\u00e1llalkoz\u00e1ssal szemben ": {}
|
||||
},
|
||||
"432. H\u00e1trasorolt k\u00f6telezetts\u00e9gek egy\u00e9b r\u00e9szesed\u00e9si viszonyban l\u00e9v\u0151 v\u00e1llalkoz\u00e1ssal szemben": {},
|
||||
"433. H\u00e1trasorolt k\u00f6telezetts\u00e9gek egy\u00e9b gazd\u00e1lkod\u00f3val szemben": {}
|
||||
},
|
||||
"44. HOSSZ\u00da LEJ\u00c1RAT\u00da K\u00d6TELEZETTS\u00c9GEK": {
|
||||
"441. Hossz\u00fa lej\u00e1ratra kapott k\u00f6lcs\u00f6n\u00f6k": {},
|
||||
"442. \u00c1tv\u00e1ltoztathat\u00f3 k\u00f6tv\u00e9nyek ": {},
|
||||
"443. Tartoz\u00e1sok k\u00f6tv\u00e9nykibocs\u00e1t\u00e1sb\u00f3l ": {
|
||||
"4431. Tartoz\u00e1sok k\u00f6tv\u00e9nykibocs\u00e1t\u00e1sb\u00f3l forintban ": {},
|
||||
"4432. Tartoz\u00e1sok k\u00f6tv\u00e9nykibocs\u00e1t\u00e1sb\u00f3l deviz\u00e1ban": {}
|
||||
},
|
||||
"444. Beruh\u00e1z\u00e1si \u00e9s fejleszt\u00e9si hitelek ": {
|
||||
"4441. Beruh\u00e1z\u00e1si \u00e9s fejleszt\u00e9si hitelek forintban ": {},
|
||||
"4442. Beruh\u00e1z\u00e1si \u00e9s fejleszt\u00e9si hitelek deviz\u00e1ban ": {}
|
||||
},
|
||||
"445. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa hitelek ": {
|
||||
"4451. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa hitelek forintban ": {},
|
||||
"4452. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa hitelek deviz\u00e1ban": {}
|
||||
},
|
||||
"446. Tart\u00f3s k\u00f6telezetts\u00e9gek kapcsolt v\u00e1llalkoz\u00e1ssal szemben ": {
|
||||
"is_group": 1
|
||||
},
|
||||
"447. Tart\u00f3s k\u00f6telezetts\u00e9gek egy\u00e9b r\u00e9szesed\u00e9si viszonyban l\u00e9v\u0151 v\u00e1llalkoz\u00e1ssal szemben": {},
|
||||
"448. P\u00e9nz\u00fcgyi l\u00edzing miatti k\u00f6telezetts\u00e9gek ": {},
|
||||
"449. Egy\u00e9b hossz\u00fa lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek ": {
|
||||
"4491. Kincst\u00e1ri vagyon r\u00e9sz\u00e9t k\u00e9pez\u0151 eszk\u00f6z\u00f6k kezel\u00e9sbe v\u00e9tel\u00e9hez kapcsol\u00f3d\u00f3 k\u00f6telezetts\u00e9g": {},
|
||||
"4492. Alap\u00edt\u00f3kkal szembeni hossz\u00fa lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek ": {}
|
||||
},
|
||||
"4499. Hossz\u00fa lej\u00e1rat\u00fa egy\u00e9b k\u00f6telezetts\u00e9gek": {}
|
||||
},
|
||||
"45-47. R\u00d6VID LEJ\u00c1RAT\u00da K\u00d6TELEZETTS\u00c9GEK": {
|
||||
"451. R\u00f6vid lej\u00e1rat\u00fa k\u00f6lcs\u00f6n\u00f6k ": {
|
||||
"4511. R\u00f6vid lej\u00e1rat\u00fa \u00e1tv\u00e1ltoztathat\u00f3 k\u00f6tv\u00e9nyek ": {},
|
||||
"4512. Egy\u00e9b r\u00f6vid lej\u00e1rat\u00fa k\u00f6lcs\u00f6n\u00f6k": {}
|
||||
},
|
||||
"452. R\u00f6vid lej\u00e1rat\u00fa hitelek ": {
|
||||
"4521. R\u00f6vid lej\u00e1rat\u00fa hitelek forintban ": {},
|
||||
"4522. R\u00f6vid lej\u00e1rat\u00fa hitelek deviz\u00e1ban ": {}
|
||||
},
|
||||
"453. Vev\u0151kt\u0151l kapott el\u0151legek": {},
|
||||
"454-456. K\u00f6telezetts\u00e9gek \u00e1rusz\u00e1ll\u00edt\u00e1sb\u00f3l \u00e9s szolg\u00e1ltat\u00e1sb\u00f3l (sz\u00e1ll\u00edt\u00f3k)": {
|
||||
"454. Sz\u00e1ll\u00edt\u00f3k ": {
|
||||
"4541. Belf\u00f6ldi anyag- \u00e9s \u00e1rusz\u00e1ll\u00edt\u00f3k ": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"4542. K\u00fclf\u00f6ldi anyag- \u00e9s \u00e1rusz\u00e1ll\u00edt\u00f3k ": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"4543. Belf\u00f6ldi szolg\u00e1ltat\u00f3k": {},
|
||||
"4544. K\u00fclf\u00f6ldi szolg\u00e1ltat\u00f3k": {},
|
||||
"4549. Nem sz\u00e1ml\u00e1zott sz\u00e1ll\u00edt\u00e1sok, szolg\u00e1ltat\u00e1sok ": {
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
}
|
||||
},
|
||||
"455. Beruh\u00e1z\u00e1si sz\u00e1ll\u00edt\u00f3k ": {
|
||||
"4551. Belf\u00f6ldi beruh\u00e1z\u00e1si sz\u00e1ll\u00edt\u00f3k ": {},
|
||||
"4552. K\u00fclf\u00f6ldi beruh\u00e1z\u00e1si sz\u00e1ll\u00edt\u00f3k": {},
|
||||
"4559. Nem sz\u00e1ml\u00e1zott beruh\u00e1z\u00e1si sz\u00e1ll\u00edt\u00f3k ": {}
|
||||
},
|
||||
"456. Nem sz\u00e1ml\u00e1zott sz\u00e1ll\u00edt\u00f3k": {}
|
||||
},
|
||||
"457. V\u00e1lt\u00f3tartoz\u00e1sok": {},
|
||||
"458. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek kapcsolt v\u00e1llalkoz\u00e1ssal szemben ": {
|
||||
"4581. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek anyav\u00e1llalattal szemben ": {},
|
||||
"4582. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek le\u00e1nyv\u00e1llalattal szemben": {},
|
||||
"4583. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek k\u00f6z\u00f6s vezet\u00e9s\u0171 v\u00e1llalkoz\u00e1ssal szemben": {},
|
||||
"4584. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek t\u00e1rsult v\u00e1llalkoz\u00e1ssal szemben": {}
|
||||
},
|
||||
"459. R\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek egy\u00e9b r\u00e9szesed\u00e9si viszonyban l\u00e9v\u0151 v\u00e1llalkoz\u00e1ssal szemben": {},
|
||||
"461-479. Egy\u00e9b r\u00f6vid lej\u00e1rat\u00fa k\u00f6telezetts\u00e9gek": {
|
||||
"461. Eredm\u00e9nyt terhel\u0151 ad\u00f3k elsz\u00e1mol\u00e1sa": {
|
||||
"4611. T\u00e1rsas\u00e1gi ad\u00f3 elsz\u00e1mol\u00e1sa ": {},
|
||||
"4612. K\u00fcl\u00f6nad\u00f3 elsz\u00e1mol\u00e1sa ": {},
|
||||
"4613. Egyszer\u0171s\u00edtett v\u00e1llalkoz\u00f3i ad\u00f3 elsz\u00e1mol\u00e1sa ": {}
|
||||
},
|
||||
"462. Szem\u00e9lyi j\u00f6vedelemad\u00f3 elsz\u00e1mol\u00e1sa ": {
|
||||
"4612. Mag\u00e1nszem\u00e9lyekt\u0151l levont szem\u00e9lyi j\u00f6vedelem ad\u00f3 elsz\u00e1mol\u00e1sa ": {},
|
||||
"4621. Kifizet\u0151t terhel\u0151 szem\u00e9lyi j\u00f6vedelem ad\u00f3 elsz\u00e1mol\u00e1sa ": {}
|
||||
},
|
||||
"463. K\u00f6lts\u00e9gvet\u00e9si befizet\u00e9si k\u00f6telezetts\u00e9gek ": {
|
||||
"463-1. Nyugd\u00edjj\u00e1rul\u00e9k ": {},
|
||||
"463-10. Innov\u00e1ci\u00f3s j\u00e1rul\u00e9k ": {},
|
||||
"463-11. \u00d6nellen\u0151rz\u00e9si p\u00f3tl\u00e9k ": {},
|
||||
"463-12. Mulaszt\u00e1si b\u00edrs\u00e1g, ad\u00f3b\u00edrs\u00e1g ": {},
|
||||
"463-13. K\u00e9sedelmi p\u00f3tl\u00e9k ": {},
|
||||
"463-14. Egy\u00e9b k\u00f6lts\u00e9gvet\u00e9si befizet\u00e9si k\u00f6telezetts\u00e9gek ": {},
|
||||
"463-2. Eg\u00e9szs\u00e9gbiztos\u00edt\u00e1si- \u00e9s munkaer\u0151 piaci j\u00e1rul\u00e9k ": {},
|
||||
"463-3. Rehabilit\u00e1ci\u00f3s hozz\u00e1j\u00e1rul\u00e1s ": {},
|
||||
"463-4. Szoci\u00e1lis hozz\u00e1j\u00e1rul\u00e1si ad\u00f3 ": {},
|
||||
"463-5. Eg\u00e9szs\u00e9g\u00fcgyi szolg\u00e1ltat\u00e1si j\u00e1rul\u00e9k ": {},
|
||||
"463-6. Szakk\u00e9pz\u00e9si hozz\u00e1j\u00e1rul\u00e1s ": {},
|
||||
"463-7. Eg\u00e9szs\u00e9g\u00fcgyi hozz\u00e1j\u00e1rul\u00e1s ": {},
|
||||
"463-8. Egyszer\u0171s\u00edtett foglalkoztat\u00e1s k\u00f6zterhe ": {},
|
||||
"463-9. C\u00e9gaut\u00f3ad\u00f3 ": {}
|
||||
},
|
||||
"464. G\u00e9pj\u00e1rm\u0171 ad\u00f3 (c\u00e9gaut\u00f3ad\u00f3) elsz\u00e1mol\u00e1sa": {
|
||||
"is_group": 1
|
||||
},
|
||||
"465. V\u00e1m- \u00e9s p\u00e9nz\u00fcgy\u0151rs\u00e9g elsz\u00e1mol\u00e1si sz\u00e1mla ": {
|
||||
"4651. V\u00e1mk\u00f6lts\u00e9gek \u00e9s egy\u00e9b v\u00e1mterhek elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
"4652. Importbeszerz\u00e9s ut\u00e1n fizetend\u0151 \u00e1ltal\u00e1nos forgalmi ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
"4653. V\u00e1m- \u00e9s p\u00e9nz\u00fcgy\u0151rs\u00e9ggel kapcsolatos egy\u00e9b elsz\u00e1mol\u00e1sok ": {}
|
||||
},
|
||||
"466. El\u0151zetesen felsz\u00e1m\u00edtott \u00e1ltal\u00e1nos forgalmi ad\u00f3 ": {
|
||||
"4661. Beszerz\u00e9sek el\u0151zetesen felsz\u00e1m\u00edtott \u00e1ltal\u00e1nos forgalmi ad\u00f3ja ": {},
|
||||
"4662. Ar\u00e1nyos\u00edt\u00e1ssal megosztand\u00f3 el\u0151zetesen felsz\u00e1m\u00edtott \u00e1ltal\u00e1nos forgalmi ad\u00f3": {}
|
||||
},
|
||||
"467. Fizetend\u0151 \u00e1ltal\u00e1nos forgalmi ad\u00f3": {},
|
||||
"468. \u00c1ltal\u00e1nos forgalmi ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
|
||||
"469. Helyi ad\u00f3k elsz\u00e1mol\u00e1si sz\u00e1mla ": {
|
||||
"4691. \u00c9p\u00edtm\u00e9nyad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
|
||||
"4692. Telekad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
"4693. Kommun\u00e1lis ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
|
||||
"4694. Idegenforgalmi ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
|
||||
"4695. Helyi ipar\u0171z\u00e9si ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
|
||||
"4696. G\u00e9pj\u00e1rm\u0171ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
"4697. K\u00fclf\u00f6ldi g\u00e9pj\u00e1rm\u0171ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla ": {},
|
||||
"4699. Egy\u00e9b helyi ad\u00f3 elsz\u00e1mol\u00e1si sz\u00e1mla": {}
|
||||
},
|
||||
"471. J\u00f6vedelemelsz\u00e1mol\u00e1si sz\u00e1mla ": {
|
||||
"4711. Keresetelsz\u00e1mol\u00e1si sz\u00e1mla ": {},
|
||||
"4712. T\u00e1rsadalombiztos\u00edt\u00e1si ell\u00e1t\u00e1s ": {},
|
||||
"4713. Egy\u00e9b kifizet\u00e9sek elsz\u00e1mol\u00e1sa": {}
|
||||
},
|
||||
"472. Fel nem vett j\u00e1rand\u00f3s\u00e1gok": {},
|
||||
"473. Elsz\u00e1mol\u00e1s a t\u00e1rsadalombiztos\u00edt\u00e1ssal ": {},
|
||||
"474. Szakk\u00e9pz\u00e9si hozz\u00e1j\u00e1rul\u00e1s": {
|
||||
"4741. K\u00f6zponti m\u0171szaki fejleszt\u00e9si hozz\u00e1j\u00e1rul\u00e1s": {},
|
||||
"4742. Elsz\u00e1mol\u00e1sra kapott p\u00e9nzeszk\u00f6z\u00f6k": {},
|
||||
"4743. K\u00f6rnyezetv\u00e9delmi term\u00e9k d\u00edjfizet\u00e9si k\u00f6telezetts\u00e9g ": {},
|
||||
"4749. Egy\u00e9b befizet\u00e9sek az elk\u00fcl\u00f6n\u00edtett alapokba": {}
|
||||
},
|
||||
"475. Eg\u00e9szs\u00e9g\u00fcgyi hozz\u00e1j\u00e1rul\u00e1s (EHO) elsz\u00e1mol\u00e1sa": {},
|
||||
"476. Egy\u00e9b \u00e1llami ad\u00f3hat\u00f3s\u00e1ggal szembeni k\u00f6telezetts\u00e9g elsz\u00e1mol\u00e1sa": {
|
||||
"4761. K\u00e1rt\u00e9r\u00edt\u00e9s": {},
|
||||
"4762. B\u00edr\u00f3i letilt\u00e1s": {},
|
||||
"4763. Banki-elsz\u00e1mol\u00e1s": {},
|
||||
"4764. Levont szakszervezeti d\u00edj": {},
|
||||
"4765. Mag\u00e1n nyugd\u00edjp\u00e9nzt\u00e1ri befizet\u00e9si k\u00f6telezetts\u00e9gek": {}
|
||||
},
|
||||
"477. R\u00f6vid lej\u00e1rat\u00fa egy\u00e9b k\u00f6telezetts\u00e9gek munkav\u00e1llal\u00f3kkal \u00e9s tulajdonosokkal szemben": {},
|
||||
"478. R\u00e9szesed\u00e9sekkel, \u00e9rt\u00e9kpap\u00edrokkal kapcsolatos k\u00f6telezetts\u00e9gek ": {},
|
||||
"479. K\u00fcl\u00f6nf\u00e9le r\u00f6vid lej\u00e1rat\u00fa egy\u00e9b befizet\u00e9si k\u00f6telezetts\u00e9gek ": {
|
||||
"4791. Biztos\u00edt\u00f3 int\u00e9zetekkel szembeni k\u00f6telezetts\u00e9gek": {},
|
||||
"4792. Hitelez\u0151k": {},
|
||||
"4793. \u00c1tv\u00e1llalt k\u00f6telezetts\u00e9gek": {},
|
||||
"4794. Beszerz\u00e9si \u00e1rba beletartoz\u00f3 el\u0151\u00edrt egy\u00e9b k\u00f6telezetts\u00e9gek ": {},
|
||||
"4795. Egy\u00e9b r\u00f6vid lej\u00e1rat\u00fa el\u0151\u00edrt k\u00f6telezetts\u00e9gek": {}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"48. PASSZ\u00cdV ID\u00d5BELI ELHAT\u00c1ROL\u00c1SOK": {
|
||||
"481. Bev\u00e9telek passz\u00edv id\u0151beli elhat\u00e1rol\u00e1sa ": {
|
||||
"4811. Befolyt, elsz\u00e1molt bev\u00e9telek elhat\u00e1rol\u00e1sa": {},
|
||||
"4812. K\u00f6lts\u00e9gek ellent\u00e9telez\u00e9s\u00e9re kapott t\u00e1mogat\u00e1sok elhat\u00e1rol\u00e1sa": {},
|
||||
"4813. Devizaeszk\u00f6z\u00f6k \u00e9s devizak\u00f6telezetts\u00e9gek m\u00e9rlegfordul\u00f3napi \u00e9rt\u00e9kel\u00e9se \u00e1rfolyamnyeres\u00e9g\u00e9nek elhat\u00e1rol\u00e1sa": {}
|
||||
},
|
||||
"482. K\u00f6lts\u00e9gek, r\u00e1ford\u00edt\u00e1sok passz\u00edv id\u0151beli elhat\u00e1rol\u00e1sa ": {
|
||||
"4821. M\u00e9rlegfordul\u00f3nap el\u0151tti id\u0151szakot terhel\u0151 k\u00f6lts\u00e9gek, r\u00e1ford\u00edt\u00e1sok elhat\u00e1rol\u00e1sa": {},
|
||||
"4822. \u00c9rt\u00e9kpap\u00edrok beszerz\u00e9s\u00e9hez kapcsol\u00f3d\u00f3 k\u00fcl\u00f6nb\u00f6zetb\u0151l az id\u0151ar\u00e1nyos \u00e1rfolyam\u008fvesztes\u00e9g elhat\u00e1rol\u00e1sa": {},
|
||||
"4823. Fizetend\u0151 kamatok elhat\u00e1rol\u00e1sa ": {}
|
||||
},
|
||||
"483. Halasztott bev\u00e9telek ": {}
|
||||
},
|
||||
"49. \u00c9VI M\u00c9RLEGSZ\u00c1ML\u00c1K": {
|
||||
"491. Nyit\u00f3m\u00e9rleg sz\u00e1mla ": {},
|
||||
"492. Z\u00e1r\u00f3m\u00e9rleg sz\u00e1mla": {},
|
||||
"493. Ad\u00f3zott eredm\u00e9ny elsz\u00e1mol\u00e1si sz\u00e1mla": {},
|
||||
"494. El\u0151z\u0151 \u00e9vi ad\u00f3zott eredm\u00e9ny elsz\u00e1mol\u00e1sa": {}
|
||||
},
|
||||
"root_type": "Liability"
|
||||
},
|
||||
"5. SZ\u00c1MLAOSZT\u00c1LY K\u00d6LTS\u00c9GNEMEK": {
|
||||
"51 - 53 ANYAGJELLEG\u00db R\u00c1FORD\u00cdT\u00c1SOK ": {
|
||||
"51. ANYAGK\u00d6LTS\u00c9G": {
|
||||
"511. V\u00e1s\u00e1rolt anyagok k\u00f6lts\u00e9gei ": {
|
||||
"5111. Alapanyag k\u00f6lts\u00e9gek": {},
|
||||
"5112. Seg\u00e9danyag k\u00f6lts\u00e9gek": {},
|
||||
"5113. \u00dczemanyag k\u00f6lts\u00e9gek": {},
|
||||
"5114. Egy \u00e9ven bel\u00fcl elhaszn\u00e1l\u00f3d\u00f3 gy\u00e1rt\u00f3eszk\u00f6z\u00f6k, berendez\u00e9sek, felszerel\u00e9sek \u00e9s egy\u00e9b eszk\u00f6z\u00f6k k\u00f6lts\u00e9gei": {},
|
||||
"5115. Egy \u00e9ven bel\u00fcl elhaszn\u00e1l\u00f3d\u00f3 munkaruha, v\u00e9d\u0151ruha felhaszn\u00e1l\u00e1s k\u00f6lts\u00e9gei": {},
|
||||
"5116. Nyomtatv\u00e1nyok, irodaszerek k\u00f6lts\u00e9gei": {},
|
||||
"5117. F\u0171t\u0151anyag k\u00f6lts\u00e9gek": {},
|
||||
"5118. Villamosenergia felhaszn\u00e1l\u00e1s \u00e9s v\u00edzfelhaszn\u00e1l\u00e1s k\u00f6lts\u00e9gei": {},
|
||||
"5119. Egy\u00e9b anyagfelhaszn\u00e1l\u00e1s k\u00f6lts\u00e9gei": {},
|
||||
"512. Egy \u00e9ven bel\u00fcl elhaszn\u00e1l\u00f3d\u00f3 anyagi eszk\u00f6z\u00f6k k\u00f6lts\u00e9gei ": {},
|
||||
"5121. V\u00e1s\u00e1rolt n\u00f6vend\u00e9k\u00e1llatok k\u00f6lts\u00e9gei": {},
|
||||
"5122. V\u00e1s\u00e1rolt h\u00edz\u00f3\u00e1llatok k\u00f6lts\u00e9gei": {},
|
||||
"5123. V\u00e1s\u00e1rolt egy\u00e9b \u00e1llatok k\u00f6lts\u00e9gei": {},
|
||||
"513. Egy\u00e9b anyagk\u00f6lts\u00e9g": {},
|
||||
"519. Anyagk\u00f6lts\u00e9g megt\u00e9r\u00fcl\u00e9s": {}
|
||||
}
|
||||
},
|
||||
"52. IG\u00c9NYBE VETT SZOLG\u00c1LTAT\u00c1SOK K\u00d6LTS\u00c9GEI": {
|
||||
"521. Sz\u00e1ll\u00edt\u00e1s-rakod\u00e1s, rakt\u00e1roz\u00e1s k\u00f6lts\u00e9gei": {},
|
||||
"522. B\u00e9rleti d\u00edjak": {},
|
||||
"523. Karbantart\u00e1si k\u00f6lts\u00e9gek": {},
|
||||
"524. Hirdet\u00e9s, rekl\u00e1m, propaganda k\u00f6lts\u00e9gek": {},
|
||||
"525. Oktat\u00e1s \u00e9s tov\u00e1bbk\u00e9pz\u00e9s k\u00f6lts\u00e9gei": {},
|
||||
"526. Utaz\u00e1si \u00e9s kik\u00fcldet\u00e9si k\u00f6lts\u00e9gek (napid\u00edj n\u00e9lk\u00fcl)": {},
|
||||
"529. Ig\u00e9nybe vett egy\u00e9b szolg\u00e1ltat\u00e1sok k\u00f6lts\u00e9gei": {}
|
||||
},
|
||||
"53. EGY\u00c9B SZOLG\u00c1LTAT\u00c1SOK K\u00d6LTS\u00c9GEI": {
|
||||
"531. Hat\u00f3s\u00e1gi igazgat\u00e1si, szolg\u00e1ltat\u00e1si d\u00edjak, illet\u00e9kek": {},
|
||||
"532. P\u00e9nz\u00fcgyi, befektet\u00e9si szolg\u00e1ltat\u00e1si d\u00edjak": {},
|
||||
"533. Biztos\u00edt\u00e1si d\u00edj ": {},
|
||||
"534. K\u00f6lts\u00e9gk\u00e9nt elsz\u00e1moland\u00f3 ad\u00f3k, j\u00e1rul\u00e9kok, term\u00e9kd\u00edjak": {},
|
||||
"539. K\u00fcl\u00f6nf\u00e9le egy\u00e9b szolg\u00e1ltat\u00e1sok k\u00f6lts\u00e9gei": {}
|
||||
}
|
||||
},
|
||||
"54 - 56. SZEM\u00c9LYI JELLEG\u00db R\u00c1FORD\u00cdT\u00c1SOK": {
|
||||
"54. B\u00c9RK\u00d6LTS\u00c9G ": {
|
||||
"541. B\u00e9rk\u00f6lts\u00e9g": {},
|
||||
"542. Tulajdonos szem\u00e9lyes k\u00f6zrem\u0171k\u00f6d\u00e9s\u00e9nek ellen\u00e9rt\u00e9ke": {},
|
||||
"543. Sz\u00f6vetkezeti tagok munkad\u00edja": {}
|
||||
},
|
||||
"55. SZEM\u00c9LYI JELLEG\u00db EGY\u00c9B KIFIZET\u00c9SEK": {
|
||||
"551. Munkav\u00e1llal\u00f3knak, tagoknak fizetett szem\u00e9lyi jelleg\u0171 kifizet\u00e9sek ": {
|
||||
"5511. Betegszabads\u00e1g d\u00edja, munk\u00e1ltat\u00f3t terhel\u0151 t\u00e1pp\u00e9nz, t\u00e1pp\u00e9nz kieg\u00e9sz\u00edt\u00e9s": {},
|
||||
"5512. V\u00e9gkiel\u00e9g\u00edt\u00e9s": {},
|
||||
"5513. Munk\u00e1baj\u00e1r\u00e1ssal kapcsolatos egy\u00e9b k\u00f6lts\u00e9gek t\u00e9r\u00edt\u00e9se": {},
|
||||
"5514. Kik\u00fcldet\u00e9s napid\u00edja": {},
|
||||
"5515. Megv\u00e1ltozott munkak\u00e9pess\u00e9g\u0171 munkav\u00e1llal\u00f3k keresetkieg\u00e9sz\u00edt\u00e9se, fizetett seg\u00e9lyek": {},
|
||||
"5516. \u00dcd\u00fcl\u00e9si hozz\u00e1j\u00e1rul\u00e1s": {},
|
||||
"5517. Lak\u00e1s\u00e9p\u00edt\u00e9sre ny\u00fajtott t\u00e1mogat\u00e1s, alb\u00e9rleti hozz\u00e1j\u00e1rul\u00e1s": {},
|
||||
"5518. Jubileumi jutalom, t\u00e1rgyjutalom": {},
|
||||
"5519. Sorkatonai vagy polg\u00e1ri szolg\u00e1lat teljes\u00edt\u00e9s\u00e9t k\u00f6vet\u0151en fizetett szem\u00e9lyi alapb\u00e9r": {}
|
||||
},
|
||||
"552. J\u00f3l\u00e9ti \u00e9s kultur\u00e1lis k\u00f6lts\u00e9gek": {},
|
||||
"559. Egy\u00e9b szem\u00e9lyi jelleg\u0171 kifizet\u00e9sek ": {
|
||||
"5591. Munk\u00e1ltat\u00f3 \u00e1ltal fizetett baleset-, \u00e9let- \u00e9s nyugd\u00edjbiztos\u00edt\u00e1s d\u00edja": {},
|
||||
"5592. Munk\u00e1ltat\u00f3 \u00e1ltal \u00f6nk\u00e9ntes p\u00e9nzt\u00e1rba befizetett munk\u00e1ltat\u00f3i tagd\u00edj hozz\u00e1j\u00e1rul\u00e1s": {},
|
||||
"5593. Munk\u00e1ltat\u00f3t terhel\u0151 szem\u00e9lyi j\u00f6vedelemad\u00f3": {},
|
||||
"5594. Munk\u00e1ltat\u00f3i hozz\u00e1j\u00e1rul\u00e1s a korengedm\u00e9nyes nyugd\u00edj ig\u00e9nybev\u00e9tel\u00e9hez": {},
|
||||
"5595. Tal\u00e1lm\u00e1nyi d\u00edj, szabadalom v\u00e9tel\u00e1ra \u00e9s hasznos\u00edt\u00e1si d\u00edja, az \u00faj\u00edt\u00e1si d\u00edj \u00e9s ezekkel kapcsolatos k\u00f6zrem\u0171k\u00f6d\u00e9si d\u00edjak": {},
|
||||
"5596. Fizetett szerz\u0151i, \u00edr\u00f3i \u00e9s m\u00e1s jogv\u00e9delmet \u00e9lvez\u0151 munk\u00e1k d\u00edjai \u00e9s ezekkel kapcsolatos k\u00f6zrem\u0171k\u00f6d\u0151i d\u00edjak": {},
|
||||
"5597. Fizetett \u00f6szt\u00f6nd\u00edjak": {},
|
||||
"5598. Reprezent\u00e1ci\u00f3s k\u00f6lts\u00e9gek, \u00e9tkez\u00e9si hozz\u00e1j\u00e1rul\u00e1s": {},
|
||||
"5599. Munk\u00e1ltat\u00f3 \u00e1ltal fizetett mag\u00e1nnyugd\u00edj-p\u00e9nzt\u00e1ri tagd\u00edj kieg\u00e9sz\u00edt\u00e9s, munkav\u00e1llal\u00f3kkal kapcsolatos biztos\u00edt\u00e1si d\u00edjak": {}
|
||||
}
|
||||
},
|
||||
"56. B\u00c9RJ\u00c1RUL\u00c9KOK": {
|
||||
"561. Nyugd\u00edjbiztos\u00edt\u00e1si \u00e9s eg\u00e9szs\u00e9gbiztos\u00edt\u00e1si j\u00e1rul\u00e9k ": {},
|
||||
"562. Eg\u00e9szs\u00e9g\u00fcgyi hozz\u00e1j\u00e1rul\u00e1s": {},
|
||||
"563. Munkaad\u00f3i j\u00e1rul\u00e9k": {},
|
||||
"564. Szakk\u00e9pz\u00e9si hozz\u00e1j\u00e1rul\u00e1s ": {},
|
||||
"569. Egy\u00e9b hozz\u00e1j\u00e1rul\u00e1s ": {}
|
||||
}
|
||||
},
|
||||
"57. \u00c9RT\u00c9KCS\u00d6KKEN\u00c9SI LE\u00cdR\u00c1S": {
|
||||
"571. Terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1s ": {
|
||||
"5711. Terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1s ": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"5712. Kiemelt, kis \u00e9rt\u00e9k\u0171 (50 eFt egyedi beszerz\u00e9si \u00e9rt\u00e9k alatti) eszk\u00f6z\u00f6k terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1sa": {},
|
||||
"57121. Kis \u00e9rt\u00e9k\u0171 (50 eFt egyedi beszerz\u00e9si \u00e9rt\u00e9k alatti) vagyoni \u00e9rt\u00e9k\u0171 jogok terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1sa": {},
|
||||
"57122. Kis \u00e9rt\u00e9k\u0171 (50 eFt egyedi beszerz\u00e9si \u00e9rt\u00e9k alatti) szellemi term\u00e9kek terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1sa": {},
|
||||
"57123. Kis \u00e9rt\u00e9k\u0171 (50 eFt egyedi beszerz\u00e9si \u00e9rt\u00e9k alatti) t\u00e1rgyi eszk\u00f6z\u00f6k terv szerinti \u00e9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1sa": {}
|
||||
}
|
||||
},
|
||||
"58. AKTIV\u00c1LT SAJ\u00c1T TELJES\u00cdTM\u00c9NYEK \u00c9RT\u00c9KE": {
|
||||
"581. Saj\u00e1t termel\u00e9s\u0171 k\u00e9szletek \u00e1llom\u00e1nyv\u00e1ltoz\u00e1sa ": {},
|
||||
"582. Saj\u00e1t el\u0151\u00e1ll\u00edt\u00e1s\u00fa eszk\u00f6z\u00f6k aktiv\u00e1lt \u00e9rt\u00e9ke": {},
|
||||
"589. Aktiv\u00e1lt saj\u00e1t teljes\u00edtm\u00e9nyek \u00e1tvezet\u00e9si sz\u00e1mla": {}
|
||||
},
|
||||
"59. K\u00d6LTS\u00c9GNEM ELLENSZ\u00c1MLA (els\u0151dleges k\u00f6lts\u00e9ghely-k\u00f6lts\u00e9gvisel\u0151 elsz\u00e1mol\u00f3s eset\u00e9n) ": {
|
||||
"is_group": 1
|
||||
},
|
||||
"59. K\u00d6LTS\u00c9GNEM \u00c1TVEZET\u00c9SI SZ\u00c1MLA (els\u0151dleges k\u00f6lts\u00e9gnem-elsz\u00e1mol\u00e1s eset\u00e9n)": {
|
||||
"is_group": 1
|
||||
},
|
||||
"59. K\u00d6LTS\u00c9GNEM \u00c1TVEZET\u00c9SI SZ\u00c1MLA (els\u0151dleges k\u00f6lts\u00e9gnem-elsz\u00e1mol\u00e1s eset\u00e9n, kiz\u00e1r\u00f3lag \u00f6sszk\u00f6lts\u00e9g elj\u00e1r\u00e1ssal)": {
|
||||
"59/51. Anyagk\u00f6lts\u00e9g \u00e1tvezet\u00e9si sz\u00e1mla": {},
|
||||
"59/52. Ig\u00e9nybe vett szolg\u00e1ltat\u00e1sok k\u00f6lts\u00e9gei \u00e1tvezet\u00e9si sz\u00e1mla ": {},
|
||||
"59/53. Egy\u00e9b szolg\u00e1ltat\u00e1sok k\u00f6lts\u00e9gei \u00e1tvezet\u00e9si sz\u00e1mla ": {},
|
||||
"59/54. B\u00e9rk\u00f6lts\u00e9g \u00e1tvezet\u00e9si sz\u00e1mla": {},
|
||||
"59/55. Szem\u00e9lyi jelleg\u0171 egy\u00e9b kifizet\u00e9sek \u00e1tvezet\u00e9si sz\u00e1mla ": {},
|
||||
"59/56. B\u00e9rj\u00e1rul\u00e9kok \u00e1tvezet\u00e9si sz\u00e1mla": {},
|
||||
"59/57. \u00c9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1s \u00e1tvezet\u00e9si sz\u00e1mla ": {}
|
||||
},
|
||||
"59. K\u00d6LTS\u00c9GNEM \u00c1TVEZET\u00c9SI SZ\u00c1MLA (kiz\u00e1r\u00f3lag k\u00f6lts\u00e9gnem-elsz\u00e1mol\u00e1s \u00e9s forgalmi k\u00f6lts\u00e9g elj\u00e1r\u00e1ssal)": {
|
||||
"is_group": 1
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"6. SZ\u00c1MLAOSZT\u00c1LY K\u00d6LTS\u00c9GHELYEK, \u00c1LTAL\u00c1NOS K\u00d6LTS\u00c9GEK": {
|
||||
"61. JAV\u00cdT\u00d3-KARBANTART\u00d3 \u00dcZEMEK K\u00d6LTS\u00c9GEI": {},
|
||||
"62. SZOLG\u00c1LTAT\u00c1ST V\u00c9GZ\u00d5 \u00dcZEMEK (EGYS\u00c9GEK) K\u00d6LTS\u00c9GEI": {},
|
||||
"63. G\u00c9PK\u00d6LTS\u00c9G": {},
|
||||
"64-65. \u00dcZEMI IR\u00c1NY\u00cdT\u00c1S \u00c1LTAL\u00c1NOS K\u00d6LTS\u00c9GEI": {},
|
||||
"66. K\u00d6ZPONTI IR\u00c1NY\u00cdT\u00c1S \u00c1LTL\u00c1NOS K\u00d6LTS\u00c9GEI": {},
|
||||
"67. \u00c9RT\u00c9KES\u00cdT\u00c9SI, FORGALMAZ\u00c1SI K\u00d6LTS\u00c9GEK": {},
|
||||
"68. ELK\u00dcL\u00d6N\u00cdTETT EGY\u00c9B \u00c1LTL\u00c1NOS K\u00d6LTS\u00c9GEK": {
|
||||
"681. Alap\u00edt\u00e1s-\u00e1tszervez\u00e9s k\u00f6lts\u00e9gei": {},
|
||||
"682. Alap- \u00e9s alkalmazott kutat\u00e1s saj\u00e1t k\u00f6lts\u00e9gei": {},
|
||||
"683. V\u00e1llalkoz\u00e1sban adott alap- \u00e9s alkalmazott kutat\u00e1s k\u00f6lts\u00e9gei": {},
|
||||
"684. K\u00eds\u00e9rleti fejleszt\u00e9s saj\u00e1t k\u00f6lts\u00e9gei": {},
|
||||
"685. V\u00e1llalkoz\u00e1sba adott k\u00eds\u00e9rleti fejleszt\u00e9s k\u00f6lts\u00e9gei": {},
|
||||
"686. Kutat\u00e1s-k\u00eds\u00e9rleti fejleszt\u00e9s \u00e1ltal\u00e1nos \u00e9s k\u00f6zvetett k\u00f6lts\u00e9gei": {},
|
||||
"687. Kutat\u00e1s-k\u00eds\u00e9rleti fejleszt\u00e9s elsz\u00e1molt \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {},
|
||||
"688. Garanci\u00e1lis jav\u00edt\u00e1s k\u00f6lts\u00e9gei": {},
|
||||
"689. Egy\u00e9b elk\u00fcl\u00f6n\u00edtett k\u00f6lts\u00e9gek": {}
|
||||
},
|
||||
"69. K\u00d6LTS\u00c9GHELYEK K\u00d6LTS\u00c9GNEMEK \u00c1TVEZET\u00c9SE": {
|
||||
"691. K\u00f6lts\u00e9ghelyek k\u00f6lts\u00e9geinek \u00e1tvezet\u00e9se": {}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"7. SZ\u00c1MLAOSZT\u00c1LY TEV\u00c9KENYS\u00c9GEKK\u00d6LTS\u00c9GEI": {
|
||||
"is_group": 1,
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"8. SZ\u00c1MLAOSZT\u00c1LY \u00c9RT\u00c9KES\u00cdT\u00c9S ELSZ\u00c1MOLT \u00d6NK\u00d6LTS\u00c9GE \u00c9S R\u00c1FORD\u00cdT\u00c1SOK": {
|
||||
"81-83. SZ\u00c1MLACSOPORTOK (az \u00f6sszk\u00f6lts\u00e9g elj\u00e1r\u00e1ssal k\u00e9sz\u00fcl\u0151 eredm\u00e9ny-kimutat\u00e1shoz)": {
|
||||
"81. ANYAGJELLEG\u00db R\u00c1FORD\u00cdT\u00c1SOK": {
|
||||
"811. Anyagk\u00f6lts\u00e9g ": {},
|
||||
"812. Ig\u00e9nybe vett szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {},
|
||||
"813. Egy\u00e9b szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {},
|
||||
"814. Eladott \u00e1ruk beszerz\u00e9si \u00e9rt\u00e9ke": {},
|
||||
"815. Eladott (k\u00f6zvet\u00edtett) szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {}
|
||||
},
|
||||
"82. SZEM\u00c9LYI JELLEG\u00db R\u00c1FORD\u00cdT\u00c1SOK": {
|
||||
"821. B\u00e9rk\u00f6lts\u00e9g": {},
|
||||
"822. Szem\u00e9lyi jelleg\u0171 egy\u00e9b kifizet\u00e9sek": {},
|
||||
"823. B\u00e9rj\u00e1rul\u00e9kok": {}
|
||||
},
|
||||
"83. \u00c9RT\u00c9KCS\u00d6KKEN\u00c9SI LE\u00cdR\u00c1S": {
|
||||
"831. \u00c9rt\u00e9kcs\u00f6kken\u00e9si le\u00edr\u00e1s ": {}
|
||||
}
|
||||
},
|
||||
"81-85. SZ\u00c1MLACSOPORTOK (a forgalmi k\u00f6lts\u00e9g elj\u00e1r\u00e1ssal k\u00e9sz\u00fcl\u0151 eredm\u00e9nykimutat\u00e1shoz)": {
|
||||
"81-82. BELF\u00d6LDI \u00c9RT\u00c9KES\u00cdT\u00c9S K\u00d6ZVETLEN K\u00d6LTS\u00c9GEI": {
|
||||
"811. Belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s elsz\u00e1molt k\u00f6zvetlen \u00f6nk\u00f6lts\u00e9ge": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"812. Belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s eladott \u00e1ruk beszerz\u00e9si \u00e9rt\u00e9ke": {
|
||||
"account_type": "Stock Adjustment"
|
||||
},
|
||||
"813. Belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s eladott (k\u00f6zvet\u00edtett) szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {
|
||||
"account_type": "Expenses Included In Valuation"
|
||||
}
|
||||
},
|
||||
"83-84. EXPORT\u00c9RT\u00c9KES\u00cdT\u00c9S K\u00d6ZVETLEN K\u00d6LTS\u00c9GEI": {
|
||||
"831. Export\u00e9rt\u00e9kes\u00edt\u00e9s elsz\u00e1molt k\u00f6zvetlen \u00f6nk\u00f6lts\u00e9ge": {},
|
||||
"832. Export\u00e9rt\u00e9kes\u00edt\u00e9s eladott \u00e1ruk beszerz\u00e9si \u00e9rt\u00e9ke": {},
|
||||
"833. Export\u00e9rt\u00e9kes\u00edt\u00e9s eladott (k\u00f6zvet\u00edtett) szolg\u00e1ltat\u00e1sok \u00e9rt\u00e9ke": {}
|
||||
},
|
||||
"85. \u00c9RT\u00c9KES\u00cdT\u00c9S K\u00d6ZVETETT K\u00d6LTS\u00c9GEI": {
|
||||
"851. \u00c9rt\u00e9kes\u00edt\u00e9si, forgalmaz\u00e1si k\u00f6lts\u00e9gek": {},
|
||||
"852. Igazgat\u00e1si k\u00f6lts\u00e9gek": {},
|
||||
"853. Egy\u00e9b \u00e1ltal\u00e1nos k\u00f6lts\u00e9gek": {}
|
||||
}
|
||||
},
|
||||
"86. EGY\u00c9B R\u00c1FORD\u00cdT\u00c1SOK": {
|
||||
"861. Egy\u00e9b r\u00e1ford\u00edt\u00e1snak min\u0151s\u00fcl\u0151 \u00e9rt\u00e9kes\u00edt\u00e9sek": {
|
||||
"8611. \u00c9rt\u00e9kes\u00edtett immateri\u00e1lis javak, t\u00e1rgyi eszk\u00f6z\u00f6k k\u00f6nyv szerinti \u00e9rt\u00e9ke": {},
|
||||
"8612. \u00c9rt\u00e9kes\u00edtett, \u00e1truh\u00e1zott (engedm\u00e9nyezett) k\u00f6vetel\u00e9sek k\u00f6nyv szerinti \u00e9rt\u00e9ke": {}
|
||||
},
|
||||
"862. Egy\u00e9b r\u00e1ford\u00edt\u00e1snak min\u0151s\u00fcl\u0151 eszk\u00f6z kivezet\u00e9sek": {
|
||||
"8621. Hi\u00e1nyz\u00f3, megsemmis\u00fclt, kiselejtezett immateri\u00e1lis javak, t\u00e1rgyi eszk\u00f6z\u00f6k nett\u00f3 \u00e9rt\u00e9ke": {},
|
||||
"8622. Hi\u00e1nyz\u00f3, megsemmis\u00fclt, \u00e1llom\u00e1nyb\u00f3l kivezetett k\u00e9szletek k\u00f6nyv szerinti \u00e9rt\u00e9ke": {}
|
||||
},
|
||||
"863. Behajthatatlan k\u00f6vetel\u00e9sek le\u00edrt \u00f6sszege": {},
|
||||
"864. C\u00e9ltartal\u00e9k k\u00e9pz\u00e9s": {
|
||||
"8641. C\u00e9ltartal\u00e9k-k\u00e9pz\u00e9s a v\u00e1rhat\u00f3 k\u00f6telezetts\u00e9gekre": {},
|
||||
"8642. C\u00e9ltartal\u00e9k-k\u00e9pz\u00e9s a j\u00f6v\u0151beni k\u00f6lts\u00e9gekre": {},
|
||||
"8643. C\u00e9ltartal\u00e9k-k\u00e9pz\u00e9s egy\u00e9b c\u00edmen": {}
|
||||
},
|
||||
"865. Ut\u00f3lag adott, nem sz\u00e1ml\u00e1zott engedm\u00e9ny": {},
|
||||
"866. Egy\u00e9b r\u00e1ford\u00edt\u00e1sk\u00e9nt elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {
|
||||
"8661. K\u00f6zponti k\u00f6lts\u00e9gvet\u00e9ssel elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
|
||||
"8662. Helyi \u00f6nkorm\u00e1nyzatokkal elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
|
||||
"8663. Elk\u00fcl\u00f6n\u00edtett \u00e1llami p\u00e9nzalapokkal elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
|
||||
"8664. T\u00e1rsadalombiztos\u00edt\u00e1ssal elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
|
||||
"8665. EU p\u00e9nz\u00fcgyi alapokkal elsz\u00e1molt ad\u00f3k, illet\u00e9kek, hozz\u00e1j\u00e1rul\u00e1sok": {},
|
||||
"8666. R\u00e1ford\u00edt\u00e1sk\u00e9nt elsz\u00e1molt egy\u00e9b ad\u00f3k \u00e9s ad\u00f3jelleg\u0171 t\u00e9telek": {}
|
||||
},
|
||||
"867. Egy\u00e9b r\u00e1ford\u00edt\u00e1sk\u00e9nt elsz\u00e1molt, ad\u00f3nak nem min\u0151s\u00fcl\u0151 kifizet\u00e9sek": {
|
||||
"8671. K\u00e1resem\u00e9nnyel kapcsolatos fizetett, fizetend\u0151 \u00f6sszegek": {},
|
||||
"8672. K\u00f6lts\u00e9gek (r\u00e1ford\u00edt\u00e1sok) ellent\u00e9telez\u00e9s\u00e9re visszafizet\u00e9si k\u00f6telezetts\u00e9g n\u00e9lk\u00fcl adott t\u00e1mogat\u00e1s, juttat\u00e1": {},
|
||||
"8673. Fejleszt\u00e9si c\u00e9lra, visszafizet\u00e9si k\u00f6telezetts\u00e9g n\u00e9lk\u00fcl adott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
|
||||
"8674. Fejleszt\u00e9si c\u00e9lra kapott t\u00e1mogat\u00e1s visszafizetend\u0151 \u00f6sszege": {},
|
||||
"8675. Tao \u00e1ltal elismert b\u00edrs\u00e1gok, k\u00f6tb\u00e9rek, k\u00e9sedelmi kamatok, p\u00f3tl\u00e9kok, k\u00e1rt\u00e9r\u00edt\u00e9sek, s\u00e9relemd\u00edjak": {},
|
||||
"8676. Tao \u00e1ltal el nem ismert b\u00edrs\u00e1gok, k\u00f6tb\u00e9rek, k\u00e9sedelmi kamatok, p\u00f3tl\u00e9kok, k\u00e1rt\u00e9r\u00edt\u00e9sek, s\u00e9relemd\u00edjak": {}
|
||||
},
|
||||
"868. Terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9sek, \u00e9rt\u00e9kveszt\u00e9sek": {
|
||||
"8681. Immateri\u00e1lis javak terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {},
|
||||
"8682. T\u00e1rgyi eszk\u00f6z\u00f6k terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9se": {},
|
||||
"8683. K\u00e9szletek \u00e9rt\u00e9kveszt\u00e9se": {},
|
||||
"8684. K\u00f6vetel\u00e9sek \u00e9rt\u00e9kveszt\u00e9se": {}
|
||||
},
|
||||
"869. K\u00fcl\u00f6nf\u00e9le egy\u00e9b r\u00e1ford\u00edt\u00e1sok": {
|
||||
"8691. T\u00e1rsas\u00e1gba bevitt, \u00e9rt\u00e9kpap\u00edrnak vagy r\u00e9szesed\u00e9snek nem min\u0151s\u00fcl\u0151 vagyont. k\u00f6nyv szerinti \u00e9s l\u00e9t. okir. meghat. veszt. k\u00fcl\u00f6nb\u00f6zet": {},
|
||||
"8692. Ellent\u00e9telez\u00e9s n\u00e9lk\u00fcl \u00e1tv\u00e1llalt k\u00f6telezetts\u00e9g szerz\u0151d\u00e9s szerinti \u00f6sszege": {},
|
||||
"8693. T\u00e9r\u00edt\u00e9s n\u00e9lk\u00fcl \u00e1tadott, r\u00e9szesed\u00e9snek vagy \u00e9rt\u00e9kpap\u00edrnak nem min\u0151s\u00fcl\u0151 eszk\u00f6z\u00f6k nyilv\u00e1ntart\u00e1s szerinti \u00e9rt\u00e9ke": {},
|
||||
"8694. T\u00e9r\u00edt\u00e9s n\u00e9lk\u00fcl ny\u00fajtott szolg\u00e1ltat\u00e1sok beker\u00fcl\u00e9si \u00e9rt\u00e9ke": {},
|
||||
"8695. Elengedett k\u00f6vetel\u00e9sek k\u00f6nyv szerinti \u00e9rt\u00e9ke": {},
|
||||
"8696. Egy\u00e9b, vagyoncs\u00f6kken\u00e9ssel j\u00e1r\u00f3 r\u00e1ford\u00edt\u00e1sok": {}
|
||||
}
|
||||
},
|
||||
"87. P\u00c9NZ\u00dcGYI M\u0170VELETEK R\u00c1FORD\u00cdT\u00c1SAI": {
|
||||
"871. R\u00e9szesed\u00e9sekb\u0151l sz\u00e1rmaz\u00f3 r\u00e1ford\u00edt\u00e1sok, \u00e1rfolyamvesztes\u00e9gek": {},
|
||||
"872. Befektetett p\u00e9nz\u00fcgyi eszk\u00f6z\u00f6kb\u0151l (\u00e9rt\u00e9kpap\u00edrokb\u00f3l, k\u00f6lcs\u00f6n\u00f6kb\u0151l) sz\u00e1rmaz\u00f3 r\u00e1ford\u00edt\u00e1sok \u00e1rfolyamvesztes\u00e9gek": {},
|
||||
"873. Hitelint\u00e9zetnek fizetend\u0151 kamatok \u00e9s kamatjelleg\u0171 r\u00e1ford\u00edt\u00e1sok": {},
|
||||
"874. Nem hitelint\u00e9zetnek fizetend\u0151 kamatok \u00e9s kamatjelleg\u0171 r\u00e1ford\u00edt\u00e1sok": {},
|
||||
"875. R\u00e9szesed\u00e9sek, \u00e9rt\u00e9kpap\u00edrok, bankbet\u00e9tek \u00e9rt\u00e9kveszt\u00e9se \u00e9s vissza\u00edr\u00e1sa": {
|
||||
"8751. R\u00e9szesed\u00e9sek, \u00e9rt\u00e9kpap\u00edrok, bankbet\u00e9tek \u00e9rt\u00e9kveszt\u00e9se": {},
|
||||
"8752. R\u00e9szesed\u00e9sek, \u00e9rt\u00e9kpap\u00edrok, bankbet\u00e9tek \u00e9rt\u00e9kveszt\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"876. K\u00fclf\u00f6ldi p\u00e9nz\u00e9rt\u00e9kre sz\u00f3l\u00f3 eszk\u00f6z\u00f6k \u00e9s k\u00f6telezetts\u00e9gek \u00e1rfolyamvesztes\u00e9gei": {
|
||||
"8761. Deviza- \u00e9s valutak\u00e9szletek forintra \u00e1tv\u00e1lt\u00e1s\u00e1nak \u00e1rfolyamvesztes\u00e9ge": {},
|
||||
"8762. K\u00fclf\u00f6ldi p\u00e9nz\u00e9rt\u00e9kre sz\u00f3l\u00f3 eszk\u00f6z\u00f6k \u00e9s k\u00f6telezetts\u00e9gek p\u00e9nz\u00fcgyileg rendezett \u00e1rfolyamvesztes\u00e9ge": {}
|
||||
},
|
||||
"877. P\u00e9nz\u00fcgyi m\u0171veletek egy\u00e9b r\u00e1ford\u00edt\u00e1sai": {},
|
||||
"878. P\u00e9nz\u00fcgyi rendez\u00e9shez kapcsol\u00f3d\u00f3an adott engedm\u00e9ny": {},
|
||||
"879. Egy\u00e9b vagyoncs\u00f6kken\u00e9ssel j\u00e1r\u00f3 p\u00e9nz\u00fcgyi r\u00e1ford\u00edt\u00e1sok": {}
|
||||
},
|
||||
"88. RENDK\u00cdV\u00dcLI R\u00c1FORD\u00cdT\u00c1SOK": {
|
||||
"881. T\u00e1rsas\u00e1gba bevitt eszk\u00f6z\u00f6k nyilv\u00e1ntart\u00e1s szerinti \u00e9rt\u00e9ke": {}
|
||||
},
|
||||
"89. EREDM\u00c9NYT TERHEL\u0150 AD\u00d3K": {
|
||||
"891. T\u00e1rsas\u00e1gi ad\u00f3": {},
|
||||
"892. Egyszer\u0171s\u00edtett v\u00e1llalkoz\u00f3i ad\u00f3": {},
|
||||
"893. Kisv\u00e1llalati ad\u00f3": {},
|
||||
"899. Eredm\u00e9nyt terhel\u0151 egy\u00e9b ad\u00f3k": {}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"9. SZ\u00c1MLAOSZT\u00c1LY BEV\u00c9TELEK": {
|
||||
"91. BELF\u00d6LDI \u00c9RT\u00c9KES\u00cdT\u00c9S \u00c1RBEV\u00c9TELE": {
|
||||
"911. Belf\u00f6ldinek \u00e9rt\u00e9kes\u00edtett saj\u00e1t termel\u00e9s\u0171 k\u00e9szletek \u00e1rbev\u00e9tele": {},
|
||||
"912. Belf\u00f6ldinek \u00e9rt\u00e9kes\u00edtett v\u00e1s\u00e1rolt k\u00e9szletek \u00e1rbev\u00e9tele": {},
|
||||
"913. Belf\u00f6ldinek ny\u00fajtott szolg\u00e1ltat\u00e1sok \u00e1rbev\u00e9tele": {},
|
||||
"918. Belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9ssel kapcsolatos \u00e1rt\u00e1mogat\u00e1s": {},
|
||||
"919. Egy\u00e9b belf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s \u00e1rbev\u00e9tele": {}
|
||||
},
|
||||
"92. EXPORT\u00c9RT\u00c9KES\u00cdT\u00c9S \u00c1RBEV\u00c9TELE": {
|
||||
"921. K\u00fclf\u00f6ldinek \u00e9rt\u00e9kes\u00edtett saj\u00e1t termel\u00e9s\u0171 k\u00e9szletek \u00e1rbev\u00e9tele": {},
|
||||
"922. K\u00fclf\u00f6ldinek \u00e9rt\u00e9kes\u00edtett v\u00e1s\u00e1rolt k\u00e9szletek \u00e1rbev\u00e9tele": {},
|
||||
"923. K\u00fclf\u00f6ldinek ny\u00fajtott szolg\u00e1ltat\u00e1sok \u00e1rbev\u00e9tele": {},
|
||||
"928. K\u00fclf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9ssel kapcsolatos \u00e1rt\u00e1mogat\u00e1s": {},
|
||||
"929. Egy\u00e9b k\u00fclf\u00f6ldi \u00e9rt\u00e9kes\u00edt\u00e9s \u00e1rbev\u00e9tele": {}
|
||||
},
|
||||
"96. EGY\u00c9B BEV\u00c9TELEK": {
|
||||
"961. Egy\u00e9b bev\u00e9telnek min\u0151s\u00fcl\u0151 \u00e9rt\u00e9kes\u00edt\u00e9sek": {
|
||||
"9611. \u00c9rt\u00e9kes\u00edtett immateri\u00e1lis javak, t\u00e1rgyi eszk\u00f6z\u00f6k ellen\u00e9rt\u00e9ke": {},
|
||||
"9612. \u00c9rt\u00e9kes\u00edtett, \u00e1truh\u00e1zott (engedm\u00e9nyezett) k\u00f6vetel\u00e9sek ellen\u00e9rt\u00e9ke": {}
|
||||
},
|
||||
"963. K\u00f6vetel\u00e9s k\u00f6nyv szerinti \u00e9rt\u00e9k\u00e9t meghalad\u00f3an realiz\u00e1lt \u00f6sszeg": {},
|
||||
"964. C\u00e9ltartal\u00e9k felold\u00e1s": {
|
||||
"9651. V\u00e1rhat\u00f3 k\u00f6telezetts\u00e9gek fedezet\u00e9re k\u00e9pzett c\u00e9ltartal\u00e9k felhaszn\u00e1l\u00e1sa ": {},
|
||||
"9652. J\u00f6v\u0151beni k\u00f6lts\u00e9gekre k\u00e9pzett c\u00e9ltartal\u00e9k felhaszn\u00e1l\u00e1sa ": {},
|
||||
"9653. Egy\u00e9b c\u00edmen k\u00e9pzett c\u00e9ltartal\u00e9k felhaszn\u00e1l\u00e1sa ": {}
|
||||
},
|
||||
"965. Ut\u00f3lag kapott, nem sz\u00e1ml\u00e1zott engedm\u00e9ny": {},
|
||||
"966. Ut\u00f3lag kapott, nem sz\u00e1ml\u00e1zott engedm\u00e9ny": {
|
||||
"9661. K\u00f6zponti k\u00f6lts\u00e9gvet\u00e9sb\u0151l kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
|
||||
"9662. Helyi \u00f6nkorm\u00e1nyzatokt\u00f3l kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
|
||||
"9663. Eur\u00f3pai Uni\u00f3t\u00f3l kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
|
||||
"9664. Egy\u00e9b forr\u00e1sb\u00f3l kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {}
|
||||
},
|
||||
"967. Egy\u00e9b bev\u00e9telk\u00e9nt elsz\u00e1molt p\u00e9nzbev\u00e9telek": {
|
||||
"9671. K\u00e1resem\u00e9nnyel kapcsolatos t\u00e9r\u00edt\u00e9sek": {},
|
||||
"9672. K\u00f6lts\u00e9gek (r\u00e1ford\u00edt\u00e1sok) ellent\u00e9telez\u00e9s\u00e9re kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
|
||||
"9673. Fejleszt\u00e9si c\u00e9lra kapott t\u00e1mogat\u00e1s, juttat\u00e1s": {},
|
||||
"9674. Kapott b\u00edrs\u00e1gok, k\u00f6tb\u00e9rek, fekb\u00e9rek, k\u00e9sedelmi kamatok, k\u00e1rt\u00e9r\u00edt\u00e9sek": {}
|
||||
},
|
||||
"968. Terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9sek, \u00e9rt\u00e9kveszt\u00e9sek vissza\u00edr\u00e1sa": {
|
||||
"9681. Immateri\u00e1lis javak terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {},
|
||||
"9682. T\u00e1rgyi eszk\u00f6z\u00f6k terven fel\u00fcli \u00e9rt\u00e9kcs\u00f6kken\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {},
|
||||
"9683. K\u00e9szletek \u00e9rt\u00e9kveszt\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {},
|
||||
"9684. R\u00e9szesed\u00e9sek \u00e9rt\u00e9kveszt\u00e9s\u00e9nek vissza\u00edr\u00e1sa": {}
|
||||
},
|
||||
"969. K\u00fcl\u00f6nf\u00e9le egy\u00e9b bev\u00e9telek": {
|
||||
"9691. Gazdas\u00e1gi t\u00e1rsas\u00e1gba bevitt, \u00e9rt\u00e9kp. vagy r\u00e9szesed\u00e9snek nem min\u0151s\u00fcl\u0151 vagyont. \u00e9rt\u00e9ke \u00e9s l\u00e9tes\u00edt\u0151 okir. \u00e9rt. nyer. jell . k\u00fcl\u00f6nb.": {},
|
||||
"9692. El\u00e9v\u00fclt k\u00f6telezetts\u00e9g k\u00f6nyv szerinti \u00e9rt\u00e9ke": {},
|
||||
"9693. T\u00e9r\u00edt\u00e9s n\u00e9lk\u00fcl \u00e1tvett, aj\u00e1nd\u00e9kk\u00e9nt, hagyat\u00e9kk\u00e9nt kapott, fellelt eszk\u00f6z\u00f6k piaci vagy jogszab\u00e1ly szerinti \u00e9rt\u00e9ke": {},
|
||||
"9694. T\u00e9r\u00edt\u00e9s n\u00e9lk\u00fcl kapott szolg\u00e1ltat\u00e1sok piaci vagy jogszab\u00e1ly szerinti \u00e9rt\u00e9ke": {},
|
||||
"9695. Elengedett \u00e9s ellent\u00e9telez\u00e9s n\u00e9lk\u00fcl \u00e1tv\u00e1llalt k\u00f6telezetts\u00e9g \u00e9rt\u00e9ke": {},
|
||||
"9696. Egy\u00e9b, vagyonn\u00f6veked\u00e9ssel j\u00e1r\u00f3 bev\u00e9telek": {}
|
||||
}
|
||||
},
|
||||
"97. P\u00c9NZ\u00dcGYI M\u0170VELETEK BEV\u00c9TELEI": {
|
||||
"971. R\u00e9szesed\u00e9sekb\u0151l sz\u00e1rmaz\u00f3 bev\u00e9telek, \u00e1rfolyamnyeres\u00e9gek": {},
|
||||
"972. Befektetett p\u00e9nz\u00fcgyi eszk\u00f6z\u00f6kb\u0151l (\u00e9rt\u00e9kpap\u00edrokb\u00f3l, k\u00f6lcs\u00f6n\u00f6kb\u0151l) sz\u00e1rmaz\u00f3 bev\u00e9telek, \u00e1rfolyamnyeres\u00e9gek": {},
|
||||
"973. Hitelint\u00e9zett\u0151l kapott kamatok \u00e9s kamatjelleg\u0171 bev\u00e9telek": {},
|
||||
"974. Nem hitelint\u00e9zett\u0151l kapott kamatok \u00e9s kamatjelleg\u0171 bev\u00e9telek": {},
|
||||
"975. Kapott (j\u00e1r\u00f3) osztal\u00e9k \u00e9s r\u00e9szesed\u00e9s": {},
|
||||
"976. K\u00fclf\u00f6ldi p\u00e9nz\u00e9rt\u00e9kre sz\u00f3l\u00f3 eszk\u00f6z\u00f6k \u00e9s k\u00f6telezetts\u00e9gek \u00e1rfolyamnyeres\u00e9gei": {
|
||||
"9761. Deviza- \u00e9s valutak\u00e9szletek forintra \u00e1tv\u00e1lt\u00e1s\u00e1nak \u00e1rfolyamnyeres\u00e9ge": {},
|
||||
"9762. K\u00fclf\u00f6ldi p\u00e9nz\u00e9rt\u00e9kre sz\u00f3l\u00f3 eszk\u00f6z\u00f6k \u00e9s k\u00f6telezetts\u00e9gek p\u00e9nz\u00fcgyileg rendezett \u00e1rfolyamnyeres\u00e9ge": {}
|
||||
},
|
||||
"977. P\u00e9nz\u00fcgyi m\u0171veletek egy\u00e9b bev\u00e9telei": {},
|
||||
"978. P\u00e9nz\u00fcgyi rendez\u00e9shez kapcsol\u00f3d\u00f3an kapott engedm\u00e9ny": {},
|
||||
"979. Egy\u00e9b vagyonn\u00f6veked\u00e9ssel j\u00e1r\u00f3 p\u00e9nz\u00fcgyi bev\u00e9telek": {}
|
||||
},
|
||||
"root_type": "Income"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,722 @@
|
||||
{
|
||||
"country_code": "tw",
|
||||
"name": "Taiwan - Chart of Accounts",
|
||||
"tree": {
|
||||
"1-\u8cc7\u7522": {
|
||||
"11~12-\u6d41\u52d5\u8cc7\u7522": {
|
||||
"111-\u73fe\u91d1\u53ca\u7d04\u7576\u73fe\u91d1": {
|
||||
"1111-\u5eab\u5b58\u73fe\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1112-\u96f6\u7528\u91d1/\u9031\u8f49\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1113-\u9280\u884c\u5b58\u6b3e": {
|
||||
"account_type": "Bank",
|
||||
"\u4e2d\u570b\u4fe1\u8a17": {
|
||||
"account_type": "Bank"
|
||||
},
|
||||
"\u53f0\u5317\u5bcc\u90a6": {
|
||||
"account_type": "Bank"
|
||||
}
|
||||
},
|
||||
"1116-\u5728\u9014\u73fe\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1117-\u7d04\u7576\u73fe\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"1118-\u5176\u4ed6\u73fe\u91d1\u53ca\u7d04\u7576\u73fe\u91d1": {
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"account_type": "Cash"
|
||||
},
|
||||
"112-\u77ed\u671f\u6295\u8cc7": {
|
||||
"1121-\u77ed\u671f\u6295\u8cc7 \u2014\u80a1\u7968": {}
|
||||
},
|
||||
"113-\u61c9\u6536\u7968\u64da": {
|
||||
"1131-\u61c9\u6536\u7968\u64da": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1132-\u61c9\u6536\u7968\u64da\u8cbc\u73fe ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1138-\u5176\u4ed6\u61c9\u6536\u7968\u64da ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1139-\u5099\u62b5\u5446\u5e33 \uff0d\u61c9\u6536\u7968\u64da ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"114-\u61c9\u6536\u5e33\u6b3e": {
|
||||
"1141-\u61c9\u6536\u5e33\u6b3e ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1142-\u61c9\u6536\u5206\u671f\u5e33\u6b3e ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1149-\u5099\u62b5\u5446\u5e33 \uff0d\u61c9\u6536\u5e33\u6b3e ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"118-\u5176\u4ed6\u61c9\u6536\u6b3e": {
|
||||
"1184-\u61c9\u6536\u6536\u76ca": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1185-\u61c9\u6536\u9000\u7a05\u6b3e": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1189-\u5099\u62b5\u5446\u5e33 \u2014 \u5176\u4ed6\u61c9\u6536\u6b3e ": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"121~122-\u5b58\u8ca8": {
|
||||
"1219-\u5099\u62b5\u5b58\u8ca8\u8dcc\u50f9\u640d\u5931": {},
|
||||
"1229-\u5099\u62b5\u5b58\u8ca8\u8dcc\u50f9\u640d\u5931": {},
|
||||
"account_type": "Stock",
|
||||
"is_group": 1
|
||||
},
|
||||
"125-\u9810\u4ed8\u8cbb\u7528": {
|
||||
"1251-\u9810\u4ed8\u85aa\u8cc7": {},
|
||||
"1252-\u9810\u4ed8\u79df\u91d1": {},
|
||||
"1253-\u9810\u4ed8\u4fdd\u96aa\u8cbb": {},
|
||||
"1254-\u7528\u54c1\u76e4\u5b58": {},
|
||||
"1255-\u9810\u4ed8\u6240\u5f97\u7a05": {},
|
||||
"1258-\u5176\u4ed6\u9810\u4ed8\u8cbb\u7528": {}
|
||||
},
|
||||
"126-\u9810\u4ed8\u6b3e\u9805": {
|
||||
"1261-\u9810\u4ed8\u8ca8\u6b3e": {},
|
||||
"1268-\u5176\u4ed6\u9810\u4ed8\u6b3e\u9805": {}
|
||||
},
|
||||
"128~129-\u5176\u4ed6\u6d41\u52d5\u8cc7\u7522": {
|
||||
"1281-\u9032\u9805\u7a05\u984d": {},
|
||||
"1282-\u7559\u62b5\u7a05\u984d": {},
|
||||
"1283-\u66ab\u4ed8\u6b3e": {},
|
||||
"1284-\u4ee3\u4ed8\u6b3e": {},
|
||||
"1285-\u54e1\u5de5\u501f\u652f": {}
|
||||
}
|
||||
},
|
||||
"13-\u57fa\u91d1\u53ca\u9577\u671f\u6295\u8cc7": {
|
||||
"131-\u57fa\u91d1": {
|
||||
"1311-\u511f\u50b5\u57fa\u91d1": {},
|
||||
"1313-\u610f\u5916\u640d\u5931\u6e96\u5099\u57fa\u91d1": {},
|
||||
"1314-\u9000\u4f11\u57fa\u91d1": {},
|
||||
"1318-\u5176\u4ed6\u57fa\u91d1": {}
|
||||
},
|
||||
"132-\u9577\u671f\u6295\u8cc7": {
|
||||
"1321-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7": {},
|
||||
"1322-\u9577\u671f\u50b5\u5238\u6295\u8cc7": {},
|
||||
"1323-\u9577\u671f\u4e0d\u52d5\u7522\u6295\u8cc7": {},
|
||||
"1328-\u5176\u4ed6\u9577\u671f\u6295\u8cc7": {}
|
||||
}
|
||||
},
|
||||
"14~15-\u56fa\u5b9a\u8cc7\u7522": {
|
||||
"141-\u571f\u5730": {
|
||||
"1411-\u571f\u5730": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"142-\u571f\u5730\u6539\u826f\u7269": {
|
||||
"1421-\u571f\u5730\u6539\u826f\u7269": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"143-\u623f\u5c4b\u53ca\u5efa\u7269": {
|
||||
"1431-\u623f\u5c4b\u53ca\u5efa\u7269": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"144~146-\u6a5f(\u5668)\u5177\u53ca\u8a2d\u5099": {
|
||||
"1441-\u6a5f(\u5668)\u5177": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"151-\u79df\u8cc3\u8cc7\u7522": {
|
||||
"1511-\u79df\u8cc3\u8cc7\u7522": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"152-\u79df\u8cc3\u6b0a\u76ca\u6539\u826f": {
|
||||
"1521-\u79df\u8cc3\u6b0a\u76ca\u6539\u826f": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"156-\u672a\u5b8c\u5de5\u7a0b\u53ca\u9810\u4ed8\u8cfc\u7f6e\u8a2d\u5099\u6b3e": {
|
||||
"1561-\u672a\u5b8c\u5de5\u7a0b": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"158-\u96dc\u9805\u56fa\u5b9a\u8cc7\u7522": {
|
||||
"1581-\u96dc\u9805\u56fa\u5b9a\u8cc7\u7522": {
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"account_type": "Fixed Asset"
|
||||
},
|
||||
"16-\u905e\u8017\u8cc7\u7522": {
|
||||
"161-\u905e\u8017\u8cc7\u7522": {
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"17-\u7121\u5f62\u8cc7\u7522": {
|
||||
"171-\u5546\u6a19\u6b0a": {
|
||||
"1711-\u5546\u6a19\u6b0a": {}
|
||||
},
|
||||
"172-\u5c08\u5229\u6b0a": {
|
||||
"1721-\u5c08\u5229\u6b0a": {}
|
||||
},
|
||||
"176-\u5546\u8b7d": {
|
||||
"1761-\u5546\u8b7d": {}
|
||||
},
|
||||
"177-\u958b\u8fa6\u8cbb": {
|
||||
"1771-\u958b\u8fa6\u8cbb": {}
|
||||
},
|
||||
"178-\u5176\u4ed6\u7121\u5f62\u8cc7\u7522": {
|
||||
"1781-\u905e\u5ef6\u9000\u4f11\u91d1\u6210\u672c": {}
|
||||
}
|
||||
},
|
||||
"18-\u5176\u4ed6\u8cc7\u7522": {
|
||||
"181-\u905e\u5ef6\u8cc7\u7522": {
|
||||
"1811-\u50b5\u5238\u767c\u884c\u6210\u672c": {},
|
||||
"1812-\u9577\u671f\u9810\u4ed8\u79df\u91d1": {},
|
||||
"1813-\u9577\u671f\u9810\u4ed8\u4fdd\u96aa\u8cbb": {},
|
||||
"1814-\u905e\u5ef6\u6240\u5f97\u7a05\u8cc7\u7522": {},
|
||||
"1815-\u9810\u4ed8\u9000\u4f11\u91d1": {},
|
||||
"1818-\u5176\u4ed6\u905e\u5ef6\u8cc7\u7522": {}
|
||||
},
|
||||
"182-\u9592\u7f6e\u8cc7\u7522": {
|
||||
"1821-\u9592\u7f6e\u8cc7\u7522": {}
|
||||
},
|
||||
"184-\u9577\u671f\u61c9\u6536\u7968\u64da\u53ca\u6b3e\u9805\u8207\u50ac\u6536\u5e33\u6b3e": {
|
||||
"1841-\u9577\u671f\u61c9\u6536\u7968\u64da": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1842-\u9577\u671f\u61c9\u6536\u5e33\u6b3e": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1843-\u50ac\u6536\u5e33\u6b3e": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1848-\u5176\u4ed6\u9577\u671f\u61c9\u6536\u6b3e\u9805": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"1849-\u5099\u62b5\u5446\u5e33\u2014\u9577\u671f\u61c9\u6536\u7968\u64da\u53ca\u6b3e\u9805\u8207\u50ac\u6536\u5e33\u6b3e": {
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"account_type": "Receivable"
|
||||
},
|
||||
"185-\u51fa\u79df\u8cc7\u7522": {
|
||||
"1851-\u51fa\u79df\u8cc7\u7522": {},
|
||||
"1858-\u51fa\u79df\u8cc7\u7522 \u2014\u91cd\u4f30\u589e\u503c": {},
|
||||
"1859-\u7d2f\u7a4d\u6298\u820a \u2014\u51fa\u79df\u8cc7\u7522": {
|
||||
"account_type": "Accumulated Depreciation"
|
||||
}
|
||||
},
|
||||
"186-\u5b58\u51fa\u4fdd\u8b49\u91d1": {
|
||||
"1861-\u5b58\u51fa\u4fdd\u8b49\u91d1": {}
|
||||
},
|
||||
"188-\u96dc\u9805\u8cc7\u7522": {
|
||||
"1881-\u53d7\u9650\u5236\u5b58\u6b3e": {},
|
||||
"1888-\u96dc\u9805\u8cc7\u7522 \u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"Temporary Accounts": {
|
||||
"Temporary Opening": {
|
||||
"account_type": "Temporary"
|
||||
},
|
||||
"account_type": "Temporary"
|
||||
},
|
||||
"root_type": "Asset"
|
||||
},
|
||||
"2-\u8ca0\u50b5": {
|
||||
"21~22-\u6d41\u52d5\u8ca0\u50b5": {
|
||||
"211-\u77ed\u671f\u501f\u6b3e": {
|
||||
"2111-\u9280\u884c\u900f\u652f": {},
|
||||
"2112-\u9280\u884c\u501f\u6b3e": {}
|
||||
},
|
||||
"212-\u61c9\u4ed8\u77ed\u671f\u7968\u5238": {
|
||||
"2121-\u61c9\u4ed8\u5546\u696d\u672c\u7968": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"2122-\u9280\u884c\u627f\u514c\u532f\u7968": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"213-\u61c9\u4ed8\u7968\u64da": {
|
||||
"2131-\u61c9\u4ed8\u7968\u64da": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"214-\u61c9\u4ed8\u5e33\u6b3e": {
|
||||
"2141-\u61c9\u4ed8\u5e33\u6b3e": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"216-\u61c9\u4ed8\u6240\u5f97\u7a05": {
|
||||
"2161-\u61c9\u4ed8\u6240\u5f97\u7a05": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"217-\u61c9\u4ed8\u8cbb\u7528": {
|
||||
"2171-\u61c9\u4ed8\u85aa\u5de5": {},
|
||||
"2172-\u61c9\u4ed8\u79df\u91d1": {},
|
||||
"2173-\u61c9\u4ed8\u5229\u606f": {},
|
||||
"2174-\u61c9\u4ed8\u71df\u696d\u7a05": {},
|
||||
"2175-\u61c9\u4ed8\u7a05\u6350 \u2014\u5176\u4ed6": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"2178-\u5176\u4ed6\u61c9\u4ed8\u8cbb\u7528": {}
|
||||
},
|
||||
"218~219-\u5176\u4ed6\u61c9\u4ed8\u6b3e": {
|
||||
"2184-\u61c9\u4ed8\u571f\u5730\u623f\u5c4b\u6b3e": {},
|
||||
"2185-\u61c9\u4ed8\u8a2d\u5099\u6b3e": {},
|
||||
"2192-\u61c9\u4ed8\u80a1\u5229": {}
|
||||
},
|
||||
"226-\u9810\u6536\u6b3e\u9805": {
|
||||
"2261-\u9810\u6536\u8ca8\u6b3e": {},
|
||||
"2262-\u9810\u6536\u6536\u5165": {},
|
||||
"2268-\u5176\u4ed6\u9810\u6536\u6b3e": {}
|
||||
},
|
||||
"227-\u4e00\u5e74\u6216\u4e00\u71df\u696d\u9031\u671f\u5167\u5230\u671f\u9577\u671f\u8ca0\u50b5": {
|
||||
"is_group": 1
|
||||
},
|
||||
"228~229-\u5176\u4ed6\u6d41\u52d5\u8ca0\u50b5": {
|
||||
"2281-\u92b7\u9805\u7a05\u984d": {},
|
||||
"2283-\u66ab\u6536\u6b3e ": {},
|
||||
"2284-\u4ee3\u6536\u6b3e": {},
|
||||
"2285-\u4f30\u8a08\u552e\u5f8c\u670d\u52d9/\u4fdd\u56fa\u8ca0\u50b5": {},
|
||||
"2291-\u905e\u5ef6\u6240\u5f97\u7a05\u8ca0\u50b5": {},
|
||||
"2292-\u905e\u5ef6\u514c\u63db\u5229\u76ca": {}
|
||||
}
|
||||
},
|
||||
"23-\u9577\u671f\u8ca0\u50b5": {
|
||||
"231-\u61c9\u4ed8\u516c\u53f8\u50b5": {
|
||||
"2311-\u61c9\u4ed8\u516c\u53f8\u50b5": {},
|
||||
"2319-\u61c9\u4ed8\u516c\u53f8\u50b5\u6ea2(\u6298)\u50f9": {}
|
||||
},
|
||||
"232-\u9577\u671f\u501f\u6b3e": {
|
||||
"2321-\u9577\u671f\u9280\u884c\u501f\u6b3e": {},
|
||||
"2324-\u9577\u671f\u501f\u6b3e \u2014\u696d\u4e3b": {},
|
||||
"2325-\u9577\u671f\u501f\u6b3e \u2014\u54e1\u5de5": {},
|
||||
"2327-\u9577\u671f\u501f\u6b3e \u2014\u95dc\u4fc2\u4eba": {},
|
||||
"2328-\u9577\u671f\u501f\u6b3e \u2014\u5176\u4ed6": {}
|
||||
},
|
||||
"233-\u9577\u671f\u61c9\u4ed8\u7968\u64da\u53ca\u6b3e\u9805": {
|
||||
"2331-\u9577\u671f\u61c9\u4ed8\u7968\u64da": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"2332-\u9577\u671f\u61c9\u4ed8\u5e33\u6b3e": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"2333-\u9577\u671f\u61c9\u4ed8\u79df\u8cc3\u8ca0\u50b5": {
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"account_type": "Payable"
|
||||
},
|
||||
"234-\u4f30\u8a08\u61c9\u4ed8\u571f\u5730\u589e\u503c\u7a05": {
|
||||
"2341-\u4f30\u8a08\u61c9\u4ed8\u571f\u5730\u589e\u503c\u7a05": {}
|
||||
},
|
||||
"235-\u61c9\u8a08\u9000\u4f11\u91d1\u8ca0\u50b5": {
|
||||
"2351-\u61c9\u8a08\u9000\u4f11\u91d1\u8ca0\u50b5": {}
|
||||
},
|
||||
"238-\u5176\u4ed6\u9577\u671f\u8ca0\u50b5": {
|
||||
"2388-\u5176\u4ed6\u9577\u671f\u8ca0\u50b5\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"28-\u5176\u4ed6\u8ca0\u50b5": {
|
||||
"281-\u905e\u5ef6\u8ca0\u50b5": {
|
||||
"2811-\u905e\u5ef6\u6536\u5165": {},
|
||||
"2814-\u905e\u5ef6\u6240\u5f97\u7a05\u8ca0\u50b5": {},
|
||||
"2818-\u5176\u4ed6\u905e\u5ef6\u8ca0\u50b5": {}
|
||||
},
|
||||
"286-\u5b58\u5165\u4fdd\u8b49\u91d1": {
|
||||
"2861-\u5b58\u5165\u4fdd\u8b49\u91d1": {}
|
||||
},
|
||||
"288-\u96dc\u9805\u8ca0\u50b5": {
|
||||
"2888-\u96dc\u9805\u8ca0\u50b5 \u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"Stock Received But Not Billed": {
|
||||
"account_type": "Stock Received But Not Billed"
|
||||
},
|
||||
"root_type": "Liability"
|
||||
},
|
||||
"3-\u696d\u4e3b\u6b0a\u76ca": {
|
||||
"31-\u8cc7\u672c": {
|
||||
"311-\u8cc7\u672c\uff08\u80a1\u672c\uff09 ": {
|
||||
"3111-\u666e\u901a\u80a1\u80a1\u672c": {},
|
||||
"3112-\u7279\u5225\u80a1\u80a1\u672c": {},
|
||||
"3113-\u9810\u6536\u80a1\u672c": {},
|
||||
"3114-\u5f85\u5206\u914d\u80a1\u7968\u80a1\u5229": {},
|
||||
"3115-\u8cc7\u672c": {}
|
||||
}
|
||||
},
|
||||
"32-\u8cc7\u672c\u516c\u7a4d": {
|
||||
"321-\u80a1\u7968\u6ea2\u50f9": {
|
||||
"3211-\u666e\u901a\u80a1\u80a1\u7968\u6ea2\u50f9": {},
|
||||
"3212-\u7279\u5225\u80a1\u80a1\u7968\u6ea2\u50f9": {}
|
||||
},
|
||||
"323-\u8cc7\u7522\u91cd\u4f30\u589e\u503c\u6e96\u5099": {
|
||||
"3231-\u8cc7\u7522\u91cd\u4f30\u589e\u503c\u6e96\u5099": {}
|
||||
},
|
||||
"324-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u516c\u7a4d": {
|
||||
"3241-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u516c\u7a4d": {}
|
||||
},
|
||||
"325-\u5408\u4f75\u516c\u7a4d": {
|
||||
"3251-\u5408\u4f75\u516c\u7a4d": {}
|
||||
},
|
||||
"326-\u53d7\u8d08\u516c\u7a4d": {
|
||||
"3261-\u53d7\u8d08\u516c\u7a4d": {}
|
||||
},
|
||||
"328-\u5176\u4ed6\u8cc7\u672c\u516c\u7a4d": {
|
||||
"3281-\u6b0a\u76ca\u6cd5\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u8cc7\u672c\u516c\u7a4d": {},
|
||||
"3282-\u8cc7\u672c\u516c\u7a4d\u2014 \u5eab\u85cf\u80a1\u7968\u4ea4\u6613": {}
|
||||
}
|
||||
},
|
||||
"33-\u4fdd\u7559\u76c8\u9918(\u7d2f\u7a4d\u8667\u640d)": {
|
||||
"331-\u6cd5\u5b9a\u76c8\u9918\u516c\u7a4d": {
|
||||
"3311-\u6cd5\u5b9a\u76c8\u9918\u516c\u7a4d": {}
|
||||
},
|
||||
"332-\u7279\u5225\u76c8\u9918\u516c\u7a4d": {
|
||||
"3321-\u610f\u5916\u640d\u5931\u6e96\u5099": {},
|
||||
"3322-\u6539\u826f\u64f4\u5145\u6e96\u5099": {},
|
||||
"3323-\u511f\u50b5\u6e96\u5099": {},
|
||||
"3328-\u5176\u4ed6\u7279\u5225\u76c8\u9918\u516c\u7a4d": {}
|
||||
},
|
||||
"335-\u672a\u5206\u914d\u76c8\u9918(\u7d2f\u7a4d\u8667\u640d) ": {
|
||||
"is_group": 1
|
||||
}
|
||||
},
|
||||
"34-\u6b0a\u76ca\u8abf\u6574": {
|
||||
"341-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {
|
||||
"3411-\u9577\u671f\u80a1\u6b0a\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {}
|
||||
},
|
||||
"342-\u7d2f\u7a4d\u63db\u7b97\u8abf\u6574\u6578": {
|
||||
"3421-\u7d2f\u7a4d\u63db\u7b97\u8abf\u6574\u6578": {}
|
||||
},
|
||||
"343-\u672a\u8a8d\u5217\u70ba\u9000\u4f11\u91d1\u6210\u672c\u4e4b\u6de8\u640d\u5931": {
|
||||
"3431-\u672a\u8a8d\u5217\u70ba\u9000\u4f11\u91d1\u6210\u672c\u4e4b\u6de8\u640d\u5931": {}
|
||||
}
|
||||
},
|
||||
"35-\u5eab\u85cf\u80a1": {
|
||||
"351-\u5eab\u85cf\u80a1": {
|
||||
"3511-\u5eab\u85cf\u80a1": {}
|
||||
}
|
||||
},
|
||||
"36-\u5c11\u6578\u80a1\u6b0a": {
|
||||
"361-\u5c11\u6578\u80a1\u6b0a": {
|
||||
"3611-\u5c11\u6578\u80a1\u6b0a": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Equity"
|
||||
},
|
||||
"4-\u71df\u696d\u6536\u5165": {
|
||||
"41-\u92b7\u8ca8\u6536\u5165": {
|
||||
"411-\u92b7\u8ca8\u6536\u5165": {
|
||||
"4111-\u92b7\u8ca8\u6536\u5165": {},
|
||||
"4112-\u5206\u671f\u4ed8\u6b3e\u92b7\u8ca8\u6536\u5165": {}
|
||||
},
|
||||
"417-\u92b7\u8ca8\u9000\u56de": {
|
||||
"4171-\u92b7\u8ca8\u9000\u56de": {}
|
||||
},
|
||||
"419-\u92b7\u8ca8\u6298\u8b93": {
|
||||
"4191-\u92b7\u8ca8\u6298\u8b93": {}
|
||||
}
|
||||
},
|
||||
"46-\u52de\u52d9\u6536\u5165": {
|
||||
"461-\u52de\u52d9\u6536\u5165": {
|
||||
"4611-\u52de\u52d9\u6536\u5165": {}
|
||||
}
|
||||
},
|
||||
"47-\u696d\u52d9\u6536\u5165": {
|
||||
"471-\u696d\u52d9\u6536\u5165": {
|
||||
"4711-\u696d\u52d9\u6536\u5165": {}
|
||||
}
|
||||
},
|
||||
"48-\u5176\u4ed6\u71df\u696d\u6536\u5165": {
|
||||
"488-\u5176\u4ed6\u71df\u696d\u6536\u5165\u2014\u5176\u4ed6": {
|
||||
"4888-\u5176\u4ed6\u71df\u696d\u6536\u5165\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"5-\u71df\u696d\u6210\u672c": {
|
||||
"51-\u92b7\u8ca8\u6210\u672c": {
|
||||
"511-\u92b7\u8ca8\u6210\u672c": {
|
||||
"5111-\u92b7\u8ca8\u6210\u672c": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"5112-\u5206\u671f\u4ed8\u6b3e\u92b7\u8ca8\u6210\u672c": {
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"512-\u9032\u8ca8": {
|
||||
"5121-\u9032\u8ca8": {},
|
||||
"5122-\u9032\u8ca8\u8cbb\u7528": {},
|
||||
"5123-\u9032\u8ca8\u9000\u51fa": {},
|
||||
"5124-\u9032\u8ca8\u6298\u8b93": {}
|
||||
},
|
||||
"513-\u9032\u6599": {
|
||||
"5131-\u9032\u6599": {},
|
||||
"5132-\u9032\u6599\u8cbb\u7528": {},
|
||||
"5133-\u9032\u6599\u9000\u51fa": {},
|
||||
"5134-\u9032\u6599\u6298\u8b93": {}
|
||||
},
|
||||
"514-\u76f4\u63a5\u4eba\u5de5": {
|
||||
"5141-\u76f4\u63a5\u4eba\u5de5": {}
|
||||
},
|
||||
"515~518-\u88fd\u9020\u8cbb\u7528": {
|
||||
"5151-\u9593\u63a5\u4eba\u5de5": {},
|
||||
"5152-\u79df\u91d1\u652f\u51fa": {},
|
||||
"5153-\u6587\u5177\u7528\u54c1": {},
|
||||
"5154-\u65c5\u8cbb": {},
|
||||
"5155-\u904b\u8cbb": {},
|
||||
"5156-\u90f5\u96fb\u8cbb": {},
|
||||
"5157-\u4fee\u7e55\u8cbb": {},
|
||||
"5158-\u5305\u88dd\u8cbb": {},
|
||||
"5161-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
|
||||
"5162-\u4fdd\u96aa\u8cbb": {},
|
||||
"5163-\u52a0\u5de5\u8cbb": {},
|
||||
"5166-\u7a05\u6350": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"5168-\u6298\u820a ": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"5169-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
|
||||
"5172-\u4f19\u98df\u8cbb": {},
|
||||
"5173-\u8077\u5de5\u798f\u5229": {},
|
||||
"5176-\u8a13\u7df4\u8cbb": {},
|
||||
"5177-\u9593\u63a5\u6750\u6599": {},
|
||||
"5188-\u5176\u4ed6\u88fd\u9020\u8cbb\u7528": {}
|
||||
},
|
||||
"Expenses Included In Valuation": {
|
||||
"account_type": "Expenses Included In Valuation"
|
||||
},
|
||||
"account_type": "Cost of Goods Sold"
|
||||
},
|
||||
"56-\u52de\u52d9\u6210\u672c\u88fd": {
|
||||
"561-\u52de\u52d9\u6210\u672c": {
|
||||
"5611-\u52de\u52d9\u6210\u672c": {}
|
||||
}
|
||||
},
|
||||
"57-\u696d\u52d9\u6210\u672c": {
|
||||
"571-\u696d\u52d9\u6210\u672c": {
|
||||
"5711-\u696d\u52d9\u6210\u672c": {}
|
||||
}
|
||||
},
|
||||
"58-\u5176\u4ed6\u71df\u696d\u6210\u672c": {
|
||||
"588-\u5176\u4ed6\u71df\u696d\u6210\u672c\u2014\u5176\u4ed6 ": {
|
||||
"5888-\u5176\u4ed6\u71df\u696d\u6210\u672c\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"Stock Adjustment": {
|
||||
"account_type": "Stock Adjustment"
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"6-\u71df\u696d\u8cbb\u7528": {
|
||||
"61-\u63a8\u92b7\u8cbb\u7528": {
|
||||
"615~618-\u63a8\u92b7\u8cbb\u7528": {
|
||||
"6151-\u85aa\u8cc7\u652f\u51fa": {},
|
||||
"6152-\u79df\u91d1\u652f\u51fa": {},
|
||||
"6153-\u6587\u5177\u7528\u54c1": {},
|
||||
"6154-\u65c5\u8cbb": {},
|
||||
"6155-\u904b\u8cbb": {},
|
||||
"6156-\u90f5\u96fb\u8cbb": {},
|
||||
"6157-\u4fee\u7e55\u8cbb": {},
|
||||
"6159-\u5ee3\u544a\u8cbb": {},
|
||||
"6161-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
|
||||
"6162-\u4fdd\u96aa\u8cbb": {},
|
||||
"6164-\u4ea4\u969b\u8cbb": {},
|
||||
"6165-\u6350\u8d08": {},
|
||||
"6166-\u7a05\u6350": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"6167-\u5446\u5e33\u640d\u5931": {},
|
||||
"6168-\u6298\u820a ": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"6169-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
|
||||
"6172-\u4f19\u98df\u8cbb": {},
|
||||
"6173-\u8077\u5de5\u798f\u5229": {},
|
||||
"6175-\u4f63\u91d1\u652f\u51fa": {},
|
||||
"6176-\u8a13\u7df4\u8cbb": {},
|
||||
"6188-\u5176\u4ed6\u63a8\u92b7\u8cbb\u7528": {}
|
||||
}
|
||||
},
|
||||
"62-\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {
|
||||
"625~628-\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {
|
||||
"6251-\u85aa\u8cc7\u652f\u51fa": {},
|
||||
"6252-\u79df\u91d1\u652f\u51fa": {},
|
||||
"6253-\u6587\u5177\u7528\u54c1": {},
|
||||
"6254-\u65c5\u8cbb": {},
|
||||
"6255-\u904b\u8cbb": {},
|
||||
"6256-\u90f5\u96fb\u8cbb": {},
|
||||
"6257-\u4fee\u7e55\u8cbb": {},
|
||||
"6259-\u5ee3\u544a\u8cbb": {},
|
||||
"6261-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
|
||||
"6262-\u4fdd\u96aa\u8cbb": {},
|
||||
"6264-\u4ea4\u969b\u8cbb": {},
|
||||
"6265-\u6350\u8d08": {},
|
||||
"6266-\u7a05\u6350": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"6267-\u5446\u5e33\u640d\u5931": {},
|
||||
"6268-\u6298\u820a": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"6269-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
|
||||
"6271-\u5916\u92b7\u640d\u5931": {},
|
||||
"6272-\u4f19\u98df\u8cbb": {},
|
||||
"6273-\u8077\u5de5\u798f\u5229": {},
|
||||
"6274-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {},
|
||||
"6275-\u4f63\u91d1\u652f\u51fa": {},
|
||||
"6276-\u8a13\u7df4\u8cbb": {},
|
||||
"6278-\u52de\u52d9\u8cbb": {},
|
||||
"6288-\u5176\u4ed6\u7ba1\u7406\u53ca\u7e3d\u52d9\u8cbb\u7528": {}
|
||||
}
|
||||
},
|
||||
"63-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {
|
||||
"635~638-\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {
|
||||
"6351-\u85aa\u8cc7\u652f\u51fa": {},
|
||||
"6352-\u79df\u91d1\u652f\u51fa": {},
|
||||
"6353-\u6587\u5177\u7528\u54c1": {},
|
||||
"6354-\u65c5\u8cbb": {},
|
||||
"6355-\u904b\u8cbb": {},
|
||||
"6356-\u90f5\u96fb\u8cbb": {},
|
||||
"6357-\u4fee\u7e55\u8cbb": {},
|
||||
"6361-\u6c34\u96fb\u74e6\u65af\u8cbb": {},
|
||||
"6362-\u4fdd\u96aa\u8cbb": {},
|
||||
"6364-\u4ea4\u969b\u8cbb": {},
|
||||
"6366-\u7a05\u6350": {
|
||||
"account_type": "Tax",
|
||||
"tax_rate": 5.0
|
||||
},
|
||||
"6368-\u6298\u820a": {
|
||||
"account_type": "Depreciation"
|
||||
},
|
||||
"6369-\u5404\u9805\u8017\u7aed\u53ca\u6524\u63d0": {},
|
||||
"6372-\u4f19\u98df\u8cbb": {},
|
||||
"6373-\u8077\u5de5\u798f\u5229": {},
|
||||
"6376-\u8a13\u7df4\u8cbb": {},
|
||||
"6378-\u5176\u4ed6\u7814\u7a76\u767c\u5c55\u8cbb\u7528": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"7-\u71df\u696d\u5916\u6536\u5165\u53ca\u8cbb\u7528": {
|
||||
"71~74-\u71df\u696d\u5916\u6536\u5165": {
|
||||
"711-\u5229\u606f\u6536\u5165": {
|
||||
"7111-\u5229\u606f\u6536\u5165": {}
|
||||
},
|
||||
"712-\u6295\u8cc7\u6536\u76ca": {
|
||||
"7121-\u6b0a\u76ca\u6cd5\u8a8d\u5217\u4e4b\u6295\u8cc7\u6536\u76ca": {},
|
||||
"7122-\u80a1\u5229\u6536\u5165": {},
|
||||
"7123-\u77ed\u671f\u6295\u8cc7\u5e02\u50f9\u56de\u5347\u5229\u76ca": {}
|
||||
},
|
||||
"713-\u514c\u63db\u5229\u76ca": {
|
||||
"7131-\u514c\u63db\u5229\u76ca": {}
|
||||
},
|
||||
"714-\u8655\u5206\u6295\u8cc7\u6536\u76ca": {
|
||||
"7141-\u8655\u5206\u6295\u8cc7\u6536\u76ca": {}
|
||||
},
|
||||
"715-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u6536\u5165": {
|
||||
"7151-\u8655\u5206\u8cc7\u7522\u6ea2\u50f9\u6536\u5165": {}
|
||||
},
|
||||
"748-\u5176\u4ed6\u71df\u696d\u5916\u6536\u5165": {
|
||||
"7481-\u6350\u8d08\u6536\u5165": {},
|
||||
"7482-\u79df\u91d1\u6536\u5165": {},
|
||||
"7483-\u4f63\u91d1\u6536\u5165": {},
|
||||
"7484-\u51fa\u552e\u4e0b\u8173\u53ca\u5ee2\u6599\u6536\u5165": {},
|
||||
"7485-\u5b58\u8ca8\u76e4\u76c8": {},
|
||||
"7486-\u5b58\u8ca8\u8dcc\u50f9\u56de\u5347\u5229\u76ca": {},
|
||||
"7487-\u58de\u5e33\u8f49\u56de\u5229\u76ca": {},
|
||||
"7488-\u5176\u4ed6\u71df\u696d\u5916\u6536\u5165\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"75~78-\u71df\u696d\u5916\u8cbb\u7528": {
|
||||
"751-\u5229\u606f\u8cbb\u7528": {
|
||||
"7511-\u5229\u606f\u8cbb\u7528": {}
|
||||
},
|
||||
"752-\u6295\u8cc7\u640d\u5931": {
|
||||
"7521-\u6b0a\u76ca\u6cd5\u8a8d\u5217\u4e4b\u6295\u8cc7\u640d\u5931": {},
|
||||
"7523-\u77ed\u671f\u6295\u8cc7\u672a\u5be6\u73fe\u8dcc\u50f9\u640d\u5931": {}
|
||||
},
|
||||
"753-\u514c\u63db\u640d\u5931": {
|
||||
"7531-\u514c\u63db\u640d\u5931": {}
|
||||
},
|
||||
"754-\u8655\u5206\u6295\u8cc7\u640d\u5931": {
|
||||
"7541-\u8655\u5206\u6295\u8cc7\u640d\u5931": {}
|
||||
},
|
||||
"755-\u8655\u5206\u8cc7\u7522\u640d\u5931": {
|
||||
"7551-\u8655\u5206\u8cc7\u7522\u640d\u5931 ": {}
|
||||
},
|
||||
"788-\u5176\u4ed6\u71df\u696d\u5916\u8cbb\u7528": {
|
||||
"7881-\u505c\u5de5\u640d\u5931": {},
|
||||
"7882-\u707d\u5bb3\u640d\u5931": {},
|
||||
"7885-\u5b58\u8ca8\u76e4\u640d": {},
|
||||
"7886-\u5b58\u8ca8\u8dcc\u50f9\u53ca\u5446\u6eef\u640d\u5931": {},
|
||||
"7888-\u5176\u4ed6\u71df\u696d\u5916\u8cbb\u7528\u2014\u5176\u4ed6": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Income"
|
||||
},
|
||||
"8-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca)": {
|
||||
"81-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca)": {
|
||||
"811-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca) ": {
|
||||
"8111-\u6240\u5f97\u7a05\u8cbb\u7528(\u5229\u76ca) ": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
},
|
||||
"9-\u975e\u7d93\u5e38\u71df\u696d\u640d\u76ca": {
|
||||
"91-\u505c\u696d\u90e8\u9580\u640d\u76ca": {
|
||||
"911-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u505c\u696d\u524d\u71df\u696d\u640d\u76ca": {
|
||||
"9111-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u505c\u696d\u524d\u71df\u696d\u640d\u76ca": {}
|
||||
},
|
||||
"912-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u8655\u5206\u640d\u76ca": {
|
||||
"9121-\u505c\u696d\u90e8\u9580\u640d\u76ca\u2014\u8655\u5206\u640d\u76ca": {}
|
||||
}
|
||||
},
|
||||
"92-\u975e\u5e38\u640d\u76ca": {
|
||||
"921-\u975e\u5e38\u640d\u76ca": {
|
||||
"9211-\u975e\u5e38\u640d\u76ca": {}
|
||||
}
|
||||
},
|
||||
"93-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {
|
||||
"931-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {
|
||||
"9311-\u6703\u8a08\u539f\u5247\u8b8a\u52d5\u7d2f\u7a4d\u5f71\u97ff\u6578": {}
|
||||
}
|
||||
},
|
||||
"94-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {
|
||||
"941-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {
|
||||
"9411-\u5c11\u6578\u80a1\u6b0a\u6de8\u5229": {}
|
||||
}
|
||||
},
|
||||
"root_type": "Expense"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,9 @@ QUnit.test("test account", function(assert) {
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => frappe.set_route('Tree', 'Account'),
|
||||
() => frappe.timeout(3),
|
||||
() => frappe.click_button('Expand All'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Debtors'),
|
||||
() => frappe.click_button('Edit'),
|
||||
() => frappe.timeout(1),
|
||||
|
||||
46
erpnext/accounts/doctype/account/test_make_tax_account.js
Normal file
46
erpnext/accounts/doctype/account/test_make_tax_account.js
Normal file
@@ -0,0 +1,46 @@
|
||||
QUnit.module('accounts');
|
||||
QUnit.test("test account", assert => {
|
||||
assert.expect(3);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => frappe.set_route('Tree', 'Account'),
|
||||
() => frappe.click_button('Expand All'),
|
||||
() => frappe.click_link('Duties and Taxes - '+ frappe.get_abbr(frappe.defaults.get_default("Company"))),
|
||||
() => {
|
||||
if($('a:contains("CGST"):visible').length == 0){
|
||||
return frappe.map_tax.make('CGST', 9);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
if($('a:contains("SGST"):visible').length == 0){
|
||||
return frappe.map_tax.make('SGST', 9);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
if($('a:contains("IGST"):visible').length == 0){
|
||||
return frappe.map_tax.make('IGST', 18);
|
||||
}
|
||||
},
|
||||
() => {
|
||||
assert.ok($('a:contains("CGST"):visible').length!=0, "CGST Checked");
|
||||
assert.ok($('a:contains("SGST"):visible').length!=0, "SGST Checked");
|
||||
assert.ok($('a:contains("IGST"):visible').length!=0, "IGST Checked");
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
|
||||
frappe.map_tax = {
|
||||
make:function(text,rate){
|
||||
return frappe.run_serially([
|
||||
() => frappe.click_button('Add Child'),
|
||||
() => frappe.timeout(0.2),
|
||||
() => cur_dialog.set_value('account_name',text),
|
||||
() => cur_dialog.set_value('account_type','Tax'),
|
||||
() => cur_dialog.set_value('tax_rate',rate),
|
||||
() => cur_dialog.set_value('account_currency','INR'),
|
||||
() => frappe.click_button('Create New'),
|
||||
]);
|
||||
}
|
||||
};
|
||||
@@ -286,6 +286,99 @@
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "currency_exchange_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Currency Exchange Settings",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"fieldname": "allow_stale",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Allow Stale Exchange Rates",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "1",
|
||||
"depends_on": "eval:doc.allow_stale==0",
|
||||
"fieldname": "stale_days",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Stale Days",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
@@ -299,7 +392,7 @@
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-16 17:39:50.614522",
|
||||
"modified": "2017-09-05 10:10:03.117505",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Accounts Settings",
|
||||
@@ -324,6 +417,46 @@
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Sales User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 0,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 0,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Purchase User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 0,
|
||||
"submit": 0,
|
||||
"write": 0
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
@@ -333,4 +466,4 @@
|
||||
"sort_order": "ASC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,10 +5,20 @@
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe import _
|
||||
from frappe.utils import cint, comma_and
|
||||
from frappe.utils import cint
|
||||
from frappe.model.document import Document
|
||||
|
||||
|
||||
class AccountsSettings(Document):
|
||||
def on_update(self):
|
||||
pass
|
||||
pass
|
||||
|
||||
def validate(self):
|
||||
self.validate_stale_days()
|
||||
|
||||
def validate_stale_days(self):
|
||||
if not self.allow_stale and cint(self.stale_days) <= 0:
|
||||
frappe.msgprint(
|
||||
"Stale Days should start from 1.", title='Error', indicator='red',
|
||||
raise_exception=1)
|
||||
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
QUnit.module('accounts');
|
||||
|
||||
QUnit.test("test: Accounts Settings doesn't allow negatives", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
assert.expect(2);
|
||||
|
||||
frappe.run_serially([
|
||||
() => frappe.set_route('Form', 'Accounts Settings', 'Accounts Settings'),
|
||||
() => frappe.timeout(2),
|
||||
() => unchecked_if_checked(cur_frm, 'Allow Stale Exchange Rates', frappe.click_check),
|
||||
() => cur_frm.set_value('stale_days', 0),
|
||||
() => frappe.click_button('Save'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.ok(cur_dialog);
|
||||
},
|
||||
() => frappe.click_button('Close'),
|
||||
() => cur_frm.set_value('stale_days', -1),
|
||||
() => frappe.click_button('Save'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.ok(cur_dialog);
|
||||
},
|
||||
() => frappe.click_button('Close'),
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
|
||||
const unchecked_if_checked = function(frm, field_name, fn){
|
||||
if (frm.doc.allow_stale) {
|
||||
return fn(field_name);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
import unittest
|
||||
|
||||
import frappe
|
||||
|
||||
|
||||
class TestAccountsSettings(unittest.TestCase):
|
||||
def tearDown(self):
|
||||
# Just in case `save` method succeeds, we need to take things back to default so that other tests
|
||||
# don't break
|
||||
cur_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
|
||||
cur_settings.allow_stale = 1
|
||||
cur_settings.save()
|
||||
|
||||
def test_stale_days(self):
|
||||
cur_settings = frappe.get_doc('Accounts Settings', 'Accounts Settings')
|
||||
cur_settings.allow_stale = 0
|
||||
cur_settings.stale_days = 0
|
||||
|
||||
self.assertRaises(frappe.ValidationError, cur_settings.save)
|
||||
|
||||
cur_settings.stale_days = -1
|
||||
self.assertRaises(frappe.ValidationError, cur_settings.save)
|
||||
@@ -55,13 +55,13 @@ frappe.ui.form.on('Asset', {
|
||||
});
|
||||
}
|
||||
|
||||
frm.trigger("show_graph");
|
||||
frm.trigger("setup_chart");
|
||||
}
|
||||
},
|
||||
|
||||
show_graph: function(frm) {
|
||||
var x_intervals = ["x", frm.doc.purchase_date];
|
||||
var asset_values = ["Asset Value", frm.doc.gross_purchase_amount];
|
||||
setup_chart: function(frm) {
|
||||
var x_intervals = [frm.doc.purchase_date];
|
||||
var asset_values = [frm.doc.gross_purchase_amount];
|
||||
var last_depreciation_date = frm.doc.purchase_date;
|
||||
|
||||
if(frm.doc.opening_accumulated_depreciation) {
|
||||
@@ -94,32 +94,21 @@ frappe.ui.form.on('Asset', {
|
||||
last_depreciation_date = frm.doc.disposal_date;
|
||||
}
|
||||
|
||||
frm.dashboard.setup_chart({
|
||||
frm.dashboard.render_graph({
|
||||
title: "Asset Value",
|
||||
data: {
|
||||
x: 'x',
|
||||
columns: [x_intervals, asset_values],
|
||||
regions: {
|
||||
'Asset Value': [{'start': last_depreciation_date, 'style':'dashed'}]
|
||||
}
|
||||
labels: x_intervals,
|
||||
datasets: [{
|
||||
color: 'green',
|
||||
values: asset_values,
|
||||
formatted: asset_values.map(d => d.toFixed(2))
|
||||
}]
|
||||
},
|
||||
legend: {
|
||||
show: false
|
||||
},
|
||||
axis: {
|
||||
x: {
|
||||
type: 'timeseries',
|
||||
tick: {
|
||||
format: "%d-%m-%Y"
|
||||
}
|
||||
},
|
||||
y: {
|
||||
min: 0,
|
||||
padding: {bottom: 10}
|
||||
}
|
||||
}
|
||||
type: 'line'
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
item_code: function(frm) {
|
||||
if(frm.doc.item_code) {
|
||||
frappe.call({
|
||||
|
||||
@@ -36,12 +36,15 @@ def make_depreciation_entry(asset_name, date=None):
|
||||
fixed_asset_account, accumulated_depreciation_account, depreciation_expense_account = \
|
||||
get_depreciation_accounts(asset)
|
||||
|
||||
depreciation_cost_center = frappe.db.get_value("Company", asset.company, "depreciation_cost_center")
|
||||
depreciation_cost_center, depreciation_series = frappe.db.get_value("Company", asset.company,
|
||||
["depreciation_cost_center", "series_for_depreciation_entry"])
|
||||
|
||||
|
||||
for d in asset.get("schedules"):
|
||||
if not d.journal_entry and getdate(d.schedule_date) <= getdate(date):
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.voucher_type = "Depreciation Entry"
|
||||
je.naming_series = depreciation_series
|
||||
je.posting_date = d.schedule_date
|
||||
je.company = asset.company
|
||||
je.remark = "Depreciation Entry against {0} worth {1}".format(asset_name, d.depreciation_amount)
|
||||
@@ -109,8 +112,11 @@ def scrap_asset(asset_name):
|
||||
elif asset.status in ("Cancelled", "Sold", "Scrapped"):
|
||||
frappe.throw(_("Asset {0} cannot be scrapped, as it is already {1}").format(asset.name, asset.status))
|
||||
|
||||
depreciation_series = frappe.db.get_value("Company", asset.company, "series_for_depreciation_entry")
|
||||
|
||||
je = frappe.new_doc("Journal Entry")
|
||||
je.voucher_type = "Journal Entry"
|
||||
je.naming_series = depreciation_series
|
||||
je.posting_date = today()
|
||||
je.company = asset.company
|
||||
je.remark = "Scrap Entry for asset {0}".format(asset_name)
|
||||
|
||||
@@ -13,6 +13,7 @@ class TestAsset(unittest.TestCase):
|
||||
def setUp(self):
|
||||
set_depreciation_settings_in_company()
|
||||
create_asset()
|
||||
frappe.db.sql("delete from `tabTax Rule`")
|
||||
|
||||
def test_purchase_asset(self):
|
||||
asset = frappe.get_doc("Asset", "Macbook Pro 1")
|
||||
@@ -150,11 +151,16 @@ class TestAsset(unittest.TestCase):
|
||||
asset.load_from_db()
|
||||
self.assertEqual(asset.status, "Submitted")
|
||||
|
||||
frappe.db.set_value("Company", "_Test Company", "series_for_depreciation_entry", "DEPR-")
|
||||
|
||||
post_depreciation_entries(date="2021-01-01")
|
||||
asset.load_from_db()
|
||||
|
||||
self.assertEqual(asset.status, "Partially Depreciated")
|
||||
|
||||
# check depreciation entry series
|
||||
self.assertEqual(asset.get("schedules")[0].journal_entry[:4], "DEPR")
|
||||
|
||||
expected_gle = (
|
||||
("_Test Accumulated Depreciations - _TC", 0.0, 30000.0),
|
||||
("_Test Depreciations - _TC", 30000.0, 0.0)
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
QUnit.module('Account');
|
||||
|
||||
QUnit.test("test Bank Reconciliation", function(assert) {
|
||||
assert.expect(0);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => frappe.set_route('Form', 'Bank Reconciliation'),
|
||||
() => cur_frm.set_value('bank_account','Cash - FT'),
|
||||
() => frappe.click_button('Get Payment Entries'),
|
||||
() => {
|
||||
for(var i=0;i<=cur_frm.doc.payment_entries.length-1;i++){
|
||||
cur_frm.doc.payment_entries[i].clearance_date = frappe.datetime.add_days(frappe.datetime.now_date(), 2);
|
||||
}
|
||||
},
|
||||
() => {cur_frm.refresh_fields('payment_entries');},
|
||||
() => frappe.click_button('Update Clearance Date'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.click_button('Close'),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -36,7 +36,7 @@ class GLEntry(Document):
|
||||
validate_balance_type(self.account, adv_adj)
|
||||
|
||||
# Update outstanding amt on against voucher
|
||||
if self.against_voucher_type in ['Journal Entry', 'Sales Invoice', 'Purchase Invoice'] \
|
||||
if self.against_voucher_type in ['Journal Entry', 'Sales Invoice', 'Purchase Invoice', 'Fees'] \
|
||||
and self.against_voucher and update_outstanding == 'Yes' and not from_repost:
|
||||
update_outstanding_amt(self.account, self.party_type, self.party, self.against_voucher_type,
|
||||
self.against_voucher)
|
||||
@@ -196,7 +196,7 @@ def update_outstanding_amt(account, party_type, party, against_voucher_type, aga
|
||||
frappe.throw(_("Outstanding for {0} cannot be less than zero ({1})").format(against_voucher, fmt_money(bal)))
|
||||
|
||||
# Update outstanding amt on against voucher
|
||||
if against_voucher_type in ["Sales Invoice", "Purchase Invoice"]:
|
||||
if against_voucher_type in ["Sales Invoice", "Purchase Invoice", "Fees"]:
|
||||
ref_doc = frappe.get_doc(against_voucher_type, against_voucher)
|
||||
ref_doc.db_set('outstanding_amount', bal)
|
||||
ref_doc.set_status(update=True)
|
||||
|
||||
@@ -1337,6 +1337,67 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1382,7 +1443,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-06-13 14:29:09.794076",
|
||||
"modified": "2017-08-31 11:21:09.442695",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Journal Entry",
|
||||
|
||||
@@ -12,8 +12,8 @@ from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amo
|
||||
from erpnext.hr.doctype.employee_loan.employee_loan import update_disbursement_status
|
||||
|
||||
class JournalEntry(AccountsController):
|
||||
def __init__(self, arg1, arg2=None):
|
||||
super(JournalEntry, self).__init__(arg1, arg2)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(JournalEntry, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_feed(self):
|
||||
return self.voucher_type
|
||||
@@ -54,7 +54,7 @@ class JournalEntry(AccountsController):
|
||||
def update_advance_paid(self):
|
||||
advance_paid = frappe._dict()
|
||||
for d in self.get("accounts"):
|
||||
if d.is_advance:
|
||||
if d.is_advance == "Yes":
|
||||
if d.reference_type in ("Sales Order", "Purchase Order"):
|
||||
advance_paid.setdefault(d.reference_type, []).append(d.reference_name)
|
||||
|
||||
@@ -76,7 +76,7 @@ class JournalEntry(AccountsController):
|
||||
|
||||
def unlink_advance_entry_reference(self):
|
||||
for d in self.get("accounts"):
|
||||
if d.is_advance and d.reference_type in ("Sales Invoice", "Purchase Invoice"):
|
||||
if d.is_advance == "Yes" and d.reference_type in ("Sales Invoice", "Purchase Invoice"):
|
||||
doc = frappe.get_doc(d.reference_type, d.reference_name)
|
||||
doc.delink_advance_entries(self.name)
|
||||
d.reference_type = ''
|
||||
|
||||
39
erpnext/accounts/doctype/journal_entry/test_journal_entry.js
Normal file
39
erpnext/accounts/doctype/journal_entry/test_journal_entry.js
Normal file
@@ -0,0 +1,39 @@
|
||||
QUnit.module('Journal Entry');
|
||||
|
||||
QUnit.test("test journal entry", function(assert) {
|
||||
assert.expect(2);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Journal Entry', [
|
||||
{posting_date:frappe.datetime.add_days(frappe.datetime.nowdate(), 0)},
|
||||
{accounts: [
|
||||
[
|
||||
{'account':'Debtors - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
|
||||
{'party_type':'Customer'},
|
||||
{'party':'Test Customer 1'},
|
||||
{'credit_in_account_currency':1000},
|
||||
{'is_advance':'Yes'},
|
||||
],
|
||||
[
|
||||
{'account':'HDFC - '+frappe.get_abbr(frappe.defaults.get_default('Company'))},
|
||||
{'debit_in_account_currency':1000},
|
||||
]
|
||||
]},
|
||||
{cheque_no:1234},
|
||||
{cheque_date: frappe.datetime.add_days(frappe.datetime.nowdate(), -1)},
|
||||
{user_remark: 'Test'},
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.total_debit==1000, "total debit correct");
|
||||
assert.ok(cur_frm.doc.total_credit==1000, "total credit correct");
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -12,7 +12,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
|
||||
setup: function(frm) {
|
||||
frm.set_query("paid_from", function() {
|
||||
var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable";
|
||||
var party_account_type = in_list(["Customer", "Student"], frm.doc.party_type) ?
|
||||
"Receivable" : "Payable";
|
||||
var account_types = in_list(["Pay", "Internal Transfer"], frm.doc.payment_type) ?
|
||||
["Bank", "Cash"] : party_account_type;
|
||||
|
||||
@@ -28,13 +29,14 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_query("party_type", function() {
|
||||
return{
|
||||
"filters": {
|
||||
"name": ["in",["Customer","Supplier"]],
|
||||
"name": ["in",["Customer","Supplier", "Employee", "Student"]],
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
frm.set_query("paid_to", function() {
|
||||
var party_account_type = frm.doc.party_type=="Customer" ? "Receivable" : "Payable";
|
||||
var party_account_type = in_list(["Customer", "Student"], frm.doc.party_type) ?
|
||||
"Receivable" : "Payable";
|
||||
var account_types = in_list(["Receive", "Internal Transfer"], frm.doc.payment_type) ?
|
||||
["Bank", "Cash"] : party_account_type;
|
||||
|
||||
@@ -70,6 +72,10 @@ frappe.ui.form.on('Payment Entry', {
|
||||
var doctypes = ["Sales Order", "Sales Invoice", "Journal Entry"];
|
||||
} else if (frm.doc.party_type=="Supplier") {
|
||||
var doctypes = ["Purchase Order", "Purchase Invoice", "Journal Entry"];
|
||||
} else if (frm.doc.party_type=="Employee") {
|
||||
var doctypes = ["Expense Claim", "Journal Entry"];
|
||||
} else if (frm.doc.party_type=="Student") {
|
||||
var doctypes = ["Fees"];
|
||||
} else {
|
||||
var doctypes = ["Journal Entry"];
|
||||
}
|
||||
@@ -82,12 +88,18 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_query("reference_name", "references", function(doc, cdt, cdn) {
|
||||
child = locals[cdt][cdn];
|
||||
filters = {"docstatus": 1, "company": doc.company};
|
||||
party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice', 'Purchase Order'];
|
||||
party_type_doctypes = ['Sales Invoice', 'Sales Order', 'Purchase Invoice',
|
||||
'Purchase Order', 'Expense Claim', 'Fees'];
|
||||
|
||||
if (in_list(party_type_doctypes, child.reference_doctype)) {
|
||||
filters[doc.party_type.toLowerCase()] = doc.party;
|
||||
}
|
||||
|
||||
if(child.reference_doctype == "Expense Claim") {
|
||||
filters["status"] = "Approved";
|
||||
filters["is_paid"] = 0;
|
||||
}
|
||||
|
||||
return {
|
||||
filters: filters
|
||||
};
|
||||
@@ -199,13 +211,13 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.set_value(field, null);
|
||||
});
|
||||
} else {
|
||||
if(!frm.doc.party)
|
||||
frm.set_value("party_type", frm.doc.payment_type=="Receive" ? "Customer" : "Supplier");
|
||||
else
|
||||
frm.events.party(frm);
|
||||
if(frm.doc.party) {
|
||||
frm.events.party(frm);
|
||||
}
|
||||
|
||||
if(frm.doc.mode_of_payment)
|
||||
if(frm.doc.mode_of_payment) {
|
||||
frm.events.mode_of_payment(frm);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -240,6 +252,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
date: frm.doc.posting_date
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
console.log(r, rt);
|
||||
if(r.message) {
|
||||
if(frm.doc.payment_type == "Receive") {
|
||||
frm.set_value("paid_from", r.message.party_account);
|
||||
@@ -339,7 +352,8 @@ frappe.ui.form.on('Payment Entry', {
|
||||
method: "erpnext.setup.utils.get_exchange_rate",
|
||||
args: {
|
||||
from_currency: frm.doc.paid_from_account_currency,
|
||||
to_currency: company_currency
|
||||
to_currency: company_currency,
|
||||
transaction_date: frm.doc.posting_date
|
||||
},
|
||||
callback: function(r, rt) {
|
||||
frm.set_value("source_exchange_rate", r.message);
|
||||
@@ -389,6 +403,9 @@ frappe.ui.form.on('Payment Entry', {
|
||||
|
||||
frm.events.set_difference_amount(frm);
|
||||
}
|
||||
|
||||
// Make read only if Accounts Settings doesn't allow stale rates
|
||||
frm.set_df_property("source_exchange_rate", "read_only", erpnext.stale_rate_allowed());
|
||||
},
|
||||
|
||||
target_exchange_rate: function(frm) {
|
||||
@@ -407,6 +424,9 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frm.events.set_difference_amount(frm);
|
||||
}
|
||||
frm.set_paid_amount_based_on_received_amount = false;
|
||||
|
||||
// Make read only if Accounts Settings doesn't allow stale rates
|
||||
frm.set_df_property("target_exchange_rate", "read_only", erpnext.stale_rate_allowed());
|
||||
},
|
||||
|
||||
paid_amount: function(frm) {
|
||||
@@ -484,9 +504,12 @@ frappe.ui.form.on('Payment Entry', {
|
||||
var c = frm.add_child("references");
|
||||
c.reference_doctype = d.voucher_type;
|
||||
c.reference_name = d.voucher_no;
|
||||
c.due_date = d.due_date
|
||||
c.total_amount = d.invoice_amount;
|
||||
c.outstanding_amount = d.outstanding_amount;
|
||||
if(!in_list(["Sales Order", "Purchase Order"], d.voucher_type)) {
|
||||
c.bill_no = d.bill_no;
|
||||
|
||||
if(!in_list(["Sales Order", "Purchase Order", "Expense Claim"], d.voucher_type)) {
|
||||
if(flt(d.outstanding_amount) > 0)
|
||||
total_positive_outstanding += flt(d.outstanding_amount);
|
||||
else
|
||||
@@ -501,14 +524,15 @@ frappe.ui.form.on('Payment Entry', {
|
||||
} else {
|
||||
c.exchange_rate = 1;
|
||||
}
|
||||
if (in_list(['Sales Invoice', 'Purchase Invoice'], d.reference_doctype)){
|
||||
if (in_list(['Sales Invoice', 'Purchase Invoice', "Expense Claim"], d.reference_doctype)){
|
||||
c.due_date = d.due_date;
|
||||
}
|
||||
});
|
||||
|
||||
if(
|
||||
(frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier")
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")
|
||||
) {
|
||||
if(total_positive_outstanding > total_negative_outstanding)
|
||||
frm.set_value("paid_amount",
|
||||
@@ -552,8 +576,9 @@ frappe.ui.form.on('Payment Entry', {
|
||||
})
|
||||
|
||||
var allocated_negative_outstanding = 0;
|
||||
if((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier")) {
|
||||
if ((frm.doc.payment_type=="Receive" && frm.doc.party_type=="Customer") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Supplier") ||
|
||||
(frm.doc.payment_type=="Pay" && frm.doc.party_type=="Employee")) {
|
||||
if(total_positive_outstanding_including_order > paid_amount) {
|
||||
var remaining_outstanding = total_positive_outstanding_including_order - paid_amount;
|
||||
allocated_negative_outstanding = total_negative_outstanding < remaining_outstanding ?
|
||||
@@ -561,7 +586,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
}
|
||||
|
||||
var allocated_positive_outstanding = paid_amount + allocated_negative_outstanding;
|
||||
} else {
|
||||
} else if (in_list(["Customer", "Supplier"], frm.doc.party_type)) {
|
||||
if(paid_amount > total_negative_outstanding) {
|
||||
if(total_negative_outstanding == 0) {
|
||||
frappe.msgprint(__("Cannot {0} {1} {2} without any negative outstanding invoice",
|
||||
@@ -626,7 +651,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
if(frm.doc.party) {
|
||||
var party_amount = frm.doc.payment_type=="Receive" ?
|
||||
frm.doc.paid_amount : frm.doc.received_amount;
|
||||
|
||||
|
||||
var total_deductions = frappe.utils.sum($.map(frm.doc.deductions || [],
|
||||
function(d) { return flt(d.amount) }));
|
||||
|
||||
@@ -654,11 +679,7 @@ frappe.ui.form.on('Payment Entry', {
|
||||
difference_amount = flt(frm.doc.base_paid_amount) - flt(frm.doc.base_received_amount);
|
||||
}
|
||||
|
||||
$.each(frm.doc.deductions || [], function(i, d) {
|
||||
if(d.amount) difference_amount -= flt(d.amount);
|
||||
})
|
||||
|
||||
frm.set_value("difference_amount", difference_amount);
|
||||
frm.set_value("difference_amount", difference_amount - total_deductions);
|
||||
|
||||
frm.events.hide_unhide_fields(frm);
|
||||
},
|
||||
@@ -694,6 +715,14 @@ frappe.ui.form.on('Payment Entry', {
|
||||
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Purchase Order, Purchase Invoice or Journal Entry", [row.idx]));
|
||||
return false;
|
||||
}
|
||||
|
||||
if(frm.doc.party_type=="Employee" &&
|
||||
!in_list(["Expense Claim", "Journal Entry"], row.reference_doctype)
|
||||
) {
|
||||
frappe.model.set_value(row.doctype, row.name, "against_voucher_type", null);
|
||||
frappe.msgprint(__("Row #{0}: Reference Document Type must be one of Expense Claim or Journal Entry", [row.idx]));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (row) {
|
||||
|
||||
@@ -1659,6 +1659,67 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1730,7 +1791,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-06-13 14:29:04.244537",
|
||||
"modified": "2017-08-31 11:20:37.578469",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry",
|
||||
|
||||
@@ -12,27 +12,27 @@ from erpnext.accounts.doctype.journal_entry.journal_entry \
|
||||
import get_average_exchange_rate, get_default_bank_cash_account
|
||||
from erpnext.setup.utils import get_exchange_rate
|
||||
from erpnext.accounts.general_ledger import make_gl_entries
|
||||
|
||||
from erpnext.hr.doctype.expense_claim.expense_claim import update_reimbursed_amount
|
||||
from erpnext.controllers.accounts_controller import AccountsController
|
||||
|
||||
class InvalidPaymentEntry(ValidationError): pass
|
||||
|
||||
class PaymentEntry(AccountsController):
|
||||
def setup_party_account_field(self):
|
||||
def setup_party_account_field(self):
|
||||
self.party_account_field = None
|
||||
self.party_account = None
|
||||
self.party_account_currency = None
|
||||
|
||||
|
||||
if self.payment_type == "Receive":
|
||||
self.party_account_field = "paid_from"
|
||||
self.party_account = self.paid_from
|
||||
self.party_account_currency = self.paid_from_account_currency
|
||||
|
||||
|
||||
elif self.payment_type == "Pay":
|
||||
self.party_account_field = "paid_to"
|
||||
self.party_account = self.paid_to
|
||||
self.party_account_currency = self.paid_to_account_currency
|
||||
|
||||
|
||||
def validate(self):
|
||||
self.setup_party_account_field()
|
||||
self.set_missing_values()
|
||||
@@ -50,18 +50,20 @@ class PaymentEntry(AccountsController):
|
||||
self.set_remarks()
|
||||
self.validate_duplicate_entry()
|
||||
self.validate_allocated_amount()
|
||||
|
||||
|
||||
def on_submit(self):
|
||||
self.setup_party_account_field()
|
||||
if self.difference_amount:
|
||||
frappe.throw(_("Difference Amount must be zero"))
|
||||
self.make_gl_entries()
|
||||
self.update_advance_paid()
|
||||
|
||||
self.update_expense_claim()
|
||||
|
||||
def on_cancel(self):
|
||||
self.setup_party_account_field()
|
||||
self.make_gl_entries(cancel=1)
|
||||
self.update_advance_paid()
|
||||
self.update_expense_claim()
|
||||
self.delink_advance_entry_references()
|
||||
|
||||
def validate_duplicate_entry(self):
|
||||
@@ -70,8 +72,8 @@ class PaymentEntry(AccountsController):
|
||||
if (d.reference_doctype, d.reference_name) in reference_names:
|
||||
frappe.throw(_("Row #{0}: Duplicate entry in References {1} {2}").format(d.idx, d.reference_doctype, d.reference_name))
|
||||
reference_names.append((d.reference_doctype, d.reference_name))
|
||||
|
||||
|
||||
|
||||
|
||||
def validate_allocated_amount(self):
|
||||
for d in self.get("references"):
|
||||
if (flt(d.allocated_amount))> 0:
|
||||
@@ -87,111 +89,115 @@ class PaymentEntry(AccountsController):
|
||||
|
||||
def set_missing_values(self):
|
||||
if self.payment_type == "Internal Transfer":
|
||||
for field in ("party", "party_balance", "total_allocated_amount",
|
||||
for field in ("party", "party_balance", "total_allocated_amount",
|
||||
"base_total_allocated_amount", "unallocated_amount"):
|
||||
self.set(field, None)
|
||||
self.references = []
|
||||
else:
|
||||
if not self.party_type:
|
||||
frappe.throw(_("Party Type is mandatory"))
|
||||
|
||||
|
||||
if not self.party:
|
||||
frappe.throw(_("Party is mandatory"))
|
||||
|
||||
self.party_name = frappe.db.get_value(self.party_type, self.party,
|
||||
self.party_type.lower() + "_name")
|
||||
|
||||
|
||||
_party_name = "title" if self.party_type == "Student" else self.party_type.lower() + "_name"
|
||||
self.party_name = frappe.db.get_value(self.party_type, self.party, _party_name)
|
||||
|
||||
if self.party:
|
||||
if not self.party_balance:
|
||||
self.party_balance = get_balance_on(party_type=self.party_type,
|
||||
party=self.party, date=self.posting_date, company=self.company)
|
||||
|
||||
|
||||
if not self.party_account:
|
||||
party_account = get_party_account(self.party_type, self.party, self.company)
|
||||
self.set(self.party_account_field, party_account)
|
||||
self.party_account = party_account
|
||||
|
||||
|
||||
if self.paid_from and not (self.paid_from_account_currency or self.paid_from_account_balance):
|
||||
acc = get_account_details(self.paid_from, self.posting_date)
|
||||
self.paid_from_account_currency = acc.account_currency
|
||||
self.paid_from_account_balance = acc.account_balance
|
||||
|
||||
|
||||
if self.paid_to and not (self.paid_to_account_currency or self.paid_to_account_balance):
|
||||
acc = get_account_details(self.paid_to, self.posting_date)
|
||||
self.paid_to_account_currency = acc.account_currency
|
||||
self.paid_to_account_balance = acc.account_balance
|
||||
|
||||
|
||||
self.party_account_currency = self.paid_from_account_currency \
|
||||
if self.payment_type=="Receive" else self.paid_to_account_currency
|
||||
|
||||
|
||||
self.set_missing_ref_details()
|
||||
|
||||
|
||||
|
||||
|
||||
def set_missing_ref_details(self):
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount:
|
||||
ref_details = get_reference_details(d.reference_doctype,
|
||||
ref_details = get_reference_details(d.reference_doctype,
|
||||
d.reference_name, self.party_account_currency)
|
||||
|
||||
|
||||
for field, value in ref_details.items():
|
||||
if not d.get(field):
|
||||
d.set(field, value)
|
||||
|
||||
|
||||
def validate_payment_type(self):
|
||||
if self.payment_type not in ("Receive", "Pay", "Internal Transfer"):
|
||||
frappe.throw(_("Payment Type must be one of Receive, Pay and Internal Transfer"))
|
||||
|
||||
|
||||
def validate_party_details(self):
|
||||
if self.party:
|
||||
if not frappe.db.exists(self.party_type, self.party):
|
||||
frappe.throw(_("Invalid {0}: {1}").format(self.party_type, self.party))
|
||||
|
||||
|
||||
if self.party_account:
|
||||
party_account_type = "Receivable" if self.party_type=="Customer" else "Payable"
|
||||
party_account_type = "Receivable" if self.party_type in ("Customer", "Student") else "Payable"
|
||||
self.validate_account_type(self.party_account, [party_account_type])
|
||||
|
||||
|
||||
def validate_bank_accounts(self):
|
||||
if self.payment_type in ("Pay", "Internal Transfer"):
|
||||
self.validate_account_type(self.paid_from, ["Bank", "Cash"])
|
||||
|
||||
|
||||
if self.payment_type in ("Receive", "Internal Transfer"):
|
||||
self.validate_account_type(self.paid_to, ["Bank", "Cash"])
|
||||
|
||||
|
||||
def validate_account_type(self, account, account_types):
|
||||
account_type = frappe.db.get_value("Account", account, "account_type")
|
||||
if account_type not in account_types:
|
||||
frappe.throw(_("Account Type for {0} must be {1}").format(account, comma_or(account_types)))
|
||||
|
||||
|
||||
def set_exchange_rate(self):
|
||||
if self.paid_from and not self.source_exchange_rate:
|
||||
if self.paid_from_account_currency == self.company_currency:
|
||||
self.source_exchange_rate = 1
|
||||
else:
|
||||
self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency,
|
||||
self.source_exchange_rate = get_exchange_rate(self.paid_from_account_currency,
|
||||
self.company_currency, self.posting_date)
|
||||
|
||||
|
||||
if self.paid_to and not self.target_exchange_rate:
|
||||
self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,
|
||||
self.target_exchange_rate = get_exchange_rate(self.paid_to_account_currency,
|
||||
self.company_currency, self.posting_date)
|
||||
|
||||
|
||||
def validate_mandatory(self):
|
||||
for field in ("paid_amount", "received_amount", "source_exchange_rate", "target_exchange_rate"):
|
||||
if not self.get(field):
|
||||
frappe.throw(_("{0} is mandatory").format(self.meta.get_label(field)))
|
||||
|
||||
|
||||
def validate_reference_documents(self):
|
||||
if self.party_type == "Customer":
|
||||
if self.party_type == "Student":
|
||||
valid_reference_doctypes = ("Fees")
|
||||
elif self.party_type == "Customer":
|
||||
valid_reference_doctypes = ("Sales Order", "Sales Invoice", "Journal Entry")
|
||||
else:
|
||||
elif self.party_type == "Supplier":
|
||||
valid_reference_doctypes = ("Purchase Order", "Purchase Invoice", "Journal Entry")
|
||||
|
||||
elif self.party_type == "Employee":
|
||||
valid_reference_doctypes = ("Expense Claim", "Journal Entry")
|
||||
|
||||
for d in self.get("references"):
|
||||
if not d.allocated_amount:
|
||||
continue
|
||||
if d.reference_doctype not in valid_reference_doctypes:
|
||||
frappe.throw(_("Reference Doctype must be one of {0}")
|
||||
.format(comma_or(valid_reference_doctypes)))
|
||||
|
||||
|
||||
elif d.reference_name:
|
||||
if not frappe.db.exists(d.reference_doctype, d.reference_name):
|
||||
frappe.throw(_("{0} {1} does not exist").format(d.reference_doctype, d.reference_name))
|
||||
@@ -204,21 +210,28 @@ class PaymentEntry(AccountsController):
|
||||
.format(d.reference_doctype, d.reference_name, self.party_type, self.party))
|
||||
else:
|
||||
self.validate_journal_entry()
|
||||
|
||||
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice"):
|
||||
ref_party_account = ref_doc.debit_to \
|
||||
if self.party_type=="Customer" else ref_doc.credit_to
|
||||
|
||||
if d.reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim", "Fees"):
|
||||
if self.party_type == "Customer":
|
||||
ref_party_account = ref_doc.debit_to
|
||||
elif self.party_type == "Student":
|
||||
ref_party_account = ref_doc.receivable_account
|
||||
elif self.party_type=="Supplier":
|
||||
ref_party_account = ref_doc.credit_to
|
||||
elif self.party_type=="Employee":
|
||||
ref_party_account = ref_doc.payable_account
|
||||
|
||||
if ref_party_account != self.party_account:
|
||||
frappe.throw(_("{0} {1} does not associated with Party Account {2}")
|
||||
.format(d.reference_doctype, d.reference_name, self.party_account))
|
||||
|
||||
frappe.throw(_("{0} {1} is associated with {2}, but Party Account is {3}")
|
||||
.format(d.reference_doctype, d.reference_name, ref_party_account, self.party_account))
|
||||
|
||||
if ref_doc.docstatus != 1:
|
||||
frappe.throw(_("{0} {1} must be submitted")
|
||||
.format(d.reference_doctype, d.reference_name))
|
||||
|
||||
|
||||
def validate_journal_entry(self):
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount and d.reference_doctype == "Journal Entry":
|
||||
if d.allocated_amount and d.reference_doctype == "Journal Entry":
|
||||
je_accounts = frappe.db.sql("""select debit, credit from `tabJournal Entry Account`
|
||||
where account = %s and party=%s and docstatus = 1 and parent = %s
|
||||
and (reference_type is null or reference_type in ("", "Sales Order", "Purchase Order"))
|
||||
@@ -236,7 +249,7 @@ class PaymentEntry(AccountsController):
|
||||
if not valid:
|
||||
frappe.throw(_("Against Journal Entry {0} does not have any unmatched {1} entry")
|
||||
.format(d.reference_name, dr_or_cr))
|
||||
|
||||
|
||||
def set_amounts(self):
|
||||
self.set_amounts_in_company_currency()
|
||||
self.set_total_allocated_amount()
|
||||
@@ -246,111 +259,110 @@ class PaymentEntry(AccountsController):
|
||||
def set_amounts_in_company_currency(self):
|
||||
self.base_paid_amount, self.base_received_amount, self.difference_amount = 0, 0, 0
|
||||
if self.paid_amount:
|
||||
self.base_paid_amount = flt(flt(self.paid_amount) * flt(self.source_exchange_rate),
|
||||
self.base_paid_amount = flt(flt(self.paid_amount) * flt(self.source_exchange_rate),
|
||||
self.precision("base_paid_amount"))
|
||||
|
||||
|
||||
if self.received_amount:
|
||||
self.base_received_amount = flt(flt(self.received_amount) * flt(self.target_exchange_rate),
|
||||
self.base_received_amount = flt(flt(self.received_amount) * flt(self.target_exchange_rate),
|
||||
self.precision("base_received_amount"))
|
||||
|
||||
|
||||
def set_total_allocated_amount(self):
|
||||
if self.payment_type == "Internal Transfer":
|
||||
return
|
||||
|
||||
|
||||
total_allocated_amount, base_total_allocated_amount = 0, 0
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount:
|
||||
if d.allocated_amount:
|
||||
total_allocated_amount += flt(d.allocated_amount)
|
||||
base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate),
|
||||
base_total_allocated_amount += flt(flt(d.allocated_amount) * flt(d.exchange_rate),
|
||||
self.precision("base_paid_amount"))
|
||||
|
||||
|
||||
self.total_allocated_amount = abs(total_allocated_amount)
|
||||
self.base_total_allocated_amount = abs(base_total_allocated_amount)
|
||||
|
||||
|
||||
def set_unallocated_amount(self):
|
||||
self.unallocated_amount = 0;
|
||||
if self.party:
|
||||
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
|
||||
|
||||
|
||||
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
||||
|
||||
|
||||
if self.total_allocated_amount < party_amount:
|
||||
if self.payment_type == "Receive":
|
||||
self.unallocated_amount = party_amount - (self.total_allocated_amount - total_deductions)
|
||||
else:
|
||||
self.unallocated_amount = party_amount - (self.total_allocated_amount + total_deductions)
|
||||
|
||||
|
||||
def set_difference_amount(self):
|
||||
base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
|
||||
base_unallocated_amount = flt(self.unallocated_amount) * (flt(self.source_exchange_rate)
|
||||
if self.payment_type=="Receive" else flt(self.target_exchange_rate))
|
||||
|
||||
|
||||
base_party_amount = flt(self.base_total_allocated_amount) + flt(base_unallocated_amount)
|
||||
|
||||
|
||||
if self.payment_type == "Receive":
|
||||
self.difference_amount = base_party_amount - self.base_received_amount
|
||||
elif self.payment_type == "Pay":
|
||||
self.difference_amount = self.base_paid_amount - base_party_amount
|
||||
else:
|
||||
self.difference_amount = self.base_paid_amount - flt(self.base_received_amount)
|
||||
|
||||
for d in self.get("deductions"):
|
||||
if d.amount:
|
||||
self.difference_amount -= flt(d.amount)
|
||||
|
||||
self.difference_amount = flt(self.difference_amount, self.precision("difference_amount"))
|
||||
|
||||
|
||||
total_deductions = sum([flt(d.amount) for d in self.get("deductions")])
|
||||
|
||||
self.difference_amount = flt(self.difference_amount - total_deductions,
|
||||
self.precision("difference_amount"))
|
||||
|
||||
def clear_unallocated_reference_document_rows(self):
|
||||
self.set("references", self.get("references", {"allocated_amount": ["not in", [0, None, ""]]}))
|
||||
|
||||
frappe.db.sql("""delete from `tabPayment Entry Reference`
|
||||
frappe.db.sql("""delete from `tabPayment Entry Reference`
|
||||
where parent = %s and allocated_amount = 0""", self.name)
|
||||
|
||||
|
||||
def validate_payment_against_negative_invoice(self):
|
||||
if ((self.payment_type=="Pay" and self.party_type=="Customer")
|
||||
if ((self.payment_type=="Pay" and self.party_type=="Customer")
|
||||
or (self.payment_type=="Receive" and self.party_type=="Supplier")):
|
||||
|
||||
total_negative_outstanding = sum([abs(flt(d.outstanding_amount))
|
||||
|
||||
total_negative_outstanding = sum([abs(flt(d.outstanding_amount))
|
||||
for d in self.get("references") if flt(d.outstanding_amount) < 0])
|
||||
|
||||
|
||||
party_amount = self.paid_amount if self.payment_type=="Receive" else self.received_amount
|
||||
|
||||
if not total_negative_outstanding:
|
||||
frappe.throw(_("Cannot {0} {1} {2} without any negative outstanding invoice")
|
||||
.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"),
|
||||
.format(self.payment_type, ("to" if self.party_type=="Customer" else "from"),
|
||||
self.party_type), InvalidPaymentEntry)
|
||||
|
||||
|
||||
elif party_amount > total_negative_outstanding:
|
||||
frappe.throw(_("Paid Amount cannot be greater than total negative outstanding amount {0}")
|
||||
.format(total_negative_outstanding), InvalidPaymentEntry)
|
||||
|
||||
|
||||
def set_title(self):
|
||||
if self.payment_type in ("Receive", "Pay"):
|
||||
self.title = self.party
|
||||
else:
|
||||
self.title = self.paid_from + " - " + self.paid_to
|
||||
|
||||
|
||||
def validate_transaction_reference(self):
|
||||
bank_account = self.paid_to if self.payment_type == "Receive" else self.paid_from
|
||||
bank_account_type = frappe.db.get_value("Account", bank_account, "account_type")
|
||||
|
||||
|
||||
if bank_account_type == "Bank":
|
||||
if not self.reference_no or not self.reference_date:
|
||||
frappe.throw(_("Reference No and Reference Date is mandatory for Bank transaction"))
|
||||
|
||||
|
||||
def set_remarks(self):
|
||||
if self.remarks: return
|
||||
|
||||
|
||||
if self.payment_type=="Internal Transfer":
|
||||
remarks = [_("Amount {0} {1} transferred from {2} to {3}")
|
||||
.format(self.paid_from_account_currency, self.paid_amount, self.paid_from, self.paid_to)]
|
||||
else:
|
||||
|
||||
|
||||
remarks = [_("Amount {0} {1} {2} {3}").format(
|
||||
self.party_account_currency,
|
||||
self.paid_amount if self.payment_type=="Receive" else self.received_amount,
|
||||
_("received from") if self.payment_type=="Receive" else _("to"), self.party
|
||||
)]
|
||||
|
||||
|
||||
if self.reference_no:
|
||||
remarks.append(_("Transaction reference no {0} dated {1}")
|
||||
.format(self.reference_no, self.reference_date))
|
||||
@@ -358,35 +370,35 @@ class PaymentEntry(AccountsController):
|
||||
if self.payment_type in ["Receive", "Pay"]:
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount:
|
||||
remarks.append(_("Amount {0} {1} against {2} {3}").format(self.party_account_currency,
|
||||
remarks.append(_("Amount {0} {1} against {2} {3}").format(self.party_account_currency,
|
||||
d.allocated_amount, d.reference_doctype, d.reference_name))
|
||||
|
||||
|
||||
for d in self.get("deductions"):
|
||||
if d.amount:
|
||||
remarks.append(_("Amount {0} {1} deducted against {2}")
|
||||
.format(self.company_currency, d.amount, d.account))
|
||||
|
||||
self.set("remarks", "\n".join(remarks))
|
||||
|
||||
|
||||
def make_gl_entries(self, cancel=0, adv_adj=0):
|
||||
if self.payment_type in ("Receive", "Pay") and not self.get("party_account_field"):
|
||||
self.setup_party_account_field()
|
||||
|
||||
|
||||
gl_entries = []
|
||||
self.add_party_gl_entries(gl_entries)
|
||||
self.add_bank_gl_entries(gl_entries)
|
||||
self.add_deductions_gl_entries(gl_entries)
|
||||
|
||||
make_gl_entries(gl_entries, cancel=cancel, adv_adj=adv_adj)
|
||||
|
||||
|
||||
def add_party_gl_entries(self, gl_entries):
|
||||
if self.party_account:
|
||||
if self.payment_type=="Receive":
|
||||
against_account = self.paid_to
|
||||
else:
|
||||
against_account = self.paid_from
|
||||
|
||||
|
||||
against_account = self.paid_from
|
||||
|
||||
|
||||
party_gl_dict = self.get_gl_dict({
|
||||
"account": self.party_account,
|
||||
"party_type": self.party_type,
|
||||
@@ -394,39 +406,39 @@ class PaymentEntry(AccountsController):
|
||||
"against": against_account,
|
||||
"account_currency": self.party_account_currency
|
||||
})
|
||||
|
||||
dr_or_cr = "credit" if self.party_type == "Customer" else "debit"
|
||||
|
||||
|
||||
dr_or_cr = "credit" if self.party_type in ["Customer", "Student"] else "debit"
|
||||
|
||||
for d in self.get("references"):
|
||||
gle = party_gl_dict.copy()
|
||||
gle.update({
|
||||
"against_voucher_type": d.reference_doctype,
|
||||
"against_voucher": d.reference_name
|
||||
})
|
||||
|
||||
allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate),
|
||||
self.precision("paid_amount"))
|
||||
|
||||
|
||||
allocated_amount_in_company_currency = flt(flt(d.allocated_amount) * flt(d.exchange_rate),
|
||||
self.precision("paid_amount"))
|
||||
|
||||
gle.update({
|
||||
dr_or_cr + "_in_account_currency": d.allocated_amount,
|
||||
dr_or_cr: allocated_amount_in_company_currency
|
||||
})
|
||||
|
||||
|
||||
gl_entries.append(gle)
|
||||
|
||||
|
||||
if self.unallocated_amount:
|
||||
base_unallocated_amount = base_unallocated_amount = self.unallocated_amount * \
|
||||
(self.source_exchange_rate if self.payment_type=="Receive" else self.target_exchange_rate)
|
||||
|
||||
|
||||
gle = party_gl_dict.copy()
|
||||
|
||||
|
||||
gle.update({
|
||||
dr_or_cr + "_in_account_currency": self.unallocated_amount,
|
||||
dr_or_cr: base_unallocated_amount
|
||||
})
|
||||
|
||||
gl_entries.append(gle)
|
||||
|
||||
|
||||
def add_bank_gl_entries(self, gl_entries):
|
||||
if self.payment_type in ("Pay", "Internal Transfer"):
|
||||
gl_entries.append(
|
||||
@@ -448,14 +460,14 @@ class PaymentEntry(AccountsController):
|
||||
"debit": self.base_received_amount
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
def add_deductions_gl_entries(self, gl_entries):
|
||||
for d in self.get("deductions"):
|
||||
if d.amount:
|
||||
account_currency = get_account_currency(d.account)
|
||||
if account_currency != self.company_currency:
|
||||
frappe.throw(_("Currency for {0} must be {1}").format(d.account, self.company_currency))
|
||||
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": d.account,
|
||||
@@ -466,114 +478,142 @@ class PaymentEntry(AccountsController):
|
||||
"cost_center": d.cost_center
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
def update_advance_paid(self):
|
||||
if self.payment_type in ("Receive", "Pay") and self.party:
|
||||
for d in self.get("references"):
|
||||
if d.allocated_amount and d.reference_doctype in ("Sales Order", "Purchase Order"):
|
||||
frappe.get_doc(d.reference_doctype, d.reference_name).set_total_advance_paid()
|
||||
|
||||
def update_expense_claim(self):
|
||||
if self.payment_type in ("Pay") and self.party:
|
||||
for d in self.get("references"):
|
||||
if d.reference_doctype=="Expense Claim" and d.reference_name:
|
||||
doc = frappe.get_doc("Expense Claim", d.reference_name)
|
||||
update_reimbursed_amount(doc)
|
||||
|
||||
def on_recurring(self, reference_doc, subscription_doc):
|
||||
self.reference_no = reference_doc.name
|
||||
self.reference_date = nowdate()
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_outstanding_reference_documents(args):
|
||||
args = json.loads(args)
|
||||
if isinstance(args, basestring):
|
||||
args = json.loads(args)
|
||||
|
||||
party_account_currency = get_account_currency(args.get("party_account"))
|
||||
company_currency = frappe.db.get_value("Company", args.get("company"), "default_currency")
|
||||
|
||||
|
||||
# Get negative outstanding sales /purchase invoices
|
||||
total_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
|
||||
|
||||
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
||||
args.get("party"), args.get("party_account"), total_field)
|
||||
|
||||
# Get positive outstanding sales /purchase invoices
|
||||
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||
negative_outstanding_invoices = []
|
||||
if (args.get("party_type") != "Student"):
|
||||
negative_outstanding_invoices = get_negative_outstanding_invoices(args.get("party_type"),
|
||||
args.get("party"), args.get("party_account"), total_field)
|
||||
|
||||
# Get positive outstanding sales /purchase invoices/ Fees
|
||||
outstanding_invoices = get_outstanding_invoices(args.get("party_type"), args.get("party"),
|
||||
args.get("party_account"))
|
||||
|
||||
|
||||
for d in outstanding_invoices:
|
||||
d["exchange_rate"] = 1
|
||||
if party_account_currency != company_currency:
|
||||
if d.voucher_type in ("Sales Invoice", "Purchase Invoice"):
|
||||
if d.voucher_type in ("Sales Invoice", "Purchase Invoice", "Expense Claim"):
|
||||
d["exchange_rate"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "conversion_rate")
|
||||
elif d.voucher_type == "Journal Entry":
|
||||
d["exchange_rate"] = get_exchange_rate(
|
||||
party_account_currency, company_currency, d.posting_date
|
||||
)
|
||||
if d.voucher_type in ("Purchase Invoice"):
|
||||
d["bill_no"] = frappe.db.get_value(d.voucher_type, d.voucher_no, "bill_no")
|
||||
|
||||
# Get all SO / PO which are not fully billed or aginst which full advance not paid
|
||||
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"), args.get("party"),
|
||||
party_account_currency, company_currency)
|
||||
|
||||
orders_to_be_billed = []
|
||||
if (args.get("party_type") != "Student"):
|
||||
orders_to_be_billed = get_orders_to_be_billed(args.get("posting_date"),args.get("party_type"),
|
||||
args.get("party"), party_account_currency, company_currency)
|
||||
|
||||
return negative_outstanding_invoices + outstanding_invoices + orders_to_be_billed
|
||||
|
||||
|
||||
def get_orders_to_be_billed(posting_date, party_type, party, party_account_currency, company_currency):
|
||||
voucher_type = 'Sales Order' if party_type == "Customer" else 'Purchase Order'
|
||||
if party_type == "Customer":
|
||||
voucher_type = 'Sales Order'
|
||||
elif party_type == "Supplier":
|
||||
voucher_type = 'Purchase Order'
|
||||
elif party_type == "Employee":
|
||||
voucher_type = None
|
||||
|
||||
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
|
||||
orders = []
|
||||
if voucher_type:
|
||||
ref_field = "base_grand_total" if party_account_currency == company_currency else "grand_total"
|
||||
|
||||
orders = frappe.db.sql("""
|
||||
select
|
||||
name as voucher_no,
|
||||
{ref_field} as invoice_amount,
|
||||
({ref_field} - advance_paid) as outstanding_amount,
|
||||
transaction_date as posting_date
|
||||
from
|
||||
`tab{voucher_type}`
|
||||
where
|
||||
{party_type} = %s
|
||||
and docstatus = 1
|
||||
and ifnull(status, "") != "Closed"
|
||||
and {ref_field} > advance_paid
|
||||
and abs(100 - per_billed) > 0.01
|
||||
order by
|
||||
transaction_date, name
|
||||
""".format(**{
|
||||
"ref_field": ref_field,
|
||||
"voucher_type": voucher_type,
|
||||
"party_type": scrub(party_type)
|
||||
}), party, as_dict = True)
|
||||
orders = frappe.db.sql("""
|
||||
select
|
||||
name as voucher_no,
|
||||
{ref_field} as invoice_amount,
|
||||
({ref_field} - advance_paid) as outstanding_amount,
|
||||
transaction_date as posting_date
|
||||
from
|
||||
`tab{voucher_type}`
|
||||
where
|
||||
{party_type} = %s
|
||||
and docstatus = 1
|
||||
and ifnull(status, "") != "Closed"
|
||||
and {ref_field} > advance_paid
|
||||
and abs(100 - per_billed) > 0.01
|
||||
order by
|
||||
transaction_date, name
|
||||
""".format(**{
|
||||
"ref_field": ref_field,
|
||||
"voucher_type": voucher_type,
|
||||
"party_type": scrub(party_type)
|
||||
}), party, as_dict = True)
|
||||
|
||||
order_list = []
|
||||
for d in orders:
|
||||
d["voucher_type"] = voucher_type
|
||||
# This assumes that the exchange rate required is the one in the SO
|
||||
d["exchange_rate"] = get_exchange_rate(party_account_currency,
|
||||
d["exchange_rate"] = get_exchange_rate(party_account_currency,
|
||||
company_currency, posting_date)
|
||||
order_list.append(d)
|
||||
|
||||
return order_list
|
||||
|
||||
|
||||
def get_negative_outstanding_invoices(party_type, party, party_account, total_field):
|
||||
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
"{voucher_type}" as voucher_type, name as voucher_no,
|
||||
{total_field} as invoice_amount, outstanding_amount, posting_date,
|
||||
due_date, conversion_rate as exchange_rate
|
||||
from
|
||||
`tab{voucher_type}`
|
||||
where
|
||||
{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
|
||||
order by
|
||||
posting_date, name
|
||||
""".format(**{
|
||||
"total_field": total_field,
|
||||
"voucher_type": voucher_type,
|
||||
"party_type": scrub(party_type),
|
||||
"party_account": "debit_to" if party_type=="Customer" else "credit_to"
|
||||
}), (party, party_account), as_dict = True)
|
||||
|
||||
if party_type != "Employee":
|
||||
voucher_type = "Sales Invoice" if party_type == "Customer" else "Purchase Invoice"
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
"{voucher_type}" as voucher_type, name as voucher_no,
|
||||
{total_field} as invoice_amount, outstanding_amount, posting_date,
|
||||
due_date, conversion_rate as exchange_rate
|
||||
from
|
||||
`tab{voucher_type}`
|
||||
where
|
||||
{party_type} = %s and {party_account} = %s and docstatus = 1 and outstanding_amount < 0
|
||||
order by
|
||||
posting_date, name
|
||||
""".format(**{
|
||||
"total_field": total_field,
|
||||
"voucher_type": voucher_type,
|
||||
"party_type": scrub(party_type),
|
||||
"party_account": "debit_to" if party_type=="Customer" else "credit_to"
|
||||
}), (party, party_account), as_dict = True)
|
||||
else:
|
||||
return []
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_party_details(company, party_type, party, date):
|
||||
if not frappe.db.exists(party_type, party):
|
||||
frappe.throw(_("Invalid {0}: {1}").format(party_type, party))
|
||||
|
||||
|
||||
party_account = get_party_account(party_type, party, company)
|
||||
|
||||
|
||||
account_currency = get_account_currency(party_account)
|
||||
account_balance = get_balance_on(party_account, date)
|
||||
party_balance = get_balance_on(party_type=party_type, party=party)
|
||||
|
||||
|
||||
return {
|
||||
"party_account": party_account,
|
||||
"party_account_currency": account_currency,
|
||||
@@ -581,7 +621,7 @@ def get_party_details(company, party_type, party, date):
|
||||
"account_balance": account_balance
|
||||
}
|
||||
|
||||
@frappe.whitelist()
|
||||
@frappe.whitelist()
|
||||
def get_account_details(account, date):
|
||||
frappe.has_permission('Payment Entry', throw=True)
|
||||
return frappe._dict({
|
||||
@@ -589,77 +629,93 @@ def get_account_details(account, date):
|
||||
"account_balance": get_balance_on(account, date),
|
||||
"account_type": frappe.db.get_value("Account", account, "account_type")
|
||||
})
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_company_defaults(company):
|
||||
fields = ["write_off_account", "exchange_gain_loss_account", "cost_center"]
|
||||
ret = frappe.db.get_value("Company", company, fields, as_dict=1)
|
||||
|
||||
|
||||
for fieldname in fields:
|
||||
if not ret[fieldname]:
|
||||
frappe.throw(_("Please set default {0} in Company {1}")
|
||||
.format(frappe.get_meta("Company").get_label(fieldname), company))
|
||||
|
||||
|
||||
return ret
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_reference_details(reference_doctype, reference_name, party_account_currency):
|
||||
total_amount = outstanding_amount = exchange_rate = None
|
||||
ref_doc = frappe.get_doc(reference_doctype, reference_name)
|
||||
|
||||
if reference_doctype != "Journal Entry":
|
||||
|
||||
if reference_doctype == "Fees":
|
||||
total_amount = ref_doc.get("grand_total")
|
||||
exchange_rate = 1
|
||||
outstanding_amount = ref_doc.get("outstanding_amount")
|
||||
elif reference_doctype != "Journal Entry":
|
||||
if party_account_currency == ref_doc.company_currency:
|
||||
total_amount = ref_doc.base_grand_total
|
||||
if ref_doc.doctype == "Expense Claim":
|
||||
total_amount = ref_doc.total_sanctioned_amount
|
||||
else:
|
||||
total_amount = ref_doc.base_grand_total
|
||||
exchange_rate = 1
|
||||
else:
|
||||
total_amount = ref_doc.grand_total
|
||||
|
||||
# Get the exchange rate from the original ref doc
|
||||
|
||||
# Get the exchange rate from the original ref doc
|
||||
# or get it based on the posting date of the ref doc
|
||||
exchange_rate = ref_doc.get("conversion_rate") or \
|
||||
get_exchange_rate(party_account_currency, ref_doc.company_currency, ref_doc.posting_date)
|
||||
|
||||
|
||||
outstanding_amount = ref_doc.get("outstanding_amount") \
|
||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice") \
|
||||
else flt(total_amount) - flt(ref_doc.advance_paid)
|
||||
if reference_doctype in ("Sales Invoice", "Purchase Invoice", "Expense Claim") \
|
||||
else flt(total_amount) - flt(ref_doc.advance_paid)
|
||||
else:
|
||||
# Get the exchange rate based on the posting date of the ref doc
|
||||
exchange_rate = get_exchange_rate(party_account_currency,
|
||||
exchange_rate = get_exchange_rate(party_account_currency,
|
||||
ref_doc.company_currency, ref_doc.posting_date)
|
||||
|
||||
|
||||
return frappe._dict({
|
||||
"due_date": ref_doc.get("due_date"),
|
||||
"total_amount": total_amount,
|
||||
"outstanding_amount": outstanding_amount,
|
||||
"exchange_rate": exchange_rate
|
||||
})
|
||||
|
||||
|
||||
@frappe.whitelist()
|
||||
def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=None):
|
||||
doc = frappe.get_doc(dt, dn)
|
||||
|
||||
|
||||
if dt in ("Sales Order", "Purchase Order") and flt(doc.per_billed, 2) > 0:
|
||||
frappe.throw(_("Can only make payment against unbilled {0}").format(dt))
|
||||
|
||||
party_type = "Customer" if dt in ("Sales Invoice", "Sales Order") else "Supplier"
|
||||
|
||||
if dt in ("Sales Invoice", "Sales Order"):
|
||||
party_type = "Customer"
|
||||
elif dt in ("Purchase Invoice", "Purchase Order"):
|
||||
party_type = "Supplier"
|
||||
elif dt in ("Expense Claim"):
|
||||
party_type = "Employee"
|
||||
elif dt in ("Fees"):
|
||||
party_type = "Student"
|
||||
|
||||
# party account
|
||||
if dt == "Sales Invoice":
|
||||
party_account = doc.debit_to
|
||||
elif dt == "Purchase Invoice":
|
||||
party_account = doc.credit_to
|
||||
elif dt == "Fees":
|
||||
party_account = doc.receivable_account
|
||||
else:
|
||||
party_account = get_party_account(party_type, doc.get(party_type.lower()), doc.company)
|
||||
|
||||
|
||||
party_account_currency = doc.get("party_account_currency") or get_account_currency(party_account)
|
||||
|
||||
|
||||
# payment type
|
||||
if (dt == "Sales Order" or (dt=="Sales Invoice" and doc.outstanding_amount > 0)) \
|
||||
if (dt == "Sales Order" or (dt in ("Sales Invoice", "Fees") and doc.outstanding_amount > 0)) \
|
||||
or (dt=="Purchase Invoice" and doc.outstanding_amount < 0):
|
||||
payment_type = "Receive"
|
||||
else:
|
||||
payment_type = "Pay"
|
||||
|
||||
|
||||
# amounts
|
||||
grand_total = outstanding_amount = 0
|
||||
if party_amount:
|
||||
@@ -667,15 +723,21 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
elif dt in ("Sales Invoice", "Purchase Invoice"):
|
||||
grand_total = doc.base_grand_total if party_account_currency == doc.company_currency else doc.grand_total
|
||||
outstanding_amount = doc.outstanding_amount
|
||||
elif dt in ("Expense Claim"):
|
||||
grand_total = doc.total_sanctioned_amount
|
||||
outstanding_amount = doc.total_sanctioned_amount - doc.total_amount_reimbursed
|
||||
elif dt == "Fees":
|
||||
grand_total = doc.grand_total
|
||||
outstanding_amount = doc.outstanding_amount
|
||||
else:
|
||||
total_field = "base_grand_total" if party_account_currency == doc.company_currency else "grand_total"
|
||||
grand_total = flt(doc.get(total_field))
|
||||
outstanding_amount = grand_total - flt(doc.advance_paid)
|
||||
|
||||
# bank or cash
|
||||
bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
|
||||
bank = get_default_bank_cash_account(doc.company, "Bank", mode_of_payment=doc.get("mode_of_payment"),
|
||||
account=bank_account)
|
||||
|
||||
|
||||
paid_amount = received_amount = 0
|
||||
if party_account_currency == bank.account_currency:
|
||||
paid_amount = received_amount = abs(outstanding_amount)
|
||||
@@ -687,7 +749,7 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
received_amount = abs(outstanding_amount)
|
||||
if bank_amount:
|
||||
paid_amount = bank_amount
|
||||
|
||||
|
||||
pe = frappe.new_doc("Payment Entry")
|
||||
pe.payment_type = payment_type
|
||||
pe.company = doc.company
|
||||
@@ -704,10 +766,11 @@ def get_payment_entry(dt, dn, party_amount=None, bank_account=None, bank_amount=
|
||||
pe.received_amount = received_amount
|
||||
pe.allocate_payment_amount = 1
|
||||
pe.letter_head = doc.get("letter_head")
|
||||
|
||||
|
||||
pe.append("references", {
|
||||
"reference_doctype": dt,
|
||||
"reference_name": dn,
|
||||
"bill_no": doc.get("bill_no"),
|
||||
"due_date": doc.get("due_date"),
|
||||
"total_amount": grand_total,
|
||||
"outstanding_amount": outstanding_amount,
|
||||
|
||||
@@ -10,6 +10,7 @@ from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_orde
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, InvalidPaymentEntry
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import make_purchase_invoice
|
||||
from erpnext.hr.doctype.expense_claim.test_expense_claim import make_expense_claim
|
||||
|
||||
test_dependencies = ["Item"]
|
||||
|
||||
@@ -20,80 +21,102 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
pe.paid_from = "Debtors - _TC"
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["Debtors - _TC", 0, 1000, so.name],
|
||||
["_Test Cash - _TC", 1000.0, 0, None]
|
||||
])
|
||||
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
|
||||
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
|
||||
self.assertEqual(so_advance_paid, 1000)
|
||||
|
||||
|
||||
pe.cancel()
|
||||
|
||||
|
||||
self.assertFalse(self.get_gle(pe.name))
|
||||
|
||||
|
||||
so_advance_paid = frappe.db.get_value("Sales Order", so.name, "advance_paid")
|
||||
self.assertEqual(so_advance_paid, 0)
|
||||
|
||||
|
||||
def test_payment_entry_against_si_usd_to_usd(self):
|
||||
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.target_exchange_rate = 50
|
||||
pe.target_exchange_rate = 50
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Receivable USD - _TC", 0, 5000, si.name],
|
||||
["_Test Bank USD - _TC", 5000.0, 0, None]
|
||||
])
|
||||
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 0)
|
||||
|
||||
|
||||
pe.cancel()
|
||||
self.assertFalse(self.get_gle(pe.name))
|
||||
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 100)
|
||||
|
||||
|
||||
def test_payment_entry_against_pi(self):
|
||||
pi = make_purchase_invoice(supplier="_Test Supplier USD", debit_to="_Test Payable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
pe = get_payment_entry("Purchase Invoice", pi.name, bank_account="_Test Bank USD - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.source_exchange_rate = 50
|
||||
pe.source_exchange_rate = 50
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Payable USD - _TC", 12500, 0, pi.name],
|
||||
["_Test Bank USD - _TC", 0, 12500, None]
|
||||
])
|
||||
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", pi.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 0)
|
||||
|
||||
|
||||
def test_payment_entry_against_ec(self):
|
||||
|
||||
payable = frappe.db.get_value('Company', "_Test Company", 'default_payable_account')
|
||||
ec = make_expense_claim(payable, 300, 300, "_Test Company","Travel Expenses - _TC")
|
||||
pe = get_payment_entry("Expense Claim", ec.name, bank_account="_Test Bank USD - _TC", bank_amount=300)
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.source_exchange_rate = 1
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
[payable, 300, 0, ec.name],
|
||||
["_Test Bank USD - _TC", 0, 300, None]
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Expense Claim", ec.name, "total_sanctioned_amount")) - \
|
||||
flt(frappe.db.get_value("Expense Claim", ec.name, "total_amount_reimbursed"))
|
||||
self.assertEqual(outstanding_amount, 0)
|
||||
|
||||
def test_payment_entry_against_si_usd_to_inr(self):
|
||||
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
pe = get_payment_entry("Sales Invoice", si.name, party_amount=20,
|
||||
pe = get_payment_entry("Sales Invoice", si.name, party_amount=20,
|
||||
bank_account="_Test Bank - _TC", bank_amount=900)
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
|
||||
|
||||
self.assertEqual(pe.difference_amount, 100)
|
||||
|
||||
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Exchange Gain/Loss - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
@@ -101,15 +124,15 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
})
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Receivable USD - _TC", 0, 1000, si.name],
|
||||
["_Test Bank - _TC", 900, 0, None],
|
||||
["_Test Exchange Gain/Loss - _TC", 100.0, 0, None],
|
||||
])
|
||||
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 80)
|
||||
|
||||
@@ -140,7 +163,7 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
pe.source_exchange_rate, 65.1,
|
||||
"{0} is not equal to {1}".format(pe.source_exchange_rate, 65.1)
|
||||
)
|
||||
|
||||
|
||||
def test_internal_transfer_usd_to_inr(self):
|
||||
pe = frappe.new_doc("Payment Entry")
|
||||
pe.payment_type = "Internal Transfer"
|
||||
@@ -152,31 +175,31 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
pe.received_amount = 4500
|
||||
pe.reference_no = "2"
|
||||
pe.reference_date = nowdate()
|
||||
|
||||
|
||||
pe.setup_party_account_field()
|
||||
pe.set_missing_values()
|
||||
pe.set_exchange_rate()
|
||||
pe.set_amounts()
|
||||
|
||||
|
||||
self.assertEquals(pe.difference_amount, 500)
|
||||
|
||||
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Exchange Gain/Loss - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"amount": 500
|
||||
})
|
||||
|
||||
|
||||
pe.insert()
|
||||
pe.submit()
|
||||
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Bank USD - _TC", 0, 5000, None],
|
||||
["_Test Bank - _TC", 4500, 0, None],
|
||||
["_Test Exchange Gain/Loss - _TC", 500.0, 0, None],
|
||||
])
|
||||
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
|
||||
def test_payment_against_negative_sales_invoice(self):
|
||||
pe1 = frappe.new_doc("Payment Entry")
|
||||
pe1.payment_type = "Pay"
|
||||
@@ -186,33 +209,33 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
pe1.paid_from = "_Test Cash - _TC"
|
||||
pe1.paid_amount = 100
|
||||
pe1.received_amount = 100
|
||||
|
||||
|
||||
self.assertRaises(InvalidPaymentEntry, pe1.validate)
|
||||
|
||||
|
||||
si1 = create_sales_invoice()
|
||||
|
||||
|
||||
# create full payment entry against si1
|
||||
pe2 = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Cash - _TC")
|
||||
pe2.insert()
|
||||
pe2.submit()
|
||||
|
||||
|
||||
# create return entry against si1
|
||||
create_sales_invoice(is_return=1, return_against=si1.name, qty=-1)
|
||||
si1_outstanding = frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount")
|
||||
self.assertEqual(si1_outstanding, -100)
|
||||
|
||||
|
||||
# pay more than outstanding against si1
|
||||
pe3 = get_payment_entry("Sales Invoice", si1.name, bank_account="_Test Cash - _TC")
|
||||
pe3.paid_amount = pe3.received_amount = 300
|
||||
self.assertRaises(InvalidPaymentEntry, pe3.validate)
|
||||
|
||||
|
||||
# pay negative outstanding against si1
|
||||
pe3.paid_to = "Debtors - _TC"
|
||||
pe3.paid_amount = pe3.received_amount = 100
|
||||
|
||||
|
||||
pe3.insert()
|
||||
pe3.submit()
|
||||
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["Debtors - _TC", 100, 0, si1.name],
|
||||
["_Test Cash - _TC", 0, 100, None]
|
||||
@@ -228,10 +251,10 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si1.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, -100)
|
||||
|
||||
|
||||
def validate_gl_entries(self, voucher_no, expected_gle):
|
||||
gl_entries = self.get_gle(voucher_no)
|
||||
|
||||
|
||||
self.assertTrue(gl_entries)
|
||||
|
||||
for i, gle in enumerate(gl_entries):
|
||||
@@ -239,8 +262,70 @@ class TestPaymentEntry(unittest.TestCase):
|
||||
self.assertEquals(expected_gle[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_gle[gle.account][2], gle.credit)
|
||||
self.assertEquals(expected_gle[gle.account][3], gle.against_voucher)
|
||||
|
||||
|
||||
def get_gle(self, voucher_no):
|
||||
return frappe.db.sql("""select account, debit, credit, against_voucher
|
||||
from `tabGL Entry` where voucher_type='Payment Entry' and voucher_no=%s
|
||||
order by account asc""", voucher_no, as_dict=1)
|
||||
|
||||
def test_payment_entry_write_off_difference(self):
|
||||
si = create_sales_invoice()
|
||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Cash - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.received_amount = pe.paid_amount = 110
|
||||
pe.insert()
|
||||
|
||||
self.assertEqual(pe.unallocated_amount, 10)
|
||||
|
||||
pe.received_amount = pe.paid_amount = 95
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Write Off - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"amount": 5
|
||||
})
|
||||
pe.save()
|
||||
|
||||
self.assertEqual(pe.unallocated_amount, 0)
|
||||
self.assertEqual(pe.difference_amount, 0)
|
||||
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["Debtors - _TC", 0, 100, si.name],
|
||||
["_Test Cash - _TC", 95, 0, None],
|
||||
["_Test Write Off - _TC", 5, 0, None]
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
def test_payment_entry_exchange_gain_loss(self):
|
||||
si = create_sales_invoice(customer="_Test Customer USD", debit_to="_Test Receivable USD - _TC",
|
||||
currency="USD", conversion_rate=50)
|
||||
pe = get_payment_entry("Sales Invoice", si.name, bank_account="_Test Bank USD - _TC")
|
||||
pe.reference_no = "1"
|
||||
pe.reference_date = "2016-01-01"
|
||||
pe.target_exchange_rate = 55
|
||||
|
||||
pe.append("deductions", {
|
||||
"account": "_Test Exchange Gain/Loss - _TC",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"amount": -500
|
||||
})
|
||||
pe.save()
|
||||
|
||||
self.assertEqual(pe.unallocated_amount, 0)
|
||||
self.assertEqual(pe.difference_amount, 0)
|
||||
|
||||
pe.submit()
|
||||
|
||||
expected_gle = dict((d[0], d) for d in [
|
||||
["_Test Receivable USD - _TC", 0, 5000, si.name],
|
||||
["_Test Bank USD - _TC", 5500, 0, None],
|
||||
["_Test Exchange Gain/Loss - _TC", 0, 500, None],
|
||||
])
|
||||
|
||||
self.validate_gl_entries(pe.name, expected_gle)
|
||||
|
||||
outstanding_amount = flt(frappe.db.get_value("Sales Invoice", si.name, "outstanding_amount"))
|
||||
self.assertEqual(outstanding_amount, 0)
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
QUnit.module('Payment Entry');
|
||||
|
||||
QUnit.test("test payment entry", function(assert) {
|
||||
assert.expect(6);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'item_code': 'Test Product 1'},
|
||||
{'qty': 1},
|
||||
{'rate': 101},
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Make'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Payment'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.equal(frappe.get_route()[1], 'Payment Entry',
|
||||
'made payment entry');
|
||||
assert.equal(cur_frm.doc.party, 'Test Customer 1',
|
||||
'customer set in payment entry');
|
||||
assert.equal(cur_frm.doc.paid_amount, 101,
|
||||
'paid amount set in payment entry');
|
||||
assert.equal(cur_frm.doc.references[0].allocated_amount, 101,
|
||||
'amount allocated against sales invoice');
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.set_value('paid_amount', 100),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
frappe.model.set_value("Payment Entry Reference", cur_frm.doc.references[0].name,
|
||||
"allocated_amount", 101);
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Write Off Difference Amount'),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.difference_amount, 0, 'difference amount is zero');
|
||||
assert.equal(cur_frm.doc.deductions[0].amount, 1, 'Write off amount = 1');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,60 @@
|
||||
QUnit.module('Payment Entry');
|
||||
|
||||
QUnit.test("test payment entry", function(assert) {
|
||||
assert.expect(7 );
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Invoice', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{bill_no: 'in1234'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 2},
|
||||
{'item_code': 'Test Product 1'},
|
||||
{'rate':1000},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{supplier_address: 'Test1-Billing'},
|
||||
{contact_person: 'Contact 3-Test Supplier'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is just a Test'}
|
||||
]);
|
||||
},
|
||||
|
||||
() => cur_frm.save(),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Make'),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.click_link('Payment'),
|
||||
() => frappe.timeout(3),
|
||||
() => cur_frm.set_value('mode_of_payment','Cash'),
|
||||
() => frappe.timeout(3),
|
||||
() => {
|
||||
assert.equal(frappe.get_route()[1], 'Payment Entry',
|
||||
'made payment entry');
|
||||
assert.equal(cur_frm.doc.party, 'Test Supplier',
|
||||
'supplier set in payment entry');
|
||||
assert.equal(cur_frm.doc.paid_amount, 2000,
|
||||
'paid amount set in payment entry');
|
||||
assert.equal(cur_frm.doc.references[0].allocated_amount, 2000,
|
||||
'amount allocated against purchase invoice');
|
||||
assert.equal(cur_frm.doc.references[0].bill_no, 'in1234',
|
||||
'invoice number allocated against purchase invoice');
|
||||
assert.equal(cur_frm.get_field('total_allocated_amount').value, 2000,
|
||||
'correct amount allocated in Write Off');
|
||||
assert.equal(cur_frm.get_field('unallocated_amount').value, 0,
|
||||
'correct amount unallocated in Write Off');
|
||||
},
|
||||
|
||||
() => cur_frm.save(),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
QUnit.module('Accounts');
|
||||
|
||||
QUnit.test("test payment entry", function(assert) {
|
||||
assert.expect(1);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Payment Entry', [
|
||||
{payment_type:'Receive'},
|
||||
{mode_of_payment:'Cash'},
|
||||
{party_type:'Customer'},
|
||||
{party:'Test Customer 3'},
|
||||
{paid_amount:675},
|
||||
{reference_no:123},
|
||||
{reference_date: frappe.datetime.add_days(frappe.datetime.nowdate(), 0)},
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.total_allocated_amount==675, "Allocated AmountCorrect");
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -0,0 +1,67 @@
|
||||
QUnit.module('Payment Entry');
|
||||
|
||||
QUnit.test("test payment entry", function(assert) {
|
||||
assert.expect(8);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{company: 'For Testing'},
|
||||
{currency: 'INR'},
|
||||
{selling_price_list: '_Test Price List'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 1},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => cur_frm.save(),
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1.5),
|
||||
() => frappe.click_button('Close'),
|
||||
() => frappe.timeout(0.5),
|
||||
() => frappe.click_button('Make'),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_link('Payment'),
|
||||
() => frappe.timeout(2),
|
||||
() => cur_frm.set_value("paid_to", "_Test Cash - FT"),
|
||||
() => frappe.timeout(0.5),
|
||||
() => {
|
||||
assert.equal(frappe.get_route()[1], 'Payment Entry', 'made payment entry');
|
||||
assert.equal(cur_frm.doc.party, 'Test Customer 1', 'customer set in payment entry');
|
||||
assert.equal(cur_frm.doc.paid_from, 'Debtors - FT', 'customer account set in payment entry');
|
||||
assert.equal(cur_frm.doc.paid_amount, 100, 'paid amount set in payment entry');
|
||||
assert.equal(cur_frm.doc.references[0].allocated_amount, 100,
|
||||
'amount allocated against sales invoice');
|
||||
},
|
||||
() => cur_frm.set_value('paid_amount', 95),
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
frappe.model.set_value("Payment Entry Reference",
|
||||
cur_frm.doc.references[0].name, "allocated_amount", 100);
|
||||
},
|
||||
() => frappe.timeout(.5),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.difference_amount, 5, 'difference amount is 5');
|
||||
},
|
||||
() => {
|
||||
frappe.db.set_value("Company", "For Testing", "write_off_account", "_Test Write Off - FT");
|
||||
frappe.timeout(1);
|
||||
frappe.db.set_value("Company", "For Testing",
|
||||
"exchange_gain_loss_account", "_Test Exchange Gain/Loss - FT");
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Write Off Difference Amount'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.difference_amount, 0, 'difference amount is zero');
|
||||
assert.equal(cur_frm.doc.deductions[0].amount, 5, 'Write off amount = 5');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
@@ -12,6 +13,7 @@
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -42,6 +44,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -72,6 +75,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -101,6 +105,38 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "",
|
||||
"fieldname": "bill_no",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Supplier Invoice No",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -129,6 +165,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -158,6 +195,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -187,6 +225,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -216,10 +255,12 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:(doc.reference_doctype=='Purchase Invoice')",
|
||||
"fieldname": "exchange_rate",
|
||||
"fieldtype": "Float",
|
||||
"hidden": 0,
|
||||
@@ -245,17 +286,17 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-17 16:47:17.156256",
|
||||
"modified": "2017-10-16 17:37:01.192312",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Payment Entry Reference",
|
||||
@@ -270,4 +311,4 @@
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ from erpnext.accounts.party import get_party_account
|
||||
from erpnext.accounts.utils import get_account_currency
|
||||
from erpnext.accounts.doctype.payment_entry.payment_entry import get_payment_entry, get_company_defaults
|
||||
from frappe.integrations.utils import get_payment_gateway_controller
|
||||
from frappe.utils.background_jobs import enqueue
|
||||
|
||||
class PaymentRequest(Document):
|
||||
def validate(self):
|
||||
@@ -34,15 +35,16 @@ class PaymentRequest(Document):
|
||||
|
||||
def on_submit(self):
|
||||
send_mail = True
|
||||
self.make_communication_entry()
|
||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||
|
||||
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
|
||||
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart") \
|
||||
or self.flags.mute_email:
|
||||
send_mail = False
|
||||
|
||||
if send_mail and not self.flags.mute_email:
|
||||
if send_mail:
|
||||
self.set_payment_request_url()
|
||||
self.send_email()
|
||||
self.make_communication_entry()
|
||||
|
||||
def on_cancel(self):
|
||||
self.check_if_payment_entry_exists()
|
||||
@@ -50,7 +52,7 @@ class PaymentRequest(Document):
|
||||
|
||||
def make_invoice(self):
|
||||
ref_doc = frappe.get_doc(self.reference_doctype, self.reference_name)
|
||||
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
|
||||
if (hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart"):
|
||||
from erpnext.selling.doctype.sales_order.sales_order import make_sales_invoice
|
||||
si = make_sales_invoice(self.reference_name, ignore_permissions=True)
|
||||
si = si.insert(ignore_permissions=True)
|
||||
@@ -67,16 +69,19 @@ class PaymentRequest(Document):
|
||||
self.db_set('status', 'Initiated')
|
||||
|
||||
def get_payment_url(self):
|
||||
data = frappe.db.get_value(self.reference_doctype, self.reference_name,
|
||||
["company", "customer_name"], as_dict=1)
|
||||
if self.reference_doctype != "Fees":
|
||||
data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["company", "customer_name"], as_dict=1)
|
||||
else:
|
||||
data = frappe.db.get_value(self.reference_doctype, self.reference_name, ["student_name"], as_dict=1)
|
||||
data.update({"company": frappe.defaults.get_defaults().company})
|
||||
|
||||
controller = get_payment_gateway_controller(self.payment_gateway)
|
||||
controller.validate_transaction_currency(self.currency)
|
||||
|
||||
return controller.get_payment_url(**{
|
||||
"amount": flt(self.grand_total, self.precision("grand_total")),
|
||||
"title": data.company,
|
||||
"description": self.subject,
|
||||
"title": data.company.encode("utf-8"),
|
||||
"description": self.subject.encode("utf-8"),
|
||||
"reference_doctype": "Payment Request",
|
||||
"reference_docname": self.name,
|
||||
"payer_email": self.email_to or frappe.session.user,
|
||||
@@ -142,9 +147,15 @@ class PaymentRequest(Document):
|
||||
|
||||
def send_email(self):
|
||||
"""send email with payment link"""
|
||||
frappe.sendmail(recipients=self.email_to, sender=None, subject=self.subject,
|
||||
message=self.get_message(), attachments=[frappe.attach_print(self.reference_doctype,
|
||||
self.reference_name, file_name=self.reference_name, print_format=self.print_format)])
|
||||
email_args = {
|
||||
"recipients": self.email_to,
|
||||
"sender": None,
|
||||
"subject": self.subject,
|
||||
"message": self.get_message(),
|
||||
"now": True,
|
||||
"attachments": [frappe.attach_print(self.reference_doctype, self.reference_name,
|
||||
file_name=self.reference_name, print_format=self.print_format)]}
|
||||
enqueue(method=frappe.sendmail, queue='short', timeout=300, async=True, **email_args)
|
||||
|
||||
def get_message(self):
|
||||
"""return message with payment gateway link"""
|
||||
@@ -216,12 +227,9 @@ def make_payment_request(**args):
|
||||
"""Make payment request"""
|
||||
|
||||
args = frappe._dict(args)
|
||||
|
||||
ref_doc = frappe.get_doc(args.dt, args.dn)
|
||||
|
||||
gateway_account = get_gateway_details(args) or frappe._dict()
|
||||
|
||||
grand_total = get_amount(ref_doc, args.dt)
|
||||
gateway_account = get_gateway_details(args) or frappe._dict()
|
||||
|
||||
existing_payment_request = frappe.db.get_value("Payment Request",
|
||||
{"reference_doctype": args.dt, "reference_name": args.dn, "docstatus": ["!=", 2]})
|
||||
@@ -244,22 +252,19 @@ def make_payment_request(**args):
|
||||
"reference_name": args.dn
|
||||
})
|
||||
|
||||
if args.return_doc:
|
||||
return pr
|
||||
|
||||
if args.mute_email:
|
||||
if args.order_type == "Shopping Cart" or args.mute_email:
|
||||
pr.flags.mute_email = True
|
||||
|
||||
if args.submit_doc:
|
||||
pr.insert(ignore_permissions=True)
|
||||
pr.submit()
|
||||
|
||||
if hasattr(ref_doc, "order_type") and getattr(ref_doc, "order_type") == "Shopping Cart":
|
||||
if args.order_type == "Shopping Cart":
|
||||
frappe.db.commit()
|
||||
frappe.local.response["type"] = "redirect"
|
||||
frappe.local.response["location"] = pr.get_payment_url()
|
||||
|
||||
if not args.cart:
|
||||
if args.return_doc:
|
||||
return pr
|
||||
|
||||
return pr.as_dict()
|
||||
@@ -275,6 +280,9 @@ def get_amount(ref_doc, dt):
|
||||
else:
|
||||
grand_total = flt(ref_doc.outstanding_amount) / ref_doc.conversion_rate
|
||||
|
||||
if dt == "Fees":
|
||||
grand_total = ref_doc.outstanding_amount
|
||||
|
||||
if grand_total > 0 :
|
||||
return grand_total
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class TestPaymentRequest(unittest.TestCase):
|
||||
|
||||
so_inr = make_sales_order(currency="INR")
|
||||
pr = make_payment_request(dt="Sales Order", dn=so_inr.name, recipient_id="saurabh@erpnext.com",
|
||||
mute_email=1, submit_doc=1)
|
||||
mute_email=1, submit_doc=1, return_doc=1)
|
||||
pe = pr.set_as_paid()
|
||||
|
||||
so_inr = frappe.get_doc("Sales Order", so_inr.name)
|
||||
@@ -81,7 +81,7 @@ class TestPaymentRequest(unittest.TestCase):
|
||||
currency="USD", conversion_rate=50)
|
||||
|
||||
pr = make_payment_request(dt="Sales Invoice", dn=si_usd.name, recipient_id="saurabh@erpnext.com",
|
||||
mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1)
|
||||
mute_email=1, payment_gateway="_Test Gateway - USD", submit_doc=1, return_doc=1)
|
||||
|
||||
pe = pr.set_as_paid()
|
||||
|
||||
|
||||
@@ -8,10 +8,6 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
||||
return { filters: { selling: 1 } };
|
||||
});
|
||||
|
||||
frm.set_query("print_format", function() {
|
||||
return { filters: { doc_type: "Sales Invoice", print_format_type: "Js"} };
|
||||
});
|
||||
|
||||
erpnext.queries.setup_queries(frm, "Warehouse", function() {
|
||||
return erpnext.queries.warehouse(frm.doc);
|
||||
});
|
||||
@@ -27,6 +23,27 @@ frappe.ui.form.on("POS Profile", "onload", function(frm) {
|
||||
});
|
||||
|
||||
frappe.ui.form.on('POS Profile', {
|
||||
setup: function(frm) {
|
||||
frm.set_query("online_print_format", function() {
|
||||
return {
|
||||
filters: [
|
||||
['Print Format', 'doc_type', '=', 'Sales Invoice'],
|
||||
['Print Format', 'print_format_type', '!=', 'Js'],
|
||||
]
|
||||
};
|
||||
});
|
||||
|
||||
frm.set_query("print_format", function() {
|
||||
return { filters: { doc_type: "Sales Invoice", print_format_type: "Js"} };
|
||||
});
|
||||
|
||||
frappe.db.get_value('POS Settings', {name: 'POS Settings'}, 'use_pos_in_offline_mode', (r) => {
|
||||
is_offline = r && cint(r.use_pos_in_offline_mode)
|
||||
frm.toggle_display('offline_pos_section', is_offline);
|
||||
frm.toggle_display('print_format_for_online', !is_offline);
|
||||
});
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if(frm.doc.company) {
|
||||
frm.trigger("toggle_display_account_head");
|
||||
|
||||
@@ -631,8 +631,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Point of Sale",
|
||||
"fieldname": "print_format",
|
||||
"fieldname": "print_format_for_online",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -641,7 +640,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Format",
|
||||
"label": "Print Format for Online",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
@@ -822,7 +821,7 @@
|
||||
"columns": 0,
|
||||
"fieldname": "apply_discount",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"hidden": 1,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
@@ -836,7 +835,7 @@
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
@@ -851,7 +850,7 @@
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Grand Total",
|
||||
"depends_on": "apply_discount",
|
||||
"depends_on": "",
|
||||
"fieldname": "apply_discount_on",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
@@ -883,7 +882,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "customer_details",
|
||||
"fieldname": "offline_pos_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -892,7 +891,7 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "New Customer Details",
|
||||
"label": "Offline POS Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@@ -969,6 +968,38 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Point of Sale",
|
||||
"fieldname": "print_format",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Format",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1291,7 +1322,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-28 03:40:03.253088",
|
||||
"modified": "2017-09-01 15:55:14.890452",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Profile",
|
||||
|
||||
@@ -14,6 +14,7 @@ class POSProfile(Document):
|
||||
self.check_for_duplicate()
|
||||
self.validate_all_link_fields()
|
||||
self.validate_duplicate_groups()
|
||||
self.check_default_payment()
|
||||
self.validate_customer_territory_group()
|
||||
|
||||
def check_for_duplicate(self):
|
||||
@@ -49,6 +50,14 @@ class POSProfile(Document):
|
||||
if len(customer_groups) != len(set(customer_groups)):
|
||||
frappe.throw(_("Duplicate customer group found in the cutomer group table"), title = "Duplicate Customer Group")
|
||||
|
||||
def check_default_payment(self):
|
||||
if self.payments:
|
||||
default_mode_of_payment = [d.default for d in self.payments if d.default]
|
||||
if not default_mode_of_payment:
|
||||
frappe.throw(_("Set default mode of payment"))
|
||||
|
||||
if len(default_mode_of_payment) > 1:
|
||||
frappe.throw(_("Multiple default mode of payment is not allowed"))
|
||||
def validate_customer_territory_group(self):
|
||||
if not self.territory:
|
||||
frappe.throw(_("Territory is Required in POS Profile"), title="Mandatory Field")
|
||||
|
||||
@@ -31,6 +31,8 @@ class TestPOSProfile(unittest.TestCase):
|
||||
frappe.db.sql("delete from `tabPOS Profile`")
|
||||
|
||||
def make_pos_profile():
|
||||
frappe.db.sql("delete from `tabPOS Profile`")
|
||||
|
||||
pos_profile = frappe.get_doc({
|
||||
"company": "_Test Company",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
|
||||
8
erpnext/accounts/doctype/pos_settings/pos_settings.js
Normal file
8
erpnext/accounts/doctype/pos_settings/pos_settings.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('POS Settings', {
|
||||
refresh: function() {
|
||||
|
||||
}
|
||||
});
|
||||
133
erpnext/accounts/doctype/pos_settings/pos_settings.json
Normal file
133
erpnext/accounts/doctype/pos_settings/pos_settings.json
Normal file
@@ -0,0 +1,133 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
"creation": "2017-08-28 16:46:41.732676",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0",
|
||||
"fieldname": "use_pos_in_offline_mode",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Use POS in Offline Mode",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 1,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-09-11 13:57:28.787023",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "POS Settings",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 0,
|
||||
"create": 0,
|
||||
"delete": 0,
|
||||
"email": 1,
|
||||
"export": 0,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 0,
|
||||
"role": "Sales User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 0,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
19
erpnext/accounts/doctype/pos_settings/pos_settings.py
Normal file
19
erpnext/accounts/doctype/pos_settings/pos_settings.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
from frappe.model.document import Document
|
||||
|
||||
class POSSettings(Document):
|
||||
def validate(self):
|
||||
self.set_link_for_pos()
|
||||
|
||||
def set_link_for_pos(self):
|
||||
link = 'pos' if self.use_pos_in_offline_mode else 'point-of-sale'
|
||||
desktop_icon = frappe.db.get_value('Desktop Icon',
|
||||
{'standard': 1, 'module_name': 'POS'}, 'name')
|
||||
|
||||
if desktop_icon:
|
||||
frappe.db.set_value('Desktop Icon', desktop_icon, 'link', link)
|
||||
23
erpnext/accounts/doctype/pos_settings/test_pos_settings.js
Normal file
23
erpnext/accounts/doctype/pos_settings/test_pos_settings.js
Normal file
@@ -0,0 +1,23 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: POS Settings", function (assert) {
|
||||
let done = assert.async();
|
||||
|
||||
// number of asserts
|
||||
assert.expect(1);
|
||||
|
||||
frappe.run_serially([
|
||||
// insert a new POS Settings
|
||||
() => frappe.tests.make('POS Settings', [
|
||||
// values to be set
|
||||
{key: 'value'}
|
||||
]),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.key, 'value');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
|
||||
});
|
||||
@@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import unittest
|
||||
|
||||
class TestPOSSettings(unittest.TestCase):
|
||||
pass
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "field:title",
|
||||
@@ -12,6 +13,7 @@
|
||||
"editable_grid": 0,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -40,6 +42,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -69,6 +72,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -99,6 +103,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -129,6 +134,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -159,6 +165,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -189,6 +196,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -217,6 +225,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -247,6 +256,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -275,6 +285,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -303,6 +314,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -331,6 +343,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -359,6 +372,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -387,6 +401,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -417,6 +432,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -447,6 +463,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -477,6 +494,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -507,6 +525,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -537,6 +556,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -567,6 +587,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -597,6 +618,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -627,6 +649,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -655,6 +678,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -683,6 +707,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -711,6 +736,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -739,6 +765,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -767,6 +794,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -796,6 +824,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -824,6 +853,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -851,6 +881,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -880,6 +911,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -910,6 +942,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -941,6 +974,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -969,6 +1003,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -988,7 +1023,7 @@
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "2",
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
@@ -1000,6 +1035,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1028,6 +1064,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1058,6 +1095,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1085,13 +1123,14 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.price_or_discount==\"Price\"",
|
||||
"fieldname": "price",
|
||||
"fieldtype": "Float",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -1114,6 +1153,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1143,6 +1183,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1173,6 +1214,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1202,6 +1244,7 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
@@ -1230,18 +1273,18 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"icon": "fa fa-gift",
|
||||
"idx": 1,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-02-17 16:21:28.446208",
|
||||
"modified": "2017-09-27 08:31:38.432574",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Pricing Rule",
|
||||
|
||||
@@ -285,8 +285,9 @@ def get_pricing_rules(args):
|
||||
|
||||
def filter_pricing_rules(args, pricing_rules):
|
||||
# filter for qty
|
||||
stock_qty = args.get('qty') * args.get('conversion_factor', 1)
|
||||
if pricing_rules:
|
||||
stock_qty = flt(args.get('qty')) * args.get('conversion_factor', 1)
|
||||
|
||||
pricing_rules = filter(lambda x: (flt(stock_qty)>=flt(x.min_qty)
|
||||
and (flt(stock_qty)<=x.max_qty if x.max_qty else True)), pricing_rules)
|
||||
|
||||
@@ -347,6 +348,8 @@ def apply_internal_priority(pricing_rules, field_set, args):
|
||||
return filtered_rules or pricing_rules
|
||||
|
||||
def set_transaction_type(args):
|
||||
if args.transaction_type:
|
||||
return
|
||||
if args.doctype in ("Opportunity", "Quotation", "Sales Order", "Delivery Note", "Sales Invoice"):
|
||||
args.transaction_type = "selling"
|
||||
elif args.doctype in ("Material Request", "Supplier Quotation", "Purchase Order",
|
||||
@@ -355,4 +358,4 @@ def set_transaction_type(args):
|
||||
elif args.customer:
|
||||
args.transaction_type = "selling"
|
||||
else:
|
||||
args.transaction_type = "buying"
|
||||
args.transaction_type = "buying"
|
||||
|
||||
28
erpnext/accounts/doctype/pricing_rule/test_pricing_rule.js
Normal file
28
erpnext/accounts/doctype/pricing_rule/test_pricing_rule.js
Normal file
@@ -0,0 +1,28 @@
|
||||
QUnit.module('Pricing Rule"');
|
||||
|
||||
QUnit.test("test pricing rule", function(assert) {
|
||||
assert.expect(2);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make("Pricing Rule", [
|
||||
{title: 'Test Pricing Rule'},
|
||||
{item_code:'Test Product 2'},
|
||||
{selling:1},
|
||||
{applicable_for:'Customer'},
|
||||
{customer:'Test Customer 3'},
|
||||
{min_qty:1},
|
||||
{max_qty:20},
|
||||
{valid_upto: frappe.datetime.add_days(frappe.defaults.get_default("year_end_date"), 1)},
|
||||
{discount_percentage:10},
|
||||
{for_price_list:'Standard Selling'}
|
||||
]);
|
||||
},
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.item_code=='Test Product 2');
|
||||
assert.ok(cur_frm.doc.customer=='Test Customer 3');
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -46,6 +46,12 @@ erpnext.accounts.PurchaseInvoice = erpnext.buying.BuyingController.extend({
|
||||
cur_frm.add_custom_button(__('Return / Debit Note'),
|
||||
this.make_debit_note, __("Make"));
|
||||
}
|
||||
|
||||
if(!doc.subscription) {
|
||||
cur_frm.add_custom_button(__('Subscription'), function() {
|
||||
erpnext.utils.make_subscription(doc.doctype, doc.name)
|
||||
}, __("Make"))
|
||||
}
|
||||
}
|
||||
|
||||
if(doc.docstatus===0) {
|
||||
@@ -343,6 +349,7 @@ frappe.ui.form.on("Purchase Invoice", {
|
||||
'Payment Entry': 'Payment'
|
||||
}
|
||||
},
|
||||
|
||||
onload: function(frm) {
|
||||
$.each(["warehouse", "rejected_warehouse"], function(i, field) {
|
||||
frm.set_query(field, "items", function() {
|
||||
@@ -370,5 +377,5 @@ frappe.ui.form.on("Purchase Invoice", {
|
||||
erpnext.buying.get_default_bom(frm);
|
||||
}
|
||||
frm.toggle_reqd("supplier_warehouse", frm.doc.is_subcontracted==="Yes");
|
||||
}
|
||||
})
|
||||
},
|
||||
})
|
||||
@@ -2072,6 +2072,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment (Company Currency)",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2166,6 +2197,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -3352,11 +3414,9 @@
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "is_recurring",
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus<2 && !doc.__islocal",
|
||||
"fieldname": "recurring_invoice",
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -3365,12 +3425,12 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Recurring Invoice",
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "fa fa-time",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@@ -3386,70 +3446,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus<2",
|
||||
"description": "",
|
||||
"fieldname": "is_recurring",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Recurring",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Select the period when the invoice will be generated automatically",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Recurring Type",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Monthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"depends_on": "",
|
||||
"description": "Start date of current invoice's period",
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
@@ -3480,7 +3477,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"depends_on": "",
|
||||
"description": "End date of current invoice's period",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
@@ -3505,138 +3502,13 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
|
||||
"fieldname": "submit_on_creation",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Submit on creation",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
|
||||
"description": "",
|
||||
"fieldname": "notify_by_email",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Notify by email",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "The day of the month on which auto invoice will be generated e.g. 05, 28 etc",
|
||||
"fieldname": "repeat_on_day_of_month",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Repeat on Day of Month",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "The date on which recurring invoice will be stop",
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "End Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_82",
|
||||
"fieldname": "column_break_114",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -3648,101 +3520,8 @@
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "The date on which next invoice will be generated. It is generated on submit.",
|
||||
"fieldname": "next_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Next Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "The unique id for tracking all recurring invoices. It is generated on submit.",
|
||||
"fieldname": "recurring_id",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Recurring Id",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"description": "Enter Email Address separated by commas, invoice will be mailed automatically on particular date",
|
||||
"fieldname": "notification_email_address",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Notification Email Address",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@@ -3758,8 +3537,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring==1",
|
||||
"fieldname": "recurring_print_format",
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -3768,15 +3546,15 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Recurring Print Format",
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
@@ -3797,7 +3575,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-07-19 13:53:48.673757",
|
||||
"modified": "2017-10-24 12:51:51.199594",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Purchase Invoice",
|
||||
|
||||
@@ -15,14 +15,15 @@ from erpnext.stock import get_warehouse_account_map
|
||||
from erpnext.accounts.general_ledger import make_gl_entries, merge_similar_entries, delete_gl_entries
|
||||
from erpnext.accounts.doctype.gl_entry.gl_entry import update_outstanding_amt
|
||||
from erpnext.buying.utils import check_for_closed_status
|
||||
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
||||
|
||||
form_grid_templates = {
|
||||
"items": "templates/form_grid/item_grid.html"
|
||||
}
|
||||
|
||||
class PurchaseInvoice(BuyingController):
|
||||
def __init__(self, arg1, arg2=None):
|
||||
super(PurchaseInvoice, self).__init__(arg1, arg2)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(PurchaseInvoice, self).__init__(*args, **kwargs)
|
||||
self.status_updater = [{
|
||||
'source_dt': 'Purchase Invoice Item',
|
||||
'target_dt': 'Purchase Order Item',
|
||||
@@ -53,6 +54,9 @@ class PurchaseInvoice(BuyingController):
|
||||
if (self.is_paid == 1):
|
||||
self.validate_cash()
|
||||
|
||||
if self._action=="submit" and self.update_stock:
|
||||
self.make_batches('warehouse')
|
||||
|
||||
self.check_conversion_rate()
|
||||
self.validate_credit_to_acc()
|
||||
self.clear_unallocated_advances("Purchase Invoice Advance", "advances")
|
||||
@@ -350,6 +354,7 @@ class PurchaseInvoice(BuyingController):
|
||||
|
||||
self.make_payment_gl_entries(gl_entries)
|
||||
self.make_write_off_gl_entry(gl_entries)
|
||||
self.make_gle_for_rounding_adjustment(gl_entries)
|
||||
|
||||
return gl_entries
|
||||
|
||||
@@ -581,6 +586,21 @@ class PurchaseInvoice(BuyingController):
|
||||
})
|
||||
)
|
||||
|
||||
def make_gle_for_rounding_adjustment(self, gl_entries):
|
||||
if self.rounding_adjustment:
|
||||
round_off_account, round_off_cost_center = \
|
||||
get_round_off_account_and_cost_center(self.company)
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": round_off_account,
|
||||
"against": self.supplier,
|
||||
"debit_in_account_currency": self.rounding_adjustment,
|
||||
"debit": self.base_rounding_adjustment,
|
||||
"cost_center": round_off_cost_center,
|
||||
}
|
||||
))
|
||||
|
||||
def on_cancel(self):
|
||||
self.check_for_closed_status()
|
||||
|
||||
@@ -664,7 +684,7 @@ class PurchaseInvoice(BuyingController):
|
||||
if account_type != 'Fixed Asset':
|
||||
frappe.throw(_("Row {0}# Account must be of type 'Fixed Asset'").format(d.idx))
|
||||
|
||||
def on_recurring(self, reference_doc):
|
||||
def on_recurring(self, reference_doc, subscription_doc):
|
||||
self.due_date = None
|
||||
|
||||
@frappe.whitelist()
|
||||
|
||||
@@ -8,7 +8,8 @@ def get_data():
|
||||
'Payment Entry': 'reference_name',
|
||||
'Payment Request': 'reference_name',
|
||||
'Landed Cost Voucher': 'receipt_document',
|
||||
'Purchase Invoice': 'return_against'
|
||||
'Purchase Invoice': 'return_against',
|
||||
'Subscription': 'reference_document'
|
||||
},
|
||||
'internal_links': {
|
||||
'Purchase Order': ['items', 'purchase_order'],
|
||||
@@ -27,5 +28,9 @@ def get_data():
|
||||
'label': _('Returns'),
|
||||
'items': ['Purchase Invoice']
|
||||
},
|
||||
{
|
||||
'label': _('Subscription'),
|
||||
'items': ['Subscription']
|
||||
},
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
QUnit.module('Purchaes Invoice');
|
||||
|
||||
QUnit.test("test purchase invoice", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Invoice', [
|
||||
{supplier: 'Test Supplier'},
|
||||
{bill_no: 'in123'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
{'rate':100},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{supplier_address: 'Test1-Billing'},
|
||||
{contact_person: 'Contact 3-Test Supplier'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// get tax account head details
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(1),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -256,10 +256,6 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertFalse(frappe.db.sql("""select name from `tabJournal Entry Account`
|
||||
where reference_type='Purchase Invoice' and reference_name=%s""", pi.name))
|
||||
|
||||
def test_recurring_invoice(self):
|
||||
from erpnext.controllers.tests.test_recurring_document import test_recurring_document
|
||||
test_recurring_document(self, test_records)
|
||||
|
||||
def test_total_purchase_cost_for_project(self):
|
||||
existing_purchase_cost = frappe.db.sql("""select sum(base_net_amount)
|
||||
from `tabPurchase Invoice Item` where project = '_Test Project' and docstatus=1""")
|
||||
@@ -403,6 +399,27 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
self.assertEquals(expected_gl_entries[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_gl_entries[gle.account][2], gle.credit)
|
||||
|
||||
def test_auto_batch(self):
|
||||
item_code = frappe.db.get_value('Item',
|
||||
{'has_batch_no': 1, 'create_new_batch':1}, 'name')
|
||||
|
||||
if not item_code:
|
||||
doc = frappe.get_doc({
|
||||
'doctype': 'Item',
|
||||
'is_stock_item': 1,
|
||||
'item_code': 'test batch item',
|
||||
'item_group': 'Products',
|
||||
'has_batch_no': 1,
|
||||
'create_new_batch': 1
|
||||
}).insert(ignore_permissions=True)
|
||||
item_code = doc.name
|
||||
|
||||
pi = make_purchase_invoice(update_stock=1, posting_date=frappe.utils.nowdate(),
|
||||
posting_time=frappe.utils.nowtime(), item_code=item_code)
|
||||
|
||||
self.assertTrue(frappe.db.get_value('Batch',
|
||||
{'item': item_code, 'reference_name': pi.name}))
|
||||
|
||||
def test_update_stock_and_purchase_return(self):
|
||||
actual_qty_0 = get_qty_after_transaction()
|
||||
|
||||
@@ -456,6 +473,7 @@ class TestPurchaseInvoice(unittest.TestCase):
|
||||
import test_records as jv_test_records
|
||||
|
||||
jv = frappe.copy_doc(jv_test_records[1])
|
||||
jv.accounts[0].is_advance = 'Yes'
|
||||
jv.insert()
|
||||
jv.submit()
|
||||
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
QUnit.module('Sales Taxes and Charges Template');
|
||||
|
||||
QUnit.test("test sales taxes and charges template", function(assert) {
|
||||
assert.expect(1);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Purchase Taxes and Charges Template', [
|
||||
{title: "TEST In State GST"},
|
||||
{taxes:[
|
||||
[
|
||||
{charge_type:"On Net Total"},
|
||||
{account_head:"CGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
|
||||
],
|
||||
[
|
||||
{charge_type:"On Net Total"},
|
||||
{account_head:"SGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -88,7 +88,7 @@ def update_pos_profile_data(doc, pos_profile, company_data):
|
||||
doc.naming_series = pos_profile.get('naming_series') or 'SINV-'
|
||||
doc.letter_head = pos_profile.get('letter_head') or company_data.default_letter_head
|
||||
doc.ignore_pricing_rule = pos_profile.get('ignore_pricing_rule') or 0
|
||||
doc.apply_discount_on = pos_profile.get('apply_discount_on') if pos_profile.get('apply_discount') else ''
|
||||
doc.apply_discount_on = pos_profile.get('apply_discount_on') or 'Grand Total'
|
||||
doc.customer_group = pos_profile.get('customer_group') or get_root('Customer Group')
|
||||
doc.territory = pos_profile.get('territory') or get_root('Territory')
|
||||
doc.terms = frappe.db.get_value('Terms and Conditions', pos_profile.get('tc_name'), 'terms') or doc.terms or ''
|
||||
@@ -151,13 +151,8 @@ def get_items_list(pos_profile):
|
||||
|
||||
def get_item_groups(pos_profile):
|
||||
item_group_dict = {}
|
||||
if pos_profile.get('item_groups'):
|
||||
item_groups = []
|
||||
for d in pos_profile.get('item_groups'):
|
||||
item_groups.extend(get_child_nodes('Item Group', d.item_group))
|
||||
else:
|
||||
item_groups = frappe.db.sql("""Select name,
|
||||
lft, rgt from `tabItem Group` order by lft""", as_dict=1)
|
||||
item_groups = frappe.db.sql("""Select name,
|
||||
lft, rgt from `tabItem Group` order by lft""", as_dict=1)
|
||||
|
||||
for data in item_groups:
|
||||
item_group_dict[data.name] = [data.lft, data.rgt]
|
||||
@@ -325,8 +320,7 @@ def make_invoice(doc_list={}, email_queue_list={}, customers_list={}):
|
||||
si_doc.set_posting_time = 1
|
||||
si_doc.customer = get_customer_id(doc)
|
||||
si_doc.due_date = doc.get('posting_date')
|
||||
submit_invoice(si_doc, name, doc)
|
||||
name_list.append(name)
|
||||
name_list = submit_invoice(si_doc, name, doc, name_list)
|
||||
else:
|
||||
name_list.append(name)
|
||||
|
||||
@@ -423,6 +417,7 @@ def make_contact(args,customer):
|
||||
'link_doctype': 'Customer',
|
||||
'link_name': customer
|
||||
})
|
||||
doc.flags.ignore_mandatory = True
|
||||
doc.save(ignore_permissions=True)
|
||||
|
||||
def make_address(args, customer):
|
||||
@@ -447,6 +442,7 @@ def make_address(args, customer):
|
||||
address.is_primary_address = 1
|
||||
address.is_shipping_address = 1
|
||||
address.update(args)
|
||||
address.flags.ignore_mandatory = True
|
||||
address.save(ignore_permissions = True)
|
||||
|
||||
def make_email_queue(email_queue):
|
||||
@@ -480,19 +476,33 @@ def validate_item(doc):
|
||||
frappe.db.commit()
|
||||
|
||||
|
||||
def submit_invoice(si_doc, name, doc):
|
||||
def submit_invoice(si_doc, name, doc, name_list):
|
||||
try:
|
||||
si_doc.insert()
|
||||
si_doc.submit()
|
||||
frappe.db.commit()
|
||||
except Exception, e:
|
||||
name_list.append(name)
|
||||
except Exception as e:
|
||||
if frappe.message_log: frappe.message_log.pop()
|
||||
frappe.db.rollback()
|
||||
save_invoice(e, si_doc, name)
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
name_list = save_invoice(doc, name, name_list)
|
||||
|
||||
def save_invoice(e, si_doc, name):
|
||||
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
|
||||
si_doc.docstatus = 0
|
||||
si_doc.flags.ignore_mandatory = True
|
||||
si_doc.due_date = si_doc.posting_date
|
||||
si_doc.insert()
|
||||
return name_list
|
||||
|
||||
def save_invoice(doc, name, name_list):
|
||||
try:
|
||||
if not frappe.db.exists('Sales Invoice', {'offline_pos_name': name}):
|
||||
si = frappe.new_doc('Sales Invoice')
|
||||
si.update(doc)
|
||||
si.set_posting_time = 1
|
||||
si.customer = get_customer_id(doc)
|
||||
si.due_date = doc.get('posting_date')
|
||||
si.flags.ignore_mandatory = True
|
||||
si.insert(ignore_permissions=True)
|
||||
frappe.db.commit()
|
||||
name_list.append(name)
|
||||
except Exception:
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
|
||||
return name_list
|
||||
|
||||
@@ -86,7 +86,11 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
this.make_payment_request, __("Make"));
|
||||
}
|
||||
|
||||
|
||||
if(!doc.subscription) {
|
||||
cur_frm.add_custom_button(__('Subscription'), function() {
|
||||
erpnext.utils.make_subscription(doc.doctype, doc.name)
|
||||
}, __("Make"))
|
||||
}
|
||||
}
|
||||
|
||||
// Show buttons only when pos view is active
|
||||
@@ -325,23 +329,6 @@ erpnext.accounts.SalesInvoiceController = erpnext.selling.SellingController.exte
|
||||
}
|
||||
|
||||
this.frm.refresh_fields();
|
||||
},
|
||||
|
||||
company_address: function() {
|
||||
var me = this;
|
||||
if(this.frm.doc.company_address) {
|
||||
frappe.call({
|
||||
method: "frappe.contacts.doctype.address.address.get_address_display",
|
||||
args: {"address_dict": this.frm.doc.company_address },
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
me.frm.set_value("company_address_display", r.message)
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
this.frm.set_value("company_address_display", "");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -352,7 +339,7 @@ $.extend(cur_frm.cscript, new erpnext.accounts.SalesInvoiceController({frm: cur_
|
||||
// ------------
|
||||
cur_frm.cscript.hide_fields = function(doc) {
|
||||
var parent_fields = ['project', 'due_date', 'is_opening', 'source', 'total_advance', 'get_advances',
|
||||
'advances', 'sales_partner', 'commission_rate', 'total_commission', 'advances', 'from_date', 'to_date'];
|
||||
'advances', 'advances', 'from_date', 'to_date'];
|
||||
|
||||
if(cint(doc.is_pos) == 1) {
|
||||
hide_field(parent_fields);
|
||||
@@ -533,6 +520,24 @@ frappe.ui.form.on('Sales Invoice', {
|
||||
};
|
||||
});
|
||||
},
|
||||
//When multiple companies are set up. in case company name is changed set default company address
|
||||
company:function(frm){
|
||||
if (frm.doc.company)
|
||||
{
|
||||
frappe.call({
|
||||
method:"frappe.contacts.doctype.address.address.get_default_address",
|
||||
args:{ doctype:'Company',name:frm.doc.company},
|
||||
callback: function(r){
|
||||
if (r.message){
|
||||
frm.set_value("company_address",r.message)
|
||||
}
|
||||
else {
|
||||
frm.set_value("company_address","")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
},
|
||||
|
||||
project: function(frm){
|
||||
frm.call({
|
||||
|
||||
@@ -1670,36 +1670,6 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "net_total",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Net Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -1731,6 +1701,36 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "net_total",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Net Total",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2337,6 +2337,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "base_rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment (Company Currency)",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Company:company:default_currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -2463,6 +2494,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "rounding_adjustment",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Rounding Adjustment",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "currency",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -4179,11 +4241,9 @@
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"collapsible_depends_on": "is_recurring",
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus<2 && !doc.__islocal",
|
||||
"fieldname": "recurring_invoice",
|
||||
"fieldname": "subscription_section",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
@@ -4192,230 +4252,12 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Recurring Invoice",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "fa fa-time",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break11",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Settings",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.docstatus<2",
|
||||
"description": "",
|
||||
"fieldname": "is_recurring",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Is Recurring",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "is_recurring",
|
||||
"description": "",
|
||||
"fieldname": "recurring_id",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Document",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Sales Invoice",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
|
||||
"description": "",
|
||||
"fieldname": "recurring_type",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Frequency",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
|
||||
"description": "",
|
||||
"fieldname": "repeat_on_day_of_month",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Repeat on Day of Month",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
|
||||
"description": "",
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "End Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
|
||||
"fieldname": "submit_on_creation",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Submit on creation",
|
||||
"label": "Subscription Section",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@@ -4431,133 +4273,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.recurring_id === doc.name",
|
||||
"description": "",
|
||||
"fieldname": "notify_by_email",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Notify by email",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name",
|
||||
"description": "",
|
||||
"fieldname": "notification_email_address",
|
||||
"fieldtype": "Code",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Notification Email Address",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Email",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.is_recurring && doc.notify_by_email && doc.recurring_id === doc.name",
|
||||
"fieldname": "recurring_print_format",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Recurring Print Format",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break12",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "This Document",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0,
|
||||
"width": "50%"
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "is_recurring",
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fieldname": "from_date",
|
||||
"fieldtype": "Date",
|
||||
@@ -4588,7 +4304,7 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "is_recurring",
|
||||
"depends_on": "",
|
||||
"description": "",
|
||||
"fieldname": "to_date",
|
||||
"fieldtype": "Date",
|
||||
@@ -4619,10 +4335,8 @@
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "is_recurring",
|
||||
"description": "",
|
||||
"fieldname": "next_date",
|
||||
"fieldtype": "Date",
|
||||
"fieldname": "column_break_140",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
@@ -4630,11 +4344,11 @@
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Next Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
@@ -4644,6 +4358,37 @@
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "subscription",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subscription",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
@@ -4688,7 +4433,7 @@
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"menu_index": 0,
|
||||
"modified": "2017-07-07 13:05:37.469682",
|
||||
"modified": "2017-10-24 12:46:48.331723",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice",
|
||||
|
||||
@@ -19,14 +19,16 @@ from erpnext.accounts.doctype.asset.depreciation \
|
||||
import get_disposal_account_and_cost_center, get_gl_entries_on_asset_disposal
|
||||
from erpnext.stock.doctype.batch.batch import set_batch_nos
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos, get_delivery_note_serial_no
|
||||
from erpnext.setup.doctype.company.company import update_company_current_month_sales
|
||||
from erpnext.accounts.general_ledger import get_round_off_account_and_cost_center
|
||||
|
||||
form_grid_templates = {
|
||||
"items": "templates/form_grid/item_grid.html"
|
||||
}
|
||||
|
||||
class SalesInvoice(SellingController):
|
||||
def __init__(self, arg1, arg2=None):
|
||||
super(SalesInvoice, self).__init__(arg1, arg2)
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SalesInvoice, self).__init__(*args, **kwargs)
|
||||
self.status_updater = [{
|
||||
'source_dt': 'Sales Invoice Item',
|
||||
'target_field': 'billed_amt',
|
||||
@@ -68,6 +70,7 @@ class SalesInvoice(SellingController):
|
||||
self.clear_unallocated_advances("Sales Invoice Advance", "advances")
|
||||
self.add_remarks()
|
||||
self.validate_write_off_account()
|
||||
self.validate_duplicate_offline_pos_entry()
|
||||
self.validate_account_for_change_amount()
|
||||
self.validate_fixed_asset()
|
||||
self.set_income_account_for_fixed_assets()
|
||||
@@ -106,9 +109,9 @@ class SalesInvoice(SellingController):
|
||||
def on_submit(self):
|
||||
self.validate_pos_paid_amount()
|
||||
|
||||
if not self.recurring_id:
|
||||
if not self.subscription:
|
||||
frappe.get_doc('Authorization Control').validate_approving_authority(self.doctype,
|
||||
self.company, self.base_grand_total, self)
|
||||
self.company, self.base_grand_total, self)
|
||||
|
||||
self.check_prev_docstatus()
|
||||
|
||||
@@ -140,7 +143,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
self.update_time_sheet(self.name)
|
||||
|
||||
frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales', company=self.company)
|
||||
self.update_current_month_sales()
|
||||
|
||||
def validate_pos_paid_amount(self):
|
||||
if len(self.payments) == 0 and self.is_pos:
|
||||
@@ -178,6 +181,15 @@ class SalesInvoice(SellingController):
|
||||
self.make_gl_entries_on_cancel()
|
||||
frappe.db.set(self, 'status', 'Cancelled')
|
||||
|
||||
self.update_current_month_sales()
|
||||
|
||||
def update_current_month_sales(self):
|
||||
if frappe.flags.in_test:
|
||||
update_company_current_month_sales(self.company)
|
||||
else:
|
||||
frappe.enqueue('erpnext.setup.doctype.company.company.update_company_current_month_sales',
|
||||
company=self.company)
|
||||
|
||||
def update_status_updater_args(self):
|
||||
if cint(self.update_stock):
|
||||
self.status_updater.extend([{
|
||||
@@ -303,7 +315,7 @@ class SalesInvoice(SellingController):
|
||||
|
||||
for fieldname in ('territory', 'naming_series', 'currency', 'taxes_and_charges', 'letter_head', 'tc_name',
|
||||
'selling_price_list', 'company', 'select_print_heading', 'cash_bank_account',
|
||||
'write_off_account', 'write_off_cost_center'):
|
||||
'write_off_account', 'write_off_cost_center', 'apply_discount_on'):
|
||||
if (not for_validate) or (for_validate and not self.get(fieldname)):
|
||||
self.set(fieldname, pos.get(fieldname))
|
||||
|
||||
@@ -451,6 +463,12 @@ class SalesInvoice(SellingController):
|
||||
if flt(self.write_off_amount) and not self.write_off_account:
|
||||
msgprint(_("Please enter Write Off Account"), raise_exception=1)
|
||||
|
||||
def validate_duplicate_offline_pos_entry(self):
|
||||
if self.is_pos and self.offline_pos_name \
|
||||
and frappe.db.get_value('Sales Invoice',
|
||||
{'offline_pos_name': self.offline_pos_name, 'docstatus': 1}):
|
||||
frappe.throw(_("Duplicate offline pos sales invoice {0}").format(self.offline_pos_name))
|
||||
|
||||
def validate_account_for_change_amount(self):
|
||||
if flt(self.change_amount) and not self.account_for_change_amount:
|
||||
msgprint(_("Please enter Account for Change Amount"), raise_exception=1)
|
||||
@@ -615,6 +633,7 @@ class SalesInvoice(SellingController):
|
||||
self.make_gle_for_change_amount(gl_entries)
|
||||
|
||||
self.make_write_off_gl_entry(gl_entries)
|
||||
self.make_gle_for_rounding_adjustment(gl_entries)
|
||||
|
||||
return gl_entries
|
||||
|
||||
@@ -774,6 +793,21 @@ class SalesInvoice(SellingController):
|
||||
}, write_off_account_currency)
|
||||
)
|
||||
|
||||
def make_gle_for_rounding_adjustment(self, gl_entries):
|
||||
if self.rounding_adjustment:
|
||||
round_off_account, round_off_cost_center = \
|
||||
get_round_off_account_and_cost_center(self.company)
|
||||
|
||||
gl_entries.append(
|
||||
self.get_gl_dict({
|
||||
"account": round_off_account,
|
||||
"against": self.customer,
|
||||
"credit_in_account_currency": self.rounding_adjustment,
|
||||
"credit": self.base_rounding_adjustment,
|
||||
"cost_center": round_off_cost_center,
|
||||
}
|
||||
))
|
||||
|
||||
def update_billing_status_in_dn(self, update_modified=True):
|
||||
updated_delivery_notes = []
|
||||
for d in self.get("items"):
|
||||
@@ -789,7 +823,7 @@ class SalesInvoice(SellingController):
|
||||
for dn in set(updated_delivery_notes):
|
||||
frappe.get_doc("Delivery Note", dn).update_billing_percentage(update_modified=update_modified)
|
||||
|
||||
def on_recurring(self, reference_doc):
|
||||
def on_recurring(self, reference_doc, subscription_doc):
|
||||
for fieldname in ("c_form_applicable", "c_form_no", "write_off_amount"):
|
||||
self.set(fieldname, reference_doc.get(fieldname))
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ def get_data():
|
||||
'Journal Entry': 'reference_name',
|
||||
'Payment Entry': 'reference_name',
|
||||
'Payment Request': 'reference_name',
|
||||
'Sales Invoice': 'return_against'
|
||||
'Sales Invoice': 'return_against',
|
||||
'Subscription': 'reference_document',
|
||||
},
|
||||
'internal_links': {
|
||||
'Sales Order': ['items', 'sales_order']
|
||||
@@ -26,5 +27,9 @@ def get_data():
|
||||
'label': _('Returns'),
|
||||
'items': ['Sales Invoice']
|
||||
},
|
||||
{
|
||||
'label': _('Subscription'),
|
||||
'items': ['Subscription']
|
||||
},
|
||||
]
|
||||
}
|
||||
43
erpnext/accounts/doctype/sales_invoice/test_sales_invoice.js
Normal file
43
erpnext/accounts/doctype/sales_invoice/test_sales_invoice.js
Normal file
@@ -0,0 +1,43 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// get tax account head details
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest, copy
|
||||
from frappe.utils import nowdate, add_days, flt
|
||||
import unittest, copy, time
|
||||
from frappe.utils import nowdate, add_days, flt, cint
|
||||
from frappe.model.dynamic_links import get_dynamic_link_map
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_stock_entry, get_qty_after_transaction
|
||||
from erpnext.accounts.doctype.purchase_invoice.test_purchase_invoice import unlink_payment_on_cancel_of_invoice
|
||||
@@ -168,15 +168,15 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"_Test Account S&H Education Cess - _TC": [1.5, 1619.5, 0.03, 32.39],
|
||||
"_Test Account CST - _TC": [32.5, 1652, 0.65, 33.04],
|
||||
"_Test Account VAT - _TC": [156.5, 1808.5, 3.13, 36.17],
|
||||
"_Test Account Discount - _TC": [-180.5, 1628, -3.61, 32.56]
|
||||
"_Test Account Discount - _TC": [-181.0, 1627.5, -3.62, 32.55]
|
||||
}
|
||||
|
||||
for d in si.get("taxes"):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.base_grand_total, 1628)
|
||||
self.assertEquals(si.grand_total, 32.56)
|
||||
self.assertEquals(si.base_grand_total, 1627.5)
|
||||
self.assertEquals(si.grand_total, 32.55)
|
||||
|
||||
def test_sales_invoice_with_discount_and_inclusive_tax(self):
|
||||
si = create_sales_invoice(qty=100, rate=50, do_not_save=True)
|
||||
@@ -215,12 +215,12 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.save()
|
||||
|
||||
# with inclusive tax and additional discount
|
||||
self.assertEquals(si.net_total, 4298.24)
|
||||
self.assertEquals(si.net_total, 4298.25)
|
||||
self.assertEquals(si.grand_total, 4900.00)
|
||||
|
||||
def test_sales_invoice_discount_amount(self):
|
||||
si = frappe.copy_doc(test_records[3])
|
||||
si.discount_amount = 104.95
|
||||
si.discount_amount = 104.94
|
||||
si.append("taxes", {
|
||||
"charge_type": "On Previous Row Amount",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
@@ -236,21 +236,29 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"price_list_rate": 62.5,
|
||||
"discount_percentage": 0,
|
||||
"rate": 62.5, "amount": 625,
|
||||
"rate": 62.5,
|
||||
"amount": 625,
|
||||
"base_price_list_rate": 62.5,
|
||||
"base_rate": 62.5, "base_amount": 625,
|
||||
"net_rate": 46.54, "net_amount": 465.37,
|
||||
"base_net_rate": 46.54, "base_net_amount": 465.37
|
||||
"base_rate": 62.5,
|
||||
"base_amount": 625,
|
||||
"net_rate": 46.54,
|
||||
"net_amount": 465.37,
|
||||
"base_net_rate": 46.54,
|
||||
"base_net_amount": 465.37
|
||||
},
|
||||
{
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"price_list_rate": 190.66,
|
||||
"discount_percentage": 0,
|
||||
"rate": 190.66, "amount": 953.3,
|
||||
"rate": 190.66,
|
||||
"amount": 953.3,
|
||||
"base_price_list_rate": 190.66,
|
||||
"base_rate": 190.66, "base_amount": 953.3,
|
||||
"net_rate": 139.62, "net_amount": 698.08,
|
||||
"base_net_rate": 139.62, "base_net_amount": 698.08
|
||||
"base_rate": 190.66,
|
||||
"base_amount": 953.3,
|
||||
"net_rate": 139.62,
|
||||
"net_amount": 698.08,
|
||||
"base_net_rate": 139.62,
|
||||
"base_net_amount": 698.08
|
||||
}
|
||||
]
|
||||
|
||||
@@ -271,13 +279,13 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"keys": ["tax_amount", "tax_amount_after_discount_amount", "total"],
|
||||
"_Test Account Excise Duty - _TC": [140, 130.31, 1293.76],
|
||||
"_Test Account Education Cess - _TC": [2.8, 2.61, 1296.37],
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1.31, 1297.68],
|
||||
"_Test Account CST - _TC": [27.88, 25.96, 1323.64],
|
||||
"_Test Account VAT - _TC": [156.25, 145.43, 1469.07],
|
||||
"_Test Account Customs Duty - _TC": [125, 116.35, 1585.42],
|
||||
"_Test Account Shipping Charges - _TC": [100, 100, 1685.42],
|
||||
"_Test Account Discount - _TC": [-180.33, -168.54, 1516.88],
|
||||
"_Test Account Service Tax - _TC": [-18.03, -16.88, 1500]
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1.30, 1297.67],
|
||||
"_Test Account CST - _TC": [27.88, 25.95, 1323.62],
|
||||
"_Test Account VAT - _TC": [156.25, 145.43, 1469.05],
|
||||
"_Test Account Customs Duty - _TC": [125, 116.35, 1585.40],
|
||||
"_Test Account Shipping Charges - _TC": [100, 100, 1685.40],
|
||||
"_Test Account Discount - _TC": [-180.33, -168.54, 1516.86],
|
||||
"_Test Account Service Tax - _TC": [-18.03, -16.85, 1500.01]
|
||||
}
|
||||
|
||||
for d in si.get("taxes"):
|
||||
@@ -286,10 +294,12 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
self.assertEquals(si.base_grand_total, 1500)
|
||||
self.assertEquals(si.grand_total, 1500)
|
||||
self.assertEquals(si.rounding_adjustment, -0.01)
|
||||
|
||||
def test_discount_amount_gl_entry(self):
|
||||
frappe.db.set_value("Company", "_Test Company", "round_off_account", "Round Off - _TC")
|
||||
si = frappe.copy_doc(test_records[3])
|
||||
si.discount_amount = 104.95
|
||||
si.discount_amount = 104.94
|
||||
si.append("taxes", {
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"charge_type": "On Previous Row Amount",
|
||||
@@ -313,13 +323,14 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
[test_records[3]["items"][0]["income_account"], 0.0, 1163.45],
|
||||
[test_records[3]["taxes"][0]["account_head"], 0.0, 130.31],
|
||||
[test_records[3]["taxes"][1]["account_head"], 0.0, 2.61],
|
||||
[test_records[3]["taxes"][2]["account_head"], 0.0, 1.31],
|
||||
[test_records[3]["taxes"][3]["account_head"], 0.0, 25.96],
|
||||
[test_records[3]["taxes"][2]["account_head"], 0.0, 1.30],
|
||||
[test_records[3]["taxes"][3]["account_head"], 0.0, 25.95],
|
||||
[test_records[3]["taxes"][4]["account_head"], 0.0, 145.43],
|
||||
[test_records[3]["taxes"][5]["account_head"], 0.0, 116.35],
|
||||
[test_records[3]["taxes"][6]["account_head"], 0.0, 100],
|
||||
[test_records[3]["taxes"][7]["account_head"], 168.54, 0.0],
|
||||
["_Test Account Service Tax - _TC", 16.88, 0.0],
|
||||
["_Test Account Service Tax - _TC", 16.85, 0.0],
|
||||
["Round Off - _TC", 0.01, 0.0]
|
||||
])
|
||||
|
||||
for gle in gl_entries:
|
||||
@@ -335,6 +346,61 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
self.assertFalse(gle)
|
||||
|
||||
def test_tax_calculation_with_multiple_items(self):
|
||||
si = create_sales_invoice(qty=84, rate=4.6, do_not_save=True)
|
||||
item_row = si.get("items")[0]
|
||||
for qty in (54, 288, 144, 430):
|
||||
item_row_copy = copy.deepcopy(item_row)
|
||||
item_row_copy.qty = qty
|
||||
si.append("items", item_row_copy)
|
||||
|
||||
si.append("taxes", {
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"rate": 19
|
||||
})
|
||||
si.insert()
|
||||
|
||||
self.assertEquals(si.net_total, 4600)
|
||||
|
||||
self.assertEquals(si.get("taxes")[0].tax_amount, 874.0)
|
||||
self.assertEquals(si.get("taxes")[0].total, 5474.0)
|
||||
|
||||
self.assertEquals(si.grand_total, 5474.0)
|
||||
|
||||
def test_tax_calculation_with_multiple_items_and_discount(self):
|
||||
si = create_sales_invoice(qty=1, rate=75, do_not_save=True)
|
||||
item_row = si.get("items")[0]
|
||||
for rate in (500, 200, 100, 50, 50):
|
||||
item_row_copy = copy.deepcopy(item_row)
|
||||
item_row_copy.price_list_rate = rate
|
||||
item_row_copy.rate = rate
|
||||
si.append("items", item_row_copy)
|
||||
|
||||
si.apply_discount_on = "Net Total"
|
||||
si.discount_amount = 75.0
|
||||
|
||||
si.append("taxes", {
|
||||
"account_head": "_Test Account VAT - _TC",
|
||||
"charge_type": "On Net Total",
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"description": "VAT",
|
||||
"doctype": "Sales Taxes and Charges",
|
||||
"rate": 24
|
||||
})
|
||||
si.insert()
|
||||
|
||||
self.assertEquals(si.total, 975)
|
||||
self.assertEquals(si.net_total, 900)
|
||||
|
||||
self.assertEquals(si.get("taxes")[0].tax_amount, 216.0)
|
||||
self.assertEquals(si.get("taxes")[0].total, 1116.0)
|
||||
|
||||
self.assertEquals(si.grand_total, 1116.0)
|
||||
|
||||
def test_inclusive_rate_validations(self):
|
||||
si = frappe.copy_doc(test_records[2])
|
||||
for i, tax in enumerate(si.get("taxes")):
|
||||
@@ -360,13 +426,12 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
expected_values = {
|
||||
"keys": ["price_list_rate", "discount_percentage", "rate", "amount",
|
||||
"base_price_list_rate", "base_rate", "base_amount", "net_rate", "net_amount"],
|
||||
"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 62.5, 62.5, 625.0, 50, 499.98],
|
||||
"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 190.66, 190.66, 953.3, 150, 750],
|
||||
"_Test Item Home Desktop 100": [62.5, 0, 62.5, 625.0, 62.5, 62.5, 625.0, 50, 499.97600115194473],
|
||||
"_Test Item Home Desktop 200": [190.66, 0, 190.66, 953.3, 190.66, 190.66, 953.3, 150, 749.9968530500239],
|
||||
}
|
||||
|
||||
# check if children are saved
|
||||
self.assertEquals(len(si.get("items")),
|
||||
len(expected_values)-1)
|
||||
self.assertEquals(len(si.get("items")), len(expected_values)-1)
|
||||
|
||||
# check if item values are calculated
|
||||
for d in si.get("items"):
|
||||
@@ -374,28 +439,28 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEquals(d.get(k), expected_values[d.item_code][i])
|
||||
|
||||
# check net total
|
||||
self.assertEquals(si.base_net_total, 1249.98)
|
||||
self.assertEquals(si.net_total, 1249.97)
|
||||
self.assertEquals(si.total, 1578.3)
|
||||
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
"keys": ["tax_amount", "total"],
|
||||
"_Test Account Excise Duty - _TC": [140, 1389.98],
|
||||
"_Test Account Education Cess - _TC": [2.8, 1392.78],
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1394.18],
|
||||
"_Test Account CST - _TC": [27.88, 1422.06],
|
||||
"_Test Account VAT - _TC": [156.25, 1578.31],
|
||||
"_Test Account Customs Duty - _TC": [125, 1703.31],
|
||||
"_Test Account Shipping Charges - _TC": [100, 1803.31],
|
||||
"_Test Account Discount - _TC": [-180.33, 1622.98]
|
||||
"_Test Account Excise Duty - _TC": [140, 1389.97],
|
||||
"_Test Account Education Cess - _TC": [2.8, 1392.77],
|
||||
"_Test Account S&H Education Cess - _TC": [1.4, 1394.17],
|
||||
"_Test Account CST - _TC": [27.88, 1422.05],
|
||||
"_Test Account VAT - _TC": [156.25, 1578.30],
|
||||
"_Test Account Customs Duty - _TC": [125, 1703.30],
|
||||
"_Test Account Shipping Charges - _TC": [100, 1803.30],
|
||||
"_Test Account Discount - _TC": [-180.33, 1622.97]
|
||||
}
|
||||
|
||||
for d in si.get("taxes"):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.base_grand_total, 1622.98)
|
||||
self.assertEquals(si.grand_total, 1622.98)
|
||||
self.assertEquals(si.base_grand_total, 1622.97)
|
||||
self.assertEquals(si.grand_total, 1622.97)
|
||||
|
||||
def test_sales_invoice_calculation_export_currency_with_tax_inclusive_price(self):
|
||||
# prepare
|
||||
@@ -417,21 +482,29 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"item_code": "_Test Item Home Desktop 100",
|
||||
"price_list_rate": 55.56,
|
||||
"discount_percentage": 10,
|
||||
"rate": 50, "amount": 500,
|
||||
"rate": 50,
|
||||
"amount": 500,
|
||||
"base_price_list_rate": 2778,
|
||||
"base_rate": 2500, "base_amount": 25000,
|
||||
"net_rate": 40, "net_amount": 399.98,
|
||||
"base_net_rate": 2000, "base_net_amount": 19999
|
||||
"base_rate": 2500,
|
||||
"base_amount": 25000,
|
||||
"net_rate": 40,
|
||||
"net_amount": 399.9808009215558,
|
||||
"base_net_rate": 2000,
|
||||
"base_net_amount": 19999
|
||||
},
|
||||
{
|
||||
"item_code": "_Test Item Home Desktop 200",
|
||||
"price_list_rate": 187.5,
|
||||
"discount_percentage": 20,
|
||||
"rate": 150, "amount": 750,
|
||||
"rate": 150,
|
||||
"amount": 750,
|
||||
"base_price_list_rate": 9375,
|
||||
"base_rate": 7500, "base_amount": 37500,
|
||||
"net_rate": 118.01, "net_amount": 590.05,
|
||||
"base_net_rate": 5900.5, "base_net_amount": 29502.5
|
||||
"base_rate": 7500,
|
||||
"base_amount": 37500,
|
||||
"net_rate": 118.01,
|
||||
"net_amount": 590.0531205155963,
|
||||
"base_net_rate": 5900.5,
|
||||
"base_net_amount": 29502.5
|
||||
}
|
||||
]
|
||||
|
||||
@@ -451,22 +524,25 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
# check tax calculation
|
||||
expected_values = {
|
||||
"keys": ["base_tax_amount", "base_total", "tax_amount", "total"],
|
||||
"_Test Account Excise Duty - _TC": [5540.5, 55042, 110.81, 1100.84],
|
||||
"_Test Account Education Cess - _TC": [111, 55153, 2.22, 1103.06],
|
||||
"_Test Account S&H Education Cess - _TC": [55.5, 55208.5, 1.11, 1104.17],
|
||||
"_Test Account CST - _TC": [1104, 56312.5, 22.08, 1126.25],
|
||||
"_Test Account VAT - _TC": [6188, 62500.5, 123.76, 1250.01],
|
||||
"_Test Account Customs Duty - _TC": [4950.5, 67451, 99.01, 1349.02],
|
||||
"_Test Account Shipping Charges - _TC": [ 100, 67551, 2, 1351.02],
|
||||
"_Test Account Discount - _TC": [ -6755, 60796, -135.10, 1215.92]
|
||||
"_Test Account Excise Duty - _TC": [5540.0, 55041.5, 110.80, 1100.83],
|
||||
"_Test Account Education Cess - _TC": [111, 55152.5, 2.22, 1103.05],
|
||||
"_Test Account S&H Education Cess - _TC": [55.5, 55208.0, 1.11, 1104.16],
|
||||
"_Test Account CST - _TC": [1104, 56312.0, 22.08, 1126.24],
|
||||
"_Test Account VAT - _TC": [6187.5, 62499.5, 123.75, 1249.99],
|
||||
"_Test Account Customs Duty - _TC": [4950.0, 67449.5, 99.0, 1348.99],
|
||||
"_Test Account Shipping Charges - _TC": [ 100, 67549.5, 2, 1350.99],
|
||||
"_Test Account Discount - _TC": [ -6755, 60794.5, -135.10, 1215.89]
|
||||
}
|
||||
|
||||
for d in si.get("taxes"):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
||||
|
||||
self.assertEquals(si.base_grand_total, 60796)
|
||||
self.assertEquals(si.grand_total, 1215.92)
|
||||
self.assertEquals(si.base_grand_total, 60795)
|
||||
self.assertEquals(si.grand_total, 1215.90)
|
||||
self.assertEquals(si.rounding_adjustment, 0.01)
|
||||
self.assertEquals(si.base_rounding_adjustment, 0.50)
|
||||
|
||||
|
||||
def test_outstanding(self):
|
||||
w = self.make()
|
||||
@@ -589,6 +665,47 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
|
||||
self.pos_gl_entry(si, pos, 330)
|
||||
|
||||
def test_make_pos_invoice_in_draft(self):
|
||||
from erpnext.accounts.doctype.sales_invoice.pos import make_invoice
|
||||
from erpnext.stock.doctype.item.test_item import make_item
|
||||
|
||||
set_perpetual_inventory()
|
||||
|
||||
allow_negative_stock = frappe.db.get_single_value('Stock Settings', 'allow_negative_stock')
|
||||
if allow_negative_stock:
|
||||
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 0)
|
||||
|
||||
make_pos_profile()
|
||||
timestamp = cint(time.time())
|
||||
|
||||
item = make_item("_Test POS Item")
|
||||
pos = copy.deepcopy(test_records[1])
|
||||
pos['items'][0]['item_code'] = item.name
|
||||
pos["is_pos"] = 1
|
||||
pos["offline_pos_name"] = timestamp
|
||||
pos["update_stock"] = 1
|
||||
pos["payments"] = [{'mode_of_payment': 'Bank Draft', 'account': '_Test Bank - _TC', 'amount': 300},
|
||||
{'mode_of_payment': 'Cash', 'account': 'Cash - _TC', 'amount': 330}]
|
||||
|
||||
invoice_data = [{timestamp: pos}]
|
||||
si = make_invoice(invoice_data).get('invoice')
|
||||
self.assertEquals(si[0], timestamp)
|
||||
|
||||
sales_invoice = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
|
||||
self.assertEquals(sales_invoice[0].docstatus, 0)
|
||||
|
||||
timestamp = cint(time.time())
|
||||
pos["offline_pos_name"] = timestamp
|
||||
invoice_data = [{timestamp: pos}]
|
||||
si1 = make_invoice(invoice_data).get('invoice')
|
||||
self.assertEquals(si1[0], timestamp)
|
||||
|
||||
sales_invoice1 = frappe.get_all('Sales Invoice', fields =["*"], filters = {'offline_pos_name': timestamp})
|
||||
self.assertEquals(sales_invoice1[0].docstatus, 0)
|
||||
|
||||
if allow_negative_stock:
|
||||
frappe.db.set_value('Stock Settings', None, 'allow_negative_stock', 1)
|
||||
|
||||
def pos_gl_entry(self, si, pos, cash_amount):
|
||||
# check stock ledger entries
|
||||
sle = frappe.db.sql("""select * from `tabStock Ledger Entry`
|
||||
@@ -738,10 +855,6 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertTrue(not frappe.db.sql("""select name from `tabJournal Entry Account`
|
||||
where reference_name=%s""", si.name))
|
||||
|
||||
def test_recurring_invoice(self):
|
||||
from erpnext.controllers.tests.test_recurring_document import test_recurring_document
|
||||
test_recurring_document(self, test_records)
|
||||
|
||||
def test_serialized(self):
|
||||
from erpnext.stock.doctype.stock_entry.test_stock_entry import make_serialized_item
|
||||
from erpnext.stock.doctype.serial_no.serial_no import get_serial_nos
|
||||
@@ -917,19 +1030,20 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
"_Test Account Excise Duty - _TC": [70, 70, 70],
|
||||
"_Test Account Education Cess - _TC": [1.4, 1.4, 1.4],
|
||||
"_Test Account S&H Education Cess - _TC": [.7, 0.7, 0.7],
|
||||
"_Test Account CST - _TC": [17.2, 17.2, 17.2],
|
||||
"_Test Account CST - _TC": [17.19, 17.19, 17.19],
|
||||
"_Test Account VAT - _TC": [78.13, 78.13, 78.13],
|
||||
"_Test Account Discount - _TC": [-95.49, -95.49, -95.49]
|
||||
}
|
||||
|
||||
for d in si.get("taxes"):
|
||||
for i, k in enumerate(expected_values["keys"]):
|
||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
||||
if expected_values.get(d.account_head):
|
||||
self.assertEquals(d.get(k), expected_values[d.account_head][i])
|
||||
|
||||
|
||||
self.assertEquals(si.total_taxes_and_charges, 234.44)
|
||||
self.assertEquals(si.base_grand_total, 859.44)
|
||||
self.assertEquals(si.grand_total, 859.44)
|
||||
self.assertEquals(si.total_taxes_and_charges, 234.43)
|
||||
self.assertEquals(si.base_grand_total, 859.43)
|
||||
self.assertEquals(si.grand_total, 859.43)
|
||||
|
||||
def test_multi_currency_gle(self):
|
||||
set_perpetual_inventory(0)
|
||||
@@ -1011,7 +1125,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.items[0].price_list_rate = price_list_rate
|
||||
si.items[0].margin_type = 'Percentage'
|
||||
si.items[0].margin_rate_or_amount = 25
|
||||
si.insert()
|
||||
si.save()
|
||||
self.assertEqual(si.get("items")[0].rate, flt((price_list_rate*25)/100 + price_list_rate))
|
||||
|
||||
def test_outstanding_amount_after_advance_jv_cancelation(self):
|
||||
@@ -1019,6 +1133,7 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
import test_records as jv_test_records
|
||||
|
||||
jv = frappe.copy_doc(jv_test_records[0])
|
||||
jv.accounts[0].is_advance = 'Yes'
|
||||
jv.insert()
|
||||
jv.submit()
|
||||
|
||||
@@ -1095,8 +1210,15 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
self.assertEqual(flt(si.outstanding_amount), flt(si.grand_total + si.total_advance, si.precision("outstanding_amount")))
|
||||
|
||||
def test_multiple_uom_in_selling(self):
|
||||
si = frappe.copy_doc(test_records[1])
|
||||
frappe.db.sql("""delete from `tabItem Price`
|
||||
where price_list='_Test Price List' and item_code='_Test Item'""")
|
||||
item_price = frappe.new_doc("Item Price")
|
||||
item_price.price_list = "_Test Price List"
|
||||
item_price.item_code = "_Test Item"
|
||||
item_price.price_list_rate = 100
|
||||
item_price.insert()
|
||||
|
||||
si = frappe.copy_doc(test_records[1])
|
||||
si.items[0].uom = "_Test UOM 1"
|
||||
si.items[0].conversion_factor = None
|
||||
si.items[0].price_list_rate = None
|
||||
@@ -1200,6 +1322,51 @@ class TestSalesInvoice(unittest.TestCase):
|
||||
si.insert()
|
||||
return si
|
||||
|
||||
def test_company_monthly_sales(self):
|
||||
existing_current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
|
||||
|
||||
si = create_sales_invoice()
|
||||
current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
|
||||
self.assertEqual(current_month_sales, existing_current_month_sales + si.base_grand_total)
|
||||
|
||||
si.cancel()
|
||||
current_month_sales = frappe.db.get_value("Company", "_Test Company", "total_monthly_sales")
|
||||
self.assertEqual(current_month_sales, existing_current_month_sales)
|
||||
|
||||
def test_rounding_adjustment(self):
|
||||
si = create_sales_invoice(rate=24900, do_not_save=True)
|
||||
for tax in ["Tax 1", "Tax2"]:
|
||||
si.append("taxes", {
|
||||
"charge_type": "On Net Total",
|
||||
"account_head": "_Test Account Service Tax - _TC",
|
||||
"description": tax,
|
||||
"rate": 14,
|
||||
"cost_center": "_Test Cost Center - _TC",
|
||||
"included_in_print_rate": 1
|
||||
})
|
||||
si.save()
|
||||
|
||||
self.assertEqual(si.net_total, 19453.13)
|
||||
self.assertEqual(si.grand_total, 24900)
|
||||
self.assertEqual(si.total_taxes_and_charges, 5446.88)
|
||||
self.assertEqual(si.rounding_adjustment, -0.01)
|
||||
|
||||
expected_values = dict((d[0], d) for d in [
|
||||
[si.debit_to, 24900, 0.0],
|
||||
["_Test Account Service Tax - _TC", 0.0, 5446.88],
|
||||
["Sales - _TC", 0.0, 19453.13],
|
||||
["Round Off - _TC", 0.01, 0.0]
|
||||
])
|
||||
|
||||
gl_entries = frappe.db.sql("""select account, debit, credit
|
||||
from `tabGL Entry` where voucher_type='Sales Invoice' and voucher_no=%s
|
||||
order by account asc""", si.name, as_dict=1)
|
||||
|
||||
for gle in gl_entries:
|
||||
self.assertEquals(expected_values[gle.account][0], gle.account)
|
||||
self.assertEquals(expected_values[gle.account][1], gle.debit)
|
||||
self.assertEquals(expected_values[gle.account][2], gle.credit)
|
||||
|
||||
def create_sales_invoice(**args):
|
||||
si = frappe.new_doc("Sales Invoice")
|
||||
args = frappe._dict(args)
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// get tax account head details
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice with payment", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.tests.click_button('Make'),
|
||||
() => frappe.tests.click_link('Payment'),
|
||||
() => frappe.timeout(0.2),
|
||||
() => { cur_frm.set_value('mode_of_payment','Cash');},
|
||||
() => { cur_frm.set_value('paid_to','Cash - '+frappe.get_abbr(frappe.defaults.get_default('Company')));},
|
||||
() => {cur_frm.set_value('reference_no','TEST1234');},
|
||||
() => {cur_frm.set_value('reference_date',frappe.datetime.add_days(frappe.datetime.nowdate(), 0));},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get payment details
|
||||
assert.ok(cur_frm.doc.paid_amount==590, "Paid Amount Correct");
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice with payment request", function(assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 5},
|
||||
{'item_code': 'Test Product 1'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 1', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==590, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(2),
|
||||
() => frappe.tests.click_button('Close'),
|
||||
() => frappe.tests.click_button('Make'),
|
||||
() => frappe.tests.click_link('Payment Request'),
|
||||
() => frappe.timeout(0.2),
|
||||
() => { cur_frm.set_value('print_format','GST Tax Invoice');},
|
||||
() => { cur_frm.set_value('email_to','test@gmail.com');},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get payment details
|
||||
assert.ok(cur_frm.doc.grand_total==590, "grand total Correct");
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
QUnit.module('Sales Invoice');
|
||||
|
||||
QUnit.test("test sales Invoice with serialize item", function(assert) {
|
||||
assert.expect(5);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Invoice', [
|
||||
{customer: 'Test Customer 1'},
|
||||
{items: [
|
||||
[
|
||||
{'qty': 2},
|
||||
{'item_code': 'Test Product 4'},
|
||||
]
|
||||
]},
|
||||
{update_stock:1},
|
||||
{customer_address: 'Test1-Billing'},
|
||||
{shipping_address_name: 'Test1-Shipping'},
|
||||
{contact_person: 'Contact 1-Test Customer 1'},
|
||||
{taxes_and_charges: 'TEST In State GST'},
|
||||
{tc_name: 'Test Term 1'},
|
||||
{terms: 'This is Test'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => {
|
||||
// get_item_details
|
||||
assert.ok(cur_frm.doc.items[0].item_name=='Test Product 4', "Item name correct");
|
||||
// get tax details
|
||||
assert.ok(cur_frm.doc.taxes_and_charges=='TEST In State GST', "Tax details correct");
|
||||
// get tax account head details
|
||||
assert.ok(cur_frm.doc.taxes[0].account_head=='CGST - '+frappe.get_abbr(frappe.defaults.get_default('Company')), " Account Head abbr correct");
|
||||
// get batch number
|
||||
assert.ok(cur_frm.doc.items[0].batch_no=='TEST-BATCH-001', " Batch Details correct");
|
||||
// grand_total Calculated
|
||||
assert.ok(cur_frm.doc.grand_total==218, "Grad Total correct");
|
||||
|
||||
},
|
||||
() => frappe.tests.click_button('Submit'),
|
||||
() => frappe.tests.click_button('Yes'),
|
||||
() => frappe.timeout(0.3),
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -699,7 +699,7 @@
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "2",
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
@@ -2166,7 +2166,7 @@
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-07-17 17:54:48.246507",
|
||||
"modified": "2017-09-27 08:31:37.827893",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Item",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 0,
|
||||
"allow_rename": 0,
|
||||
"beta": 0,
|
||||
@@ -11,16 +12,51 @@
|
||||
"editable_grid": 1,
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:parent.doctype == 'POS Profile'",
|
||||
"fieldname": "default",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Default",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "mode_of_payment",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Mode of Payment",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -30,6 +66,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -37,9 +74,11 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "0.0",
|
||||
"depends_on": "eval:parent.doctype == 'Sales Invoice'",
|
||||
"fieldname": "amount",
|
||||
@@ -48,7 +87,9 @@
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amount",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -58,6 +99,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
@@ -65,16 +107,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_3",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
@@ -82,6 +128,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -89,16 +136,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "account",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Account",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -108,6 +159,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -115,16 +167,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "type",
|
||||
"fieldtype": "Read Only",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Type",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
@@ -134,6 +190,7 @@
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -141,16 +198,20 @@
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "base_amount",
|
||||
"fieldtype": "Currency",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Base Amount (Company Currency)",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
@@ -160,6 +221,7 @@
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
@@ -167,17 +229,17 @@
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"in_dialog": 0,
|
||||
"is_submittable": 0,
|
||||
"issingle": 0,
|
||||
"istable": 1,
|
||||
"max_attachments": 0,
|
||||
"modified": "2016-07-11 03:28:07.779228",
|
||||
"modified": "2017-07-24 17:25:03.765856",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Sales Invoice Payment",
|
||||
@@ -187,7 +249,9 @@
|
||||
"quick_entry": 1,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"track_changes": 0,
|
||||
"track_seen": 0
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
QUnit.module('Sales Taxes and Charges Template');
|
||||
|
||||
QUnit.test("test sales taxes and charges template", function(assert) {
|
||||
assert.expect(1);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make('Sales Taxes and Charges Template', [
|
||||
{title: "TEST In State GST"},
|
||||
{taxes:[
|
||||
[
|
||||
{charge_type:"On Net Total"},
|
||||
{account_head:"CGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
|
||||
],
|
||||
[
|
||||
{charge_type:"On Net Total"},
|
||||
{account_head:"SGST - "+frappe.get_abbr(frappe.defaults.get_default("Company")) }
|
||||
]
|
||||
]}
|
||||
]);
|
||||
},
|
||||
() => {assert.ok(cur_frm.doc.title=='TEST In State GST');},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
@@ -54,13 +54,15 @@ class ShippingRule(Document):
|
||||
d.idx = i + 1
|
||||
|
||||
def validate_overlapping_shipping_rule_conditions(self):
|
||||
def overlap_exists_between((x1, x2), (y1, y2)):
|
||||
def overlap_exists_between(num_range1, num_range2):
|
||||
"""
|
||||
(x1, x2) and (y1, y2) are two ranges
|
||||
if condition x = 100 to 300
|
||||
then condition y can only be like 50 to 99 or 301 to 400
|
||||
num_range1 and num_range2 are two ranges
|
||||
ranges are represented as a tuple e.g. range 100 to 300 is represented as (100, 300)
|
||||
if condition num_range1 = 100 to 300
|
||||
then condition num_range2 can only be like 50 to 99 or 301 to 400
|
||||
hence, non-overlapping condition = (x1 <= x2 < y1 <= y2) or (y1 <= y2 < x1 <= x2)
|
||||
"""
|
||||
(x1, x2), (y1, y2) = num_range1, num_range2
|
||||
separate = (x1 <= x2 <= y1 <= y2) or (y1 <= y2 <= x1 <= x2)
|
||||
return (not separate)
|
||||
|
||||
|
||||
35
erpnext/accounts/doctype/shipping_rule/test_shipping_rule.js
Normal file
35
erpnext/accounts/doctype/shipping_rule/test_shipping_rule.js
Normal file
@@ -0,0 +1,35 @@
|
||||
QUnit.module('Shipping Rule');
|
||||
|
||||
QUnit.test("test Shipping Rule", function(assert) {
|
||||
assert.expect(1);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make("Shipping Rule", [
|
||||
{label: "Next Day Shipping"},
|
||||
{conditions:[
|
||||
[
|
||||
{from_value:1},
|
||||
{to_value:200},
|
||||
{shipping_amount:100}
|
||||
],
|
||||
[
|
||||
{from_value:201},
|
||||
{to_value:2000},
|
||||
{shipping_amount:50}
|
||||
],
|
||||
]},
|
||||
{countries:[
|
||||
[
|
||||
{country:'India'}
|
||||
]
|
||||
]},
|
||||
{account:'Accounts Payable - '+frappe.get_abbr(frappe.defaults.get_default("Company"))},
|
||||
{cost_center:'Main - '+frappe.get_abbr(frappe.defaults.get_default("Company"))}
|
||||
]);
|
||||
},
|
||||
() => {assert.ok(cur_frm.doc.name=='Next Day Shipping');},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
|
||||
75
erpnext/accounts/doctype/subscription/subscription.js
Normal file
75
erpnext/accounts/doctype/subscription/subscription.js
Normal file
@@ -0,0 +1,75 @@
|
||||
// Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
// For license information, please see license.txt
|
||||
|
||||
frappe.ui.form.on('Subscription', {
|
||||
setup: function(frm) {
|
||||
frm.fields_dict['reference_doctype'].get_query = function(doc) {
|
||||
return {
|
||||
query: "erpnext.accounts.doctype.subscription.subscription.subscription_doctype_query"
|
||||
};
|
||||
};
|
||||
|
||||
frm.fields_dict['reference_document'].get_query = function() {
|
||||
return {
|
||||
filters: {
|
||||
"docstatus": 1,
|
||||
"subscription": ''
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
frm.fields_dict['print_format'].get_query = function() {
|
||||
return {
|
||||
filters: {
|
||||
"doc_type": frm.doc.reference_doctype
|
||||
}
|
||||
};
|
||||
};
|
||||
},
|
||||
|
||||
refresh: function(frm) {
|
||||
if(frm.doc.docstatus == 1) {
|
||||
let label = __('View {0}', [frm.doc.reference_doctype]);
|
||||
frm.add_custom_button(__(label),
|
||||
function() {
|
||||
frappe.route_options = {
|
||||
"subscription": frm.doc.name,
|
||||
};
|
||||
frappe.set_route("List", frm.doc.reference_doctype);
|
||||
}
|
||||
);
|
||||
|
||||
if(frm.doc.status != 'Stopped') {
|
||||
frm.add_custom_button(__("Stop"),
|
||||
function() {
|
||||
frm.events.stop_resume_subscription(frm, "Stopped");
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
if(frm.doc.status == 'Stopped') {
|
||||
frm.add_custom_button(__("Resume"),
|
||||
function() {
|
||||
frm.events.stop_resume_subscription(frm, "Resumed");
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
stop_resume_subscription: function(frm, status) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.subscription.subscription.stop_resume_subscription",
|
||||
args: {
|
||||
subscription: frm.doc.name,
|
||||
status: status
|
||||
},
|
||||
callback: function(r) {
|
||||
if(r.message) {
|
||||
frm.set_value("status", r.message);
|
||||
frm.reload_doc();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
865
erpnext/accounts/doctype/subscription/subscription.json
Normal file
865
erpnext/accounts/doctype/subscription/subscription.json
Normal file
@@ -0,0 +1,865 @@
|
||||
{
|
||||
"allow_copy": 0,
|
||||
"allow_guest_to_view": 0,
|
||||
"allow_import": 1,
|
||||
"allow_rename": 1,
|
||||
"autoname": "naming_series:",
|
||||
"beta": 0,
|
||||
"creation": "2017-07-18 17:50:43.967266",
|
||||
"custom": 0,
|
||||
"docstatus": 0,
|
||||
"doctype": "DocType",
|
||||
"document_type": "",
|
||||
"editable_grid": 1,
|
||||
"engine": "InnoDB",
|
||||
"fields": [
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_1",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "naming_series",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Series",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "SUB-",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reference_doctype",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Doctype",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "DocType",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "reference_document",
|
||||
"fieldtype": "Dynamic Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Reference Document",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "reference_doctype",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_5",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "start_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Start Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "end_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "End Date",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "submit_on_creation",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Submit on Creation",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "disabled",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Disabled",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "section_break_10",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "frequency",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Frequency",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nDaily\nWeekly\nMonthly\nQuarterly\nHalf-yearly\nYearly",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 1,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_13",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: in_list([\"Monthly\", \"Quarterly\", \"Yearly\"], doc.frequency)",
|
||||
"fieldname": "repeat_on_day",
|
||||
"fieldtype": "Int",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Repeat on Day",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "next_schedule_date",
|
||||
"fieldtype": "Date",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Next Schedule Date",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"fieldname": "notification",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Notification",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "notify_by_email",
|
||||
"fieldtype": "Check",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Notify by Email",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: doc.notify_by_email",
|
||||
"description": "To add dynamic subject, use jinja tags like\n\n<div><pre><code>New {{ doc.doctype }} #{{ doc.name }}</code></pre></div>",
|
||||
"fieldname": "subject",
|
||||
"fieldtype": "Data",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Subject",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "column_break_17",
|
||||
"fieldtype": "Column Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "notify_by_email",
|
||||
"fieldname": "recipients",
|
||||
"fieldtype": "Small Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Recipients",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"depends_on": "notify_by_email",
|
||||
"fieldname": "print_format",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Print Format",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "Print Format",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"depends_on": "eval:doc.notify_by_email",
|
||||
"fieldname": "section_break_20",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Message",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Please find attached {{ doc.doctype }} #{{ doc.name }}",
|
||||
"fieldname": "message",
|
||||
"fieldtype": "Text",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Message",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 1,
|
||||
"columns": 0,
|
||||
"depends_on": "eval: !doc.__islocal",
|
||||
"fieldname": "section_break_16",
|
||||
"fieldtype": "Section Break",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 0,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 1,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"default": "Draft",
|
||||
"fieldname": "status",
|
||||
"fieldtype": "Select",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 1,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Status",
|
||||
"length": 0,
|
||||
"no_copy": 0,
|
||||
"options": "\nDraft\nStopped\nSubmitted\nCancelled\nCompleted",
|
||||
"permlevel": 0,
|
||||
"precision": "",
|
||||
"print_hide": 0,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
},
|
||||
{
|
||||
"allow_bulk_edit": 0,
|
||||
"allow_on_submit": 0,
|
||||
"bold": 0,
|
||||
"collapsible": 0,
|
||||
"columns": 0,
|
||||
"fieldname": "amended_from",
|
||||
"fieldtype": "Link",
|
||||
"hidden": 0,
|
||||
"ignore_user_permissions": 0,
|
||||
"ignore_xss_filter": 0,
|
||||
"in_filter": 0,
|
||||
"in_global_search": 0,
|
||||
"in_list_view": 0,
|
||||
"in_standard_filter": 0,
|
||||
"label": "Amended From",
|
||||
"length": 0,
|
||||
"no_copy": 1,
|
||||
"options": "Subscription",
|
||||
"permlevel": 0,
|
||||
"print_hide": 1,
|
||||
"print_hide_if_no_value": 0,
|
||||
"read_only": 1,
|
||||
"remember_last_selected_value": 0,
|
||||
"report_hide": 0,
|
||||
"reqd": 0,
|
||||
"search_index": 0,
|
||||
"set_only_once": 0,
|
||||
"unique": 0
|
||||
}
|
||||
],
|
||||
"has_web_view": 0,
|
||||
"hide_heading": 0,
|
||||
"hide_toolbar": 0,
|
||||
"idx": 0,
|
||||
"image_view": 0,
|
||||
"in_create": 0,
|
||||
"is_submittable": 1,
|
||||
"issingle": 0,
|
||||
"istable": 0,
|
||||
"max_attachments": 0,
|
||||
"modified": "2017-10-23 18:28:08.966403",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Subscription",
|
||||
"name_case": "",
|
||||
"owner": "Administrator",
|
||||
"permissions": [
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "System Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts User",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
},
|
||||
{
|
||||
"amend": 0,
|
||||
"apply_user_permissions": 0,
|
||||
"cancel": 1,
|
||||
"create": 1,
|
||||
"delete": 1,
|
||||
"email": 1,
|
||||
"export": 1,
|
||||
"if_owner": 0,
|
||||
"import": 0,
|
||||
"permlevel": 0,
|
||||
"print": 1,
|
||||
"read": 1,
|
||||
"report": 1,
|
||||
"role": "Accounts Manager",
|
||||
"set_user_permissions": 0,
|
||||
"share": 1,
|
||||
"submit": 1,
|
||||
"write": 1
|
||||
}
|
||||
],
|
||||
"quick_entry": 0,
|
||||
"read_only": 0,
|
||||
"read_only_onload": 0,
|
||||
"search_fields": "reference_document",
|
||||
"show_name_in_global_search": 0,
|
||||
"sort_field": "modified",
|
||||
"sort_order": "DESC",
|
||||
"title_field": "reference_document",
|
||||
"track_changes": 1,
|
||||
"track_seen": 0
|
||||
}
|
||||
313
erpnext/accounts/doctype/subscription/subscription.py
Normal file
313
erpnext/accounts/doctype/subscription/subscription.py
Normal file
@@ -0,0 +1,313 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and contributors
|
||||
# For license information, please see license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import calendar
|
||||
from frappe import _
|
||||
from frappe.desk.form import assign_to
|
||||
from frappe.utils.jinja import validate_template
|
||||
from dateutil.relativedelta import relativedelta
|
||||
from frappe.utils.user import get_system_managers
|
||||
from frappe.utils import cstr, getdate, split_emails, add_days, today, get_last_day, get_first_day
|
||||
from frappe.model.document import Document
|
||||
|
||||
month_map = {'Monthly': 1, 'Quarterly': 3, 'Half-yearly': 6, 'Yearly': 12}
|
||||
class Subscription(Document):
|
||||
def validate(self):
|
||||
self.update_status()
|
||||
self.validate_reference_doctype()
|
||||
self.validate_dates()
|
||||
self.validate_next_schedule_date()
|
||||
self.validate_email_id()
|
||||
|
||||
validate_template(self.subject or "")
|
||||
validate_template(self.message or "")
|
||||
|
||||
def before_submit(self):
|
||||
if not self.next_schedule_date:
|
||||
self.next_schedule_date = get_next_schedule_date(self.start_date,
|
||||
self.frequency, self.repeat_on_day)
|
||||
|
||||
def on_submit(self):
|
||||
self.update_subscription_id()
|
||||
|
||||
def on_update_after_submit(self):
|
||||
self.validate_dates()
|
||||
self.set_next_schedule_date()
|
||||
|
||||
def before_cancel(self):
|
||||
self.unlink_subscription_id()
|
||||
self.next_schedule_date = None
|
||||
|
||||
def unlink_subscription_id(self):
|
||||
frappe.db.sql("update `tab{0}` set subscription = null where subscription=%s"
|
||||
.format(self.reference_doctype), self.name)
|
||||
|
||||
def validate_reference_doctype(self):
|
||||
if not frappe.get_meta(self.reference_doctype).has_field('subscription'):
|
||||
frappe.throw(_("Add custom field Subscription in the doctype {0}").format(self.reference_doctype))
|
||||
|
||||
def validate_dates(self):
|
||||
if self.end_date and getdate(self.start_date) > getdate(self.end_date):
|
||||
frappe.throw(_("End date must be greater than start date"))
|
||||
|
||||
def validate_next_schedule_date(self):
|
||||
if self.repeat_on_day and self.next_schedule_date:
|
||||
next_date = getdate(self.next_schedule_date)
|
||||
if next_date.day != self.repeat_on_day:
|
||||
# if the repeat day is the last day of the month (31)
|
||||
# and the current month does not have as many days,
|
||||
# then the last day of the current month is a valid date
|
||||
lastday = calendar.monthrange(next_date.year, next_date.month)[1]
|
||||
if self.repeat_on_day < lastday:
|
||||
|
||||
# the specified day of the month is not same as the day specified
|
||||
# or the last day of the month
|
||||
frappe.throw(_("Next Date's day and Repeat on Day of Month must be equal"))
|
||||
|
||||
def validate_email_id(self):
|
||||
if self.notify_by_email:
|
||||
if self.recipients:
|
||||
email_list = split_emails(self.recipients.replace("\n", ""))
|
||||
|
||||
from frappe.utils import validate_email_add
|
||||
for email in email_list:
|
||||
if not validate_email_add(email):
|
||||
frappe.throw(_("{0} is an invalid email address in 'Recipients'").format(email))
|
||||
else:
|
||||
frappe.throw(_("'Recipients' not specified"))
|
||||
|
||||
def set_next_schedule_date(self):
|
||||
if self.repeat_on_day:
|
||||
self.next_schedule_date = get_next_date(self.next_schedule_date, 0, self.repeat_on_day)
|
||||
|
||||
def update_subscription_id(self):
|
||||
frappe.db.set_value(self.reference_doctype, self.reference_document, "subscription", self.name)
|
||||
|
||||
def update_status(self, status=None):
|
||||
self.status = {
|
||||
'0': 'Draft',
|
||||
'1': 'Submitted',
|
||||
'2': 'Cancelled'
|
||||
}[cstr(self.docstatus or 0)]
|
||||
|
||||
if status and status != 'Resumed':
|
||||
self.status = status
|
||||
|
||||
def get_next_schedule_date(start_date, frequency, repeat_on_day):
|
||||
mcount = month_map.get(frequency)
|
||||
if mcount:
|
||||
next_date = get_next_date(start_date, mcount, repeat_on_day)
|
||||
else:
|
||||
days = 7 if frequency == 'Weekly' else 1
|
||||
next_date = add_days(start_date, days)
|
||||
return next_date
|
||||
|
||||
def make_subscription_entry(date=None):
|
||||
date = date or today()
|
||||
for data in get_subscription_entries(date):
|
||||
schedule_date = getdate(data.next_schedule_date)
|
||||
while schedule_date <= getdate(today()):
|
||||
create_documents(data, schedule_date)
|
||||
schedule_date = get_next_schedule_date(schedule_date,
|
||||
data.frequency, data.repeat_on_day)
|
||||
|
||||
if schedule_date and not frappe.db.get_value('Subscription', data.name, 'disabled'):
|
||||
frappe.db.set_value('Subscription', data.name, 'next_schedule_date', schedule_date)
|
||||
|
||||
def get_subscription_entries(date):
|
||||
return frappe.db.sql(""" select * from `tabSubscription`
|
||||
where docstatus = 1 and next_schedule_date <=%s
|
||||
and reference_document is not null and reference_document != ''
|
||||
and next_schedule_date <= ifnull(end_date, '2199-12-31')
|
||||
and ifnull(disabled, 0) = 0 and status != 'Stopped' """, (date), as_dict=1)
|
||||
|
||||
def create_documents(data, schedule_date):
|
||||
try:
|
||||
doc = make_new_document(data, schedule_date)
|
||||
if data.notify_by_email and data.recipients:
|
||||
print_format = data.print_format or "Standard"
|
||||
send_notification(doc, data, print_format=print_format)
|
||||
|
||||
frappe.db.commit()
|
||||
except Exception:
|
||||
frappe.db.rollback()
|
||||
frappe.db.begin()
|
||||
frappe.log_error(frappe.get_traceback())
|
||||
disable_subscription(data)
|
||||
frappe.db.commit()
|
||||
if data.reference_document and not frappe.flags.in_test:
|
||||
notify_error_to_user(data)
|
||||
|
||||
def disable_subscription(data):
|
||||
subscription = frappe.get_doc('Subscription', data.name)
|
||||
subscription.db_set('disabled', 1)
|
||||
|
||||
def notify_error_to_user(data):
|
||||
party = ''
|
||||
party_type = ''
|
||||
|
||||
if data.reference_doctype in ['Sales Order', 'Sales Invoice', 'Delivery Note']:
|
||||
party_type = 'customer'
|
||||
elif data.reference_doctype in ['Purchase Order', 'Purchase Invoice', 'Purchase Receipt']:
|
||||
party_type = 'supplier'
|
||||
|
||||
if party_type:
|
||||
party = frappe.db.get_value(data.reference_doctype, data.reference_document, party_type)
|
||||
|
||||
notify_errors(data.reference_document, data.reference_doctype, party, data.owner, data.name)
|
||||
|
||||
def make_new_document(args, schedule_date):
|
||||
doc = frappe.get_doc(args.reference_doctype, args.reference_document)
|
||||
new_doc = frappe.copy_doc(doc, ignore_no_copy=False)
|
||||
update_doc(new_doc, doc , args, schedule_date)
|
||||
new_doc.insert(ignore_permissions=True)
|
||||
|
||||
if args.submit_on_creation:
|
||||
new_doc.submit()
|
||||
|
||||
return new_doc
|
||||
|
||||
def update_doc(new_document, reference_doc, args, schedule_date):
|
||||
new_document.docstatus = 0
|
||||
if new_document.meta.get_field('set_posting_time'):
|
||||
new_document.set('set_posting_time', 1)
|
||||
|
||||
mcount = month_map.get(args.frequency)
|
||||
|
||||
if new_document.meta.get_field('subscription'):
|
||||
new_document.set('subscription', args.name)
|
||||
|
||||
for fieldname in ['naming_series', 'ignore_pricing_rule', 'posting_time'
|
||||
'select_print_heading', 'remarks', 'owner']:
|
||||
if new_document.meta.get_field(fieldname):
|
||||
new_document.set(fieldname, reference_doc.get(fieldname))
|
||||
|
||||
# copy item fields
|
||||
if new_document.meta.get_field('items'):
|
||||
for i, item in enumerate(new_document.items):
|
||||
for fieldname in ("page_break",):
|
||||
item.set(fieldname, reference_doc.items[i].get(fieldname))
|
||||
|
||||
for data in new_document.meta.fields:
|
||||
if data.fieldtype == 'Date' and data.reqd:
|
||||
new_document.set(data.fieldname, schedule_date)
|
||||
|
||||
set_subscription_period(args, mcount, new_document)
|
||||
|
||||
new_document.run_method("on_recurring", reference_doc=reference_doc, subscription_doc=args)
|
||||
|
||||
def set_subscription_period(args, mcount, new_document):
|
||||
if mcount and new_document.meta.get_field('from_date') and new_document.meta.get_field('to_date'):
|
||||
last_ref_doc = frappe.db.sql("""
|
||||
select name, from_date, to_date
|
||||
from `tab{0}`
|
||||
where subscription=%s and docstatus < 2
|
||||
order by creation desc
|
||||
limit 1
|
||||
""".format(args.reference_doctype), args.name, as_dict=1)
|
||||
|
||||
if not last_ref_doc:
|
||||
return
|
||||
|
||||
from_date = get_next_date(last_ref_doc[0].from_date, mcount)
|
||||
|
||||
if (cstr(get_first_day(last_ref_doc[0].from_date)) == cstr(last_ref_doc[0].from_date)) and \
|
||||
(cstr(get_last_day(last_ref_doc[0].to_date)) == cstr(last_ref_doc[0].to_date)):
|
||||
to_date = get_last_day(get_next_date(last_ref_doc[0].to_date, mcount))
|
||||
else:
|
||||
to_date = get_next_date(last_ref_doc[0].to_date, mcount)
|
||||
|
||||
new_document.set('from_date', from_date)
|
||||
new_document.set('to_date', to_date)
|
||||
|
||||
def get_next_date(dt, mcount, day=None):
|
||||
dt = getdate(dt)
|
||||
dt += relativedelta(months=mcount, day=day)
|
||||
|
||||
return dt
|
||||
|
||||
def send_notification(new_rv, subscription_doc, print_format='Standard'):
|
||||
"""Notify concerned persons about recurring document generation"""
|
||||
print_format = print_format
|
||||
|
||||
if not subscription_doc.subject:
|
||||
subject = _("New {0}: #{1}").format(new_rv.doctype, new_rv.name)
|
||||
elif "{" in subscription_doc.subject:
|
||||
subject = frappe.render_template(subscription_doc.subject, {'doc': new_rv})
|
||||
|
||||
if not subscription_doc.message:
|
||||
message = _("Please find attached {0} #{1}").format(new_rv.doctype, new_rv.name)
|
||||
elif "{" in subscription_doc.message:
|
||||
message = frappe.render_template(subscription_doc.message, {'doc': new_rv})
|
||||
|
||||
attachments = [frappe.attach_print(new_rv.doctype, new_rv.name,
|
||||
file_name=new_rv.name, print_format=print_format)]
|
||||
|
||||
frappe.sendmail(subscription_doc.recipients,
|
||||
subject=subject, message=message, attachments=attachments)
|
||||
|
||||
def notify_errors(doc, doctype, party, owner, name):
|
||||
recipients = get_system_managers(only_name=True)
|
||||
frappe.sendmail(recipients + [frappe.db.get_value("User", owner, "email")],
|
||||
subject=_("[Urgent] Error while creating recurring %s for %s" % (doctype, doc)),
|
||||
message = frappe.get_template("templates/emails/recurring_document_failed.html").render({
|
||||
"type": _(doctype),
|
||||
"name": doc,
|
||||
"party": party or "",
|
||||
"subscription": name
|
||||
}))
|
||||
|
||||
assign_task_to_owner(name, "Recurring Documents Failed", recipients)
|
||||
|
||||
def assign_task_to_owner(name, msg, users):
|
||||
for d in users:
|
||||
args = {
|
||||
'doctype' : 'Subscription',
|
||||
'assign_to' : d,
|
||||
'name' : name,
|
||||
'description' : msg,
|
||||
'priority' : 'High'
|
||||
}
|
||||
assign_to.add(args)
|
||||
|
||||
@frappe.whitelist()
|
||||
def make_subscription(doctype, docname):
|
||||
doc = frappe.new_doc('Subscription')
|
||||
|
||||
reference_doc = frappe.get_doc(doctype, docname)
|
||||
doc.reference_doctype = doctype
|
||||
doc.reference_document = docname
|
||||
doc.start_date = reference_doc.get('posting_date') or reference_doc.get('transaction_date')
|
||||
return doc
|
||||
|
||||
@frappe.whitelist()
|
||||
def stop_resume_subscription(subscription, status):
|
||||
doc = frappe.get_doc('Subscription', subscription)
|
||||
frappe.msgprint(_("Subscription has been {0}").format(status))
|
||||
if status == 'Resumed':
|
||||
doc.next_schedule_date = get_next_schedule_date(today(),
|
||||
doc.frequency, doc.repeat_on_day)
|
||||
|
||||
doc.update_status(status)
|
||||
doc.save()
|
||||
|
||||
return doc.status
|
||||
|
||||
def subscription_doctype_query(doctype, txt, searchfield, start, page_len, filters):
|
||||
return frappe.db.sql("""select parent from `tabDocField`
|
||||
where fieldname = 'subscription'
|
||||
and parent like %(txt)s
|
||||
order by
|
||||
if(locate(%(_txt)s, parent), locate(%(_txt)s, parent), 99999),
|
||||
parent
|
||||
limit %(start)s, %(page_len)s""".format(**{
|
||||
'key': searchfield,
|
||||
}), {
|
||||
'txt': "%%%s%%" % txt,
|
||||
'_txt': txt.replace("%", ""),
|
||||
'start': start,
|
||||
'page_len': page_len
|
||||
})
|
||||
16
erpnext/accounts/doctype/subscription/subscription_list.js
Normal file
16
erpnext/accounts/doctype/subscription/subscription_list.js
Normal file
@@ -0,0 +1,16 @@
|
||||
frappe.listview_settings['Subscription'] = {
|
||||
add_fields: ["next_schedule_date"],
|
||||
get_indicator: function(doc) {
|
||||
if(doc.disabled) {
|
||||
return [__("Disabled"), "red"];
|
||||
} else if(doc.next_schedule_date >= frappe.datetime.get_today() && doc.status != 'Stopped') {
|
||||
return [__("Active"), "green"];
|
||||
} else if(doc.docstatus === 0) {
|
||||
return [__("Draft"), "red", "docstatus,=,0"];
|
||||
} else if(doc.status === 'Stopped') {
|
||||
return [__("Stopped"), "red"];
|
||||
} else {
|
||||
return [__("Expired"), "darkgrey"];
|
||||
}
|
||||
}
|
||||
};
|
||||
32
erpnext/accounts/doctype/subscription/test_subscription.js
Normal file
32
erpnext/accounts/doctype/subscription/test_subscription.js
Normal file
@@ -0,0 +1,32 @@
|
||||
/* eslint-disable */
|
||||
// rename this file from _test_[name] to test_[name] to activate
|
||||
// and remove above this line
|
||||
|
||||
QUnit.test("test: Subscription", function (assert) {
|
||||
assert.expect(4);
|
||||
let done = assert.async();
|
||||
frappe.run_serially([
|
||||
// insert a new Subscription
|
||||
() => {
|
||||
return frappe.tests.make("Subscription", [
|
||||
{reference_doctype: 'Sales Invoice'},
|
||||
{reference_document: 'SINV-00004'},
|
||||
{start_date: frappe.datetime.month_start()},
|
||||
{end_date: frappe.datetime.month_end()},
|
||||
{frequency: 'Weekly'}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.savesubmit(),
|
||||
() => frappe.timeout(1),
|
||||
() => frappe.click_button('Yes'),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.ok(cur_frm.doc.frequency.includes("Weekly"), "Set frequency Weekly");
|
||||
assert.ok(cur_frm.doc.reference_doctype.includes("Sales Invoice"), "Set base doctype Sales Invoice");
|
||||
assert.equal(cur_frm.doc.docstatus, 1, "Submitted subscription");
|
||||
assert.equal(cur_frm.doc.next_schedule_date,
|
||||
frappe.datetime.add_days(frappe.datetime.get_today(), 7), "Set schedule date");
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
93
erpnext/accounts/doctype/subscription/test_subscription.py
Normal file
93
erpnext/accounts/doctype/subscription/test_subscription.py
Normal file
@@ -0,0 +1,93 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright (c) 2017, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
# See license.txt
|
||||
from __future__ import unicode_literals
|
||||
|
||||
import frappe
|
||||
import unittest
|
||||
from frappe.utils import today, add_days, getdate
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext.accounts.report.financial_statements import get_months
|
||||
from erpnext.accounts.doctype.sales_invoice.test_sales_invoice import create_sales_invoice
|
||||
from erpnext.selling.doctype.sales_order.test_sales_order import make_sales_order
|
||||
from erpnext.accounts.doctype.subscription.subscription import make_subscription_entry
|
||||
|
||||
class TestSubscription(unittest.TestCase):
|
||||
def test_daily_subscription(self):
|
||||
qo = frappe.copy_doc(quotation_records[0])
|
||||
qo.submit()
|
||||
|
||||
doc = make_subscription(reference_document=qo.name)
|
||||
self.assertEquals(doc.next_schedule_date, today())
|
||||
make_subscription_entry()
|
||||
frappe.db.commit()
|
||||
|
||||
quotation = frappe.get_doc(doc.reference_doctype, doc.reference_document)
|
||||
self.assertEquals(quotation.subscription, doc.name)
|
||||
|
||||
new_quotation = frappe.db.get_value('Quotation',
|
||||
{'subscription': doc.name, 'name': ('!=', quotation.name)}, 'name')
|
||||
|
||||
new_quotation = frappe.get_doc('Quotation', new_quotation)
|
||||
|
||||
for fieldname in ['customer', 'company', 'order_type', 'total', 'net_total']:
|
||||
self.assertEquals(quotation.get(fieldname), new_quotation.get(fieldname))
|
||||
|
||||
for fieldname in ['item_code', 'qty', 'rate', 'amount']:
|
||||
self.assertEquals(quotation.items[0].get(fieldname),
|
||||
new_quotation.items[0].get(fieldname))
|
||||
|
||||
def test_monthly_subscription_for_so(self):
|
||||
current_fiscal_year = get_fiscal_year(today(), as_dict=True)
|
||||
start_date = current_fiscal_year.year_start_date
|
||||
end_date = current_fiscal_year.year_end_date
|
||||
|
||||
for doctype in ['Sales Order', 'Sales Invoice']:
|
||||
if doctype == 'Sales Invoice':
|
||||
docname = create_sales_invoice(posting_date=start_date)
|
||||
else:
|
||||
docname = make_sales_order()
|
||||
|
||||
self.monthly_subscription(doctype, docname.name, start_date, end_date)
|
||||
|
||||
def monthly_subscription(self, doctype, docname, start_date, end_date):
|
||||
doc = make_subscription(reference_doctype=doctype, frequency = 'Monthly',
|
||||
reference_document = docname, start_date=start_date, end_date=end_date)
|
||||
|
||||
doc.disabled = 1
|
||||
doc.save()
|
||||
frappe.db.commit()
|
||||
|
||||
make_subscription_entry()
|
||||
docnames = frappe.get_all(doc.reference_doctype, {'subscription': doc.name})
|
||||
self.assertEquals(len(docnames), 1)
|
||||
|
||||
doc = frappe.get_doc('Subscription', doc.name)
|
||||
doc.disabled = 0
|
||||
doc.save()
|
||||
|
||||
months = get_months(getdate(start_date), getdate(today()))
|
||||
make_subscription_entry()
|
||||
|
||||
docnames = frappe.get_all(doc.reference_doctype, {'subscription': doc.name})
|
||||
self.assertEquals(len(docnames), months)
|
||||
|
||||
quotation_records = frappe.get_test_records('Quotation')
|
||||
|
||||
def make_subscription(**args):
|
||||
args = frappe._dict(args)
|
||||
doc = frappe.get_doc({
|
||||
'doctype': 'Subscription',
|
||||
'reference_doctype': args.reference_doctype or 'Quotation',
|
||||
'reference_document': args.reference_document or \
|
||||
frappe.db.get_value('Quotation', {'docstatus': 1}, 'name'),
|
||||
'frequency': args.frequency or 'Daily',
|
||||
'start_date': args.start_date or add_days(today(), -1),
|
||||
'end_date': args.end_date or add_days(today(), 1),
|
||||
'submit_on_creation': args.submit_on_creation or 0
|
||||
}).insert(ignore_permissions=True)
|
||||
|
||||
if not args.do_not_submit:
|
||||
doc.submit()
|
||||
|
||||
return doc
|
||||
@@ -8,6 +8,8 @@ from frappe import _
|
||||
from frappe.model.document import Document
|
||||
from frappe.utils import cstr, cint
|
||||
from frappe.contacts.doctype.address.address import get_default_address
|
||||
from frappe.utils.nestedset import get_root_of
|
||||
from erpnext.setup.doctype.customer_group.customer_group import get_parent_customer_groups
|
||||
|
||||
class IncorrectCustomerGroup(frappe.ValidationError): pass
|
||||
class IncorrectSupplierType(frappe.ValidationError): pass
|
||||
@@ -134,6 +136,10 @@ def get_tax_template(posting_date, args):
|
||||
for key, value in args.iteritems():
|
||||
if key=="use_for_shopping_cart":
|
||||
conditions.append("use_for_shopping_cart = {0}".format(1 if value else 0))
|
||||
if key == 'customer_group':
|
||||
if not value: value = get_root_of("Customer Group")
|
||||
customer_group_condition = get_customer_group_condition(value)
|
||||
conditions.append("ifnull({0}, '') in ('', {1})".format(key, customer_group_condition))
|
||||
else:
|
||||
conditions.append("ifnull({0}, '') in ('', '{1}')".format(key, frappe.db.escape(cstr(value))))
|
||||
|
||||
@@ -157,3 +163,10 @@ def get_tax_template(posting_date, args):
|
||||
return None
|
||||
|
||||
return tax_template
|
||||
|
||||
def get_customer_group_condition(customer_group):
|
||||
condition = ""
|
||||
customer_groups = ["'%s'"%(frappe.db.escape(d.name)) for d in get_parent_customer_groups(customer_group)]
|
||||
if customer_groups:
|
||||
condition = ",".join(['%s'] * len(customer_groups))%(tuple(customer_groups))
|
||||
return condition
|
||||
@@ -11,7 +11,10 @@ test_records = frappe.get_test_records('Tax Rule')
|
||||
|
||||
class TestTaxRule(unittest.TestCase):
|
||||
def setUp(self):
|
||||
frappe.db.sql("delete from `tabTax Rule` where use_for_shopping_cart <> 1")
|
||||
frappe.db.sql("delete from `tabTax Rule`")
|
||||
|
||||
def tearDown(self):
|
||||
frappe.db.sql("delete from `tabTax Rule`")
|
||||
|
||||
def test_conflict(self):
|
||||
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
||||
@@ -34,6 +37,14 @@ class TestTaxRule(unittest.TestCase):
|
||||
tax_rule2.save()
|
||||
self.assertTrue(tax_rule2.name)
|
||||
|
||||
def test_for_parent_customer_group(self):
|
||||
tax_rule1 = make_tax_rule(customer_group= "All Customer Groups",
|
||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01")
|
||||
tax_rule1.save()
|
||||
|
||||
self.assertEquals(get_tax_template("2015-01-01", {"customer_group" : "Commercial", "use_for_shopping_cart":0}),
|
||||
"_Test Sales Taxes and Charges Template")
|
||||
|
||||
def test_conflict_with_overlapping_dates(self):
|
||||
tax_rule1 = make_tax_rule(customer= "_Test Customer",
|
||||
sales_tax_template = "_Test Sales Taxes and Charges Template", priority = 1, from_date = "2015-01-01", to_date = "2015-01-05")
|
||||
|
||||
@@ -136,14 +136,7 @@ def round_off_debit_credit(gl_map):
|
||||
make_round_off_gle(gl_map, debit_credit_diff)
|
||||
|
||||
def make_round_off_gle(gl_map, debit_credit_diff):
|
||||
round_off_account, round_off_cost_center = frappe.db.get_value("Company", gl_map[0].company,
|
||||
["round_off_account", "round_off_cost_center"]) or [None, None]
|
||||
if not round_off_account:
|
||||
frappe.throw(_("Please mention Round Off Account in Company"))
|
||||
|
||||
if not round_off_cost_center:
|
||||
frappe.throw(_("Please mention Round Off Cost Center in Company"))
|
||||
|
||||
round_off_account, round_off_cost_center = get_round_off_account_and_cost_center(gl_map[0].company)
|
||||
|
||||
round_off_gle = frappe._dict()
|
||||
for k in ["voucher_type", "voucher_no", "company",
|
||||
@@ -165,6 +158,17 @@ def make_round_off_gle(gl_map, debit_credit_diff):
|
||||
|
||||
gl_map.append(round_off_gle)
|
||||
|
||||
def get_round_off_account_and_cost_center(company):
|
||||
round_off_account, round_off_cost_center = frappe.db.get_value("Company", company,
|
||||
["round_off_account", "round_off_cost_center"]) or [None, None]
|
||||
if not round_off_account:
|
||||
frappe.throw(_("Please mention Round Off Account in Company"))
|
||||
|
||||
if not round_off_cost_center:
|
||||
frappe.throw(_("Please mention Round Off Cost Center in Company"))
|
||||
|
||||
return round_off_account, round_off_cost_center
|
||||
|
||||
def delete_gl_entries(gl_entries=None, voucher_type=None, voucher_no=None,
|
||||
adv_adj=False, update_outstanding="Yes"):
|
||||
|
||||
|
||||
@@ -8,7 +8,16 @@ frappe.pages['pos'].on_page_load = function (wrapper) {
|
||||
single_column: true
|
||||
});
|
||||
|
||||
wrapper.pos = new erpnext.pos.PointOfSale(wrapper)
|
||||
frappe.db.get_value('POS Settings', {name: 'POS Settings'}, 'is_online', (r) => {
|
||||
if (r && r.use_pos_in_offline_mode && cint(r.use_pos_in_offline_mode)) {
|
||||
// offline
|
||||
wrapper.pos = new erpnext.pos.PointOfSale(wrapper);
|
||||
cur_pos = wrapper.pos;
|
||||
} else {
|
||||
// online
|
||||
frappe.set_route('point-of-sale');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
frappe.pages['pos'].refresh = function (wrapper) {
|
||||
@@ -75,6 +84,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.get_data_from_server(function () {
|
||||
me.make_control();
|
||||
me.create_new();
|
||||
me.make();
|
||||
});
|
||||
},
|
||||
|
||||
@@ -104,6 +114,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
|
||||
this.page.add_menu_item(__("Sync Offline Invoices"), function () {
|
||||
me.freeze_screen = true;
|
||||
me.sync_sales_invoice()
|
||||
});
|
||||
|
||||
@@ -260,9 +271,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.calculate_outstanding_amount();
|
||||
}
|
||||
|
||||
if (this.frm.doc.customer) {
|
||||
this.party_field.$input.val(this.frm.doc.customer);
|
||||
}
|
||||
this.set_customer_value_in_party_field();
|
||||
|
||||
if (!this.frm.doc.write_off_account) {
|
||||
this.frm.doc.write_off_account = doc.write_off_account
|
||||
@@ -273,6 +282,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
},
|
||||
|
||||
set_customer_value_in_party_field: function() {
|
||||
if (this.frm.doc.customer) {
|
||||
this.party_field.$input.val(this.frm.doc.customer);
|
||||
}
|
||||
},
|
||||
|
||||
get_invoice_doc: function (si_docs) {
|
||||
var me = this;
|
||||
this.si_docs = this.get_doc_from_localstorage();
|
||||
@@ -368,7 +383,6 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
},
|
||||
|
||||
setup: function () {
|
||||
this.make();
|
||||
this.set_primary_action();
|
||||
this.party_field.$input.attr('disabled', false);
|
||||
if(this.selected_row) {
|
||||
@@ -426,11 +440,16 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
|
||||
this.serach_item.make_input();
|
||||
this.serach_item.$input.on("keyup", function () {
|
||||
setTimeout(function () {
|
||||
me.items = me.get_items();
|
||||
me.make_item_list();
|
||||
}, 1000);
|
||||
|
||||
this.serach_item.$input.on("keypress", function (event) {
|
||||
|
||||
clearTimeout(me.last_search_timeout);
|
||||
me.last_search_timeout = setTimeout(() => {
|
||||
if((me.serach_item.$input.val() != "") || (event.which == 13)) {
|
||||
me.items = me.get_items();
|
||||
me.make_item_list();
|
||||
}
|
||||
}, 400);
|
||||
});
|
||||
|
||||
this.search_item_group = this.wrapper.find('.search-item-group');
|
||||
@@ -681,6 +700,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
|
||||
set_focus: function () {
|
||||
if (this.default_customer || this.frm.doc.customer) {
|
||||
this.set_customer_value_in_party_field();
|
||||
this.serach_item.$input.focus();
|
||||
} else {
|
||||
this.party_field.$input.focus();
|
||||
@@ -727,14 +747,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
|
||||
input = input.toLowerCase();
|
||||
item = this.get_item(item.value);
|
||||
var searchtext =
|
||||
Object.keys(item)
|
||||
.filter(key => ['customer_name', 'customer_group', 'value', 'label', 'email_id', 'phone', 'mobile_no'].includes(key))
|
||||
.map(key => item[key])
|
||||
.join(" ")
|
||||
.toLowerCase();
|
||||
|
||||
return searchtext.includes(input)
|
||||
result = item ? item.searchtext.includes(input) : '';
|
||||
if(!result) {
|
||||
me.prepare_customer_mapper(input);
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
},
|
||||
item: function (item, input) {
|
||||
var d = this.get_item(item.value);
|
||||
@@ -755,6 +773,9 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
|
||||
this.party_field.$input
|
||||
.on('input', function (e) {
|
||||
if(me.customers_mapper.length <= 1) {
|
||||
me.prepare_customer_mapper(e.target.value);
|
||||
}
|
||||
me.party_field.awesomeplete.list = me.customers_mapper;
|
||||
})
|
||||
.on('awesomplete-select', function (e) {
|
||||
@@ -795,20 +816,56 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
});
|
||||
},
|
||||
|
||||
prepare_customer_mapper: function() {
|
||||
prepare_customer_mapper: function(key) {
|
||||
var me = this;
|
||||
var customer_data = '';
|
||||
|
||||
this.customers_mapper = this.customers.map(function (c) {
|
||||
contact = me.contacts[c.name];
|
||||
return {
|
||||
label: c.name,
|
||||
value: c.name,
|
||||
customer_name: c.customer_name,
|
||||
customer_group: c.customer_group,
|
||||
territory: c.territory,
|
||||
phone: contact ? contact["phone"] : '',
|
||||
mobile_no: contact ? contact["mobile_no"] : '',
|
||||
email_id: contact ? contact["email_id"] : ''
|
||||
if (key) {
|
||||
key = key.toLowerCase().trim();
|
||||
var re = new RegExp('%', 'g');
|
||||
var reg = new RegExp(key.replace(re, '\\w*\\s*[a-zA-Z0-9]*'));
|
||||
|
||||
customer_data = $.grep(this.customers, function(data) {
|
||||
contact = me.contacts[data.name];
|
||||
if(reg.test(data.name.toLowerCase())
|
||||
|| reg.test(data.customer_name.toLowerCase())
|
||||
|| (contact && reg.test(contact["mobile_no"]))
|
||||
|| (contact && reg.test(contact["phone"]))
|
||||
|| (data.customer_group && reg.test(data.customer_group.toLowerCase()))){
|
||||
return data;
|
||||
}
|
||||
})
|
||||
} else {
|
||||
customer_data = this.customers;
|
||||
}
|
||||
|
||||
this.customers_mapper = [];
|
||||
|
||||
customer_data.forEach(function (c, index) {
|
||||
if(index < 30) {
|
||||
contact = me.contacts[c.name];
|
||||
if(contact && !c['phone']) {
|
||||
c["phone"] = contact["phone"];
|
||||
c["email_id"] = contact["email_id"];
|
||||
c["mobile_no"] = contact["mobile_no"];
|
||||
}
|
||||
|
||||
me.customers_mapper.push({
|
||||
label: c.name,
|
||||
value: c.name,
|
||||
customer_name: c.customer_name,
|
||||
customer_group: c.customer_group,
|
||||
territory: c.territory,
|
||||
phone: contact ? contact["phone"] : '',
|
||||
mobile_no: contact ? contact["mobile_no"] : '',
|
||||
email_id: contact ? contact["email_id"] : '',
|
||||
searchtext: ['customer_name', 'customer_group', 'name', 'value',
|
||||
'label', 'email_id', 'phone', 'mobile_no']
|
||||
.map(key => c[key]).join(' ')
|
||||
.toLowerCase()
|
||||
});
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1284,6 +1341,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
|
||||
this.wrapper.find('input.discount-percentage').on("change", function () {
|
||||
me.frm.doc.additional_discount_percentage = flt($(this).val(), precision("additional_discount_percentage"));
|
||||
|
||||
if(me.frm.doc.additional_discount_percentage && me.frm.doc.discount_amount) {
|
||||
// Reset discount amount
|
||||
me.frm.doc.discount_amount = 0;
|
||||
}
|
||||
|
||||
var total = me.frm.doc.grand_total
|
||||
|
||||
if (me.frm.doc.apply_discount_on == 'Net Total') {
|
||||
@@ -1291,15 +1354,15 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
}
|
||||
|
||||
me.frm.doc.discount_amount = flt(total * flt(me.frm.doc.additional_discount_percentage) / 100, precision("discount_amount"));
|
||||
me.wrapper.find('input.discount-amount').val(me.frm.doc.discount_amount)
|
||||
me.refresh();
|
||||
me.wrapper.find('input.discount-amount').val(me.frm.doc.discount_amount)
|
||||
});
|
||||
|
||||
this.wrapper.find('input.discount-amount').on("change", function () {
|
||||
me.frm.doc.discount_amount = flt($(this).val(), precision("discount_amount"));
|
||||
me.frm.doc.additional_discount_percentage = 0.0;
|
||||
me.wrapper.find('input.discount-percentage').val(0);
|
||||
me.refresh();
|
||||
me.wrapper.find('input.discount-percentage').val(0);
|
||||
});
|
||||
},
|
||||
|
||||
@@ -1460,6 +1523,8 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
var me = this;
|
||||
this.wrapper.find(".net-total").text(format_currency(me.frm.doc.total, me.frm.doc.currency));
|
||||
this.wrapper.find(".grand-total").text(format_currency(me.frm.doc.grand_total, me.frm.doc.currency));
|
||||
this.wrapper.find('input.discount-percentage').val(this.frm.doc.additional_discount_percentage);
|
||||
this.wrapper.find('input.discount-amount').val(this.frm.doc.discount_amount);
|
||||
},
|
||||
|
||||
set_primary_action: function () {
|
||||
@@ -1628,6 +1693,7 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
set_interval_for_si_sync: function () {
|
||||
var me = this;
|
||||
setInterval(function () {
|
||||
me.freeze_screen = false;
|
||||
me.sync_sales_invoice()
|
||||
}, 60000)
|
||||
},
|
||||
@@ -1641,9 +1707,12 @@ erpnext.pos.PointOfSale = erpnext.taxes_and_totals.extend({
|
||||
this.freeze = this.customer_doc.display
|
||||
}
|
||||
|
||||
freeze_screen = this.freeze_screen || false;
|
||||
|
||||
if ((this.si_docs.length || this.email_queue_list || this.customers_list) && !this.freeze) {
|
||||
frappe.call({
|
||||
method: "erpnext.accounts.doctype.sales_invoice.pos.make_invoice",
|
||||
freeze: freeze_screen,
|
||||
args: {
|
||||
doc_list: me.si_docs,
|
||||
email_queue_list: me.email_queue_list,
|
||||
|
||||
51
erpnext/accounts/page/pos/test_pos.js
Normal file
51
erpnext/accounts/page/pos/test_pos.js
Normal file
@@ -0,0 +1,51 @@
|
||||
QUnit.test("test:Sales Invoice", function(assert) {
|
||||
assert.expect(3);
|
||||
let done = assert.async();
|
||||
|
||||
frappe.run_serially([
|
||||
() => {
|
||||
return frappe.tests.make("POS Profile", [
|
||||
{naming_series: "SINV"},
|
||||
{country: "India"},
|
||||
{currency: "INR"},
|
||||
{write_off_account: "Write Off - FT"},
|
||||
{write_off_cost_center: "Main - FT"},
|
||||
{payments: [
|
||||
[
|
||||
{"default": 1},
|
||||
{"mode_of_payment": "Cash"}
|
||||
]]
|
||||
}
|
||||
]);
|
||||
},
|
||||
() => cur_frm.save(),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.payments[0].default, 1, "Default mode of payment tested");
|
||||
},
|
||||
() => frappe.timeout(1),
|
||||
() => {
|
||||
return frappe.tests.make("Sales Invoice", [
|
||||
{customer: "Test Customer 2"},
|
||||
{is_pos: 1},
|
||||
{posting_date: frappe.datetime.get_today()},
|
||||
{due_date: frappe.datetime.get_today()},
|
||||
{items: [
|
||||
[
|
||||
{"item_code": "Test Product 1"},
|
||||
{"qty": 5},
|
||||
{"warehouse":'Stores - FT'}
|
||||
]]
|
||||
}
|
||||
]);
|
||||
},
|
||||
() => frappe.timeout(2),
|
||||
() => cur_frm.save(),
|
||||
() => frappe.timeout(2),
|
||||
() => {
|
||||
assert.equal(cur_frm.doc.payments[0].default, 1, "Default mode of payment tested");
|
||||
assert.equal(cur_frm.doc.payments[0].mode_of_payment, "Cash", "Default mode of payment tested");
|
||||
},
|
||||
() => done()
|
||||
]);
|
||||
});
|
||||
@@ -15,7 +15,8 @@ from frappe.contacts.doctype.address.address import (get_address_display,
|
||||
from frappe.contacts.doctype.contact.contact import get_contact_details, get_default_contact
|
||||
from erpnext.exceptions import PartyFrozen, PartyDisabled, InvalidAccountCurrency
|
||||
from erpnext.accounts.utils import get_fiscal_year
|
||||
from erpnext import get_default_currency
|
||||
from erpnext import get_default_currency, get_company_currency
|
||||
|
||||
|
||||
class DuplicatePartyAccountError(frappe.ValidationError): pass
|
||||
|
||||
@@ -43,6 +44,7 @@ def _get_party_details(party=None, account=None, party_type="Customer", company=
|
||||
frappe.throw(_("Not permitted for {0}").format(party), frappe.PermissionError)
|
||||
|
||||
party = frappe.get_doc(party_type, party)
|
||||
currency = party.default_currency if party.default_currency else get_company_currency(company)
|
||||
|
||||
set_address_details(out, party, party_type, doctype, company)
|
||||
set_contact_details(out, party, party_type)
|
||||
@@ -66,18 +68,20 @@ def set_address_details(out, party, party_type, doctype=None, company=None):
|
||||
billing_address_field = "customer_address" if party_type == "Lead" \
|
||||
else party_type.lower() + "_address"
|
||||
out[billing_address_field] = get_default_address(party_type, party.name)
|
||||
out.update(get_fetch_values(doctype, billing_address_field, out[billing_address_field]))
|
||||
if doctype:
|
||||
out.update(get_fetch_values(doctype, billing_address_field, out[billing_address_field]))
|
||||
|
||||
# address display
|
||||
out.address_display = get_address_display(out[billing_address_field])
|
||||
|
||||
# shipping address
|
||||
if party_type in ["Customer", "Lead"]:
|
||||
out.shipping_address_name = get_default_address(party_type, party.name, 'is_shipping_address')
|
||||
out.shipping_address_name = get_party_shipping_address(party_type, party.name)
|
||||
out.shipping_address = get_address_display(out["shipping_address_name"])
|
||||
out.update(get_fetch_values(doctype, 'shipping_address_name', out.shipping_address_name))
|
||||
if doctype:
|
||||
out.update(get_fetch_values(doctype, 'shipping_address_name', out.shipping_address_name))
|
||||
|
||||
if doctype and doctype in ['Sales Invoice']:
|
||||
if doctype and doctype in ['Delivery Note', 'Sales Invoice']:
|
||||
out.update(get_company_address(company))
|
||||
if out.company_address:
|
||||
out.update(get_fetch_values(doctype, 'company_address', out.company_address))
|
||||
@@ -318,11 +322,15 @@ def set_taxes(party, party_type, posting_date, company, customer_group=None, sup
|
||||
from erpnext.accounts.doctype.tax_rule.tax_rule import get_tax_template, get_party_details
|
||||
args = {
|
||||
party_type.lower(): party,
|
||||
"customer_group": customer_group,
|
||||
"supplier_type": supplier_type,
|
||||
"company": company
|
||||
}
|
||||
|
||||
if customer_group:
|
||||
args['customer_group'] = customer_group
|
||||
|
||||
if supplier_type:
|
||||
args['supplier_type'] = supplier_type
|
||||
|
||||
if billing_address or shipping_address:
|
||||
args.update(get_party_details(party, party_type, {"billing_address": billing_address, \
|
||||
"shipping_address": shipping_address }))
|
||||
@@ -410,3 +418,32 @@ def get_dashboard_info(party_type, party):
|
||||
info["total_unpaid"] = -1 * info["total_unpaid"]
|
||||
|
||||
return info
|
||||
|
||||
|
||||
def get_party_shipping_address(doctype, name):
|
||||
"""
|
||||
Returns an Address name (best guess) for the given doctype and name for which `address_type == 'Shipping'` is true.
|
||||
and/or `is_shipping_address = 1`.
|
||||
|
||||
It returns an empty string if there is no matching record.
|
||||
|
||||
:param doctype: Party Doctype
|
||||
:param name: Party name
|
||||
:return: String
|
||||
"""
|
||||
out = frappe.db.sql(
|
||||
'SELECT dl.parent '
|
||||
'from `tabDynamic Link` dl join `tabAddress` ta on dl.parent=ta.name '
|
||||
'where '
|
||||
'dl.link_doctype=%s '
|
||||
'and dl.link_name=%s '
|
||||
'and dl.parenttype="Address" '
|
||||
'and '
|
||||
'(ta.address_type="Shipping" or ta.is_shipping_address=1) '
|
||||
'order by ta.is_shipping_address desc, ta.address_type desc limit 1',
|
||||
(doctype, name)
|
||||
)
|
||||
if out:
|
||||
return out[0][0]
|
||||
else:
|
||||
return ''
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"align_labels_right": 0,
|
||||
"creation": "2017-08-08 12:33:04.773099",
|
||||
"custom_format": 1,
|
||||
"disabled": 0,
|
||||
"doc_type": "Sales Invoice",
|
||||
"docstatus": 0,
|
||||
"doctype": "Print Format",
|
||||
"font": "Default",
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ doc.company }}<br>\n\t{% if doc.company_address_display %}\n\t\t{% set company_address = doc.company_address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t{% if \"GSTIN\" not in company_address %}\n\t\t\t{{ company_address }}\n\t\t\t<b>{{ _(\"GSTIN\") }}:</b>{{ doc.company_gstin }}\n\t\t{% else %}\n\t\t\t{{ company_address.replace(\"GSTIN\", \"<br>GSTIN\") }}\n\t\t{% endif %}\n\t{% endif %}\n\t<br>\n\t<b>{{ doc.select_print_heading or _(\"Invoice\") }}</b><br>\n</p>\n<p>\n\t<b>{{ _(\"Receipt No\") }}:</b> {{ doc.name }}<br>\n\t<b>{{ _(\"Date\") }}:</b> {{ doc.get_formatted(\"posting_date\") }}<br>\n\t{% if doc.grand_total > 50000 %}\n\t\t{% set customer_address = doc.address_display.replace(\"\\n\", \" \").replace(\"<br>\", \" \") %}\n\t\t<b>{{ _(\"Customer\") }}:</b><br>\n\t\t{{ doc.customer_name }}<br>\n\t\t{{ customer_address }}\n\t{% endif %}\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"40%\">{{ _(\"Item\") }}</b></th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Qty\") }}</th>\n\t\t\t<th width=\"30%\" class=\"text-right\">{{ _(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{%- for item in doc.items -%}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_code }}\n\t\t\t\t{%- if item.item_name != item.item_code -%}\n\t\t\t\t\t<br>{{ item.item_name }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.gst_hsn_code -%}\n\t\t\t\t\t<br><b>{{ _(\"HSN/SAC\") }}:</b> {{ item.gst_hsn_code }}\n\t\t\t\t{%- endif -%}\n\t\t\t\t{%- if item.serial_no -%}\n\t\t\t\t\t<br><b>{{ _(\"Serial No\") }}:</b> {{ item.serial_no }}\n\t\t\t\t{%- endif -%}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ item.qty }}<br>@ {{ item.rate }}</td>\n\t\t\t<td class=\"text-right\">{{ item.get_formatted(\"amount\") }}</td>\n\t\t</tr>\n\t\t{%- endfor -%}\n\t</tbody>\n</table>\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ _(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"net_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- for row in doc.taxes -%}\n\t\t{%- if not row.included_in_print_rate -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ row.get_formatted(\"tax_amount\", doc) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t{%- endfor -%}\n\t\t{%- if doc.discount_amount -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ _(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"discount_amount\") }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{%- endif -%}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ _(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ doc.get_formatted(\"grand_total\") }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n<p><b>Tax Breakup:</b></p>\n<div style=\"font-size: 8px\">\n\t{{ doc.other_charges_calculation }}\n</div>\n<p>{{ doc.terms or \"\" }}</p>\n<p class=\"text-center\">{{ _(\"Thank you, please visit again.\") }}</p>",
|
||||
"idx": 0,
|
||||
"line_breaks": 0,
|
||||
"modified": "2017-09-14 15:54:19.467642",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "GST POS Invoice",
|
||||
"owner": "Administrator",
|
||||
"print_format_builder": 0,
|
||||
"print_format_type": "Server",
|
||||
"show_section_headings": 0,
|
||||
"standard": "Yes"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"align_labels_left": 0,
|
||||
"align_labels_right": 0,
|
||||
"creation": "2016-05-05 17:16:18.564460",
|
||||
"custom_format": 1,
|
||||
"disabled": 0,
|
||||
@@ -10,7 +10,7 @@
|
||||
"html": "<style>\n\t.print-format table, .print-format tr, \n\t.print-format td, .print-format div, .print-format p {\n\t\tfont-family: Monospace;\n\t\tline-height: 200%;\n\t\tvertical-align: middle;\n\t}\n\t@media screen {\n\t\t.print-format {\n\t\t\twidth: 4in;\n\t\t\tpadding: 0.25in;\n\t\t\tmin-height: 8in;\n\t\t}\n\t}\n</style>\n\n<p class=\"text-center\">\n\t{{ company }}<br>\n\t{{ __(\"POS No : \") }} {{ offline_pos_name }}<br>\n</p>\n<p>\n\t<b>{{ __(\"Customer\") }}:</b> {{ customer }}<br>\n</p>\n\n<p>\n\t<b>{{ __(\"Date\") }}:</b> {{ dateutil.global_date_format(posting_date) }}<br>\n</p>\n\n<hr>\n<table class=\"table table-condensed cart no-border\">\n\t<thead>\n\t\t<tr>\n\t\t\t<th width=\"50%\">{{ __(\"Item\") }}</b></th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Qty\") }}</th>\n\t\t\t<th width=\"25%\" class=\"text-right\">{{ __(\"Amount\") }}</th>\n\t\t</tr>\n\t</thead>\n\t<tbody>\n\t\t{% for item in items %}\n\t\t<tr>\n\t\t\t<td>\n\t\t\t\t{{ item.item_name }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">{{ format_number(item.qty, null,precision(\"difference\")) }}<br>@ {{ format_currency(item.rate, currency) }}</td>\n\t\t\t<td class=\"text-right\">{{ format_currency(item.amount, currency) }}</td>\n\t\t</tr>\n\t\t{% endfor %}\n\t</tbody>\n</table>\n\n<table class=\"table table-condensed no-border\">\n\t<tbody>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ __(\"Net Total\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% for row in taxes %}\n\t\t{% if not row.included_in_print_rate %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 70%\">\n\t\t\t\t{{ row.description }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(row.tax_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t{% endfor %}\n\t\t{% if discount_amount %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t{{ __(\"Discount\") }}\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(discount_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t{% endif %}\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Grand Total\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(grand_total, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t\t<tr>\n\t\t\t<td class=\"text-right\" style=\"width: 75%\">\n\t\t\t\t<b>{{ __(\"Paid Amount\") }}</b>\n\t\t\t</td>\n\t\t\t<td class=\"text-right\">\n\t\t\t\t{{ format_currency(paid_amount, currency) }}\n\t\t\t</td>\n\t\t</tr>\n\t</tbody>\n</table>\n\n\n<hr>\n<p>{{ terms }}</p>\n<p class=\"text-center\">{{ __(\"Thank you, please visit again.\") }}</p>",
|
||||
"idx": 0,
|
||||
"line_breaks": 0,
|
||||
"modified": "2017-05-19 14:36:04.740728",
|
||||
"modified": "2017-09-14 14:36:04.740728",
|
||||
"modified_by": "Administrator",
|
||||
"module": "Accounts",
|
||||
"name": "Point of Sale",
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
<thead>
|
||||
<tr>
|
||||
{% if(report.report_name === "Accounts Receivable" || report.report_name === "Accounts Payable") { %}
|
||||
<th style="width: 15%">{%= __("Date") %}</th>
|
||||
<th style="width: 15%">{%= __("Ref") %}</th>
|
||||
<th style="width: 40%">{%= __("Party") %}</th>
|
||||
<th style="width: 15%">{%= __("Invoiced Amount") %}</th>
|
||||
<th style="width: 15%">{%= __("Paid Amount") %}</th>
|
||||
<th style="width: 15%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||
<th style="width: 15%">{%= __("Outstanding Amount") %}</th>
|
||||
<th style="width: 14%">{%= __("Date") %}</th>
|
||||
<th style="width: 16%">{%= __("Ref") %}</th>
|
||||
<th style="width: 30%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
<th style="width: 10%">{%= __("Invoiced Amount") %}</th>
|
||||
<th style="width: 10%">{%= __("Paid Amount") %}</th>
|
||||
<th style="width: 10%">{%= report.report_name === "Accounts Receivable" ? __('Credit Note') : __('Debit Note') %}</th>
|
||||
<th style="width: 10%">{%= __("Outstanding Amount") %}</th>
|
||||
{% } else { %}
|
||||
<th style="width: 40%">{%= __("Party") %}</th>
|
||||
<th style="width: 40%">{%= (filters.customer || filters.supplier) ? __("Remarks"): __("Party") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Invoiced Amount") %}</th>
|
||||
<th style="width: 15%">{%= __("Total Paid Amount") %}</th>
|
||||
<th style="width: 15%">{%= report.report_name === "Accounts Receivable Summary" ? __('Credit Note Amount') : __('Debit Note Amount') %}</th>
|
||||
@@ -34,8 +34,12 @@
|
||||
<td>{%= dateutil.str_to_user(data[i][__("Posting Date")]) %}</td>
|
||||
<td>{%= data[i][__("Voucher Type")] %}
|
||||
<br>{%= data[i][__("Voucher No")] %}</td>
|
||||
<td>{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}
|
||||
<br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer Name")] || data[i][__("Customer")] || data[i][__("Supplier Name")] || data[i][__("Supplier")] %}<br>{%= __("Remarks") %}:
|
||||
{% } %}
|
||||
{%= data[i][__("Remarks")] %}
|
||||
</td>
|
||||
<td style="text-align: right">
|
||||
{%= format_currency(data[i]["Invoiced Amount"], data[i]["currency"]) %}</td>
|
||||
<td style="text-align: right">
|
||||
@@ -59,8 +63,13 @@
|
||||
{% } else { %}
|
||||
{% if(data[i][__("Customer")] || data[i][__("Supplier")]|| " ") { %}
|
||||
{% if((data[i][__("Customer")] || data[i][__("Supplier")]) != __("'Total'")) { %}
|
||||
<td>{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
<br>{%= __("Remarks") %}: {%= data[i][__("Remarks")] %}</td>
|
||||
<td>
|
||||
{% if(!(filters.customer || filters.supplier)) { %}
|
||||
{%= data[i][__("Customer")] || data[i][__("Supplier")] %}
|
||||
<br>{%= __("Remarks") %}:
|
||||
{% } %}
|
||||
{%= data[i][__("Remarks")] %}
|
||||
</td>
|
||||
{% } else { %}
|
||||
<td><b>{%= __("Total") %}</b></td>
|
||||
{% } %}
|
||||
|
||||
@@ -44,7 +44,7 @@ class ReceivablePayableReport(object):
|
||||
})
|
||||
|
||||
columns += [_("Age (Days)") + ":Int:80"]
|
||||
|
||||
|
||||
self.ageing_col_idx_start = len(columns)
|
||||
|
||||
if not "range1" in self.filters:
|
||||
@@ -53,7 +53,7 @@ class ReceivablePayableReport(object):
|
||||
self.filters["range2"] = "60"
|
||||
if not "range3" in self.filters:
|
||||
self.filters["range3"] = "90"
|
||||
|
||||
|
||||
for label in ("0-{range1}".format(range1=self.filters["range1"]),
|
||||
"{range1}-{range2}".format(range1=cint(self.filters["range1"])+ 1, range2=self.filters["range2"]),
|
||||
"{range2}-{range3}".format(range2=cint(self.filters["range2"])+ 1, range3=self.filters["range3"]),
|
||||
@@ -74,14 +74,14 @@ class ReceivablePayableReport(object):
|
||||
})
|
||||
if args.get("party_type") == "Customer":
|
||||
columns += [
|
||||
_("Territory") + ":Link/Territory:80",
|
||||
_("Territory") + ":Link/Territory:80",
|
||||
_("Customer Group") + ":Link/Customer Group:120"
|
||||
]
|
||||
if args.get("party_type") == "Supplier":
|
||||
columns += [_("Supplier Type") + ":Link/Supplier Type:80"]
|
||||
|
||||
|
||||
columns.append(_("Remarks") + "::200")
|
||||
|
||||
|
||||
return columns
|
||||
|
||||
def get_data(self, party_naming_by, args):
|
||||
@@ -97,13 +97,13 @@ class ReceivablePayableReport(object):
|
||||
self.filters["company"] = frappe.db.get_single_value('Global Defaults', 'default_company')
|
||||
|
||||
company_currency = frappe.db.get_value("Company", self.filters.get("company"), "default_currency")
|
||||
|
||||
|
||||
return_entries = self.get_return_entries(args.get("party_type"))
|
||||
|
||||
data = []
|
||||
for gle in self.get_entries_till(self.filters.report_date, args.get("party_type")):
|
||||
if self.is_receivable_or_payable(gle, dr_or_cr, future_vouchers):
|
||||
outstanding_amount, credit_note_amount = self.get_outstanding_amount(gle,
|
||||
outstanding_amount, credit_note_amount = self.get_outstanding_amount(gle,
|
||||
self.filters.report_date, dr_or_cr, return_entries, currency_precision)
|
||||
if abs(outstanding_amount) > 0.1/10**currency_precision:
|
||||
row = [gle.posting_date, gle.party]
|
||||
@@ -179,15 +179,15 @@ class ReceivablePayableReport(object):
|
||||
# entries adjusted with future vouchers
|
||||
((gle.against_voucher_type, gle.against_voucher) in future_vouchers)
|
||||
)
|
||||
|
||||
|
||||
def get_return_entries(self, party_type):
|
||||
doctype = "Sales Invoice" if party_type=="Customer" else "Purchase Invoice"
|
||||
return [d.name for d in frappe.get_all(doctype, filters={"is_return": 1, "docstatus": 1})]
|
||||
return [d.name for d in frappe.get_all(doctype, filters={"is_return": 1, "docstatus": 1})]
|
||||
|
||||
def get_outstanding_amount(self, gle, report_date, dr_or_cr, return_entries, currency_precision):
|
||||
payment_amount, credit_note_amount = 0.0, 0.0
|
||||
reverse_dr_or_cr = "credit" if dr_or_cr=="debit" else "debit"
|
||||
|
||||
|
||||
for e in self.get_gl_entries_for(gle.party, gle.party_type, gle.voucher_type, gle.voucher_no):
|
||||
if getdate(e.posting_date) <= report_date and e.name!=gle.name:
|
||||
amount = flt(e.get(reverse_dr_or_cr)) - flt(e.get(dr_or_cr))
|
||||
@@ -195,11 +195,11 @@ class ReceivablePayableReport(object):
|
||||
payment_amount += amount
|
||||
else:
|
||||
credit_note_amount += amount
|
||||
|
||||
|
||||
outstanding_amount = flt((flt(gle.get(dr_or_cr)) - flt(gle.get(reverse_dr_or_cr)) \
|
||||
- payment_amount - credit_note_amount), currency_precision)
|
||||
credit_note_amount = flt(credit_note_amount, currency_precision)
|
||||
|
||||
|
||||
return outstanding_amount, credit_note_amount
|
||||
|
||||
def get_party_name(self, party_type, party_name):
|
||||
@@ -207,7 +207,7 @@ class ReceivablePayableReport(object):
|
||||
|
||||
def get_territory(self, party_name):
|
||||
return self.get_party_map("Customer").get(party_name, {}).get("territory") or ""
|
||||
|
||||
|
||||
def get_customer_group(self, party_name):
|
||||
return self.get_party_map("Customer").get(party_name, {}).get("customer_group") or ""
|
||||
|
||||
@@ -220,7 +220,7 @@ class ReceivablePayableReport(object):
|
||||
select_fields = "name, customer_name, territory, customer_group"
|
||||
elif party_type == "Supplier":
|
||||
select_fields = "name, supplier_name, supplier_type"
|
||||
|
||||
|
||||
self.party_map = dict(((r.name, r) for r in frappe.db.sql("select {0} from `tab{1}`"
|
||||
.format(select_fields, party_type), as_dict=True)))
|
||||
|
||||
@@ -250,8 +250,8 @@ class ReceivablePayableReport(object):
|
||||
else:
|
||||
select_fields = "sum(debit) as debit, sum(credit) as credit"
|
||||
|
||||
self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
|
||||
voucher_type, voucher_no, against_voucher_type, against_voucher,
|
||||
self.gl_entries = frappe.db.sql("""select name, posting_date, account, party_type, party,
|
||||
voucher_type, voucher_no, against_voucher_type, against_voucher,
|
||||
account_currency, remarks, {0}
|
||||
from `tabGL Entry`
|
||||
where docstatus < 2 and party_type=%s and (party is not null and party != '') {1}
|
||||
@@ -277,13 +277,13 @@ class ReceivablePayableReport(object):
|
||||
|
||||
if party_type_field=="customer":
|
||||
if self.filters.get("customer_group"):
|
||||
lft, rgt = frappe.db.get_value("Customer Group",
|
||||
lft, rgt = frappe.db.get_value("Customer Group",
|
||||
self.filters.get("customer_group"), ["lft", "rgt"])
|
||||
|
||||
conditions.append("""party in (select name from tabCustomer
|
||||
where exists(select name from `tabCustomer Group` where lft >= {0} and rgt <= {1}
|
||||
|
||||
conditions.append("""party in (select name from tabCustomer
|
||||
where exists(select name from `tabCustomer Group` where lft >= {0} and rgt <= {1}
|
||||
and name=tabCustomer.customer_group))""".format(lft, rgt))
|
||||
|
||||
|
||||
if self.filters.get("credit_days_based_on"):
|
||||
conditions.append("party in (select name from tabCustomer where credit_days_based_on=%s)")
|
||||
values.append(self.filters.get("credit_days_based_on"))
|
||||
@@ -303,22 +303,22 @@ class ReceivablePayableReport(object):
|
||||
return self.gl_entries_map.get(party, {})\
|
||||
.get(against_voucher_type, {})\
|
||||
.get(against_voucher, [])
|
||||
|
||||
|
||||
def get_chart_data(self, columns, data):
|
||||
ageing_columns = columns[self.ageing_col_idx_start : self.ageing_col_idx_start+4]
|
||||
|
||||
|
||||
rows = []
|
||||
for d in data:
|
||||
rows.append(d[self.ageing_col_idx_start : self.ageing_col_idx_start+4])
|
||||
|
||||
if rows:
|
||||
rows.insert(0, [[d.get("label")] for d in ageing_columns])
|
||||
|
||||
|
||||
return {
|
||||
"data": {
|
||||
'rows': rows
|
||||
'labels': rows
|
||||
},
|
||||
"chart_type": 'pie'
|
||||
"type": 'percentage'
|
||||
}
|
||||
|
||||
def execute(filters=None):
|
||||
|
||||
@@ -8,18 +8,18 @@ from frappe.utils import flt, cint
|
||||
from erpnext.accounts.report.financial_statements import (get_period_list, get_columns, get_data)
|
||||
|
||||
def execute(filters=None):
|
||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||
period_list = get_period_list(filters.from_fiscal_year, filters.to_fiscal_year,
|
||||
filters.periodicity, company=filters.company)
|
||||
|
||||
asset = get_data(filters.company, "Asset", "Debit", period_list,
|
||||
asset = get_data(filters.company, "Asset", "Debit", period_list,
|
||||
only_current_fiscal_year=False, filters=filters,
|
||||
accumulated_values=filters.accumulated_values)
|
||||
|
||||
liability = get_data(filters.company, "Liability", "Credit", period_list,
|
||||
|
||||
liability = get_data(filters.company, "Liability", "Credit", period_list,
|
||||
only_current_fiscal_year=False, filters=filters,
|
||||
accumulated_values=filters.accumulated_values)
|
||||
|
||||
equity = get_data(filters.company, "Equity", "Credit", period_list,
|
||||
|
||||
equity = get_data(filters.company, "Equity", "Credit", period_list,
|
||||
only_current_fiscal_year=False, filters=filters,
|
||||
accumulated_values=filters.accumulated_values)
|
||||
|
||||
@@ -43,17 +43,17 @@ def execute(filters=None):
|
||||
unclosed[period.key] = opening_balance
|
||||
if provisional_profit_loss:
|
||||
provisional_profit_loss[period.key] = provisional_profit_loss[period.key] - opening_balance
|
||||
|
||||
|
||||
unclosed["total"]=opening_balance
|
||||
data.append(unclosed)
|
||||
|
||||
|
||||
if provisional_profit_loss:
|
||||
data.append(provisional_profit_loss)
|
||||
if total_credit:
|
||||
data.append(total_credit)
|
||||
data.append(total_credit)
|
||||
|
||||
columns = get_columns(filters.periodicity, period_list, filters.accumulated_values, company=filters.company)
|
||||
|
||||
|
||||
chart = get_chart_data(filters, columns, asset, liability, equity)
|
||||
|
||||
return columns, data, message, chart
|
||||
@@ -87,7 +87,7 @@ def get_provisional_profit_loss(asset, liability, equity, period_list, company):
|
||||
|
||||
total += flt(provisional_profit_loss[period.key])
|
||||
provisional_profit_loss["total"] = total
|
||||
|
||||
|
||||
total_row_total += flt(total_row[period.key])
|
||||
total_row["total"] = total_row_total
|
||||
|
||||
@@ -98,7 +98,7 @@ def get_provisional_profit_loss(asset, liability, equity, period_list, company):
|
||||
"warn_if_negative": True,
|
||||
"currency": currency
|
||||
})
|
||||
|
||||
|
||||
return provisional_profit_loss, total_row
|
||||
|
||||
def check_opening_balance(asset, liability, equity):
|
||||
@@ -111,17 +111,17 @@ def check_opening_balance(asset, liability, equity):
|
||||
opening_balance -= flt(liability[0].get("opening_balance", 0), float_precision)
|
||||
if equity:
|
||||
opening_balance -= flt(equity[0].get("opening_balance", 0), float_precision)
|
||||
|
||||
|
||||
opening_balance = flt(opening_balance, float_precision)
|
||||
if opening_balance:
|
||||
return _("Previous Financial Year is not closed"),opening_balance
|
||||
return None,None
|
||||
|
||||
|
||||
def get_chart_data(filters, columns, asset, liability, equity):
|
||||
x_intervals = ['x'] + [d.get("label") for d in columns[2:]]
|
||||
|
||||
labels = [d.get("label") for d in columns[2:]]
|
||||
|
||||
asset_data, liability_data, equity_data = [], [], []
|
||||
|
||||
|
||||
for p in columns[2:]:
|
||||
if asset:
|
||||
asset_data.append(asset[-2].get(p.get("fieldname")))
|
||||
@@ -129,23 +129,25 @@ def get_chart_data(filters, columns, asset, liability, equity):
|
||||
liability_data.append(liability[-2].get(p.get("fieldname")))
|
||||
if equity:
|
||||
equity_data.append(equity[-2].get(p.get("fieldname")))
|
||||
|
||||
columns = [x_intervals]
|
||||
|
||||
datasets = []
|
||||
if asset_data:
|
||||
columns.append(["Assets"] + asset_data)
|
||||
datasets.append({'title':'Assets', 'values': asset_data})
|
||||
if liability_data:
|
||||
columns.append(["Liabilities"] + liability_data)
|
||||
datasets.append({'title':'Liabilities', 'values': liability_data})
|
||||
if equity_data:
|
||||
columns.append(["Equity"] + equity_data)
|
||||
datasets.append({'title':'Equity', 'values': equity_data})
|
||||
|
||||
chart = {
|
||||
"data": {
|
||||
'x': 'x',
|
||||
'columns': columns
|
||||
'labels': labels,
|
||||
'datasets': datasets
|
||||
}
|
||||
}
|
||||
|
||||
if not filters.accumulated_values:
|
||||
chart["chart_type"] = "bar"
|
||||
chart["type"] = "bar"
|
||||
else:
|
||||
chart["type"] = "line"
|
||||
|
||||
return chart
|
||||
@@ -99,7 +99,8 @@ def get_actual_details(name, filters):
|
||||
where
|
||||
b.name = ba.parent
|
||||
and b.docstatus = 1
|
||||
and ba.account=gl.account
|
||||
and ba.account=gl.account
|
||||
and b.{budget_against} = gl.{budget_against}
|
||||
and gl.fiscal_year=%s
|
||||
and b.{budget_against}=%s
|
||||
and exists(select name from `tab{tab}` where name=gl.{budget_against} and {cond})
|
||||
|
||||
@@ -142,10 +142,16 @@ def get_data(company, root_type, balance_must_be, period_list, filters=None,
|
||||
|
||||
return out
|
||||
|
||||
|
||||
def calculate_values(accounts_by_name, gl_entries_by_account, period_list, accumulated_values, ignore_accumulated_values_for_fy):
|
||||
for entries in gl_entries_by_account.values():
|
||||
for entry in entries:
|
||||
d = accounts_by_name.get(entry.account)
|
||||
if not d:
|
||||
frappe.msgprint(
|
||||
_("Could not retrieve information for {0}.".format(entry.account)), title="Error",
|
||||
raise_exception=1
|
||||
)
|
||||
for period in period_list:
|
||||
# check if posting date is within the period
|
||||
|
||||
@@ -234,7 +240,7 @@ def add_total_row(out, root_type, balance_must_be, period_list, company_currency
|
||||
for period in period_list:
|
||||
total_row.setdefault(period.key, 0.0)
|
||||
total_row[period.key] += row.get(period.key, 0.0)
|
||||
row[period.key] = ""
|
||||
row[period.key] = 0.0
|
||||
|
||||
total_row.setdefault("total", 0.0)
|
||||
total_row["total"] += flt(row["total"])
|
||||
|
||||
@@ -17,7 +17,6 @@ def execute(filters=None):
|
||||
gross_profit_data = GrossProfitGenerator(filters)
|
||||
|
||||
data = []
|
||||
source = gross_profit_data.grouped_data if filters.get("group_by") != "Invoice" else gross_profit_data.data
|
||||
|
||||
group_wise_columns = frappe._dict({
|
||||
"invoice": ["parent", "customer", "customer_group", "posting_date","item_code", "item_name","item_group", "brand", "description", \
|
||||
@@ -45,7 +44,7 @@ def execute(filters=None):
|
||||
|
||||
columns = get_columns(group_wise_columns, filters)
|
||||
|
||||
for src in source:
|
||||
for src in gross_profit_data.grouped_data:
|
||||
row = []
|
||||
for col in group_wise_columns.get(scrub(filters.group_by)):
|
||||
row.append(src.get(col))
|
||||
@@ -103,10 +102,13 @@ class GrossProfitGenerator(object):
|
||||
self.load_stock_ledger_entries()
|
||||
self.load_product_bundle()
|
||||
self.load_non_stock_items()
|
||||
self.get_returned_invoice_items()
|
||||
self.process()
|
||||
|
||||
def process(self):
|
||||
self.grouped = {}
|
||||
self.grouped_data = []
|
||||
|
||||
for row in self.si_list:
|
||||
if self.skip_row(row, self.product_bundles):
|
||||
continue
|
||||
@@ -143,40 +145,67 @@ class GrossProfitGenerator(object):
|
||||
row.gross_profit_percent = 0.0
|
||||
|
||||
# add to grouped
|
||||
if self.filters.group_by != "Invoice":
|
||||
self.grouped.setdefault(row.get(scrub(self.filters.group_by)), []).append(row)
|
||||
|
||||
self.data.append(row)
|
||||
self.grouped.setdefault(row.get(scrub(self.filters.group_by)), []).append(row)
|
||||
|
||||
if self.grouped:
|
||||
self.get_average_rate_based_on_group_by()
|
||||
else:
|
||||
self.grouped_data = []
|
||||
|
||||
def get_average_rate_based_on_group_by(self):
|
||||
# sum buying / selling totals for group
|
||||
self.grouped_data = []
|
||||
for key in self.grouped.keys():
|
||||
for i, row in enumerate(self.grouped[key]):
|
||||
if i==0:
|
||||
new_row = row
|
||||
else:
|
||||
new_row.qty += row.qty
|
||||
new_row.buying_amount += row.buying_amount
|
||||
new_row.base_amount += row.base_amount
|
||||
if self.filters.get("group_by") != "Invoice":
|
||||
for i, row in enumerate(self.grouped[key]):
|
||||
if i==0:
|
||||
new_row = row
|
||||
else:
|
||||
new_row.qty += row.qty
|
||||
new_row.buying_amount += row.buying_amount
|
||||
new_row.base_amount += row.base_amount
|
||||
new_row = self.set_average_rate(new_row)
|
||||
self.grouped_data.append(new_row)
|
||||
else:
|
||||
for i, row in enumerate(self.grouped[key]):
|
||||
if row.parent in self.returned_invoices \
|
||||
and row.item_code in self.returned_invoices[row.parent]:
|
||||
returned_item_rows = self.returned_invoices[row.parent][row.item_code]
|
||||
for returned_item_row in returned_item_rows:
|
||||
row.qty += returned_item_row.qty
|
||||
row.base_amount += returned_item_row.base_amount
|
||||
row.buying_amount = row.qty * row.buying_rate
|
||||
if row.qty:
|
||||
row = self.set_average_rate(row)
|
||||
self.grouped_data.append(row)
|
||||
|
||||
new_row.gross_profit = new_row.base_amount - new_row.buying_amount
|
||||
new_row.gross_profit_percent = ((new_row.gross_profit / new_row.base_amount) * 100.0) \
|
||||
if new_row.base_amount else 0
|
||||
new_row.buying_rate = (new_row.buying_amount / new_row.qty) \
|
||||
if new_row.qty else 0
|
||||
new_row.base_rate = (new_row.base_amount / new_row.qty) \
|
||||
if new_row.qty else 0
|
||||
def set_average_rate(self, new_row):
|
||||
new_row.gross_profit = new_row.base_amount - new_row.buying_amount
|
||||
new_row.gross_profit_percent = ((new_row.gross_profit / new_row.base_amount) * 100.0) \
|
||||
if new_row.base_amount else 0
|
||||
new_row.buying_rate = (new_row.buying_amount / new_row.qty) if new_row.qty else 0
|
||||
new_row.base_rate = (new_row.base_amount / new_row.qty) if new_row.qty else 0
|
||||
return new_row
|
||||
|
||||
self.grouped_data.append(new_row)
|
||||
def get_returned_invoice_items(self):
|
||||
returned_invoices = frappe.db.sql("""
|
||||
select
|
||||
si.name, si_item.item_code, si_item.qty, si_item.base_amount, si.return_against
|
||||
from
|
||||
`tabSales Invoice` si, `tabSales Invoice Item` si_item
|
||||
where
|
||||
si.name = si_item.parent
|
||||
and si.docstatus = 1
|
||||
and si.is_return = 1
|
||||
""", as_dict=1)
|
||||
|
||||
self.returned_invoices = frappe._dict()
|
||||
for inv in returned_invoices:
|
||||
self.returned_invoices.setdefault(inv.return_against, frappe._dict())\
|
||||
.setdefault(inv.item_code, []).append(inv)
|
||||
|
||||
def skip_row(self, row, product_bundles):
|
||||
if self.filters.get("group_by") != "Invoice" and not row.get(scrub(self.filters.get("group_by"))):
|
||||
if self.filters.get("group_by") != "Invoice":
|
||||
if not row.get(scrub(self.filters.get("group_by"))):
|
||||
return True
|
||||
elif row.get("is_return") == 1:
|
||||
return True
|
||||
|
||||
def get_buying_amount_from_product_bundle(self, row, product_bundle):
|
||||
@@ -268,20 +297,26 @@ class GrossProfitGenerator(object):
|
||||
sales_person_cols = ""
|
||||
sales_team_table = ""
|
||||
|
||||
self.si_list = frappe.db.sql("""select `tabSales Invoice Item`.parenttype, `tabSales Invoice Item`.parent,
|
||||
`tabSales Invoice`.posting_date, `tabSales Invoice`.posting_time, `tabSales Invoice`.project, `tabSales Invoice`.update_stock,
|
||||
`tabSales Invoice`.customer, `tabSales Invoice`.customer_group, `tabSales Invoice`.territory,
|
||||
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.item_name, `tabSales Invoice Item`.description,
|
||||
`tabSales Invoice Item`.warehouse, `tabSales Invoice Item`.item_group, `tabSales Invoice Item`.brand,
|
||||
`tabSales Invoice Item`.dn_detail, `tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.stock_qty as qty,
|
||||
`tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount, `tabSales Invoice Item`.name as "item_row"
|
||||
self.si_list = frappe.db.sql("""
|
||||
select
|
||||
`tabSales Invoice Item`.parenttype, `tabSales Invoice Item`.parent,
|
||||
`tabSales Invoice`.posting_date, `tabSales Invoice`.posting_time,
|
||||
`tabSales Invoice`.project, `tabSales Invoice`.update_stock,
|
||||
`tabSales Invoice`.customer, `tabSales Invoice`.customer_group,
|
||||
`tabSales Invoice`.territory, `tabSales Invoice Item`.item_code,
|
||||
`tabSales Invoice Item`.item_name, `tabSales Invoice Item`.description,
|
||||
`tabSales Invoice Item`.warehouse, `tabSales Invoice Item`.item_group,
|
||||
`tabSales Invoice Item`.brand, `tabSales Invoice Item`.dn_detail,
|
||||
`tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.stock_qty as qty,
|
||||
`tabSales Invoice Item`.base_net_rate, `tabSales Invoice Item`.base_net_amount,
|
||||
`tabSales Invoice Item`.name as "item_row", `tabSales Invoice`.is_return
|
||||
{sales_person_cols}
|
||||
from
|
||||
`tabSales Invoice`
|
||||
inner join `tabSales Invoice Item` on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
|
||||
`tabSales Invoice` inner join `tabSales Invoice Item`
|
||||
on `tabSales Invoice Item`.parent = `tabSales Invoice`.name
|
||||
{sales_team_table}
|
||||
where
|
||||
`tabSales Invoice`.docstatus = 1 {conditions} {match_cond}
|
||||
`tabSales Invoice`.docstatus=1 {conditions} {match_cond}
|
||||
order by
|
||||
`tabSales Invoice`.posting_date desc, `tabSales Invoice`.posting_time desc"""
|
||||
.format(conditions=conditions, sales_person_cols=sales_person_cols,
|
||||
|
||||
@@ -7,7 +7,7 @@ frappe.query_reports["Item-wise Purchase Register"] = {
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_user_default("year_start_date"),
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
"width": "80"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from erpnext.accounts.report.item_wise_sales_register.item_wise_sales_register import get_tax_accounts
|
||||
|
||||
def execute(filters=None):
|
||||
return _execute(filters)
|
||||
@@ -12,12 +13,14 @@ def execute(filters=None):
|
||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||
if not filters: filters = {}
|
||||
columns = get_columns(additional_table_columns)
|
||||
last_col = len(columns)
|
||||
|
||||
company_currency = erpnext.get_company_currency(filters.company)
|
||||
|
||||
item_list = get_items(filters, additional_query_columns)
|
||||
aii_account_map = get_aii_accounts()
|
||||
if item_list:
|
||||
item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency,
|
||||
doctype="Purchase Invoice", tax_doctype="Purchase Taxes and Charges")
|
||||
|
||||
columns.append({
|
||||
"fieldname": "currency",
|
||||
@@ -25,7 +28,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
"fieldtype": "Data",
|
||||
"width": 80
|
||||
})
|
||||
company_currency = frappe.db.get_value("Company", filters.company, "default_currency")
|
||||
|
||||
po_pr_map = get_purchase_receipts_against_purchase_order(item_list)
|
||||
|
||||
data = []
|
||||
for d in item_list:
|
||||
@@ -33,8 +37,7 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
if d.purchase_receipt:
|
||||
purchase_receipt = d.purchase_receipt
|
||||
elif d.po_detail:
|
||||
purchase_receipt = ", ".join(frappe.db.sql_list("""select distinct parent
|
||||
from `tabPurchase Receipt Item` where docstatus=1 and purchase_order_item=%s""", d.po_detail))
|
||||
purchase_receipt = ", ".join(po_pr_map.get(d.po_detail, []))
|
||||
|
||||
expense_account = d.expense_account or aii_account_map.get(d.company)
|
||||
row = [d.item_code, d.item_name, d.item_group, d.parent, d.posting_date, d.supplier,
|
||||
@@ -46,13 +49,15 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
|
||||
row += [
|
||||
d.credit_to, d.mode_of_payment, d.project, d.company, d.purchase_order,
|
||||
purchase_receipt, expense_account, d.qty, d.base_net_rate, d.base_net_amount
|
||||
purchase_receipt, expense_account, d.stock_qty, d.stock_uom, d.base_net_rate, d.base_net_amount
|
||||
]
|
||||
|
||||
for tax in tax_accounts:
|
||||
row.append(item_row_tax.get(d.name, {}).get(tax, 0))
|
||||
total_tax = 0
|
||||
for tax in tax_columns:
|
||||
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
|
||||
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
|
||||
total_tax += flt(item_tax.get("tax_amount"))
|
||||
|
||||
total_tax = sum(row[last_col:])
|
||||
row += [total_tax, d.base_net_amount + total_tax, company_currency]
|
||||
|
||||
data.append(row)
|
||||
@@ -76,7 +81,8 @@ def get_columns(additional_table_columns):
|
||||
_("Mode of Payment") + ":Link/Mode of Payment:80", _("Project") + ":Link/Project:80",
|
||||
_("Company") + ":Link/Company:100", _("Purchase Order") + ":Link/Purchase Order:100",
|
||||
_("Purchase Receipt") + ":Link/Purchase Receipt:100", _("Expense Account") + ":Link/Account:140",
|
||||
_("Qty") + ":Float:120", _("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
|
||||
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100",
|
||||
_("Rate") + ":Currency/currency:120", _("Amount") + ":Currency/currency:120"
|
||||
]
|
||||
|
||||
return columns
|
||||
@@ -85,10 +91,10 @@ def get_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
for opts in (("company", " and company=%(company)s"),
|
||||
("supplier", " and pi.supplier = %(supplier)s"),
|
||||
("item_code", " and pi_item.item_code = %(item_code)s"),
|
||||
("from_date", " and pi.posting_date>=%(from_date)s"),
|
||||
("to_date", " and pi.posting_date<=%(to_date)s"),
|
||||
("supplier", " and `tabPurchase Invoice`.supplier = %(supplier)s"),
|
||||
("item_code", " and `tabPurchase Invoice Item`.item_code = %(item_code)s"),
|
||||
("from_date", " and `tabPurchase Invoice`.posting_date>=%(from_date)s"),
|
||||
("to_date", " and `tabPurchase Invoice`.posting_date<=%(to_date)s"),
|
||||
("mode_of_payment", " and ifnull(mode_of_payment, '') = %(mode_of_payment)s")):
|
||||
if filters.get(opts[0]):
|
||||
conditions += opts[1]
|
||||
@@ -98,71 +104,47 @@ def get_conditions(filters):
|
||||
def get_items(filters, additional_query_columns):
|
||||
conditions = get_conditions(filters)
|
||||
match_conditions = frappe.build_match_conditions("Purchase Invoice")
|
||||
|
||||
if match_conditions:
|
||||
match_conditions = " and {0} ".format(match_conditions)
|
||||
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
pi_item.name, pi_item.parent, pi.posting_date, pi.credit_to, pi.company,
|
||||
pi.supplier, pi.remarks, pi.base_net_total, pi_item.item_code, pi_item.item_name,
|
||||
pi_item.item_group, pi_item.project, pi_item.purchase_order, pi_item.purchase_receipt,
|
||||
pi_item.po_detail, pi_item.expense_account, pi_item.qty, pi_item.base_net_rate,
|
||||
pi_item.base_net_amount, pi.supplier_name, pi.mode_of_payment {0}
|
||||
from `tabPurchase Invoice` pi, `tabPurchase Invoice Item` pi_item
|
||||
where pi.name = pi_item.parent and pi.docstatus = 1 %s %s
|
||||
order by pi.posting_date desc, pi_item.item_code desc
|
||||
`tabPurchase Invoice Item`.`name`, `tabPurchase Invoice Item`.`parent`,
|
||||
`tabPurchase Invoice`.posting_date, `tabPurchase Invoice`.credit_to, `tabPurchase Invoice`.company,
|
||||
`tabPurchase Invoice`.supplier, `tabPurchase Invoice`.remarks, `tabPurchase Invoice`.base_net_total, `tabPurchase Invoice Item`.`item_code`,
|
||||
`tabPurchase Invoice Item`.`item_name`, `tabPurchase Invoice Item`.`item_group`,
|
||||
`tabPurchase Invoice Item`.`project`, `tabPurchase Invoice Item`.`purchase_order`,
|
||||
`tabPurchase Invoice Item`.`purchase_receipt`, `tabPurchase Invoice Item`.`po_detail`,
|
||||
`tabPurchase Invoice Item`.`expense_account`, `tabPurchase Invoice Item`.`stock_qty`,
|
||||
`tabPurchase Invoice Item`.`stock_uom`, `tabPurchase Invoice Item`.`base_net_rate`,
|
||||
`tabPurchase Invoice Item`.`base_net_amount`,
|
||||
`tabPurchase Invoice`.supplier_name, `tabPurchase Invoice`.mode_of_payment {0}
|
||||
from `tabPurchase Invoice`, `tabPurchase Invoice Item`
|
||||
where `tabPurchase Invoice`.name = `tabPurchase Invoice Item`.`parent` and
|
||||
`tabPurchase Invoice`.docstatus = 1 %s %s
|
||||
order by `tabPurchase Invoice`.posting_date desc, `tabPurchase Invoice Item`.item_code desc
|
||||
""".format(additional_query_columns) % (conditions, match_conditions), filters, as_dict=1)
|
||||
|
||||
def get_aii_accounts():
|
||||
return dict(frappe.db.sql("select name, stock_received_but_not_billed from tabCompany"))
|
||||
|
||||
def get_tax_accounts(item_list, columns):
|
||||
import json
|
||||
item_row_tax = {}
|
||||
tax_accounts = []
|
||||
invoice_item_row = {}
|
||||
item_row_map = {}
|
||||
for d in item_list:
|
||||
invoice_item_row.setdefault(d.parent, []).append(d)
|
||||
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
|
||||
def get_purchase_receipts_against_purchase_order(item_list):
|
||||
po_pr_map = frappe._dict()
|
||||
po_item_rows = list(set([d.po_detail for d in item_list]))
|
||||
|
||||
tax_details = frappe.db.sql("""
|
||||
select
|
||||
parent, account_head, item_wise_tax_detail, charge_type, base_tax_amount_after_discount_amount
|
||||
from `tabPurchase Taxes and Charges`
|
||||
where parenttype = 'Purchase Invoice' and docstatus = 1
|
||||
and (account_head is not null and account_head != '')
|
||||
and category in ('Total', 'Valuation and Total')
|
||||
and parent in (%s)
|
||||
""" % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
|
||||
if po_item_rows:
|
||||
purchase_receipts = frappe.db.sql("""
|
||||
select parent, purchase_order_item
|
||||
from `tabPurchase Receipt Item`
|
||||
where docstatus=1 and purchase_order_item in (%s)
|
||||
group by purchase_order_item, parent
|
||||
""" % (', '.join(['%s']*len(po_item_rows))), tuple(po_item_rows), as_dict=1)
|
||||
|
||||
for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||
if account_head not in tax_accounts:
|
||||
tax_accounts.append(account_head)
|
||||
for pr in purchase_receipts:
|
||||
po_pr_map.setdefault(pr.po_detail, []).append(pr.parent)
|
||||
|
||||
if item_wise_tax_detail:
|
||||
try:
|
||||
item_wise_tax_detail = json.loads(item_wise_tax_detail)
|
||||
|
||||
for item_code, tax_amount in item_wise_tax_detail.items():
|
||||
tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
|
||||
|
||||
item_net_amount = sum([flt(d.base_net_amount)
|
||||
for d in item_row_map.get(parent, {}).get(item_code, [])])
|
||||
|
||||
for d in item_row_map.get(parent, {}).get(item_code, []):
|
||||
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
|
||||
item_row_tax.setdefault(d.name, {})[account_head] = item_tax_amount
|
||||
|
||||
except ValueError:
|
||||
continue
|
||||
elif charge_type == "Actual" and tax_amount:
|
||||
for d in invoice_item_row.get(parent, []):
|
||||
item_row_tax.setdefault(d.name, {})[account_head] = \
|
||||
flt((tax_amount * d.base_net_amount) / d.base_net_total)
|
||||
|
||||
tax_accounts.sort()
|
||||
columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
|
||||
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
|
||||
|
||||
return item_row_tax, tax_accounts
|
||||
return po_pr_map
|
||||
@@ -7,7 +7,7 @@ frappe.query_reports["Item-wise Sales Register"] = frappe.query_reports["Sales R
|
||||
"fieldname":"from_date",
|
||||
"label": __("From Date"),
|
||||
"fieldtype": "Date",
|
||||
"default": frappe.defaults.get_default("year_start_date"),
|
||||
"default": frappe.datetime.add_months(frappe.datetime.get_today(), -1),
|
||||
"width": "80"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
# License: GNU General Public License v3. See license.txt
|
||||
|
||||
from __future__ import unicode_literals
|
||||
import frappe
|
||||
import frappe, erpnext
|
||||
from frappe import _
|
||||
from frappe.utils import flt
|
||||
from frappe.model.meta import get_field_precision
|
||||
from erpnext.accounts.report.sales_register.sales_register import get_mode_of_payments
|
||||
|
||||
def execute(filters=None):
|
||||
@@ -13,19 +14,20 @@ def execute(filters=None):
|
||||
def _execute(filters=None, additional_table_columns=None, additional_query_columns=None):
|
||||
if not filters: filters = {}
|
||||
columns = get_columns(additional_table_columns)
|
||||
last_col = len(columns)
|
||||
|
||||
company_currency = erpnext.get_company_currency(filters.company)
|
||||
|
||||
item_list = get_items(filters, additional_query_columns)
|
||||
if item_list:
|
||||
item_row_tax, tax_accounts = get_tax_accounts(item_list, columns)
|
||||
itemised_tax, tax_columns = get_tax_accounts(item_list, columns, company_currency)
|
||||
columns.append({
|
||||
"fieldname": "currency",
|
||||
"label": _("Currency"),
|
||||
"fieldtype": "Data",
|
||||
"width": 80
|
||||
})
|
||||
company_currency = frappe.db.get_value("Company", filters.get("company"), "default_currency")
|
||||
mode_of_payments = get_mode_of_payments(set([d.parent for d in item_list]))
|
||||
so_dn_map = get_delivery_notes_against_sales_order(item_list)
|
||||
|
||||
data = []
|
||||
for d in item_list:
|
||||
@@ -33,8 +35,8 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
if d.delivery_note:
|
||||
delivery_note = d.delivery_note
|
||||
elif d.so_detail:
|
||||
delivery_note = ", ".join(frappe.db.sql_list("""select distinct parent
|
||||
from `tabDelivery Note Item` where docstatus=1 and so_detail=%s""", d.so_detail))
|
||||
delivery_note = ", ".join(so_dn_map.get(d.so_detail, []))
|
||||
|
||||
if not delivery_note and d.update_stock:
|
||||
delivery_note = d.parent
|
||||
|
||||
@@ -47,13 +49,16 @@ def _execute(filters=None, additional_table_columns=None, additional_query_colum
|
||||
row += [
|
||||
d.customer_group, d.debit_to, ", ".join(mode_of_payments.get(d.parent, [])),
|
||||
d.territory, d.project, d.company, d.sales_order,
|
||||
delivery_note, d.income_account, d.cost_center, d.qty, d.base_net_rate, d.base_net_amount
|
||||
delivery_note, d.income_account, d.cost_center, d.stock_qty, d.stock_uom,
|
||||
d.base_net_rate, d.base_net_amount
|
||||
]
|
||||
|
||||
for tax in tax_accounts:
|
||||
row.append(item_row_tax.get(d.name, {}).get(tax, 0))
|
||||
total_tax = 0
|
||||
for tax in tax_columns:
|
||||
item_tax = itemised_tax.get(d.name, {}).get(tax, {})
|
||||
row += [item_tax.get("tax_rate", 0), item_tax.get("tax_amount", 0)]
|
||||
total_tax += flt(item_tax.get("tax_amount"))
|
||||
|
||||
total_tax = sum(row[last_col:])
|
||||
row += [total_tax, d.base_net_amount + total_tax, company_currency]
|
||||
|
||||
data.append(row)
|
||||
@@ -77,7 +82,7 @@ def get_columns(additional_table_columns):
|
||||
_("Project") + ":Link/Project:80", _("Company") + ":Link/Company:100",
|
||||
_("Sales Order") + ":Link/Sales Order:100", _("Delivery Note") + ":Link/Delivery Note:100",
|
||||
_("Income Account") + ":Link/Account:140", _("Cost Center") + ":Link/Cost Center:140",
|
||||
_("Qty") + ":Float:120",
|
||||
_("Stock Qty") + ":Float:120", _("Stock UOM") + "::100",
|
||||
_("Rate") + ":Currency/currency:120",
|
||||
_("Amount") + ":Currency/currency:120"
|
||||
]
|
||||
@@ -88,86 +93,147 @@ def get_conditions(filters):
|
||||
conditions = ""
|
||||
|
||||
for opts in (("company", " and company=%(company)s"),
|
||||
("customer", " and si.customer = %(customer)s"),
|
||||
("item_code", " and si_item.item_code = %(item_code)s"),
|
||||
("from_date", " and si.posting_date>=%(from_date)s"),
|
||||
("to_date", " and si.posting_date<=%(to_date)s")):
|
||||
("customer", " and `tabSales Invoice`.customer = %(customer)s"),
|
||||
("item_code", " and `tabSales Invoice Item`.item_code = %(item_code)s"),
|
||||
("from_date", " and `tabSales Invoice`.posting_date>=%(from_date)s"),
|
||||
("to_date", " and `tabSales Invoice`.posting_date<=%(to_date)s")):
|
||||
if filters.get(opts[0]):
|
||||
conditions += opts[1]
|
||||
|
||||
if filters.get("mode_of_payment"):
|
||||
conditions += """ and exists(select name from `tabSales Invoice Payment`
|
||||
where parent=si.name
|
||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||
where parent=si.name
|
||||
and ifnull(`tabSales Invoice Payment`.mode_of_payment, '') = %(mode_of_payment)s)"""
|
||||
|
||||
return conditions
|
||||
|
||||
def get_items(filters, additional_query_columns):
|
||||
conditions = get_conditions(filters)
|
||||
match_conditions = frappe.build_match_conditions("Sales Invoice")
|
||||
|
||||
if match_conditions:
|
||||
match_conditions = " and {0} ".format(match_conditions)
|
||||
|
||||
if additional_query_columns:
|
||||
additional_query_columns = ', ' + ', '.join(additional_query_columns)
|
||||
|
||||
conditions = get_conditions(filters)
|
||||
return frappe.db.sql("""
|
||||
select
|
||||
si_item.name, si_item.parent, si.posting_date, si.debit_to, si.project,
|
||||
si.customer, si.remarks, si.territory, si.company, si.base_net_total,
|
||||
si_item.item_code, si_item.item_name, si_item.item_group, si_item.sales_order,
|
||||
si_item.delivery_note, si_item.income_account, si_item.cost_center, si_item.qty,
|
||||
si_item.base_net_rate, si_item.base_net_amount, si.customer_name,
|
||||
si.customer_group, si_item.so_detail, si.update_stock {0}
|
||||
from `tabSales Invoice` si, `tabSales Invoice Item` si_item
|
||||
where si.name = si_item.parent and si.docstatus = 1 %s
|
||||
order by si.posting_date desc, si_item.item_code desc
|
||||
""".format(additional_query_columns or '') % conditions, filters, as_dict=1)
|
||||
`tabSales Invoice Item`.name, `tabSales Invoice Item`.parent,
|
||||
`tabSales Invoice`.posting_date, `tabSales Invoice`.debit_to,
|
||||
`tabSales Invoice`.project, `tabSales Invoice`.customer, `tabSales Invoice`.remarks,
|
||||
`tabSales Invoice`.territory, `tabSales Invoice`.company, `tabSales Invoice`.base_net_total,
|
||||
`tabSales Invoice Item`.item_code, `tabSales Invoice Item`.item_name,
|
||||
`tabSales Invoice Item`.item_group, `tabSales Invoice Item`.sales_order,
|
||||
`tabSales Invoice Item`.delivery_note, `tabSales Invoice Item`.income_account,
|
||||
`tabSales Invoice Item`.cost_center, `tabSales Invoice Item`.stock_qty,
|
||||
`tabSales Invoice Item`.stock_uom, `tabSales Invoice Item`.base_net_rate,
|
||||
`tabSales Invoice Item`.base_net_amount, `tabSales Invoice`.customer_name,
|
||||
`tabSales Invoice`.customer_group, `tabSales Invoice Item`.so_detail,
|
||||
`tabSales Invoice`.update_stock {0}
|
||||
from `tabSales Invoice`, `tabSales Invoice Item`
|
||||
where `tabSales Invoice`.name = `tabSales Invoice Item`.parent
|
||||
and `tabSales Invoice`.docstatus = 1 %s %s
|
||||
order by `tabSales Invoice`.posting_date desc, `tabSales Invoice Item`.item_code desc
|
||||
""".format(additional_query_columns or '') % (conditions, match_conditions), filters, as_dict=1)
|
||||
|
||||
def get_tax_accounts(item_list, columns):
|
||||
def get_delivery_notes_against_sales_order(item_list):
|
||||
so_dn_map = frappe._dict()
|
||||
so_item_rows = list(set([d.so_detail for d in item_list]))
|
||||
|
||||
if so_item_rows:
|
||||
delivery_notes = frappe.db.sql("""
|
||||
select parent, so_detail
|
||||
from `tabDelivery Note Item`
|
||||
where docstatus=1 and so_detail in (%s)
|
||||
group by so_detail, parent
|
||||
""" % (', '.join(['%s']*len(so_item_rows))), tuple(so_item_rows), as_dict=1)
|
||||
|
||||
for dn in delivery_notes:
|
||||
so_dn_map.setdefault(dn.so_detail, []).append(dn.parent)
|
||||
|
||||
return so_dn_map
|
||||
|
||||
def get_tax_accounts(item_list, columns, company_currency,
|
||||
doctype="Sales Invoice", tax_doctype="Sales Taxes and Charges"):
|
||||
import json
|
||||
item_row_tax = {}
|
||||
tax_accounts = []
|
||||
invoice_item_row = {}
|
||||
item_row_map = {}
|
||||
tax_columns = []
|
||||
invoice_item_row = {}
|
||||
itemised_tax = {}
|
||||
|
||||
tax_amount_precision = get_field_precision(frappe.get_meta(tax_doctype).get_field("tax_amount"),
|
||||
currency=company_currency) or 2
|
||||
|
||||
for d in item_list:
|
||||
invoice_item_row.setdefault(d.parent, []).append(d)
|
||||
item_row_map.setdefault(d.parent, {}).setdefault(d.item_code, []).append(d)
|
||||
|
||||
conditions = ""
|
||||
if doctype == "Purchase Invoice":
|
||||
conditions = " and category in ('Total', 'Valuation and Total')"
|
||||
|
||||
tax_details = frappe.db.sql("""
|
||||
select
|
||||
parent, account_head, item_wise_tax_detail,
|
||||
parent, description, item_wise_tax_detail,
|
||||
charge_type, base_tax_amount_after_discount_amount
|
||||
from `tabSales Taxes and Charges`
|
||||
from `tab%s`
|
||||
where
|
||||
parenttype = 'Sales Invoice' and docstatus = 1
|
||||
and (account_head is not null and account_head != '')
|
||||
parenttype = %s and docstatus = 1
|
||||
and (description is not null and description != '')
|
||||
and parent in (%s)
|
||||
""" % ', '.join(['%s']*len(invoice_item_row)), tuple(invoice_item_row.keys()))
|
||||
%s
|
||||
order by description
|
||||
""" % (tax_doctype, '%s', ', '.join(['%s']*len(invoice_item_row)), conditions),
|
||||
tuple([doctype] + invoice_item_row.keys()))
|
||||
|
||||
for parent, account_head, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||
if account_head not in tax_accounts:
|
||||
tax_accounts.append(account_head)
|
||||
for parent, description, item_wise_tax_detail, charge_type, tax_amount in tax_details:
|
||||
if description not in tax_columns and tax_amount:
|
||||
tax_columns.append(description)
|
||||
|
||||
if item_wise_tax_detail:
|
||||
try:
|
||||
item_wise_tax_detail = json.loads(item_wise_tax_detail)
|
||||
|
||||
for item_code, tax_amount in item_wise_tax_detail.items():
|
||||
tax_amount = flt(tax_amount[1]) if isinstance(tax_amount, list) else flt(tax_amount)
|
||||
for item_code, tax_data in item_wise_tax_detail.items():
|
||||
itemised_tax.setdefault(item_code, frappe._dict())
|
||||
|
||||
if isinstance(tax_data, list):
|
||||
tax_rate, tax_amount = tax_data
|
||||
else:
|
||||
tax_rate = tax_data
|
||||
tax_amount = 0
|
||||
|
||||
if charge_type == "Actual" and not tax_rate:
|
||||
tax_rate = "NA"
|
||||
|
||||
item_net_amount = sum([flt(d.base_net_amount)
|
||||
for d in item_row_map.get(parent, {}).get(item_code, [])])
|
||||
|
||||
for d in item_row_map.get(parent, {}).get(item_code, []):
|
||||
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) if item_net_amount else 0
|
||||
item_row_tax.setdefault(d.name, {})[account_head] = item_tax_amount
|
||||
item_tax_amount = flt((tax_amount * d.base_net_amount) / item_net_amount) \
|
||||
if item_net_amount else 0
|
||||
if item_tax_amount:
|
||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||
"tax_rate": tax_rate,
|
||||
"tax_amount": flt(item_tax_amount, tax_amount_precision)
|
||||
})
|
||||
|
||||
except ValueError:
|
||||
continue
|
||||
elif charge_type == "Actual" and tax_amount:
|
||||
for d in invoice_item_row.get(parent, []):
|
||||
item_row_tax.setdefault(d.name, {})[account_head] = \
|
||||
flt((tax_amount * d.base_net_amount) / d.base_net_total)
|
||||
itemised_tax.setdefault(d.name, {})[description] = frappe._dict({
|
||||
"tax_rate": "NA",
|
||||
"tax_amount": flt((tax_amount * d.base_net_amount) / d.base_net_total,
|
||||
tax_amount_precision)
|
||||
})
|
||||
|
||||
tax_accounts.sort()
|
||||
columns += [account_head + ":Currency/currency:80" for account_head in tax_accounts]
|
||||
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:80"]
|
||||
tax_columns.sort()
|
||||
for desc in tax_columns:
|
||||
columns.append(desc + " Rate:Data:80")
|
||||
columns.append(desc + " Amount:Currency/currency:100")
|
||||
|
||||
return item_row_tax, tax_accounts
|
||||
columns += ["Total Tax:Currency/currency:80", "Total:Currency/currency:100"]
|
||||
|
||||
return itemised_tax, tax_columns
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user